OperatorSearch = function( searchOptions ) { let searchOptionDefaults = { applySearch : function( searchParams ) { // default does nothing, caller must override } }; this.searchOptions = $.extend( true, {}, searchOptionDefaults, searchOptions ) this.dataURL = $("link#appDataURL").attr( "href" ), this.dxBasicForm = null; this.dxFlexFieldForm = null; this.dxPopup = null; this.popupPromise = null; this.filterPreferences = {}; // scrum 46030 this.priorityTypes = [ {"prioritycode":"*","desc":"A+"}, {"prioritycode":"A","desc":"A"}, {"prioritycode":"B","desc":"B"}, {"prioritycode":"C","desc":"C"}, {"prioritycode":"D","desc":"D"} ]; this.displayCompanyTypes = [ { displayCompanyType : "Independent" }, { displayCompanyType : "HQ" }, { displayCompanyType : "Unit" }, { displayCompanyType : "GPO" }, { displayCompanyType : "CMC" }, { displayCompanyType : "Holding" }, ]; this.listManagementEnabled = Fse.Portal.checkPermission( "PartnerListManagement" ); // scrum 46030 - this.init(); } OperatorSearch.prototype.constructor = OperatorSearch; /* scrum 46030 OperatorSearch.prototype.init = function() { this.createPopup(); } */ OperatorSearch.prototype.createFlexFieldForm = function() { let instance = this; let flexData = { flexFields : null, flexTabs : null } let flexDataPromise = $.Deferred(); flexDataPromise.progress( function( notify ) { flexData[notify.dataField] = notify.value; if( flexData.flexFields && flexData.flexTabs ) { flexData.flexTabs.forEach( function( ft ) { let tabCategories = []; ft.categories.forEach( function( ftc ) { tabCategories.push( ftc.name ); }) ft.fields = []; let remainingFields = []; flexData.flexFields.forEach( function( ff ) { if( tabCategories.includes( ff.category )) { ft.fields.push( ff ); } else { remainingFields.push( ff ) } }) flexData.flexFields = remainingFields; }) if( flexData.flexFields.length ) { let detailFlexTab = { displayName : "Basic Profile", fields : flexData.flexFields } flexData.flexTabs.unshift( detailFlexTab ); } console.log( flexData.flexTabs ); flexDataPromise.resolve( flexData.flexTabs ); } }) let tabsDS = Fse.Data.newDataSource( { object : "OPR.flexTabs", paginate : false, keyField : "displayName", objectParams : { operatorId : 0 } } ); tabsDS.load().done( function( flexTabs ) { flexDataPromise.notify( { dataField : "flexTabs", value : flexTabs } ); console.log( "FlexTabs", flexTabs ); }) let customDS = Fse.Data.newDataSource( { object : "OPR.flexFields", paginate : false, key : "fieldId" } ); customDS.filter( [ "searchable", "=", "Y" ] ); customDS.load().done( function( flexFields ) { flexDataPromise.notify( { dataField : "flexFields", value : flexFields } ); console.log( "flexFields", flexFields ); }); flexDataPromise.done( function( flexTabs ) { instance.dxFlexFieldForm = null; if( flexTabs.length ) { let items = []; let marginTopCSSValue = "0px"; flexTabs.forEach( function( flexTab ) { if( flexTab.fields.length == 0 ) return; items.push( { template : function() { return $("
").append( flexTab.displayName ).css( { "margin-top" : `${marginTopCSSValue}`, "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } } ); marginTopCSSValue = "8px"; let data = flexTab.fields; data.forEach( function( fieldDef ) { let label = fieldDef.label; label = label.replace( /\s*\(.*\)/, '' ); let item = { dataField : `${fieldDef.name}$${fieldDef.fieldId}`, label : { text : label }, value : null, editorType : "dxTextBox" }; let lookupValues = fieldDef.lookupValues; if( ( ! lookupValues || ! lookupValues.length ) && fieldDef.config ) { // parse the config value to find build a list of lookup values let configOptions = fieldDef.config.split( "," ); configOptions.forEach( function( co ) { if( ! co.match( /^rows=|^cols=|^size=|^readonly/ ) ) { if( ! lookupValues ) { lookupValues = []; } let lookupElements = co.split( ":" ); if( lookupElements.length > 1 ) { lookupValues.push( { value : lookupElements[0], text : lookupElements[1] } ) } else { lookupValues.push( { value : lookupElements[0], text : lookupElements[0] } ) } } }) } if( Array.isArray( lookupValues ) && lookupValues.length ) { item.editorType = "dxSelectBox", item.editorOptions = { dataSource : lookupValues, displayExpr : "text", valueExpr : "value" } item.editorType = "dxDropDownBox", item.editorOptions = { placeholder : "Select...", dataSource : { store : { type : "array", data : lookupValues, key : "value" }}, showClearButton : true, valueExpr : "value", displayExpr : "text", fieldTemplate : function( value, fieldElement ) { let ddbx = this; let displayText = null; if( value ) { if( ! Array.isArray( value )) { value = [value]; } if( value.length > 1 ) { displayText = "Multiple selected..."; } else if ( value.length == 1 ) { ddbx.getDataSource().store().byKey( value[0] ).done( function( item ) { displayText = item.text; }); } else { displayText = null; } } let field = $("
").dxTextBox( { placeholder : ddbx.option( "placeholder" ), readOnly : true, value : displayText }) fieldElement.append( field ); }, contentTemplate : function( e ) { const v = e.component.option( "value" ); const list = $("
").dxList( { dataSource : e.component.getDataSource(), displayExpr : "text", keyExpr : "value", selectionMode: "multiple", showSelectionControls : true, selectedItemKeys : v, onSelectionChanged : function( sce ) { const keys = sce.component.option( "selectedItemKeys" ); e.component.option( "value", keys ); } }).dxList( "instance" ); e.component.on('valueChanged', (args) => { const { value } = args; list.option( "selectedItemKeys", value ); }); return list.element(); } } } items.push( item ); }) }) if( items.length ) { instance.dxFlexFieldForm = $("
").dxForm( { items : items } ).dxForm( "instance" ); } } instance.popupPromise.notify( "createFlexFieldForm" ); }); } OperatorSearch.prototype.createBasicForm = function() { let instance = this; let unassignedLabel = "Unassigned"; if( Fse.Portal.appConfiguration.OPR.unassignedLabel ) { unassignedLabel = Fse.Portal.appConfiguration.OPR.unassignedLabel; } let operatorListsDataSource = Fse.Data.newDataSource( { object : "LST.lists", keyField : "listId", objectParams : { includeStatus : false, partnerTypes : "OPR" }}); operatorListsDataSource.filter( [ [[ "published", "=", 1 ], "and", [ "forSearch", "=", 1 ]] , "or" , [ [ "creator", "=", 1 ], "or", [ "contributor", "=", 1 ]] ]); let marketItems = []; let leftItems = []; leftItems.push( { template : function() { return $("
").append( "Account Management" ).css( { "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } }, // territoryPath { dataField : "territoryPath", label : { location : "left", text : "Territory" }, editorType : "dxDropDownBox", cssClass : instance.activeFilterPreferences.territoryPath ? 'fx-active-preference' : null, // scrum 46030 editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "TER.salesTerritories", keyField : "territoryPath" } ), searchExpr : "territoryPath", searchMode : "contains", displayExpr : "territoryPath", multipleSelectedDisplay : "Multiple Territories Selected", keyExpr : "territoryPath", title : "Select Territories" }) }, { dataField : "includeSubTerritories", label : { location : "left", text : "Incl. Sub Territories" }, editorType : "dxCheckBox" }, //sales rep { dataField : "salesRepId", label : { location : "left", text : "Sales Rep" }, editorType : "dxDropDownBox", cssClass : instance.activeFilterPreferences.effectiveRepId ? 'fx-active-preference' : null, // scrum 46030 editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "CRM.salesRepList", keyField : "valueId" } ), searchExpr : "valueName", searchMode : "contains", displayExpr : "valueName", multipleSelectedDisplay : "Multiple Sales Reps Selected", keyExpr : "valueId", title : "Select Sales Reps" }) }, { dataField : "assigned", label : { location : "left", text : "Acct. Ownership" }, editorType : "dxSelectBox", editorOptions : { showClearButton : true, dataSource : { store : { type : "array", data : [ { value : "Y", text : "Assigned" }, { value : "N", text : unassignedLabel } ] } }, displayExpr : "text", valueExpr : "value", placeholder : "All Accounts" } } ) leftItems.push( { template : function() { return $("
").append( "Quick Navigations" ).css( { "margin-top" : "8px", "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } }, { dataField : "operatorListId", label : { location : "left", text : `${getText( 'OPERATOR' )} List` }, editorType : "dxSelectBox", editorOptions : { dataSource : operatorListsDataSource, // Fse.Data.newDataSource( { object : "LST.lists", keyField : "listId", objectParams : { includeStats : false, detailLists : true, partnerTypes : 'OPR', listUses : "SEARCH" } }), displayExpr : "listName", searchEnabled : true, searchExpr : "listName", valueExpr : "listId", placeholder : "Select", showClearButton : true } }, { dataField : "includeFavoritesOnly", label : { location : "left", text : "My Favorites Only" }, editorType : "dxCheckBox" }, { dataField : "includeMyAccountsOnly", label : { location : "left", text : "My Accounts Only" }, editorType : "dxCheckBox" } ); if( instance.listManagementEnabled ) { leftItems.push ({ dataField : "operatorSelectionStatus", label : { location : "left", text : "Selection Status" }, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { text : "Selected", value : "SELECTED" }, { text : "Not selected", value : "NOT-SELECTED" } ], key : "value" } }, showClearButton : true, displayExpr : "text", valueExpr : "value", keyExpr : "value", placeholder : "Select" } }); } leftItems.push( { template : function() { return $("
").append( "Tasks" ).css( { "margin-top" : "8px", "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } }, { dataField : "withOpenTasks", label : { location : "left", text : "with Open Tasks" }, editorType : "dxCheckBox" }, { dataField : "tasksAssignedTo", label : { text : "Assigned To" }, editorType : "dxSelectBox", editorOptions : { dataSource : Fse.Data.newDataSource( { object : "FSPRO.members", keyField : "fspro_userId", paginate : true } ), valueExpr : "fspro_userId", displayExpr : "fullName", searchEnabled : true, searchExpr : "fullName", searchMode : "contains", showClearButton : true, disabled : true } } ); marketItems.push( { template : function() { return $("
").append( "Industry Relationships" ).css( { "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } }, // distributor hierarchy { dataField : "cdr_dstPath", label : { location : "left", text : `${getText( 'DISTRIBUTOR' )}` }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "CDR.distributorsLight", keyField : "cdr_dstPath" } ), searchExpr : "cdr_dstPath", searchMode : "contains", displayExpr : "cdr_dstPath", multipleSelectedDisplay : `Multiple ${getTextPlural( 'DISTRIBUTOR' )} Selected`, keyExpr : "cdr_dstPath", title : `Select ${getText( 'DISTRIBUTOR' )}` }) }, /* { itemType : "group", colCount : 3, items : [ */ { dataField : "gpoId", colSpan : 2, label : { location : "left", text : "GPO" }, editorType : "dxDropDownBox", // cssClass : instance.activeFilterPreferences.clientSegPath ? 'fx-active-preference' : null, editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "G" } } ), searchExpr : "companyName", searchMode : "contains", displayExpr : "companyName", multipleSelectedDisplay : "Multiple GPOs Selected", keyExpr : "operatorId", title : "Select GPOs" }) }, { dataField : "noGPO", label : { text : "No GPO" }, editorType : "dxSwitch" }, { dataField : "cmcId", colSpan : 2, label : { location : "left", text : "CMC" }, editorType : "dxDropDownBox", // cssClass : instance.activeFilterPreferences.clientSegPath ? 'fx-active-preference' : null, editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "C" } } ), searchExpr : "companyName", searchMode : "contains", displayExpr : "companyName", multipleSelectedDisplay : "Multiple CMCs Selected", keyExpr : "operatorId", title : "Select CMCs" }) }, { dataField : "noCMC", label : { text : "Self Managed" }, editorType : "dxSwitch"} /* ] } */ , { dataField : "excludeMemberGroupId", label : { location : "left", text : "Exclude GPO/CMC" }, editorType : "dxDropDownBox", // cssClass : instance.activeFilterPreferences.clientSegPath ? 'fx-active-preference' : null, editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "OPR.memberGroups", keyField : "operatorId", objectParams : { "oprCompanyType" : "" } } ), searchExpr : "companyName", searchMode : "contains", displayExpr : "companyName", multipleSelectedDisplay : "Multiple GPO/CMCs Selected", keyExpr : "operatorId", title : "Membership to exclude" }) } ) let showBRO = Fse.Portal.appConfiguration.STP.ownerType === "MFR"; let showMFR = Fse.Portal.appConfiguration.STP.ownerType === "BRO"; if( showBRO ) { marketItems.push( // broker_id { dataField : "broker_id", label : { location : "left", text : "Broker" }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { object : "MFR.brokers", keyField : "broker_id" } ), searchExpr : "broker_name", searchMode : "contains", displayExpr : "broker_name", multipleSelectedDisplay : "Multiple Brokers Selected", keyExpr : "broker_id", title : "Select Brokers" }) }); } //PRIORITY let operatorItems = []; operatorItems.push( // profile section { template : function() { return $("
").append( "Profile" ).css( { "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } }, //segments { dataField : "segmentPath", label : { location : "left", text : "Segment" }, editorType : "dxDropDownBox", cssClass : instance.activeFilterPreferences.clientSegPath ? 'fx-active-preference' : null, // scrum 46030 editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "OPR.segments", keyField : "segmentPath" } ), searchExpr : "segmentPath", searchMode : "contains", displayExpr : "segmentPath", multipleSelectedDisplay : "Multiple Segments Selected", keyExpr : "segmentPath", title : "Select Segments" }) }, //Cuisine { dataField : "cuisineId", label : { location : "left", text : "Cuisine" }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "OPR.cuisines", keyField : "cuisineId" } ), searchExpr : "cuisine", searchMode : "contains", displayExpr : "cuisine", multipleSelectedDisplay : "Multiple Cuisines Selected", keyExpr : "cuisineId", title : "Select Cuisines" }) }, // seasonal { dataField : "seasonal", label : { location : "left", text : "Seasonality" }, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { value : 'Y', text : "Seasonal"}, { value : 'N', text : "Open all year" } ], key : "value" } }, displayExpr : "text", keyExpr : "value", valueExpr : "value", placeholder : "Select...", showClearButton : true } }, // classification { dataField : "classificationId", label : { location : "left", text : "Classification" }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "OPR.classifications", keyField : "classificationId" } ), searchExpr : "name", searchMode : "contains", displayExpr : "name", multipleSelectedDisplay : "Multiple Classifications Selected", keyExpr : "classificationId", title : "Select Classifications" }) }, { dataField : "priority", label : { location : "left", text : "Priority" }, editorType : "dxDropDownBox", editorOptions : { placeholder : "Select Priority", dataSource : new DevExpress.data.ArrayStore({ data: instance.priorityTypes, key: "prioritycode" }) , valueExpr : "prioritycode", displayExpr : "desc", contentTemplate : function( e ) { const v = e.component.option( "value" ); const $list = $("
").dxList( { dataSource : e.component.getDataSource(), displayExpr : "desc", selectionMode: "all", showSelectionControls : true, selectedItemKeys : v, onSelectionChanged : function( sce ) { const keys = sce.component.option( "selectedItemKeys" ); e.component.option( "value", keys ); } }) list = $list.dxList('instance'); e.component.on('valueChanged', (args) => { const { value } = args; list.option( "selectedItemKeys", value ); }); return $list; } } }, { dataField : "profileComplete", label : { location : "left", text : "Profile Status" }, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { text : "Complete", value : "Y" }, { text : "Incomplete", value : "N" } ], key : "value" } }, showClearButton : true, displayExpr : "text", valueExpr : "value", keyExpr : "value", placeholder : "Select" }}, { template : function() { return $("
").append( "HQ/Unit" ).css( { "text-align": "left", "margin-top" : "8px", "font-weight" : "bold" } ) } }, { dataField : "displayCompanyType", label : { text : "Company Type" }, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : instance.displayCompanyTypes, key : "displayCompanyType" }}, displayExpr : "displayCompanyType", valueExpr : "displayCompanyType", showClearButton : true, placeholder : "Select Company Type" }}, //operator(HQ) { dataField : "parentOperatorId", label : { location : "left", text : `${getText( 'OPERATOR' )} HQ` }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "OPR.operatorHQList", keyField : "OperatorID" } ), searchExpr : "oprCompanyName", searchMode : "contains", displayExpr : "oprCompanyName", multipleSelectedDisplay : `Multiple ${getText( 'OPERATOR' )} (HQ) Selected`, keyExpr : "OperatorID", title : `Select ${getText( 'OPERATOR' )} (HQ)` }) }, // removed as per scrum 62340 // { dataField : "chainHQsOnly", label : { location : "left", text : "Chain HQ Only" }, editorType : "dxCheckBox" }, /* { dataField : "numUnitsRange", label : { location : "left", text : "Units"}, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { value : '1-1', text : "1 Unit"}, { value : '2-5', text : "> 1 Unit and <= 5 Units" }, { value : '6-10', text : "> 5 Units and <= 10 Units" }, { value : '11-25', text : "> 10 Units and <= 25 Units" }, { value : '26-100', text : "> 25 Units and <= 100 Units" }, { value : '101', text : "> 100 Units"} ], key : "value" } }, displayExpr : "text", keyExpr : "value", valueExpr : "value", placeholder : "Select...", showClearButton : true }}, */ { dataField : "numUnitsRange", label : { location : "left", text : "Units" }, editorType : "dxDropDownBox", editorOptions : { placeholder : "Select...", dataSource : { store : { type : "array", data : [ { value : '1-1', text : "1 Unit"}, { value : '2-5', text : "> 1 Unit and <= 5 Units" }, { value : '6-10', text : "> 5 Units and <= 10 Units" }, { value : '11-25', text : "> 10 Units and <= 25 Units" }, { value : '26-100', text : "> 25 Units and <= 100 Units" }, { value : '101', text : "> 100 Units"} ], key : "value" } }, valueExpr : "value", displayExpr : "text", contentTemplate : function( e ) { const v = e.component.option( "value" ); const $list = $("
").dxList( { dataSource : e.component.getDataSource(), displayExpr : "text", selectionMode: "all", showSelectionControls : true, selectedItemKeys : v, onSelectionChanged : function( sce ) { const keys = sce.component.option( "selectedItemKeys" ); e.component.option( "value", keys ); } }) const list = $list.dxList('instance'); e.component.on('valueChanged', (args) => { const { value } = args; list.option( "selectedItemKeys", value ); }); return $list; } } }, { dataField : "buyerLocationsOnly", label : { location : "left", text : "Buyer Locations Only" }, editorType : "dxCheckBox" }, // { dataField : "hasActiveAgreements", label : { location : "left", text : "Has Active Agreements" }, editorType : "dxSwitch" }, // TSE-1660 { dataField : "agreementStatus", label : { location : "left", text : "Agreement Status" }, editorType : "dxSelectBox", editorOptions : { showClearButton : true, placeholder : "Select...", dataSource : { store : { type : "array", data : [ { agreementStatus : "Active" }, { agreementStatus : "Expired" },{ agreementStatus : "None" }], key : "agreementStatus" }}, valueExpr : "agreementStatus", displayExpr : "agreementStatus" } } // TSE-1660 ); if ( false ) { operatorItems.push( { dataField : "lastInteractionRange", label : { location : "left", text : "Last Interaction"}, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { value : '30', text : "Past 30 days"}, { value : '60', text : "Past 60 days" }, { value : '90', text : "Past 90 days" }, { value : '120', text : "Past 120 days" }, { value : '365', text : "Past year" }, { value : '-30', text : "Not in past 30 days"}, { value : '-60', text : "Not in past 60 days"}, { value : '-90', text : "Not in past 90 days"}, { value : '-120', text : "Not in past 120 days"}, { value : '-365', text : "Not in past year"}, { value : 'NEVER', text : "Never"}, ], key : "value" } }, displayExpr : "text", keyExpr : "value", valueExpr : "value", placeholder : "Select...", showClearButton : true }} ); } let crmItems = []; crmItems.push( { template : function() { return $("
").append( "Interactions" ).css( { "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } }, { dataField : "interactionAge", label : { location : "left", text : "Last Interaction"}, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { value : 30, text : "Past 30 days"}, { value : 60, text : "Past 60 days" }, { value : 90, text : "Past 90 days" }, { value : 120, text : "Past 120 days" }, { value : 365, text : "Past year" } /* { value : -30, text : "Next 30 days"}, { value : -60, text : "Next 60 days" }, { value : -90, text : "Next 90 days" }, { value : -120, text : "Next 120 days" } */ ], key : "value" } }, displayExpr : "text", keyExpr : "value", valueExpr : "value", placeholder : "Select...", showClearButton : true }} , { dataField : "interactionPurposeId", label : { location : "left", "text" : "Interaction Purpose" }, editorType : "dxSelectBox", editorOptions : { dataSource : Fse.Data.newDataSource( { object : "CRM.interactionPurposes", keyField : "purposeId", objectParams : { partnerType : "OPR" } }), displayExpr : "purposeName", searchEnabled : true, searchExpr : "purposeName", valueExpr : "purposeId", placeholder : "Select Interaction Purpose", showClearButton : true }}, { dataField : "interactionDisposition", label : { location : "left", text : "Interaction Status"}, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { value : "?", text : "Planned"}, { value : "X", text : "Completed" } ], key : "value" } }, displayExpr : "text", keyExpr : "value", valueExpr : "value", placeholder : "Select...", showClearButton : true } }); // opportunity filters crmItems.push( { template : function() { return $("
").append( "Pipeline" ).css( { "margin-top" : "8px", "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } }, { dataField : "stageId", label : { location : "left", text : "Stage" }, editorType : "dxDropDownBox", editorOptions : { placeholder : "Select Stage", dataSource : Fse.Data.newDataSource( { object : "SPL.stages", keyField : "stageId" } ), valueExpr : "stageId", displayExpr : "stageNameFull", contentTemplate : function( e ) { const v = e.component.option( "value" ); const list = $("
").dxList( { dataSource : e.component.getDataSource(), displayExpr : "stageNameFull", selectionMode: "all", showSelectionControls : true, selectedItemKeys : v, onSelectionChanged : function( sce ) { const keys = sce.component.option( "selectedItemKeys" ); e.component.option( "value", keys ); } }).dxList( "instance"); e.component.on('valueChanged', (args) => { const { value } = args; list.option( "selectedItemKeys", value ); }); return list.element(); } } }, { // sales rep dataField : "opportunityEffectiveRepId", label : { location : "left", text : "Opportunity Owner" }, editorType : "dxDropDownBox", cssClass : instance.activeFilterPreferences.effectiveRepId ? 'fx-active-preference' : null, // scrum 46030 editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "CRM.salesRepList", keyField : "valueId" } ), searchExpr : "valueName", searchMode : "contains", displayExpr : "valueName", multipleSelectedDisplay : "Multiple Opportunity Owners Selected", keyExpr : "valueId", title : "Select Opportunity Owners" }) } ) crmItems.push( { template : function() { return $("
").append( "Purchasing" ).css( { "margin-top" : "8px", "text-align": "left", "xfont-size" : "larger", "font-weight" : "bold" } ) } }, { dataField : "productStatusPurchasingStatus", label : { location : "left", text : "Status" }, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", key : "value", data : [ { value : "B", text : "Buying" }, { value : "N", text : "Not Buying" } ]} }, valueExpr : "value", displayExpr : "text", showClearButton : true, keyExpr : "value", placeholder : "Select Purchasing Status" } } ); if( showMFR ) { crmItems.push( { dataField : "productStatusMfrId", label : { location : "left", text : "Manufacturer" }, editorType : "dxSelectBox", editorOptions : { disabled : true, dataSource : Fse.Data.newDataSource( { object : "PRD.manufacturers", keyField : "mfr_id" } ), searchExpr : "mfr_name", searchMode : "contains", searchEnabled : true, displayExpr : "mfr_name", showClearButton : true, multipleSelectedDisplay : "Multiple Manufacturers Selected", keyExpr : "mfr_id", valueExpr : "mfr_id", title : "Select Manufacturer" } } ); } crmItems.push( { dataField : "productStatusProductHierarchyPath", label : { location : "left", text : "Product" }, editorType : "dxDropDownBox", editorOptions : { dataSource : ! showMFR ? Fse.Data.newDataSource( { object : "PRD.productHierarchyPaths", keyField : "productHierarchyPath" } ) : null, disabled : true, valueExpr : "productHierarchyPath", displayExpr : "productHierarchyPath", contentTemplate : function( options ) { let list = $("
").dxList( { dataSource : options.component.getDataSource(), // Fse.Data.newDataSource( { object : "PRD.productHierarchyPaths", keyField : "productHierarchyPath" } ), itemTemplate : function( itemData ) { let pathParts = itemData.productHierarchyPath.split( "/" ); let item = $("
").text( pathParts[pathParts.length-1] ); let indents = pathParts.length - 1; if( indents ) { item.css( { "padding-left" : `${indents*10}px` }) } return item; }, pageLoadMode : "scrollBottom", onItemClick : function( e ) { options.component.option( "value", e.itemData.productHierarchyPath ); options.component.close(); }, searchEnabled : true, searchExpr : "productHierarchyPath", searchMode : "contains" }) return list; }, showClearButton : true, displayValueFormatter : function( itemData ) { let formattedDisplayValue = null; if( Array.isArray( itemData ) && itemData.length ) { let pathParts = itemData[0].split( "/" ); let prefix = ""; if( pathParts.length > 1 ) { prefix = ".../"; } formattedDisplayValue = `${prefix}${pathParts[pathParts.length-1]}`; } return formattedDisplayValue; }, placeholder : "Select Product" } }, { dataField : "productStatusNoSaleReasonId", label : { location : "left", text : "Not Buying Reason" }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { paginate : false, object : "CRM.noSaleReasons", keyField : "reasonId" } ), disabled : true, searchExpr : "reasonName", searchMode : "contains", displayExpr : "reasonName", multipleSelectedDisplay : "Multiple Not Buying Reasons Selected", keyExpr : "reasonId", title : "Select No Buying Reason" }) }, { dataField : "productStatusSourceCompetitorId", label : { location : "left", text : "From Competitor" }, editorType : "dxSelectBox", editorOptions : { dataSource : ! showMFR ? Fse.Data.newDataSource( { object : "CMP.competitorNames", keyField : "competitorId" } ) : null, valueExpr : "competitorId", disabled : true, displayExpr : "competitorName", keyExpr : "competitorId", showClearButton : true, searchEnabled : true, searchMode : "contains", searchExpr : "competitorName", placeholder : "Select Competitor" } }, { dataField : "productStatusSourceOther", label : { location : "left", text : "From Other" }, editorType : "dxSelectBox", editorOptions : { dataSource : ! showMFR ? Fse.Data.newDataSource( { object : "CMP.otherSources", keyField : "source" } ) : null, disabled : true, displayExpr : "source", valueExpr : "source", searchExpr : "source", searchMode : "contains", searchEnabled : true, // showDataBeforeSearch : false, // minSearchLength : 3, // usePopover : true, showClearButton : true, placeholder : "Select Other" } } ); if( Fse.Portal.appConfiguration.CRM.tastewiseEnabled == "true" ) { this.menuApplicabilityEnabledFieldConfig = { dataField : "menuApplicabilityEnabled", label : { text : "Enabled" }, editorType : "dxSwitch" }; this.menuApplicabilityReturnUnits = { dataField : "tastewiseReturnUnits", label : { text : "Include Units" }, editorType : "dxSwitch" } this.menuApplicabilityFieldConfig = { dataField : "productSetId", label : { text : "Menu Applicability" }, editorType : "dxSelectBox", editorOptions : { dataSource : Fse.Data.newDataSource( { object : "PRD.productSets", keyField : "productSetId", paginate : true }), showClearButton : true, placeholder : "All Products", displayExpr : "productSetName", valueExpr : "productSetId", disabled : true } } this.menuSearchFieldConfig = { dataField : "tastewiseMenuSearch", label : { text : "Menu Search"}, editorType : "dxTextBox", editorOptions : { showClearButton : true, placeholder : "keyword", disabled : true } } marketItems.push( { template : function() { return $("
").append( "Menu Insights Powered by Tastewise AI" ).css( { "text-align": "left", "font-weight" : "bold" } ) } }, this.menuApplicabilityEnabledFieldConfig, this.menuApplicabilityFieldConfig, this.menuSearchFieldConfig, this.menuApplicabilityReturnUnits // { // dataField : "tastewiseMenuSearch", // label : { text : "Menu Search" }, // editorType : "dxTextBox", // editorOptions : { showClearButton : true } // } ) } activateProductStatusFields = function() { let form = instance.dxBasicForm; let formData = form.option( "formData" ); let purchasingStatus = formData.productStatusPurchasingStatus; let mfrId = null; if( showMFR ) { let productStatusMfrIdDisabled = true; if( purchasingStatus ) { productStatusMfrIdDisabled = false; } if( productStatusMfrIdDisabled ) { form.updateData( { "productStatusMfrId": null } ); } form.getEditor( "productStatusMfrId" ).option( "disabled", productStatusMfrIdDisabled ) ; mfrId = formData.productStatusMfrId; if( ! mfrId ) { purchasingStatus = null; } } let fieldDefinitions = [ { dataField : "productStatusProductHierarchyPath", disabled : true }, { dataField : "productStatusSourceCompetitorId", disabled : true }, { dataField : "productStatusSourceOther", disabled : true }, { dataField : "productStatusNoSaleReasonId", disabled : true } ]; let updatedData = {}; fieldDefinitions.forEach( function( fd ) { fd.editor = form.getEditor( fd.dataField ); fd.mfr_id = fd.editor.option( "mfr_id" ); if( purchasingStatus ) { if( fd.dataField === "productStatusProductHierarchyPath" ) { fd.disabled = false; } else if ( purchasingStatus === "N" ) { fd.disabled = false; } } if( showMFR && fd.mfr_id != mfrId ) { if( fd.dataField === "productStatusProductHierarchyPath" ) { fd.dataSource = Fse.Data.newDataSource( { object : "PRD.productHierarchyPaths", keyField : "productHierarchyPath" } ); fd.dataSource.filter( [ "mfr_id", "=", mfrId ] ); } else if ( fd.dataField === "productStatusSourceCompetitorId" ) { fd.dataSource = Fse.Data.newDataSource( { object : "CMP.competitorNames", keyField : "competitorId" } ); fd.dataSource.filter( ["mfr_id", "=", mfrId ] ); } else if ( fd.dataField === "productStatusSourceOther" ) { fd.dataSource = Fse.Data.newDataSource( { object : "CMP.otherSources", keyField : "source" } ); fd.dataSource.filter( ["mfr_id", "=", mfrId ] ); } else if ( fd.dataField === "productStatusNoSaleReasonId" ) { // this is a multi select custom component and doesnt support changing the datasource and instead // uses a custom attribute called availableFilter fd.availableFilter = [["mfr_id", "=", mfrId ], "or", ["mfr_id", "is", "null" ]]; } } let editorOptions = { disabled : fd.disabled, mfr_id : mfrId } if( fd.availableFilter ) { editorOptions.availableFilter = fd.availableFilter; updatedData[fd.dataField] = null; } else if( fd.dataSource ) { editorOptions.dataSource = fd.dataSource, updatedData[fd.dataField] = null; } if( fd.disabled ) { updatedData[fd.dataField] = null; } fd.editor.option( editorOptions ); if( fd.dataSource ) { fd.editor.repaint(); } }) form.updateData( updatedData ); } instance.dxBasicForm = $("
").dxForm( { colCount : 4, items : [ { name : "left", itemType : "group", items : leftItems }, { name : "operator", itemType : "group", items : operatorItems }, { name : "market", itemType : "group", items : marketItems }, { name : "crm", itemType : "group", items : crmItems } ], onFieldDataChanged : function( e ) { switch ( e.dataField ) { case "productStatusMfrId" : { activateProductStatusFields(); } break; case "productStatusPurchasingStatus" : { activateProductStatusFields(); } break; case "menuApplicabilityEnabled" : { let productSetEditor = e.component.getEditor( "productSetId" ); let menuSearchEditor = e.component.getEditor( "tastewiseMenuSearch" ); let returnUnitsEditor = e.component.getEditor( "tastewiseReturnUnits" ); if( e.value ) { productSetEditor.option( { "disabled" : false } ) menuSearchEditor.option( { "disabled" : false } ) returnUnitsEditor.option( { "disabled" : false } ) } else { productSetEditor.option( { "disabled" : true, value : null } ) menuSearchEditor.option( { "disabled" : true, value : null } ) returnUnitsEditor.option( { "disabled" : true } ) } } case "withOpenTasks" : let tasksAssignedTo = e.component.getEditor( "tasksAssignedTo" ); if( e.value ) { tasksAssignedTo.option( "disabled", false ); } else { tasksAssignedTo.option( { "disabled" : true, "value" : null } ); } break; } } }).dxForm("instance"); this.popupPromise.notify( "createBasicForm" ) } OperatorSearch.prototype.createPopup = function( applyPromise ) { let instance = this; instance.popupPromise = $.Deferred(); instance.popupPromise.createBasicForm = false; instance.popupPromise.createFlexFieldForm = false; instance.popupPromise.progress( function( operation ) { instance.popupPromise[operation] = true; if( instance.popupPromise.createBasicForm && instance.popupPromise.createFlexFieldForm ) { instance.popupPromise.resolve(); } }); instance.createBasicForm(); instance.createFlexFieldForm(); // scrum 46030 - moved outside of dxPopup creation let bottomToolbarItems = [ { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "clear", onClick : function( e ) { instance.dxBasicForm.option( "formData", { includeSubTerritories : true } ); if( instance.dxFlexFieldForm ) { instance.dxFlexFieldForm.option( "formData", {} ); } } } }, { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "search", type : "default", onClick : function( e ) { let applySearch = instance.searchOptions.applySearch; let searchParams = instance.dxBasicForm.option( "formData" ); if( instance.dxFlexFieldForm ) { searchParams.flexFields = instance.dxFlexFieldForm.option( "formData" ); } instance.dxPopup.hide(); applySearch( searchParams ); if( applyPromise ) { applyPromise.resolve(); } } } } ]; // scrum 46030 if( Object.keys( this.activeFilterPreferences ).length ) { bottomToolbarItems.push( { toolbar : "bottom", location : "before", template : function() { let annotation = $("
").append( $("").addClass( "dx-field-item-label-text" ).append( "*filter preference active")).addClass( "fx-active-preference" ).css( { "cursor" : "pointer" } ); /* TODO: bring up the global preferences annotation.on( "click", function( e ) { // if the global filter preferences are applied, then close this popup let onSaveFilterPreferences = function() { widget.preferencesPopup.hide(); } widget.widgetOptions.dashboard.editFilterPreferences( onSaveFilterPreferences ); }) */ return annotation; } }) } instance.dxPopup = $("
").dxPopup( { title : `${getText( 'OPERATOR' )} Search`, width : "90vw", contentTemplate : function() { if( instance.dxFlexFieldForm ) { let tabs = $("
").dxTabPanel( { items : [ { title : "Basic", template : function() { let basic = $("
") basic.append( instance.dxBasicForm.element().css( "padding", "15px" )); return basic.dxScrollView( { height : '100%', xheight : 545 } ); // return instance.dxBasicForm.element(); } }, { title : "Custom", template : function() { let custom = $("
"); custom.append( instance.dxFlexFieldForm.element().css( "padding", "15px" ) ); return custom.dxScrollView( { height : "100%", xheight : 545 } ); } } ] }); return tabs; } else { return instance.dxBasicForm.element(); } }, toolbarItems : bottomToolbarItems, // on hidden added to cleanup ui objects - scrum 46030 onHidden : function( e ) { // clean up e.component.element().remove(); instance.dxBasicForm.dispose(); instance.dxBasicForm = null; instance.dxPopup.dispose(); instance.dxPopup = null; } }).appendTo( "body" ).dxPopup("instance"); return this.popupPromise; } // scrum 46030 OperatorSearch.prototype.show = function( searchParams, filterPreferences ) { let instance = this; instance.processFilterPreferences( filterPreferences, searchParams ); let applyPromise = $.Deferred(); instance.createPopup( applyPromise ).done( function() { if( searchParams ) { instance.dxBasicForm.updateData( searchParams ); if( searchParams.flexFields && instance.dxFlexFieldForm ) { instance.dxFlexFieldForm.updateData( searchParams.flexFields ) } } instance.dxPopup.show(); } ); return applyPromise; } // scrum 46030 OperatorSearch.prototype.getPreferenceableFilters = function() { // when the global filters are expressed with different variable names, they need to translated to this widgets variable names const preferenceableFilters = { // widgetVariableName : "globalFilterVariableName" territoryPath : "territoryPath", salesRepId : "salesRepId", budgetCategoryId : "budgetCategoryId", clientSegPath : "clientSegPath" } return preferenceableFilters; } // scrum 46030 OperatorSearch.prototype.processFilterPreferences = function( filterPreferencesIn, searchParamsIn ) { let filterPreferences = {} if( filterPreferencesIn ) { filterPreferences = $.extend( true, {}, filterPreferencesIn ); } let searchParams = {}; if( searchParamsIn ) { searchParams = $.extend( true, {}, searchParamsIn ); } this.activeFilterPreferences = {}; // when the global filters are expressed with different variable names, they need to translated to this widgets variable names let preferenceableFilters = this.getPreferenceableFilters(); for( let p in preferenceableFilters ) { let gp = p; // global filter param is the same name as widget param // apply translation - global filter param is not the same name as widget param if( preferenceableFilters[p] ) { gp = preferenceableFilters[p]; } // if the global filter preferences have the propery and it has a value, update the objectparams if( filterPreferences.hasOwnProperty( gp ) && filterPreferences[gp]) { if( searchParams[p] == null ) { this.activeFilterPreferences[p] = filterPreferences[gp]; } } } // console.log( "ACTIVE FILTER PREFERENCES" ); // console.log( this.activeFilterPreferences ); }