Custom KPI & Hashtag Queries on Saleslogix Mobile 3.0
Posted By: nicocrm on November 1st, 2013 in Saleslogix, SLX Mobile
No Gravatar

KPI and Hash tag queries are 2 new exciting features of Mobile 3.0. Together they allow convenient adhoc reporting in the field. In this post I will review how to add your own queries and KPI for a custom entity (SalesOrder – which is actually a stock Saleslogix entity, but is not available by default on the mobile client). This assumes familiarity with how to develop your own custom module and defining the list view for it. This is still a new feature for me so I won’t go too deep in the details, specifically I won’t go over configuration of the chart. Also, this is taken from a live customization so some of the properties are not available on the default Saleslogix entity – you’ll have to adapt to your own use case of course.

Hash tag queries are easy – you just need to define the hashTagQueries property on your list class:

hashTagQueries: {
   'shipped-this-week': 'ActualShipDate ge "' + dateAdd(-7) + '"',
   'shipping-this-week': 'DatePromised le "' + dateAdd(7) + '" and ActualShipDate eq ""',
   'shipping-today': 'DatePromised lt "' + dateAdd(1) + '" and ActualShipDate eq ""',
   'pending': 'Status like "Pending%"',
   'shorted-this-week': 'ActualShipDate ge "' + dateAdd(-7) + '" and OrderShorted eq true'
},

Instead of a string you can also use a function that returns a string if it needs to be dynamic. As you can see the queries are simply hard coded in the class and whatever is made available there, will be available for the user to select.

KPIs are a little bit more involved because there is a degree of user configurability – the metric that they select stay enabled between sessions and when they do a different query, so this is stored in the application preferences, which are stored in the browser’s localStorage (as a side note you can review the localStorage for the current site on the Chrome developer tools “Resources” tab). In fact the entire metric definition is stored in the preferences, not just the configurable part. This is important to know because it means that your users will have to clear their preferences in order to get the updated metric definition. For development purposes, the most convenient way I found to do it was to use a Chrome “incognito” window (aka “porn mode”) and just close it and open a new one when I want a full reload.

As for how the KPIs are actually defined, this is also a bit different because of where they are loaded – you can’t just add the definition to your list class. Similar to how we have to hack the Saleslogix Application object to change the default views definition, its “setDefaultMetricPreferences” method needs to be extended inside of your custom module’s loadCustomizations method. For example using the dojo/aspect module:

aspect.after(SalesLogixApplication.prototype, "setDefaultMetricPreferences", function () {
    var metrics = this.preferences.metrics;
    if (!metrics.salesorders) {
        metrics.salesorders = [
        {
            "title": "Total Cases",
            "queryName": "executeMetric",
            "queryArgs": {
                "_filterName": "AccountManager",
                "_metricName": "TotalQuantityMetric"
            },
            "metricDisplayName": "Total Cases",
            "filterDisplayName": "Vendor",
            "chartType": "bar",
            "aggregate": "sum",
            "formatter": "bigNumber",
            "enabled": false
        },
        {
            "title": "Total Lbs",
            "queryName": "executeMetric",
            "queryArgs": {
                "_filterName": "AccountManager",
                "_metricName": "TotalWeightMetric"
            },
            "metricDisplayName": "Total Lbs",
            "filterDisplayName": "Vendor",
            "chartType": "bar",
            "aggregate": "sum",
            "formatter": "bigNumber",
            "enabled": false
        },
        {
            "title": "Total $",
            "queryName": "executeMetric",
            "queryArgs": {
                "_filterName": "AccountManager",
                "_metricName": "OrderTotalMetric"
            },
            "metricDisplayName": "Total $",
            "filterDisplayName": "Vendor",
            "chartType": "bar",
            "aggregate": "sum",
            "formatter": "bigNumber",
            "enabled": false
        }
        ];
        this.persistPreferences();
    }
});

A few things to note:

  • - both “_filterName” and “_metricName” must be defined inside of “queryArgs”, otherwise the query will not run
  • - the “enabled”: false refers to the default state of the widget – i.e. whether it’s selected by default or not
  • - _metricName refers to a metric defined in AA (under filters, similar to how we do it for SlxClient dashboards)
  • - _filterName is the group that is used on the chart. This needs to be chosen carefully because if you select a filter that is based on ranges, the server will send 1 query per range to the database!! For example if you select AccountName as filter, and the AccountName filter is defined using a range of 1 letter as is common, the database will have to run 27 queries, obviously this is terrible for performance when we only need to get the total. If you select a filter based on distinct, then the system will send a “group by” query, this is still some extra work to be performed by the database (and then on the client since we have to sum the results to display only the total), but at least it’s only 1 query. So basically choose your filter well (I am sure in the near future the widget will be optimized to not send the filter name for the totals display but for now it is what it is)
  • - “chartType”, “aggregate” and “formatter” are in theory extension points where you could load your own module to perform the calculation but I have not had the chance to mess with them yet

That’s it for now, hope it gives you a head start.


Leave a Reply