From 5b49fb3044055dac0ac1b241230817ad50c8e09b Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 3 Mar 2022 17:55:19 +0000 Subject: [PATCH] --- docs/8.0/ayanova/docs/home-dashboard.md | 2 +- server/AyaNova/kpi/KPIFactory.cs | 20 ++++--- server/AyaNova/kpi/WorkOrderStatusCount.cs | 62 ++++++++++++++++++++ server/AyaNova/kpi/WorkOrderStatusPct.cs | 68 ++++++++++++++++++++++ server/AyaNova/resource/de.json | 2 + server/AyaNova/resource/en.json | 2 + server/AyaNova/resource/es.json | 2 + server/AyaNova/resource/fr.json | 2 + server/AyaNova/util/Seeder.cs | 2 +- 9 files changed, 152 insertions(+), 10 deletions(-) create mode 100644 server/AyaNova/kpi/WorkOrderStatusCount.cs create mode 100644 server/AyaNova/kpi/WorkOrderStatusPct.cs diff --git a/docs/8.0/ayanova/docs/home-dashboard.md b/docs/8.0/ayanova/docs/home-dashboard.md index f8c4fa8d..b1ff7bb5 100644 --- a/docs/8.0/ayanova/docs/home-dashboard.md +++ b/docs/8.0/ayanova/docs/home-dashboard.md @@ -309,7 +309,7 @@ Available filter criteria: Management bar chart showing the percentage of work orders that were completed on time for the criteria selected. -Work orders created within the time span criteria selected that have a date to be completed date in the past are queried. +The data displayed is from work orders *created* within the time span criteria selected that also have a *date to be completed* in the past that were completed on time. Completed on time means work orders that were set to a [Completed work order status](svc-work-order-status.md#is-a-completed-status) before the Work order's [date to be completed setting](svc-workorders.md#date-to-be-completed). diff --git a/server/AyaNova/kpi/KPIFactory.cs b/server/AyaNova/kpi/KPIFactory.cs index a30c0b93..5f7874c9 100644 --- a/server/AyaNova/kpi/KPIFactory.cs +++ b/server/AyaNova/kpi/KPIFactory.cs @@ -25,6 +25,10 @@ namespace AyaNova.KPI return new WorkOrderOverdueAllList() as IAyaKPI; case "WorkOrderCreatedCount": return new WorkOrderCreatedCount() as IAyaKPI; + case "WorkOrderStatusCount": + return new WorkOrderStatusCount() as IAyaKPI; + case "WorkOrderStatusPct": + return new WorkOrderStatusPct() as IAyaKPI; case "WorkOrderCompletedOnTimePct": return new WorkOrderCompletedOnTimePct() as IAyaKPI; @@ -35,15 +39,15 @@ namespace AyaNova.KPI //return null; } - //List all the KPI types available - internal static List GetListOfAllKPI() - { - List ret = new List(); + // //List all the KPI types available + // internal static List GetListOfAllKPI() + // { + // List ret = new List(); - ret.Add("WorkOrderItemLaborQuantitySummary"); - ret.Add("WorkOrderUnscheduledOpenList"); + // ret.Add("WorkOrderItemLaborQuantitySummary"); + // ret.Add("WorkOrderUnscheduledOpenList"); - return ret; - } + // return ret; + // } }//eoc }//eons \ No newline at end of file diff --git a/server/AyaNova/kpi/WorkOrderStatusCount.cs b/server/AyaNova/kpi/WorkOrderStatusCount.cs new file mode 100644 index 00000000..db35752f --- /dev/null +++ b/server/AyaNova/kpi/WorkOrderStatusCount.cs @@ -0,0 +1,62 @@ +using AyaNova.Biz; +using AyaNova.DataList; +using System.Collections.Generic; + +namespace AyaNova.KPI +{ + internal class WorkOrderStatusCount : IAyaKPI + { + private string _metaQuery = null; + private string _dataQuery = null; + private string _errorMessage = null; + + public AuthorizationRoles AllowedRoles + { + get => AuthorizationRoles.BizAdmin + | AuthorizationRoles.BizAdminRestricted + | AuthorizationRoles.ServiceRestricted + | AuthorizationRoles.Service + | AuthorizationRoles.Accounting; + } + + public string MetaQuery => _metaQuery; + public string DataQuery => _dataQuery; + public string ErrorMessage => _errorMessage; + + public void BuildQuery(KPIRequestOptions options, long userId) + { + //build data and meta queries + + //validate criteria exists + if (!options.Criteria.ContainsKey("timeSpan")) + { + _errorMessage = "Missing 'timeSpan' criteria"; + return; + } + + if (!options.Criteria.ContainsKey("interval")) + { + _errorMessage = "Missing 'interval' criteria"; + return; + } + + var timeSpan = (string)options.Criteria["timeSpan"]; + var interval = (string)options.Criteria["interval"]; + var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorder.createddate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp); + var wotags = options.Criteria["wotags"].ToObject>(); + bool wotagsany = options.Criteria["wotagsany"].ToObject(); + string woTagsWhere = DataListSqlFilterCriteriaBuilder.KPITagFilterToSqlCriteria("aworkorder.tags", wotags, wotagsany); + + _dataQuery = @$"SELECT row_to_json(t) as res from ( + SELECT COUNT(AWORKORDER.ID) Y,DATE_TRUNC('{interval}', AWORKORDER.createddate) X, aworkorder.laststatusid Z + FROM AWORKORDER + LEFT JOIN AWORKORDERSTATUS ON (AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID) WHERE {dateWhere} {woTagsWhere} + GROUP BY Z, X + ORDER BY X ASC + ) t"; + _metaQuery = @"SELECT row_to_json(t) as res from (select id, name, color from aworkorderstatus order by name asc) t"; + } + + + }//eoc +}//eons \ No newline at end of file diff --git a/server/AyaNova/kpi/WorkOrderStatusPct.cs b/server/AyaNova/kpi/WorkOrderStatusPct.cs new file mode 100644 index 00000000..6ddbb449 --- /dev/null +++ b/server/AyaNova/kpi/WorkOrderStatusPct.cs @@ -0,0 +1,68 @@ +using AyaNova.Biz; +using AyaNova.DataList; +using System.Collections.Generic; + +namespace AyaNova.KPI +{ + internal class WorkOrderStatusPct : IAyaKPI + { + private string _metaQuery = null; + private string _dataQuery = null; + private string _errorMessage = null; + + public AuthorizationRoles AllowedRoles + { + get => AuthorizationRoles.BizAdmin + | AuthorizationRoles.BizAdminRestricted + | AuthorizationRoles.ServiceRestricted + | AuthorizationRoles.Service + | AuthorizationRoles.Accounting; + } + + public string MetaQuery => _metaQuery; + public string DataQuery => _dataQuery; + public string ErrorMessage => _errorMessage; + + public void BuildQuery(KPIRequestOptions options, long userId) + { + //build data and meta queries + + //validate criteria exists + if (!options.Criteria.ContainsKey("timeSpan")) + { + _errorMessage = "Missing 'timeSpan' criteria"; + return; + } + + if (!options.Criteria.ContainsKey("interval")) + { + _errorMessage = "Missing 'interval' criteria"; + return; + } + + var timeSpan = (string)options.Criteria["timeSpan"]; + var interval = (string)options.Criteria["interval"]; + var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorder.createddate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp); + var wotags = options.Criteria["wotags"].ToObject>(); + bool wotagsany = options.Criteria["wotagsany"].ToObject(); + string woTagsWhere = DataListSqlFilterCriteriaBuilder.KPITagFilterToSqlCriteria("aworkorder.tags", wotags, wotagsany); + + _dataQuery = @$"SELECT row_to_json(t) as res from ( + WITH SUBQ AS + (SELECT COUNT(AWORKORDER.ID) WOCOUNT, DATE_TRUNC('{interval}', AWORKORDER.CREATEDDATE) X, + AWORKORDER.LASTSTATUSID Z + FROM AWORKORDER + LEFT JOIN AWORKORDERSTATUS ON (AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID) + WHERE {dateWhere} {woTagsWhere} + GROUP BY Z, X) + SELECT X,Z, + ROUND(WOCOUNT / SUM(WOCOUNT) OVER (PARTITION BY X) * 100,2) AS Y + FROM SUBQ + ORDER BY X ASC, y desc + ) t"; + _metaQuery = @"SELECT row_to_json(t) as res from (select id, name, color from aworkorderstatus order by name asc) t"; + } + + + }//eoc +}//eons \ No newline at end of file diff --git a/server/AyaNova/resource/de.json b/server/AyaNova/resource/de.json index 7497b83d..366863fe 100644 --- a/server/AyaNova/resource/de.json +++ b/server/AyaNova/resource/de.json @@ -235,6 +235,8 @@ "DashboardOpenCSR":"Offene Serviceanfragen", "DashboardCountWorkOrdersCreated": "Anzahl der erstellten Arbeitsaufträge", "DashboardPctWorkOrderCompletedOnTime": "% Arbeitsaufträge pünktlich abgeschlossen", + "DashboardWorkOrderStatusCount":"Anzahl der Arbeitsaufträge nach Status", + "DashboardWorkOrderStatusPct":"% der Arbeitsaufträge nach Status", "Database": "Datenbank", "DatabaseID": "Datenbank-ID", "DataListSavedFilter": "Listenfilter", diff --git a/server/AyaNova/resource/en.json b/server/AyaNova/resource/en.json index d3715ab3..5f987287 100644 --- a/server/AyaNova/resource/en.json +++ b/server/AyaNova/resource/en.json @@ -235,6 +235,8 @@ "DashboardOpenCSR": "Open service requests", "DashboardCountWorkOrdersCreated": "Count of Work orders created", "DashboardPctWorkOrderCompletedOnTime": "% Work orders completed on time", + "DashboardWorkOrderStatusCount":"Count of work orders by status", + "DashboardWorkOrderStatusPct":"% of work orders by status", "Database": "Database", "DatabaseID": "Database ID", "DataListSavedFilter": "List filter", diff --git a/server/AyaNova/resource/es.json b/server/AyaNova/resource/es.json index 81f59452..ca194b00 100644 --- a/server/AyaNova/resource/es.json +++ b/server/AyaNova/resource/es.json @@ -235,6 +235,8 @@ "DashboardOpenCSR":"Solicitudes de servicio abiertas", "DashboardCountWorkOrdersCreated": "Recuento de órdenes de trabajo creadas", "DashboardPctWorkOrderCompletedOnTime": "% de órdenes de trabajo completadas a tiempo", + "DashboardWorkOrderStatusCount":"Recuento de órdenes de trabajo por estado", + "DashboardWorkOrderStatusPct":"% de órdenes de trabajo por estado", "Database": "Base de datos", "DatabaseID": "Id. de base de datos", "DataListSavedFilter": "Filtro de lista", diff --git a/server/AyaNova/resource/fr.json b/server/AyaNova/resource/fr.json index 83068797..7ce866bf 100644 --- a/server/AyaNova/resource/fr.json +++ b/server/AyaNova/resource/fr.json @@ -235,6 +235,8 @@ "DashboardOpenCSR":"Demandes de service - ouvertes", "DashboardCountWorkOrdersCreated": "Nombre de bons de travail créés", "DashboardPctWorkOrderCompletedOnTime": "% des ordres de travail terminés à temps", + "DashboardWorkOrderStatusCount":"Nombre d'ordres de travail par statut", + "DashboardWorkOrderStatusPct":"% des bons de travail par statut", "Database": "Base de données", "DatabaseID": "ID base de données", "DataListSavedFilter": "Filtre de liste", diff --git a/server/AyaNova/util/Seeder.cs b/server/AyaNova/util/Seeder.cs index aebc4ec1..84fc2a06 100644 --- a/server/AyaNova/util/Seeder.cs +++ b/server/AyaNova/util/Seeder.cs @@ -1138,7 +1138,7 @@ namespace AyaNova.Util WorkOrderStatus stat = new WorkOrderStatus(); stat.Name = "Closed"; stat.Active = true; - stat.Color = "#FCF1C2";//maybe white is better? I.e. no color basically + stat.Color = "#CDC4AA";//boring oatmeal stat.Completed = true; stat.Locked = true; stat.SelectRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;