@things-factory/worksheet-base 4.3.753 → 4.3.756

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 (31) hide show
  1. package/dist-server/controllers/outbound/picking-worksheet-controller.js +97 -27
  2. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/outbound/sorting-worksheet-controller.js +117 -24
  4. package/dist-server/controllers/outbound/sorting-worksheet-controller.js.map +1 -1
  5. package/dist-server/controllers/render-ro-do.js +324 -96
  6. package/dist-server/controllers/render-ro-do.js.map +1 -1
  7. package/dist-server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.js +244 -123
  8. package/dist-server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.js.map +1 -1
  9. package/dist-server/graphql/resolvers/worksheet/index.js +1 -1
  10. package/dist-server/graphql/resolvers/worksheet/index.js.map +1 -1
  11. package/dist-server/graphql/resolvers/worksheet/loading/index.js +3 -1
  12. package/dist-server/graphql/resolvers/worksheet/loading/index.js.map +1 -1
  13. package/dist-server/graphql/resolvers/worksheet/loading/validate-qc-seals.js +79 -0
  14. package/dist-server/graphql/resolvers/worksheet/loading/validate-qc-seals.js.map +1 -0
  15. package/dist-server/graphql/types/worksheet/index.js +5 -1
  16. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  17. package/dist-server/graphql/types/worksheet/validate-qc-seals-result.js +12 -0
  18. package/dist-server/graphql/types/worksheet/validate-qc-seals-result.js.map +1 -0
  19. package/dist-server/graphql/types/worksheet/worksheet-info.js +1 -0
  20. package/dist-server/graphql/types/worksheet/worksheet-info.js.map +1 -1
  21. package/package.json +21 -21
  22. package/server/controllers/outbound/picking-worksheet-controller.ts +105 -31
  23. package/server/controllers/outbound/sorting-worksheet-controller.ts +137 -25
  24. package/server/controllers/render-ro-do.ts +378 -136
  25. package/server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.ts +305 -128
  26. package/server/graphql/resolvers/worksheet/index.ts +3 -2
  27. package/server/graphql/resolvers/worksheet/loading/index.ts +5 -0
  28. package/server/graphql/resolvers/worksheet/loading/validate-qc-seals.ts +91 -0
  29. package/server/graphql/types/worksheet/index.ts +5 -1
  30. package/server/graphql/types/worksheet/validate-qc-seals-result.ts +9 -0
  31. package/server/graphql/types/worksheet/worksheet-info.ts +1 -0
@@ -1304,11 +1304,51 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
1304
1304
  }
1305
1305
  }
