@things-factory/worksheet-base 4.3.106 → 4.3.108

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