This commit is contained in:
2022-03-03 17:55:19 +00:00
parent baa4eb36f9
commit 5b49fb3044
9 changed files with 152 additions and 10 deletions

View File

@@ -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. 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). 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).

View File

@@ -25,6 +25,10 @@ namespace AyaNova.KPI
return new WorkOrderOverdueAllList() as IAyaKPI; return new WorkOrderOverdueAllList() as IAyaKPI;
case "WorkOrderCreatedCount": case "WorkOrderCreatedCount":
return new WorkOrderCreatedCount() as IAyaKPI; return new WorkOrderCreatedCount() as IAyaKPI;
case "WorkOrderStatusCount":
return new WorkOrderStatusCount() as IAyaKPI;
case "WorkOrderStatusPct":
return new WorkOrderStatusPct() as IAyaKPI;
case "WorkOrderCompletedOnTimePct": case "WorkOrderCompletedOnTimePct":
return new WorkOrderCompletedOnTimePct() as IAyaKPI; return new WorkOrderCompletedOnTimePct() as IAyaKPI;
@@ -35,15 +39,15 @@ namespace AyaNova.KPI
//return null; //return null;
} }
//List all the KPI types available // //List all the KPI types available
internal static List<string> GetListOfAllKPI() // internal static List<string> GetListOfAllKPI()
{ // {
List<string> ret = new List<string>(); // List<string> ret = new List<string>();
ret.Add("WorkOrderItemLaborQuantitySummary"); // ret.Add("WorkOrderItemLaborQuantitySummary");
ret.Add("WorkOrderUnscheduledOpenList"); // ret.Add("WorkOrderUnscheduledOpenList");
return ret; // return ret;
} // }
}//eoc }//eoc
}//eons }//eons

View File

@@ -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<List<string>>();
bool wotagsany = options.Criteria["wotagsany"].ToObject<bool>();
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

View File

@@ -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<List<string>>();
bool wotagsany = options.Criteria["wotagsany"].ToObject<bool>();
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

View File

@@ -235,6 +235,8 @@
"DashboardOpenCSR":"Offene Serviceanfragen", "DashboardOpenCSR":"Offene Serviceanfragen",
"DashboardCountWorkOrdersCreated": "Anzahl der erstellten Arbeitsaufträge", "DashboardCountWorkOrdersCreated": "Anzahl der erstellten Arbeitsaufträge",
"DashboardPctWorkOrderCompletedOnTime": "% Arbeitsaufträge pünktlich abgeschlossen", "DashboardPctWorkOrderCompletedOnTime": "% Arbeitsaufträge pünktlich abgeschlossen",
"DashboardWorkOrderStatusCount":"Anzahl der Arbeitsaufträge nach Status",
"DashboardWorkOrderStatusPct":"% der Arbeitsaufträge nach Status",
"Database": "Datenbank", "Database": "Datenbank",
"DatabaseID": "Datenbank-ID", "DatabaseID": "Datenbank-ID",
"DataListSavedFilter": "Listenfilter", "DataListSavedFilter": "Listenfilter",

View File

@@ -235,6 +235,8 @@
"DashboardOpenCSR": "Open service requests", "DashboardOpenCSR": "Open service requests",
"DashboardCountWorkOrdersCreated": "Count of Work orders created", "DashboardCountWorkOrdersCreated": "Count of Work orders created",
"DashboardPctWorkOrderCompletedOnTime": "% Work orders completed on time", "DashboardPctWorkOrderCompletedOnTime": "% Work orders completed on time",
"DashboardWorkOrderStatusCount":"Count of work orders by status",
"DashboardWorkOrderStatusPct":"% of work orders by status",
"Database": "Database", "Database": "Database",
"DatabaseID": "Database ID", "DatabaseID": "Database ID",
"DataListSavedFilter": "List filter", "DataListSavedFilter": "List filter",

View File

@@ -235,6 +235,8 @@
"DashboardOpenCSR":"Solicitudes de servicio abiertas", "DashboardOpenCSR":"Solicitudes de servicio abiertas",
"DashboardCountWorkOrdersCreated": "Recuento de órdenes de trabajo creadas", "DashboardCountWorkOrdersCreated": "Recuento de órdenes de trabajo creadas",
"DashboardPctWorkOrderCompletedOnTime": "% de órdenes de trabajo completadas a tiempo", "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", "Database": "Base de datos",
"DatabaseID": "Id. de base de datos", "DatabaseID": "Id. de base de datos",
"DataListSavedFilter": "Filtro de lista", "DataListSavedFilter": "Filtro de lista",

View File

@@ -235,6 +235,8 @@
"DashboardOpenCSR":"Demandes de service - ouvertes", "DashboardOpenCSR":"Demandes de service - ouvertes",
"DashboardCountWorkOrdersCreated": "Nombre de bons de travail créés", "DashboardCountWorkOrdersCreated": "Nombre de bons de travail créés",
"DashboardPctWorkOrderCompletedOnTime": "% des ordres de travail terminés à temps", "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", "Database": "Base de données",
"DatabaseID": "ID base de données", "DatabaseID": "ID base de données",
"DataListSavedFilter": "Filtre de liste", "DataListSavedFilter": "Filtre de liste",

View File

@@ -1138,7 +1138,7 @@ namespace AyaNova.Util
WorkOrderStatus stat = new WorkOrderStatus(); WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Closed"; stat.Name = "Closed";
stat.Active = true; stat.Active = true;
stat.Color = "#FCF1C2";//maybe white is better? I.e. no color basically stat.Color = "#CDC4AA";//boring oatmeal
stat.Completed = true; stat.Completed = true;
stat.Locked = true; stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin; stat.SelectRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;