OperatorDetails = function( operatorProfile ) { let instance = this; instance.operatorProfileInstance = operatorProfile; instance.requiredFields = { distrib1 : Fse.Portal.appConfiguration.OPR.profile.REQUIRED.PREFDISTRIBUTOR == "true" ? true : false, oprSegment : Fse.Portal.appConfiguration.OPR.profile.REQUIRED.PRIMARYSEGMENT == "true" ? true : false, phone : Fse.Portal.appConfiguration.OPR.profile.REQUIRED.MAINPHONE == "true" ? true : false, address : Fse.Portal.appConfiguration.OPR.profile.REQUIRED.STREET == "true" ? true : false, city : Fse.Portal.appConfiguration.OPR.profile.REQUIRED.CITYSTATE == "true" ? true : false, state : Fse.Portal.appConfiguration.OPR.profile.REQUIRED.CITYSTATE == "true" ? true : false, zipCode : Fse.Portal.appConfiguration.OPR.profile.REQUIRED.ZIPCODE == "true" ? true : false }; instance.readOnly = Fse.Portal.checkPermission( "OperatorManagementEdit" ) ? false : true; instance.initDataFromProfile(); /* instance.data = $.extend( true, {}, operatorProfile.data ); instance.operatorProfileInstance.flexValues.forEach( function( fv ) { $.extend( true, instance.data, fv ); }) */ /* instance.changes = new DevExpress.data.ArrayStore( { data : [], key : "dataField", }) */ } OperatorDetails.prototype.constructor = OperatorDetails; OperatorDetails.prototype.element = function() { let instance = this; if( instance.rootElement ) { return instance.rootElement; } instance.rootElement = $("
").addClass( "OperatorDetails"); instance.rootElement.append( instance.detailsTabTemplate() ) instance.saveButton = $("
").dxButton( { text : "Save", disabled : true, type : "default", onClick : function( e ) { instance.save(); } }).dxButton( "instance" ); let toolbar = $("
").dxToolbar( { items : [ { location : "after", template : function() { return instance.saveButton.element(); } } ] }).appendTo( instance.rootElement ); instance.initializeFormData(); return instance.rootElement; } OperatorDetails.prototype.save = function() { let instance = this; let vr = instance.detailsForm.validate(); if( vr.isValid ) { // TODO - get this to protect the page until the load operation is complete let loadPanel = $("
").dxLoadPanel( { message : "Working...", deplay : 0, hideOnOutsideClick : false, hideOnParentScroll : false, container : instance.rootElement, onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); } }).appendTo( $("body") ).dxLoadPanel( "instance" ); let formData = instance.detailsForm.option( "formData" ); let dataToSend = {}; let before = $.extend( true, {}, instance.data ); let changes = instance.changes.createQuery().toArray(); changes.forEach( function( c ) { dataToSend[c.dataField] = c.value before[c.dataField] = instance.data[c.dataField]; }) dataToSend.operatorId = formData.operatorId; dataToSend.lastUpdated = formData.lastUpdated; dataToSend._before = before; console.log( dataToSend ); loadPanel.show(); Fse.Ajax.performAction( { object : "OPR.saveOperatorDetails", data : dataToSend }).done( function( saveOperatorDetailsResult ) { // console.log("result"); // console.log( saveOperatorDetailsResult) let resultProcessed = $.Deferred(); if( ! saveOperatorDetailsResult.status ) { Fse.UI.toast( `Details NOT Saved, possible conflict with another user's change. Try again.`, "warning", 2000 ); resultProcessed.resolve(); } else { Fse.UI.toast( `Details Saved`, "success", 1000 ); resultProcessed.resolve(); } resultProcessed.done( function() { instance.operatorProfileInstance.load().done( function( ) { console.log( "Reloaded" ); // instance.operatorProfileInstance = operatorProfile; instance.initDataFromProfile(); // instance.data = $.extend( true, {}, instance.operatorProfileInstance.data ); instance.initializeFormData(); }) }) }).then( function() { loadPanel.hide(); }); } } OperatorDetails.prototype.detailsTabTemplate = function() { let instance = this; let formData = $.extend( true, {}, instance.data ); formData.flexCategories = []; let managedUnit = instance.data.isUnit; let cuisineReadOnly = managedUnit ? instance.data.cuisineFollowsHQ == "Y" : false; cuisineReadOnly = cuisineReadOnly || instance.readOnly; let segmentReadOnly = managedUnit ? instance.data.segmentFollowsHQ == "Y" : false; segmentReadOnly = segmentReadOnly || instance.readOnly; let territoryReadOnly = Fse.Portal.checkPermission( "OperatorAcctTerritoryChange" ) ? false : true; territoryReadOnly = territoryReadOnly || instance.readOnly; let salesRepReadOnly = Fse.Portal.checkPermission( "OperatorAcctSalesRepChange" ) ? false : true; salesRepReadOnly = salesRepReadOnly || instance.readOnly; let priorityReadOnly = Fse.Portal.checkPermission( "OperatorAcctPriorityChange" ) ? false : true; priorityReadOnly = priorityReadOnly || instance.readOnly; let classificationReadOnly = Fse.Portal.checkPermission( "OperatorAcctClassChange" ) ? false : true; classificationReadOnly = classificationReadOnly || instance.readOnly; let oneFSMode = instance.data.fsl_choId > 0; let accountManagementItems = []; let industryItems = []; let addIndustryItems = function( items ) { if( ! items ) { return; } if( ! Array.isArray( items )) { items = [items]; } items.forEach( function( i ) { industryItems.push( i ); }) } let basicItems = []; let addBasicItems = function( items ) { if( ! items ) { return; } if( ! Array.isArray( items )) { items = [items]; } items.forEach( function( i ) { basicItems.push( i ); }) } instance.salesRepDisplayElement = null; instance.profileErrorsElement = null; accountManagementItems.push( { dataField : "priority", label : { text : "Priority" }, isRequired : true, editorType : "dxSelectBox", editorOptions : { readOnly : priorityReadOnly, width : 100, dataSource : { store : { type : "array", data : [ { value : "*", text : "A+" }, { value : "A", text : "A" }, { value : "B", text : "B" }, { value : "C", text : "C" }, { value : "D", text : "D" } ], key : "value" } }, displayExpr : "text", valueExpr : "value" } }, { dataField : "classificationId", label : { text : "Classification" }, editorType : "dxSelectBox", editorOptions : { width : 300, // dataSource : Fse.Data.newDataSource( { object : "OPR.classifications", keyField : "classificationId" } ), dataSource : Fse.Data.getLocalDataSource( "$.operatorClassifications" ), valueExpr : "classificationId", displayExpr : "name", readOnly : classificationReadOnly, searchEnabled : true, searchMethod : "contains", searchExpr : "name", showClearButton : true }}, { dataField : "territoryId", isRequired : true, label : { text : "Sales Territory" }, editorType : "dxSelectBox", editorOptions : { // dataSource : Fse.Data.newDataSource( { object : "TER.salesTerritories", keyField : "TerritoryID" } ), dataSource : Fse.Data.getLocalDataSource( "$.salesTerritories" ), width : 300, readOnly : territoryReadOnly, searchEnabled : true, searchMethod : "contains", searchExpr : "territoryName", displayExpr : "territoryName", valueExpr : "TerritoryID" }}, { dataField : "mfr_bsr_id", label : { text : "Relationship Manager" }, editorType : "dxSelectBox", editorOptions : { width : 300, dataSource : Fse.Data.getLocalDataSource( "$.salesRepList" ), displayExpr : "fullName", readOnly : salesRepReadOnly, searchEnabled : true, searchMethod : "contains", searchExpr : "fullName", valueExpr : "fspro_userId", showClearButton : true }}, { label : { template : function() { return $("
"); }}, template : function( options, itemContainer ) { instance.salesRepDisplayElement = $("
").css( { "padding-bottom" : "10px" }); itemContainer.append( instance.salesRepDisplayElement ); instance.profileErrorsElement = $("
"); itemContainer.append( instance.profileErrorsElement ); } } ); basicItems.push( { dataField : "operatorType", label : { text : "Company Type" }, editorType : "dxDropDownBox", editorOptions : { readOnly : true, stylingMode : "underlined", dataSource : { store : { type : "array", key : "operatorType", data : [ { operatorType : "INDEPENDENT", operatorTypeDisplay : "Independent"}, { operatorType : "UNIT", operatorTypeDisplay : "Unit"}, { operatorType : "CHAIN HQ", operatorTypeDisplay : "Chain HQ"}, { operatorType : "GPO", operatorTypeDisplay : "GPO"}, { operatorType : "CMC", operatorTypeDisplay : "CMC"}, { operatorType : "SERVICE", operatorTypeDisplay : "Service Company"}, { operatorType : "HOLDING", operatorTypeDisplay : "Holding Company"}, { operatorType : "UKNOWN", operatorTypeDisplay : "Unknown Type"}, ] } }, displayExpr : "operatorTypeDisplay", valueExpr : "operatorType", width : 150 } } ); if( managedUnit ) { basicItems.push( { name : "parentCompanyLink", dataField : "parentOperatorId", label : { text : "Chain HQ" }, template : function( options, container ) { instance.parentOperatorLinkContainer = $("
"); container.append( instance.parentOperatorLinkContainer ); } }, { dataField : "unitNbr", label : { text : "Chain Unit #" }, editorOptions : { readOnly : true } }, { dataField : "chainHQUnitNotesFromParent", label : { text : "Chain Notes" }, editorType : "dxTextArea", editorOptions : { height : "3em" }, editorOptions : { readOnly : true } } ) } if( instance.data.mfrCustNum ) { // this should really be added at all time ans become visible or not based on the data dynamically, but I can't get it // to work for some reason - MWG basicItems.push( { itemType : "group", name : "mfrCustNumGroup", items : [ { dataField : "mfrCustNum", name : "mfrCustNum", label : { text : "Customer #" }, editorType : "dxTextBox", editorOptions : { readOnly : true } } ] } ) } basicItems.push( { dataField : "companyName", label : { text : "Company Name" }, isRequired : true, editorOptions : { width : 400, }} ); if( ! instance.data.is1FSMapped && Fse.Portal.appConfiguration.STP.oneFSEnabled != "Y" ) { basicItems.push( { dataField : "isChainHQ", label : { text : "Company HQ" }, editorType : "dxSwitch" } ) } if( instance.data.isChainHQ ) { let currentYear = ( new Date() ).getFullYear(); let unitItems = [ { dataField : "num_units_lastYr", label : { text : `${currentYear-1}` }, editorType : "dxNumberBox", editorOptions : { mode : "text", width : 60, max : 999999, min : 1 } }, { dataField : "num_units_thisYr", label : { text : `${currentYear}` }, editorType : "dxNumberBox", editorOptions : { mode : "text", width : 60, max : 999999, min : 1 } }, { dataField : "num_units_nextYr", label : { text : `${currentYear+1}` }, editorType : "dxNumberBox", editorOptions : { mode : "text", width : 60, max : 999999, min : 1 } }, { itemType : "empty", colCount : 6 } ]; basicItems.push( { itemType : "group", colCount : 10, items : [ { label : { text : "Number of Units", location : "left" }, template : function( options, container ) { container.append( $("
" ) ) } }, { colSpan : 9, itemType : "group", colCount : 9, alignItemLabels : false, items : unitItems } ] }) } if( instance.data.mdmType ) { let mdmLabel = instance.data.mdmType; if( mdmLabel == "CBS" ) { mdmLabel = "CBSC"; } basicItems.push( { dataField : "mdmId", label : { location : "left", text : `${mdmLabel} ID` }, editorType : "dxTextBox", editorOptions : { readOnly : true, width : 250 } }) } if( Fse.Portal.appConfiguration.TPM.tradeEnabled == "Y" ) { basicItems.push( { itemType: "group", name : "trade", colCount : 7, items : [ { dataField : "tradeEnabled", editorType : "dxSwitch", label : { text : "Trade Enabled" } }, { colSpan : 2, dataField : "tradeNbr", editorType : "dxTextBox", label : { text : "Trade ID" }, disabled : true, editorOptions : { onOptionChanged : function( e ) { console.log( e ) } } }, { itemType : "empty", colSpan : 4 } ] }) } addBasicItems( instance.flexFieldItems( formData, "BASIC_A" )); basicItems.push( { dataField : "primaryContactId", label : { text : "Primary Contact" }, editorType : "dxSelectBox", editorOptions : { width : 300, showClearButton : true, dataSource : Fse.Data.newDataSource( { object : "CRM.partnerContacts", objectParams : { partnerId : instance.data.operatorId, partnerType : "OPR" }, paginate : true, pageSize : 50, keyField : "fspro_userId" }), displayExpr : function( data ) { return data && `${data.firstName} ${data.lastName}`; }, valueExpr : "fspro_userId" } }) basicItems.push( { dataField : "oprSegment", label : { text : "Primary Segment" }, editorType : "dxSelectBox", isRequired : instance.requiredFields.oprSegment, editorOptions : { width : 300, showClearButton : true, // dataSource : Fse.Data.newDataSource( { object : "OPR.segments", paginate : false, keyField : "clientSegId" }), dataSource : Fse.Data.getLocalDataSource( "$.operatorSegments" ), readOnly : segmentReadOnly, displayExpr : "segmentPath", searchEnabled : true, searchMethod : "contains", searchExpr : "segmentPath", valueExpr : "clientSegId" } }) basicItems.push( { dataField : "cuisineId", label : { text : "Primary Cusine" }, editorType : "dxSelectBox", editorOptions : { width : 300, showClearButton : true, readOnly : cuisineReadOnly, // dataSource : Fse.Data.newDataSource( { object : "OPR.cuisines", paginate : false, keyField : "cuisineId" }), dataSource : Fse.Data.getLocalDataSource( "$.operatorCusines" ), searchEnabled : true, searchMethod : "contains", searchExpr : "cuisine", displayExpr : "cuisine", valueExpr : "cuisineId" } }) basicItems.push( { dataField : "alcoholStatus", label : { text : "Serves Alcohol" }, editorType : "dxSelectBox", editorOptions : { width : 300, // dataSource : Fse.Data.newDataSource( { object : "CRM.alcoholStatus", paginate : false, keyField : "alchoholStatus" }), dataSource : Fse.Data.getLocalDataSource( "$.alcoholStatus" ), displayExpr : "alcoholStatusDesc", valueExpr : "alcoholStatus" } }) addBasicItems( instance.seasonalityFields() ); addBasicItems( instance.addressAndPhoneFields() ) addBasicItems( instance.internetFields() ); addIndustryItems( instance.distributionFields() ); addIndustryItems( instance.memberGroupFields() ); addIndustryItems( { template : function( ) { return $("
").css( { "margin-top" : "8px", "margin-bottom" : "8px", "border-bottom" : "1px solid silver", "width" : "100%" } ); } } ) // basic b fields are inserted just after distribution notes addBasicItems( instance.flexFieldItems( formData, "BASIC_B" )); industryItems.push( { dataField : "comments", label : { text : "Comments" }, editorType : "dxTextArea", editorOptions : { maxLength : 1000, height : "4em" } } ) industryItems.push( { dataField : "operatorId", label : { "text" : "System ID" }, editorOptions : { readOnly : true, stylingMode : "underlined" } }, { dataField : "recordSource", label : { "text" : "Source" }, editorOptions : { readOnly : true, stylingMode : "underlined" } } ) basicItems.push( { itemType : "empty" } ); let formItems = [ { itemType : "group", name : "accountManagement", caption : "Account Management", items : accountManagementItems }, { itemType : "group", name : "basic", caption : "Basic Profile", items : basicItems }, { itemType : "group", name : "industry", caption : "Industry Relationships", items : industryItems } ] instance.detailsForm = $("
").dxForm( { readOnly : instance.readOnly, items : formItems, validationGroup : "OperatorDetails", onFieldDataChanged : function( e ) { if( e.dataField == "mfr_bsr_id" ) { instance.updateSalesRepDisplay( e.component ); } if( e.dataField == "mfrCustNum" ) { let visible = false; if( e.value ) { visible = true; } let options = { visible : visible } console.log( "mfrCustNum options", options ); e.component.itemOption( "mfrCustNumGroup.mfrCustNum", "visible", visible ) } if( e.dataField == "parentCompanyName" && e.value && instance.parentOperatorLinkContainer) { let parentCompanyName = e.value; let fd = e.component.option( "formData" ) $("") .append( parentCompanyName ) .css( { "cursor" : "pointer", "text-decoration" : "underline" }) .attr( { title : `Go to '${parentCompanyName}'` }) .appendTo( instance.parentOperatorLinkContainer ) .on( "click", function( jqe) { OperatorPortfolio.getInstance().gotoProfile( { operatorId : fd.parentOperatorId } ); }) } if( e.dataField == "profileErrors" ) { instance.updateProfileErrorDisplay( e.component ); } if( e.dataField == "countryId" || e.dataField == "state" ) { instance.reconfigureFields( e.component, "county" ); let editor = e.component.getEditor( "county" ); let formData = e.component.option( "formData" ); let countyDataSource = editor.getDataSource(); let countyFilter = [ [ "state", "=", '?' ], "and", [ "countryId", "=", 0 ] ] if( formData.countryId && formData.state ) { countyFilter = [ [ "state", "=", formData.state ], "and", [ "countryId", "=", formData.countryId ] ]; } countyDataSource.filter( countyFilter ); editor.option( "value", null ); } if( e.dataField == "territoryId" ) { let territoryId = e.value if( ! territoryId ) { territoryId = -1; } [ "distrib1", "distrib2", "mfr_bsr_id" ].forEach( function( _dataField ) { //, "mfr_bsr_id" let editor = e.component.getEditor( _dataField ); let dataSource= editor.getDataSource(); let filter = [ "territoryId", "=", territoryId ]; if( _dataField == "mfr_bsr_id" ) { filter = [ "territoryIdList", "contains", `#${territoryId};` ]; } dataSource.filter( filter ); dataSource.load(); }) e.component.updateData( { distrib1 : null, distrib2 : null, mfr_bsr_id : null } ); /* let salesRepEditor = e.component.getEditor( "mfr_bsr_id" ); let territoryEditor = e.component.getEditor( "territoryId" ); if( salesRepEditor && territoryEditor ) { let selectedTerritory = territoryEditor.option( "selectedItem" ); let salesRepFilter = null; if( selectedTerritory ) { salesRepFilter = [ "territoryPath", "startswith", selectedTerritory.territoryPath ]; } else { salesRepFilter = [ "territoryPath", "=", "NONE" ]; } let ds = salesRepEditor.getDataSource(); ds.filter( salesRepFilter ); e.component.updateData( { mfr_bsr_id : null } ); } */ } if( e.dataField == "distrib1" || e.dataField == "distrib2" ) { instance.reconfigureFields( e.component, [ `${e.dataField}_accountNumber`, `${e.dataField}_avgWeeklyPurchases`, `${e.dataField}_salesRepId`] ); let distribField = e.dataField; let cdrRecordId = e.component.option("formData")[distribField]; let disabled = cdrRecordId ? false : true; let editor = e.component.getEditor( `${distribField}_salesRepId` ); if( editor ) { let partnerId = cdrRecordId; if( ! partnerId ) { partnerId = -1; } let filter = [ "partnerId", "=", partnerId ]; console.log( filter ); let dataSource = editor.getDataSource(); dataSource.filter( filter ); // dataSource.load(); editor.option( { "disabled" : disabled, "value" : null } ); editor.repaint(); } } if( e.dataField == "tradeEnabled" ) { instance.reconfigureFields( e.component, "tradeNbr" ); } if( e.dataField == "countryId" ) { let editor = e.component.getEditor( "state" ); let stateDS = editor.getDataSource(); console.log( "stateDS") console.log( stateDS ); let stateFilter = [ "countryId", "=", 0 ]; if( e.value ) { stateFilter = [ "countryId", "=", e.value ]; } stateDS.filter( stateFilter ); stateDS.load(); } if( e.dataField == "directCustomer" ) { instance.reconfigureFields( e.component, "directCustomerNbr" ); } let customFields = $.extend( true, {}, e.component.option( "customFields" )); if( customFields && customFields[e.dataField] ) { let customField = customFields[e.dataField]; if( customField.editor ) { customField.editor.option( "value", e.value ); } if( customField.onFieldDataChanged ) { customField.onFieldDataChanged( e ); } } if( instance.changes ) { instance.changes.byKey( e.dataField ) .done( function( change ) { instance.changes.update( e.dataField, { value : e.value }) }) .fail( function() { let change = { dataField : e.dataField, value : e.value } instance.changes.insert( change ); }); } }, onContentReady : function( e ) { console.log( "onContentReady" ); instance.reconfigureFields( e.component ); } }).dxForm( "instance" ); return instance.detailsForm.element(); } OperatorDetails.prototype.initDataFromProfile = function() { let instance = this; instance.data = $.extend( true, {}, instance.operatorProfileInstance.data ); instance.operatorProfileInstance.flexValues.forEach( function( fv ) { $.extend( true, instance.data, fv ); }) } OperatorDetails.prototype.initializeFormData = function() { let instance = this; let formData = $.extend( true, {}, instance.data ); formData.flexCategories = []; instance.saveButton.option( "disabled", true ); instance.changes = null; instance.detailsForm.beginUpdate(); instance.detailsForm.updateData( formData ); // these are set specifically after the all of the fiels are set because they get changed if they are set after the territory is set (mixed in with the above instance.detailsForm.updateData( { mfr_bsr_id : formData.mfr_bsr_id, distrib1 : formData.distrib1, distrib1_accountNumber : formData.distrib1_accountNumber, distrib1_avgWeeklyPurchases : formData.distrib1_avgWeeklyPurchases, distrib1_salesRepId : formData.distrib1_salesRepId, distrib2 : formData.distrib2, distrib2_accountNumber : formData.distrib2_accountNumber, distrib2_avgWeeklyPurchases : formData.distrib2_avgWeeklyPurchases, distrib2_salesRepId : formData.distrib2_salesRepId } ); instance.detailsForm.endUpdate(); instance.changes = new DevExpress.data.ArrayStore( { data : [], key : "dataField", onModified : function( e ) { console.log( e ); instance.saveButton.option( { disabled : false } ) } }) } OperatorDetails.prototype.isSaveNeeded = function() { return this.saveButton.option( "disabled" ) ? false : true; } OperatorDetails.prototype.reconfigureFields = function( form, dataField ) { console.log( "reconfigureFields" ); let dataFields = dataField; let instance = this; if( ! dataFields ) { // do all the fields dataFields = [ "mfr_bsr_id", "profileErrors", "tradeNbr", "distrib1_accountNumber", "distrib1_avgWeeklyPurchases", "distrib1_salesRepId", "distrib2_accountNumber", "distrib2_avgWeeklyPurchases", "distrib2_salesRepId", "seasonOpenDate", "seasonCloseDate" ]; if( Fse.Portal.appConfiguration.STP.ownerType == "MFR" ) { dataFields.push( "directCustomerNbr" ) } } if( ! Array.isArray( dataFields )) { dataFields = [ dataFields ]; } //console.log( dataFields ); let formData = form.option( "formData" ); dataFields.forEach( function( _dataField ) { switch ( _dataField ) { case "mfr_bsr_id" : instance.updateSalesRepDisplay( form ); break; case "profileErrors" : instance.updateProfileErrorDisplay( form ); break; case "distrib1_accountNumber" : case "distrib2_accountNumber" : case "distrib1_avgWeeklyPurchases" : case "distrib2_avgWeeklyPurchases" : case "distrib1_salesRepId" : case "distrib2_salesRepId" :{ let distribField = _dataField.split( "_" )[0]; let cdrRecordId = formData[distribField]; let disabled = cdrRecordId ? false : true; let editor = form.getEditor( _dataField ); if( editor ) { let editorOptions = { disabled : disabled } editor.option( editorOptions ); } } break; case "tradeNbr" : { if( formData.tradeEnabled ) { form.itemOption( "basic.trade.tradeNbr", { disabled : false }) } else { form.itemOption( "basic.trade.tradeNbr", { disabled : true }) } } break; case "seasonOpenDate" : case "seasonCloseDate" : { let msb = form.option( `${_dataField}_msb` ); let dsb = form.option( `${_dataField}_dsb` ); let seasonDate = formData[_dataField]; if( seasonDate ) { let date = new Date( seasonDate ); let m = date.getMonth(); let d = date.getDate(); msb.option( "value", m ); dsb.option( "value", d ); } else { msb.option( "value", null ); dsb.option( "value", null ); } } break; case "directCustomerNbr" : { let editor = form.getEditor( "directCustomerNbr" ); if( editor ) editor.option( "disabled", formData.directCustomer == "Y" ? false : true ); } break; } }) } OperatorDetails.prototype.distributionFields = function() { let instance = this; let items = []; let distributorDataFieldPrefixes = [ "distrib1", "distrib2" ]; distributorDataFieldPrefixes.forEach( function( dataFieldPrefix ) { let labelText = "Preferred Distributor"; if( dataFieldPrefix == "distrib2" ) { labelText = "Secondary Distributor"; } // let distributorDataObject = "CDR.distributors2"; let distributorsDataObject = "CDR.distributorsLight"; let distribDataSource = Fse.Data.newDataSource( { object : distributorsDataObject, keyField : "cdr_recordId", paginate : true, pageSize : 50 } ); distribDataSource.filter( ["territoryId", "=", -1 ] ); let contactsDataSource = Fse.Data.newDataSource( { object : "CRM.partnerContacts", keyField : "fspro_userId", paginate : true, objectParams : { partnerType : 'CDR', partnerId : -1 } } ); contactsDataSource.filter( [ "partnerId", "=", -1 ]) let fieldRequired = false; if( dataFieldPrefix == "distrib1" ) { fieldRequired = instance.requiredFields.distrib1; } items.push( { itemType : "group", colCount : 4, items : [ { label : { text : labelText }, dataField : `${dataFieldPrefix}`, editorType : "dxSelectBox", isRequired : fieldRequired, editorOptions : { deferredRendering : true, dataSource : distribDataSource, showClearButton : true, valueExpr : "cdr_recordId", displayExpr : "cdr_dstName", searchExpr : "cdr_dstName", searchEnabled : true, searchMode : "contains" } }, { label : { text : "Acct. Nbr" }, dataField : `${dataFieldPrefix}_accountNumber`, editorOptions : { disabled : true, maxLength : 50 } }, { label : { text : "Avg. Weekly Purchases" }, dataField : `${dataFieldPrefix}_avgWeeklyPurchases`, editorType : "dxNumberBox", editorOptions : { format : { type : "fixedPoint", precision : 0 }, showSpinButtons : false, disabled : true } }, { label : { text : "Distributor Rep" }, dataField : `${dataFieldPrefix}_salesRepId`, editorType : "dxSelectBox", editorOptions : { disabled : true, showClearButton : true, dataSource : contactsDataSource, displayExpr : function( data ) { return data && `${data.firstName} ${data.lastName}`; }, valueExpr : "fspro_userId" } } ] }) }) // MFR only if( Fse.Portal.appConfiguration.STP.ownerType == "MFR" ) { items.push( { itemType : "group", colCount : 4, items : [ { dataField : "directCustomer", editorType : "dxRadioGroup", editorOptions : { layout : "horizontal", items : [ { value : "Y", text : "Yes", }, { value : "N", text : "No", } ], valueExpr : "value", displayExpr : "text", value : "N" }, label : { text : "Direct Customer" } }, { dataField : "directCustomerNbr", label : { text : "Acct. Nbr." }, editorType : "dxTextBox", editorOptions : { maxLength : 20, width : 150, disabled : true } }, { itemType : "empty", colSpan : 2 } ] }) } items.push( { label : { text : "Distribution Notes" }, dataField : "chain_distr_notes", editorType : "dxTextArea", editorOptions : { maxLength : 500, height : "3em", } } ) return items; } OperatorDetails.prototype.memberGroupFields = function() { let instance = this; let items = []; // these should be readonly if the client is oneFSEnabled let memberGroupsReadOnly = true; // we should only include these if the operator is not a GPO or CMC let memberGroups = []; if( ! ( instance.data.isGPO || instance.data.isCMC ) ) { memberGroups.push ( { label : "Food Mgmt Co.", placeholder : "Self Operated", dataFields : ["cmcID_1,cmcPartnerAffiliateNbr_1,cmcAffiliationDate_1"], // dataSource : Fse.Data.newDataSource( { object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "C" } } ) dataSourceOptions : { object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "C" } }, challengeType : "CMC" }, { label : "Buying Group/GPO", placeholder : "None", dataFields : ["gpoID_1,gpoPartnerAffiliateNbr_1,gpoAffiliationDate_1", "gpoID_2,gpoPartnerAffiliateNbr_2,gpoAffiliationDate_3", "gpoID_3,gpoPartnerAffiliateNbr_3,gpoAffiliationDate_3", "gpoID_4,gpoPartnerAffiliateNbr_4,gpoAffiliationDate_4"], dataSourceOptions : { object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "G" } }, challengeType : "GPO" } ) } memberGroups.forEach( function( mg ) { let alreadyLabeled = false; let fields = []; mg.dataFields.forEach( function( df ) { let dataFields = df.split( "," ); let labelConfig = { text : mg.label }; if( alreadyLabeled ) { labelConfig.template = function( options, container ) { container.append( $("
" ) ) } } alreadyLabeled = true; fields.push( { label : labelConfig, dataField : dataFields[0], editorType : "dxSelectBox", colSpan : 2, editorOptions : { readOnly : memberGroupsReadOnly, placeholder : mg.placeholder, showClearButton : true, dataSource : Fse.Data.newDataSource( mg.dataSourceOptions ), searchExpr : "companyName", searchMode : "contains", searchEnabled : true, displayExpr : "companyName", valueExpr : "operatorId", keyExpr : "operatorId" } }, { label : { text : "ID" }, dataField : dataFields[1], editorType : "dxTextBox", editorOptions : { readOnly : memberGroupsReadOnly, maxLength : 50 } }, { label : { text : "Since" }, dataField : dataFields[2], editorType : "dxDateBox", editorOptions : { readOnly : memberGroupsReadOnly } } ) if( memberGroupsReadOnly ) { fields.push ( { template : function( options, container ) { console.log( options ) $("
").dxButton( { icon : $("link#PortalDocRootURL").attr( "href" ) + "/resources/stp-clean/graphics/ico-challenge.png", onClick : function( e ) { let okayToSubmitChallenge = true; if( Fse.Portal.appConfiguration.STP.oneFSEnabled != "Y" ) { // if the details tab need to be saved they user will have to do so if( instance.isSaveNeeded() ) { okayToSubmitChallenge = false; alert( "Please save changes first" ); } } if( okayToSubmitChallenge ) { let mcp = new MembershipChallengePopup(); let challenging = options.component.option( "formData")[dataFields[0]]; mcp.show( { operatorId : instance.data.operatorId, relationshipField : dataFields[0], challengeType : mg.challengeType, challenging : challenging }) } } }).appendTo( container ); } } ) } else { fields.push( { itemType : "empty" }) } }) items.push( { itemType : "group", colCount : 5, items : fields }); }) return items; } /* OperatorDetails.prototype.memberGroupFieldsSave = function() { let instance = this; let items = []; // these should be readonly if the client is oneFSEnabled let memberGroupsReadOnly = true; // we should only include these if the operator is not a GPO or CMC let memberGroups = []; if( ! ( instance.data.isGPO || instance.data.isCMC ) ) { memberGroups.push ( { label : "Food Mgmt Co.", placeholder : "Self Operated", dataFields : ["cmcID_1,cmcPartnerAffiliateNbr_1,cmcAffiliationDate_1"], // dataSource : Fse.Data.newDataSource( { object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "C" } } ) dataSourceOptions : { object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "C" } }, challengeType : "CMC" }, { label : "Buying Group/GPO", placeholder : "None", dataFields : ["gpoID_1,gpoPartnerAffiliateNbr_1,gpoAffiliationDate_1", "gpoID_2,gpoPartnerAffiliateNbr_2,gpoAffiliationDate_3", "gpoID_3,gpoPartnerAffiliateNbr_3,gpoAffiliationDate_3", "gpoID_4,gpoPartnerAffiliateNbr_4,gpoAffiliationDate_4"], dataSourceOptions : { object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "G" } }, challengeType : "GPO" } ) } memberGroups.forEach( function( mg ) { let fields = []; mg.dataFields.forEach( function( df ) { let dataFields = df.split( "," ); fields.push( { label : { visible : false }, dataField : dataFields[0], editorType : "dxSelectBox", editorOptions : { readOnly : memberGroupsReadOnly, placeholder : mg.placeholder, showClearButton : true, dataSource : Fse.Data.newDataSource( mg.dataSourceOptions ), searchExpr : "companyName", searchMode : "contains", searchEnabled : true, displayExpr : "companyName", valueExpr : "operatorId", keyExpr : "operatorId" } }, { label : { text : "ID" }, dataField : dataFields[1], editorType : "dxTextBox", editorOptions : { readOnly : memberGroupsReadOnly, maxLength : 50 } }, { label : { text : "Since" }, dataField : dataFields[2], editorType : "dxDateBox", editorOptions : { readOnly : memberGroupsReadOnly } } ) if( memberGroupsReadOnly ) { fields.push ( { template : function( options, container ) { console.log( options ) $("
").dxButton( { icon : $("link#PortalDocRootURL").attr( "href" ) + "/resources/stp-clean/graphics/ico-challenge.png", onClick : function( e ) { let okayToSubmitChallenge = true; if( Fse.Portal.appConfiguration.STP.oneFSEnabled != "Y" ) { // if the details tab need to be saved they user will have to do so if( instance.isSaveNeeded() ) { okayToSubmitChallenge = false; alert( "Please save changes first" ); } } if( okayToSubmitChallenge ) { let mcp = new MembershipChallengePopup(); let challenging = options.component.option( "formData")[dataFields[0]]; mcp.show( { operatorId : instance.data.operatorId, relationshipField : dataFields[0], challengeType : mg.challengeType, challenging : challenging }) } } }).appendTo( container ); } } ) } else { fields.push( { itemType : "empty" }) } }) items.push( { itemType : "group", colCount : 8, alignItemLabels : false, items : [ { label : { text : mg.label }, template : function( options, container ) { container.append( $("
" ) ) } }, { itemType : "group", colSpan : 7, colCount : 4, alignItemLabels : false, items : fields } ] }); }) return items; } */ OperatorDetails.prototype.addressAndPhoneFields = function() { let instance = this; let items = []; // let countyDS = Fse.Data.newDataSource( { object : "UT.counties", paginate : false, keyField : "county" } ); let countyDS = Fse.Data.getLocalDataSource( "$.counties" ); countyDS.filter( [ [ "state", "=", '?' ], "and", [ "countryId", "=", 0 ] ] ); // let stateDS = Fse.Data.newDataSource( { object : "UT.states", paginate : false, keyField : "state" } ); let stateDS = Fse.Data.getLocalDataSource( "$.states" ); /* -- if we do this, the inbound will not pick the state in the drop down if we use $.states, if we use UT.states it does? -- UT.states is a network hit every time stateDS.filter( [ "countryId", "=", 0 ]) */ items.push( { dataField : "address", label : { text : "Street" }, isRequired : instance.requiredFields.address, editorOptions : { maxLength : 75, width : 400 } }, { dataField : "address2", label : { text : "Street 2" }, editorOptions : { maxLength : 75, width : 400 } }, { dataField : "countryId", label : { text : "Country" }, editorType : "dxSelectBox", editorOptions : { // dataSource : Fse.Data.newDataSource( { object : "UT.countries", keyField : "countryId" } ), dataSource : Fse.Data.getLocalDataSource( "$.countries" ), displayExpr : "countryAbbrev", valueExpr : "countryId", width : 80 }}, { itemType : "group", colCount : 4, items : [ { dataField : "city", label : { text : "City" }, isRequired : instance.requiredFields.city, editorOptions : { maxLength : 75 } }, { dataField : "state", label : { text : "State" }, isRequired : instance.requiredFields.state, editorType : "dxSelectBox", editorOptions : { width : 80, dataSource : stateDS, placeholder : "state", displayExpr : "state", valueExpr : "state", searchEnabled : true, searchExpr : "state", searchMethod : "startswith", showClearButton : true }}, { dataField : "zipCode", label : { text : "Zip Code" }, isRequired : instance.requiredFields.zipCode, editorOptions : { maxLength : 10 } }, { itemType : "empty" } ] }, { dataField : "county", label : { text : "County" }, editorType : "dxAutocomplete", editorOptions : { width : 150, dataSource : countyDS, valueExpr : "county" } } ); let phoneValidationRules = [ { ignoreEmptyValue : true, type: 'pattern', pattern: /^\d{3}-\d{3}-\d{4}$/, message: 'The phone must have a correct phone format', } ]; if( instance.requiredFields.phone ) { phoneValidationRules.push( { type : "custom", message : "The phone is required", reevaluate : true, ignoreEmptyValue : false, validationCallback : function( options ) { let result = false; if( options.value ) { result = true; } return result; } }) } items.push( { itemType : "group", colCount : 4, items : [ { dataField : "phone", isRequired : instance.requiredFields.phone, editorOptions : { maxLength : 30, width : 150, mask: '000-000-0000', maskChar : ' ', maskInvalidMessage: 'The phone must have a correct phone format', useMaskedValue : true, onValueChanged : function( e ) { if( e.value ) { if( e.value.replace( /\s|-/g, '' ) == '' ) { e.component.option( "value", null ); } } } }, validationRules : phoneValidationRules }, { dataField : "phoneExt", editorOptions : { maxLength : 10, width : 80 } }, // { dataField : "faxNbr", editorOptions : { maxLength : 30, width : 150 } }, { itemType : "empty", colSpan : 2 } ] } ); return items; } OperatorDetails.prototype.internetFields = function() { let instance = this; let items = []; let validURLPattern = Fse.CRM.socialMediaPlatforms.other.urlRegEx; let internetFields = [ { dataField : "url", label : "URL", placeholder : "Company URL", maxLength : 150, width : 300, type : "url" }, { dataField : "email", label : "Email", placeholder : "email", maxLength : 75, width : 200, validationRules : [ { type : "email", message : "Invalid Email" } ] }, { dataField : "facebookURL", label : "Facebook", placeholder : "Facebook URL or ID", width : 300, type : "url", socialMediaPlatform : "facebook" }, { dataField : "instagramURL", label : "Instagram", placeholder : "Instagram URL or ID", width : 300, type : "url", socialMediaPlatform : "instagram" }, { dataField : "twitterURL", label : "\"X\"", placeholder : "\"X\" URL or ID (1-15 char)", width : 300, type : "url", socialMediaPlatform : "twitter" }, { dataField : "tiktokURL", label : "TikTok",placeholder : "TikTok URL or ID", width : 300, type : "url", socialMediaPlatform : "tiktok", }, { dataField : "youtubeURL", label : "YouTube", placeholder : "YouTube URL or ID (10 char)", width : 300, type : "url", socialMediaPlatform : "youtube" }, { dataField : "linkedInURL", label : "LinkedIn", placeholder : "LinkedIn URL", maxLength : 150, width : 300, type : "url", socialMediaPlatform : "linkedin" } ]; internetFields.forEach( function( il ) { let item = { dataField : il.dataField, label : { text : il.label }, template : function( options, itemElement ) { let customFields = options.component.option( "customFields" ); if( ! customFields ) { customFields = {}; } let textBoxConfig = { maxLength : il.maxLength ? il.maxLength : null, placeholder : il.placeholder ? il.placeholder : null, width : il.width ? il.width : null, onValueChanged : function( e ) { options.component.updateData( options.dataField, e.value ); }, readOnly : instance.readOnly }; if( il.type == "url" ) { textBoxConfig.onOptionChanged = function( e ) { if( e.name == "validationErrors" ) { let validationErrors = e.value; if( validationErrors ) { let errorHandled = false; validationErrors.forEach( function( ve ) { if( errorHandled ) return; if( ve.type == "pattern" ) { if( ve.socialMediaPlatform ) { let value = ve.value; if( ! value.match( validURLPattern ) ) { value = ve.urlTransform( value ); if( value.match( validURLPattern ) && value.match( ve.pattern ) ) { errorHandled = true; setTimeout( function() { e.component.option( "value", value ) }, 10 ); } } } else { let value = ve.value; if( ! value.match( /^https+:\/\//i) ) { value = value.replace( /^.*:/i, '' ).replace( /^\/\//, '' ); value = `https://${value}` errorHandled = true; setTimeout( function() { e.component.option( "value", value ) }, 10 ); } } } }) } } } } let textBox = $("
").dxTextBox( textBoxConfig ).dxTextBox( "instance" ); let validationRules = il.validationRules ? il.validationRules : null; if( ! validationRules && il.type == "url" ) { validationRules = []; let message = "Invalid URL"; if( il.socialMediaPlatform && Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform] ) { let pattern = Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform].urlRegEx; let urlTransform = Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform].urlTransform; urlTransform ? urlTransform : function( v ) { return v }; message = `Invalid ${il.placeholder}`; validationRules.push( { type : "pattern", socialMediaPlatform : il.socialMediaPlatform, message : message, pattern : pattern, urlTransform : urlTransform } ) } validationRules.push( { type : "pattern", message : message, pattern : validURLPattern } ); } textBox.element().dxValidator( { validationGroup : options.component.option( "validationGroup" ), validationRules : validationRules }) let editorContainer = $("
"); editorContainer.append( textBox.element() ); itemElement.append( editorContainer ); customFields[il.dataField] = { editor : textBox }; options.component.option( "customFields", customFields ); } } items.push( item ); }); return items; } OperatorDetails.prototype.seasonalityFields = function() { let items = []; let instance = this; let managedUnit = instance.data.isUnit; let seasonalityReadOnly = managedUnit ? instance.data.seasonalityFollowsHQ == "Y" : false; seasonalityReadOnly = seasonalityReadOnly || instance.readOnly; let configureSeasonalityDays = function( form, dataField ) { let msb = form.option( `${dataField}_msb` ); let dsb = form.option( `${dataField}_dsb` ); let days = []; let month = msb.option( "selectedItem" ); let daysDisabled = true; if( month ) { let dayValue = dsb.option( "value" ); daysDisabled = false; days = []; for( let d = 1; d <= month.days; d++ ) { days.push( d ); } if( dayValue && dayValue > days.length ) { dayValue = days.length; } dsb.option( { dataSource : days, value : dayValue, disabled : false }); } else { dsb.option( { dataSource : days, value : null, disabled : true }); } } // a two field template Month and Day to allow for selecting the season open/close date without the year let seasonDateTemplate = function ( options, container ) { let msb = null; let dsb = null; // the days in the month are based on 2000, a leap year msb = $("
").dxSelectBox( { showClearButton : true, readOnly : seasonalityReadOnly, dataSource : [ { id : 0, month : "January", days : 31 }, { id : 1, month : "Feburary", days : 29 }, { id : 2, month : "March", days : 31 }, { id : 3, month : "April", days : 30 }, { id : 4, month : "May", days : 31 }, { id : 5, month : "June", days : 30 }, { id : 6, month : "July", days : 31 }, { id : 7, month : "August", days : 31 }, { id : 8, month : "September", days : 30 }, { id : 9, month : "October", days : 31 }, { id : 10, month : "November", days : 30 }, { id : 11, month : "December", days : 31 }, ], displayExpr : "month", valueExpr : "id", placeholder : "month", onValueChanged : function(e ) { configureSeasonalityDays( options.component, options.dataField ); }, width : 120 }).css( "display", "inline-block" ).dxSelectBox( "instance" ); options.component.option( `${options.dataField}_msb`, msb ); dsb = $("
").dxSelectBox( { dataSource : [], readOnly : seasonalityReadOnly, placeholder : "day", validationGroup : options.component.option( "validationGroup" ), width : 70, disabled : true, onValueChanged : function( e ) { let dateValue = null; if( e.value ) { let d = e.value; let m = msb.option( "value") let date = null; date = new Date(); date.setHours(0); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0); date.setFullYear(2000); date.setMonth( m ); date.setDate( d ); console.log( `Date: ${date}` ); dateValue = DevExpress.localization.formatDate( date, "yyyy-MM-ddTHH:mm:ss" ); } //console.log( `Date: ${dateValue}` ); options.component.updateData( options.dataField, dateValue ); } } ).css( { "display" : "inline-block", "margin-left" : "5px" }).dxSelectBox( "instance" ); options.component.option( `${options.dataField}_dsb`, dsb ); container.append( msb.element() ).append( dsb.element() ) let customFields = $.extend( true, {}, options.component.option( "customFields" )); customFields[options.dataField] = { onFieldDataChanged : function( e ) { instance.reconfigureFields( e.component, e.dataField ); } } options.component.option( "customFields", customFields ); } // seasonality items.push ( { itemType : "group", colCount : 9, xalignItemLabels : false, items : [ { colSpan : 2, dataField : "seasonOpenDate", dataType : "date", label : { text : "Season Open" }, template : function ( options, container ) { seasonDateTemplate( options, container ); } }, { colSpan : 2, dataField : "seasonCloseDate", dataType : "date", label : { text : "Season Close" }, template : function ( options, container ) { seasonDateTemplate( options, container ); } }, { itemType : "empty", colSpan : 5 } ] }) return items; } /* OperatorDetails.prototype.seasonalityFieldsSave = function() { let items = []; let instance = this; let managedUnit = instance.data.isUnit; let seasonalityReadOnly = managedUnit ? instance.data.seasonalityFollowsHQ == "Y" : false; seasonalityReadOnly = seasonalityReadOnly || instance.readOnly; let configureSeasonalityDays = function( form, dataField ) { let msb = form.option( `${dataField}_msb` ); let dsb = form.option( `${dataField}_dsb` ); let days = []; let month = msb.option( "selectedItem" ); let daysDisabled = true; if( month ) { let dayValue = dsb.option( "value" ); daysDisabled = false; days = []; for( let d = 1; d <= month.days; d++ ) { days.push( d ); } if( dayValue && dayValue > days.length ) { dayValue = days.length; } dsb.option( { dataSource : days, value : dayValue, disabled : false }); } else { dsb.option( { dataSource : days, value : null, disabled : true }); } } // a two field template Month and Day to allow for selecting the season open/close date without the year let seasonDateTemplate = function ( options, container ) { let msb = null; let dsb = null; // the days in the month are based on 2000, a leap year msb = $("
").dxSelectBox( { showClearButton : true, readOnly : seasonalityReadOnly, dataSource : [ { id : 0, month : "January", days : 31 }, { id : 1, month : "Feburary", days : 29 }, { id : 2, month : "March", days : 31 }, { id : 3, month : "April", days : 30 }, { id : 4, month : "May", days : 31 }, { id : 5, month : "June", days : 30 }, { id : 6, month : "July", days : 31 }, { id : 7, month : "August", days : 31 }, { id : 8, month : "September", days : 30 }, { id : 9, month : "October", days : 31 }, { id : 10, month : "November", days : 30 }, { id : 11, month : "December", days : 31 }, ], displayExpr : "month", valueExpr : "id", placeholder : "month", onValueChanged : function(e ) { configureSeasonalityDays( options.component, options.dataField ); }, width : 120 }).css( "display", "inline-block" ).dxSelectBox( "instance" ); options.component.option( `${options.dataField}_msb`, msb ); dsb = $("
").dxSelectBox( { dataSource : [], readOnly : seasonalityReadOnly, placeholder : "day", validationGroup : options.component.option( "validationGroup" ), width : 70, disabled : true, onValueChanged : function( e ) { let dateValue = null; if( e.value ) { let d = e.value; let m = msb.option( "value") let date = null; date = new Date(); date.setHours(0); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0); date.setFullYear(2000); date.setMonth( m ); date.setDate( d ); console.log( `Date: ${date}` ); dateValue = DevExpress.localization.formatDate( date, "yyyy-MM-ddTHH:mm:ss" ); } //console.log( `Date: ${dateValue}` ); options.component.updateData( options.dataField, dateValue ); } } ).css( { "display" : "inline-block", "margin-left" : "5px" }).dxSelectBox( "instance" ); options.component.option( `${options.dataField}_dsb`, dsb ); container.append( msb.element() ).append( dsb.element() ) let customFields = $.extend( true, {}, options.component.option( "customFields" )); customFields[options.dataField] = { onFieldDataChanged : function( e ) { instance.reconfigureFields( e.component, e.dataField ); } } options.component.option( "customFields", customFields ); } // seasonality items.push ( { itemType : "group", colCount : 8, alignItemLabels : false, items : [ { label : { text : "Seasonality Dates" }, template : function( options, container ) { container.append( $("
" )); } }, { colSpan : 7, colCount : 8, itemType : "group", items : [ { colSpan : 3, dataField : "seasonOpenDate", dataType : "date", label : { text : "Opens On" }, template : function ( options, container ) { seasonDateTemplate( options, container ); } }, { colSpan : 3, dataField : "seasonCloseDate", dataType : "date", label : { text : "Closes On" }, template : function ( options, container ) { seasonDateTemplate( options, container ); } }, { itemType : "empty", colSpan : 2 } ] } ], }) return items; } */ OperatorDetails.prototype.flexFieldItems = function( formData, fieldCategory ) { let items = []; let instance = this; // basic a fields are inserted just before primary contact instance.operatorProfileInstance.fieldCategoryStore.byKey( fieldCategory ).done( function( data ) { if( data && data.items.length ) { instance.operatorProfileInstance.buildFlexFieldItems( data.items, items ); formData.flexCategories.push( fieldCategory ); if( instance.operatorProfileInstance.flexValues[0][fieldCategory] ) { let values = {}; values[fieldCategory] = instance.operatorProfileInstance.flexValues[0][fieldCategory]; $.extend( true, formData, values ); } } }) return items; } OperatorDetails.prototype.updateSalesRepDisplay = function( form ) { let instance = this; let formData = form.option( "formData" ); let mfr_bsr_id = formData.mfr_bsr_id; if ( mfr_bsr_id ) { instance.salesRepDisplayElement.html( "loading..." ); let ds = form.getEditor( "mfr_bsr_id" ).getDataSource(); ds.store().byKey( mfr_bsr_id ).done( function( data ) { let salesRep = Array.isArray( data ) & data.length ? data[0] : data; let salesRepDisplay = $("
"); if( salesRep.title ) { salesRepDisplay.append( $("
").text( salesRep.title ).css( { "padding-top" : "2px" } ) ); } if( salesRep.phone ) { let phoneElement = $("
").text( salesRep.phone ).css( { "padding-top" : "2px" }); if( salesRep.phoneExt ) { phoneElement.append( ` Ext. ${salesRep.phoneExt}` ); } salesRepDisplay.append( phoneElement ); } salesRepDisplay.append( $("
").text( salesRep.email ).css( { "padding-top" : "2px" } ) ) instance.salesRepDisplayElement.empty().append( salesRepDisplay ); }).fail( function( e ) { console.log( e ); }) } else { instance.salesRepDisplayElement.html( `` ); } } OperatorDetails.prototype.updateProfileErrorDisplay = function( form ) { let instance = this; let formData = form.option( "formData" ); let profileErrors = formData.profileErrors; if( profileErrors ) { let priority = formData.priority; if( priority == "*" ) { priority = "A+"; } let errorsElement = $("
") .css( { "color" : "red", "border" : "1px solid red", "padding" : "5px", "maxWidth" : "400px" } ) errorsElement.append( $("
").text( "Profile Incomplete" ).css( "text-decoration", "underline" ) ); errorsElement.append( $("

").text( `The following elements of this profile are missing values which are required for "${priority}" operators.` ) ) profileErrors.split( "," ).forEach( function( profileError ) { errorsElement.append( $("

") .append( " · " ) .append( instance.resolveProfileError( profileError ) ) ); }) instance.profileErrorsElement.empty().append( errorsElement ); } else { instance.profileErrorsElement.empty(); } } OperatorDetails.prototype.resolveProfileError = function( profileError ) { let resolvedProfileError switch ( profileError ) { case "pc" : resolvedProfileError = "No Primary Contact"; break; case "pc_phone" : resolvedProfileError = "Contact Phone"; break; case "pc_email" : resolvedProfileError = "Contact Email"; break; case "pc_title" : resolvedProfileError = "Contact Title"; break; case "pc_last" : resolvedProfileError = "Contact Last Name"; break; case "pc_first" : resolvedProfileError = "Contact First Name"; break; case "pc_jobfunc" : resolvedProfileError = "Contact Job Func."; break; case "addr" : resolvedProfileError = "Street"; break; case "state" : resolvedProfileError = "State"; break; case "county" : resolvedProfileError = "County"; break; case "city" : resolvedProfileError = "City"; break; case "zip" : resolvedProfileError = "Zip/Postal Code"; break; case "seg" : resolvedProfileError = "Primary Segment"; break; case "cdr" : resolvedProfileError = "Primary Distributor"; break; // on units if HQ case "dd" : resolvedProfileError = "Primary Distributor Details"; break; case "cdr2" : resolvedProfileError = "Secondary Distributor"; break; // on units if HQ case "dd2" : resolvedProfileError = "Seconary Distributor Details"; break; case "cls" : resolvedProfileError = "Classification"; break; case "phone" : resolvedProfileError = "Main Phone"; break; case "fax" : resolvedProfileError = "Fax Number"; break; case "cuisine" : resolvedProfileError = "Cuisine"; break; case "pprof" : resolvedProfileError = "Incomplete Purchasing Profile"; break; case "ansls" : resolvedProfileError = "Annual Sales (TY & LY)"; break; case "cm" : resolvedProfileError = "Assigned Customer Manager"; break; case "bp" : resolvedProfileError = "Business Plan (Opportunities)"; break; } if( ! resolvedProfileError ) { if( profileError.match( /^f_\d+$/ ) != -1 ) { // flex field id let fieldId = profileError.split( "_" )[1]; instance.operatorProfileInstance.flexFields.forEach( function( field ) { if( field.fieldId == fieldId ) { resolvedProfileError = `${field.label} (${field.category})`; } }) } if( ! resolvedProfileError ) { resolvedProfileError = profileError; } } return resolvedProfileError; }