@things-factory/worksheet-base 5.0.0-alpha.3 → 5.0.0-alpha.30

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 (131) hide show
  1. package/dist-server/controllers/inbound/unloading-worksheet-controller.js +301 -2
  2. package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/outbound/loading-worksheet-controller.js +10 -0
  4. package/dist-server/controllers/outbound/loading-worksheet-controller.js.map +1 -1
  5. package/dist-server/controllers/outbound/packing-worksheet-controller.js +172 -7
  6. package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
  7. package/dist-server/controllers/outbound/picking-worksheet-controller.js +352 -11
  8. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  9. package/dist-server/controllers/outbound/returning-worksheet-controller.js +11 -1
  10. package/dist-server/controllers/outbound/returning-worksheet-controller.js.map +1 -1
  11. package/dist-server/controllers/outbound/sorting-worksheet-controller.js +110 -3
  12. package/dist-server/controllers/outbound/sorting-worksheet-controller.js.map +1 -1
  13. package/dist-server/controllers/render-grn.js +27 -3
  14. package/dist-server/controllers/render-grn.js.map +1 -1
  15. package/dist-server/controllers/render-invoices.js +103 -65
  16. package/dist-server/controllers/render-invoices.js.map +1 -1
  17. package/dist-server/controllers/render-orientage-do.js.map +1 -1
  18. package/dist-server/controllers/render-orientage-grn.js +1 -0
  19. package/dist-server/controllers/render-orientage-grn.js.map +1 -1
  20. package/dist-server/controllers/render-ro-do.js +65 -1
  21. package/dist-server/controllers/render-ro-do.js.map +1 -1
  22. package/dist-server/controllers/worksheet-controller.js +15 -0
  23. package/dist-server/controllers/worksheet-controller.js.map +1 -1
  24. package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js +30 -1
  25. package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js.map +1 -1
  26. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-arrival-notice-worksheet.js +27 -23
  27. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-arrival-notice-worksheet.js.map +1 -1
  28. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +3 -0
  29. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
  30. package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js +16 -2
  31. package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js.map +1 -1
  32. package/dist-server/graphql/resolvers/worksheet/packing/index.js +2 -1
  33. package/dist-server/graphql/resolvers/worksheet/packing/index.js.map +1 -1
  34. package/dist-server/graphql/resolvers/worksheet/packing/packing.js +4 -4
  35. package/dist-server/graphql/resolvers/worksheet/packing/packing.js.map +1 -1
  36. package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js +4 -4
  37. package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js.map +1 -1
  38. package/dist-server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.js +15 -0
  39. package/dist-server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.js.map +1 -0
  40. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +152 -132
  41. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
  42. package/dist-server/graphql/resolvers/worksheet/picking/assign-picking-worker.js +13 -10
  43. package/dist-server/graphql/resolvers/worksheet/picking/assign-picking-worker.js.map +1 -1
  44. package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +0 -17
  45. package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
  46. package/dist-server/graphql/resolvers/worksheet/picking/index.js +2 -1
  47. package/dist-server/graphql/resolvers/worksheet/picking/index.js.map +1 -1
  48. package/dist-server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.js +4 -7
  49. package/dist-server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.js.map +1 -1
  50. package/dist-server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.js +15 -0
  51. package/dist-server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.js.map +1 -0
  52. package/dist-server/graphql/resolvers/worksheet/sorting/scan-product-sorting.js +4 -4
  53. package/dist-server/graphql/resolvers/worksheet/sorting/scan-product-sorting.js.map +1 -1
  54. package/dist-server/graphql/resolvers/worksheet/sorting/sorting-product.js +4 -4
  55. package/dist-server/graphql/resolvers/worksheet/sorting/sorting-product.js.map +1 -1
  56. package/dist-server/graphql/resolvers/worksheet/sorting-worksheet.js +6 -0
  57. package/dist-server/graphql/resolvers/worksheet/sorting-worksheet.js.map +1 -1
  58. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js +3 -2
  59. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js.map +1 -1
  60. package/dist-server/graphql/resolvers/worksheet/unloading/index.js +3 -1
  61. package/dist-server/graphql/resolvers/worksheet/unloading/index.js.map +1 -1
  62. package/dist-server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.js +15 -0
  63. package/dist-server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.js.map +1 -0
  64. package/dist-server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.js +15 -0
  65. package/dist-server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.js.map +1 -0
  66. package/dist-server/graphql/resolvers/worksheet/unloading/unload.js.map +1 -1
  67. package/dist-server/graphql/resolvers/worksheet/unloading-worksheet.js +3 -1
  68. package/dist-server/graphql/resolvers/worksheet/unloading-worksheet.js.map +1 -1
  69. package/dist-server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.js +4 -5
  70. package/dist-server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.js.map +1 -1
  71. package/dist-server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.js +4 -2
  72. package/dist-server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.js.map +1 -1
  73. package/dist-server/graphql/types/worksheet/find-release-orders-by-task-no.js +11 -0
  74. package/dist-server/graphql/types/worksheet/find-release-orders-by-task-no.js.map +1 -0
  75. package/dist-server/graphql/types/worksheet/index.js +30 -4
  76. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  77. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js +3 -0
  78. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js.map +1 -1
  79. package/dist-server/graphql/types/worksheet/worksheet-info.js +1 -0
  80. package/dist-server/graphql/types/worksheet/worksheet-info.js.map +1 -1
  81. package/dist-server/graphql/types/worksheet-detail/index.js +0 -2
  82. package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
  83. package/dist-server/index.js +4 -0
  84. package/dist-server/index.js.map +1 -1
  85. package/dist-server/utils/inventory-util.js +14 -25
  86. package/dist-server/utils/inventory-util.js.map +1 -1
  87. package/package.json +17 -17
  88. package/server/controllers/inbound/unloading-worksheet-controller.ts +363 -6
  89. package/server/controllers/outbound/loading-worksheet-controller.ts +13 -0
  90. package/server/controllers/outbound/packing-worksheet-controller.ts +224 -9
  91. package/server/controllers/outbound/picking-worksheet-controller.ts +465 -16
  92. package/server/controllers/outbound/returning-worksheet-controller.ts +12 -1
  93. package/server/controllers/outbound/sorting-worksheet-controller.ts +149 -4
  94. package/server/controllers/render-grn.ts +39 -5
  95. package/server/controllers/render-invoices.ts +119 -72
  96. package/server/controllers/render-orientage-do.ts +11 -11
  97. package/server/controllers/render-orientage-grn.ts +12 -11
  98. package/server/controllers/render-ro-do.ts +93 -8
  99. package/server/controllers/worksheet-controller.ts +18 -2
  100. package/server/graphql/resolvers/worksheet/find-release-orders-by-task-no.ts +35 -2
  101. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-arrival-notice-worksheet.ts +35 -25
  102. package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +2 -0
  103. package/server/graphql/resolvers/worksheet/loading/complete-loading.ts +25 -6
  104. package/server/graphql/resolvers/worksheet/packing/index.ts +3 -1
  105. package/server/graphql/resolvers/worksheet/packing/packing.ts +5 -4
  106. package/server/graphql/resolvers/worksheet/packing/scan-product-packing.ts +9 -4
  107. package/server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.ts +24 -0
  108. package/server/graphql/resolvers/worksheet/packing-worksheet.ts +167 -145
  109. package/server/graphql/resolvers/worksheet/picking/assign-picking-worker.ts +15 -11
  110. package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +0 -18
  111. package/server/graphql/resolvers/worksheet/picking/index.ts +3 -1
  112. package/server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.ts +5 -7
  113. package/server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.ts +24 -0
  114. package/server/graphql/resolvers/worksheet/sorting/scan-product-sorting.ts +5 -4
  115. package/server/graphql/resolvers/worksheet/sorting/sorting-product.ts +5 -4
  116. package/server/graphql/resolvers/worksheet/sorting-worksheet.ts +6 -0
  117. package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +6 -2
  118. package/server/graphql/resolvers/worksheet/unloading/index.ts +4 -0
  119. package/server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.ts +26 -0
  120. package/server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.ts +24 -0
  121. package/server/graphql/resolvers/worksheet/unloading/unload.ts +3 -1
  122. package/server/graphql/resolvers/worksheet/unloading-worksheet.ts +3 -1
  123. package/server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.ts +10 -12
  124. package/server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.ts +4 -2
  125. package/server/graphql/types/worksheet/find-release-orders-by-task-no.ts +8 -0
  126. package/server/graphql/types/worksheet/index.ts +30 -4
  127. package/server/graphql/types/worksheet/worksheet-detail-info.ts +3 -0
  128. package/server/graphql/types/worksheet/worksheet-info.ts +1 -0
  129. package/server/graphql/types/worksheet-detail/index.ts +0 -2
  130. package/server/index.ts +4 -0
  131. package/server/utils/inventory-util.ts +15 -23
