@things-factory/worksheet-base 4.3.106 → 4.3.108

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 (73) hide show
  1. package/dist-server/controllers/inbound/unloading-worksheet-controller.js +58 -73
  2. package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js +7 -6
  4. package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js.map +1 -1
  5. package/dist-server/controllers/outbound/loading-worksheet-controller.js +10 -4
  6. package/dist-server/controllers/outbound/loading-worksheet-controller.js.map +1 -1
  7. package/dist-server/controllers/outbound/packing-worksheet-controller.js +33 -24
  8. package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
  9. package/dist-server/controllers/outbound/picking-worksheet-controller.js +78 -48
  10. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  11. package/dist-server/controllers/outbound/sorting-worksheet-controller.js +12 -14
  12. package/dist-server/controllers/outbound/sorting-worksheet-controller.js.map +1 -1
  13. package/dist-server/controllers/vas/vas-worksheet-controller.js +1 -2
  14. package/dist-server/controllers/vas/vas-worksheet-controller.js.map +1 -1
  15. package/dist-server/controllers/worksheet-controller.js +3 -8
  16. package/dist-server/controllers/worksheet-controller.js.map +1 -1
  17. package/dist-server/entities/index.js +3 -2
  18. package/dist-server/entities/index.js.map +1 -1
  19. package/dist-server/entities/warehouse-bizplace-onhand-inventory.js +29 -62
  20. package/dist-server/entities/warehouse-bizplace-onhand-inventory.js.map +1 -1
  21. package/dist-server/graphql/resolvers/worksheet/batch-picking-worksheet.js +6 -0
  22. package/dist-server/graphql/resolvers/worksheet/batch-picking-worksheet.js.map +1 -1
  23. package/dist-server/graphql/resolvers/worksheet/check-stock-take-current-location.js +43 -39
  24. package/dist-server/graphql/resolvers/worksheet/check-stock-take-current-location.js.map +1 -1
  25. package/dist-server/graphql/resolvers/worksheet/confirm-cancellation-release-order.js +1 -2
  26. package/dist-server/graphql/resolvers/worksheet/confirm-cancellation-release-order.js.map +1 -1
  27. package/dist-server/graphql/resolvers/worksheet/cycle-count-adjustment.js +6 -6
  28. package/dist-server/graphql/resolvers/worksheet/cycle-count-adjustment.js.map +1 -1
  29. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +2 -1
  30. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
  31. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +4 -1
  32. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
  33. package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js +3 -2
  34. package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js.map +1 -1
  35. package/dist-server/graphql/resolvers/worksheet/transfer.js +9 -9
  36. package/dist-server/graphql/resolvers/worksheet/transfer.js.map +1 -1
  37. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js +1 -1
  38. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js.map +1 -1
  39. package/dist-server/graphql/resolvers/worksheet/vas-transactions/common-utils.js +17 -17
  40. package/dist-server/graphql/resolvers/worksheet/vas-transactions/common-utils.js.map +1 -1
  41. package/dist-server/graphql/resolvers/worksheet/worksheets.js +1 -1
  42. package/dist-server/graphql/resolvers/worksheet/worksheets.js.map +1 -1
  43. package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js +4 -4
  44. package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js.map +1 -1
  45. package/dist-server/graphql/types/worksheet-detail/index.js +1 -0
  46. package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
  47. package/dist-server/utils/inventory-util.js +1 -98
  48. package/dist-server/utils/inventory-util.js.map +1 -1
  49. package/package.json +17 -17
  50. package/server/controllers/inbound/unloading-worksheet-controller.ts +72 -86
  51. package/server/controllers/inspect/cycle-count-worksheet-controller.ts +7 -6
  52. package/server/controllers/outbound/loading-worksheet-controller.ts +9 -3
  53. package/server/controllers/outbound/packing-worksheet-controller.ts +41 -36
  54. package/server/controllers/outbound/picking-worksheet-controller.ts +98 -66
  55. package/server/controllers/outbound/sorting-worksheet-controller.ts +12 -12
  56. package/server/controllers/vas/vas-worksheet-controller.ts +2 -2
  57. package/server/controllers/worksheet-controller.ts +18 -23
  58. package/server/entities/index.ts +2 -2
  59. package/server/entities/warehouse-bizplace-onhand-inventory.ts +29 -63
  60. package/server/graphql/resolvers/worksheet/batch-picking-worksheet.ts +6 -0
  61. package/server/graphql/resolvers/worksheet/check-stock-take-current-location.ts +52 -50
  62. package/server/graphql/resolvers/worksheet/confirm-cancellation-release-order.ts +1 -2
  63. package/server/graphql/resolvers/worksheet/cycle-count-adjustment.ts +2 -2
  64. package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +3 -1
  65. package/server/graphql/resolvers/worksheet/packing-worksheet.ts +4 -2
  66. package/server/graphql/resolvers/worksheet/picking-worksheet.ts +3 -2
  67. package/server/graphql/resolvers/worksheet/transfer.ts +18 -16
  68. package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +1 -1
  69. package/server/graphql/resolvers/worksheet/vas-transactions/common-utils.ts +3 -2
  70. package/server/graphql/resolvers/worksheet/worksheets.ts +1 -1
  71. package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts +4 -1
  72. package/server/graphql/types/worksheet-detail/index.ts +1 -0
  73. package/server/utils/inventory-util.ts +1 -126
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/worksheet-base",
3
- "version": "4.3.106",
3
+ "version": "4.3.108",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -24,21 +24,21 @@
24
24
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
25
25
  },
