@things-factory/worksheet-base 4.3.108 → 4.3.109

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 (76) hide show
  1. package/dist-server/controllers/inbound/unloading-worksheet-controller.js +73 -58
  2. package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js +6 -7
  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/check-stock-take-current-location.js +39 -43
  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 +2 -1
  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 +1 -2
  30. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.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 +3 -3
  34. package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js.map +1 -1
  35. package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js +2 -3
  36. package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js.map +1 -1
  37. package/dist-server/graphql/resolvers/worksheet/transfer.js +9 -9
  38. package/dist-server/graphql/resolvers/worksheet/transfer.js.map +1 -1
  39. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js +1 -1
  40. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js.map +1 -1
  41. package/dist-server/graphql/resolvers/worksheet/vas-transactions/common-utils.js +17 -17
  42. package/dist-server/graphql/resolvers/worksheet/vas-transactions/common-utils.js.map +1 -1
  43. package/dist-server/graphql/resolvers/worksheet/worksheets.js +1 -1
  44. package/dist-server/graphql/resolvers/worksheet/worksheets.js.map +1 -1
  45. package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js +4 -4
  46. package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js.map +1 -1
  47. package/dist-server/graphql/types/worksheet-detail/index.js +0 -1
  48. package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
  49. package/dist-server/utils/inventory-util.js +98 -1
  50. package/dist-server/utils/inventory-util.js.map +1 -1
  51. package/package.json +17 -17
  52. package/server/controllers/inbound/unloading-worksheet-controller.ts +86 -72
  53. package/server/controllers/inspect/cycle-count-worksheet-controller.ts +6 -7
  54. package/server/controllers/outbound/loading-worksheet-controller.ts +3 -9
  55. package/server/controllers/outbound/packing-worksheet-controller.ts +36 -41
  56. package/server/controllers/outbound/picking-worksheet-controller.ts +66 -98
  57. package/server/controllers/outbound/sorting-worksheet-controller.ts +12 -12
  58. package/server/controllers/vas/vas-worksheet-controller.ts +2 -2
  59. package/server/controllers/worksheet-controller.ts +23 -18
  60. package/server/entities/index.ts +2 -2
  61. package/server/entities/warehouse-bizplace-onhand-inventory.ts +63 -29
  62. package/server/graphql/resolvers/worksheet/batch-picking-worksheet.ts +0 -6
  63. package/server/graphql/resolvers/worksheet/check-stock-take-current-location.ts +50 -52
  64. package/server/graphql/resolvers/worksheet/confirm-cancellation-release-order.ts +2 -1
  65. package/server/graphql/resolvers/worksheet/cycle-count-adjustment.ts +2 -2
  66. package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +1 -3
  67. package/server/graphql/resolvers/worksheet/packing-worksheet.ts +2 -4
  68. package/server/graphql/resolvers/worksheet/picking/complete-batch-picking.ts +3 -3
  69. package/server/graphql/resolvers/worksheet/picking-worksheet.ts +2 -3
  70. package/server/graphql/resolvers/worksheet/transfer.ts +16 -18
  71. package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +1 -1
  72. package/server/graphql/resolvers/worksheet/vas-transactions/common-utils.ts +2 -3
  73. package/server/graphql/resolvers/worksheet/worksheets.ts +1 -1
  74. package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts +1 -4
  75. package/server/graphql/types/worksheet-detail/index.ts +0 -1
  76. package/server/utils/inventory-util.ts +126 -1
@@ -28,13 +28,12 @@ import {
28
28
  Location,
29
29
  LOCATION_TYPE,
30
30
  Tote,
31
- TOTE_STATUS,
32
- generateInventoryHistory
31
+ TOTE_STATUS
33
32
  } from '@things-factory/warehouse-base'
34
33
 
