@things-factory/worksheet-base 4.3.137 → 4.3.139

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 (70) hide show
  1. package/dist-server/controllers/inbound/unloading-worksheet-controller.js +59 -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 +2 -4
  4. package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js.map +1 -1
  5. package/dist-server/controllers/outbound/loading-worksheet-controller.js +5 -4
  6. package/dist-server/controllers/outbound/loading-worksheet-controller.js.map +1 -1
  7. package/dist-server/controllers/outbound/packing-worksheet-controller.js +23 -23
  8. package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
  9. package/dist-server/controllers/outbound/picking-worksheet-controller.js +157 -120
  10. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  11. package/dist-server/controllers/outbound/sorting-worksheet-controller.js +14 -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 +7 -7
  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/confirm-cancellation-release-order.js +1 -2
  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/find-sorting-release-orders-by-task-no.js +2 -2
  28. package/dist-server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.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-detail/regenerate-release-good-worksheet-details.js +4 -4
  42. package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js.map +1 -1
  43. package/dist-server/graphql/types/worksheet-detail/index.js +1 -0
  44. package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
  45. package/dist-server/utils/inventory-util.js +1 -98
  46. package/dist-server/utils/inventory-util.js.map +1 -1
  47. package/package.json +16 -16
  48. package/server/controllers/inbound/unloading-worksheet-controller.ts +74 -86
  49. package/server/controllers/inspect/cycle-count-worksheet-controller.ts +2 -4
  50. package/server/controllers/outbound/loading-worksheet-controller.ts +13 -3
  51. package/server/controllers/outbound/packing-worksheet-controller.ts +32 -37
  52. package/server/controllers/outbound/picking-worksheet-controller.ts +186 -150
  53. package/server/controllers/outbound/sorting-worksheet-controller.ts +14 -21
  54. package/server/controllers/vas/vas-worksheet-controller.ts +2 -2
  55. package/server/controllers/worksheet-controller.ts +15 -10
  56. package/server/entities/index.ts +2 -2
  57. package/server/entities/warehouse-bizplace-onhand-inventory.ts +29 -63
  58. package/server/graphql/resolvers/worksheet/batch-picking-worksheet.ts +6 -0
  59. package/server/graphql/resolvers/worksheet/confirm-cancellation-release-order.ts +1 -2
  60. package/server/graphql/resolvers/worksheet/cycle-count-adjustment.ts +2 -2
  61. package/server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.ts +2 -2
  62. package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +3 -1
  63. package/server/graphql/resolvers/worksheet/packing-worksheet.ts +4 -2
  64. package/server/graphql/resolvers/worksheet/picking-worksheet.ts +3 -2
  65. package/server/graphql/resolvers/worksheet/transfer.ts +18 -16
  66. package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +1 -1
  67. package/server/graphql/resolvers/worksheet/vas-transactions/common-utils.ts +3 -2
  68. package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts +4 -1
  69. package/server/graphql/types/worksheet-detail/index.ts +1 -0
  70. package/server/utils/inventory-util.ts +1 -126
@@ -2,7 +2,7 @@ import { Equal, Not } from 'typeorm'
2
2
 
3
3
  import { ApplicationType } from '@things-factory/auth-base'
4
4
  import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
5
- import { Product, ProductDetail } from '@things-factory/product-base'
5
+ import { Product, ProductDetail, ProductBarcode } from '@things-factory/product-base'
6
6
  import { logger } from '@things-factory/env'
7
7
  import { ORDER_INVENTORY_STATUS, ORDER_STATUS, OrderInventory, ReleaseGood } from '@things-factory/sales-base'
8
8
  import { Setting } from '@things-factory/setting-base'
@@ -141,13 +141,15 @@ export class PackingWorksheetController extends VasWorksheetController {
141
141
  'targetInventory.releaseGood',
142
142
  'targetInventory.inventory',
143
143
  'targetInventory.inventory.location',
144
- 'targetInventory.product'
144
+ 'targetInventory.product',
145
+ 'targetInventory.productDetail'
145
146
  ]
146
147
  )
147
- const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
148
148
  let targetInventory: OrderInventory = worksheetDetail.targetInventory
149
- const product: Product = targetInventory.product
150
149
  let inventory: Inventory = targetInventory.inventory
150
+ const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
151
+ const product: Product = targetInventory.product
152
+ const productDetail: ProductDetail = targetInventory.productDetail
151
153
  const pickedQty: number = targetInventory.releaseQty