1306
1306
  async completePicking(releaseGood, worksheet, inventories) {
1307
- const foundNotSealedOrderTote = await this.trxMgr
1308
- .getRepository(sales_base_1.OrderTote)
1309
- .findOne({ where: { releaseGood, closedDate: (0, typeorm_1.IsNull)() } });
1310
- if (foundNotSealedOrderTote) {
1311
- throw new Error('Please seal the tote(s) before completing');
1307
+ var _a;
1308
+ // Check enable-tote-scanning setting
1309
+ let enableToteScanningSetting = await this.trxMgr.getRepository(setting_base_1.Setting).findOne({
1310
+ where: {
1311
+ domain: this.domain,
1312
+ category: 'id-rule',
1313
+ name: 'enable-tote-scanning'
1314
+ }
1315
+ });
1316
+ if (enableToteScanningSetting) {
1317
+ // enable-tote-scanning is numeric: 0 = disabled, >= 1 = enabled
1318
+ const enableToteScanningValue = parseInt(enableToteScanningSetting.value || '0', 10);
1319
+ if (enableToteScanningValue >= 1) {
1320
+ // Check minimum-seal-number setting
1321
+ let minimumSealNumberSetting = await this.trxMgr.getRepository(setting_base_1.Setting).findOne({
1322
+ where: {
1323
+ domain: this.domain,
1324
+ category: 'id-rule',
1325
+ name: 'minimum-seal-number'
1326
+ }
1327
+ });
1328
+ const minimumSealNumber = parseInt((minimumSealNumberSetting === null || minimumSealNumberSetting === void 0 ? void 0 : minimumSealNumberSetting.value) || '0', 10);
1329
+ // Check if there are unsealed totes (closedDate is null)
1330
+ const foundNotSealedOrderTote = await this.trxMgr
1331
+ .getRepository(sales_base_1.OrderTote)
1332
+ .findOne({ where: { releaseGood, closedDate: (0, typeorm_1.IsNull)() } });
1333
+ if (foundNotSealedOrderTote) {
1334
+ throw new Error('Please seal the tote(s) before completing');
1335
+ }
1336
+ // If minimum-seal-number > 0, validate seal counts per tote
1337
+ if (minimumSealNumber > 0) {
1338
+ // Get all order totes for this release good
1339
+ const orderTotes = await this.trxMgr.getRepository(sales_base_1.OrderTote).find({
1340
+ where: { releaseGood },
1341
+ relations: ['orderToteSeals']
1342
+ });
1343
+ // Validate each tote has at least minimum-seal-number seals
1344
+ for (const orderTote of orderTotes) {
1345
+ const sealCount = ((_a = orderTote.orderToteSeals) === null || _a === void 0 ? void 0 : _a.length) || 0;
1346
+ if (sealCount < minimumSealNumber) {
1347
+ throw new Error(`Tote ${orderTote.name} has ${sealCount} seal(s), but minimum ${minimumSealNumber} seal(s) required`);
1348
+ }
1349
+ }
1350
+ }
1351
+ }
1312
1352
  }
1313
1353
  //check if any inventories is obsolete
1314
1354
  if (!releaseGood.recall) {
@@ -1639,28 +1679,28 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
1639
1679
  }
1640
1680
  }
1641
1681
  async toteScanning(toteNo, targetProduct, targetInventory, pickedQty, releaseGood, bizplace) {
1682
+ var _a;
1642
1683
  //1. find tote
1643
- let foundTote = await this.trxMgr
1684
+ const foundTote = await this.trxMgr
1644
1685
  .getRepository(warehouse_base_1.Tote)
1645
1686
  .findOne({ where: { bizplace, name: toteNo, deletedAt: (0, typeorm_1.IsNull)() } });
1646
- if ((foundTote === null || foundTote === void 0 ? void 0 : foundTote.status) == warehouse_base_1.TOTE_STATUS.DAMAGED || (foundTote === null || foundTote === void 0 ? void 0 : foundTote.status) == warehouse_base_1.TOTE_STATUS.DISPATCHED) {
1647
- foundTote = null;
1648
- }
1687
+ const validTote = (foundTote === null || foundTote === void 0 ? void 0 : foundTote.status) !== warehouse_base_1.TOTE_STATUS.DAMAGED && (foundTote === null || foundTote === void 0 ? void 0 : foundTote.status) !== warehouse_base_1.TOTE_STATUS.DISPATCHED
1688
+ ? foundTote
1689
+ : null;
1649
1690
  //2. find order tote
1650
- let foundOrderTote = await this.trxMgr
1691
+ let orderTote = await this.trxMgr
1651
1692
  .getRepository(sales_base_1.OrderTote)
1652
1693
  .findOne({ where: { domain: this.domain, name: toteNo, releaseGood } });
1653
- //if order tote not found the create one, if tote not found means it's tote box
1654
- //create order tote item
1655
- if (!foundOrderTote) {
1656
- const orderTote = await this.trxMgr.getRepository(sales_base_1.OrderTote).save({
1694
+ //if order tote not found then create one, if tote not found means it's tote box
1695
+ if (!orderTote) {
1696
+ orderTote = await this.trxMgr.getRepository(sales_base_1.OrderTote).save({
1657
1697
  name: toteNo,
1658
1698
  domain: this.domain,
1659
1699
  releaseGood,
1660
- tote: foundTote ? foundTote : null,
1700
+ tote: validTote !== null && validTote !== void 0 ? validTote : null,
1661
1701
  updater: this.user
1662
1702
  });
1663
- const orderToteItem = await this.trxMgr.getRepository(sales_base_1.OrderToteItem).save({
1703
+ await this.trxMgr.getRepository(sales_base_1.OrderToteItem).save({
1664
1704
  domain: this.domain,
1665
1705
  name: sales_base_1.OrderNoGenerator.orderToteItem(),
1666
1706
  orderProduct: targetProduct,
@@ -1671,7 +1711,7 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
1671
1711
  });
1672
1712
  }
1673
1713
  else {
1674
- if (foundOrderTote.closedDate) {
1714
+ if (orderTote.closedDate) {
1675
1715
  throw new Error('Tote has been sealed, please try another tote!');
1676
1716
  }
1677
1717
  //if found order tote then check if order tote item exist
@@ -1679,23 +1719,43 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
1679
1719
  domain: this.domain,
1680
1720
  orderProduct: targetProduct,
1681
1721
  orderInventory: targetInventory,
1682
- orderTote: foundOrderTote
1722
+ orderTote
1683
1723
  });
1684
- //if not order tote item doesnt exist then create one
1685
1724
  if (!foundOrderToteItem) {
1686
- const orderToteItem = await this.trxMgr.getRepository(sales_base_1.OrderToteItem).save({
1725
+ await this.trxMgr.getRepository(sales_base_1.OrderToteItem).save({
1687
1726
  domain: this.domain,
1688
1727
  name: sales_base_1.OrderNoGenerator.orderToteItem(),
1689
1728
  orderProduct: targetProduct,
1690
1729
  orderInventory: targetInventory,
1691
- orderTote: foundOrderTote,
1730
+ orderTote,
1692
1731
  qty: pickedQty,
1693
1732
  updater: this.user
1694
1733
  });
1695
1734
  }
1696
1735
  else {
1697
- //if found order tote item found then add the quantity
1698
- const orderToteItem = await this.trxMgr.getRepository(sales_base_1.OrderToteItem).save(Object.assign(Object.assign({}, foundOrderToteItem), { qty: foundOrderToteItem.qty + pickedQty }));
1736
+ await this.trxMgr.getRepository(sales_base_1.OrderToteItem).update(foundOrderToteItem.id, {
1737
+ qty: foundOrderToteItem.qty + pickedQty,
1738
+ updater: this.user,
1739
+ updatedAt: new Date()
1740
+ });
1741
+ }
1742
+ }
1743
+ // Check minimum-seal-number setting - if 0, automatically close the tote
1744
+ if (!orderTote.closedDate) {
1745
+ const sealNoSetting = await this.trxMgr.getRepository(setting_base_1.Setting).findOne({
1746
+ where: {
1747
+ domain: this.domain,
1748
+ name: 'minimum-seal-number'
1749
+ }
1750
+ });
1751
+ const minimumSealRequiredRaw = parseInt((_a = sealNoSetting === null || sealNoSetting === void 0 ? void 0 : sealNoSetting.value) !== null && _a !== void 0 ? _a : '0', 10);
1752
+ const minimumSealRequired = isNaN(minimumSealRequiredRaw) ? 0 : Math.max(0, minimumSealRequiredRaw);
1753
+ if (minimumSealRequired === 0) {
1754
+ await this.trxMgr.getRepository(sales_base_1.OrderTote).update(orderTote.id, {
1755
+ closedDate: new Date(),
1756
+ updater: this.user,
1757
+ updatedAt: new Date()
1758
+ });
1699
1759
  }
1700
1760
  }
1701
1761
  }
@@ -1756,6 +1816,7 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
1756
1816
  await this.updateOrderTargets([targetInventory]);
1757
1817
  }
1758
1818
  async sealTote(sealNo, toteNo, orderNo) {
1819
+ var _a;
1759
1820
  const checkDuplicateSeal = await this.trxMgr.getRepository(sales_base_1.OrderToteSeal).findOne({
1760
1821
  where: {
1761
1822
  name: sealNo
@@ -1787,7 +1848,7 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
1787
1848
  if (!foundOrderTote) {
1788
1849
  throw new Error('Tote not scanned under this order');
1789
1850
  }
1790
- let totalOrderToteItems = await this.trxMgr.getRepository(sales_base_1.OrderToteItem).count({
1851
+ const totalOrderToteItems = await this.trxMgr.getRepository(sales_base_1.OrderToteItem).count({
1791
1852
  where: {
1792
1853
  orderTote: foundOrderTote
1793
1854
  }
@@ -1795,7 +1856,7 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
1795
1856
  if (totalOrderToteItems < 1) {
1796
1857
  throw new Error('Tote carton is empty');
1797
1858
  }
1798
- const newToteOrderSeal = await this.trxMgr.getRepository(sales_base_1.OrderToteSeal).save({
1859
+ await this.trxMgr.getRepository(sales_base_1.OrderToteSeal).save({
1799
1860
  domain: this.domain,
1800
1861
  name: sealNo,
1801
1862
  orderTote: foundOrderTote,
@@ -1804,8 +1865,17 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
1804
1865
  const totalSeal = await this.trxMgr.getRepository(sales_base_1.OrderToteSeal).count({
1805
1866
  orderTote: foundOrderTote
1806
1867
  });
1807
- if (totalSeal >= parseInt((sealNoSetting === null || sealNoSetting === void 0 ? void 0 : sealNoSetting.value) || 0)) {
1808
- await this.trxMgr.getRepository(sales_base_1.OrderTote).save(Object.assign(Object.assign({}, foundOrderTote), { closedDate: new Date() }));
1868
+ // Determine minimum seals required; clamp negative values to 0
1869
+ const minimumSealRequiredRaw = parseInt((_a = sealNoSetting === null || sealNoSetting === void 0 ? void 0 : sealNoSetting.value) !== null && _a !== void 0 ? _a : '0', 10);
1870
+ const minimumSealRequired = isNaN(minimumSealRequiredRaw) ? 0 : Math.max(0, minimumSealRequiredRaw);
1871
+ // Close tote if: seals are optional (0) OR minimum seal count reached
1872
+ const shouldCloseTote = minimumSealRequired === 0 || totalSeal >= minimumSealRequired;
1873
+ if (shouldCloseTote) {
1874
+ await this.trxMgr.getRepository(sales_base_1.OrderTote).update(foundOrderTote.id, {
1875
+ closedDate: new Date(),
1876
+ updater: this.user,
1877
+ updatedAt: new Date()
1878
+ });
1809
1879
  }
1810
1880
  }
1811
1881
  async assignInventoriesForUnassignedOrder(worksheet, tx) {