@things-factory/operato-pms 4.3.595 → 4.3.609

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/client/pages/harvesting/harvesting-create-record.js +5 -2
  2. package/client/pages/loading/edit-loading-record.js +2 -0
  3. package/client/pages/report/report-daily-ffb-dispatch-and-production.js +19 -23
  4. package/dist-server/entities/daily-dispatch.js +2 -2
  5. package/dist-server/entities/daily-dispatch.js.map +1 -1
  6. package/dist-server/entities/ramp-block-history.js.map +1 -1
  7. package/dist-server/graphql/resolvers/daily-dispatch/delete-daily-dispatch.js +49 -1
  8. package/dist-server/graphql/resolvers/daily-dispatch/delete-daily-dispatch.js.map +1 -1
  9. package/dist-server/graphql/resolvers/daily-dispatch/generate-daily-dispatch.js +124 -112
  10. package/dist-server/graphql/resolvers/daily-dispatch/generate-daily-dispatch.js.map +1 -1
  11. package/dist-server/graphql/resolvers/daily-dispatch/update-daily-dispatch.js +51 -2
  12. package/dist-server/graphql/resolvers/daily-dispatch/update-daily-dispatch.js.map +1 -1
  13. package/dist-server/graphql/resolvers/daily-harvest/delete-daily-harvest.js +5 -7
  14. package/dist-server/graphql/resolvers/daily-harvest/delete-daily-harvest.js.map +1 -1
  15. package/dist-server/graphql/resolvers/daily-harvest/generate-daily-harvest.js +3 -3
  16. package/dist-server/graphql/resolvers/daily-harvest/generate-daily-harvest.js.map +1 -1
  17. package/dist-server/graphql/resolvers/daily-loading/delete-daily-loading.js +6 -0
  18. package/dist-server/graphql/resolvers/daily-loading/delete-daily-loading.js.map +1 -1
  19. package/dist-server/graphql/resolvers/daily-loading/generate-daily-loading.js +68 -52
  20. package/dist-server/graphql/resolvers/daily-loading/generate-daily-loading.js.map +1 -1
  21. package/dist-server/graphql/resolvers/daily-loading/update-daily-loading.js +16 -22
  22. package/dist-server/graphql/resolvers/daily-loading/update-daily-loading.js.map +1 -1
  23. package/dist-server/graphql/resolvers/report/daily-ffb-dispatch-production-reports.js +50 -19
  24. package/dist-server/graphql/resolvers/report/daily-ffb-dispatch-production-reports.js.map +1 -1
  25. package/dist-server/graphql/resolvers/report/daily-production-reports.js +96 -67
  26. package/dist-server/graphql/resolvers/report/daily-production-reports.js.map +1 -1
  27. package/dist-server/graphql/resolvers/report/daily-staff-harvest-reports.js +1 -0
  28. package/dist-server/graphql/resolvers/report/daily-staff-harvest-reports.js.map +1 -1
  29. package/dist-server/graphql/resolvers/report/monthly-block-dispatch-reports.js +7 -2
  30. package/dist-server/graphql/resolvers/report/monthly-block-dispatch-reports.js.map +1 -1
  31. package/dist-server/graphql/resolvers/report/monthly-dispatch-summary-reports.js +11 -5
  32. package/dist-server/graphql/resolvers/report/monthly-dispatch-summary-reports.js.map +1 -1
  33. package/dist-server/graphql/resolvers/report/monthly-ffb-sale-reports.js +21 -9
  34. package/dist-server/graphql/resolvers/report/monthly-ffb-sale-reports.js.map +1 -1
  35. package/dist-server/graphql/resolvers/report/monthly-production-reports.js +5 -2
  36. package/dist-server/graphql/resolvers/report/monthly-production-reports.js.map +1 -1
  37. package/dist-server/graphql/resolvers/report/yearly-production-reports.js +5 -2
  38. package/dist-server/graphql/resolvers/report/yearly-production-reports.js.map +1 -1
  39. package/dist-server/graphql/types/daily-loading-detail/daily-loading-detail-patch.js +2 -0
  40. package/dist-server/graphql/types/daily-loading-detail/daily-loading-detail-patch.js.map +1 -1
  41. package/dist-server/utils/transaction-util.js +32 -53
  42. package/dist-server/utils/transaction-util.js.map +1 -1
  43. package/package.json +6 -6
  44. package/server/entities/daily-dispatch.ts +2 -2
  45. package/server/entities/ramp-block-history.ts +2 -5
  46. package/server/graphql/resolvers/daily-dispatch/delete-daily-dispatch.ts +69 -2
  47. package/server/graphql/resolvers/daily-dispatch/generate-daily-dispatch.ts +179 -141
  48. package/server/graphql/resolvers/daily-dispatch/update-daily-dispatch.ts +68 -5
  49. package/server/graphql/resolvers/daily-harvest/delete-daily-harvest.ts +9 -26
  50. package/server/graphql/resolvers/daily-harvest/generate-daily-harvest.ts +3 -3
  51. package/server/graphql/resolvers/daily-loading/delete-daily-loading.ts +11 -1
  52. package/server/graphql/resolvers/daily-loading/generate-daily-loading.ts +95 -98
  53. package/server/graphql/resolvers/daily-loading/update-daily-loading.ts +44 -47
  54. package/server/graphql/resolvers/report/daily-ffb-dispatch-production-reports.ts +61 -26
  55. package/server/graphql/resolvers/report/daily-production-reports.ts +103 -72
  56. package/server/graphql/resolvers/report/daily-staff-harvest-reports.ts +5 -2
  57. package/server/graphql/resolvers/report/monthly-block-dispatch-reports.ts +20 -9
  58. package/server/graphql/resolvers/report/monthly-dispatch-summary-reports.ts +16 -12
  59. package/server/graphql/resolvers/report/monthly-ffb-sale-reports.ts +26 -12
  60. package/server/graphql/resolvers/report/monthly-production-reports.ts +5 -3
  61. package/server/graphql/resolvers/report/yearly-production-reports.ts +5 -2
  62. package/server/graphql/types/daily-loading-detail/daily-loading-detail-patch.ts +2 -0
  63. package/server/utils/transaction-util.ts +36 -56
  64. package/translations/en.json +1 -1
  65. package/translations/ja.json +1 -1
  66. package/translations/ko.json +1 -1
  67. package/translations/ms.json +1 -1
  68. package/translations/zh.json +1 -1
