@things-factory/worksheet-base 4.3.105-alpha.0 → 4.3.106

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