").dxContextMenu( {
target : button.element(),
items : [
{ text : "Export Opportunities...", id : "exportOpportunities" }
],
onItemClick : function( e ) {
if( e.itemData.id == "exportOpportunities" ) {
instance.exportOpportunityData();
}
},
hideOnOutsideClick : true
}).appendTo( $("body") )
return button.element();
},
xwidget : "dxButton",
xoptions : {
icon : "export",
hint : "Excel Export",
onClick : function( ee ) {
Fse.UI.DataGridHelper.exportDataGrid( { dataGrid : e.component, fileName : "BookOfBusinessReach.xlsx" } );
}
}
})
}
}).dxDataGrid( "instance" );
instance.rootElement = $("
").addClass( "BookOfBusinessReachWidget" );
instance.rootElement.append( instance.dataGrid.element() )
instance.applyFilters();
return instance.rootElement
}
BookOfBusinessReachWidget.prototype.exportOpportunityData = function() {
let instance = this;
let objectParams = $.extend( true, {}, instance.objectParams )
objectParams.returnType = "opportunityData";
let exportGrid = $("
").dxDataGrid( {
visible : false,
columns : [
{ dataField : "opportunityId", caption : "Opportunity ID", dataType : "number", format : "fixedPoint" },
{ dataField : "partnerTerritoryName", caption : "Account Territory" },
{ dataField : "partnerName", caption : "Account Name" },
{ dataField : "estOrderDate", dataType : "date" },
{ dataField : "product", caption : "Product Code" },
{ dataField : "shortDesc", caption : "Product Description" },
{ dataField : "sku", caption : "SKU Code" },
{ dataField : "skuDesc", caption : "SKU Description" },
{ dataField : "cases", dataType : "number" },
{ dataField : "lbs", dataType : "number" },
{ dataField : "dollars", dataType : "number" },
{ dataField : "effectiveRepEmail", dataField : "Sales Rep Email" },
{ dataField : "stageName", caption : "Stage" },
{ dataField : "likelihoodPercent", caption : "Likely %", format : "percent", dataType : "number" }
],
dataSource : Fse.Data.newDataSource( { object : "SPL.bookOfBusinessReach", paginate : false, objectParams : objectParams })
}).dxDataGrid( "instance" );
exportGrid.getDataSource().load().done( function() {
Fse.UI.DataGridHelper.exportDataGrid( { dataGrid : exportGrid, fileName : "OpportunityData.xlsx" } );
})
}
BookOfBusinessReachWidget.prototype.viewOpportunities = function( data, metricField ) {
let instance = this;
instance.loadMetaData().done( function( metaData ) {
console.log( `META DATA ${data.accountType}` );
console.log( metaData );
let searchParams = {
effectiveRepOwnerType : "MFR",
partnerClassificationKey : []
}
if( metricField == "active" ) {
searchParams.stageId = metaData.activeStageIds
} else if ( metricField == "activePlus" ) {
searchParams.stageId = metaData.activePlusStageIds
} else if ( metricField == "sale" ) {
searchParams.stageId = metaData.saleStageIds
} else if ( metricField == "noSale" ) {
searchParams.stageId = metaData.noSaleStageIds
} else {
searchParams.stageId = metaData.stageIds
}
let fieldNames = [ "bobOPRClassificationIds", "bobCDRClassificationIds" ];
fieldNames.forEach( function( fn ) {
let partnerType = "OPR";
if( fn.search( /CDR/ ) > 0 ) {
partnerType = "CDR";
}
let classificationIds = metaData[fn];
classificationIds.forEach( function( classificationId ) {
searchParams.partnerClassificationKey.push( `${partnerType}:${classificationId}` );
})
})
// merge in widget filters
for( p in instance.widgetOptions.config ) {
if( instance.widgetOptions.config[p] && ! searchParams[p]) {
searchParams[p] = instance.widgetOptions.config[p]
}
}
// translate salesRepId
if( searchParams.salesRepId ) {
searchParams.effectiveRepId = searchParams.salesRepId;
}
delete searchParams.salesRepId;
if( ! searchParams.effectiveRepId ) {
searchParams.excludeEffectiveRepId = metaData.excludeSalesRepId;
}
// translate territoryPath
if( searchParams.territoryPath ) {
searchParams.partnerTerritoryPath = searchParams.territoryPath;
}
delete searchParams.territoryPath;
// remove the grouping search param from the filters
delete searchParams.grouping;
// change this to a readable value
let groupings = new DevExpress.data.ArrayStore( {
data : [
{ value : "accountOwnerFullName", searchParam : "effectiveRepId" },
{ value : "divisionName", searchParam : "partnerTerritoryPath" },
{ value : "regionName", searchParam : "partnerTerritoryPath" },
{ value : "territoryName", searchParam : "partnerTerritoryPath" },
{ value : "segmentName", searchParam : "clientSegPath" }
],
key : "value"
})
let groupingSearchParam = null;
groupings.byKey( instance.widgetOptions.config.grouping ).done( function( grouping ) {
groupingSearchParam = grouping.searchParam;
})
searchParams[groupingSearchParam] = data.groupingKey;
console.log( "Click Search Params" );
console.log( searchParams );
instance.widgetOptions.dashboard.tabSearch( "OpportunityAnalyzer", searchParams );
})
}
BookOfBusinessReachWidget.prototype.loadMetaData = function() {
let instance = this;
let d = $.Deferred();
let appDataURL = $("link#appDataURL").attr( "href" );
let bobMetaDataURL = Fse.Util.updateURL( appDataURL, { object : "SPL.bookOfBusinessMetaData", mode : "direct" } )
$.ajax( {
url : bobMetaDataURL,
method : "GET"
}).done( function( metaData ) {
instance.metaData = metaData;
d.resolve( instance.metaData );
}).fail( function() {
d.reject();
})
return d;
}
BookOfBusinessReachWidget.prototype.edit = function( applyFn ) {
this.showGrouping = true;
let widgetPreferenceEditor = new BookOfBusinessWidgetPreferences( this );
widgetPreferenceEditor.show( applyFn );
}
BookOfBusinessReachWidget.prototype.getDefaultConfig = function() {
let estOrderDateRange = Fse.CRM.dateRanges.rangeByKey( "F,TY" ); // fiscal this year
return {
territoryPath : null,
productHierarchyPath : null,
estOrderDateStart : estOrderDateRange.startDate,
estOrderDateEnd : estOrderDateRange.endDate,
estOrderDateRange : estOrderDateRange.rangeKey,
clientSegPath : null,
productSetTags : null,
partnerType : null,
salesRepId : null,
objPath : null,
grouping : "accountOwnerFullName"
}
}
BookOfBusinessReachWidget.prototype.applyPreferences = function( preferences ) {
this.widgetOptions.config = $.extend( true, {}, preferences );
this.applyFilters();
}
BookOfBusinessReachWidget.prototype.applyFilters = function() {
let instance = this;
let widgetFilters = $.extend( true, {}, instance.widgetOptions.config );
let filterPreferences = instance.widgetOptions.filterPreferences;
let activeFilterPreferences = instance.activeFilterPreferences;
// global filters suppored by this widget, when the global filters are expressed with different variable names, they need to translated to this widgets variable names
const globalFilters = {
// widgetVariableName : "globalFilterVariableName"
salesRepId : "salesRepId",
territoryPath : "territoryPath",
productHierarchyPath : "productHierarchyPath",
productSetTags : "productSetTags",
clientSegPath : "clientSegPath"
};
for( let p in globalFilters ) {
// apply translation - global filter param is not the same name as widget param
let gp = globalFilters[p];
// if the global filter preferences have the propery and it has a value, update the objectparams
if( filterPreferences.hasOwnProperty( gp ) && filterPreferences[gp]) {
if( widgetFilters[p] == null ) {
widgetFilters[p] = filterPreferences[gp];
activeFilterPreferences[p] = widgetFilters[p]; // indicate that this widget parameter has an active filter preference - used when displaying the edit page
}
}
}
let opportunityFilters = [];
let accountFilters = [];
let salesRepFilterActive = false;
if( widgetFilters.estOrderDateStart && widgetFilters.estOrderDateEnd ) {
opportunityFilters.push( [
[ "estOrderDate", ">=", widgetFilters.estOrderDateStart ],
"and",
[ "estOrderDate", "<=", widgetFilters.estOrderDateEnd ]
])
}
if( widgetFilters.productSetTags ) {
let filter = [];
widgetFilters.productSetTags.forEach( function( ve ) {
if( filter.length ) {
filter.push( "or" );
}
filter.push( [ "productSetTags", "contains", ve ] );
})
if( filter.length ) {
if( opportunityFilters.length ) opportunityFilters.push( "and" );
opportunityFilters.push( filter );
}
}
if( widgetFilters.productHierarchyPath ) {
let filter = [];
widgetFilters.productHierarchyPath.forEach( function( ve ) {
if( filter.length ) {
filter.push( "or" );
}
filter.push( [ "productHierarchyPath", "startswith", ve ] );
})
if( filter.length ) {
if( opportunityFilters.length ) opportunityFilters.push( "and" );
opportunityFilters.push( filter );
}
}
if( widgetFilters.objPath ) {
let objPaths = widgetFilters.objPath;
// there are 5 objective path fields to search
if( ! Array.isArray( objPaths ) ) {
objPaths = [objPaths];
}
filter = [];
objPaths.forEach( function( objPath ) {
let objPathFilter = [
["objPath1", "startswith", objPath],
"or",
["objPath2", "startswith", objPath],
"or",
["objPath3", "startswith", objPath],
"or",
["objPath4", "startswith", objPath],
"or",
["objPath5", "startswith", objPath]
]
if( filter.length ) {
filter.push( "or" )
}
filter.push( objPathFilter );
})
if( filter.length ) {
if( opportunityFilters.length ) opportunityFilters.push( "and" );
opportunityFilters.push( filter );
}
}
if( widgetFilters.territoryPath ) {
let filter = [];
widgetFilters.territoryPath.forEach( function( ve ) {
if( filter.length ) {
filter.push( "or" );
}
filter.push( [ "territoryPath", "startswith", ve ] );
})
if( filter.length ) {
if( accountFilters.length ) accountFilters.push( "and" );
accountFilters.push( filter );
}
}
if( widgetFilters.clientSegPath ) {
let filter = [];
widgetFilters.clientSegPath.forEach( function( ve ) {
if( filter.length ) {
filter.push( "or" );
}
filter.push( [ "clientSegPath", "startswith", ve ] );
})
if( filter.length ) {
if( accountFilters.length ) accountFilters.push( "and" );
accountFilters.push( filter );
}
}
if( widgetFilters.salesRepId ) {
let filter = [];
widgetFilters.salesRepId.forEach( function( ve ) {
if( filter.length ) {
filter.push( "or" );
}
filter.push( [ "salesRepId", "=", ve ] );
})
if( filter.length ) {
if( accountFilters.length ) accountFilters.push( "and" );
accountFilters.push( filter );
salesRepFilterActive = true;
}
}
if( widgetFilters.partnerType ) {
if( accountFilters.length ) accountFilters.push( "and" );
accountFilters.push( [ "partnerType", "=", widgetFilters.partnerType ] );
}
objectParams = {
salesRepFilterActive : salesRepFilterActive,
grouping : widgetFilters.grouping
};
if( opportunityFilters.length ) {
objectParams.opportunityFilters = opportunityFilters;
}
if( accountFilters.length ) {
objectParams.accountFilters = accountFilters;
}
let groupingNameCaption = widgetFilters.grouping;
// change this to a readable value
let groupings = new DevExpress.data.ArrayStore( {
data : [
{ value : "accountOwnerFullName", caption : "Account Owner" },
{ value : "divisionName", caption : "Division" },
{ value : "regionName", caption : "Region" },
{ value : "territoryName", caption : "Territory" },
{ value : "segmentName", caption : "Segment" }
],
key : "value"
})
groupings.byKey( widgetFilters.grouping ).done( function( grouping ) {
groupingNameCaption = grouping.caption;
})
instance.objectParams = objectParams;
instance.dataGrid.option( "dataSource", Fse.Data.newDataSource( { object : "SPL.bookOfBusinessReach", paginate : false, objectParams : objectParams }) );
instance.dataGrid.columnOption( "groupingName", { caption : groupingNameCaption } )
}
Fse.Portal.addWidgetFactory( "BookOfBusinessReachWidget", function( widgetDef ) {
return new BookOfBusinessReachWidget( widgetDef );
})