@@ -1,5 +1,4 @@
1
1
  import { EntityManager, getRepository, Repository } from 'typeorm'
2
-
3
2
  import { User } from '@things-factory/auth-base'
4
3
  import { Domain } from '@things-factory/shell'
5
4
 
@@ -11,40 +10,36 @@ export const generateDailyLoading = {
11
10
  async generateDailyLoading(_: any, { dailyLoading }, context: any) {
12
11
  const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
13
12
 
14
- let dailyLoadingDetails: DailyLoadingDetail[] = dailyLoading.dailyLoadingDetails
15
-
16
- const totalWeight: number = dailyLoadingDetails.reduce(function (prev, cur) {
17
- return prev + cur.totalBunchWeight
18
- }, 0)
13
+ try {
14
+ const dailyLoadingDetails: DailyLoadingDetail[] = dailyLoading.dailyLoadingDetails
19
15
 
20
- const totalBunch: number = dailyLoadingDetails.reduce(function (prev, cur) {
21
- return prev + cur.totalBunchLoaded
22
- }, 0)
16
+ // Calculate total weight and total bunch
17
+ const totalWeight = parseFloat(
18
+ dailyLoadingDetails.reduce((prev, cur) => prev + cur.totalBunchWeight, 0).toFixed(4)
19
+ )
20
+ const totalBunch = parseFloat(
21
+ dailyLoadingDetails.reduce((prev, cur) => prev + cur.totalBunchLoaded, 0).toFixed(4)
22
+ )
23
23
 
24
- // 1. Create daily loading
25
- let newDailyLoading: DailyLoading = new DailyLoading()
26
- newDailyLoading.name = NoGenerator.dailyLoading()
27
- newDailyLoading.domain = domain
28
- newDailyLoading.loadingDate = dailyLoading.loadingDate
29
- newDailyLoading.totalBunch = totalBunch
30
- newDailyLoading.totalWeight = totalWeight
31
- newDailyLoading.status = RECORD_STATUS.STORED
32
- newDailyLoading.creator = user
24
+ // 1. Create daily loading
25
+ const newDailyLoading = await tx.getRepository(DailyLoading).save({
26
+ name: NoGenerator.dailyLoading(),
27
+ domain,
28
+ loadingDate: dailyLoading.loadingDate,
29
+ totalBunch,
30
+ totalWeight,
31
+ status: RECORD_STATUS.STORED,
32
+ creator: user
33
+ })
33
34
 
34
- newDailyLoading = await tx.getRepository(DailyLoading).save(newDailyLoading)
35
+ // 2. Create daily loading details and update inventory
36
+ await addDailyLoadingDetail(domain, newDailyLoading, dailyLoadingDetails, user, tx)
35
37
 
36
- // 2. Create daily loading detail
37
- dailyLoadingDetails = await addDailyLoadingDetail(
38
- domain,
39
- newDailyLoading,
40
- dailyLoadingDetails.map((record: DailyLoadingDetail) => {
41
- return { ...record }
42
- }),
43
- user,
44
- tx
45
- )
46
-
47
- return newDailyLoading
38
+ return newDailyLoading
39
+ } catch (error) {
40
+ console.error('Error generating daily loading:', error)
41
+ throw new Error('Failed to generate daily loading.')
42
+ }
48
43
  }
49
44
  }
