statistics.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. const _ = require('lodash')
  2. const { Terminal } = require('../database')
  3. const sequelize = require('../database/sequelize')
  4. const { sanitize } = require('@alancnet/material-framework/lib/util')
  5. const get = async (req, res) => {
  6. const terminalIds = (await Terminal.findAll())
  7. .filter(loc => req.claims.TERMINAL_ALL_ACCESS || req.claims[`TERMINAL_${loc.key}_ACCESS`])
  8. .map(loc => loc.id)
  9. const [metricsOverTime, metadata] = await sequelize.query(`
  10. SELECT
  11. loc.key,
  12. wd.date,
  13. wd.laborCost,
  14. SUM(distinct svc.cartons) as cartons,
  15. cast(SUM(distinct wd.laborCost) as double) / SUM(distinct svc.cartons) as efficiency
  16. FROM workdays wd
  17. JOIN terminals loc on wd.terminalId = loc.id
  18. LEFT JOIN services svc on svc.workdayId = wd.id
  19. WHERE loc.id IN(:terminalIds)
  20. GROUP BY loc.key, wd.date
  21. `, {
  22. replacements: { terminalIds }
  23. })
  24. const metricsSql = `
  25. select
  26. terminals.key as terminal,
  27. serviceCategories.key as serviceCategory,
  28. serviceCategories.displayOrder,
  29. laborCategories.key as laborCategory,
  30. sum(distinct labors.laborCost) as laborCost,
  31. sum(distinct services.cartons) as cartons,
  32. cast(sum(distinct labors.laborCost) as double) / sum(distinct services.cartons) as costPerCarton
  33. -- Start with Terminals
  34. from terminals
  35. -- Link to labor cost
  36. join workdays on workdays.terminalId = terminals.id
  37. join services on services.workdayId = workdays.id
  38. join labors on labors.workdayId = workdays.id
  39. -- Link to LaborCategory
  40. join staffMembers on labors.staffMemberId = staffMembers.id
  41. join laborCategories on staffMembers.laborCategoryId = laborCategories.id
  42. -- Link to ServiceCategory
  43. join laborServiceCategories on laborServiceCategories.laborCategoryId = laborCategories.id
  44. join serviceCategories on laborServiceCategories.serviceCategoryId = serviceCategories.id
  45. group by terminals.key, serviceCategories.key, laborCategories.key
  46. `
  47. const metricsPerServiceCategorySql = `
  48. select
  49. serviceCategory,
  50. displayOrder,
  51. cast(sum(distinct laborCost) as double) / sum(distinct cartons) as costPerCarton
  52. from (${metricsSql})
  53. group by serviceCategory
  54. order by displayOrder
  55. `
  56. const metricsPerLaborCategorySql = `
  57. select
  58. serviceCategory,
  59. laborCategory,
  60. cast(sum(distinct laborCost) as double) / sum(distinct cartons) as costPerCarton
  61. from (${metricsSql})
  62. group by laborCategory
  63. `
  64. const metricsPerTerminalAndServiceCategorySql = `
  65. select
  66. terminal,
  67. serviceCategory,
  68. cast(sum(distinct laborCost) as double) / sum(distinct cartons) as costPerCarton
  69. from (${metricsSql})
  70. group by terminal, serviceCategory
  71. `
  72. const metricsPerTerminalAndLaborCategorySql = `
  73. select
  74. terminal,
  75. serviceCategory,
  76. laborCategory,
  77. cast(sum(distinct laborCost) as double) / sum(distinct cartons) as costPerCarton
  78. from (${metricsSql})
  79. group by terminal, laborCategory
  80. `
  81. const metricsPerServiceCategory = await sanitize(req, (await sequelize.query(metricsPerServiceCategorySql))[0])
  82. const metricsPerLaborCategory = await sanitize(req, (await sequelize.query(metricsPerLaborCategorySql))[0])
  83. const metricsPerTerminalAndServiceCategory = await sanitize(req, (await sequelize.query(metricsPerTerminalAndServiceCategorySql))[0])
  84. const metricsPerTerminalAndLaborCategory = await sanitize(req, (await sequelize.query(metricsPerTerminalAndLaborCategorySql))[0])
  85. const results = {
  86. serviceCategories: metricsPerServiceCategory.map(mpsc => Object.assign(mpsc, {
  87. laborCategories: metricsPerLaborCategory.filter(mplc => mplc.serviceCategory === mpsc.serviceCategory),
  88. terminals: metricsPerTerminalAndServiceCategory.filter(mpt => mpt.serviceCategory === mpsc.serviceCategory).map(mpt => Object.assign(mpt, {
  89. laborCategories: metricsPerTerminalAndLaborCategory.filter(mptlc => mptlc.serviceCategory === mpsc.serviceCategory && mptlc.terminal === mpt.terminal)
  90. }))
  91. })),
  92. metricsOverTime
  93. }
  94. res.status(200).send(results)
  95. }
  96. module.exports = {
  97. get
  98. }