26
26
  "dependencies": {
27
- "@things-factory/auth-base": "^4.3.99",
28
- "@things-factory/biz-base": "^4.3.99",
29
- "@things-factory/document-template-base": "^4.3.99",
30
- "@things-factory/id-rule-base": "^4.3.99",
31
- "@things-factory/integration-lmd": "^4.3.99",
32
- "@things-factory/integration-marketplace": "^4.3.101",
33
- "@things-factory/integration-sellercraft": "^4.3.101",
34
- "@things-factory/integration-sftp": "^4.3.99",
35
- "@things-factory/marketplace-base": "^4.3.101",
36
- "@things-factory/notification": "^4.3.99",
37
- "@things-factory/sales-base": "^4.3.106",
38
- "@things-factory/setting-base": "^4.3.99",
39
- "@things-factory/shell": "^4.3.99",
40
- "@things-factory/transport-base": "^4.3.99",
41
- "@things-factory/warehouse-base": "^4.3.106"
27
+ "@things-factory/auth-base": "^4.3.108",
28
+ "@things-factory/biz-base": "^4.3.108",
29
+ "@things-factory/document-template-base": "^4.3.108",
30
+ "@things-factory/id-rule-base": "^4.3.108",
31
+ "@things-factory/integration-lmd": "^4.3.108",
32
+ "@things-factory/integration-marketplace": "^4.3.108",
33
+ "@things-factory/integration-sellercraft": "^4.3.108",
34
+ "@things-factory/integration-sftp": "^4.3.108",
35
+ "@things-factory/marketplace-base": "^4.3.108",
36
+ "@things-factory/notification": "^4.3.108",
37
+ "@things-factory/sales-base": "^4.3.108",
38
+ "@things-factory/setting-base": "^4.3.108",
39
+ "@things-factory/shell": "^4.3.108",
40
+ "@things-factory/transport-base": "^4.3.108",
41
+ "@things-factory/warehouse-base": "^4.3.108"
42
42
  },
43
- "gitHead": "0bbfb21a08ef01d28176936d9f04392215e5d84d"
43
+ "gitHead": "8aa8811dd0ebb1f4c1d9bc50fc221766d855c553"
44
44
  }
@@ -19,8 +19,8 @@ import {
19
19
  VAS_TARGET_TYPES,
20
20
  VAS_TYPES
21
21
  } from '@things-factory/sales-base'
22
- import { Domain } from '@things-factory/shell'
23
22
  import { PartnerSetting, Setting } from '@things-factory/setting-base'