50
45
 
@@ -58,29 +53,39 @@ export async function addDailyLoadingDetail(
58
53
  const truckRepo: Repository<Truck> = tx?.getRepository(Truck) || getRepository(Truck)
59
54
  const blockRepo: Repository<Block> = tx?.getRepository(Block) || getRepository(Block)
60
55
  const rampRepo: Repository<Ramp> = tx?.getRepository(Ramp) || getRepository(Ramp)
61
-
62
56
  const dailyLoadingDetailRepo: Repository<DailyLoadingDetail> =
63
57
  tx?.getRepository(DailyLoadingDetail) || getRepository(DailyLoadingDetail)
64
58
 
65
- dailyLoadingDetails = await Promise.all(
66
- dailyLoadingDetails.map(async (record: DailyLoadingDetail) => {
67
- return {
68
- ...record,
69
- domain,
70
- name: NoGenerator.dailyLoadingDetail(),
71
- truck: await truckRepo.findOne({ id: record.truck.id }),
72
- block: await blockRepo.findOne({ id: record.block.id }),
73
- ramp: await rampRepo.findOne({ id: record.ramp.id }),
74
- dailyLoading: newDailyLoading,
75
- creator: user
76
- }
77
- })
78
- )
59
+ // Fetch all related entities in a single query to reduce database calls
60
+ const trucks = await truckRepo.findByIds(dailyLoadingDetails.map(d => d.truck.id))
61
+ const blocks = await blockRepo.findByIds(dailyLoadingDetails.map(d => d.block.id))
62
+ const ramps = await rampRepo.findByIds(dailyLoadingDetails.map(d => d.ramp.id))
63
+
64
+ const detailsToSave = dailyLoadingDetails.map(record => {
65
+ const truck = trucks.find(t => t.id === record.truck.id)
66
+ const block = blocks.find(b => b.id === record.block.id)
67
+ const ramp = ramps.find(r => r.id === record.ramp.id)
68
+
69
+ if (!truck || !block || !ramp) {
70
+ throw new Error(`Truck, Block, or Ramp not found for detail: ${record.name}`)
71
+ }
72
+
73
+ return {
74
+ ...record,
75
+ domain,
76
+ name: NoGenerator.dailyLoadingDetail(),
77
+ truck,
78
+ block,
79
+ ramp,
80
+ dailyLoading: newDailyLoading,
81
+ creator: user
82
+ }
83
+ })
79
84
 
80
- dailyLoadingDetails = await dailyLoadingDetailRepo.save(dailyLoadingDetails)
81
- await updatePlantationInventory(domain, newDailyLoading, dailyLoadingDetails, user, tx)
85
+ const savedDetails = await dailyLoadingDetailRepo.save(detailsToSave)
86
+ await updatePlantationInventory(domain, newDailyLoading, savedDetails, user, tx)
82
87
 
83
- return dailyLoadingDetails
88
+ return savedDetails
84
89
  }
