")
instance.dataGrid = instance.createDataGrid();
instance.rootElement.append( instance.dataGrid.element() );
return instance.rootElement;
}
SalesCallPerformanceWidget.prototype.createDataGrid = function() {
let instance = this;
instance.groupTypesStore = new DevExpress.data.ArrayStore( {
data : [ { text : "Sales Rep", groupType : "salesRep" }, { text : "Territory", groupType : "territory" }, { text : "Region", groupType : "region" }],
key : "groupType"
});
let groupCaption = "Group";
instance.groupTypesStore.byKey( instance.widgetOptions.config.groupType ).done( function( data ) {
groupCaption = data.text;
})
let headerCellTemplate = function( container, options ) {
if( options.column.hint ) {
container.attr( "title", options.column.hint );
}
container.append( options.column.caption )
}
return $("
").dxDataGrid( {
scrolling : { mode : "virtual" },
showBorders : true,
height : "100%",
columns : [
{ dataField : "groupDisplay", caption : groupCaption,
width : "auto",
calculateDisplayValue : function( data ) {
if( ! data || ! data.groupDisplay ) return;
if( ! data.groupColumn.match( /Path$/ )) {
return data.groupDisplay;
}
let parts = data.groupDisplay.split( "/" );
if( parts.length == 1 ) {
return data.groupDisplay;
} else {
let lastPart = parts[parts.length-1].replace( "|", "/" );
return `.../${lastPart}`;
}
},
cellTemplate : function( container, options ) {
if( options.rowType != "data" ) return;
if( options.data.groupColumn.match( /Path$/) ) {
container.attr( { "title" : options.value } )
}
container.append( options.displayValue );
}
},
// call fields
{ dataField : "totalCalls", caption : "Calls", hint : "Total Calls", xwidth :50, dataType : "number", format : { type : "fixedPoint", precision : 0 }, headerCellTemplate : headerCellTemplate },
{ dataField : "callsPerWeek", caption : "Calls/Wk", hint : "Average Calls per Week", xwidth : 80, dataType : "number",format : { type : "fixedPoint", precision : 1 }, headerCellTemplate : headerCellTemplate },
{ dataField : "callsPerWeekPerRep", caption : "Rep/Calls/Wk", hint : "Average Calls per Rep per Week", width : 100, dataType : "number", format : { type : "fixedPoint", precision : 1 }, headerCellTemplate : headerCellTemplate },
{ dataField : "uniqueAccountsPct", caption : "Uniq Accts", hint: "% of Unique Accounts Called On", xwidth : 80, dataType : "number", format : { type : "percent", precision : 1 }, headerCellTemplate : headerCellTemplate},
// debug
{ visible : false, dataField : "uniqueAccounts", caption : "UA", width : 50, dataType : "number", format : { type : "fixedPoint", precision : 0 }, headerCellTemplate : headerCellTemplate },
{ visible : false, dataField : "newAccounts", caption : "NA", width : 50, dataType : "number", format : { type : "fixedPoint", precision : 0 }, headerCellTemplate : headerCellTemplate },
{ dataField : "newAccountsPct", caption : "New Accts", hint: "% of New Accounts Called", xwidth: 80, dataType : "number", format : { type : "percent", precision : 1 }, headerCellTemplate : headerCellTemplate },
{ dataField : "objectiveCallsPct", caption : "Obj Calls", hint: "% of Calls Tied to Objectives", xwidth : 80, dataType : "number", format : { type : "percent", precision : 1 }, headerCellTemplate : headerCellTemplate },
// item fields
{ dataField : "totalPresentations", caption : "Items", hint: "Total Number of Items Presented", xwidth : 55, dataType : "number", format : { type : "fixedPoint", precision : 0 }, headerCellTemplate : headerCellTemplate },
// debug
{ visible : false, dataField : "totalWins", caption : "Wins", width : 50, dataType : "number", format : { type : "fixedPoint", precision : 0 }, headerCellTemplate : headerCellTemplate },
{ visible : false, dataField : "totalLoses", caption : "Losses", width : 50, dataType : "number", format : { type : "fixedPoint", precision : 0 }, headerCellTemplate : headerCellTemplate },
{ visible : false, dataField : "totalFollowUps", caption : "FUs", width : 50, dataType : "number", format : { type : "fixedPoint", precision : 0 }, headerCellTemplate : headerCellTemplate },
{ dataField : "closeRate", caption : "Close", hint: "Close Rate % (Sale / Sale + No Sale)", xwidth : 55, dataType : "number", format : { type : "percent", precision : 1 }, headerCellTemplate : headerCellTemplate },
{ dataField : "efficiencyRate", caption : "Eff", hint : "Efficiency % (Sale / Sale + Follow Up + No Sale)", xwidth : 55, dataType : "number", format : { type : "percent", precision : 1 }, headerCellTemplate : headerCellTemplate },
{ dataField : "avgCallsToClose", caption : "Calls/Close", hint :"Average Number of Calls to Close", xwidth : 75, dataType : "number", format : { type : "fixedPoint", precision : 1 }, headerCellTemplate : headerCellTemplate },
{ dataField : "avgItemsPerCall", caption : "Items/Call", hint : "Average Number of Items per Call", xwidth : 75, dataType : "number", format : { type : "fixedPoint", precision : 1 }, headerCellTemplate : headerCellTemplate }
],
onCellPrepared: function(e) {
if (e.rowType === "data") {
if (e.column.dataField === "newAccountsPct" && e.data.newAccounts ) {
e.cellElement.attr( { "title" : `${e.data.newAccounts} New Accounts` } );
}
if (e.column.dataField === "uniqueAccountsPct" && e.data.uniqueAccounts ) {
e.cellElement.attr( { "title" : `${e.data.uniqueAccounts} Unique Accounts` } );
}
}
},
onCellClick : function( e ) {
if( e.rowType != "data" ) return;
instance.viewInteractions( e.data );
},
onToolbarPreparing : function( e ) {
if( ! e.toolbarOptions.items ) {
e.toolbarOptions.items = [];
}
let dataGrid = e.component;
e.toolbarOptions.items.push( { location: "after", widget : "dxButton",
options : {
hint : "Excel Export",
icon : "export",
onClick : function( e ) {
Fse.UI.DataGridHelper.exportDataGrid( { dataGrid : dataGrid, fileName : "salescallperformance.xlsx" } );
}}});
}
}).dxDataGrid("instance");
}
SalesCallPerformanceWidget.prototype.viewInteractions = function( data ) {
let instance = this;
let itemParams = instance.widgetOptions.config;
let dashboard = instance.widgetOptions.dashboard;
let anlayzerSearchReady = $.Deferred();
let analyzerParams = {
disposition : 'X',
interactionDateStart : itemParams.interactionDateStart,
interactionDateEnd : itemParams.interactionDateEnd,
interactionDateRange : itemParams.interactionDateRange,
excludeDirectMarketing : true
};
if( itemParams.territoryPath ) {
analyzerParams.territoryPath = itemParams.territoryPath;
}
if( itemParams.salesRepId ) {
analyzerParams.salesRepId = itemParams.salesRepId;
}
if( itemParams.partnerType ) {
analyzerParams.partnerType = itemParams.partnerType;
}
if( itemParams.mfr_id ) {
analyzerParams.mfr_id = itemParams.mfr_id;
}
if( itemParams.salesRepOwnerType ) {
analyzerParams.salesRepOwnerType = itemParams.salesRepOwnerType
}
if( itemParams.excludeDeletedSalesReps ) {
analyzerParams.excludeDeletedSalesReps = true
}
if( itemParams.clientSegPath ) {
analyzerParams.clientSegPath = itemParams.clientSegPath
}
if( itemParams.interactionMethod ) {
analyzerParams.interactionMethod = itemsParams.interactionMethod;
}
if( itemParams.groupType == "salesRep" ) {
console.log( data );
analyzerParams.salesRepId = data.groupId;
anlayzerSearchReady.resolve();
} else if ( itemParams.groupType == "territory" ) {
// get the territory path for a territoryId (groupId)
let territoryStore = Fse.Data.newDataSource( { object : "TER.salesTerritories", key : "TerritoryId" } ).store();
territoryStore.byKey( data.groupId ).done( function( territoryData ) {
analyzerParams.territoryPath = territoryData.territoryPath;
anlayzerSearchReady.resolve();
})
} else if ( itemParams.groupType == "region" ) {
// get the territory path for a territoryName (groupId )
let regionDataSource = Fse.Data.newDataSource( { object : "TER.salesTerritories", key : "TerritoryId", paginate : false, filter : [ "territoryName", "=", data.groupId ] } )
regionDataSource.load().done( function( regions ) {
if( regions.length ) {
analyzerParams.territoryPath = regions[0].territoryPath;
anlayzerSearchReady.resolve();
}
})
} else {
anlayzerSearchReady.resolve();
}
anlayzerSearchReady.done( function() {
dashboard.tabSearch( "InteractionAnalyzer", analyzerParams )
})
}
SalesCallPerformanceWidget.prototype.edit = function( applyFn ) {
let instance = this;
if( ! instance.preferencesPopup ) {
const items = [];
items.push( { label : { location : "left", text : "Territory" },
dataField : "territoryPath",
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"
})
});
items.push( { label : { text : "Sales Rep", location : "left" },
dataField : "salesRepId",
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", objectParams : { version : 2 } } ),
searchExpr : "valueName",
searchMode : "contains",
displayExpr : "valueName",
multipleSelectedDisplay : "Multiple Sales Reps Selected",
keyExpr : "valueId",
title : "Select Sales Reps"
})
});
if( Fse.Portal.appConfiguration.STP.ownerType === "MFR" ) {
let staffTypeList = [
{ "text": "Manufacturer Staff Only" , "staffType": "MFR"},
{ "text": "Broker Staff Only" ,"staffType": "BRO"}
];
items.push( { label : { location : "left", text : "Staff Type" }, dataField : "salesRepOwnerType",
editorType : "dxSelectBox",
cssClass : instance.activeFilterPreferences.salesRepOwnerType ? 'fx-active-preference' : null,
editorOptions : {
dataSource: { store : { type : "array", data : staffTypeList, key : "staffType" }},
displayExpr: "text",
valueExpr : "staffType",
placeholder : "Select Staff Type",
showClearButton: true
}
})
}
items.push( {
dataField : "excludeDeletedSalesReps", label : { text : "Exclude Inactive & Deleted Sales Reps" }, editorType : "dxSwitch"
})
items.push( { label : { location : "left", text : "Call Date" },
dataField : "interactionDateRange",
editorType : "dxDropDownBox",
editorOptions : Fse.UI.dateRangePickerOptions( {
applyCustomDateRange : function( startDate, endDate ) {
instance.preferencesForm.updateData( { interactionDateStart : startDate, interactionDateEnd : endDate } )
}
} )
} )
if( Fse.Portal.appConfiguration.STP.ownerType === "BRO" ) {
items.push( { label : { location : "left", text : "Manufacturer" },
dataField : "mfr_id",
editorType : "dxDropDownBox",
cssClass : instance.activeFilterPreferences.mfr_id ? 'fx-active-preference' : null, // scrum 46030
editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( {
dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "PRD.manufacturers", keyField : "mfr_id" } ),
searchExpr : "mfr_name",
searchMode : "contains",
displayExpr : "mfr_name",
multipleSelectedDisplay : "Multiple Manufacturers Selected",
keyExpr : "mfr_id",
title : "Select Manufacturer"
})
})
}
items.push( {
label : { text : "Customer Type" },
dataField : "partnerType",
editorType : "dxSelectBox",
editorOptions : {
showClearButton : true,
dataSource : {
store : {
type : "array",
data : [ { text : "Operators", partnerType : "OPR"}, { text : "Distributors", partnerType : "CDR" } ],
key : "partnerType"
}
},
displayExpr : "text",
valueExpr : "partnerType",
placeholder : "Select Customer Type"
}
})
items.push( {
dataField : "groupType",
label : { text : "Group by" },
editorType : "dxSelectBox",
editorOptions : {
dataSource : { store : instance.groupTypesStore },
displayExpr : "text",
valueExpr : "groupType"
}
});
items.push({ dataField : "clientSegPath", label : { location : "left", text : "Segment" }, editorType : "dxDropDownBox",
cssClass : instance.activeFilterPreferences.clientSegPath ? 'fx-active-preference' : null,
editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( {
dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "SPL.segments", keyField : "clientSegPath" } ),
searchExpr : "clientSegPath",
searchMode : "contains",
displayExpr : "clientSegPath",
multipleSelectedDisplay : "Multiple Segments Selected",
keyExpr : "clientSegPath",
title : "Select Segments"
})
});
items.push( { label : { location : "left", text : "Call Method" },
dataField : "interactionMethod",
editorType : "dxDropDownBox",
editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( {
dataSource : Fse.Data.newDataSource( { object : "CRM.interactionMethods", key : "methodCode" } ),
searchExpr : "methodName",
displayExpr : "methodName",
searchMode : "contains",
multipleSelectedDisplay : "Multiple Methods Selected",
keyExpr : "methodCode",
title : "Select Method"
})
})
if( Object.keys( instance.activeFilterPreferences ).length ) {
items.push( {
template : function() {
let annotation = $("
").append( $("
").addClass( "dx-field-item-label-text" ).append( "*filter preference active")).addClass( "fx-active-preference" ).css( { "cursor" : "pointer" } );
annotation.on( "click", function( e ) {
// if the global filter preferences are applied, then close this popup
let onSaveFilterPreferences = function() {
instance.preferencesPopup.hide();
}
instance.widgetOptions.dashboard.editFilterPreferences( onSaveFilterPreferences );
})
return annotation;
}
})
}
let formData = {
territoryPath : instance.widgetOptions.config.territoryPath,
salesRepId : instance.widgetOptions.config.salesRepId,
mfr_id : instance.widgetOptions.config.mfr_id,
interactionDateStart : instance.widgetOptions.config.interactionDateStart,
insteractionDateEnd : instance.widgetOptions.config.interactionDateEnd,
interactionDateRange : instance.widgetOptions.config.interactionDateRange,
partnerType : instance.widgetOptions.config.partnerType,
groupType : instance.widgetOptions.config.groupType,
salesRepOwnerType : instance.widgetOptions.config.salesRepOwnerType,
excludeDeletedSalesReps : instance.widgetOptions.config.excludeDeletedSalesReps,
clientSegPath : instance.widgetOptions.config.clientSegPath,
interactionMethod : instance.widgetOptions.config.interactionMethod
};
instance.preferencesPopup = $("").dxPopup( {
title : "Preferences",
width : 450, height : "auto",
position : { my : "right top", at : "right top", of : instance.widgetOptions.portlet },
hideOnOutsideClick : true,
contentTemplate : function() {
instance.preferencesForm = $("
").dxForm( {
colCount : 1,
items : items,
} ).dxForm("instance");
instance.preferencesForm.updateData( formData );
return instance.preferencesForm.element();
},
toolbarItems : [
{ // scrum 49810.14
toolbar : "bottom",
location : "after",
widget : "dxButton",
options : {
text : "Use Defaults",
type : "normal",
onClick : function() {
instance.preferencesPopup.hide();
applyFn( instance.getDefaultConfig() );
}
}
},
{
toolbar : "bottom",
location : "after",
widget : "dxButton",
options : {
text : "Apply",
type : "default",
onClick : function() {
instance.preferencesPopup.hide();
applyFn( instance.preferencesForm.option( "formData" ) );
}
}
} ]
} ).dxPopup( "instance" );
instance.preferencesPopup.element().appendTo( "body" );
}
instance.preferencesPopup.show();
}
Fse.Portal.addWidgetFactory( "SalesCallPerformanceWidget", function( widgetDef ) {
return new SalesCallPerformanceWidget( widgetDef );
})