35
34
  import { TASK_NUMBER_RULE_TYPE, TASK_NUMBER_SETTING_KEY, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
36
35
  import { Worksheet, WorksheetDetail } from '../../entities'
37
- import { WorksheetNoGenerator } from '../../utils'
36
+ import { generateInventoryHistory, WorksheetNoGenerator } from '../../utils'
38
37
  import { VasWorksheetController } from '../vas/vas-worksheet-controller'
39
38
 
40
39
  export class PickingWorksheetController extends VasWorksheetController {
@@ -214,7 +213,7 @@ export class PickingWorksheetController extends VasWorksheetController {
214
213
  if (vasWorksheet) {
215
214
  await this.activateVAS(vasWorksheet.name, vasWorksheet.worksheetDetails)
216
215
  }
217
- } catch (e) {}
216
+ } catch (e) { }
218
217
 
219
218
  const pendingSplitOIs: OrderInventory[] = await this.trxMgr.getRepository(OrderInventory).find({
220
219
  where: { domain: this.domain, releaseGood, status: ORDER_INVENTORY_STATUS.PENDING_SPLIT }
@@ -431,7 +430,11 @@ export class PickingWorksheetController extends VasWorksheetController {
431
430
  .innerJoinAndSelect('oi.inventory', 'inv')
432
431
  .leftJoinAndSelect('oi.orderProduct', 'op')
433
432
  .innerJoinAndSelect('oi.product', 'prd')
434
- .innerJoinAndSelect('oi.productDetail', 'pd')
433
+ .leftJoinAndSelect(
434
+ 'prd.productDetails',
435
+ 'pd',
436
+ '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'
437
+ )
435
438
  .where('wd.name = :name', { name: worksheetDetailName })
436
439
  .andWhere('wd.domain_id = :domainId', { domainId: this.domain.id })
437
440
  .andWhere('wd.type = :type', { type: worksheetType })
@@ -440,41 +443,27 @@ export class PickingWorksheetController extends VasWorksheetController {
440
443
  .getOne()
441
444
 
442
445
  //validation to check matching worksheet detail based on name
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 productDetail: ProductDetail = targetInventory.productDetail
450
- let inventory: Inventory = targetInventory.inventory
451
- let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
452
- let pickedUomValue = pickedQty * productDetail.uomValue
453
- let matchingProduct
446
+ if (!worksheetDetail || !worksheetDetail.targetInventory)
447
+ throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
454
448
 
455
449
  //validation to prevent duplicated picking
456
- if (targetInventory?.status != ORDER_INVENTORY_STATUS.PICKING)
450
+ if (worksheetDetail?.targetInventory?.status != ORDER_INVENTORY_STATUS.PICKING)
457
451
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`))
458
452
 
459
- if (productBarcode !== productDetail.gtin) {
460
- if (product?.isRequireSerialNumberScanningOutbound)
461
- throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
462
-
463
- matchingProduct = await this.getDirectQty(
464
- {
465
- ...productDetail,
466
- product: targetInventory?.product
467
- },
468
- productBarcode,
469
- pickedQty
470
- )
453
+ let matchingProduct = await this.getDirectQty(
454
+ {
455
+ ...worksheetDetail?.targetInventory?.product?.productDetails[0],
456
+ product: worksheetDetail?.targetInventory?.product
457
+ },
458
+ productBarcode,
459
+ pickedQty
460
+ )
471
461
 
472
- //validate matching product details based on scanned barcode
473
- if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
462
+ //validate matching product details based on scanned barcode
463
+ if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
474
464
 
475
- pickedQty = matchingProduct.qty
476
- pickedUomValue = matchingProduct.uomValue
477
- }
465
+ pickedQty = matchingProduct.qty
466
+ let pickedUomValue = matchingProduct.uomValue
478
467
 
479
468
  //validation to prevent over release
480
469
  if (
@@ -484,24 +473,15 @@ export class PickingWorksheetController extends VasWorksheetController {
484
473
  )
485
474
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
486
475
 
487
- targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
488
-
489
- // // search for matching product barcode
490
- // const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
491
- // // scannedProductDetail can be child or gtin
492
- // const scannedProductDetail: ProductDetail = productDetails.find(detail => detail.gtin == productBarcode)
493
- // if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
476
+ const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
494
477
 
495
- // // case for scanning parent packing type, packing size
496
- // // when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
497
- // if (scannedProductDetail.id !== productDetail.id && !product?.isRequireSerialNumberScanningOutbound) {
498
- // let childQty = await this.getChildQty(productDetails, productBarcode, productDetail, scannedProductDetail)
499
- // pickedQty *= childQty
500
- // }
478
+ let targetInventory: OrderInventory = worksheetDetail.targetInventory
479
+ let targetProduct: OrderProduct = targetInventory.orderProduct
480
+ let inventory: Inventory = targetInventory.inventory
481
+ let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
482
+ const product: Product = targetInventory.product
501
483
 
502
- // if (pickedQty + targetInventory.pickedQty > releaseQty) {
503
- // throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
504
- // }
484
+ targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
505
485
 
506
486
  // for required outbound serial number scanning
507
487
  if (product?.isRequireSerialNumberScanningOutbound) {
@@ -549,7 +529,6 @@ export class PickingWorksheetController extends VasWorksheetController {
549
529
  inventoryItem.outboundOrderId = releaseGood.id
550
530
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
551
531
  inventoryItem.product = product
552
- inventoryItem.productDetail = productDetail
553
532
  inventoryItem.inventory = inventory
554
533
  inventoryItem.domain = this.domain
555
534
 
@@ -715,15 +694,13 @@ export class PickingWorksheetController extends VasWorksheetController {
715
694
  'targetInventory.orderProduct',
716
695
  'targetInventory.inventory',
717
696
  'targetInventory.inventory.location',
718
- 'targetInventory.product',
719
- 'targetInventory.productDetail'
697
+ 'targetInventory.product'
720
698
  ]
721
699
  )
722
700
 
723
701
  const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
724
702
  let targetInventory: OrderInventory = worksheetDetail.targetInventory
725
703
  const product: Product = targetInventory.product
726
- const productDetail: ProductDetail = targetInventory.productDetail
727
704
  let inventory: Inventory = targetInventory.inventory
728
705
  let targetProduct: OrderProduct = targetInventory.orderProduct
729
706
  let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
@@ -753,13 +730,13 @@ export class PickingWorksheetController extends VasWorksheetController {
753
730
  })
754
731
 
755
732
  let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
756
- where: { domain: this.domain, serialNumber: serialNumber, productDetail },
757
- relations: ['product', 'productDetail', 'inventory']
733
+ where: { domain: this.domain, serialNumber: serialNumber, product },
734
+ relations: ['product', 'inventory']
758
735
  })
759
736
 
760
737
  let scannedPalletIdInventory: Inventory = await this.trxMgr
761
738
  .getRepository(Inventory)
762
- .findOne({ where: { domain: this.domain, palletId }, relations: ['productDetail'] })
739
+ .findOne({ where: { domain: this.domain, palletId }, relations: ['product'] })
763
740
 
764
741
  if (foundSerialNumber) {
765
742
  if (foundSerialNumber.outboundOrderId) {
@@ -786,7 +763,6 @@ export class PickingWorksheetController extends VasWorksheetController {
786
763
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
787
764
  inventoryItem.outboundOrderId = releaseGood.id
788
765
  inventoryItem.product = product
789
- inventoryItem.productDetail = productDetail
790
766
  inventoryItem.inventory = scannedPalletIdInventory
791
767
  inventoryItem.domain = this.domain
792
768
 
@@ -812,7 +788,8 @@ export class PickingWorksheetController extends VasWorksheetController {
812
788
  )
813
789
  } else if (
814
790
  scannedPalletIdInventory.batchId == inventory.batchId &&
815
- scannedPalletIdInventory.productDetail.id == productDetail.id
791
+ scannedPalletIdInventory.product.id == product.id &&
792
+ scannedPalletIdInventory.product.packingType == product.packingType
816
793
  ) {
817
794
  //if replacement order inventory does not exist
818
795
  await this.serialNumberReplacement(
@@ -820,7 +797,6 @@ export class PickingWorksheetController extends VasWorksheetController {
820
797
  scannedPalletIdInventory,
821
798
  releaseGood,
822
799
  product,
823
- productDetail,
824
800
  worksheetDetail,
825
801
  foundSerialNumber
826
802
  )
@@ -996,8 +972,6 @@ export class PickingWorksheetController extends VasWorksheetController {
996
972
  'worksheetDetails.targetInventory.releaseGood',
997
973
  'worksheetDetails.targetInventory.inventory',
998
974
  'worksheetDetails.targetInventory.inventory.location',
999
- 'worksheetDetails.targetInventory.productDetail',
1000
- 'worksheetDetails.targetInventory.productDetail.product',
1001
975
  'worksheetDetails.targetInventory.product',
1002
976
  'worksheetDetails.targetInventory.product.productDetails',
1003
977
  'worksheetDetails.targetInventory.product.productDetails.childProductDetail'
@@ -1005,53 +979,49 @@ export class PickingWorksheetController extends VasWorksheetController {
1005
979
  })
1006
980
 
1007
981
  const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
1008
- const productDetail: ProductDetail = worksheetDetails
1009
- .map(wsd => wsd.targetInventory.productDetail)
1010
- .find(productDetail => productDetail.id === inventory.productDetail.id)
1011
-
1012
- const product: Product = productDetail.product
982
+ const product: Product = worksheetDetails
983
+ .map((wsd: WorksheetDetail) => wsd.targetInventory.product)
984
+ .find((product: Product) => product.id === inventory.product.id)
1013
985
 
1014
986
  const batchId: string = inventory.batchId
987
+ const packingType: string = inventory.packingType
988
+ const packingSize: number = inventory.packingSize
1015
989
  let pickedQty: number = pickingQty ? pickingQty : 1
1016
- let matchingProduct
1017
990
 
1018
991
  const targetInventories: OrderInventory[] = worksheetDetails
1019
992
  .map((wsd: WorksheetDetail) => wsd.targetInventory)
1020
993
  .filter(
1021
994
  (targetInventory: OrderInventory) =>
1022
995
  targetInventory.batchId === batchId &&
996
+ targetInventory.packingType === packingType &&
1023
997
  targetInventory.inventory.cartonId === cartonId &&
1024
- targetInventory.productDetail.id === productDetail.id
1025
- )
1026
-
1027
- if (productBarcode !== productDetail.gtin) {
1028
- matchingProduct = await this.getDirectQty(
1029
- {
1030
- ...productDetail,
1031
- product
1032
- },
1033
- productBarcode,
1034
- pickedQty
998
+ targetInventory.product.id === product.id
1035
999
  )
1036
1000
 
1037
- //validate matching product details based on scanned barcode
1038
- if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
1001
+ // search for matching product barcode
1002
+ const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
1003
+ const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
1004
+ if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(`GTIN (${productBarcode})`))
1039
1005
 
1040
- pickedQty = matchingProduct.qty
1041
- }
1006
+ // case for scanning parent packing type, packing size
1007
+ const foundProductDetail: ProductDetail = productDetails.find(
1008
+ (detail: ProductDetail) =>
1009
+ detail.gtin === productBarcode && detail.packingType === packingType && detail.packingSize == packingSize
1010
+ )
1042
1011
 
1043
- // // search for matching product barcode
1044
- // const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
1045
- // // scannedProductDetail can be child or gtin
1046
- // const scannedProductDetail: ProductDetail = productDetails.find(detail => detail.gtin == productBarcode)
1047
- // if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
1012
+ if (!foundProductDetail) {
1013
+ const roProductDetail: ProductDetail = productDetails.find(
1014
+ (parentDetail: ProductDetail) =>
1015
+ parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
1016
+ )
1017
+ if (!roProductDetail)
1018
+ throw new Error(
1019
+ this.ERROR_MSG.FIND.NO_RESULT(`Packing Type ( ${packingType}) or Packing Size (${packingSize})`)
1020
+ )
1048
1021
 
1049
- // // case for scanning parent packing type, packing size
1050
- // // when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
1051
- // if (scannedProductDetail.id !== productDetail.id) {
1052
- // let childQty = await this.getChildQty(productDetails, productBarcode, productDetail, scannedProductDetail)
1053
- // pickedQty *= childQty
1054
- // }
1022
+ let childQty = await this.getChildQty(productDetails, productBarcode, roProductDetail)
1023
+ pickedQty *= childQty
1024
+ }
1055
1025
 
1056
1026
  const sumOfReleaseQty: number = targetInventories
1057
1027
  .map((oi: OrderInventory) => oi.releaseQty)
@@ -1436,7 +1406,7 @@ export class PickingWorksheetController extends VasWorksheetController {
1436
1406
  await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.ild)
1437
1407
  await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
1438
1408
  }
1439
- } catch (e) {}
1409
+ } catch (e) { }
1440
1410
  }
1441
1411
 
1442
1412
  private async serialNumberReplacement(
@@ -1444,7 +1414,6 @@ export class PickingWorksheetController extends VasWorksheetController {
1444
1414
  scannedPalletIdInventory,
1445
1415
  releaseGood,
1446
1416
  product,
1447
- productDetail,
1448
1417
  worksheetDetail,
1449
1418
  foundSerialNumber
1450
1419
  ) {
@@ -1509,7 +1478,6 @@ export class PickingWorksheetController extends VasWorksheetController {
1509
1478
  releaseUomValue: newOrderInventoryReleaseUomValue,
1510
1479
  pickedQty: 1,
1511
1480
  product,
1512
- productDetail,
1513
1481
  inventory: scannedPalletIdInventory,
1514
1482
  creator: this.user,
1515
1483
  updater: this.user
@@ -1553,7 +1521,7 @@ export class PickingWorksheetController extends VasWorksheetController {
1553
1521
  await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.id)
1554
1522
  await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
1555
1523
  }
1556
- } catch (e) {}
1524
+ } catch (e) { }
1557
1525
  }
1558
1526
 
1559
1527
  private async toteScanning(toteNo, targetProduct, targetInventory, pickedQty, releaseGood, bizplace) {
@@ -95,8 +95,7 @@ export class SortingWorksheetController extends VasWorksheetController {
95
95
  'worksheetDetails.targetInventory.inventory.product',
96
96
  'worksheetDetails.targetInventory.inventory.product.productDetails',
97
97
  'worksheetDetails.targetInventory.inventory.product.productDetails.product',
98
- 'worksheetDetails.targetInventory.releaseGood',
99
- 'worksheetDetails.targetInventory.productDetail'
98
+ 'worksheetDetails.targetInventory.releaseGood'
100
99
  ]
101
100
  })
102
101
 
@@ -119,12 +118,17 @@ export class SortingWorksheetController extends VasWorksheetController {
119
118
  const matchingProductDetail: ProductDetail = productDetails.find(
120
119
  (productDetail: ProductDetail) => productDetail.gtin === productBarcode
121
120
  )
122
- if (!matchingProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
121
+ if (!matchingProductDetail) throw new Error('Unable to find product barcode.')
123
122
  const packingType: string = matchingProductDetail.packingType
124
123
  const packingSize: number = matchingProductDetail.packingSize
124
+ if (!matchingProductDetail)
125
+ throw new Error(this.ERROR_MSG.PRODUCT.BARCODE_NOT_EXIST(productBarcode, packingType, packingSize))
125
126
 
126
127
  let matchingOIs: OrderInventory[] = orderInventories.filter(
127
- (oi: OrderInventory) => oi.productDetail.id === matchingProductDetail.id
128
+ (oi: OrderInventory) =>
129
+ oi.packingType === packingType &&
130
+ oi.packingSize === packingSize &&
131
+ oi.product?.id === matchingProductDetail.product?.id
128
132
  )
129
133
 
130
134
  let sortedQty: number = 1
@@ -138,7 +142,6 @@ export class SortingWorksheetController extends VasWorksheetController {
138
142
  const inventory: Inventory = matchingOI.inventory
139
143
  const releaseGood: ReleaseGood = matchingOI.releaseGood
140
144
  const product: Product = inventory.product
141
- const productDetail: ProductDetail = matchingOI.productDetail
142
145
 
143
146
  if (releaseQty != matchingOI?.sortedQty && sortedQty == 1) {
144
147
  // Serial Number scanning for batch picking
@@ -150,7 +153,7 @@ export class SortingWorksheetController extends VasWorksheetController {
150
153
 
151
154
  let foundSerialNumber: InventoryItem = await this.trxMgr
152
155
  .getRepository(InventoryItem)
153
- .findOne({ where: { domain: this.domain, serialNumber: serialNumber, productDetail } })
156
+ .findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
154
157
 
155
158
  if (foundSerialNumber) {
156
159
  if (foundSerialNumber.inventoryId !== inventory.id) {
@@ -177,7 +180,6 @@ export class SortingWorksheetController extends VasWorksheetController {
177
180
  inventoryItem.outboundOrderId = releaseGood.id
178
181
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
179
182
  inventoryItem.product = product
180
- inventoryItem.productDetail = productDetail
181
183
  inventoryItem.inventory = inventory
182
184
  inventoryItem.domain = this.domain
183
185
 
@@ -261,8 +263,7 @@ export class SortingWorksheetController extends VasWorksheetController {
261
263
  'worksheetDetails.targetInventory.inventory.product',
262
264
  'worksheetDetails.targetInventory.inventory.product.productDetails',
263
265
  'worksheetDetails.targetInventory.inventory.product.productDetails.product',
264
- 'worksheetDetails.targetInventory.releaseGood',
265
- 'worksheetDetails.targetInventory.productDetail'
266
+ 'worksheetDetails.targetInventory.releaseGood'
266
267
  ]
267
268
  })
268
269
 
@@ -282,7 +283,6 @@ export class SortingWorksheetController extends VasWorksheetController {
282
283
  const inventory: Inventory = matchingOI.inventory
283
284
  const releaseGood: ReleaseGood = matchingOI.releaseGood
284
285
  const product: Product = matchingOI.inventory.product
285
- const productDetail: ProductDetail = matchingOI.productDetail
286
286
  const packingType: string = matchingOI.packingType
287
287
  const packingSize: number = matchingOI.packingSize
288
288
 
@@ -292,7 +292,8 @@ export class SortingWorksheetController extends VasWorksheetController {
292
292
  }
293
293
 
294
294
  let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
295
- where: { domain: this.domain, serialNumber: serialNumber, productDetail }
295
+ where: { domain: this.domain, serialNumber: serialNumber, product },
296
+ relations: ['product', 'inventory']
296
297
  })
297
298
 
298
299
  if (foundSerialNumber) {
@@ -316,7 +317,6 @@ export class SortingWorksheetController extends VasWorksheetController {
316
317
  inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
317
318
  inventoryItem.outboundOrderId = releaseGood.id
318
319
  inventoryItem.product = product
319
- inventoryItem.productDetail = productDetail
320
320
  inventoryItem.inventory = inventory
321
321
  inventoryItem.domain = this.domain
322
322
 
@@ -22,8 +22,7 @@ import {
22
22
  InventoryNoGenerator,
23
23
  Location,
24
24
  LOCATION_TYPE,
25
- Warehouse,
26
- generateInventoryHistory
25
+ Warehouse
27
26
  } from '@things-factory/warehouse-base'
28
27
 
29
28
  import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
@@ -37,6 +36,7 @@ import {
37
36
  RefOrderType
38
37
  } from '../../graphql/resolvers/worksheet/vas-transactions'
39
38
  import { PackingUnits } from '../../graphql/resolvers/worksheet/vas-transactions/interfaces/repackaging'
39
+ import { generateInventoryHistory } from '../../utils'
40
40
  import { ReferenceOrderType, WorksheetController } from '../worksheet-controller'
41
41
 
42
42
  type CompleteTransactionType = (trxMgr: EntityManager, orderVas: OrderVas, user: User) => Promise<void>
@@ -19,17 +19,11 @@ import {
19
19
  VasOrder
20
20
  } from '@things-factory/sales-base'
21
21
  import { Domain } from '@things-factory/shell'
22
- import {
23
- Inventory,
24
- INVENTORY_STATUS,
25
- InventoryItem,
26
- Pallet,
27
- generateInventoryHistory
28
- } from '@things-factory/warehouse-base'
22
+ import { Inventory, INVENTORY_STATUS, InventoryItem, Pallet } from '@things-factory/warehouse-base'
29
23
 
30
24
  import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../constants'
31
25
  import { Worksheet, WorksheetDetail } from '../entities'
32
- import { WorksheetNoGenerator } from '../utils'
26
+ import { generateInventoryHistory, WorksheetNoGenerator } from '../utils'
33
27
 
34
28
  export type ReferenceOrderType = ArrivalNotice | ReleaseGood | VasOrder | InventoryCheck | DeliveryOrder | ReturnOrder
35
29
  export type OrderTargetTypes = OrderProduct | OrderInventory | OrderVas
@@ -399,7 +393,7 @@ export class WorksheetController {
399
393
  let existingWorksheet: Worksheet
400
394
  try {
401
395
  existingWorksheet = await this.findWorksheetByRefOrder(refOrder, type)
402
- } catch (e) {}
396
+ } catch (e) { }
403
397
 
404
398
  if (existingWorksheet)
405
399
  throw new Error(
@@ -518,6 +512,7 @@ export class WorksheetController {
518
512
  if (!refOrder.updater?.id) refOrder = this.setStamp(refOrder)
519
513
 
520
514
  if (currentStatus && entitySchema == ReleaseGood) {
515
+
521
516
  let res = await getRepository(entitySchema).query(
522
517
  `
523
518
  update release_goods
@@ -1012,9 +1007,11 @@ export class WorksheetController {
1012
1007
  async getChildQty(
1013
1008
  productDetails: ProductDetail[],
1014
1009
  productBarcode: string,
1015
- orderProductDetail: ProductDetail,
1016
- scannedProductDetail: ProductDetail
1010
+ orderProductDetail: ProductDetail
1017
1011
  ): Promise<number> {
1012
+ const scannedProductDetail: ProductDetail = productDetails.find(
1013
+ (productDetail: ProductDetail) => productDetail.gtin === productBarcode
1014
+ )
1018
1015
  let hasChildRelation: boolean = Boolean(scannedProductDetail?.childProductDetail)
1019
1016
  let hasMatchingChild: boolean
1020
1017
  let childQty: number
@@ -1057,11 +1054,14 @@ export class WorksheetController {
1057
1054
  return childQty
1058
1055
  }
1059
1056
 
1060
- public async getDirectQty(productDetail: ProductDetail, productBarcode: string, qty: number): Promise<any> {
1057
+ public async getDirectQty(
1058
+ productDetail: ProductDetail,
1059
+ productBarcode: string,
1060
+ qty: number
1061
+ ): Promise<any> {
1061
1062
  try {
1062
1063
  console.time('getDirectQty')
1063
- let results = await this.trxMgr.query(
1064
- `
1064
+ let results = await this.trxMgr.query(`
1065
1065
  WITH RECURSIVE cte as (
1066
1066
  select * from (
1067
1067
  select pd.product_id as "productId", id, pd.packing_size as "packingSize",
@@ -1078,11 +1078,14 @@ export class WorksheetController {
1078
1078
  where pd.deleted_at is null
1079
1079
  )
1080
1080
  select * from cte where gtin = $3
1081
- `,
1082
- [productDetail.id, qty, productBarcode]
1083
- )
1081
+ `, [
1082
+ productDetail.id,
1083
+ qty,
1084
+ productBarcode
1085
+ ])
1084
1086
 
1085
- if (results.length <= 0) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
1087
+ if (results.length <= 0)
1088
+ throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
1086
1089
 
1087
1090
  console.timeEnd('getDirectQty')
1088
1091
  return results[0]
@@ -1091,6 +1094,8 @@ export class WorksheetController {
1091
1094
  }
1092
1095
  }
1093
1096
 
1097
+
1098
+
1094
1099
  /**
1095
1100
  * @summary Check for product child qty at any scanned level
1096
1101
  * @description It will check every level of product detail by comparing scanned level and GAN registered level.
@@ -1,8 +1,8 @@
1
- import { WarehouseBizplaceOnhandInventory } from './warehouse-bizplace-onhand-inventory'
2
1
  import { Worksheet } from './worksheet'
3
2
  import { WorksheetDetail } from './worksheet-detail'
4
3
  import { WorksheetMovement } from './worksheet-movement'
4
+ import { WarehouseBizplaceOnhandInventory } from './warehouse-bizplace-onhand-inventory'
5
5
 
6
6
  export const entities = [Worksheet, WorksheetDetail, WorksheetMovement, WarehouseBizplaceOnhandInventory]
7
7
 
8
- export { WarehouseBizplaceOnhandInventory, Worksheet, WorksheetDetail, WorksheetMovement }
8
+ export { Worksheet, WorksheetDetail, WorksheetMovement }
@@ -2,23 +2,55 @@ import { ViewColumn, ViewEntity } from 'typeorm'
2
2
 
3
3
  @ViewEntity({
4
4
  expression: `
5
- select d.name as "domain_name", b.name as "bizplace_name", src.* from (
5
+ select d.name as "domainName", b.name as "bizplaceName", src.* from (
6
+ WITH oi as (
7
+ select
8
+ oi.domain_id,
9
+ oi.bizplace_id,
10
+ SUM(oi.release_qty) AS release_qty,
11
+ SUM(oi.release_uom_value) AS release_uom_value,
12
+ oi.batch_id,
13
+ oi.batch_id_ref,
14
+ oi.product_id,
15
+ oi.packing_type,
16
+ oi.packing_size,
17
+ oi.uom
18
+ FROM
19
+ order_inventories oi
20
+ WHERE
21
+ (oi.status = 'PENDING' or oi.status = 'PENDING_RECEIVE' or oi.status = 'PENDING_WORKSHEET' or oi.status = 'PENDING_SPLIT')
22
+ AND oi.batch_id NOTNULL
23
+ AND oi.product_id NOTNULL
24
+ AND oi.packing_type NOTNULL
25
+ AND oi.packing_size NOTNULL
26
+ AND oi.inventory_id IS NULL
27
+ GROUP BY
28
+ oi.domain_id,
29
+ oi.bizplace_id,
30
+ oi.batch_id,
31
+ oi.batch_id_ref,
32
+ oi.product_id,
33
+ oi.packing_type,
34
+ oi.packing_size,
35
+ oi.uom
36
+ )
6
37
  -- SINGLE ITEM INVENTORY QUERY
7
38
  select
8
- i.domain_id as "domain_id",
9
- i.bizplace_id as "bizplace_id",
10
- i.packing_type as "packing_type",
11
- i.packing_size as "packing_size",
39
+ i.domain_id as "domainId",
40
+ i.bizplace_id as "bizplaceId",
41
+ i.packing_type as "packingType",
42
+ i.packing_size as "packingSize",
12
43
  i.uom,
13
- i.product_id as "product_id",
14
- null as "product_bundle_id",
15
- COALESCE(SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0))) AS "remain_qty",
16
- COALESCE(SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0))) AS "remain_uom_value",
44
+ i.product_id as "productId",
45
+ null as "productBundleId",
46
+ COALESCE(SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0))) AS "remainQty",
47
+ COALESCE(SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0)), 0) AS "remainUomValue",
17
48
  COALESCE(sum(COALESCE(i.qty, 0::double precision))) AS "qty",
18
- COALESCE(sum(COALESCE(i.uom_value, 0::double precision))) AS "uom_value",
19
- 'SINGLE' AS "group_type"
49
+ COALESCE(sum(COALESCE(i.uom_value, 0::double precision))) AS "uomValue",
50
+ 'SINGLE' AS "groupType"
20
51
  FROM inventories i
21
52
  INNER JOIN locations l2 ON i.location_id = l2.id AND i.domain_id = l2.domain_id AND l2.type NOT IN ('QUARANTINE', 'RESERVE')
53
+ LEFT JOIN oi ON i.batch_id = oi.batch_id AND i.product_id = oi.product_id AND i.packing_type = oi.packing_type AND i.packing_size = oi.packing_size AND i.uom = oi.uom
22
54
  WHERE i.status = 'STORED'
23
55
  GROUP by
24
56
  i.domain_id,
@@ -30,28 +62,29 @@ import { ViewColumn, ViewEntity } from 'typeorm'
30
62
  union all
31
63
  -- BUNDLE ITEM INVENTORY QUERY
32
64
  SELECT
33
- pbs.domain_id as "domain_id",
34
- pbs.bizplace_id as "bizplace_id",
35
- pb.packing_type as "packing_type",
36
- pb.packing_size as "packing_size",
65
+ pbs.domain_id as "domainId",
66
+ pbs.bizplace_id as "bizplaceId",
67
+ pb.packing_type as "packingType",
68
+ pb.packing_size as "packingSize",
37
69
  'UNIT' AS "uom",
38
- null as "product_id",
39
- pb.id AS "product_bundle_id",
40
- COALESCE(MIN(FLOOR(pbs."available_qty")),0) AS "remain_qty",
41
- COALESCE(MIN(FLOOR(pbs."available_uom_value")),0) AS "remain_uom_value",
70
+ null as "productId",
71
+ pb.id AS "productBundleId",
72
+ COALESCE(MIN(FLOOR(pbs."availableQty")),0) AS "remainQty",
73
+ COALESCE(MIN(FLOOR(pbs."availableUomValue")),0) AS "remainUomValue",
42
74
  COALESCE(MIN(FLOOR(pbs."qty")), 0::double precision) AS "qty",
43
- COALESCE(MIN(FLOOR(pbs."uom_value")), 0::double precision) AS "uom_value",
44
- 'BUNDLE' AS "group_type"
75
+ COALESCE(MIN(FLOOR(pbs."uomValue")), 0::double precision) AS "uomValue",
76
+ 'BUNDLE' AS "groupType"
45
77
  FROM product_bundles pb
46
78
  INNER JOIN (
47
79
  SELECT i.domain_id, i.bizplace_id, pbs.product_id, pbs.product_bundle_id, min(pbs.bundle_qty),
48
- (SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0))) / min(pbs.bundle_qty) AS "available_qty",
49
- (SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0))) / min(pbs.bundle_qty) AS "available_uom_value",
80
+ (SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0)) - MAX(COALESCE(oi.release_qty, 0))) / min(pbs.bundle_qty) AS "availableQty",
81
+ (SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(oi.release_uom_value, 0))) / min(pbs.bundle_qty) AS "availableUomValue",
50
82
  (sum(COALESCE(i.qty, 0::double precision))) / min(pbs.bundle_qty)::double precision AS "qty",
51
- (sum(COALESCE(i.uom_value, 0::double precision))) / min(pbs.bundle_qty)::double precision AS "uom_value"
83
+ (sum(COALESCE(i.uom_value, 0::double precision))) / min(pbs.bundle_qty)::double precision AS "uomValue"
52
84
  FROM product_bundle_settings pbs
53
85
  LEFT JOIN inventories i ON i.product_id = pbs.product_id AND i.status = 'STORED'
54
- INNER JOIN locations l ON i.location_id = l.id AND i.domain_id = l.domain_id AND l.type NOT IN ('QUARANTINE', 'RESERVE')
86
+ INNER JOIN locations l ON i.location_id = l.id AND i.domain_id = l.domain_id AND l.type NOT IN ('QUARANTINE', 'RESERVE')
87
+ LEFT JOIN oi ON oi.product_id = i.product_id
55
88
  GROUP by
56
89
  i.domain_id,
57
90
  i.bizplace_id,
@@ -68,13 +101,14 @@ import { ViewColumn, ViewEntity } from 'typeorm'
68
101
  pb.id
69
102
  )
70
103
  AS src
71
- inner join domains d on d.id = src."domain_id"
72
- inner join bizplaces b on b.id = src."bizplace_id"
73
- where src."remain_qty" >= 0
104
+ inner join domains d on d.id = src."domainId"
105
+ inner join bizplaces b on b.id = src."bizplaceId"
106
+ where src."remainQty" >= 0
74
107
  and src."qty" > 0
75
- order by src."domain_id"
108
+ order by src."domainId"
76
109
  `
77
110
  })
111
+
78
112
  export class WarehouseBizplaceOnhandInventory {
79
113
  @ViewColumn()
80
114
  domainName: string