From e8d58ad83415dc43e12804ad6a7be8ed6e418ab7 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 3 Mar 2022 17:55:19 +0000 Subject: [PATCH] --- ayanova/devdocs/todo.txt | 116 ++---- ayanova/src/api/dash-registry.js | 42 ++ .../dash-labor-hours-everyone-bar.vue | 2 - .../dash-labor-hours-everyone-line.vue | 2 - .../dash-labor-hours-personal-bar.vue | 2 - .../dash-labor-hours-personal-line.vue | 2 - .../src/components/dash-today-reminders.vue | 2 - ...h-work-order-completed-on-time-pct-bar.vue | 21 - .../dash-work-order-created-count-bar.vue | 2 - .../dash-work-order-created-count-line.vue | 2 - .../dash-work-order-status-count-bar.vue | 362 +++++++++++++++++ .../dash-work-order-status-pct-bar.vue | 364 ++++++++++++++++++ ayanova/src/views/home-dashboard.vue | 6 +- 13 files changed, 815 insertions(+), 110 deletions(-) create mode 100644 ayanova/src/components/dash-work-order-status-count-bar.vue create mode 100644 ayanova/src/components/dash-work-order-status-pct-bar.vue diff --git a/ayanova/devdocs/todo.txt b/ayanova/devdocs/todo.txt index ddc1ccc5..26a28a43 100644 --- a/ayanova/devdocs/todo.txt +++ b/ayanova/devdocs/todo.txt @@ -31,7 +31,7 @@ FIRST CLIENT SOURCE CODE COMMIT JAN 3rd 2019 # SEEDING ISSUES -??seeder wo created date not set properly, should match the way it's generated +seeder, make a few wo that are not completed in time in each month seeder make reminders and reviews for all users, just random scattering for now to future month ahead at least one per day to show off schedule and widgets seeder wo need new fields and generate data to show off and test kpi widgets and features @@ -45,84 +45,50 @@ seeder wo need new fields and generate data to show off and test kpi widgets and # WIDGETS -https://www.calculator.net/percent-calculator.html + +Should LIST types have a fixed limit of maximum records returned?? + i.e. no more than 500 or something? + if reaches the limit then says "500 limit reached" in the list as the last item? - Widgets to make for beta in order of priority **MUST HAVE*** - - - BAR % wo completed status vs not completed by completed date within interval - query is - all wo not completed that should be by now within the interval vs all that were completed within the interval, count up each, count up the total and present as a pct for that interval - count of wo with complete by in the interval and not closed / count of wo with complete by within the interval and closed - group by convert completed or not into a simple bool so group by completed then by interval like the multiple techs ones as a framework - - criteria: - timespan, interval - tags wo - -SELECT COUNT(AWORKORDER.ID) Y, -DATE_TRUNC('month',AWORKORDER.createddate) X, -(LASTSTATUSID IS NULL OR AWORKORDERSTATUS.COMPLETED = FALSE) Z -FROM AWORKORDER -LEFT JOIN AWORKORDERSTATUS ON (AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID) -where AWORKORDER.COMPLETEBYDATE < NOW() -GROUP BY X,Z -ORDER BY X ASC - -with subq as ( - SELECT COUNT(AWORKORDER.ID) wocount, - DATE_TRUNC('month',AWORKORDER.createddate) x, - (LASTSTATUSID IS NULL OR AWORKORDERSTATUS.COMPLETED = FALSE) z - FROM AWORKORDER - LEFT JOIN AWORKORDERSTATUS ON (AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID) - where AWORKORDER.COMPLETEBYDATE < NOW() - GROUP BY x,z -) -select X,Z, - wocount / sum(wocount) over (partition by X) * 100 as Y -from subq -order by x ASC; - -... -WITH SUBQ AS - (SELECT COUNT(AWORKORDER.ID) WOCOUNT, - DATE_TRUNC('month', AWORKORDER.CREATEDDATE) X, - (aworkorder.laststatusid is not null AND AWORKORDERSTATUS.COMPLETED = TRUE AND laststate.created < aworkorder.completebydate) Z - FROM AWORKORDER - LEFT JOIN AWORKORDERSTATUS ON (AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID) - LEFT JOIN LATERAL - - (SELECT created - FROM aworkorderstate - WHERE aworkorderstate.workorderid = aworkorder.id - ORDER BY aworkorderstate.created DESC - LIMIT 1) AS laststate ON TRUE - - WHERE AWORKORDER.COMPLETEBYDATE < NOW() - AND AWORKORDER.CREATEDDATE > '1753-01-02T08:00:59.9990000Z' - AND AWORKORDER.CREATEDDATE < '2022-03-03T01:00:00.0000000Z' - - GROUP BY X,Z) -SELECT X,Z, - ROUND(WOCOUNT / SUM(WOCOUNT) OVER (PARTITION BY X) * 100,2) AS Y -FROM SUBQ -ORDER BY X ASC -... - - - - - BAR-VERT Billable hours leader board case 3696: https://www.openfaas.com/blog/serverless-single-page-app/?utm_source=DigitalOcean_Newsletter - criteria: - timespan, interval - tags wo + BAR Count of wo within each status by time period / tags shows all status types that are in the data returned only, not *all* status though I think it does that automatically future: click on status bar it opens a filtered list of all wo by that status + +SELECT COUNT(AWORKORDER.ID) Y,DATE_TRUNC('month', AWORKORDER.createddate) X, aworkorder.laststatusid Z +FROM AWORKORDER +LEFT JOIN AWORKORDERSTATUS ON (AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID) +WHERE AWORKORDER.createddate >'2022-01-01T07:59:59.9990000Z' AND AWORKORDER.createddate <'2023-01-01T08:00:00.0000000Z' +GROUP BY Z, X +ORDER BY X ASC + + - LIST work orders by status (case 1974) + BAR same as above?? but by % wo within each status by time range / tags + this will show the state of things overall + + WITH SUBQ AS + (SELECT COUNT(AWORKORDER.ID) WOCOUNT, DATE_TRUNC('month', AWORKORDER.CREATEDDATE) X, + AWORKORDER.LASTSTATUSID Z + FROM AWORKORDER + LEFT JOIN AWORKORDERSTATUS ON (AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID) + WHERE AWORKORDER.CREATEDDATE > '2022-01-01T07:59:59.9990000Z' + AND AWORKORDER.CREATEDDATE < '2023-01-01T08:00:00.0000000Z' + 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 + + + + LIST work orders by status (case 1974) + this *does* make sense because it can be hyper specific to something like a "waiting for parts" status so + if that is useful to a user then can see that list + needs limit, could bring in thousands if not careful criteria: wo status timespan @@ -132,13 +98,12 @@ ORDER BY X ASC **NICE TO HAVE** (these are not triaged yet) - DASHBOARD:CR - open wo list by selectable status case 1974 + avg time or time breakdown by % of overdueness of workorders i.e. 10% of overdue were x days overdue etc avg time in each status by time period / tags this could cover response time as they can just designate a status as unresponded or new - % wo within each status by time range / tags - this will show the state of things overall + @@ -930,6 +895,9 @@ BUILD 8.0.0-beta.1-rc3 CHANGES OF NOTE - added dashboard widget Service rate quantity showing personal service rate quantity on chart as line or bar version - added dashboard widget Service rate quantity - All showing all selected criteria users service rate quantity on chart as line or bar version - added dashboard widget Count of work orders created per day over time as bar and line chart for management +- added dashboard widget % of work orders completed on time as bar chart for management +- TODO: statuscount +- TODO: status pct - Added *back* User color as it now ties in with widget charts (user edit form, import, backend, docs etc) - v8-migrate plugin, fixed new issue related to removal of unused locale / translation keys preventing migrate - Login form added prominent warning "beta test - not for production use" diff --git a/ayanova/src/api/dash-registry.js b/ayanova/src/api/dash-registry.js index 484ec858..0b9b8a94 100644 --- a/ayanova/src/api/dash-registry.js +++ b/ayanova/src/api/dash-registry.js @@ -5,6 +5,48 @@ const role = authorizationroles.AUTHORIZATION_ROLES; */ export default { registry: [ + { + roles: [ + role.BizAdmin, + role.BizAdminRestricted, + role.ServiceRestricted, + role.Service, + role.Accounting + ], + title: "DashboardWorkOrderStatusCount", + icon: "$ayiChartBar", + type: "GzDashWorkOrderStatusCount", + scheduleableUserOnly: false, + singleOnly: false, + settings: { + customTitle: null, + timeSpan: "*thisyear*", + interval: "month", + wotags: [], + wotagsany: true + } + }, + { + roles: [ + role.BizAdmin, + role.BizAdminRestricted, + role.ServiceRestricted, + role.Service, + role.Accounting + ], + title: "DashboardWorkOrderStatusPct", + icon: "$ayiChartBar", + type: "GzDashWorkOrderStatusPct", + scheduleableUserOnly: false, + singleOnly: false, + settings: { + customTitle: null, + timeSpan: "*thisyear*", + interval: "month", + wotags: [], + wotagsany: true + } + }, { roles: [ role.BizAdmin, diff --git a/ayanova/src/components/dash-labor-hours-everyone-bar.vue b/ayanova/src/components/dash-labor-hours-everyone-bar.vue index 7f4bdc8f..dd4a5b61 100644 --- a/ayanova/src/components/dash-labor-hours-everyone-bar.vue +++ b/ayanova/src/components/dash-labor-hours-everyone-bar.vue @@ -222,8 +222,6 @@ export default { await initWidget(this); }, async mounted() { - //must be called from mounted to have refs available - //console.log("reminders-mounted"); await this.getDataFromApi(); }, methods: { diff --git a/ayanova/src/components/dash-labor-hours-everyone-line.vue b/ayanova/src/components/dash-labor-hours-everyone-line.vue index a2cf45ce..c31edcac 100644 --- a/ayanova/src/components/dash-labor-hours-everyone-line.vue +++ b/ayanova/src/components/dash-labor-hours-everyone-line.vue @@ -225,8 +225,6 @@ export default { await initWidget(this); }, async mounted() { - //must be called from mounted to have refs available - //console.log("reminders-mounted"); await this.getDataFromApi(); }, methods: { diff --git a/ayanova/src/components/dash-labor-hours-personal-bar.vue b/ayanova/src/components/dash-labor-hours-personal-bar.vue index bf7b09e3..6085a48f 100644 --- a/ayanova/src/components/dash-labor-hours-personal-bar.vue +++ b/ayanova/src/components/dash-labor-hours-personal-bar.vue @@ -195,8 +195,6 @@ export default { await initWidget(this); }, async mounted() { - //must be called from mounted to have refs available - //console.log("reminders-mounted"); await this.getDataFromApi(); }, methods: { diff --git a/ayanova/src/components/dash-labor-hours-personal-line.vue b/ayanova/src/components/dash-labor-hours-personal-line.vue index 1d000721..67f973b5 100644 --- a/ayanova/src/components/dash-labor-hours-personal-line.vue +++ b/ayanova/src/components/dash-labor-hours-personal-line.vue @@ -198,8 +198,6 @@ export default { await initWidget(this); }, async mounted() { - //must be called from mounted to have refs available - //console.log("reminders-mounted"); await this.getDataFromApi(); }, methods: { diff --git a/ayanova/src/components/dash-today-reminders.vue b/ayanova/src/components/dash-today-reminders.vue index b925400a..16ab0407 100644 --- a/ayanova/src/components/dash-today-reminders.vue +++ b/ayanova/src/components/dash-today-reminders.vue @@ -74,8 +74,6 @@ export default { //console.log("reminders-beforeUpdate"); }, async mounted() { - //must be called from mounted to have refs available - //console.log("reminders-mounted"); await this.getDataFromApi(); }, methods: { diff --git a/ayanova/src/components/dash-work-order-completed-on-time-pct-bar.vue b/ayanova/src/components/dash-work-order-completed-on-time-pct-bar.vue index 788a749d..f420b6e2 100644 --- a/ayanova/src/components/dash-work-order-completed-on-time-pct-bar.vue +++ b/ayanova/src/components/dash-work-order-completed-on-time-pct-bar.vue @@ -164,25 +164,6 @@ export default { }, computed: { chartData() { - // let onTime = { - // lable: "Ontime", - // backgroundColor: "#00ff00", - // data: [] - // }; - // let notOnTime = { - // lable: "Not on time", - // backgroundColor: "#ff0000", - // data: [] - // }; - // this.obj.forEach(z => { - // if (z.z) { - // notOnTime.data.push({ x: z.x, y: z.y }); - // } else { - // onTime.data.push({ x: z.x, y: z.y }); - // } - // }); - - // return { datasets: [onTime, notOnTime] }; let onTime = { backgroundColor: this.settings.color, data: [] @@ -201,8 +182,6 @@ export default { await initWidget(this); }, async mounted() { - //must be called from mounted to have refs available - //console.log("reminders-mounted"); await this.getDataFromApi(); }, methods: { diff --git a/ayanova/src/components/dash-work-order-created-count-bar.vue b/ayanova/src/components/dash-work-order-created-count-bar.vue index 5cc61abb..2fdcc668 100644 --- a/ayanova/src/components/dash-work-order-created-count-bar.vue +++ b/ayanova/src/components/dash-work-order-created-count-bar.vue @@ -195,8 +195,6 @@ export default { await initWidget(this); }, async mounted() { - //must be called from mounted to have refs available - //console.log("reminders-mounted"); await this.getDataFromApi(); }, methods: { diff --git a/ayanova/src/components/dash-work-order-created-count-line.vue b/ayanova/src/components/dash-work-order-created-count-line.vue index e39f8f49..44d3c878 100644 --- a/ayanova/src/components/dash-work-order-created-count-line.vue +++ b/ayanova/src/components/dash-work-order-created-count-line.vue @@ -198,8 +198,6 @@ export default { await initWidget(this); }, async mounted() { - //must be called from mounted to have refs available - //console.log("reminders-mounted"); await this.getDataFromApi(); }, methods: { diff --git a/ayanova/src/components/dash-work-order-status-count-bar.vue b/ayanova/src/components/dash-work-order-status-count-bar.vue new file mode 100644 index 00000000..fe346633 --- /dev/null +++ b/ayanova/src/components/dash-work-order-status-count-bar.vue @@ -0,0 +1,362 @@ + + diff --git a/ayanova/src/components/dash-work-order-status-pct-bar.vue b/ayanova/src/components/dash-work-order-status-pct-bar.vue new file mode 100644 index 00000000..c15fb21a --- /dev/null +++ b/ayanova/src/components/dash-work-order-status-pct-bar.vue @@ -0,0 +1,364 @@ + + diff --git a/ayanova/src/views/home-dashboard.vue b/ayanova/src/views/home-dashboard.vue index 8a428478..022438f6 100644 --- a/ayanova/src/views/home-dashboard.vue +++ b/ayanova/src/views/home-dashboard.vue @@ -97,6 +97,8 @@ import GzDashWorkorderOverdueAllList from "../components/dash-workorder-overdue- import GzDashWorkOrderCreatedCountLine from "../components/dash-work-order-created-count-line.vue"; import GzDashWorkOrderCreatedCountBar from "../components/dash-work-order-created-count-bar.vue"; import GzDashPctWorkOrderCompletedOnTimeBar from "../components/dash-work-order-completed-on-time-pct-bar.vue"; +import GzDashWorkOrderStatusCount from "../components/dash-work-order-status-count-bar.vue"; +import GzDashWorkOrderStatusPct from "../components/dash-work-order-status-pct-bar.vue"; export default { components: { GzDashLaborHoursPersonalLine, @@ -112,7 +114,9 @@ export default { GzDashWorkorderOverdueAllList, GzDashWorkOrderCreatedCountLine, GzDashWorkOrderCreatedCountBar, - GzDashPctWorkOrderCompletedOnTimeBar + GzDashPctWorkOrderCompletedOnTimeBar, + GzDashWorkOrderStatusCount, + GzDashWorkOrderStatusPct }, data() { return {