85
90
 
86
91
  export async function updatePlantationInventory(
@@ -93,68 +98,60 @@ export async function updatePlantationInventory(
93
98
  const plantationInvRepo: Repository<PlantationInventory> =
94
99
  tx?.getRepository(PlantationInventory) || getRepository(PlantationInventory)
95
100
 
96
- for (let dailyLoadingDetail of dailyLoadingDetails) {
97
- let existingRampTonnage: PlantationInventory = await plantationInvRepo.findOne({
98
- where: { domain, type: INVENTORY_TYPE.RAMP_TONNAGE, ramp: dailyLoadingDetail.ramp },
99
- relations: ['domain', 'block', 'ramp']
100
- })
101
-
102
- if (existingRampTonnage) {
103
- existingRampTonnage.totalTonnage = existingRampTonnage.totalTonnage + dailyLoadingDetail.totalBunchWeight
104
- existingRampTonnage.updater = user
105
- await plantationInvRepo.save(existingRampTonnage)
101
+ for (const detail of dailyLoadingDetails) {
102
+ // Use a transaction to ensure atomicity
103
+ await tx.transaction(async transactionalEntityManager => {
104
+ let existingRampTonnage = await transactionalEntityManager.findOne(PlantationInventory, {
105
+ where: { domain, type: INVENTORY_TYPE.RAMP_TONNAGE, ramp: detail.ramp },
106
+ relations: ['domain', 'block', 'ramp']
107
+ })
108
+
109
+ if (existingRampTonnage) {
110
+ existingRampTonnage.totalTonnage = parseFloat(
111
+ (existingRampTonnage.totalTonnage + detail.totalBunchWeight).toFixed(4)
112
+ )
113
+ existingRampTonnage.updater = user
114
+ await transactionalEntityManager.save(existingRampTonnage)
115
+ } else {
116
+ const plantationInventory = transactionalEntityManager.create(PlantationInventory, {
117
+ domain,
118
+ name: NoGenerator.rampTonnageName(),
119
+ block: detail.block,
120
+ type: INVENTORY_TYPE.RAMP_TONNAGE,
121
+ totalTonnage: detail.totalBunchWeight,
122
+ status: INVENTORY_STATUS.STORED,
123
+ ramp: detail.ramp,
124
+ creator: user
125
+ })
126
+ await transactionalEntityManager.save(plantationInventory)
127
+ }
106
128
 
107
129
  await generateTransactionHistory(
108
- dailyLoadingDetail.block,
130
+ detail.block,
109
131
  domain,
110
- dailyLoadingDetail.ramp,
132
+ detail.ramp,
111
133
  newDailyLoading.id,
112
134
  newDailyLoading.name,
113
135
  TRANSACTION_TYPE.LOADING,
114
136
  newDailyLoading.loadingDate,
115
- 0,
116
- dailyLoadingDetail.totalBunchWeight,
137
+ detail.totalBunchLoaded,
138
+ detail.totalBunchWeight,
117
139
  user,
118
- tx
140
+ transactionalEntityManager
119
141
  )
120
- } else {
121
- let plantationInventory: PlantationInventory = new PlantationInventory()
122
- plantationInventory.domain = domain
123
- plantationInventory.name = NoGenerator.rampTonnageName()
124
- plantationInventory.block = dailyLoadingDetail.block
125
- plantationInventory.type = INVENTORY_TYPE.RAMP_TONNAGE
126
- plantationInventory.totalTonnage = dailyLoadingDetail.totalBunchWeight
127
- plantationInventory.status = INVENTORY_STATUS.STORED
128
- plantationInventory.ramp = dailyLoadingDetail.ramp
129
- plantationInventory.creator = user
130
- plantationInventory = await plantationInvRepo.save(plantationInventory)
131
142
 
132
- await generateTransactionHistory(
133
- dailyLoadingDetail.block,
143
+ await generateRampBlockHistories(
144
+ detail.block,
134
145
  domain,
135
- dailyLoadingDetail.ramp,
136
- newDailyLoading.id,
137
- newDailyLoading.name,
138
- TRANSACTION_TYPE.LOADING,
146
+ detail.ramp,
147
+ 'LOADING',
139
148
  newDailyLoading.loadingDate,
140
- 0,
141
- dailyLoadingDetail.totalBunchWeight,
149
+ detail.totalBunchWeight,
142
150
  user,
143
- tx
151
+ null,
152
+ null,
153
+ transactionalEntityManager
144
154
  )
145
- }
146
-
147
- await generateRampBlockHistories(
148
- dailyLoadingDetail.block,
149
- domain,
150
- dailyLoadingDetail.ramp,
151
- 'LOADING',
152
- newDailyLoading.loadingDate,
153
- dailyLoadingDetail.totalBunchWeight,
154
- user,
155
- null,
156
- null,
157
- tx
158
- )
155
+ })
159
156
  }
160
157
  }
@@ -3,8 +3,8 @@ import { EntityManager, getRepository, Repository } from 'typeorm'
3
3
  import { User } from '@things-factory/auth-base'
4
4
  import { Domain } from '@things-factory/shell'
5
5
 
6
- import { INVENTORY_TYPE, TRANSACTION_TYPE } from '../../../constants'
7
- import { Block, DailyLoading, DailyLoadingDetail, PlantationInventory, Ramp, Truck } from '../../../entities'
6
+ import { TRANSACTION_TYPE } from '../../../constants'
7
+ import { Block, DailyLoading, DailyLoadingDetail, Ramp, Truck } from '../../../entities'
8
8
  import { generateTransactionHistory, NoGenerator } from '../../../utils'
9
9
 
10
10
  export const updateDailyLoading = {
@@ -31,8 +31,8 @@ export const updateDailyLoading = {
31
31
  return prev + cur.totalBunchWeight
32
32
  }, 0)
33
33
 
34
- dailyLoading.totalBunch = totalBunch
35
- dailyLoading.totalWeight = totalWeight
34
+ dailyLoading.totalBunch = parseFloat(totalBunch.toFixed(4))
35
+ dailyLoading.totalWeight = parseFloat(totalWeight.toFixed(4))
36
36
  dailyLoading.loadingDate = dailyLoadingPatch.loadingDate
37
37
  dailyLoading.updater = user
38
38
  dailyLoading = await dailyLoadingRepo.save(dailyLoading)
@@ -59,12 +59,11 @@ export async function updateDailyLoadingDetail(
59
59
 
60
60
  let updatedDailyLoadingDetails: any[] = []
61
61
  const dailyLoadingDetails: DailyLoadingDetail[] = dailyLoading.dailyLoadingDetails
62
- // for existing data row
62
+
63
+ // Filter existing and new records
63
64
  const existingDailyLoadingDetails: DailyLoadingDetail[] = dailyLoadingDetailPatches.filter(
64
65
  detail => detail.name !== null
65
66
  )
66
-
67
- // new row added in client side
68
67
  const newDailyLoadingDetail: DailyLoadingDetail[] = dailyLoadingDetailPatches.filter(detail => detail.name === null)
69
68
 
70
69
  if (existingDailyLoadingDetails?.length > 0) {
@@ -74,8 +73,29 @@ export async function updateDailyLoadingDetail(
74
73
  detail => detail.name === existingRecord.name
75
74
  )
76
75
 
77
- if (foundDailyLoadingDetailPatch.totalBunchWeight !== existingRecord.totalBunchWeight) {
78
- await updatePlantationInventory(domain, dailyLoading, foundDailyLoadingDetailPatch, existingRecord, user, tx)
76
+ if (foundDailyLoadingDetailPatch) {
77
+ // Calculate variance for totalBunchLoaded
78
+ const bunchLoadedVariance =
79
+ foundDailyLoadingDetailPatch.totalBunchLoaded - foundDailyLoadingDetailPatch.prevTotalBunchLoaded
80
+ const bunchWeightVariance =
81
+ foundDailyLoadingDetailPatch.totalBunchWeight - foundDailyLoadingDetailPatch.prevTotalBunchWeight
82
+
83
+ // If there is a variance, generate a transaction history
84
+ if (bunchLoadedVariance !== 0 || bunchWeightVariance !== 0) {
85
+ await generateTransactionHistory(
86
+ existingRecord.block,
87
+ domain,
88
+ existingRecord.ramp,
89
+ dailyLoading.id,
90
+ dailyLoading.name,
91
+ TRANSACTION_TYPE.LOADING_ADJUSTMENT, // Use appropriate transaction type
92
+ dailyLoading.loadingDate,
93
+ bunchLoadedVariance,
94
+ bunchWeightVariance,
95
+ user,
96
+ tx
97
+ )
98
+ }
79
99
  }
80
100
 
81
101
  return {
@@ -110,45 +130,22 @@ export async function updateDailyLoadingDetail(
110
130
  newDailyLoadingDetail.dailyLoading = dailyLoading
111
131
 
112
132
  await dailyLoadingDetailRepo.save(newDailyLoadingDetail)
113
- })
114
- )
115
- }
116
- }
117
133
 
118
- export async function updatePlantationInventory(
119
- domain: Domain,
120
- dailyLoading: DailyLoading,
121
- foundDailyLoadingDetailPatch: any,
122
- existingRecord: DailyLoadingDetail,
123
- user: User,
124
- tx?: EntityManager
125
- ): Promise<void> {
126
- const plantationInvRepo: Repository<PlantationInventory> =
127
- tx?.getRepository(PlantationInventory) || getRepository(PlantationInventory)
128
-
129
- let existingRampTonnage: PlantationInventory = await plantationInvRepo.findOne({
130
- where: { domain, type: INVENTORY_TYPE.RAMP_TONNAGE, ramp: existingRecord.ramp },
131
- relations: ['domain', 'block', 'ramp']
132
- })
133
-
134
- if (existingRampTonnage) {
135
- const tonnageChanges: number = foundDailyLoadingDetailPatch.totalBunchWeight - existingRecord.totalBunchWeight
136
- existingRampTonnage.totalTonnage = existingRampTonnage.totalTonnage + tonnageChanges
137
- existingRampTonnage.updater = user
138
- await plantationInvRepo.save(existingRampTonnage)
139
-
140
- await generateTransactionHistory(
141
- existingRampTonnage.block,
142
- domain,
143
- existingRampTonnage.ramp,
144
- dailyLoading.id,
145
- dailyLoading.name,
146
- TRANSACTION_TYPE.LOADING_ADJUSTMENT,
147
- dailyLoading.loadingDate,
148
- 0,
149
- tonnageChanges,
150
- user,
151
- tx
134
+ // Generate transaction history for new records
135
+ await generateTransactionHistory(
136
+ newDailyLoadingDetail.block,
137
+ domain,
138
+ newDailyLoadingDetail.ramp,
139
+ dailyLoading.id,
140
+ dailyLoading.name,
141
+ TRANSACTION_TYPE.LOADING, // Use appropriate transaction type
142
+ dailyLoading.loadingDate,
143
+ newDailyLoadingDetail.totalBunchLoaded,
144
+ newDailyLoadingDetail.totalBunchWeight,
145
+ user,
146
+ tx
147
+ )
148
+ })
152
149
  )
153
150
  }
154
151
  }
@@ -6,7 +6,7 @@ import { Block, Organization, Ramp } from '../../../entities'
6
6
  export const dailyFfbDispatchProductionReports = {
7
7
  async dailyFfbDispatchProductionReports(_: any, params: ListParam, context: any) {
8
8
  try {
9
- const { domain, tx }: { domain: Domain, tx: EntityManager } = context.state
9
+ const { domain, tx }: { domain: Domain; tx: EntityManager } = context.state
10
10
 
11
11
  let year = parseInt(params.filters.filter(x => x.name == 'month')[0].value.split('-')[0])
12
12
  let month = parseInt(params.filters.filter(x => x.name == 'month')[0].value.split('-')[1])
@@ -36,14 +36,16 @@ export const dailyFfbDispatchProductionReports = {
36
36
  where: { domain: domain.id, deletedAt: IsNull() }
37
37
  })
38
38
 
39
- let blocks = await tx.getRepository(Block).query(`
39
+ let blocks = await tx.getRepository(Block).query(
40
+ `
40
41
  SELECT b.id, b.name FROM ramps r
41
42
  INNER JOIN blocks b ON b.id = r.block_id
42
43
  WHERE b.deleted_at IS NULL
43
44
  AND r.domain_id = $1
44
45
  GROUP BY b.id, b.name
45
- `, [domain.id])
46
-
46
+ `,
47
+ [domain.id]
48
+ )
47
49
 
48
50
  // -- WHERE dd.dispatch_at::timestamp between $1::timestamp and $2::timestamp
49
51
  // [fromDateString, toDateString]
@@ -52,44 +54,67 @@ export const dailyFfbDispatchProductionReports = {
52
54
  await tx.query(
53
55
  `
54
56
  CREATE TEMP TABLE raw_block_dispatch ON COMMIT DROP AS (
55
- SELECT "name", "dispatch_at", sum(weight) AS weight FROM(
57
+ SELECT
58
+ "name",
59
+ "dispatch_at",
60
+ SUM(weight::numeric) AS weight
61
+ FROM (
56
62
  SELECT * FROM (
57
- SELECT dd.id,COALESCE(b.name, 'unknown') AS name, 1 AS "rank", dd.dispatch_at::date AS dispatch_at,
58
- COALESCE(ddd.adjusted_weight, ddd.collected_ramp_weight, 0) AS weight
59
- FROM daily_dispatches dd
60
- INNER JOIN daily_dispatch_details ddd ON ddd.daily_dispatch_id = dd.id
61
- INNER JOIN ramps r ON r.id = ddd.ramp_id
62
- INNER JOIN blocks b ON b.id = r.block_id
63
- WHERE dd.dispatch_at::date between $1 and $2
64
- AND b.deleted_at is null
63
+ SELECT
64
+ rbh.id,
65
+ COALESCE(b.name, 'unknown') AS name,
66
+ 1 AS "rank",
67
+ rbh.transaction_date::date AS dispatch_at,
68
+ CASE
69
+ WHEN rbh.transaction_type = 'DISPATCH' AND rbh.weight < 0 THEN ABS(rbh.weight)
70
+ WHEN rbh.transaction_type IN ('REVERSE_DISPATCH', 'TONNAGE_VARIANCE') THEN ABS(rbh.weight)
71
+ ELSE 0
72
+ END AS weight
73
+ FROM ramp_block_histories rbh
74
+ INNER JOIN blocks b ON b.id = rbh.block_id
75
+ WHERE rbh.transaction_type IN ('DISPATCH', 'REVERSE_DISPATCH', 'TONNAGE_VARIANCE')
76
+ AND rbh.transaction_date::date BETWEEN $1 AND $2
77
+ AND b.deleted_at IS NULL
65
78
  UNION
66
- SELECT dd.id, COALESCE(c.name, 'unknown') AS name, CASE WHEN c.name IS NULL THEN 3 ELSE 2 END AS "rank", dd.dispatch_at::date AS dispatch_at,
67
- COALESCE((SELECT SUM(COALESCE(ddd.adjusted_weight, ddd.collected_ramp_weight, 0)) FROM daily_dispatch_details ddd WHERE ddd.daily_dispatch_id = dd.id),0) AS weight
79
+ SELECT
80
+ dd.id,
81
+ COALESCE(c.name, 'unknown') AS name,
82
+ CASE WHEN c.name IS NULL THEN 3 ELSE 2 END AS "rank",
83
+ dd.dispatch_at::date AS dispatch_at,
84
+ COALESCE(
85
+ (SELECT SUM(COALESCE(ddd.adjusted_weight, ddd.collected_ramp_weight, 0))
86
+ FROM daily_dispatch_details ddd
87
+ WHERE ddd.daily_dispatch_id = dd.id), 0
88
+ ) AS weight
68
89
  FROM daily_dispatches dd
69
90
  LEFT JOIN organizations c ON c.id = dd.dispatch_to_id
70
- WHERE dd.dispatch_at::date between $1 and $2
91
+ WHERE dd.dispatch_at::date BETWEEN $1 AND $2
92
+ AND dd.deleted_at IS NULL
71
93
  ) foo
72
94
  ORDER BY "rank", "name", "dispatch_at"
73
95
  ) foo
74
96
  GROUP BY "name", "dispatch_at"
75
97
  ORDER BY name, "dispatch_at"
76
- )
98
+ );
77
99
  `,
78
100
  [fromDateString, toDateString]
79
101
  )
80
102
 
81
- await tx.query(`
103
+ await tx.query(
104
+ `
82
105
  create temp table cross_column ON COMMIT DROP as (
83
- SELECT b.name FROM ramps r
84
- INNER JOIN blocks b ON b.id = r.block_id
85
- WHERE r.deleted_at IS NULL AND r.domain_id = $1
106
+ SELECT b.name FROM blocks b
107
+ WHERE 1=1
108
+ AND b.domain_id = $1
86
109
  AND b.deleted_at is null
87
110
  GROUP BY b.id, b.name
88
111
  UNION
89
112
  SELECT c.name FROM organizations c
90
113
  where c.deleted_at is null
91
114
  )
92
- `, [domain.id])
115
+ `,
116
+ [domain.id]
117
+ )
93
118
 
94
119
  let definedCrossColumn = await tx.query(`
95
120
  select string_agg(concat('"', name, '"'),',') as columns from cross_column
@@ -108,7 +133,12 @@ export const dailyFfbDispatchProductionReports = {
108
133
  $$
109
134
  SELECT name from cross_column
110
135
  $$
111
- ) AS (dispatch_at date, ${definedCrossColumn[0].columns.split(',').map(itm => { return itm + ' varchar' }).join(',')} )
136
+ ) AS (dispatch_at date, ${definedCrossColumn[0].columns
137
+ .split(',')
138
+ .map(itm => {
139
+ return itm + ' varchar'
140
+ })
141
+ .join(',')} )
112
142
  );
113
143
  `
114
144
  )
@@ -117,7 +147,12 @@ export const dailyFfbDispatchProductionReports = {
117
147
  `
118
148
  CREATE TEMP TABLE temp_monthly_production_data ON COMMIT DROP AS (
119
149
  SELECT TO_CHAR(md.dateDay:: DATE, 'dd/mm/yyyy') as "date"
120
- , row_to_json((SELECT d FROM (SELECT ${definedCrossColumn[0].columns.split(',').map(itm => { return 'pbd.' + itm }).join(',')}) d))::varchar as "blockData"
150
+ , row_to_json((SELECT d FROM (SELECT ${definedCrossColumn[0].columns
151
+ .split(',')
152
+ .map(itm => {
153
+ return 'pbd.' + itm
154
+ })
155
+ .join(',')}) d))::varchar as "blockData"
121
156
  , (SELECT sum(weight) FROM raw_block_dispatch rbd WHERE rbd.dispatch_at = pbd.dispatch_at) AS "today"
122
157
  FROM (select generate_series((date '${fromDateString}')::timestamp, (date '${toDateString}')::timestamp, interval '1 day')::date as dateDay) as md
123
158
  LEFT JOIN pivot_block_dispatch pbd on pbd.dispatch_at::date = md.dateDay
@@ -138,13 +173,13 @@ export const dailyFfbDispatchProductionReports = {
138
173
  `
139
174
  )
140
175
 
141
-
142
176
  return {
143
177
  items: result.map(itm => {
144
178
  return {
145
179
  ...itm
146
180
  }
147
- }), total: total[0].count
181
+ }),
182
+ total: total[0].count
148
183
  }
149
184
  } catch (error) {
150
185
  throw error