This commit is contained in:
17
server/AyaNova/kpi/IAyaKPI.cs
Normal file
17
server/AyaNova/kpi/IAyaKPI.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using AyaNova.Biz;
|
||||||
|
namespace AyaNova.KPI
|
||||||
|
{
|
||||||
|
internal interface IAyaKPI
|
||||||
|
{
|
||||||
|
//allowed roles to access this kpi
|
||||||
|
AuthorizationRoles AllowedRoles { get; }
|
||||||
|
|
||||||
|
//build the data and meta queries based on the criteria and this kpi's standard query
|
||||||
|
void BuildQuery(string criteria, DateTimeOffset clientTimeStamp);
|
||||||
|
string MetaQuery{get;}//Query to fetch json meta data for report purposes mainly (lookup stuff like names etc where applicable)
|
||||||
|
string DataQuery{get;}//Query to fetch json format data for result set
|
||||||
|
string ErrorMessage{get;}//if there was a problem then this is set with the error message
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
39
server/AyaNova/kpi/KPIFactory.cs
Normal file
39
server/AyaNova/kpi/KPIFactory.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using AyaNova.Biz;
|
||||||
|
using AyaNova.Models;
|
||||||
|
|
||||||
|
|
||||||
|
namespace AyaNova.KPI
|
||||||
|
{
|
||||||
|
internal static class KPIFactory
|
||||||
|
{
|
||||||
|
|
||||||
|
//Instantiate list object specified from type
|
||||||
|
internal static IAyaKPI GetAyaKPI(string name)
|
||||||
|
{
|
||||||
|
switch (name)
|
||||||
|
{
|
||||||
|
//CoreBizObject add here if it will be "picked" on any other form
|
||||||
|
case "WorkOrderItemLaborQuantitySummary":
|
||||||
|
return new WorkOrderItemLaborQuantitySummary() as IAyaKPI;
|
||||||
|
|
||||||
|
//@##### WARNING: BE SURE TO ADD NEW TYPES BELOW OR USERS WON"T BE ABLE TO EDIT THE TEMPLATE FOR THEM
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new System.NotImplementedException($"KPI {name} NOT IMPLEMENTED");
|
||||||
|
|
||||||
|
}
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//List all the KPI types available
|
||||||
|
internal static List<string> GetListOfAllKPI()
|
||||||
|
{
|
||||||
|
List<string> ret = new List<string>();
|
||||||
|
|
||||||
|
ret.Add("WorkOrderItemLaborQuantitySummary");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}//eoc
|
||||||
|
}//eons
|
||||||
139
server/AyaNova/kpi/KPIFetcher.cs
Normal file
139
server/AyaNova/kpi/KPIFetcher.cs
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
#define AYSHOWKPIQUERYINFO
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using AyaNova.Biz;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using AyaNova.Models;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AyaNova.KPI
|
||||||
|
{
|
||||||
|
internal static class KPIFetcher
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
// Get the kpi data requested
|
||||||
|
//
|
||||||
|
//
|
||||||
|
internal static async Task<JObject> GetResponseAsync(AyContext ct, string kpiName, string criteria, DateTimeOffset clientTimeStamp, AuthorizationRoles userRoles, ILogger log, long userId)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
return a jobject like:
|
||||||
|
{
|
||||||
|
error: "if error this key present",
|
||||||
|
meta: {username:"joe blow","date range:blah to blah"}
|
||||||
|
data:[{r1},{r2},{r3}]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//instantiate the list
|
||||||
|
var kpi = KPIFactory.GetAyaKPI(kpiName);
|
||||||
|
kpi.BuildQuery(criteria, clientTimeStamp);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(kpi.ErrorMessage))
|
||||||
|
{
|
||||||
|
return JObject.FromObject(new
|
||||||
|
{
|
||||||
|
error = kpi.ErrorMessage
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
System.Text.StringBuilder sbData = new System.Text.StringBuilder();
|
||||||
|
string sMeta = string.Empty;
|
||||||
|
|
||||||
|
#if (DEBUG && AYSHOWKPIQUERYINFO)
|
||||||
|
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//QUERY THE DB
|
||||||
|
using (var command = ct.Database.GetDbConnection().CreateCommand())
|
||||||
|
{
|
||||||
|
await ct.Database.OpenConnectionAsync();
|
||||||
|
|
||||||
|
//GET DATA RETURN ROWS
|
||||||
|
command.CommandText = kpi.DataQuery;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#if (DEBUG && AYSHOWKPIQUERYINFO)
|
||||||
|
stopWatch.Start();
|
||||||
|
#endif
|
||||||
|
using (var dr = await command.ExecuteReaderAsync())
|
||||||
|
{
|
||||||
|
#if (DEBUG && AYSHOWKPIQUERYINFO)
|
||||||
|
stopWatch.Stop();
|
||||||
|
log.LogInformation($"(debug) KPIFetcher:GetResponse DATA query took {stopWatch.ElapsedMilliseconds}ms to execute: {kpi.DataQuery}");
|
||||||
|
stopWatch.Reset();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (dr.Read())
|
||||||
|
{
|
||||||
|
//only one column and it's the zeroth json string column
|
||||||
|
if (!dr.IsDBNull(0))
|
||||||
|
sbData.Append(dr.GetString(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(kpi.MetaQuery))
|
||||||
|
{
|
||||||
|
//GET META DATA
|
||||||
|
command.CommandText = kpi.MetaQuery;
|
||||||
|
#if (DEBUG && AYSHOWQUERYINFO)
|
||||||
|
stopWatch.Start();
|
||||||
|
#endif
|
||||||
|
using (var dr = await command.ExecuteReaderAsync())
|
||||||
|
{
|
||||||
|
#if (DEBUG && AYSHOWQUERYINFO)
|
||||||
|
stopWatch.Stop();
|
||||||
|
log.LogInformation($"(debug) KPIFetcher:GetResponse META query took {stopWatch.ElapsedMilliseconds}ms to execute: {qTotalRecordsQuery}");
|
||||||
|
#endif
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
sMeta = dr.GetString(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Npgsql.PostgresException e)
|
||||||
|
{
|
||||||
|
//log out the exception and the query
|
||||||
|
log.LogError("KPIFetcher:GetResponseAsync query failed. Data Query was:");
|
||||||
|
log.LogError(kpi.DataQuery);
|
||||||
|
log.LogError("Meta Query was:");
|
||||||
|
log.LogError(kpi.MetaQuery);
|
||||||
|
log.LogError(e, "DB Exception");
|
||||||
|
throw new System.Exception("KPIFetcher:GetResponseAsync - Query failed see log");
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
//ensure any other type of exception gets surfaced properly
|
||||||
|
//log out the exception and the query
|
||||||
|
log.LogError("KPIFetcher:GetResponseAsync unexpected failure. Data Query was:");
|
||||||
|
log.LogError(kpi.DataQuery);
|
||||||
|
log.LogError("Meta Query was:");
|
||||||
|
log.LogError(kpi.MetaQuery);
|
||||||
|
log.LogError(e, "Exception");
|
||||||
|
throw new System.Exception("KPIFetcher:GetResponseAsync - unexpected failure see log");
|
||||||
|
}
|
||||||
|
|
||||||
|
return JObject.FromObject(new
|
||||||
|
{
|
||||||
|
meta = sMeta,
|
||||||
|
data = sbData
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}//eoc
|
||||||
|
}//eons
|
||||||
57
server/AyaNova/kpi/WorkOrderItemLaborQuantitySummary.cs
Normal file
57
server/AyaNova/kpi/WorkOrderItemLaborQuantitySummary.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using AyaNova.Biz;
|
||||||
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AyaNova.KPI
|
||||||
|
{
|
||||||
|
internal class WorkOrderItemLaborQuantitySummary : IAyaKPI
|
||||||
|
{
|
||||||
|
private string _metaQuery = null;
|
||||||
|
private string _dataQuery = null;
|
||||||
|
private string _errorMessage=null;
|
||||||
|
|
||||||
|
public AuthorizationRoles AllowedRoles { get => BizRoles.GetRoleSet(AyaType.WorkOrderItemLabor).ReadFullRecord; }
|
||||||
|
|
||||||
|
public string MetaQuery => _metaQuery;
|
||||||
|
public string DataQuery => _dataQuery;
|
||||||
|
public string ErrorMessage => _errorMessage;
|
||||||
|
|
||||||
|
public void BuildQuery(string criteria, DateTimeOffset clientTimeStamp)
|
||||||
|
{
|
||||||
|
//build data and meta queries
|
||||||
|
}
|
||||||
|
|
||||||
|
// public string GetVariantCriteria(string variant)
|
||||||
|
// {
|
||||||
|
// //Currently the only variant is a object type and id to indicate headoffice
|
||||||
|
|
||||||
|
// //ClientCriteria format for this list is "OBJECTID,AYATYPE"
|
||||||
|
// var crit = (variant ?? "").Split(',').Select(z => z.Trim()).ToArray();
|
||||||
|
// if (crit.Length > 1)
|
||||||
|
// {
|
||||||
|
// int nType = 0;
|
||||||
|
// if (!int.TryParse(crit[1], out nType)) return string.Empty;
|
||||||
|
// AyaType forType = (AyaType)nType;
|
||||||
|
// if (forType != AyaType.HeadOffice) return string.Empty;
|
||||||
|
|
||||||
|
// long lId = 0;
|
||||||
|
// if (!long.TryParse(crit[0], out lId)) return string.Empty;
|
||||||
|
// if (lId == 0) return string.Empty;
|
||||||
|
|
||||||
|
// //Have valid type, have an id, so filter away
|
||||||
|
// switch (forType)
|
||||||
|
// {
|
||||||
|
// case AyaType.HeadOffice:
|
||||||
|
// {
|
||||||
|
// return $"acustomer.headofficeid = {lId}";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return string.Empty;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}//eoc
|
||||||
|
}//eons
|
||||||
Reference in New Issue
Block a user