@@ -1,6 +1,13 @@
1
1
  import { VasWorksheetController } from '../vas/vas-worksheet-controller'
2
2
  import { Product, ProductDetail } from '@things-factory/product-base'
3
- import { Inventory, INVENTORY_TRANSACTION_TYPE } from '@things-factory/warehouse-base'
3
+ import {
4
+ Inventory,
5
+ INVENTORY_TRANSACTION_TYPE,
6
+ InventoryItem,
7
+ INVENTORY_STATUS,
8
+ InventoryNoGenerator,
9
+ INVENTORY_ITEM_SOURCE
10
+ } from '@things-factory/warehouse-base'
4
11
  import { ReleaseGood, OrderInventory, ORDER_INVENTORY_STATUS, ORDER_STATUS } from '@things-factory/sales-base'
5
12
  import { Worksheet, WorksheetDetail } from '../../entities'
6
13
  import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
@@ -51,7 +58,12 @@ export class SortingWorksheetController extends VasWorksheetController {
51
58
  return await this.activateWorksheet(worksheet, worksheetDetails, sortingWorksheetDetails)
52
59
  }
53
60
 
54
- async scanProductSorting(taskNo: string, releaseGoodNo: string, productBarcode: string): Promise<void> {
61
+ async scanProductSorting(
62
+ taskNo: string,
63
+ releaseGoodNo: string,
64
+ productBarcode: string,
65
+ serialNumber: string
66
+ ): Promise<void> {
55
67
  const worksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
56
68
  where: {
57
69
  domain: this.domain,
@@ -113,8 +125,53 @@ export class SortingWorksheetController extends VasWorksheetController {
113
125
  const releaseQty: number = matchingOI.releaseQty
114
126
  const inventory: Inventory = matchingOI.inventory
115
127
  const releaseGood: ReleaseGood = matchingOI.releaseGood
128
+ const product: Product = inventory.product
116
129
 
117
130
  if (releaseQty != matchingOI?.sortedQty && sortedQty == 1) {
131
+ // Serial Number scanning for batch picking
132
+ if (matchingOI?.refWorksheetId) {
133
+ if (product?.isRequireSerialNumberScanningOutbound) {
134
+ if (!serialNumber || serialNumber == '') {
135
+ throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('sorting', `require serial number`))
136
+ }
137
+
138
+ let foundSerialNumber: InventoryItem = await this.trxMgr
139
+ .getRepository(InventoryItem)
140
+ .findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
141
+
142
+ if (foundSerialNumber) {
143
+ if (foundSerialNumber.inventoryId !== inventory.id) {
144
+ throw new Error('Serial Number scanned is in another inventory')
145
+ }
146
+
147
+ if (foundSerialNumber.outboundOrderId) {
148
+ let releaseGood: ReleaseGood = await this.trxMgr
149
+ .getRepository(ReleaseGood)
150
+ .findOne({ where: { id: foundSerialNumber.outboundOrderId } })
151
+ throw new Error(`Inventory Item is already picked/sorted in ${releaseGood.name}`)
152
+ }
153
+
154
+ foundSerialNumber.status = INVENTORY_STATUS.SORTING
155
+ foundSerialNumber.updater = this.user
156
+ foundSerialNumber.outboundOrderId = releaseGood.id
157
+
158
+ await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
159
+ } else {
160
+ let inventoryItem: InventoryItem = new InventoryItem()
161
+ inventoryItem.name = InventoryNoGenerator.inventoryItemName()
162
+ inventoryItem.serialNumber = serialNumber
163
+ inventoryItem.status = INVENTORY_STATUS.SORTING
164
+ inventoryItem.outboundOrderId = releaseGood.id
165
+ inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
166
+ inventoryItem.product = product
167
+ inventoryItem.inventory = inventory
168
+ inventoryItem.domain = this.domain
169
+
170
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
171
+ }
172
+ }
173
+ }
174
+
118
175
  matchingOI.sortedQty = Boolean(matchingOI?.sortedQty) ? matchingOI.sortedQty + sortedQty : sortedQty
119
176
  sortedQty -= 1
120
177
  if (matchingOI.sortedQty == releaseQty) {
@@ -128,6 +185,19 @@ export class SortingWorksheetController extends VasWorksheetController {
128
185
  worksheetDetail.status = WORKSHEET_STATUS.DONE
129
186
  worksheetDetail.updater = this.user
130
187
  await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
188
+
189
+ let inventoryItems: InventoryItem = await this.trxMgr
190
+ .getRepository(InventoryItem)
191
+ .find({ where: { outboundOrderId: releaseGood.id } })
192
+
193
+ if (inventoryItems.length > 0) {
194
+ inventoryItems.forEach((itm: InventoryItem) => {
195
+ itm.status = INVENTORY_STATUS.SORTED
196
+ itm.updater = this.user
197
+ })
198
+
199
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
200
+ }
131
201
  } else if (matchingOI?.sortedQty > releaseQty) {
132
202
  const product: Product = matchingOI.inventory.product
133
203
  throw new Error(this.ERROR_MSG.ORDER_ITEM.EXCESS_QTY(product.sku, packingType, packingSize))
@@ -141,7 +211,13 @@ export class SortingWorksheetController extends VasWorksheetController {
141
211
  }
142
212
  }
143
213
 
144
- async sortingProduct(taskNo: string, releaseGoodNo: string, productId: string, sortingQty: number): Promise<void> {
214
+ async sortingProduct(
215
+ taskNo: string,
216
+ releaseGoodNo: string,
217
+ productId: string,
218
+ sortingQty: number,
219
+ serialNumber: string
220
+ ): Promise<void> {
145
221
  const worksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
146
222
  where: {
147
223
  domain: this.domain,
@@ -180,14 +256,70 @@ export class SortingWorksheetController extends VasWorksheetController {
180
256
  const packingType: string = matchingOI.packingType
181
257
  const packingSize: number = matchingOI.packingSize
182
258
 
259
+ if (product?.isRequireSerialNumberScanningOutbound) {
260
+ if (!serialNumber || serialNumber == '') {
261
+ throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('sorting', `require serial number`))
262
+ }
263
+
264
+ let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
265
+ where: { domain: this.domain, serialNumber: serialNumber, product },
266
+ relations: ['product', 'inventory']
267
+ })
268
+
269
+ if (foundSerialNumber) {
270
+ if (foundSerialNumber.outboundOrderId) {
271
+ let releaseGood: ReleaseGood = await this.trxMgr
272
+ .getRepository(ReleaseGood)
273
+ .findOne({ where: { id: foundSerialNumber.outboundOrderId } })
274
+ throw new Error(`Inventory Item is already picked/sorted in ${releaseGood.name}`)
275
+ }
276
+
277
+ foundSerialNumber.status = INVENTORY_STATUS.SORTING
278
+ foundSerialNumber.updater = this.user
279
+ foundSerialNumber.outboundOrderId = releaseGood.id
280
+
281
+ await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
282
+ } else {
283
+ let inventoryItem: InventoryItem = new InventoryItem()
284
+ inventoryItem.name = InventoryNoGenerator.inventoryItemName()
285
+ inventoryItem.serialNumber = serialNumber
286
+ inventoryItem.status = INVENTORY_STATUS.SORTING
287
+ inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
288
+ inventoryItem.outboundOrderId = releaseGood.id
289
+ inventoryItem.product = product
290
+ inventoryItem.inventory = inventory
291
+ inventoryItem.domain = this.domain
292
+
293
+ foundSerialNumber = await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
294
+ }
295
+ }
296
+
183
297
  if (releaseQty != matchingOI?.sortedQty && sortingQty != 0) {
184
- matchingOI.sortedQty = releaseQty
298
+ if (product?.isRequireSerialNumberScanningOutbound) {
299
+ matchingOI.sortedQty += sortingQty
300
+ } else {
301
+ matchingOI.sortedQty = releaseQty
302
+ }
303
+
185
304
  sortingQty -= releaseQty
186
305
  if (matchingOI.sortedQty == releaseQty) {
187
306
  matchingOI.status = ORDER_INVENTORY_STATUS.SORTED
188
307
  await this.updateOrderTargets([matchingOI])
189
308
  await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.SORTING)
190
309
 
310
+ let inventoryItems: InventoryItem = await this.trxMgr
311
+ .getRepository(InventoryItem)
312
+ .find({ where: { outboundOrderId: releaseGood.id } })
313
+
314
+ if (inventoryItems.length > 0) {
315
+ inventoryItems.forEach((itm: InventoryItem) => {
316
+ itm.status = INVENTORY_STATUS.PACKED
317
+ itm.updater = this.user
318
+ })
319
+
320
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
321
+ }
322
+
191
323
  let worksheetDetail: WorksheetDetail = worksheetDetails.find(
192
324
  wsd => wsd.targetInventory.id === matchingOI.id
193
325
  )
@@ -220,6 +352,19 @@ export class SortingWorksheetController extends VasWorksheetController {
220
352
  releaseGood.updater = this.user
221
353
  await this.trxMgr.getRepository(ReleaseGood).save(releaseGood)
222
354
 
355
+ let inventoryItems: InventoryItem = await this.trxMgr
356
+ .getRepository(InventoryItem)
357
+ .find({ where: { outboundOrderId: releaseGood.id } })
358
+
359
+ if (inventoryItems.length > 0) {
360
+ inventoryItems.forEach((itm: InventoryItem) => {
361
+ itm.status = INVENTORY_STATUS.TERMINATED
362
+ itm.updater = this.user
363
+ })
364
+
365
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
366
+ }
367
+
223
368
  return releaseGood
224
369
  }
225
370
 
@@ -1,7 +1,8 @@
1
+ import _ from 'lodash'
1
2
  import FormData from 'form-data'
2
3
  import fetch from 'node-fetch'
3
4
  import { getRepository, IsNull, Not } from 'typeorm'
4
-
5
+ import { InventoryItem } from '@things-factory/warehouse-base'
5
6
  import { Attachment, STORAGE } from '@things-factory/attachment-base'
6
7
  import { Partner } from '@things-factory/auth-base'
7
8
  import { Bizplace, ContactPoint } from '@things-factory/biz-base'
@@ -32,6 +33,10 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
32
33
  const foundGAN: ArrivalNotice = foundGRN.arrivalNotice
33
34
  const ownRefNo = foundGAN.refNo
34
35
 
36
+ const foundInventoryItem: InventoryItem[] = await getRepository(InventoryItem).query(
37
+ `select row_number() over (partition by p.sku) as "seq",p.sku,p.brand_sku, ii.serial_number from inventory_items ii left join products p on ii.product_id = p.id where inbound_order_id = '${foundGAN.id}' group by p.sku,ii.serial_number,p.brand_sku`
38
+ )
39
+
35
40
  // 4. find customer bizplace
36
41
  const partnerBiz: Bizplace = foundGRN.bizplace
37
42
 
@@ -142,6 +147,32 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
142
147
  cop = 'data:' + foundSignature.mimetype + ';base64,' + (await STORAGE.readFile(foundCop.path, 'base64'))
143
148
  }
144
149
 
150
+ const filterInventoryItem = _.groupBy(foundInventoryItem, i => i.sku)
151
+
152
+ const tempIndexArr = []
153
+
154
+ const tempTotalQuantity = []
155
+
156
+ Object.keys(filterInventoryItem).forEach(k => {
157
+ const tempIndex = foundInventoryItem.findIndex(i => {
158
+ return i.sku == k
159
+ })
160
+
161
+ tempIndexArr.push(tempIndex)
162
+ })
163
+
164
+ Object.values(filterInventoryItem).forEach(k => {
165
+ const tempQuantity = k.length
166
+
167
+ tempTotalQuantity.push(tempQuantity)
168
+ })
169
+
170
+ tempIndexArr.forEach((t, index) => {
171
+ if (t >= 0)
172
+ foundInventoryItem[t].totalQuantity = tempTotalQuantity[index]
173
+ })
174
+
175
+
145
176
  const data = {
146
177
  logo_url: logo,
147
178
  sign_url: signature,
@@ -166,6 +197,7 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
166
197
  gan_accepted_at: foundGAN.acceptedAt ? DateTimeConverter.datetime(foundGAN.acceptedAt, timezoneOffSet) : '',
167
198
  unload_date: DateTimeConverter.date(foundWS.endedAt),
168
199
  ref_no: ownRefNo ? `${foundGAN.name} / ${foundGAN.refNo}` : `${foundGAN.name}`,
200
+ ref_no_only: ownRefNo ? ` ${foundGAN.refNo}` : '',
169
201
  ref_no1: foundGAN.refNo2 ? `${foundGAN.refNo2}` : '',
170
202
  ref_no2: foundGAN.refNo3 ? `${foundGAN.refNo3}` : '',
171
203
  received_date: DateTimeConverter.date(foundWS.endedAt),
@@ -188,6 +220,7 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
188
220
  return {
189
221
  list_no: idx + 1,
190
222
  product_sku: `${item.product.sku}`,
223
+ product_brand_sku: `${item.product.brandSku}`,
191
224
  product_name: `${item.product.name}(${item.product.description})`,
192
225
  product_desc: item.product.description,
193
226
  product_nameOnly: item.product.name,
@@ -198,17 +231,18 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
198
231
  pallet_qty: item.actualPalletQty,
199
232
  product_qty: unloadInvHistory.qty || item.actualPackQty,
200
233
  product_unit_uom_value: `${Math.round(item.uomValue * 100) / 100}`,
201
- product_total_uom_value: `${
202
- Math.round((unloadInvHistory.uomValue || item.uomValue * item.actualPackQty) * 100) / 100
203
- }`,
234
+ product_total_uom_value: `${Math.round((unloadInvHistory.uomValue || item.uomValue * item.actualPackQty) * 100) / 100
235
+ }`,
204
236
  product_uom: `${unloadInvHistory.uom || item.uom}`,
205
237
  product_gross_weight: item.product.grossWeight || null,
206
238
  unit_price: item.unitPrice || null,
207
239
  expiry_date: unloadInvHistory.expiryDate || '',
240
+ manufacture_date: item.manufactureDate,
208
241
  reusable_pallet_id: unloadInvHistory.reusablePalletId || '',
209
242
  remark: (item.remark ? item.remark : '') + (item.issue ? ' [Issue]: ' + item.issue : '')
210
243
  }
211
- })
244
+ }),
245
+ serialNumber: foundInventoryItem
212
246
  }
213
247
 
214
248
  const formData = new FormData()
@@ -1,11 +1,11 @@
1
1
  import FormData from 'form-data'
2
2
  import fetch from 'node-fetch'
3
- import { getRepository } from 'typeorm'
3
+ import { getRepository, SelectQueryBuilder } from 'typeorm'
4
4
 
5
5
  import { Attachment, STORAGE } from '@things-factory/attachment-base'
6
6
  import { Bizplace } from '@things-factory/biz-base'
7
7
  import { config } from '@things-factory/env'
8
- import { Invoice, ReleaseGood } from '@things-factory/sales-base'
8
+ import { InvoiceProduct, ReleaseGood } from '@things-factory/sales-base'
9
9
  import { Domain } from '@things-factory/shell'
10
10
 
11
11
  import { TEMPLATE_TYPE } from '../constants'
@@ -22,20 +22,34 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
22
22
  let result = await Promise.all(
23
23
  req.roIds.map(async roId => {
24
24
  try {
25
- const foundReleaseGoods: ReleaseGood = await getRepository(ReleaseGood).findOne({
26
- where: { domain, id: roId },
27
- relations: ['domain', 'bizplace', 'bizplace.domain', 'bizplace.company', 'bizplace.company.domain']
28
- })
29
-
30
- if (foundReleaseGoods) {
31
- const foundInvoice: Invoice = await getRepository(Invoice).findOne({
32
- where: { releaseGood: foundReleaseGoods },
33
- relations: ['invoiceProducts', 'invoiceProducts.product', 'domain', 'creator', 'updater']
34
- })
35
-
36
- const partnerBiz: Bizplace = foundReleaseGoods.bizplace
25
+ const qb: SelectQueryBuilder<ReleaseGood> = await getRepository(ReleaseGood)
26
+ .createQueryBuilder('rg')
27
+ .innerJoinAndSelect('rg.domain', 'domain')
28
+ .innerJoinAndSelect('rg.bizplace', 'bizplace')
29
+ .innerJoinAndSelect('bizplace.domain', 'bizplace_domain')
30
+ .innerJoinAndSelect('bizplace.company', 'company')
31
+ .innerJoinAndSelect('company.domain', 'company_domain')
32
+ .innerJoinAndSelect('invoices', 'iv', 'rg.ref_no = iv.ref_no_1')
33
+ .leftJoinAndSelect('marketplace_orders', 'mo', 'rg.id = mo.release_order_id::uuid')
34
+ .leftJoinAndSelect('marketplace_order_shippings', 'mos', 'rg.id = mos.release_order_id::uuid')
35
+ .leftJoinAndSelect('mo.fulfillmentCenter', 'fc')
36
+ .where('rg.id = :roId')
37
+ .andWhere('rg.domain = :domainId')
38
+ .setParameters({ roId, domainId: domain.id })
39
+
40
+ let record: any = await qb.getRawOne()
41
+
42
+ if (record) {
43
+ const partnerBiz: Partial<Bizplace> = {
44
+ id: record.bizplace_id,
45
+ name: record.bizplace_name,
46
+ address: record.bizplace_address
47
+ }
37
48
 
38
- const partnerCompanyDomain: Domain = foundReleaseGoods.bizplace.company.domain
49
+ const partnerCompanyDomain: Partial<Domain> = {
50
+ id: record.company_domain_id,
51
+ name: record.company_domain_name
52
+ }
39
53
 
40
54
  const foundTemplate: Attachment = await getRepository(Attachment).findOne({
41
55
  where: { domain: partnerCompanyDomain, category: TEMPLATE_TYPE.INVOICE_TEMPLATE }
@@ -44,43 +58,74 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
44
58
  const template = await STORAGE.readFile(foundTemplate.path, 'utf-8')
45
59
 
46
60
  let fullBillingAddress = [
47
- foundInvoice.billingAddress1,
48
- foundInvoice.billingAddress2,
49
- foundInvoice.billingAddress3,
50
- foundInvoice.billingAddress4,
51
- foundInvoice.billingAddress5
61
+ record.iv_billing_address_1,
62
+ record.iv_billing_address_2,
63
+ record.iv_billing_address_3,
64
+ record.iv_billing_address_4,
65
+ record.iv_billing_address_5
52
66
  ]
53
67
 
54
68
  let fullDeliveryAddress = [
55
- foundInvoice.deliveryAddress1,
56
- foundInvoice.deliveryAddress2,
57
- foundInvoice.deliveryAddress3,
58
- foundInvoice.deliveryAddress4,
59
- foundInvoice.deliveryAddress5
69
+ record.iv_delivery_address_1,
70
+ record.iv_delivery_address_2,
71
+ record.iv_delivery_address_3,
72
+ record.iv_delivery_address_4,
73
+ record.iv_delivery_address_5
60
74
  ]
61
75
 
62
- let date = DateTimeConverter.date(
63
- new Date((foundInvoice.issuedOn || foundInvoice.createdAt) - timezoneOffSet)
76
+ const qb: SelectQueryBuilder<InvoiceProduct> = await getRepository(InvoiceProduct)
77
+ .createQueryBuilder('ip')
78
+ .innerJoin('invoices', 'iv', 'iv.id = ip.invoice_id')
79
+ .leftJoin('release_goods', 'rg', 'rg.ref_no = iv.ref_no_1')
80
+ .where('rg.id = :roId')
81
+ .andWhere('rg.domain = :domainId')
82
+ .setParameters({ roId, domainId: domain.id })
83
+
84
+ let items: any[] = await qb.getRawMany()
85
+
86
+ const product_list = items.map((item, idx) => {
87
+ return {
88
+ list_no: idx + 1,
89
+ product_sku: item.ip_sku,
90
+ product_name: item.ip_name,
91
+ product_desc: item.ip_description,
92
+ product_qty: item.ip_qty,
93
+ product_other_charges: item.ip_other_charges,
94
+ product_paid_price: getRoundedValue(item.ip_paid_price || item.ip_unit_price),
95
+ product_unit_price: getRoundedValue(item.ip_unit_price),
96
+ product_total_paid_price: getRoundedValue(
97
+ (item.ip_paid_price || item.ip_unit_price) * parseInt(item.ip_qty || 0)
98
+ ),
99
+ product_total_unit_price: getRoundedValue(item.ip_unit_price * parseInt(item.ip_qty || 0)),
100
+ original_price: getRoundedValue(parseFloat(item.ip_unit_price || 0)),
101
+ product_discount: getRoundedValue(parseFloat(item.ip_discount || 0)),
102
+ shipping_fee_paid_by_customer: getRoundedValue(parseFloat(item.ip_shipping_fee_paid_by_customer || 0))
103
+ }
104
+ })
105
+
106
+ const sumProductTotalPaidPrice: number = product_list.reduce(
107
+ (total, item) => total + item.product_total_paid_price,
108
+ 0
64
109
  )
110
+
111
+ let date = DateTimeConverter.date(new Date((record.iv_issued_on || record.iv_created_at) - timezoneOffSet))
65
112
  const data = {
66
- order_no: foundReleaseGoods.name,
67
- ref_no: foundReleaseGoods.refNo,
68
- deliver_to: foundInvoice.deliverTo,
69
- deliver_to_phone: foundInvoice.deliverToPhone || '',
70
- bill_to: foundInvoice.billTo,
71
- bill_to_phone: foundInvoice.billToPhone || '',
113
+ order_no: record.rg_name,
114
+ ref_no: record.rg_ref_no,
115
+ from: record.iv_from,
72
116
  customer_address: partnerBiz.address,
73
- delivery_date: date,
74
- store_name: foundInvoice.from,
75
- billing_address_1: foundInvoice.billingAddress1,
76
- billing_address_2: foundInvoice.billingAddress2,
77
- billing_address_3: foundInvoice.billingAddress3,
78
- billing_address_4: foundInvoice.billingAddress4,
79
- billing_address_5: foundInvoice.billingAddress5,
80
- billing_postcode: foundInvoice.billingPostcode,
81
- billing_city: foundInvoice.billingCity,
82
- billing_state: foundInvoice.billingState,
83
- billing_country: foundInvoice.billingCountry,
117
+ store_name: record.iv_from,
118
+ bill_to: record.iv_bill_to,
119
+ bill_to_phone: record.iv_bill_to_phone,
120
+ billing_address_1: record.iv_billing_address_1,
121
+ billing_address_2: record.iv_billing_address_2,
122
+ billing_address_3: record.iv_billing_address_3,
123
+ billing_address_4: record.iv_billing_address_4,
124
+ billing_address_5: record.iv_billing_address_5,
125
+ billing_postcode: record.iv_billing_postcode,
126
+ billing_city: record.iv_billing_city,
127
+ billing_state: record.iv_billing_state,
128
+ billing_country: record.iv_billing_country,
84
129
  full_billing_address: fullBillingAddress
85
130
  .reduce((acc, itm) => {
86
131
  if (itm && itm.trim() != '') {
@@ -90,15 +135,18 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
90
135
  return acc
91
136
  }, [])
92
137
  .join(' '),
93
- delivery_address_1: foundInvoice.deliveryAddress1,
94
- delivery_address_2: foundInvoice.deliveryAddress2,
95
- delivery_address_3: foundInvoice.deliveryAddress3,
96
- delivery_address_4: foundInvoice.deliveryAddress4,
97
- delivery_address_5: foundInvoice.deliveryAddress5,
98
- delivery_postcode: foundInvoice.deliveryPostcode,
99
- delivery_city: foundInvoice.deliveryCity,
100
- delivery_state: foundInvoice.deliveryState,
101
- delivery_country: foundInvoice.deliveryCountry,
138
+ delivery_date: date,
139
+ deliver_to: record.iv_deliver_to,
140
+ deliver_to_phone: record.iv_deliver_to_phone,
141
+ delivery_address_1: record.iv_delivery_address_1,
142
+ delivery_address_2: record.iv_delivery_address_2,
143
+ delivery_address_3: record.iv_delivery_address_3,
144
+ delivery_address_4: record.iv_delivery_address_4,
145
+ delivery_address_5: record.iv_delivery_address_5,
146
+ delivery_postcode: record.iv_delivery_postcode,
147
+ delivery_city: record.iv_delivery_city,
148
+ delivery_state: record.iv_delivery_state,
149
+ delivery_country: record.iv_delivery_country,
102
150
  full_delivery_address: fullDeliveryAddress
103
151
  .reduce((acc, itm) => {
104
152
  if (itm && itm.trim() != '') {
@@ -108,22 +156,16 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
108
156
  return acc
109
157
  }, [])
110
158
  .join(' '),
111
- product_list: foundInvoice.invoiceProducts.map((item, idx) => {
112
- return {
113
- list_no: idx + 1,
114
- product_sku: item.sku,
115
- product_name: item.name,
116
- product_desc: item.description,
117
- product_qty: item.qty,
118
- product_other_charges: item.otherCharges,
119
- product_paid_price: parseFloat(item.paidPrice || item.unitPrice).toFixed(2),
120
- product_unit_price: parseFloat(item.unitPrice).toFixed(2),
121
- product_total_paid_price: (
122
- parseFloat(item.paidPrice || item.unitPrice) * parseFloat(item.qty)
123
- ).toFixed(2),
124
- product_total_unit_price: (parseFloat(item.unitPrice) * parseFloat(item.qty)).toFixed(2)
125
- }
126
- })
159
+ fulfillment_center: record.fc_name,
160
+ voucher_amount: getRoundedValue(parseFloat(record.mo_voucher_amount || 0)),
161
+ actual_shipping_fee: getRoundedValue(parseFloat(record.mos_actual_shipping_fee || 0)),
162
+ sub_total: sumProductTotalPaidPrice,
163
+ grand_total: getRoundedValue(
164
+ sumProductTotalPaidPrice -
165
+ parseFloat(record.mo_voucher_amount || 0) +
166
+ parseFloat(record.mos_actual_shipping_fee || 0)
167
+ ),
168
+ product_list
127
169
  }
128
170
 
129
171
  const formData = new FormData()
@@ -137,18 +179,23 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
137
179
 
138
180
  return await response.text()
139
181
  }
140
- return ''
182
+ return null
141
183
  } catch (ex) {
142
- return ''
184
+ return null
143
185
  }
144
186
  })
145
187
  )
146
188
 
147
- if (result.length <= 0) {
189
+ if (result.filter(x => x != null).length <= 0) {
148
190
  throw Error('No invoice found!')
149
191
  }
192
+
150
193
  return result.join()
151
194
  } catch (ex) {
152
195
  throw ex
153
196
  }
154
197
  }
198
+
199
+ function getRoundedValue(value = 0) {
200
+ return Math.round((value + Number.EPSILON) * 100) / 100
201
+ }
@@ -150,20 +150,20 @@ export async function renderOrientageDO({ doNo }, context: any) {
150
150
  pack_size: matchedProductDetail
151
151
  ? matchedProductDetail.uomValue
152
152
  ? matchedProductDetail.uomValue +
153
- ' ' +
154
- matchedProductDetail.uom +
155
- (inventory.product.volumeSize
156
- ? ' x ' + (parseFloat(inventory.product.volumeSize) / 100).toFixed(2) + ' L'
157
- : '')
153
+ ' ' +
154
+ matchedProductDetail.uom +
155
+ (inventory.product.volumeSize
156
+ ? ' x ' + (parseFloat(inventory.product.volumeSize) / 100).toFixed(2) + ' L'
157
+ : '')
158
158
  : null
159
159
  : inventory.product.primaryValue
160
- ? inventory.product.primaryValue +
160
+ ? inventory.product.primaryValue +
161
161
  ' ' +
162
162
  inventory.product.primaryUnit +
163
163
  (inventory.product.volumeSize
164
164
  ? ' x ' + (parseFloat(inventory.product.volumeSize) / 100).toFixed(2) + ' L'
165
165
  : '')
166
- : null,
166
+ : null,
167
167
  aux_value_3: matchedProductDetail ? matchedProductDetail.auxValue3 : inventory.product.auxValue3,
168
168
  product_qty: targetInventory.inventory.warehouse !== 'DAMAGE ZONE' ? targetInventory.releaseQty : 0,
169
169
  product_qty_damage: targetInventory.inventory.warehouse === 'DAMAGE ZONE' ? targetInventory.releaseQty : 0,
@@ -176,15 +176,15 @@ export async function renderOrientageDO({ doNo }, context: any) {
176
176
  ? matchedProductDetail.volume
177
177
  : 0
178
178
  : inventory?.product?.volume
179
- ? inventory.product.volume
180
- : 0,
179
+ ? inventory.product.volume
180
+ : 0,
181
181
  total_volume: matchedProductDetail
182
182
  ? matchedProductDetail.volume
183
183
  ? Number((matchedProductDetail.volume * targetInventory.releaseQty).toFixed(4))
184
184
  : 0
185
185
  : inventory?.product?.volume
186
- ? Number((inventory.product.volume * targetInventory.releaseQty).toFixed(4))
187
- : 0,
186
+ ? Number((inventory.product.volume * targetInventory.releaseQty).toFixed(4))
187
+ : 0,
188
188
  remark: targetInventory.remark,
189
189
  inventory_remark: inventory.remark,
190
190
  cross_docking: targetInventory.crossDocking,
@@ -123,16 +123,16 @@ export async function renderOrientageGRN({ grnNo }, context: any) {
123
123
  pack_size: matchedProductDetail
124
124
  ? matchedProductDetail.uomValue
125
125
  ? matchedProductDetail.uomValue +
126
- ' ' +
127
- matchedProductDetail.uom +
128
- (item.product.volumeSize ? ' x ' + (parseFloat(item.product.volumeSize) / 100).toFixed(2) + ' L' : '')
126
+ ' ' +
127
+ matchedProductDetail.uom +
128
+ (item.product.volumeSize ? ' x ' + (parseFloat(item.product.volumeSize) / 100).toFixed(2) + ' L' : '')
129
129
  : null
130
130
  : item.product.primaryValue
131
- ? item.product.primaryValue +
131
+ ? item.product.primaryValue +
132
132
  ' ' +
133
133
  item.product.primaryUnit +
134
134
  (item.product.volumeSize ? ' x ' + (parseFloat(item.product.volumeSize) / 100).toFixed(2) + ' L' : '')
135
- : null,
135
+ : null,
136
136
  pack_qty: item.packQty ? item.packQty : 0,
137
137
  actual_pack_qty: item.actualPackQty ? item.actualPackQty : 0,
138
138
  container_no: foundGAN.containerNo ? foundGAN.containerNo : '',
@@ -142,23 +142,24 @@ export async function renderOrientageGRN({ grnNo }, context: any) {
142
142
  ? matchedProductDetail.volume
143
143
  : 0
144
144
  : item?.product?.volume
145
- ? item.product.volume
146
- : 0,
145
+ ? item.product.volume
146
+ : 0,
147
147
  total_volume: matchedProductDetail
148
148
  ? matchedProductDetail.volume
149
149
  ? Number((matchedProductDetail.volume * item.actualPackQty).toFixed(4))
150
150
  : 0
151
151
  : item?.product?.volume
152
- ? Number((item.product.volume * item.actualPackQty).toFixed(4))
153
- : 0,
152
+ ? Number((item.product.volume * item.actualPackQty).toFixed(4))
153
+ : 0,
154
+ manufacture_year: item.manufactureDate ? new Date(item.manufactureDate).getFullYear() : null,
154
155
  manufacture_date: item.manufactureDate ? item.manufactureDate : null,
155
156
  literage: matchedProductDetail
156
157
  ? matchedProductDetail.packingSize
157
158
  ? parseFloat(matchedProductDetail.packingSize) * parseFloat(item.product.volumeSize)
158
159
  : 0
159
160
  : item.packingSize
160
- ? parseFloat(item.packingSize) * parseFloat(item.product.volumeSize)
161
- : 0,
161
+ ? parseFloat(item.packingSize) * parseFloat(item.product.volumeSize)
162
+ : 0,
162
163
  remark: item.remark || ''
163
164
  }
164
165
  })