152
154
 
153
155
  if (packedQty > pickedQty) {
@@ -162,8 +164,7 @@ export class PackingWorksheetController extends VasWorksheetController {
162
164
  }
163
165
 
164
166
  let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
165
- where: { domain: this.domain, serialNumber: serialNumber, product },
166
- relations: ['product', 'inventory']
167
+ where: { domain: this.domain, serialNumber: serialNumber, productDetail }
167
168
  })
168
169
 
169
170
  if (foundSerialNumber) {
@@ -187,6 +188,7 @@ export class PackingWorksheetController extends VasWorksheetController {
187
188
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
188
189
  inventoryItem.outboundOrderId = releaseGood.id
189
190
  inventoryItem.product = product
191
+ inventoryItem.productDetail = productDetail
190
192
  inventoryItem.inventory = inventory
191
193
  inventoryItem.domain = this.domain
192
194
 
@@ -233,47 +235,39 @@ export class PackingWorksheetController extends VasWorksheetController {
233
235
  .innerJoinAndSelect('oi.releaseGood', 'rg')
234
236
  .innerJoinAndSelect('oi.inventory', 'inv')
235
237
  .leftJoinAndSelect('oi.orderProduct', 'op')
236
- .innerJoinAndSelect('inv.product', 'prd')
237
- .leftJoinAndSelect(
238
- 'prd.productDetails',
239
- 'pd',
240
- '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'
241
- )
238
+ .innerJoinAndSelect('oi.product', 'prd')
239
+ .innerJoinAndSelect('oi.productDetail', 'pd')
240
+ .innerJoinAndSelect('pd.productBarcodes', 'pb')
242
241
  .where('wd.id = :id', { id: worksheetDetailName })
243
- .andWhere('wd.type = :type', { type: WORKSHEET_TYPE.PACKING })
244
242
  .getOne()
245
243
 
246
- const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
247
- const product: Product = worksheetDetail.targetInventory.inventory.product
248
- const filterProductDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
249
244
  let targetInventory: OrderInventory = worksheetDetail.targetInventory
250
245
  let inventory: Inventory = targetInventory.inventory
251
246
  let packedQty: number = 1
252
247
  let pickedQty: number = targetInventory.releaseQty
248
+ const releaseGood: ReleaseGood = targetInventory.releaseGood
249
+ const product: Product = targetInventory.product
250
+ const productDetail: ProductDetail = targetInventory.productDetail
251
+ const productBarcodes: [ProductBarcode] = productDetail.productBarcodes
252
+ let matchingProduct
253
253
 
254
- // search for matching product barcode
255
- const productDetail: ProductDetail = product?.productDetails
256
- .filter(detail => !detail.deletedAt)
257
- .find(
258
- detail =>
259
- detail.gtin === productBarcode &&
260
- detail.packingType === inventory.packingType &&
261
- detail.packingSize === inventory.packingSize
262
- )
254
+ if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
255
+ throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
256
+ }
263
257
 
264
- if (!productDetail && !product?.isRequireSerialNumberScanningOutbound) {
265
- let roProductDetail: ProductDetail = product?.productDetails.find(
266
- (parentDetail: ProductDetail) =>
267
- parentDetail.packingType === inventory.packingType && parentDetail.packingSize == inventory.packingSize
268
- )
258
+ matchingProduct = await this.getDirectQty(
259
+ {
260
+ ...productDetail,
261
+ product: targetInventory?.product
262
+ },
263
+ productBarcode,
264
+ packedQty
265
+ )
269
266
 
270
- roProductDetail.product = product
267
+ //validate matching product details based on scanned barcode
268
+ if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
271
269
 
272
- let childQty = await this.getChildQty(filterProductDetails, productBarcode, roProductDetail)
273
- packedQty *= childQty
274
- } else if (!productDetail) {
275
- throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
276
- }
270
+ packedQty = matchingProduct.qty
277
271
 
278
272
  if (packedQty + targetInventory.packedQty > pickedQty) {
279
273
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
@@ -288,7 +282,7 @@ export class PackingWorksheetController extends VasWorksheetController {
288
282
 
289
283
  let foundSerialNumber: InventoryItem = await this.trxMgr
290
284
  .getRepository(InventoryItem)
291
- .findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
285
+ .findOne({ where: { domain: this.domain, serialNumber: serialNumber, productDetail } })
292
286
 
293
287
  if (foundSerialNumber) {
294
288
  if (foundSerialNumber.inventoryId !== inventory.id) {
@@ -315,6 +309,7 @@ export class PackingWorksheetController extends VasWorksheetController {
315
309
  inventoryItem.outboundOrderId = releaseGood.id
316
310
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
317
311
  inventoryItem.product = product
312
+ inventoryItem.productDetail = productDetail
318
313
  inventoryItem.inventory = inventory
319
314
  inventoryItem.domain = this.domain
320
315
 
@@ -2,7 +2,7 @@ import { EntityManager, Equal, getConnection, In, IsNull, Not } from 'typeorm'
2
2
 
3
3
  import { Bizplace } from '@things-factory/biz-base'
4
4
  import { generateId } from '@things-factory/id-rule-base'
5
- import { Product, ProductDetail } from '@things-factory/product-base'
5
+ import { Product, ProductDetail, ProductBarcode } from '@things-factory/product-base'
6
6
  import {
7
7
  GenerateBatchPickInfo,
8
8
  ORDER_INVENTORY_STATUS,
@@ -28,12 +28,14 @@ import {
28
28
  Location,
29
29
  LOCATION_TYPE,
30
30
  Tote,
31
- TOTE_STATUS
31
+ TOTE_STATUS,
32
+ generateInventoryHistory
32
33
  } from '@things-factory/warehouse-base'
34
+ import { logger } from '@things-factory/env'
33
35
 
34
36
  import { TASK_NUMBER_RULE_TYPE, TASK_NUMBER_SETTING_KEY, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
35
37
  import { Worksheet, WorksheetDetail } from '../../entities'
36
- import { generateInventoryHistory, WorksheetNoGenerator } from '../../utils'
38
+ import { WorksheetNoGenerator } from '../../utils'
37
39
  import { VasWorksheetController } from '../vas/vas-worksheet-controller'
38
40
 
39
41
  export class PickingWorksheetController extends VasWorksheetController {
@@ -213,7 +215,7 @@ export class PickingWorksheetController extends VasWorksheetController {
213
215
  if (vasWorksheet) {
214
216
  await this.activateVAS(vasWorksheet.name, vasWorksheet.worksheetDetails)
215
217
  }
216
- } catch (e) { }
218
+ } catch (e) {}
217
219
 
218
220
  const pendingSplitOIs: OrderInventory[] = await this.trxMgr.getRepository(OrderInventory).find({
219
221
  where: { domain: this.domain, releaseGood, status: ORDER_INVENTORY_STATUS.PENDING_SPLIT }
@@ -428,11 +430,8 @@ export class PickingWorksheetController extends VasWorksheetController {
428
430
  .innerJoinAndSelect('oi.inventory', 'inv')
429
431
  .leftJoinAndSelect('oi.orderProduct', 'op')
430
432
  .innerJoinAndSelect('oi.product', 'prd')
431
- .leftJoinAndSelect(
432
- 'prd.productDetails',
433
- 'pd',
434
- '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'
435
- )
433
+ .innerJoinAndSelect('oi.productDetail', 'pd')
434
+ .innerJoinAndSelect('pd.productBarcodes', 'pb')
436
435
  .where('wd.name = :name', { name: worksheetDetailName })
437
436
  .andWhere('wd.domain_id = :domainId', { domainId: this.domain.id })
438
437
  .andWhere('wd.type = :type', { type: worksheetType })
@@ -441,17 +440,35 @@ export class PickingWorksheetController extends VasWorksheetController {
441
440
  .getOne()
442
441
 
443
442
  //validation to check matching worksheet detail based on name
444
- if (!worksheetDetail || !worksheetDetail.targetInventory)
445
- throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
443
+ if (!worksheetDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
444
+
445
+ const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
446
+ let targetInventory: OrderInventory = worksheetDetail.targetInventory
447
+ let targetProduct: OrderProduct = targetInventory.orderProduct
448
+ const product: Product = targetInventory.product
449
+ const matchProductBarcode: ProductBarcode = await this.trxMgr.getRepository(ProductBarcode).findOne({
450
+ where: { gtin: productBarcode },
451
+ relations: ['productDetail']
452
+ })
453
+ const productDetail: ProductDetail = targetInventory.productDetail
454
+ const productBarcodes: [ProductBarcode] = productDetail.productBarcodes
455
+ let inventory: Inventory = targetInventory.inventory
456
+ let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
457
+ let pickedUomValue = pickedQty * productDetail.uomValue
458
+ let matchingProduct
446
459
 
447
460
  //validation to prevent duplicated picking
448
- if (worksheetDetail?.targetInventory?.status != ORDER_INVENTORY_STATUS.PICKING)
461
+ if (targetInventory?.status != ORDER_INVENTORY_STATUS.PICKING)
449
462
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`))
450
463
 
451
- let matchingProduct = await this.getDirectQty(
464
+ if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
465
+ throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
466
+ }
467
+
468
+ matchingProduct = await this.getDirectQty(
452
469
  {
453
- ...worksheetDetail?.targetInventory?.product?.productDetails[0],
454
- product: worksheetDetail?.targetInventory?.product
470
+ ...productDetail,
471
+ product: targetInventory?.product
455
472
  },
456
473
  productBarcode,
457
474
  pickedQty
@@ -461,7 +478,7 @@ export class PickingWorksheetController extends VasWorksheetController {
461
478
  if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
462
479
 
463
480
  pickedQty = matchingProduct.qty
464
- let pickedUomValue = matchingProduct.uomValue
481
+ pickedUomValue = matchingProduct.uomValue
465
482
 
466
483
  //validation to prevent over release
467
484
  if (
@@ -471,15 +488,24 @@ export class PickingWorksheetController extends VasWorksheetController {
471
488
  )
472
489
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
473
490
 
474
- const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
491
+ targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
475
492
 
476
- let targetInventory: OrderInventory = worksheetDetail.targetInventory
477
- let targetProduct: OrderProduct = targetInventory.orderProduct
478
- let inventory: Inventory = targetInventory.inventory
479
- let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
480
- const product: Product = targetInventory.product
493
+ // // search for matching product barcode
494
+ // const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
495
+ // // scannedProductDetail can be child or gtin
496
+ // const scannedProductDetail: ProductDetail = productDetails.find(detail => detail.gtin == productBarcode)
497
+ // if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
481
498
 
482
- targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
499
+ // // case for scanning parent packing type, packing size
500
+ // // when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
501
+ // if (scannedProductDetail.id !== productDetail.id && !product?.isRequireSerialNumberScanningOutbound) {
502
+ // let childQty = await this.getChildQty(productDetails, productBarcode, productDetail, scannedProductDetail)
503
+ // pickedQty *= childQty
504
+ // }
505
+
506
+ // if (pickedQty + targetInventory.pickedQty > releaseQty) {
507
+ // throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
508
+ // }
483
509
 
484
510
  // for required outbound serial number scanning
485
511
  if (product?.isRequireSerialNumberScanningOutbound) {
@@ -527,6 +553,7 @@ export class PickingWorksheetController extends VasWorksheetController {
527
553
  inventoryItem.outboundOrderId = releaseGood.id
528
554
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
529
555
  inventoryItem.product = product
556
+ inventoryItem.productDetail = productDetail
530
557
  inventoryItem.inventory = inventory
531
558
  inventoryItem.domain = this.domain
532
559
 
@@ -692,13 +719,15 @@ export class PickingWorksheetController extends VasWorksheetController {
692
719
  'targetInventory.orderProduct',
693
720
  'targetInventory.inventory',
694
721
  'targetInventory.inventory.location',
695
- 'targetInventory.product'
722
+ 'targetInventory.product',
723
+ 'targetInventory.productDetail'
696
724
  ]
697
725
  )
698
726
 
699
727
  const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
700
728
  let targetInventory: OrderInventory = worksheetDetail.targetInventory
701
729
  const product: Product = targetInventory.product
730
+ const productDetail: ProductDetail = targetInventory.productDetail
702
731
  let inventory: Inventory = targetInventory.inventory
703
732
  let targetProduct: OrderProduct = targetInventory.orderProduct
704
733
  let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
@@ -728,13 +757,13 @@ export class PickingWorksheetController extends VasWorksheetController {
728
757
  })
729
758
 
730
759
  let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
731
- where: { domain: this.domain, serialNumber: serialNumber, product },
732
- relations: ['product', 'inventory']
760
+ where: { domain: this.domain, serialNumber: serialNumber, productDetail },
761
+ relations: ['product', 'productDetail', 'inventory']
733
762
  })
734
763
 
735
764
  let scannedPalletIdInventory: Inventory = await this.trxMgr
736
765
  .getRepository(Inventory)
737
- .findOne({ where: { domain: this.domain, palletId }, relations: ['product'] })
766
+ .findOne({ where: { domain: this.domain, palletId }, relations: ['productDetail'] })
738
767
 
739
768
  if (foundSerialNumber) {
740
769
  if (foundSerialNumber.outboundOrderId) {
@@ -761,6 +790,7 @@ export class PickingWorksheetController extends VasWorksheetController {
761
790
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
762
791
  inventoryItem.outboundOrderId = releaseGood.id
763
792
  inventoryItem.product = product
793
+ inventoryItem.productDetail = productDetail
764
794
  inventoryItem.inventory = scannedPalletIdInventory
765
795
  inventoryItem.domain = this.domain
766
796
 
@@ -786,8 +816,7 @@ export class PickingWorksheetController extends VasWorksheetController {
786
816
  )
787
817
  } else if (
788
818
  scannedPalletIdInventory.batchId == inventory.batchId &&
789
- scannedPalletIdInventory.product.id == product.id &&
790
- scannedPalletIdInventory.product.packingType == product.packingType
819
+ scannedPalletIdInventory.productDetail.id == productDetail.id
791
820
  ) {
792
821
  //if replacement order inventory does not exist
793
822
  await this.serialNumberReplacement(
@@ -795,6 +824,7 @@ export class PickingWorksheetController extends VasWorksheetController {
795
824
  scannedPalletIdInventory,
796
825
  releaseGood,
797
826
  product,
827
+ productDetail,
798
828
  worksheetDetail,
799
829
  foundSerialNumber
800
830
  )
@@ -962,144 +992,144 @@ export class PickingWorksheetController extends VasWorksheetController {
962
992
  binLocationName: string,
963
993
  pickingQty: number
964
994
  ): Promise<void> {
965
- const worksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
966
- where: { domain: this.domain, taskNo, type: worksheetType, status: WORKSHEET_STATUS.EXECUTING },
967
- relations: [
968
- 'worksheetDetails',
969
- 'worksheetDetails.targetInventory',
970
- 'worksheetDetails.targetInventory.releaseGood',
971
- 'worksheetDetails.targetInventory.inventory',
972
- 'worksheetDetails.targetInventory.inventory.location',
973
- 'worksheetDetails.targetInventory.product',
974
- 'worksheetDetails.targetInventory.product.productDetails',
975
- 'worksheetDetails.targetInventory.product.productDetails.childProductDetail'
976
- ]
977
- })
995
+ try {
996
+ console.time(`scanProductBatchPicking:${taskNo}`)
997
+ const worksheet: Worksheet = await this.trxMgr
998
+ .getRepository(Worksheet)
999
+ .createQueryBuilder('worksheet')
1000
+ .innerJoinAndSelect('worksheet.worksheetDetails', 'worksheetDetails')
1001
+ .innerJoinAndSelect('worksheetDetails.targetInventory', 'targetInventory')
1002
+ .innerJoinAndSelect('targetInventory.product', 'product')
1003
+ .leftJoinAndSelect('targetInventory.productDetail', 'productDetail')
1004
+ .leftJoinAndSelect('targetInventory.inventory', 'inventory')
1005
+ .leftJoinAndSelect('inventory.location', 'location')
1006
+ .leftJoinAndSelect('targetInventory.releaseGood', 'releaseGood')
1007
+ .where('worksheet.domain_id = :domainId', { domainId: this.domain.id })
1008
+ .andWhere('worksheet.task_no = :taskNo', { taskNo })
1009
+ .andWhere('worksheet.type = :type', { type: worksheetType })
1010
+ .andWhere('worksheet.status = :status', { status: WORKSHEET_STATUS.EXECUTING })
1011
+ .getOne()
1012
+ const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
1013
+ const productDetail: ProductDetail = worksheetDetails
1014
+ .map(wsd => wsd.targetInventory.productDetail)
1015
+ .find(productDetail => productDetail.id === inventory.productDetail.id)
1016
+
1017
+ const product: Product = productDetail.product
1018
+
1019
+ const batchId: string = inventory.batchId
1020
+ let pickedQty: number = pickingQty ? pickingQty : 1
1021
+ let matchingProduct
1022
+
1023
+ const targetInventories: OrderInventory[] = worksheetDetails
1024
+ .map((wsd: WorksheetDetail) => wsd.targetInventory)
1025
+ .filter(
1026
+ (targetInventory: OrderInventory) =>
1027
+ targetInventory.batchId === batchId &&
1028
+ targetInventory.inventory.cartonId === cartonId &&
1029
+ targetInventory.productDetail.id === productDetail.id
1030
+ )
978
1031
 
979
- const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
980
- const product: Product = worksheetDetails
981
- .map((wsd: WorksheetDetail) => wsd.targetInventory.product)
982
- .find((product: Product) => product.id === inventory.product.id)
983
-
984
- const batchId: string = inventory.batchId
985
- const packingType: string = inventory.packingType
986
- const packingSize: number = inventory.packingSize
987
- let pickedQty: number = pickingQty ? pickingQty : 1
988
-
989
- const targetInventories: OrderInventory[] = worksheetDetails
990
- .map((wsd: WorksheetDetail) => wsd.targetInventory)
991
- .filter(
992
- (targetInventory: OrderInventory) =>
993
- targetInventory.batchId === batchId &&
994
- targetInventory.packingType === packingType &&
995
- targetInventory.inventory.cartonId === cartonId &&
996
- targetInventory.product.id === product.id
1032
+ matchingProduct = await this.getDirectQty(
1033
+ {
1034
+ ...productDetail,
1035
+ product
1036
+ },
1037
+ productBarcode,
1038
+ pickedQty
997
1039
  )
998
1040
 
999
- // search for matching product barcode
1000
- const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
1001
- const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
1002
- if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(`GTIN (${productBarcode})`))
1003
-
1004
- // case for scanning parent packing type, packing size
1005
- const foundProductDetail: ProductDetail = productDetails.find(
1006
- (detail: ProductDetail) =>
1007
- detail.gtin === productBarcode && detail.packingType === packingType && detail.packingSize == packingSize
1008
- )
1009
-
1010
- if (!foundProductDetail) {
1011
- const roProductDetail: ProductDetail = productDetails.find(
1012
- (parentDetail: ProductDetail) =>
1013
- parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
1014
- )
1015
- if (!roProductDetail)
1016
- throw new Error(
1017
- this.ERROR_MSG.FIND.NO_RESULT(`Packing Type ( ${packingType}) or Packing Size (${packingSize})`)
1018
- )
1041
+ //validate matching product details based on scanned barcode
1042
+ if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
1019
1043
 
1020
- let childQty = await this.getChildQty(productDetails, productBarcode, roProductDetail)
1021
- pickedQty *= childQty
1022
- }
1044
+ pickedQty = matchingProduct.qty
1023
1045
 
1024
- const sumOfReleaseQty: number = targetInventories
1025
- .map((oi: OrderInventory) => oi.releaseQty)
1026
- .reduce((a, b) => a + b, 0)
1046
+ const sumOfReleaseQty: number = targetInventories
1047
+ .map((oi: OrderInventory) => oi.releaseQty)
1048
+ .reduce((a, b) => a + b, 0)
1027
1049
 
1028
- const sumOfPickedQty: number =
1029
- targetInventories.map((oi: OrderInventory) => oi.pickedQty).reduce((a, b) => a + b, 0) + pickedQty
1050
+ const sumOfPickedQty: number =
1051
+ targetInventories.map((oi: OrderInventory) => oi.pickedQty).reduce((a, b) => a + b, 0) + pickedQty
1030
1052
 
1031
- if (sumOfPickedQty > sumOfReleaseQty)
1032
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
1053
+ if (sumOfPickedQty > sumOfReleaseQty)
1054
+ throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
1033
1055
 
1034
- for (var i = 0; i < targetInventories.length; i++) {
1035
- let targetInventory: OrderInventory = targetInventories[i]
1036
- let inventory: Inventory = targetInventory.inventory
1037
- const targetReleaseQty: number = targetInventory.releaseQty
1038
- const targetPickedQty: number = targetInventory.pickedQty
1039
- const releaseGood: ReleaseGood = targetInventory.releaseGood
1040
- if (pickedQty <= 0) break
1056
+ for (var i = 0; i < targetInventories.length; i++) {
1057
+ let targetInventory: OrderInventory = targetInventories[i]
1058
+ let inventory: Inventory = targetInventory.inventory
1059
+ const targetReleaseQty: number = targetInventory.releaseQty
1060
+ const targetPickedQty: number = targetInventory.pickedQty
1061
+ const releaseGood: ReleaseGood = targetInventory.releaseGood
1062
+ if (pickedQty <= 0) break
1063
+
1064
+ if (
1065
+ targetInventory.status === ORDER_INVENTORY_STATUS.PICKING &&
1066
+ targetReleaseQty > targetPickedQty &&
1067
+ pickedQty > 0
1068
+ ) {
1069
+ let remainingAssignedQty: number = pickedQty - (targetReleaseQty - targetPickedQty) // -1, 0, 1
1070
+ const gapQtyRemaining: number = targetReleaseQty - targetPickedQty // > 0
1071
+
1072
+ if (binLocationName && !targetInventory?.binLocation) {
1073
+ const binLocation: Location = await this.trxMgr.getRepository(Location).findOne({
1074
+ where: { domain: this.domain, name: binLocationName, type: LOCATION_TYPE.BIN }
1075
+ })
1041
1076
 
1042
- if (
1043
- targetInventory.status === ORDER_INVENTORY_STATUS.PICKING &&
1044
- targetReleaseQty > targetPickedQty &&
1045
- pickedQty > 0
1046
- ) {
1047
- let remainingAssignedQty: number = pickedQty - (targetReleaseQty - targetPickedQty) // -1, 0, 1
1048
- const gapQtyRemaining: number = targetReleaseQty - targetPickedQty // > 0
1049
-
1050
- if (binLocationName && !targetInventory?.binLocation) {
1051
- const binLocation: Location = await this.trxMgr.getRepository(Location).findOne({
1052
- where: { domain: this.domain, name: binLocationName, type: LOCATION_TYPE.BIN }
1053
- })
1077
+ if (!binLocation)
1078
+ throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`))
1054
1079
 
1055
- if (!binLocation)
1056
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`))
1080
+ targetInventory.binLocation = binLocation
1081
+ }
1057
1082
 
1058
- targetInventory.binLocation = binLocation
1059
- }
1083
+ // pickedQty = 1, gap = 5 || pickedQty = 12, gap = 5 || pickedQty = 5, gap = 5
1084
+ targetInventory.pickedQty += pickedQty > gapQtyRemaining ? gapQtyRemaining : pickedQty
1085
+ remainingAssignedQty = remainingAssignedQty < 0 ? 0 : remainingAssignedQty
1060
1086
 
1061
- // pickedQty = 1, gap = 5 || pickedQty = 12, gap = 5 || pickedQty = 5, gap = 5
1062
- targetInventory.pickedQty += pickedQty > gapQtyRemaining ? gapQtyRemaining : pickedQty
1063
- remainingAssignedQty = remainingAssignedQty < 0 ? 0 : remainingAssignedQty
1087
+ if (targetInventory.pickedQty == targetReleaseQty) {
1088
+ const leftQty: number = inventory.qty - targetInventory.releaseQty
1089
+ if (leftQty < 0) {
1090
+ throw new Error(
1091
+ this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`)
1092
+ )
1093
+ }
1064
1094
 
1065
- if (targetInventory.pickedQty == targetReleaseQty) {
1066
- const leftQty: number = inventory.qty - targetInventory.releaseQty
1067
- if (leftQty < 0) {
1068
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
1069
- }
1095
+ targetInventory.status = ORDER_INVENTORY_STATUS.PICKED
1096
+ await this.updateOrderTargets([targetInventory])
1070
1097
 
1071
- targetInventory.status = ORDER_INVENTORY_STATUS.PICKED
1072
- await this.updateOrderTargets([targetInventory])
1098
+ inventory.qty -= targetInventory.releaseQty
1099
+ inventory.uomValue = Math.round((inventory.uomValue - targetInventory.releaseUomValue) * 100) / 100
1100
+ inventory.lockedQty = inventory.lockedQty - targetInventory.releaseQty
1101
+ inventory.lockedUomValue =
1102
+ Math.round((inventory.lockedUomValue - targetInventory.releaseUomValue) * 100) / 100
1103
+ await this.transactionInventory(
1104
+ inventory,
1105
+ releaseGood,
1106
+ -targetInventory.releaseQty,
1107
+ -targetInventory.releaseUomValue,
1108
+ INVENTORY_TRANSACTION_TYPE.PICKING
1109
+ )
1073
1110
 
1074
- inventory.qty -= targetInventory.releaseQty
1075
- inventory.uomValue = Math.round((inventory.uomValue - targetInventory.releaseUomValue) * 100) / 100
1076
- inventory.lockedQty = inventory.lockedQty - targetInventory.releaseQty
1077
- inventory.lockedUomValue =
1078
- Math.round((inventory.lockedUomValue - targetInventory.releaseUomValue) * 100) / 100
1079
- await this.transactionInventory(
1080
- inventory,
1081
- releaseGood,
1082
- -targetInventory.releaseQty,
1083
- -targetInventory.releaseUomValue,
1084
- INVENTORY_TRANSACTION_TYPE.PICKING
1085
- )
1111
+ if (leftQty === 0) {
1112
+ inventory.status = INVENTORY_STATUS.TERMINATED
1113
+ await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
1114
+ }
1086
1115
 
1087
- if (leftQty === 0) {
1088
- inventory.status = INVENTORY_STATUS.TERMINATED
1089
- await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
1116
+ let worksheetDetail: WorksheetDetail = worksheetDetails.find(
1117
+ (wsd: WorksheetDetail) => wsd.targetInventory.id === targetInventory.id
1118
+ )
1119
+ worksheetDetail.status = WORKSHEET_STATUS.DONE
1120
+ worksheetDetail.updater = this.user
1121
+ await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
1122
+ } else {
1123
+ await this.updateOrderTargets([targetInventory])
1090
1124
  }
1091
-
1092
- let worksheetDetail: WorksheetDetail = worksheetDetails.find(
1093
- (wsd: WorksheetDetail) => wsd.targetInventory.id === targetInventory.id
1094
- )
1095
- worksheetDetail.status = WORKSHEET_STATUS.DONE
1096
- worksheetDetail.updater = this.user
1097
- await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
1098
- } else {
1099
- await this.updateOrderTargets([targetInventory])
1125
+ pickedQty = pickedQty - (targetReleaseQty - targetPickedQty)
1100
1126
  }
1101
- pickedQty = pickedQty - (targetReleaseQty - targetPickedQty)
1102
1127
  }
1128
+ } catch (error) {
1129
+ logger.error(`picking-worksheet-controller[scanProductBatchPicking]: ${error}`)
1130
+ throw new Error(error)
1131
+ } finally {
1132
+ console.timeEnd(`scanProductBatchPicking:${taskNo}`)
1103
1133
  }
1104
1134
  }
1105
1135
 
@@ -1404,7 +1434,9 @@ export class PickingWorksheetController extends VasWorksheetController {
1404
1434
  await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.ild)
1405
1435
  await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
1406
1436
  }
1407
- } catch (e) { }
1437
+ } catch (e) {
1438
+ logger.error(`picking-worksheet-controller[serialNumberReplacementForExistingOrderInv]: ${e}`)
1439
+ }
1408
1440
  }
1409
1441
 
1410
1442
  private async serialNumberReplacement(
@@ -1412,6 +1444,7 @@ export class PickingWorksheetController extends VasWorksheetController {
1412
1444
  scannedPalletIdInventory,
1413
1445
  releaseGood,
1414
1446
  product,
1447
+ productDetail,
1415
1448
  worksheetDetail,
1416
1449
  foundSerialNumber
1417
1450
  ) {
@@ -1476,6 +1509,7 @@ export class PickingWorksheetController extends VasWorksheetController {
1476
1509
  releaseUomValue: newOrderInventoryReleaseUomValue,
1477
1510
  pickedQty: 1,
1478
1511
  product,
1512
+ productDetail,
1479
1513
  inventory: scannedPalletIdInventory,
1480
1514
  creator: this.user,
1481
1515
  updater: this.user
@@ -1519,7 +1553,9 @@ export class PickingWorksheetController extends VasWorksheetController {
1519
1553
  await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.id)
1520
1554
  await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
1521
1555
  }
1522
- } catch (e) { }
1556
+ } catch (e) {
1557
+ logger.error(`picking-worksheet-controller[serialNumberReplacement]: ${e}`)
1558
+ }
1523
1559
  }
1524
1560
 
1525
1561
  private async toteScanning(toteNo, targetProduct, targetInventory, pickedQty, releaseGood, bizplace) {