OperatorVoidMatrix = function( options ) { let instance = this; instance.dataGrid = null; instance.rootElement = null; instance.noDataMessage = "No Data"; instance.lowProfitabilityRankThreshold = parseInt( Fse.Portal.getConfiguration( "CRM.lowProfitabilityRankThreshold" )); instance.starDefinitions = { // "menuApplicability" : { icon : "dx-icon-taskcomplete", on : false, hint : "Menu Applicability" }, "stocked" : { icon : "dx-icon-check", on : false, hint : "Distributor Stocked" }, "approved" : { icon : "dx-icon-link", on : false, hint : "Approved" }, "territoryTop50" : { icon : "dx-icon-map", on : false, hint : "Territory Top 50" }, "segmentTop50" : { icon : "dx-icon-food ", on : false, hint : "Segment Top 50" }, "profitable" : { icon : "dx-icon-money", on : false, hint : "Highly Profitable" } }; options = options ? options : {}; instance.operatorId = options.operatorId; instance.initialSearchParams = { topCount : 25, noGPO : false, noCMC : false, focusProduct : instance.operatorId ? true : false, } instance.searchParams = $.extend( true, {}, instance.initialSearchParams ); instance._setVoids( [] ); instance.operatorDataStore = Fse.Data.newDataSource( { object : "CRM.operatorList", key : "operatorId" }).store(); } OperatorVoidMatrix.prototype.constructor = OperatorVoidMatrix; OperatorVoidMatrix.prototype._setVoids = function( voids ) { let instance = this; instance.selections = {}; instance.operatorData = {}; instance.purchasingPromises = {}; instance.opportunityData = {}; instance.operatorSummaryData = {}; instance.callButtons = {}; instance.voids = voids; } OperatorVoidMatrix.prototype._planCall = function( operatorKey ) { let instance = this; let skuIds = []; let operatorId = parseInt( operatorKey.split( "_" ).pop()); for( key in instance.selections ) { if( ! instance.selections[key] ) continue; let keyParts = key.split( "_" ); let skuId = parseInt( keyParts.pop() ); let trialOperatorKey = keyParts.join( "_" ); if( trialOperatorKey == operatorKey ) { skuIds.push( skuId ); } } // console.log( "SKUs", skuIds ); // alert( `Plan call for ${skuIds.length}`); Fse.CLOS.createAccountInteraction( operatorId, 'OPR', function(){}, 0, skuIds ); } OperatorVoidMatrix.prototype._activateCallButtons = function() { let instance = this; let operators = {}; for( key in instance.selections ) { if( ! instance.selections[key] ) continue; let keyParts = key.split( "_" ); keyParts.pop(); operators[keyParts.join( "_" )] = true; } console.log( "operators", operators ); for( let operatorKey in instance.callButtons ) { let buttonDisabled = true; if( operators[operatorKey] ) { buttonDisabled = false; } instance.callButtons[operatorKey].option( "disabled", buttonDisabled ) } } OperatorVoidMatrix.prototype.show = function() { let instance = this; let popup = $("
").dxPopup( { title : "Void Matrix", height : "90vh", width : "90vw", contentTemplate : function() { return instance.element(); }, onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); }, toolbarItems : [ { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Close", onClick : function( e ) { popup.hide(); } } } ] }).dxPopup( "instance" ); $("body").append( popup.element() ); popup.show(); } OperatorVoidMatrix.prototype.element = function() { let instance = this; if( instance.rootElement ) { return instance.rootElement; } instance.rootElement = $("
").addClass( "OperatorVoidMatrix").css( { "height" : "100%", "width" : "96vw" } ); instance.refresh(); return instance.rootElement; } OperatorVoidMatrix.prototype._showLoadPanel = function() { let instance = this; if( ! instance.loadPanel ) { instance.loadPanel = $("
").dxLoadPanel( { message : "Loading..." }).dxLoadPanel( "instance" ); $("body").append( instance.loadPanel.element() ); } instance.loadPanel.show(); } OperatorVoidMatrix.prototype._hideLoadPanel = function() { let instance = this; if( instance.loadPanel ) { instance.loadPanel.hide(); } } OperatorVoidMatrix.prototype.load = function() { let instance = this; //instance._showLoadPanel(); let lastSearchSeq = instance.searchSeq; instance.searchSeq = ( new Date() ).getTime(); // console.log( "SearchParams", instance.searchParams ); // console.log( "productFilter", instance._buildProductFilter() ); // console.log( "operatorFilter", instance._buildOperatorFilter() ); let objectParams = { productFilter : instance._buildProductFilter(), operatorFilter : instance._buildOperatorFilter(), topCount : instance.searchParams.topCount, resultOptions : {}, searchSeq : instance.searchSeq, lastSearchSeq : lastSearchSeq } if( objectParams.productFilter.length == 0 || objectParams.operatorFilter == 0 ) { instance.noDataMessage = "No search yet, choose your filters to see results." } else { instance.noDataMessage = "No Data"; } if( instance.searchParams.operatorListId ) { objectParams.operatorListId = instance.searchParams.operatorListId; } console.log( "objectParams", objectParams ); let matrixDataSource= Fse.Data.newDataSource( { object : "OPR.voidMatrix", key : "skuId", paginate : false, objectParams : objectParams } ); return matrixDataSource.load().done( function( voids ) { instance._setVoids( voids ); //instance._hideLoadPanel(); }); } OperatorVoidMatrix.prototype._loadColumnData = function( volumeIdentifier) { let instance = this; let objectParams = { searchSeq : instance.searchSeq, volumeIdentifier : volumeIdentifier } let matrixDataSource= Fse.Data.newDataSource( { object : "OPR.voidMatrix", key : "skuId", paginate : false, objectParams : objectParams } ); return matrixDataSource.load().done( function( data ) { let changes = []; let operatorSummaryData = { totalSKUs : data.length, totalVolume : 0, totalDollars : 0, buyingSKUs : 0, activeOppSKUs : 0, whitespaceSKUs : 0 } data.forEach( function( dataRow ) { let purchasingData = dataRow[volumeIdentifier]; if( purchasingData.purchasingStatus == "B" ) { operatorSummaryData.buyingSKUs ++; operatorSummaryData.totalVolume += purchasingData[purchasingData.uom]; operatorSummaryData.totalDollars += purchasingData.dollars; } if( purchasingData.lastOpportunityStatus == "A" ) { operatorSummaryData.activeOppSKUs ++; } if( !( purchasingData.purchasingStatus == "B" || purchasingData.lastOpportunityStatus == "A" )) { operatorSummaryData.whitespaceSKUs++; } let changeData = {}; changeData[volumeIdentifier] = dataRow[volumeIdentifier]; changes.push( { type : "update", data : changeData, key : dataRow.skuId }) }) // this doesn't work because an buying sku can also have an activity opportunity which would cause it to be countered twice, understating the number of whitespace opportunities // operatorSummaryData.whitespaceSKUs = operatorSummaryData.totalSKUs - ( operatorSummaryData.activeOppSKUs + operatorSummaryData.buyingSKUs ); instance.operatorSummaryData[volumeIdentifier] = operatorSummaryData; console.log( "operatorSummaryData", operatorSummaryData ); if( changes.length ) { let dataStore = instance.dataGrid.getDataSource().store(); dataStore.push( changes ); } }); } OperatorVoidMatrix.prototype._loadStats = function() { let instance = this; let objectParams = { stats : true, searchSeq : instance.searchSeq } let matrixDataSource= Fse.Data.newDataSource( { object : "OPR.voidMatrix", key : "skuId", paginate : false, objectParams : objectParams } ); return matrixDataSource.load().done( function( data ) { instance.stats = data[0]; }); } OperatorVoidMatrix.prototype._buildProductFilter = function() { let instance = this; let productFilter = []; if( Array.isArray( instance.searchParams.productSetTags )) { let productSetTagsFilter = []; instance.searchParams.productSetTags.forEach( function( pst ) { if( productSetTagsFilter.length ) productSetTagsFilter.push( "OR" ); productSetTagsFilter.push( [ "productSetTags", "contains", pst ] ) }) if( productSetTagsFilter.length ) { if( productFilter.length ) productFilter.push( "AND" ); productFilter.push( productSetTagsFilter ); } } if( Array.isArray( instance.searchParams.productHierarchyPath )) { let productHierarchyPathFilter = []; instance.searchParams.productHierarchyPath.forEach( function( php ) { if( productHierarchyPathFilter.length ) productHierarchyPathFilter.push( "OR" ); productHierarchyPathFilter.push( [ "productHierarchyPath", "startswith", php ] ) }) if( productHierarchyPathFilter.length ) { if( productFilter.length ) productFilter.push( "AND" ); productFilter.push( productHierarchyPathFilter ); } } if( instance.searchParams.focusProduct ) { if( productFilter.length ) productFilter.push( "AND" ); productFilter.push( [ "focusProduct", "=", "Y" ] ); } return productFilter; } OperatorVoidMatrix.prototype._buildOperatorFilter = function() { let instance = this; let operatorFilter = []; if( instance.operatorId ) { operatorFilter = [ "operatorId", "=", instance.operatorId ]; return operatorFilter; } if( Array.isArray( instance.searchParams.territoryPath )) { let filter = []; instance.searchParams.territoryPath.forEach( function( fv ) { if( filter.length ) filter.push( "OR" ); filter.push( [ "territoryPath", "startswith", fv ] ) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( Array.isArray( instance.searchParams.clientSegPath )) { let filter = []; instance.searchParams.clientSegPath.forEach( function( fv ) { if( filter.length ) filter.push( "OR" ); filter.push( [ "segmentPath", "startswith", fv ] ) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( Array.isArray( instance.searchParams.cdr_dstPath )) { let filter = []; instance.searchParams.cdr_dstPath.forEach( function( fv ) { if( filter.length ) filter.push( "OR" ); filter.push( [[ "distrib1_cdr_dstPath", "startswith", fv ], "OR", [ "distrib2_cdr_dstPath", "startswith", fv ]] ) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( Array.isArray( instance.searchParams.salesRepId )) { let filter = []; instance.searchParams.salesRepId.forEach( function( fv ) { if( filter.length ) filter.push( "OR" ); filter.push( [ "mfr_bsr_id", "=", fv ] ) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( Array.isArray( instance.searchParams.classificationId )) { let filter = []; instance.searchParams.classificationId.forEach( function( fv ) { if( filter.length ) filter.push( "OR" ); filter.push( [ "classificationId", "=", fv ] ) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( Array.isArray( instance.searchParams.priority )) { let filter = []; instance.searchParams.priority.forEach( function( fv ) { if( filter.length ) filter.push( "OR" ); filter.push( [ "priority", "=", fv ] ) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( Array.isArray( instance.searchParams.gpoId )) { let filter = []; instance.searchParams.gpoId.forEach( function( fv ) { if( filter.length ) filter.push( "OR" ); filter.push( [[ "gpoId_1", "=", fv ], "or", [ "gpoId_2", "=", fv ], "or", [ "gpoId_3", "=", fv ], "or", [ "gpoId_4", "=", fv ], "or", [ "gpoId_5", "=", fv ] ] ) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( instance.searchParams.noGPO ) { // only need to check the first field because when the first one is blank all of the others are also blank (ETL) let filter = [ "gpoId_1", "isblank" ]; if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } if( Array.isArray( instance.searchParams.cmcId )) { let filter = []; instance.searchParams.cmcId.forEach( function( fv ) { if( filter.length ) filter.push( "OR" ); filter.push( [[ "cmcId_1", "=", fv ], "or", [ "cmcId_2", "=", fv ], "or", [ "cmcId_3", "=", fv ] ] ) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( instance.searchParams.noCMC ) { // only need to check the first field because when the first one is blank all of the others are also blank (ETL) let filter = [ "cmcId_1", "isblank" ]; if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } if( instance.searchParams.displayCompanyType ) { let filter = []; let displayCompanyTypes = instance.searchParams.displayCompanyType; if( ! Array.isArray( displayCompanyTypes )) displayCompanyTypes = [displayCompanyTypes]; displayCompanyTypes.forEach( function( displayCompanyType ) { switch ( displayCompanyType ) { case "Chain HQ" : if( filter.length ) filter.push( "or" ); filter.push( [ "oprCompanyType", "=", '1' ] ); break; case "Independent" : if( filter.length ) filter.push( "or" ); filter.push( [[ "oprCompanyType", "=", '0' ], "and", [ "independentYN", "=", 1 ]] ); break; case "Unit" : if( filter.length ) filter.push( "or" ); filter.push( [[ "oprCompanyType", "=", '0' ], "and", [ "independentYN", "=", 0 ]] ); break; } }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } if( instance.searchParams.operatorId ) { let operatorIds = instance.searchParams.operatorId; if( ! Array.isArray( operatorIds )) operatorIds = [operatorIds]; let filter = []; operatorIds.forEach( function( operatorId ) { if( filter.length ) filter.push( "or" ); filter.push( [ "operatorId", "=", operatorId ]) }) if( filter.length ) { if( operatorFilter.length ) operatorFilter.push( "AND" ); operatorFilter.push( filter ); } } return operatorFilter; } OperatorVoidMatrix.prototype._updateSelectionCount = function() { let instance = this; let statsText3 = ""; let onClick = null; if( instance.stats.selectedCount ) { statsText3 = `${instance.stats.selectedCount} selected`; onClick = function( jqe ) { instance.showTargets(); } } if( instance.stats.selectedCount ) { instance.sendToObjectiveSelectBox.option( "disabled", false ); } else { instance.sendToObjectiveSelectBox.option( "disabled", true ); } let textElement = $("").text( statsText3 ).css( { "font-weight" : "normal" }) if( onClick ) { textElement.on( "click", onClick ); } instance.selectedCountElement.empty().append( textElement ); } OperatorVoidMatrix.prototype.showTargets = function() { let instance = this; // let objectParams = { // searchSeq : instance.searchSeq, // picker : { // mode : selected ? 1 : 0, // skuId : skuId, // volumeIdentifier : volumeIdentifier // } // } let targetsDataSource = Fse.Data.newDataSource( { object : "OPR.voidMatrix", objectParams : { searchSeq : instance.searchSeq, targets : true } }) let popup = $("
").dxPopup( { title : "Current Selections", hideOnOutsideClick : true, height : "50vh", width : "75vw", toolbarItems: [ { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Close", type : "default", onClick : function( e ) { popup.hide(); } }} ], contentTemplate : function() { return $("
").dxDataGrid( { height : "100%", scrolling : { mode : "virtual" } , showBorders : true, rowAlternationEnabled : true, dataSource : targetsDataSource, onToolbarPreparing : function( e ) { if( ! e.toolbarOptions.items ) e.toolbarOptions.items = []; e.toolbarOptions.items.push( { location : "after", widget : "dxButton", options : { hint : "Export Voids", icon : "export", onClick : function( ee ) { Fse.UI.DataGridHelper.exportDataGrid( { dataGrid : e.component, fileName : "voids.xlsx" } ); } } }) }, columns : [ { dataField : "territoryName", caption : "Territory", width : "auto" }, { dataField : "primaryManagerFullName", caption : "Primary Manager", width : "auto" }, { dataField : "companyName", caption : "Account", width : "auto" }, { dataField : "salesRepFullName", caption : "Account Manager", width : "auto" }, { dataField : "sku", caption : "SKU", width : "auto" }, { dataField : "skuDesc", caption : "Description" } ] }) } }).appendTo( $("body") ).dxPopup( "instance" ); popup.show(); } OperatorVoidMatrix.prototype.refresh = function() { let instance = this; instance._showLoadPanel(); instance.rootElement.empty(); instance.lastPickFormData = null; instance.load().done( function() { instance._loadStats().done( function() { instance.createBreadcrumbs(); instance.createDataGrid(); console.log( "Stats", instance.stats ); // let statsBaseCSS = { // "margin-bottom" : "8px", // "border" : "1px solid", // "border-top-width" : "8px", // "padding" : "8px", // "height" : "100%", // }; let box = $("
").dxBox( { direction : "col", height : "100%", items : [ { baseSize : 80, box : { direction : "row", items : [ { ratio : 1, template : function() { // let statsText = "stats 1"; let statsElement = $("
").css( { "margin-right" : "10px" } ).addClass( ["fx-void-matrix-stats", "dx-theme-border-color" ]); let statsText1 = DevExpress.localization.formatNumber( instance.stats.voidCount, "fixedPoint" ); let statsText2 = DevExpress.localization.formatNumber( instance.stats.whitespace, "percent" ); // let statsText3 = ""; // if( instance.stats.selectedCount ) { // statsText3 = ` ${instance.stats.selectedCount} selected`; // } // instance.selectedCountElement = $("").text( `${statsText3}` ).css( { "font-size" : "10px", "cursor": "pointer", "text-decoration" : "underline" }); statsElement .append( $("
").addClass( "fx-void-matrix-stat-heading").text( "Total Whitespace Opportunities" )) .append( $("
").addClass( "fx-void-matrix-stat-value" ) .append( $("").text( statsText1 ) ) .append( $("").text( `(${statsText2})` ) ) // .append( instance.selectedCountElement ) ) return statsElement; } }, { ratio : 1, template : function() { let statsText1 = DevExpress.localization.formatNumber( instance.stats.activeOpportunities, "fixedPoint" ); let clientUOM = Fse.Portal.getConfiguration( "CRM.defaultUnitOfMeasure" ); let opportunityVolume = instance.stats.activeCases; if( clientUOM == "lbs" ) { opportunityVolume = instance.stats.activeLbs; } let statsText2 = DevExpress.localization.formatNumber( opportunityVolume, "fixedPoint" ); let statsElement = $("
").css( { "margin-right" : "10px" } ).addClass( ["fx-void-matrix-stats", "dx-theme-border-color" ]); statsElement .append( $("
").addClass( "fx-void-matrix-stat-heading").text( "Active Opportunities" )) .append( $("
").addClass( "fx-void-matrix-stat-value" ) .append( $("").text( statsText1 ) ) .append( $("").text( `(${statsText2} ${clientUOM})` ) ) ) return statsElement; } }, { ratio : 1, template : function() { let statsText1 = DevExpress.localization.formatNumber( instance.stats.coverage, "percent" ); let statsElement = $("
").css( { "margin-right" : "10px" } ).addClass( ["fx-void-matrix-stats", "dx-theme-border-color" ]); statsElement .append( $("
").addClass( "fx-void-matrix-stat-heading").text( "Average SKU Coverage" )) .append( $("
").addClass( "fx-void-matrix-stat-value" ) .append( $("").text( statsText1 ) ) ) return statsElement; } }, { ratio : 1, template : function() { let noVoidCount = DevExpress.localization.formatNumber( instance.stats.noVoidOperatorCount, "fixedPoint" ); let operatorCount = DevExpress.localization.formatNumber( instance.stats.operatorCount, "fixedPoint" ); let statsText1 = `${noVoidCount}/${operatorCount}`; let statsElement = $("
").addClass( ["fx-void-matrix-stats", "dx-theme-border-color" ]); statsElement .append( $("
").addClass( "fx-void-matrix-stat-heading").text( "Operators with No Voids" )) .append( $("
").addClass( "fx-void-matrix-stat-value" ) .append( $("").text( statsText1 ) ) ) return statsElement; } } ] } }, { baseSize : 43, template : function() { instance.breadcrumbs.update( instance.searchParams ); return $("
").append( instance.breadcrumbs.element() ); } }, { ratio : 1, template : function() { return instance.dataGrid.element(); } } ] }) instance.rootElement.append( box ); instance._hideLoadPanel(); }); }) } OperatorVoidMatrix.prototype._operatorHeaderCellTemplate = function( container, options ) { let instance = this; let dataReady = $.Deferred(); let columnDef = options.column; // let operatorData = instance.dataGrid.columnOption( columnDef.dataField, "operatorData" ); let operatorData = instance.operatorData[columnDef.dataField]; if( ! operatorData ) { let operatorId = parseInt( columnDef.dataField.split( "_" )[1]); instance.operatorDataStore.byKey( operatorId ).done( function( data ) { operatorData = data; // instance.dataGrid.columnOption( columnDef.dataField, "operatorData", operatorData ) instance.operatorData[columnDef.dataField] = operatorData; // columnDef.operatorData = operatorData; dataReady.resolve(); }) } else { dataReady.resolve(); } dataReady.done( function() { let box = $("
").dxBox( { direction : "row", width : 220, items : [ { ratio : 1, template : function() { let companyNameElement = $("
").css( { "width" : "175px", "font-weight" : "bold", "overflow" : "hidden", "white-space" : "nowrap", "padding-right" : "10px", "margin-top" : "5px" } ).text( operatorData.companyName ); // .attr( { "title" : operatorData.companyName }); companyNameElement .on( "mouseenter", function( jqe ) { let tooltip = instance._cellTooltip(); tooltip.option( { "dataType" : "operator", "operatorSummaryData" : instance.operatorSummaryData[columnDef.dataField], "operatorData" : instance.operatorData[columnDef.dataField] } ) tooltip.show( jqe.target ); }) .on( "mouseout", function( jqe ) { instance._cellTooltip().hide(); }) return companyNameElement } }, { baseSize : 45, template : function() { let buttons = $("
").css( { "text-align" : "right" } ).addClass( "fx-void-matrix-header-buttons" ); buttons.append( $("
").dxButton( { "icon" : "user", "hint" : "Operator Profile", stylingMode : "text", onClick : function( e ) { OperatorProfile.openPopupEditor( parseInt( columnDef.dataField.split( "_" ).pop() ) ); } })); let callButton = $("
").css({ "font-size" : "18px" } ).dxButton({ icon : "tel", hint : "Plan Sales Call", onClick : function( e ) { instance._planCall( columnDef.dataField ); }, stylingMode : "text", disabled : true, }).dxButton( "instance" ); instance.callButtons[columnDef.dataField] = callButton; buttons.append( callButton.element() ); return buttons; } } ] }) container.append( box ); }) } OperatorVoidMatrix.prototype._cellTooltip = function() { let instance = this; if( instance.cellTooltip ) return instance.cellTooltip; instance.cellTooltip = $("
").dxTooltip( { hideOnOutsideClick : true, hideOnParentScroll : true, width : "auto", contentTemplate : function( content ) { content.append( $("

").text( `Loading` ) ) }, onShowing : function( tte ) { let content = tte.component.content(); content.empty(); let dataType = tte.component.option( "dataType" ); let clientUOM = Fse.Portal.getConfiguration( "CRM.defaultUnitOfMeasure" ); if( dataType == "purchasingData" ) { let purchasingData = tte.component.option( "purchasingData" ); content.append( $("

").css( { "font-weight" : "bold", "text-align" : "left", "margin-bottom" : "5px", "font-size" : "larger" } ).text( "Confirmed Purchasing" ) ); let purchasingElement = $("
").addClass( "fx-void-matrix-purchasing-tooltip") // .css( { "text-align" : "left", "display" : "grid", "grid-template-columns" : "100px 100px" }) .append( $("
").text( "Rolling 12M Purchasing" )) .append( $("
").text( DevExpress.localization.formatNumber( purchasingData[purchasingData.uom], "fixedPoint" ) + ` ${purchasingData.uom}` )) .append( $("
").text( "Distributor Last Purchase" )) .append( $("
").text( purchasingData.lastPurchaseDst ? purchasingData.lastPurchaseDst : '' )).css( { "overflow" : "hidden" } ) .append( $("
").text( "Last Purchase Month" )) .append( $("
").text( DevExpress.localization.formatDate( new Date( purchasingData.lastPurchaseMonth ), "monthAndYear" ) )) .append( $("
").text( "Last Purchase Quantity" )) .append( $("
").text( DevExpress.localization.formatNumber( purchasingData.lastPurchaseAmt, "fixedPoint" ) + ` ${purchasingData.uom}` )); content.append( purchasingElement ); } else if( dataType == "opportunity" ) { let opportunity = tte.component.option( "opportunityData" ); let opportunityElement = $("
").addClass( "fx-void-matrix-opportunity-tooltip") // .css( { "text-align" : "left", "display" : "grid", "grid-template-columns" : "100px 100px" }) .append( $("
").text( "Annual Volume" )) .append( $("
").text( DevExpress.localization.formatNumber( opportunity[clientUOM], "fixedPoint" ) + ` ${clientUOM}` )) .append( $("
").text( "Est. Order Date" )) .append( $("
").text( DevExpress.localization.formatDate( new Date( opportunity.estOrderDate ), "shortDate" ) )) .append( $("
").text( "Sales Rep")) .append( $("
").text( opportunity.effectiveRepFullName )) .append( $("
").text( "Stage")) .append( $("
").text( opportunity.stageNameFull )); if( opportunity.statusCode == "R" ) { opportunityElement .append( $("
").text( "No Sale Reason")) .append( $("
").text( opportunity.noSaleGeneralReason )); } let tooltipTitle = null; if( opportunity.statusCode == "A" ) { tooltipTitle = "Active Opportunity" } if( opportunity.statusCode == "R" ) { tooltipTitle = "No Sale Opportunity" } if( opportunity.statusCode == "C" ) { tooltipTitle = "Sold Opportunity" } if( tooltipTitle ) content.append( $("
").css( { "font-weight" : "bold", "text-align" : "left", "margin-bottom" : "5px", "font-size" : "larger" } ).text( tooltipTitle ) ) content.append( opportunityElement ); } else { let operatorSummaryData = tte.component.option( "operatorSummaryData" ); let operatorData = tte.component.option( "operatorData" ); let operatorElement = $("
").addClass( "fx-void-matrix-operator-tooltip" ) // .css( { "text-align" : "left", "display" : "grid", "grid-template-columns" : "150px 100px" }); if( operatorData ) { if( operatorData.distrib1_cdr_dstName ) { operatorElement .append( $("
").text( "Primary Dist" )) .append( $("
").text( operatorData.distrib1_cdr_dstName )) } if( operatorData.distrib2_cdr_dstName ) { operatorElement .append( $("
").text( "Secondary Dist" )) .append( $("
").text( operatorData.distrib2_cdr_dstName )) } } operatorElement .append( $("
").text( "SKUs Purchased" )) .append( $("
").text( `${operatorSummaryData.buyingSKUs}/${operatorSummaryData.totalSKUs}` )) // .append( $("
").text( "Annual Purchasing $" )) // .append( $("
").text( DevExpress.localization.formatNumber( operatorSummaryData.totalDollars, "fixedPoint" ) )) .append( $("
").text( "Rolling 12M Confirmed Vol." )) // was Annual Volume .append( $("
").text( DevExpress.localization.formatNumber( operatorSummaryData.totalVolume, "fixedPoint" ) + ` ${clientUOM}`)) .append( $("
").text( "Active Opportunities" )) .append( $("
").text( DevExpress.localization.formatNumber( operatorSummaryData.activeOppSKUs, "fixedPoint" ) )) .append( $("
").text( "Whitespace Opportunities" )) .append( $("
").text( DevExpress.localization.formatNumber( operatorSummaryData.whitespaceSKUs, "fixedPoint" ) )) content.append( operatorElement ); } tte.component.repaint(); } }).dxTooltip( "instance" ); $("body").append( instance.cellTooltip.element() ); return instance.cellTooltip; } OperatorVoidMatrix.prototype._purchasingVoidCellTemplate = function( container, options ) { let instance = this; let volumeQtyField = options.column.dataField; let columnDataPromise = instance.purchasingPromises[volumeQtyField]; if( ! columnDataPromise ) { columnDataPromise = instance._loadColumnData( volumeQtyField ); instance.purchasingPromises[volumeQtyField] = columnDataPromise; } columnDataPromise.done( function() { let purchasingData = options.data[volumeQtyField]; let profitabilityRank = options.data.profitabilityRank; const buyingColor = "#CFe6C1"; const activeOpportunityColor = "#B3B3FF"; const opportunityDataKey = `${options.column.dataField}_${options.data.skuId}`; let containerCSS = {}; let box = $("
").dxBox( { direction : "row", width : "100%", height : 54, items : [ { ratio : 1, template : function() { if( ! purchasingData ) return $("
"); let display = $("
").addClass( "fx-void-matrix-cell" ).css( { "padding-left" : "8px" }); if( purchasingData.purchasingStatus != 'B' && purchasingData.lastOpportunityStatus != 'A' ) { // !purchasingData.activeOpportunities let starDefinitions = $.extend( true, {}, instance.starDefinitions ); let starCount = 0; let starExplain = []; if( purchasingData.stockingStatus == "Y" ) { starCount++; starExplain.push( "Distributor Stocked" ); starDefinitions["stocked"].on = true; // display.append( $("").text( "stocked" ).css( { "padding-left" : "1em" } )) } if( purchasingData.memberGroupApproved == "Y" ) { starCount++; starExplain.push( "Approved" ); starDefinitions["approved"].on = true; // display.append( $("").text( "approved" ).css( { "padding-left" : "1em" } )) } if( purchasingData.segmentTopSKU ) { starCount++; starDefinitions["segmentTop50"].on = true; starExplain.push( "Segment Top 50" ); } if( purchasingData.territoryTopSKU ) { starCount++; starDefinitions["territoryTop50"].on = true; starExplain.push( "Territory Top 50" ); } if( profitabilityRank > instance.lowProfitabilityRankThreshold ) { starCount++; starDefinitions["profitable"].on = true; starExplain.push( "Highly Profitable" ); } let starsSpan = $("").addClass( "fx-void-matrix-stars" ).attr( { "title" : starExplain.join( ", " )}); for( starId in starDefinitions) { let star = starDefinitions[starId]; let starIcon = $("") .addClass( star.icon ) .attr( "title", star.hint ); if( star.on ) { starIcon.addClass( "fx-void-matrix-star-on" ); } starsSpan.append( starIcon ); } display.append( starsSpan ); if( starCount ){ starsSpan.addClass( "fx-void-matrix-1fs-recommended" ); } } if( purchasingData.purchasingStatus == "B" && purchasingData[purchasingData.uom] != null ) { let annualVolume = purchasingData[purchasingData.uom]; annualVolumeDisplay = DevExpress.localization.formatNumber( annualVolume, { type : "fixedPoint", precision : 0 } ); buyingIndicator = $("").text( `${annualVolumeDisplay} ${purchasingData.uom}` ).addClass( "fx-void-matrix-volume" ) display.append( buyingIndicator ); buyingIndicator .on( "mouseenter", function( jqe ) { let tooltip = instance._cellTooltip(); tooltip.option( { "purchasingData": purchasingData, "dataType" : "purchasingData" }); tooltip.show( jqe.target ); }) .on( "mouseout", function( jqe ) { instance._cellTooltip().hide(); }) containerCSS["background-color"] = buyingColor; } let opportunityIndicator = null; if( purchasingData.lastOpportunityStatus == "C" ) { // display.append( $("").addClass( "fx-void-matrix-opp-status" ).text( "Sale" )); opportunityIndicator = $("").addClass( "fx-void-matrix-opp-status" ).text( "Sale" ); } if( purchasingData.lastOpportunityStatus == "R" ) { // display.append( $("").addClass( "fx-void-matrix-opp-status" ).text( "No Sale" )); opportunityIndicator = $("").addClass( "fx-void-matrix-opp-status" ).text( "No Sale" ); } if( purchasingData.lastOpportunityStatus == "A" ) { // display.append( $("").addClass( "fx-void-matrix-opp-status" ).text( "Active" )); opportunityIndicator = $("").addClass( "fx-void-matrix-opp-status" ).text( "Active" ); // don't overwrite active color if set if( ! containerCSS["background-color"] ) containerCSS["background-color"] = activeOpportunityColor; } if( opportunityIndicator ) { display.append( opportunityIndicator ); opportunityIndicator .on( "mouseenter", function( jqe ) { let opportunityDataReady = $.Deferred(); if( !instance.opportunityData[opportunityDataKey ]) { // if( ! instance.opportunityDataSource ) { // instance.opportunityDataSource = Fse.Data.newDataSource( { object: "SPL.opportunities", paginate : false, key : "opportunityId" }); // } // let opportunityFilter = [ // [ "partnerType", "=", "OPR" ], // [ "partnerId", "=", purchasingData.operatorId ], // [ "skuId", "=", purchasingData.skuId ], // [ "statusCode", "=", purchasingData.lastOpportunityStatus ] // ]; // console.log( "opportunityFilter", opportunityFilter ); // instance.opportunityDataSource.filter( opportunityFilter ); // instance.opportunityDataSource.load().done( function( opportunities ) { // instance.opportunityData[opportunityDataKey] = opportunities[0]; // opportunityDataReady.resolve(); // }) instance.opportunityData[opportunityDataKey] = purchasingData.lastOpportunity; opportunityDataReady.resolve(); } else { opportunityDataReady.resolve(); } opportunityDataReady.done( function() { let tooltip = instance._cellTooltip(); tooltip.option( { "opportunityData": instance.opportunityData[opportunityDataKey], "dataType" : "opportunity" }); tooltip.show( jqe.target ); }) }) .on( "mouseout", function( jqe ) { instance._cellTooltip().hide(); }) } return display; } }, { baseSize : 30, template : function() { if( ! purchasingData || ( purchasingData.purchasingStatus != 'B' && purchasingData.lastOpportunityStatus != 'A' ) ) { let selectionKey = `${volumeQtyField}_${options.data.skuId}`; instance.selections[selectionKey] = purchasingData.selected ? true : false; let display = $("
").addClass( "fx-void-matrix-cell" ); display.append( $("
").dxCheckBox({ // value : instance.selections[selectionKey] ? true : false, value : purchasingData.selected ? true : false, onValueChanged : function( e ) { instance._select( options.data.skuId, volumeQtyField, e.value ) } })); return display; } else { return $("
"); } } } ] }); container.append( box.css( containerCSS ) ).addClass( "fx-void-matrix-intersection" ); }) } OperatorVoidMatrix.prototype.createDataGrid = function() { let instance = this; const operatorCellBackgroundColor = "#EEF0F2"; const skuCellBackgroundColor = "#FAFAFA"; let columns = [ { fixed : true, width : 320, dataField : "sku", caption : "SKU", cellTemplate : function( container, options ) { let outer = $("
").css( { "display" : "flex", "align-items" : "center", "height" : "55px", "overflow" : "hidden" }) $("
") .appendTo( outer ) .append( $("
").css( { "font-family" : "Telus Font Bold", "color" : "#2A2B30" } ).text( options.data.sku ) ) .append( $("
").css( { "xmax-height" : "38px", "color" : "#565A5F", "xoverflow" : "hidden", "xwhite-space" : "nowrap", "padding-right" : "8px" }).text( options.data.skuDesc ).attr( { "title" : options.data.skuDesc } ) ) container.append( outer ); }, headerCellTemplate : function( container, options ) { container.append( $("
").css( { "font-weight" : "bold", "margin-top" : "5px" } ).text( options.column.caption) ); } }] if( instance.voids.length ) { for( dataField in instance.voids[0] ) { if( ! dataField.match( /^OPR/ ) ) continue; columns.push( { dataField : dataField, caption : dataField, width : 230, alignment : "left", allowSorting : false, headerCellTemplate : function( container, options ) { instance._operatorHeaderCellTemplate( container, options ) }, cellTemplate : function( container, options ) { instance._purchasingVoidCellTemplate( container, options ) } }) } } instance.dataGrid = $("
").dxDataGrid( { height : "100%", width : "100%", showBorders : true, showRowLines : true, wordWrapEnabled : true, dataSource :{ store : { type : "array", data : instance.voids, key : "skuId" }}, columns : columns, scrolling : { mode : "virtual", columnRenderingMode: 'virtual' }, noDataText : instance.noDataMessage, onCellPrepared: function(e) { if (e.rowType === 'header' && e.column.dataField.match( /^OPR/ )) { e.cellElement.css( "background-color", operatorCellBackgroundColor ); } if (e.rowType === 'data' && e.column.dataField.match( /^OPR/ )) { e.cellElement.css( { "padding-left" : "10px !important", "padding-right" : "1px !important", "padding-top" : "1px !important", "padding-bottom" : "1px !important" }); } if( e.rowType === "data" && e.column.dataField == "sku" ){ e.cellElement.css( { "background-color" : skuCellBackgroundColor } ); } }, onContextMenuPreparing : function( e ) { if( e.row.rowType != "data" ) return; if( ! e.items ) e.items = []; let items = e.items; items.push( { skuId : e.row.data.skuId, text : "View SKU Details", onItemClick : function( e ) { let skuId = e.itemData.skuId; let ppsdv = null; let skuDetailPopup = $("
").dxPopup( { title : "SKU Details", height : "75vh", width : "75vw", contentTemplate : function( e ) { ppsdv = new ProductPickerSKUDetailView( { skuId : skuId } ); return ppsdv.element(); }, hideOnOutsideClick : true, onShown : function( e ) { // ppsdv.refresh(); }, onHidden : function( e ){ e.component.element().remove(); e.component.dispose(); } }).dxPopup("instance"); skuDetailPopup.element().appendTo( $("body") ); skuDetailPopup.show(); } }) }, onToolbarPreparing : function( e ) { if( ! e.toolbarOptions.items ) e.toolbarOptions.items = []; let toolbarItems = e.toolbarOptions.items; if( Fse.Portal.checkPermission( "BCRMObjectiveManagementAdmin" )) { toolbarItems.push( { location : "before", template : function() { instance.bulkSelectButton = $("
").dxButton({ icon : "check", hint : "Bulk Select/Deselect operations", disabled : instance.voids && instance.voids.length ? false : true, onClick : function( e ) { instance.showBulkSelect(); } }).dxButton( "instance" ); return instance.bulkSelectButton.element(); } }, { location : "before", template : function() { instance.selectedCountElement = $("").css( { "font-size" : "10px", "cursor": "pointer", "text-decoration" : "underline" }); return instance.selectedCountElement; } }, { location : "before", template : function() { instance.sendToObjectiveSelectBox = $("
").dxSelectBox( { placeholder : "Send to objective", disabled : true, width : 400, searchEnabled : true, showClearButton : true, searchExpr : "objName", dataSource : Fse.Data.newDataSource( { object : "BOM.objectives", key : "objectiveId", filter : [[ "objLevel", "=", "P"], "or", ["objLevel", "=", "S" ], ["targetType", "=", "OPR"], ["ready", "=", "Y"], ["status", "!=", "Past"]] }), displayExpr : "objName", valueExpr : "objectiveId", onSelectionChanged : function( e ) { if( e.selectedItem ) { instance._sendToObjective( e.selectedItem, false ); // false for preview } } }).dxSelectBox( "instance" ); return instance.sendToObjectiveSelectBox.element(); } } ); } let savedSearchSettingName = "OperatorVoidMatrix.savedSearches"; if( instance.operatorId ) { savedSearchSettingName = "OperatorVoidMatrix.operatorSavedSearches"; } instance.savedSearchManager = new SavedSearchManager( { name : savedSearchSettingName, getSearchState : function() { return $.extend( true, {}, instance.searchParams ) }, applySearch : function( savedSearch ) { if( savedSearch ) { instance.searchParams = savedSearch; instance.refresh(); } }, clearSearch : function() { instance._resetAll(); } }) toolbarItems.push( { location : "after", template : function() { return instance.savedSearchManager.element(); } }) toolbarItems.push( { location : "after", widget : "dxButton", options : { icon : "filter", onClick : function( e ) { instance.showFilters(); } } }, { location : "after", widget : "dxButton", options : { type : "normal", icon :"help", hint : "View Help", onClick : function( e ) { Fse.Portal.showQuickHelp( "OperatorVoidMatrix" ); } } } ) } }).dxDataGrid("instance"); } OperatorVoidMatrix.prototype.showFilters = function() { let instance = this; let ovms = new OperatorVoidMatrixSearch( { showOperatorFilters : instance.operatorId ? false : true, applySearch : function( searchParams ) { instance.searchParams = searchParams; instance.refresh(); } } ); ovms.show( instance.searchParams ); } OperatorVoidMatrix.prototype.showBulkSelect = function() { let instance = this; if( ! instance.lastPickFormData ) instance.lastPickFormData = {}; let starItems = []; let formData = { excludeNoSale : false, excludeSale : false } for( starField in instance.starDefinitions ) { let starDef = instance.starDefinitions[starField]; let starItem = { dataField : starField, label : { text : starDef.hint, icon : starDef.icon }, editorType : "dxCheckBox" } formData[starField] = false; starItems.push( starField ); } for( dataField in formData ) { if( instance.lastPickFormData[dataField]) formData[dataField] = instance.lastPickFormData[dataField]; } let popup = null; let selectButton = $("
").dxButton( { text : "Select", type : "default", disabled : true, onClick : function( e ) { popup.hide(); instance._applyBulkSelection( 1, pickerForm.option( "formData" )) } }).dxButton( "instance" ); // let deselectButton = $("
").dxButton( { // text : "Deselect", // disabled : true, // onClick : function( e ) { // popup.hide(); // instance._applyBulkSelection( 0, pickerForm.option( "formData" )) // } // }).dxButton( "instance" ); let pickerForm = $("
").dxForm( { colCount : 2, formData : formData, items : [ { itemType : "group", items : starItems }, { itemType : "group", items : [ { dataField : "excludeSale", label : { text : "Exclude Sale" }, editorType : "dxCheckBox" }, { dataField : "excludeNoSale", label : { text : "Exclude No Sale" }, editorType : "dxCheckBox" } ] } ], onFieldDataChanged : function( e ) { let data = e.component.option( "formData" ); let disabled = true; for( starField in instance.starDefinitions ) { if( data[starField] ) { disabled = false; break; } } selectButton.option( "disabled", disabled ); // deselectButton.option( "disabled", disabled ); e.component.getEditor( "excludeSale" ).option( "disabled", disabled ); e.component.getEditor( "excludeNoSale" ).option( "disabled", disabled ); } }).dxForm( "instance" ); popup = $("
").dxPopup( { width : 500, height : "auto", title : "Picker Popup", contentTemplate : function() { return pickerForm.element(); }, toolbarItems : [ { location : "after", toolbar : "bottom", widget : "dxButton", options : { text : "Clear All", onClick : function( e ) { popup.hide(); instance._applyBulkSelection( -1, pickerForm.option( "formData" )) } } }, // { // location : "after", // toolbar : "bottom", // template : function() { // return deselectButton.element(); // } // }, { location : "after", toolbar : "bottom", template : function() { return selectButton.element(); } } ], onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); } }).appendTo( $("body") ).dxPopup( "instance" ); popup.show(); } OperatorVoidMatrix.prototype._sendToObjective = function( objective, commit ) { let instance = this; let loadMessage = `Analyzing...`; if( commit ) { loadMessage = `Updating...`; } let loadPanel = $("
").dxLoadPanel( { message : loadMessage, onHidden : function( e ) { e.component.element().remove(); } }).appendTo( $("body")).dxLoadPanel( "instance" ); loadPanel.show(); let preview = ! commit; let dataToSend = { objectiveId : objective.objectiveId, searchSeq : instance.searchSeq, preview : preview }; return Fse.Ajax.performAction( { object : "OPR.voidMatrixSendToObjective", data : dataToSend }).done( function( result ) { console.log( result ); loadPanel.hide(); if( preview ) { instance._previewSendToObjectiveResults( objective, result.targets ); } else { Fse.UI.toast( `Targets successfully added to ${objective.objName}`, "success", 2000 ); } }).fail( function() { Fse.UI.toast( `Failed Send to Objective: ${objective.objName}`, "error", 2000 ); // alert( `Failed Send to Objective: ${objective.objectiveId}: ${objective.objName}`) }) } OperatorVoidMatrix.prototype._previewSendToObjectiveResults = function( objective, data ) { let instance = this; let allowAddToObjective = false; data.forEach( function( t ) { if( t.targetStatus == "OKAY" ) allowAddToObjective = true; }) let popup = $("
").dxPopup( { title : `Send To Objective: ${objective.objName}`, hideOnOutsideClick : true, height : "80vh", width : "80vw", toolbarItems: [ // { toolbar : "bottom", location : "after", widget : "dxButton", options : { // text : "Close", // onClick : function( e ) { // popup.hide(); // } // }}, { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Add to Objective", disabled : allowAddToObjective ? false : true, type : "default", onClick : function( e ) { popup.hide(); instance._sendToObjective( objective, true ); // true = commit } }}, ], contentTemplate : function() { return $("
").dxDataGrid( { height : "100%", scrolling : { mode : "virtual" } , showBorders : true, rowAlternationEnabled : true, grouping : { autoExpandAll : false }, dataSource :{ store : { type : "array", data : data, key : "voidMatrixTargetId" }}, columns : [ { dataField : "targetStatus", groupIndex : 0, dataType : "number" }, { dataField : "companyName", caption : "Operator", width : 200 }, { dataField : "staffFullName", caption : "Staff Member", width : 150 }, { dataField : "skuFull", caption : "SKU" }, { name : "issues", caption : "Reason", width : 250, calculateDisplayValue : function( data ) { let value = null; if( data.targetStatus == "SKIP" ) { let reasons = []; if( ! data.objectiveId ) { reasons.push( "No Matching Objective" ) } else if ( data.existingObjectiveTarget == "Y" && data.existingSKU == "Y" ) { reasons.push( "Existing Target & SKU" ); } else if ( data.existingObjectiveTarget == "Y" && ! data.existingTargetInteractionId ) { reasons.push( "Existing Target with no Open Calls" ); } else { if( data.productRestriction == "FAIL" ) reasons.push( "Non-eligible SKU" ); if( data.distributorRestriction == "FAIL" ) reasons.push( "Non-eligible Distributor" ); if( data.segmentRestriction == "FAIL" ) reasons.push( "Non-eligible Segment" ); if( data.memberGroupRestriction == "FAIL" ) reasons.push( "Non-eligible Member Group" ); if( data.memberGroupRestriction == "FAIL" ) reasons.push( "Non-eligible Member Group" ); if( data.classificationRestriction == "FAIL" ) reasons.push( "Non-eligible Classification" ); if( data.priorityRestriction == "FAIL" ) reasons.push( "Non-eligible Priority" ); } value = reasons.join( ", " ); } else { if( data.existingObjectiveTarget == "Y" ) { value = "Existing Target new SKU"; } } return value; }} // "productRestriction", "distributorRestriction", "segmentRestriction", "memberGroupRestriction", "classificationRestriction", "priorityRestriction" ] }) } }).appendTo( $("body") ).dxPopup( "instance" ); popup.show(); } OperatorVoidMatrix.prototype._select = function( skuId, volumeIdentifier, selected ) { let instance = this; let objectParams = { searchSeq : instance.searchSeq, picker : { mode : selected ? 1 : 0, skuId : skuId, volumeIdentifier : volumeIdentifier } } let matrixDataSource= Fse.Data.newDataSource( { object : "OPR.voidMatrix", key : "skuId", paginate : false, objectParams : objectParams } ); return matrixDataSource.load().done( function( selections ) { instance.purchasingPromises = {}; instance.selections = {}; let selectedCount = 0; selections.forEach( function( selection ) { instance.selections[selection.selectionKey] = true; selectedCount++; }) instance.stats.selectedCount = selectedCount; instance._updateSelectionCount(); instance._activateCallButtons(); }) } OperatorVoidMatrix.prototype._applyBulkSelection = function( mode, options ) { let instance = this; let objectParams = { searchSeq : instance.searchSeq, picker : { stockingStatus : 'N', memberGroupApproved : 'N', territoryTopSKU : 0, segmentTopSKU : 0, highlyProfitable : -1, excludeNoSale : "N", excludeSale : "N", mode : mode } } instance.lastPickFormData = options; if( mode == -1 ) { instance.lastPickFormData = {} } if( instance.lastPickFormData.stocked ) { objectParams.picker.stockingStatus = 'Y' } if( instance.lastPickFormData.approved ) { objectParams.picker.memberGroupApproved = 'Y' } if( instance.lastPickFormData.territoryTop50 ) { objectParams.picker.territoryTopSKU = 1; } if( instance.lastPickFormData.segmentTop50 ) { objectParams.picker.segmentTopSKU = 1; } if( instance.lastPickFormData.profitable ) { objectParams.picker.highlyProfitable = instance.lowProfitabilityRankThreshold; } if( instance.lastPickFormData.excludeSale ) { objectParams.picker.excludeSale = "Y"; } if( instance.lastPickFormData.excludeNoSale ) { objectParams.picker.excludeNoSale = "Y"; } let loadPanel = $("
").dxLoadPanel( { message : "Updating selections...", onHidden : function( e ) { e.component.element().remove(); } }).appendTo( $("body") ).dxLoadPanel("instance"); loadPanel.show(); let matrixDataSource= Fse.Data.newDataSource( { object : "OPR.voidMatrix", key : "skuId", paginate : false, objectParams : objectParams } ); return matrixDataSource.load().done( function( selections ) { instance.purchasingPromises = {}; instance.selections = {}; let selectedCount = 0; selections.forEach( function( selection ) { instance.selections[selection.selectionKey] = true; selectedCount++; }) instance.stats.selectedCount = selectedCount; instance.dataGrid.refresh(); instance._updateSelectionCount(); instance._activateCallButtons(); loadPanel.hide(); }) } OperatorVoidMatrix.prototype._resetAll = function() { let instance = this; instance.searchParams = $.extend( true, {}, instance.initialSearchParams ); instance.refresh(); } OperatorVoidMatrix.prototype.createBreadcrumbs = function() { let instance = this; instance.breadcrumbs = new Breadcrumbs( { onRemove : function( p ) { // let copySearchParams = $.extend( true, {}, instance.searchParams ); // delete copySearchParams[p]; // // handle any dependent search params // if( p == "mfr_id" ) { // delete copySearchParams.productHierarchyPath; // } // instance.searchParams = copySearchParams; instance.showFilters(); }, onOpen : function( p ) { instance.showFilters(); }, items : [ // first column from search center { searchParam : "operatorId", hint : "OperatorId", dataObject : { name : "CRM.operatorList", key : "operatorId" }, displayExpr : "companyName", multipleDisplay : "Multiple Operators", removable : false }, { searchParam : "displayCompanyType", removable : false, displayExpr : function( v ) { let store = new DevExpress.data.ArrayStore( { data : [ { displayCompanyType : "Independent" }, { displayCompanyType : "Chain HQ" }, { displayCompanyType : "Unit" } ], key : "displayCompanyType" }); let text = null; store.byKey( v ).done( function( data ) { text = data.displayCompanyType } ); return text; } }, { searchParam : "clientSegPath", removable : false, hint : "Segment", displayExpr : "segmentPath", multipleDisplay : "Multiple Segments", dataObject : { name : "OPR.segments" , key : "clientSegPath" }}, { searchParam : "classificationId", removable : false, hint : "Classification", displayExpr : "name", multipleDisplay : "Multiple Classifications", dataObject : { name : "OPR.classifications" , key : "classificationId" }}, { searchParam : "priority", displayExpr : function( v ) { let values = v; if( ! Array.isArray( values ) ) { values = [values]; } let displayValues = []; values.forEach( function( priorityValue ) { if( priorityValue == "*" ) { displayValues.push( "A+" ) } else { displayValues.push( priorityValue ) } }) return displayValues.join( "," ); }}, // middle column from search center { searchParam : "territoryPath", removable : false, hint : "Territory", multipleDisplay : "Multiple Territories", dataObject : { name : "TER.salesTerritories", key : "territoryPath" }, displayExpr : "territoryPath" }, { searchParam : "salesRepId", removable : false, hint : "Account Owner", multipleDisplay : "Multiple Account Owners", dataObject : { name : "CRM.salesRepList", key : "fspro_userId" }, displayExpr : "fullName" }, { searchParam : "cdr_dstPath", removable : false, hint : "Distributor", multipleDisplay : "Multiple Distributors", dataObject : { name : "CDR.distributors", key : "cdr_dstPath" }, displayExpr : "cdr_dstPath" }, { searchParam : "gpoId", removable : false, hint : "GPO", multipleDisplay : "Multiple GPOs", dataObject : { name : "OPR.memberGroups", key : "operatorId"}, displayExpr : "companyName" }, { searchParam : "noGPO", removable : false, displayExpr : function( ) { return "No GPO" }}, { searchParam : "cmcId", removable : false, hint : "CMC", multipleDisplay : "Multiple CMCs", dataObject : { name : "OPR.memberGroups", key : "operatorId"}, displayExpr : "companyName" }, { searchParam : "noCMC", removable : false, displayExpr : function( ) { return "Self Managed" }}, { searchParam : "operatorListId", removable : false, hint : "List", multipleDisplay : "Multiple Lists", dataObject : { name : "LST.lists", key : "listId"}, displayExpr : "listName" }, { searchParam : "focusProducts", removable : false, displayExpr : function( v ) { return "Focus Products"; }}, { searchParam : "mfr_id", removable : false, hint : "Manufacturer", multipleDisplay : "Multiple Manufacturers", dataObject : { name : "PRD.manufacturers", key : "mfr_id" }, displayExpr : "mfr_name" }, { searchParam : "productHierarchyPath", removable : false, hint : "Product", multipleDisplay : "Multiple Products", dataObject : { name : "PRD.productHierarchyPaths", key : "productHierarchyPath" }, displayExpr : "productHierarchyPath" }, { searchParam : "topCount",removable : false, displayExpr : function( v ) { return `Top ${v} SKUs` } }, { searchParam : "productSetTags", removable : false, hint : "Product Set", multipleDisplay : "Multiple Product Sets", dataObject : { name : "PRD.productSets", key : "productSetTag" }, displayExpr : "productSetName" }, ], debug : true }) //instance.rootElement.append( instance.breadcrumbs.element().css( { "padding-top" : "5px" } ) ); instance.breadcrumbs.element().css( { "padding-top" : "5px" } ); } OperatorVoidMatrixSearch = function( searchOptions ) { let searchOptionDefaults = { applySearch : function( searchParams ) { // default does nothing, caller must override }, showOperatorFilters : true }; this.filterPreferences = {}; // scrum 46030 this.searchOptions = $.extend( true, {}, searchOptionDefaults, searchOptions ) this.dxForm = null this.dxPopup = null; // this.init(); // scrum 46030 } OperatorVoidMatrixSearch.prototype.constructor = OperatorVoidMatrixSearch; /* scrum 46030 OperatorVoidMatrixSearch.prototype.init = function() { this.createPopup(); } */ OperatorVoidMatrixSearch.prototype.createForm = function() { let instance = this; let group3Items = [ { template : function() { return $("
").append( "Product" ).css( { "text-align": "center", "font-size" : "larger" } ) } } ]; let showMFR = Fse.Portal.appConfiguration.STP.ownerType !== "MFR"; let showBRO = Fse.Portal.appConfiguration.STP.ownerType === "MFR"; let showStaffType = Fse.Portal.appConfiguration.STP.ownerType === "MFR"; if( showMFR ) { group3Items.push( { dataField : "mfr_id", label : { location : "left", text : "Manufacturer" }, editorType : "dxDropDownBox", cssClass : instance.activeFilterPreferences.mfr_id ? 'fx-active-preference' : null, // scrum 46030 editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { object : "PRD.manufacturers", key : "mfr_id" } ), searchExpr : "mfr_name", searchMode : "contains", displayExpr : "mfr_name", multipleSelectedDisplay : "Multiple Manufacturers Selected", keyExpr : "mfr_id", title : "Select Manufacturer" }) }); } group3Items.push( { dataField : "productHierarchyPath", label : { location : "left", text : "Product" }, editorType : "dxDropDownBox", cssClass : instance.activeFilterPreferences.productHierarchyPath ? 'fx-active-preference' : null, // scrum 46030 editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { object : "PRD.productHierarchyPaths", key : "productHierarchyPath", objectParams : { "crmActive" : "Y" } } ), searchExpr : "productHierarchyPath", searchMode : "contains", displayExpr : "productHierarchyPath", multipleSelectedDisplay : "Multiple Product Hierarchy Paths Selected", keyExpr : "productHierarchyPath", title : "Select Product Hierarchy Path", searchTemplate : function( applyFilters ) { return Fse.UI.productHierarchyPathMultiSelectSearchTemplate( applyFilters ) } }) }, { dataField : "productSetTags", label : { location : "left", text : "Product Set" }, editorType : "dxDropDownBox", cssClass : instance.activeFilterPreferences.productSetTags ? 'fx-active-preference' : null, editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { object : "PRD.productSets", keyField : "productSetTag" } ), searchExpr : "productSetName", searchMode : "contains", displayExpr : "productSetName", multipleSelectedDisplay : "Multiple Product Sets Selected", keyExpr : "productSetTag", title : "Select Product Set" }) } ); group3Items.push( //focus items { dataField : "focusProduct", label : { location : "left", text : "Focus Items" }, editorType : "dxSwitch"} ); group3Items.push( { dataField : "topCount", label : { text : "Top X SKUs" }, editorType : "dxSelectBox", editorOptions : { items : [ { value : 10, text : "10" }, { value : 25, text : "25" }, { value : 50, text : "50" }, { value : 75, text : "75" }, { value : 100, text : "100" }, { value : 150, text : "150" }, { value : 200, text : "200" } ], valueExpr : "value", displayExpr : "text", value : 25 } } // , // { // dataField : "rankBy", // label : { text : "Ranked By" }, // editorType : "dxSelectBox", // editorOptions : { // items : [ // { value : "volume", text : "volume"} // ], // displayExpr : "text", // valueExpr : "value", // value : "volume" // } // } ) group2Items = []; group2Items.push( // start group 2 items { template : function() { return $("
").append( "Operator" ).css( { "text-align": "center", "font-size" : "larger" } ) } }, // territoryId { 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( { object : "TER.salesTerritories", key : "territoryPath" } ), searchExpr : "territoryPath", searchMode : "contains", displayExpr : "territoryPath", multipleSelectedDisplay : "Multiple Territories Selected", keyExpr : "territoryPath", title : "Select Territories" }) } ); // if( showBRO ) { // group2Items.push( // // broker_id // { dataField : "broker_id", label : { location : "left", text : "Broker" }, editorType : "dxDropDownBox", // editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { // dataSource : Fse.Data.newDataSource( { object : "MFR.brokers", key : "broker_id" } ), // searchExpr : "broker_name", // searchMode : "contains", // displayExpr : "broker_name", // multipleSelectedDisplay : "Multiple Brokers Selected", // keyExpr : "broker_id", // title : "Select Brokers" // }) // }); // } group2Items.push( //sales rep { dataField : "salesRepId", label : { location : "left", text : "Sales Rep" }, editorType : "dxDropDownBox", cssClass : instance.activeFilterPreferences.salesRepId ? 'fx-active-preference' : null, // scrum 46030 editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { object : "CRM.salesRepList", key : "valueId" } ), searchExpr : "valueName", searchMode : "contains", displayExpr : "valueName", multipleSelectedDisplay : "Multiple Sales Reps Selected", keyExpr : "valueId", title : "Select Sales Reps" }) } // , { // dataField : "excludeDeletedSalesReps", label : { text : "Exclude Inactive & Deleted Sales Reps" }, // editorType : "dxSwitch" // } ) // if( showStaffType ) { // group2Items.push( // { // dataField: "salesRepOwnerType", label : { location : "left", text : "Staff Type" }, editorType : "dxSelectBox", // cssClass : instance.activeFilterPreferences.salesRepOwnerType ? 'fx-active-preference' : null, // editorOptions : { // showClearButton : true, // placeholder : "Select Staff Type", // dataSource : { store : { type : "array", key : "value", data : [ // { // value : "MFR", text : "Manufacturer Staff Only" // }, // { // value : "BRO", text : "Broker Staff Only" // } // ]}}, // valueExpr : "value", // displayExpr : "text" // } // } // ) // } const priorityTypes = [ {"prioritycode":"*","desc":"A+"}, {"prioritycode":"A","desc":"A"}, {"prioritycode":"B","desc":"B"}, {"prioritycode":"C","desc":"C"}, {"prioritycode":"D","desc":"D"} ]; const displayCompanyTypes = [ { displayCompanyType : "Chain HQ" }, { displayCompanyType : "Independent" }, { displayCompanyType : "Unit" } // { displayCompanyType : "GPO" }, // { displayCompanyType : "CMC" }, // { displayCompanyType : "Holding" }, ]; group2Items.push( // distributor hierarchy { dataField : "cdr_dstPath", label : { location : "left", text : "Distributor" }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( {object : "CDR.distributorsLight", key : "cdr_dstPath" } ), searchExpr : "cdr_dstPath", searchMode : "contains", displayExpr : "cdr_dstPath", multipleSelectedDisplay : "Multiple Distributors Selected", keyExpr : "cdr_dstPath", title : "Select Distributors" }) }, // { dataField : "displayCompanyType", label : { text : "Type" }, // editorType : "dxSelectBox", // editorOptions : { // dataSource : { store : { type : "array", data : displayCompanyTypes, key : "displayCompanyType" }}, // displayExpr : "displayCompanyType", // valueExpr : "displayCompanyType", // showClearButton : true, // placeholder : "Select Company Type" // } // }, { dataField : "displayCompanyType", label : { location : "left", text : "Type" }, editorType : "dxDropDownBox", editorOptions : { placeholder : "Select Company Type...", dataSource : { store : { type : "array", data : displayCompanyTypes, key : "displayCompanyType" } }, valueExpr : "displayCompanyType", displayExpr : "displayCompanyType", contentTemplate : function( e ) { const v = e.component.option( "value" ); const $list = $("
").dxList( { dataSource : e.component.getDataSource(), displayExpr : "displayCompanyType", 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 : "operatorId", label : { location : "left", text : "Operator" }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { object : "CRM.operatorList", keyField : "operatorId", filter : [[ "oprCompanyType", '=', '0' ], "or", [ "oprCompanyType", '=', '1' ]] } ), searchExpr : "companyName", searchMode : "contains", displayExpr : "companyName", multipleSelectedDisplay : "Multiple Operators Selected", keyExpr : "operatorId", title : "Select Operator" }) }, //segments { dataField : "clientSegPath", 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( { object : "OPR.segments", key : "clientSegPath" } ), searchExpr : "clientSegPath", searchMode : "contains", displayExpr : "clientSegPath", multipleSelectedDisplay : "Multiple Segments Selected", keyExpr : "clientSegPath", title : "Select Segments" }) }, { dataField : "priority", label : { location : "left", text : "Priority" }, editorType : "dxDropDownBox", editorOptions : { placeholder : "Select Priority", dataSource : new DevExpress.data.ArrayStore({ data: 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 : "classificationId", label : { text : "Classification" }, editorType : "dxDropDownBox", editorOptions : $.extend( true, { multiSelectOptions : { dataSource : Fse.Data.newDataSource( { object : "OPR.classifications", key : "classificationId" }), keyExpr: "classificationId", displayExpr : "description", searchExpr : "description", searchMode : "contains", multipleSelectedDisplay : "Multiple Classifications selected", title : "Select Classifications" } }, multiSelectEditorOptions ) }, { dataField : "gpoId", colSpan : 2, label : { location : "left", text : "GPO" }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { object : "OPR.memberGroups", key : "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( { object : "OPR.memberGroups", key : "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" }, /* 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 ]]]); */ { dataField : "operatorListId", label : { location : "left", "text" : "Operator List" }, editorType : "dxSelectBox", editorOptions : { dataSource : Fse.Data.newDataSource( { object : "LST.lists", filter : [[[ "published", "=", 1 ], "and", [ "forSearch", "=", 1 ]], "or" , [ "creator", "=", 1 ], "or", [ "contributor", "=", 1 ]], key : "listId", objectParams : { includeStatus : false, partnerTypes : "OPR" }}), displayExpr : "listName", searchEnabled : true, searchExpr : "listName", valueExpr : "listId", placeholder : "Select", showClearButton : true } } ); // let group1Items = []; // group1Items.push( // { template : function() { return $("
").append( "Options" ).css( { "text-align": "center", "font-size" : "larger" } ) } }, // { dataField : "whitespace", label : { location : "left", text : "Whitespace" }, editorType : "dxSwitch", // editorOptions: { // value: false // } // }, // { dataField : "ytdPurchasing", label : { location : "left", text : "YTD Purchasing" }, editorType : "dxSwitch", // editorOptions: { // value: false // } // }, // { dataField : "activeOpportunities", label : { location : "left", text : "Active Opportunities" }, editorType : "dxSwitch", // editorOptions: { // value: false // } // }, // { dataField : "oneFSRecommended", label : { location : "left", text : "1FS Recommended" }, editorType : "dxSwitch", // editorOptions: { // value: false // } // } // ); let formItems = []; if( instance.searchOptions.showOperatorFilters ) { formItems.push( // TERRITORY (AND CUSTOMER) { name: "group2", itemType : "group", colCount : 1, items : group2Items } ) } formItems.push( // product filters { name: "group3", itemType : "group", colCount : 1, items :group3Items } ) instance.dxForm = $("
").dxForm( { width : "100%", colCount : instance.searchOptions.showOperatorFilters ? 2 : 1, items : formItems, onFieldDataChanged : function ( e ) { // setObjPathFilter = function( mfr_id, territoryPath ) { // let objPathEditor = e.component.getEditor( "objPath" ); // let objPathFilters = []; // if( mfr_id ) { // if( ! Array.isArray( mfr_id )) { // mfr_id = [mfr_id]; // } // objPathFilters.push( [ "objOwnerType", "=", "MFR" ] ) // let objOwnerIdFilter = []; // objPathFilters.push( "and", objOwnerIdFilter ); // mfr_id.forEach( function( mfr_id_v ) { // if( objOwnerIdFilter.length ) { // objOwnerIdFilter.push( "or" ); // } // objOwnerIdFilter.push( [ "objOwnerId", "=", mfr_id_v ] ); // }) // } // if( territoryPath ) { // if( ! Array.isArray( territoryPath )) { // territoryPath = [territoryPath]; // } // territoryPathFilters = []; // territoryPath.forEach( function( territoryPath_v ) { // if( territoryPathFilters.length ) { // territoryPathFilters.push( "or" ); // } // territoryPathFilters.push( [ "territoryPath", "startswith", territoryPath_v ] ); // }) // if( objPathFilters.length ) { // objPathFilters = [ objPathFilters, "and", territoryPathFilters ]; // } else { // objPathFilters = territoryPathFilters; // } // } // console.log( "objPathFilters" ); // console.log( objPathFilters ); // objPathEditor.option( "availableFilter", objPathFilters ); // } if( e.dataField ) { if( e.dataField === "territoryPath" ) { let mfrValue = null; let mfrEditor = e.component.getEditor( "mfr_id" ); if( mfrEditor ) { mfrValue = mfrEditor.option( "value" ); } //setObjPathFilter( mfrValue, e.value ); } if( e.dataField === "mfr_id" ) { let fields = [] fields.push( e.component.getEditor( "productHierarchyPath" ) ); // fields.push( e.component.getEditor( "budgetCategoryMgr_fspro_userId" ) ); // fields.push( e.component.getEditor( "budgetCategoryId" ) ); fields.push( e.component.getEditor( "brandId" ) ); let fieldOptions = { value : null }; if( e.value && e.value != "") { fieldOptions.disabled = true; } else { fieldOptions.disabled = false; } fields.forEach( function( f ) { if( f ) { f.option( fieldOptions ); } }) // let territoryPathEditor = e.component.getEditor( "territoryPath" ); //setObjPathFilter( e.value, territoryPathEditor.option( "value" ) ); /* let objPathEditor = e.component.getEditor( "objPath" ); let objPathFilters = []; if( e.value ) { objPathFilters.push( [ "objOwnerType", "=", "MFR" ] ) let objOwnerIdFilter = []; objPathFilters.push( "and", objOwnerIdFilter ); let v = e.value; if( ! Array.isArray( v ) ) { v = [v]; } v.forEach( function( vv ) { if( objOwnerIdFilter.length ) { objOwnerIdFilter.push( "or" ); } objOwnerIdFilter.push( [ "objOwnerId", "=", vv ] ); }) } console.log( "objPathFilters" ); console.log( objPathFilters ); objPathEditor.option( "availableFilter", objPathFilters ); */ } } } }).dxForm("instance"); } OperatorVoidMatrixSearch.prototype.createPopup = function() { let instance = this; instance.createForm(); let bottomToolbarItems = [ { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "search", type : "default", onClick : function( e ) { let vr = DevExpress.validationEngine.validateGroup( "OperatorVoidMatrixFilters" ); console.log( vr ); if( ! vr.isValid ) return; let applySearch = instance.searchOptions.applySearch; let searchParams = instance.dxForm.option( "formData" ); instance.dxPopup.hide(); applySearch( searchParams ); } } } ]; 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 : "Void Search", width : "50vw", height : "auto", contentTemplate : function() { let content = $("
").append( instance.dxForm.element()); $("
").dxValidator({ validationGroup : "OperatorVoidMatrixFilters", adapter : { getValue : function() { return instance.dxForm.option( "formData" ); }, applyValidationResults : function( vr ) { console.log( "applyValidationResults", vr ); if( ! vr.isValid ) { $("
").dxToast( { message : vr.brokenRule.message, displayTime : 2000, type : "error", position : { of : instance.dxPopup.element() }, onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); } }).appendTo( $("body") ).dxToast("show") } } }, validationRules : [ { type : "custom", message : instance.searchOptions.showOperatorFilters ? "At least one Operator filter and at least one Product filter is required" : "At least on Product filter is required", reevaluate : true, validationCallback : function( validate ) { let value = validate.value; let productValid = ( value.focusProduct || ( value.productSetTags && value.productSetTags.length ) || ( value.productHierarchyPath && value.productHierarchyPath.length )) ? true : false; let operatorValid = false; if( instance.searchOptions.showOperatorFilters ) { operatorValid = ( ( value.territoryPath && value.territoryPath.length ) || ( value.salesRepId && value.salesRepId.length ) || ( value.cdr_dstPath && value.cdr_dstPath.length ) || ( value.clientSegPath && value.clientSegPath.length ) || ( value.priority && value.priority.length ) || ( value.classificationId && value.classificationId.length ) || ( value.gpoId && value.gpoId.length ) || ( value.noGPO ) || ( value.cmcId && value.cmcId.length ) || ( value.noCMC ) || ( value.operatorListId ) || ( value.operatorId ) ) ? true : false; } else { operatorValid = true; } let isValid = operatorValid && productValid; return isValid; } } ] } ).appendTo( content ); return content; }, toolbarItems : bottomToolbarItems, // on hidden added to cleanup ui objects - scrum 46030 onHidden : function( e ) { // clean up e.component.element().remove(); instance.dxForm.dispose(); instance.dxForm = null; instance.dxPopup.dispose(); instance.dxPopup = null; } }).appendTo( "body" ).dxPopup("instance"); } // scrum 46030 OperatorVoidMatrixSearch.prototype.show = function( searchParams, filterPreferences ) { this.processFilterPreferences( filterPreferences, searchParams ); console.log("searchParams"); console.log(searchParams); this.createPopup(); if( searchParams ) { this.dxForm.updateData( searchParams ); } this.dxPopup.show(); } OperatorVoidMatrixSearch.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", //focusProduct : "focusProduct", //budgetCategoryId : "budgetCategoryId", productHierarchyPath : "productHierarchyPath", mfr_id : "mfr_id", clientSegPath : "clientSegPath", //salesRepOwnerType : "staffType", productSetTags : "productSetTags" } return preferenceableFilters; } OperatorVoidMatrixSearch.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 ); }