@things-factory/worksheet-base 4.3.753 → 4.3.755

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 +35 -1
  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 +49 -3
  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
@@ -9,6 +9,7 @@ import {
9
9
  OrderNoGenerator,
10
10
  OrderTote,
11
11
  OrderToteItem,
12
+ OrderToteSeal,
12
13
  ReleaseGood
13
14
  } from '@things-factory/sales-base'
14
15
  import { Setting } from '@things-factory/setting-base'
@@ -250,7 +251,7 @@ export class SortingWorksheetController extends VasWorksheetController {
250
251
  } else {
251
252
  sortedQty = matchingProduct.qty
252
253
  }
253
-
254
+
254
255
  const releaseGood: ReleaseGood =
255
256
  orderInventories.length > 1
256
257
  ? orderInventories.find(item => item.productId === scanProductBarcode.productId)?.releaseGood
@@ -535,12 +536,59 @@ export class SortingWorksheetController extends VasWorksheetController {
535
536
  throw new Error('Order is already sorted')
536
537
  }
537
538
 
538
- const foundNotSealedOrderTote = await this.trxMgr
539
- .getRepository(OrderTote)
540
- .findOne({ where: { releaseGood, closedDate: IsNull() } })
539
+ // Check enable-tote-scanning setting
540
+ let enableToteScanningSetting: Setting = await this.trxMgr.getRepository(Setting).findOne({
541
+ where: {
542
+ domain: this.domain,
543
+ category: 'id-rule',
544
+ name: 'enable-tote-scanning'
545
+ }
546
+ })
547
+
548
+ if (enableToteScanningSetting) {
549
+ // enable-tote-scanning is numeric: 0 = disabled, >= 1 = enabled
550
+ const enableToteScanningValue = parseInt(enableToteScanningSetting.value || '0', 10)
551
+
552
+ if (enableToteScanningValue >= 1) {
553
+ // Check minimum-seal-number setting
554
+ let minimumSealNumberSetting: Setting = await this.trxMgr.getRepository(Setting).findOne({
555
+ where: {
556
+ domain: this.domain,
557
+ category: 'id-rule',
558
+ name: 'minimum-seal-number'
559
+ }
560
+ })
541
561
 
542
- if (foundNotSealedOrderTote) {
543
- throw new Error('Please seal the tote(s) before proceeding')
562
+ const minimumSealNumber = parseInt(minimumSealNumberSetting?.value || '0', 10)
563
+
564
+ // Check if there are unsealed totes (closedDate is null)
565
+ const foundNotSealedOrderTote = await this.trxMgr
566
+ .getRepository(OrderTote)
567
+ .findOne({ where: { releaseGood, closedDate: IsNull() } })
568
+
569
+ if (foundNotSealedOrderTote) {
570
+ throw new Error('Please seal the tote(s) before proceeding')
571
+ }
572
+
573
+ // If minimum-seal-number > 0, validate seal counts per tote
574
+ if (minimumSealNumber > 0) {
575
+ // Get all order totes for this release good
576
+ const orderTotes: OrderTote[] = await this.trxMgr.getRepository(OrderTote).find({
577
+ where: { releaseGood },
578
+ relations: ['orderToteSeals']
579
+ })
580
+
581
+ // Validate each tote has at least minimum-seal-number seals
582
+ for (const orderTote of orderTotes) {
583
+ const sealCount = orderTote.orderToteSeals?.length || 0
584
+ if (sealCount < minimumSealNumber) {
585
+ throw new Error(
586
+ `Tote ${orderTote.name} has ${sealCount} seal(s), but minimum ${minimumSealNumber} seal(s) required`
587
+ )
588
+ }
589
+ }
590
+ }
591
+ }
544
592
  }
545
593
 
546
594
  releaseGood.status = ORDER_STATUS.READY_TO_LOAD
@@ -583,12 +631,59 @@ export class SortingWorksheetController extends VasWorksheetController {
583
631
 
584
632
  let releaseGoodIds = worksheet.worksheetDetails.map(itm => itm.targetInventory.releaseGood.id)
585
633
 
586
- const foundNotSealedOrderTote = await this.trxMgr
587
- .getRepository(OrderTote)
588
- .findOne({ where: { releaseGood: In(releaseGoodIds), closedDate: IsNull() } })
634
+ // Check enable-tote-scanning setting
635
+ let enableToteScanningSetting: Setting = await this.trxMgr.getRepository(Setting).findOne({
636
+ where: {
637
+ domain: this.domain,
638
+ category: 'id-rule',
639
+ name: 'enable-tote-scanning'
640
+ }
641
+ })
589
642
 
590
- if (foundNotSealedOrderTote) {
591
- throw new Error('Please seal the tote(s) before proceeding')
643
+ if (enableToteScanningSetting) {
644
+ // enable-tote-scanning is numeric: 0 = disabled, >= 1 = enabled
645
+ const enableToteScanningValue = parseInt(enableToteScanningSetting.value || '0', 10)
646
+
647
+ if (enableToteScanningValue >= 1) {
648
+ // Check minimum-seal-number setting
649
+ let minimumSealNumberSetting: Setting = await this.trxMgr.getRepository(Setting).findOne({
650
+ where: {
651
+ domain: this.domain,
652
+ category: 'id-rule',
653
+ name: 'minimum-seal-number'
654
+ }
655
+ })
656
+
657
+ const minimumSealNumber = parseInt(minimumSealNumberSetting?.value || '0', 10)
658
+
659
+ // Check if there are unsealed totes (closedDate is null) for any of the release goods
660
+ const foundNotSealedOrderTote = await this.trxMgr
661
+ .getRepository(OrderTote)
662
+ .findOne({ where: { releaseGood: In(releaseGoodIds), closedDate: IsNull() } })
663
+
664
+ if (foundNotSealedOrderTote) {
665
+ throw new Error('Please seal the tote(s) before proceeding')
666
+ }
667
+
668
+ // If minimum-seal-number > 0, validate seal counts per tote for all release goods
669
+ if (minimumSealNumber > 0) {
670
+ // Get all order totes for all release goods in this worksheet
671
+ const orderTotes: OrderTote[] = await this.trxMgr.getRepository(OrderTote).find({
672
+ where: { releaseGood: In(releaseGoodIds) },
673
+ relations: ['orderToteSeals']
674
+ })
675
+
676
+ // Validate each tote has at least minimum-seal-number seals
677
+ for (const orderTote of orderTotes) {
678
+ const sealCount = orderTote.orderToteSeals?.length || 0
679
+ if (sealCount < minimumSealNumber) {
680
+ throw new Error(
681
+ `Tote ${orderTote.name} has ${sealCount} seal(s), but minimum ${minimumSealNumber} seal(s) required`
682
+ )
683
+ }
684
+ }
685
+ }
686
+ }
592
687
  }
593
688
 
594
689
  this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
@@ -617,7 +712,7 @@ export class SortingWorksheetController extends VasWorksheetController {
617
712
 
618
713
  private async toteScanning(toteNo, targetProduct, targetInventory, pickedQty, releaseGood, bizplace) {
619
714
  //1. find tote
620
- let foundTote: Tote = await this.trxMgr
715
+ const foundTote: Tote = await this.trxMgr
621
716
  .getRepository(Tote)
622
717
  .findOne({ where: { bizplace, name: toteNo, deletedAt: IsNull() } })
623
718
 
@@ -630,22 +725,21 @@ export class SortingWorksheetController extends VasWorksheetController {
630
725
  }
631
726
 
632
727
  //2. find order tote
633
- let foundOrderTote: OrderTote = await this.trxMgr
728
+ let orderTote: OrderTote = await this.trxMgr
634
729
  .getRepository(OrderTote)
635
730
  .findOne({ where: { domain: this.domain, name: toteNo, releaseGood } })
636
731
 
637
732
  //if order tote not found then create one, if tote not found means it's tote box
638
- //create order tote item
639
- if (!foundOrderTote) {
640
- const orderTote = await this.trxMgr.getRepository(OrderTote).save({
733
+ if (!orderTote) {
734
+ orderTote = await this.trxMgr.getRepository(OrderTote).save({
641
735
  name: toteNo,
642
736
  domain: this.domain,
643
737
  releaseGood,
644
- tote: foundTote ? foundTote : null,
738
+ tote: foundTote ?? null,
645
739
  updater: this.user
646
740
  })
647
741
 
648
- const orderToteItem = await this.trxMgr.getRepository(OrderToteItem).save({
742
+ await this.trxMgr.getRepository(OrderToteItem).save({
649
743
  domain: this.domain,
650
744
  name: OrderNoGenerator.orderToteItem(),
651
745
  orderProduct: targetProduct,
@@ -655,7 +749,7 @@ export class SortingWorksheetController extends VasWorksheetController {
655
749
  updater: this.user
656
750
  })
657
751
  } else {
658
- if (foundOrderTote.closedDate) {
752
+ if (orderTote.closedDate) {
659
753
  throw new Error('Tote has been sealed, please try another tote!')
660
754
  }
661
755
 
@@ -664,27 +758,45 @@ export class SortingWorksheetController extends VasWorksheetController {
664
758
  domain: this.domain,
665
759
  orderProduct: targetProduct,
666
760
  orderInventory: targetInventory,
667
- orderTote: foundOrderTote
761
+ orderTote
668
762
  })
669
763
 
670
- //if not order tote item doesnt exist then create one
671
764
  if (!foundOrderToteItem) {
672
- const orderToteItem = await this.trxMgr.getRepository(OrderToteItem).save({
765
+ await this.trxMgr.getRepository(OrderToteItem).save({
673
766
  domain: this.domain,
674
767
  name: OrderNoGenerator.orderToteItem(),
675
768
  orderProduct: targetProduct,
676
769
  orderInventory: targetInventory,
677
- orderTote: foundOrderTote,
770
+ orderTote,
678
771
  qty: pickedQty,
679
772
  updater: this.user
680
773
  })
681
774
  } else {
682
- //if found order tote item found then add the quantity
683
- const orderToteItem = await this.trxMgr.getRepository(OrderToteItem).save({
775
+ await this.trxMgr.getRepository(OrderToteItem).save({
684
776
  ...foundOrderToteItem,
685
777
  qty: foundOrderToteItem.qty + pickedQty
686
778
  })
687
779
  }
688
780
  }
781
+
782
+ // Check minimum-seal-number setting - if 0, automatically close the tote
783
+ if (!orderTote.closedDate) {
784
+ const sealNoSetting: Setting = await this.trxMgr.getRepository(Setting).findOne({
785
+ where: {
786
+ domain: this.domain,
787
+ name: 'minimum-seal-number'
788
+ }
789
+ })
790
+
791
+ const minimumSealRequiredRaw = parseInt(sealNoSetting?.value ?? '0', 10)
792
+ const minimumSealRequired = isNaN(minimumSealRequiredRaw) ? 0 : Math.max(0, minimumSealRequiredRaw)
793
+
794
+ if (minimumSealRequired === 0) {
795
+ await this.trxMgr.getRepository(OrderTote).save({
796
+ ...orderTote,
797
+ closedDate: new Date()
798
+ })
799
+ }
800
+ }
689
801
  }
690
802
  }