23
+ import { Domain } from '@things-factory/shell'
24
24
  import {
25
25
  Inventory,
26
26
  INVENTORY_ITEM_SOURCE,
@@ -31,12 +31,13 @@ import {
31
31
  InventoryNoGenerator,
32
32
  Location,
33
33
  Pallet,
34
- Warehouse
34
+ Warehouse,
35
+ generateInventoryHistory
35
36
  } from '@things-factory/warehouse-base'
36
37
 
37
38
  import { RULE_TYPE, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
38
39
  import { Worksheet, WorksheetDetail } from '../../entities'
39
- import { DateGenerator, generateInventoryHistory } from '../../utils'
40
+ import { DateGenerator } from '../../utils'
40
41
  import { VasWorksheetController } from '../vas/vas-worksheet-controller'
41
42
 
42
43
  export type UnloadingWorksheetDetail = Partial<WorksheetDetail> & {
@@ -95,11 +96,13 @@ export class UnloadingWorksheetController extends VasWorksheetController {
95
96
  'worksheet.bufferLocation.warehouse',
96
97
  'targetProduct',
97
98
  'targetProduct.product',
99
+ 'targetProduct.productDetail',
98
100
  'targetProduct.product.productDetails',
99
101
  'targetProduct.product.productDetails.childProductDetail',
100
102
  'targetInventory',
101
103
  'targetInventory.inventory',
102
104
  'targetInventory.product',
105
+ 'targetInventory.productDetail',
103
106
  'targetInventory.product.productDetails',
104
107
  'targetInventory.product.productDetails.childProductDetail'
105
108
  ]
@@ -121,6 +124,9 @@ export class UnloadingWorksheetController extends VasWorksheetController {
121
124
  const batchId: string = Boolean(arrivalNotice) ? targetProduct.batchId : targetInventory.batchId
122
125
  const batchIdRef: string = Boolean(arrivalNotice) ? targetProduct.batchIdRef : null
123
126
  const product: Product = Boolean(arrivalNotice) ? targetProduct.product : targetInventory.product
127
+ const productDetail: ProductDetail = Boolean(arrivalNotice)
128
+ ? targetProduct.productDetail
129
+ : targetInventory.productDetail
124
130
  const packingType: string = Boolean(arrivalNotice) ? targetProduct.packingType : targetInventory.packingType
125
131
  const packingSize: number = Boolean(arrivalNotice) ? targetProduct.packingSize : targetInventory.packingSize
126
132
  const remark: string = Boolean(arrivalNotice) ? targetProduct.remark : targetInventory.remark
@@ -140,6 +146,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
140
146
 
141
147
  const palletId: string = inventory?.palletId
142
148
  const cartonId: string = inventory?.cartonId
149
+ let matchingProduct
143
150
 
144
151
  if (!inventory?.palletId) {
145
152
  inventory.palletId = await generateId({
@@ -153,35 +160,24 @@ export class UnloadingWorksheetController extends VasWorksheetController {
153
160
  }
154
161
 
155
162
  if (productBarcode) {
156
- const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
157
- const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
158
- if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
159
-
160
- const foundProductDetail: ProductDetail = productDetails.find(
161
- (detail: ProductDetail) =>
162
- detail.gtin === productBarcode && detail.packingType === packingType && detail.packingSize == packingSize
163
+ matchingProduct = await this.getDirectQty(
164
+ {
165
+ ...productDetail,
166
+ product: targetInventory?.product
167
+ },
168
+ productBarcode,
169
+ qty
163
170
  )
164
171
 
165
- if (!foundProductDetail) {
166
- const orderProductDetail: ProductDetail = productDetails.find(
167
- (parentDetail: ProductDetail) =>
168
- parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
169
- )
170
- if (!orderProductDetail)
171
- throw new Error(
172
- this.ERROR_MSG.FIND.NO_RESULT(`Packing Type ( ${packingType}) or Packing Size (${packingSize})`)
173
- )
172
+ //validate matching product details based on scanned barcode
173
+ if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
174
174
 
175
- if (arrivalNotice) {
176
- uom = targetProduct.uom
177
- } else {
178
- uom = orderProductDetail.uom
179
- }
180
- qty = (await this.getChildQty(productDetails, productBarcode, orderProductDetail)) * qty
181
- } else {
182
- uom = foundProductDetail.uom
183
- qty
184
- }
175
+ qty = matchingProduct.qty
176
+ uom = arrivalNotice ? targetProduct.uom : matchingProduct.uom
177
+ }
178
+
179
+ if (!uom) {
180
+ uom = productDetail.uom
185
181
  }
186
182
 
187
183
  const uomValue: number =
@@ -200,6 +196,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
200
196
  newInventory.cartonId = inventory.cartonId
201
197
  newInventory.batchId = batchId
202
198
  newInventory.product = product
199
+ newInventory.productDetail = productDetail
203
200
  newInventory.packingType = packingType
204
201
  newInventory.packingSize = packingSize
205
202
  newInventory.uom = uom
@@ -270,9 +267,11 @@ export class UnloadingWorksheetController extends VasWorksheetController {
270
267
  'worksheet.bufferLocation.warehouse',
271
268
  'targetProduct',
272
269
  'targetProduct.product',
270
+ 'targetProduct.productDetail',
273
271
  'targetProduct.product.productDetails',
274
272
  'targetProduct.product.productDetails.childProductDetail',
275
273
  'targetInventory',
274
+ 'targetInventory.productDetail',
276
275
  'targetInventory.product',
277
276
  'targetInventory.product.productDetails',
278
277
  'targetInventory.product.productDetails.childProductDetail'
@@ -289,7 +288,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
289
288
 
290
289
  const targetProduct: OrderProduct = worksheetDetail.targetProduct
291
290
 
292
- if (targetProduct.status == ORDER_PRODUCT_STATUS.EDITED)
291
+ if (targetProduct?.status == ORDER_PRODUCT_STATUS.EDITED)
293
292
  throw new Error('this product is pending for changes approval')
294
293
 
295
294
  const bizplace: Bizplace = worksheetDetail.bizplace
@@ -298,6 +297,9 @@ export class UnloadingWorksheetController extends VasWorksheetController {
298
297
  const returnOrder: ReturnOrder = worksheet.returnOrder
299
298
  const targetInventory: OrderInventory = worksheetDetail.targetInventory
300
299
  const product: Product = Boolean(arrivalNotice) ? targetProduct.product : targetInventory.product
300
+ const productDetail: ProductDetail = Boolean(arrivalNotice)
301
+ ? targetProduct.productDetail
302
+ : targetInventory.productDetail
301
303
  const packingType: string = Boolean(arrivalNotice) ? targetProduct.packingType : targetInventory.packingType
302
304
  const packingSize: number = Boolean(arrivalNotice) ? targetProduct.packingSize : targetInventory.packingSize
303
305
  const batchId: string = Boolean(arrivalNotice) ? targetProduct.batchId : targetInventory.batchId
@@ -309,15 +311,13 @@ export class UnloadingWorksheetController extends VasWorksheetController {
309
311
 
310
312
  qty++
311
313
 
312
- const invQb: SelectQueryBuilder<Inventory> = await this.trxMgr
314
+ const invQb: SelectQueryBuilder<Inventory> = this.trxMgr
313
315
  .getRepository(Inventory)
314
316
  .createQueryBuilder('INV')
315
317
  .where('INV.domain_id = :domainId', { domainId: this.domain.id })
316
318
  .andWhere('INV.bizplace_id = :bizplaceId', { bizplaceId: bizplace.id })
317
- .andWhere('INV.product_id = :productId', { productId: product.id })
319
+ .andWhere('INV.product_detail_id = :productDetailId', { productDetailId: productDetail.id })
318
320
  .andWhere('INV.batch_id = :batchId', { batchId: batchId })
319
- .andWhere('INV.packing_type = :packingType', { packingType: packingType })
320
- .andWhere('INV.packing_size = :packingSize', { packingSize: packingSize })
321
321
 
322
322
  if (arrivalNotice) invQb.andWhere('INV.ref_order_id = :arrivalNoticeId', { arrivalNoticeId: arrivalNotice.id })
323
323
  else if (returnOrder) invQb.andWhere('INV.ref_order_id = :returnOrderId', { returnOrderId: returnOrder.id })
@@ -357,6 +357,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
357
357
  newInventory.batchId = batchId
358
358
  newInventory.batchIdRef = batchIdRef
359
359
  newInventory.product = product
360
+ newInventory.productDetail = productDetail
360
361
  newInventory.packingType = packingType
361
362
  newInventory.packingSize = packingSize
362
363
  newInventory.uom = uom
@@ -421,6 +422,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
421
422
  inventoryItem.status = foundInventory.status
422
423
  inventoryItem.inboundOrderId = foundInventory.refOrderId
423
424
  inventoryItem.product = product
425
+ inventoryItem.productDetail = productDetail
424
426
  inventoryItem.inventory = foundInventory
425
427
  inventoryItem.source = INVENTORY_ITEM_SOURCE.INBOUND
426
428
  inventoryItem.domain = this.domain
@@ -457,10 +459,12 @@ export class UnloadingWorksheetController extends VasWorksheetController {
457
459
  'worksheet.bufferLocation.warehouse',
458
460
  'targetProduct',
459
461
  'targetProduct.product',
462
+ 'targetProduct.productDetail',
460
463
  'targetProduct.product.productDetails',
461
464
  'targetProduct.product.productDetails.childProductDetail',
462
465
  'targetInventory',
463
466
  'targetInventory.product',
467
+ 'targetInventory.productDetail',
464
468
  'targetInventory.product.productDetails',
465
469
  'targetInventory.product.productDetails.childProductDetail'
466
470
  ]
@@ -485,56 +489,43 @@ export class UnloadingWorksheetController extends VasWorksheetController {
485
489
  const returnOrder: ReturnOrder = worksheet.returnOrder
486
490
  const targetInventory: OrderInventory = worksheetDetail.targetInventory
487
491
  const product: Product = Boolean(arrivalNotice) ? targetProduct.product : targetInventory.product
492
+ const productDetail: ProductDetail = Boolean(arrivalNotice)
493
+ ? targetProduct.productDetail
494
+ : targetInventory.productDetail
488
495
  const packingType: string = Boolean(arrivalNotice) ? targetProduct.packingType : targetInventory.packingType
489
496
  const packingSize: number = Boolean(arrivalNotice) ? targetProduct.packingSize : targetInventory.packingSize
490
497
  const batchId: string = Boolean(arrivalNotice) ? targetProduct.batchId : targetInventory.batchId
491
- let qty: number = 0
498
+ let qty: number = 1
492
499
  let uom: string = Boolean(arrivalNotice) ? targetProduct.uom : targetInventory.uom
493
500
  const cartonId: string = inventory.cartonId
494
501
  const orderId: string = Boolean(arrivalNotice) ? arrivalNotice.id : returnOrder.id
495
502
  await this.checkCartonDuplication(cartonId, orderId)
503
+ let matchingProduct
496
504
 
497
- // search for matching product barcode
498
- const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
499
- const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
500
- if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
501
-
502
- // case for scanning parent packing type, packing size
503
- const foundProductDetail: ProductDetail = productDetails.find(
504
- (detail: ProductDetail) =>
505
- detail.gtin === productBarcode && detail.packingType === packingType && detail.packingSize == packingSize
506
- )
507
-
508
- if (!foundProductDetail) {
509
- const orderProductDetail: ProductDetail = productDetails.find(
510
- (parentDetail: ProductDetail) =>
511
- parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
505
+ if (productBarcode !== productDetail.gtin) {
506
+ matchingProduct = await this.getDirectQty(
507
+ {
508
+ ...productDetail,
509
+ product: targetInventory?.product
510
+ },
511
+ productBarcode,
512
+ qty
512
513
  )
513
- if (!orderProductDetail)
514
- throw new Error(
515
- this.ERROR_MSG.FIND.NO_RESULT(`Packing Type ( ${packingType}) or Packing Size (${packingSize})`)
516
- )
517
514
 
518
- if (arrivalNotice) {
519
- uom = targetProduct.uom
520
- } else {
521
- uom = orderProductDetail.uom
522
- }
523
- qty = await this.getChildQty(productDetails, productBarcode, orderProductDetail)
524
- } else {
525
- uom = foundProductDetail.uom
526
- qty++
515
+ //validate matching product details based on scanned barcode
516
+ if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
517
+
518
+ qty = matchingProduct.qty
519
+ uom = arrivalNotice ? targetProduct.uom : matchingProduct.uom
527
520
  }
528
521
 
529
- const invQb: SelectQueryBuilder<Inventory> = await this.trxMgr
522
+ const invQb: SelectQueryBuilder<Inventory> = this.trxMgr
530
523
  .getRepository(Inventory)
531
524
  .createQueryBuilder('INV')
532
525
  .where('INV.domain_id = :domainId', { domainId: this.domain.id })
533
526
  .andWhere('INV.bizplace_id = :bizplaceId', { bizplaceId: bizplace.id })
534
- .andWhere('INV.product_id = :productId', { productId: product.id })
527
+ .andWhere('INV.product_detail_id = :productDetailId', { productDetailId: productDetail.id })
535
528
  .andWhere('INV.batch_id = :batchId', { batchId: batchId })
536
- .andWhere('INV.packing_type = :packingType', { packingType: packingType })
537
- .andWhere('INV.packing_size = :packingSize', { packingSize: packingSize })
538
529
 
539
530
  if (arrivalNotice) invQb.andWhere('INV.ref_order_id = :arrivalNoticeId', { arrivalNoticeId: arrivalNotice.id })
540
531
  else if (returnOrder) invQb.andWhere('INV.ref_order_id = :returnOrderId', { returnOrderId: returnOrder.id })
@@ -574,6 +565,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
574
565
  newInventory.batchId = batchId
575
566
  newInventory.batchIdRef = batchIdRef
576
567
  newInventory.product = product
568
+ newInventory.productDetail = productDetail
577
569
  newInventory.packingType = packingType
578
570
  newInventory.packingSize = packingSize
579
571
  newInventory.uom = uom
@@ -656,8 +648,10 @@ export class UnloadingWorksheetController extends VasWorksheetController {
656
648
  'worksheet.bufferLocation.warehouse',
657
649
  'targetProduct',
658
650
  'targetProduct.product',
651
+ 'targetProduct.productDetail',
659
652
  'targetInventory',
660
- 'targetInventory.product'
653
+ 'targetInventory.product',
654
+ 'targetInventory.productDetail'
661
655
  ]
662
656
  })
663
657
  if (!worksheetDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
@@ -668,9 +662,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
668
662
  const returnOrder: ReturnOrder = worksheet.returnOrder
669
663
  const targetProduct: OrderProduct = worksheetDetail.targetProduct
670
664
  const targetInventory: OrderInventory = worksheetDetail.targetInventory
671
- const product: Product = Boolean(arrivalNotice) ? targetProduct.product : targetInventory.product
672
- const packingType: string = Boolean(arrivalNotice) ? targetProduct.packingType : targetInventory.packingType
673
- const packingSize: number = Boolean(arrivalNotice) ? targetProduct.packingSize : targetInventory.packingSize
665
+ const productDetail: Product = Boolean(arrivalNotice) ? targetProduct.productDetail : targetInventory.productDetail
674
666
  const batchId: string = Boolean(arrivalNotice) ? targetProduct.batchId : targetInventory.batchId
675
667
 
676
668
  const invQb: SelectQueryBuilder<Inventory> = await this.trxMgr
@@ -678,10 +670,8 @@ export class UnloadingWorksheetController extends VasWorksheetController {
678
670
  .createQueryBuilder('INV')
679
671
  .where('INV.domain_id = :domainId', { domainId: this.domain.id })
680
672
  .andWhere('INV.bizplace_id = :bizplaceId', { bizplaceId: bizplace.id })
681
- .andWhere('INV.product_id = :productId', { productId: product.id })
673
+ .andWhere('INV.product_detail_id = :productDetailId', { productDetailId: productDetail.id })
682
674
  .andWhere('INV.batch_id = :batchId', { batchId: batchId })
683
- .andWhere('INV.packing_type = :packingType', { packingType: packingType })
684
- .andWhere('INV.packing_size = :packingSize', { packingSize: packingSize })
685
675
 
686
676
  if (arrivalNotice) invQb.andWhere('INV.ref_order_id = :arrivalNoticeId', { arrivalNoticeId: arrivalNotice.id })
687
677
  else if (returnOrder) invQb.andWhere('INV.ref_order_id = :returnOrderId', { returnOrderId: returnOrder.id })
@@ -714,7 +704,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
714
704
  const inventoryId: string = inventoryIds[i]
715
705
  let inventory: Inventory = await this.trxMgr.getRepository(Inventory).findOne({
716
706
  where: { domain: this.domain, id: inventoryId },
717
- relations: ['location', 'product']
707
+ relations: ['location', 'product', 'productDetail']
718
708
  })
719
709
 
720
710
  this.checkRecordValidity(inventory, {
@@ -744,14 +734,11 @@ export class UnloadingWorksheetController extends VasWorksheetController {
744
734
  if (orderType === ORDER_TYPES.ARRIVAL_NOTICE) {
745
735
  arrivalNotice = await this.trxMgr.getRepository(ArrivalNotice).findOne({
746
736
  where: { domain: this.domain, name: orderNo },
747
- relations: ['orderProducts', 'orderProducts.product']
737
+ relations: ['orderProducts', 'orderProducts.product', 'orderProducts.productDetail']
748
738
  })
749
739
 
750
740
  targetProduct = arrivalNotice.orderProducts.find(
751
- op =>
752
- op.batchId == inventory.batchId &&
753
- op.packingType == inventory.packingType &&
754
- op.product.id === inventory.product.id
741
+ op => op.batchId == inventory.batchId && op.productDetail.id == inventory.productDetail.id
755
742
  )
756
743
 
757
744
  if (inventory.status == INVENTORY_STATUS.UNLOADED) {
@@ -770,18 +757,17 @@ export class UnloadingWorksheetController extends VasWorksheetController {
770
757
  worksheetDetail = await this.trxMgr
771
758
  .getRepository(WorksheetDetail)
772
759
  .findOne({ where: { domain: this.domain, targetProduct } })
760
+
761
+ //remove all related serial numbers
762
+ await this.trxMgr.getRepository(InventoryItem).delete({ inventory: inventoryId })
773
763
  } else {
774
764
  returnOrder = await this.trxMgr.getRepository(ReturnOrder).findOne({
775
765
  where: { domain: this.domain, name: orderNo },
776
- relations: ['orderInventories', 'orderInventories.inventory', 'orderInventories.product']
766
+ relations: ['orderInventories', 'orderInventories.inventory', 'orderInventories.productDetail']
777
767
  })
778
768
 
779
769
  targetInventory = returnOrder.orderInventories.find(
780
- oi =>
781
- oi.batchId == inventory.batchId &&
782
- oi.packingType == inventory.packingType &&
783
- oi.product.id == inventory.product.id &&
784
- oi.packingSize === inventory.packingSize
770
+ oi => oi.batchId == inventory.batchId && oi.productDetail.id == inventory.productDetail.id
785
771
  )
786
772
  if (inventory.status == INVENTORY_STATUS.UNLOADED) {
787
773
  targetInventory.actualPackQty -= qty
@@ -103,16 +103,14 @@ export class CycleCountWorksheetController extends WorksheetController {
103
103
  let keyval = {
104
104
  batchId: 'batch_id',
105
105
  batchIdRef: 'batch_id_ref',
106
- packingType: 'packing_type',
107
- packingSize: 'packing_size',
108
- productId: 'product_id'
106
+ productDetailId: 'product_detail_id'
109
107
  }
110
108
 
111
109
  qb.andWhere(
112
110
  new Brackets(qb => {
113
111
  orderInventory.forEach((itm, idx) => {
114
112
  // sample itm value
115
- // batchId: 'WO00019730', batchIdRef: null, packingType: 'CARBOY', packingSize: 1, productId: '1d679587-c713-42d6-bd0a-74e587e39cc7'
113
+ // batchId: 'WO00019730', batchIdRef: null, productDetailId: '1d679587-c713-42d6-bd0a-74e587e39cc7'
116
114
  qb.orWhere(
117
115
  new Brackets(qb2 => {
118
116
  let first = true
@@ -309,7 +307,10 @@ export class CycleCountWorksheetController extends WorksheetController {
309
307
  targetInventory.updater = this.user
310
308
  await this.updateOrderTargets([targetInventory])
311
309
 
312
- worksheetDetail.status = WORKSHEET_STATUS.EXECUTING
310
+ worksheetDetail.status =
311
+ targetInventory.status === ORDER_INVENTORY_STATUS.MISSING
312
+ ? WORKSHEET_STATUS.NOT_TALLY
313
+ : WORKSHEET_STATUS.EXECUTING
313
314
  worksheetDetail.updater = this.user
314
315
  await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
315
316
 
@@ -397,7 +398,7 @@ export class CycleCountWorksheetController extends WorksheetController {
397
398
  targetInventory.inspectedLocation = location
398
399
  targetInventory.creator = this.user
399
400
  targetInventory.updater = this.user
400
- await this.updateOrderTargets([targetInventory])
401
+ await this.trxMgr.getRepository(OrderInventory).save(targetInventory)
401
402
 
402
403
  let worksheetDetail: WorksheetDetail = new WorksheetDetail()
403
404
  worksheetDetail.domain = this.domain
@@ -12,11 +12,10 @@ import {
12
12
  OrderToteItem,
13
13
  OrderTote
14
14
  } from '@things-factory/sales-base'
15
- import { Inventory, INVENTORY_TRANSACTION_TYPE, Tote, TOTE_STATUS } from '@things-factory/warehouse-base'
15
+ import { Inventory, INVENTORY_TRANSACTION_TYPE, Tote, TOTE_STATUS, generateInventoryHistory } from '@things-factory/warehouse-base'
16
16
 
17
17
  import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
18
18
  import { Worksheet, WorksheetDetail } from '../../entities'
19
- import { generateInventoryHistory } from '../../utils'
20
19
  import { VasWorksheetController } from '../vas/vas-worksheet-controller'
21
20
 
22
21
  export class LoadingWorksheetController extends VasWorksheetController {
@@ -112,7 +111,13 @@ export class LoadingWorksheetController extends VasWorksheetController {
112
111
  let worksheetDetail = await this.findExecutableWorksheetDetailByName(
113
112
  worksheetDetails[i].name,
114
113
  WORKSHEET_TYPE.LOADING,
115
- ['worksheet', 'targetInventory', 'targetInventory.inventory', 'targetInventory.product']
114
+ [
115
+ 'worksheet',
116
+ 'targetInventory',
117
+ 'targetInventory.inventory',
118
+ 'targetInventory.product',
119
+ 'targetInventory.productDetail'
120
+ ]
116
121
  )
117
122
 
118
123
  const worksheet: Worksheet = worksheetDetail.worksheet
@@ -170,6 +175,7 @@ export class LoadingWorksheetController extends VasWorksheetController {
170
175
  newTargetInventory.releaseQty = remainQty
171
176
  newTargetInventory.releaseUomValue = remainUomValue
172
177
  newTargetInventory.product = targetInventory.product
178
+ newTargetInventory.productDetail = targetInventory.productDetail
173
179
  newTargetInventory.packingType = targetInventory.packingType
174
180
  newTargetInventory.batchId = targetInventory.batchId
175
181
  newTargetInventory.creator = this.user
@@ -93,13 +93,15 @@ export class PackingWorksheetController extends VasWorksheetController {
93
93
  'targetInventory.releaseGood',
94
94
  'targetInventory.inventory',
95
95
  'targetInventory.inventory.location',
96
- 'targetInventory.product'
96
+ 'targetInventory.product',
97
+ 'targetInventory.productDetail'
97
98
  ]
98
99
  )
99
- const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
100
100
  let targetInventory: OrderInventory = worksheetDetail.targetInventory
101
- const product: Product = targetInventory.product
102
101
  let inventory: Inventory = targetInventory.inventory
102
+ const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
103
+ const product: Product = targetInventory.product
104
+ const productDetail: ProductDetail = targetInventory.productDetail
103
105
  const pickedQty: number = targetInventory.releaseQty
104
106
 
105
107
  if (packedQty > pickedQty) {
@@ -114,8 +116,7 @@ export class PackingWorksheetController extends VasWorksheetController {
114
116
  }
115
117
 
116
118
  let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
117
- where: { domain: this.domain, serialNumber: serialNumber, product },
118
- relations: ['product', 'inventory']
119
+ where: { domain: this.domain, serialNumber: serialNumber, productDetail }
119
120
  })
120
121
 
121
122
  if (foundSerialNumber) {
@@ -139,6 +140,7 @@ export class PackingWorksheetController extends VasWorksheetController {
139
140
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
140
141
  inventoryItem.outboundOrderId = releaseGood.id
141
142
  inventoryItem.product = product
143
+ inventoryItem.productDetail = productDetail
142
144
  inventoryItem.inventory = inventory
143
145
  inventoryItem.domain = this.domain
144
146
 
@@ -185,46 +187,48 @@ export class PackingWorksheetController extends VasWorksheetController {
185
187
  .innerJoinAndSelect('oi.releaseGood', 'rg')
186
188
  .innerJoinAndSelect('oi.inventory', 'inv')
187
189
  .leftJoinAndSelect('oi.orderProduct', 'op')
188
- .innerJoinAndSelect('inv.product', 'prd')
189
- .leftJoinAndSelect(
190
- 'prd.productDetails',
191
- 'pd',
192
- 'pd.product_id = oi.product_id AND pd.deleted_at is null AND pd.packing_type = oi.packing_type AND pd.packing_size = oi.packing_size AND pd.uom = oi.uom'
193
- )
190
+ .innerJoinAndSelect('oi.product', 'prd')
191
+ .innerJoinAndSelect('oi.productDetail', 'pd')
194
192
  .where('wd.id = :id', { id: worksheetDetailName })
195
- .andWhere('wd.type = :type', { type: WORKSHEET_TYPE.PACKING })
196
193
  .getOne()
197
194
 
198
- const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
199
- const product: Product = worksheetDetail.targetInventory.inventory.product
200
- const filterProductDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
201
195
  let targetInventory: OrderInventory = worksheetDetail.targetInventory
202
196
  let inventory: Inventory = targetInventory.inventory
203
197
  let packedQty: number = 1
204
198
  let pickedQty: number = targetInventory.releaseQty
205
-
206
- // search for matching product barcode
207
- const productDetail: ProductDetail = product?.productDetails
208
- .filter(detail => !detail.deletedAt)
209
- .find(
210
- detail =>
211
- detail.gtin === productBarcode &&
212
- detail.packingType === inventory.packingType &&
213
- detail.packingSize === inventory.packingSize
214
- )
215
-
216
- if (!productDetail && !product?.isRequireSerialNumberScanningOutbound) {
217
- let roProductDetail: ProductDetail = product?.productDetails.find(
218
- (parentDetail: ProductDetail) =>
219
- parentDetail.packingType === inventory.packingType && parentDetail.packingSize == inventory.packingSize
199
+ const releaseGood: ReleaseGood = targetInventory.releaseGood
200
+ const product: Product = targetInventory.inventory.product
201
+ const productDetail: ProductDetail = targetInventory.productDetail
202
+ let matchingProduct
203
+
204
+ // // search for matching product barcode
205
+ // const filterProductDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
206
+ // const scannedProductDetail: ProductDetail = filterProductDetails.find(detail => detail.gtin == productBarcode)
207
+ // if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
208
+
209
+ // // case for scanning parent packing type, packing size
210
+ // // when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
211
+ // if (scannedProductDetail.id !== productDetail.id && !product?.isRequireSerialNumberScanningOutbound) {
212
+ // let childQty = await this.getChildQty(filterProductDetails, productBarcode, productDetail, scannedProductDetail)
213
+ // packedQty *= childQty
214
+ // }
215
+
216
+ if (productBarcode !== productDetail.gtin) {
217
+ if (product?.isRequireSerialNumberScanningOutbound) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
218
+
219
+ matchingProduct = await this.getDirectQty(
220
+ {
221
+ ...productDetail,
222
+ product: targetInventory?.product
223
+ },
224
+ productBarcode,
225
+ packedQty
220
226
  )
221
227
 
222
- roProductDetail.product = product
228
+ //validate matching product details based on scanned barcode
229
+ if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
223
230
 
224
- let childQty = await this.getChildQty(filterProductDetails, productBarcode, roProductDetail)
225
- packedQty *= childQty
226
- } else if (!productDetail) {
227
- throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
231
+ packedQty = matchingProduct.qty
228
232
  }
229
233
 
230
234
  if (packedQty + targetInventory.packedQty > pickedQty) {
@@ -240,7 +244,7 @@ export class PackingWorksheetController extends VasWorksheetController {
240
244
 
241
245
  let foundSerialNumber: InventoryItem = await this.trxMgr
242
246
  .getRepository(InventoryItem)
243
- .findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
247
+ .findOne({ where: { domain: this.domain, serialNumber: serialNumber, productDetail } })
244
248
 
245
249
  if (foundSerialNumber) {
246
250
  if (foundSerialNumber.inventoryId !== inventory.id) {
@@ -267,6 +271,7 @@ export class PackingWorksheetController extends VasWorksheetController {
267
271
  inventoryItem.outboundOrderId = releaseGood.id
268
272
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
269
273
  inventoryItem.product = product
274
+ inventoryItem.productDetail = productDetail
270
275
  inventoryItem.inventory = inventory
271
276
  inventoryItem.domain = this.domain
272
277