@things-factory/worksheet-base 4.3.367 → 4.3.369
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.
- package/dist-server/controllers/outbound/picking-worksheet-controller.js +111 -140
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/dist-server/entities/active-worksheet-picking-view.js +141 -0
- package/dist-server/entities/active-worksheet-picking-view.js.map +1 -0
- package/dist-server/entities/index.js +4 -1
- package/dist-server/entities/index.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/activate-picking.js +64 -55
- package/dist-server/graphql/resolvers/worksheet/picking/activate-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +3 -0
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.js +2 -1
- package/dist-server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js +73 -71
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/worksheet.js +0 -3
- package/dist-server/graphql/resolvers/worksheet/worksheet.js.map +1 -1
- package/package.json +4 -4
- package/server/controllers/outbound/picking-worksheet-controller.ts +134 -167
- package/server/entities/active-worksheet-picking-view.ts +118 -0
- package/server/entities/index.ts +4 -0
- package/server/graphql/resolvers/worksheet/picking/activate-picking.ts +73 -67
- package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +4 -1
- package/server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.ts +3 -2
- package/server/graphql/resolvers/worksheet/picking-worksheet.ts +82 -80
- package/server/graphql/resolvers/worksheet/worksheet.ts +0 -3
|
@@ -298,6 +298,9 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
|
|
|
298
298
|
catch (error) {
|
|
299
299
|
throw error;
|
|
300
300
|
}
|
|
301
|
+
finally {
|
|
302
|
+
entities_1.ActiveWorksheetPickingView.refreshView();
|
|
303
|
+
}
|
|
301
304
|
return worksheets;
|
|
302
305
|
}
|
|
303
306
|
async activateBatchPicking(worksheetNo) {
|
|
@@ -498,111 +501,88 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
|
|
|
498
501
|
}, { status: sales_base_1.ORDER_INVENTORY_STATUS.PENDING_SPLIT, updater: this.user, updatedAt: new Date() });
|
|
499
502
|
}
|
|
500
503
|
async scanProductPicking(worksheetDetailName, worksheetType, productBarcode, cartonId, binLocation, serialNumber, toteNo, pickedQty = 1) {
|
|
501
|
-
var _a;
|
|
502
504
|
try {
|
|
503
505
|
//find existing worksheet detail
|
|
504
|
-
let
|
|
505
|
-
.
|
|
506
|
-
.
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
.
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
.
|
|
519
|
-
|
|
520
|
-
.andWhere('inv.carton_id = :cartonId', { cartonId: cartonId })
|
|
521
|
-
.getOne();
|
|
506
|
+
let worksheetDetailFilters = [
|
|
507
|
+
{ query: 'mawp."worksheetDetailName"', value: worksheetDetailName },
|
|
508
|
+
{ query: 'mawp."domainId"', value: this.domain.id },
|
|
509
|
+
{ query: 'mawp."inventoryCartonId"', value: cartonId }
|
|
510
|
+
// { query: 'mawp."gtin"', value: productBarcode }
|
|
511
|
+
];
|
|
512
|
+
let worksheetDetailRaw = await this.trxMgr.query(`
|
|
513
|
+
select * from active_worksheet_picking_views mawp
|
|
514
|
+
where 1 = 1
|
|
515
|
+
and
|
|
516
|
+
${worksheetDetailFilters.map((data, idx) => {
|
|
517
|
+
return `${data.query} = $${idx + 1}`;
|
|
518
|
+
}).join(' AND ')}
|
|
519
|
+
`, worksheetDetailFilters.map((data, idx) => {
|
|
520
|
+
return data.value;
|
|
521
|
+
}));
|
|
522
522
|
//validation to check matching worksheet detail based on name
|
|
523
|
-
if (
|
|
523
|
+
if ((worksheetDetailRaw.length < 1))
|
|
524
524
|
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName));
|
|
525
|
-
|
|
526
|
-
let targetInventory =
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
const
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
inventory: inventory.id,
|
|
544
|
-
status: (0, typeorm_1.In)([
|
|
545
|
-
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.PENDING,
|
|
546
|
-
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTING,
|
|
547
|
-
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED,
|
|
548
|
-
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.NOT_TALLY,
|
|
549
|
-
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.GROUP_NOT_TALLY,
|
|
550
|
-
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.MISSING,
|
|
551
|
-
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.ADDED
|
|
552
|
-
])
|
|
553
|
-
}
|
|
554
|
-
});
|
|
555
|
-
if (inventoryCheckItem) {
|
|
525
|
+
let worksheetDetailInfos = worksheetDetailRaw[0];
|
|
526
|
+
let targetInventory = await this.trxMgr.getRepository(sales_base_1.OrderInventory).findOne({ where: { id: worksheetDetailInfos.orderInventoryId } });
|
|
527
|
+
const inventory = await this.trxMgr.getRepository(warehouse_base_1.Inventory).findOne({ where: { id: worksheetDetailInfos.inventoryId } });
|
|
528
|
+
let targetProduct = { id: worksheetDetailInfos.targetProductId };
|
|
529
|
+
let bizplace = { id: worksheetDetailInfos.bizplaceId };
|
|
530
|
+
const releaseGood = { id: worksheetDetailInfos.releaseGoodId };
|
|
531
|
+
let matchingProduct, pickedUomValue;
|
|
532
|
+
// // validation to prevent picking if the inventory is involved in cycle count
|
|
533
|
+
const inventoryCheckStatus = new Set([
|
|
534
|
+
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.PENDING,
|
|
535
|
+
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTING,
|
|
536
|
+
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED,
|
|
537
|
+
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.NOT_TALLY,
|
|
538
|
+
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.GROUP_NOT_TALLY,
|
|
539
|
+
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.MISSING,
|
|
540
|
+
sales_base_1.INVENTORY_CHECK_ITEM_STATUS.ADDED
|
|
541
|
+
]);
|
|
542
|
+
if (inventoryCheckStatus.has(worksheetDetailInfos.inventoryCheckItemStatus)) {
|
|
556
543
|
throw new Error(`Inventory currently involved in an ongoing cycle count. Please complete the cycle count to proceed with picking.`);
|
|
557
544
|
}
|
|
558
545
|
//validation to prevent duplicated picking
|
|
559
|
-
if (
|
|
546
|
+
if (targetInventory.status != sales_base_1.ORDER_INVENTORY_STATUS.PICKING)
|
|
560
547
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`));
|
|
561
|
-
if (!productBarcodes.find(itm => itm.gtin == productBarcode) &&
|
|
562
|
-
|
|
548
|
+
// if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
|
|
549
|
+
// throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
550
|
+
// }
|
|
551
|
+
matchingProduct = worksheetDetailRaw.find(x => x.gtin === productBarcode);
|
|
552
|
+
if (matchingProduct) {
|
|
553
|
+
pickedUomValue = pickedQty * (matchingProduct.uomValue || 1);
|
|
563
554
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
555
|
+
else {
|
|
556
|
+
matchingProduct = await this.getDirectQty({ id: worksheetDetailInfos.productDetailId }, productBarcode, pickedQty);
|
|
557
|
+
//validate matching product details based on scanned barcode
|
|
558
|
+
if (!matchingProduct)
|
|
559
|
+
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode));
|
|
560
|
+
pickedQty = matchingProduct.qty;
|
|
561
|
+
pickedUomValue = matchingProduct.uomValue;
|
|
562
|
+
}
|
|
563
|
+
// //validation to prevent over release
|
|
564
|
+
if (!targetInventory)
|
|
565
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `inventory not assigned`));
|
|
566
|
+
// //validation to prevent over release
|
|
567
|
+
if (inventory.qty < 1 || pickedQty + ((targetInventory === null || targetInventory === void 0 ? void 0 : targetInventory.pickedQty) || 0) > targetInventory.releaseQty)
|
|
574
568
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`));
|
|
575
569
|
targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation);
|
|
576
|
-
// // search for matching product barcode
|
|
577
|
-
// const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
578
|
-
// // scannedProductDetail can be child or gtin
|
|
579
|
-
// const scannedProductDetail: ProductDetail = productDetails.find(detail => detail.gtin == productBarcode)
|
|
580
|
-
// if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
581
|
-
// // case for scanning parent packing type, packing size
|
|
582
|
-
// // when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
|
|
583
|
-
// if (scannedProductDetail.id !== productDetail.id && !product?.isRequireSerialNumberScanningOutbound) {
|
|
584
|
-
// let childQty = await this.getChildQty(productDetails, productBarcode, productDetail, scannedProductDetail)
|
|
585
|
-
// pickedQty *= childQty
|
|
586
|
-
// }
|
|
587
|
-
// if (pickedQty + targetInventory.pickedQty > releaseQty) {
|
|
588
|
-
// throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
589
|
-
// }
|
|
590
570
|
// for required outbound serial number scanning
|
|
591
|
-
if (
|
|
571
|
+
if (worksheetDetailInfos === null || worksheetDetailInfos === void 0 ? void 0 : worksheetDetailInfos.productIsRequireSerialNumberScanningOutbound) {
|
|
592
572
|
if (!serialNumber || serialNumber == '') {
|
|
593
573
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`));
|
|
594
574
|
}
|
|
595
575
|
let totalInventoryItems = await this.trxMgr.getRepository(warehouse_base_1.InventoryItem).count({
|
|
596
576
|
where: {
|
|
597
|
-
inventory,
|
|
577
|
+
inventory: { id: worksheetDetailInfos.inventoryId },
|
|
598
578
|
status: (0, typeorm_1.Not)((0, typeorm_1.In)([warehouse_base_1.INVENTORY_STATUS.TERMINATED, warehouse_base_1.INVENTORY_STATUS.PICKED]))
|
|
599
579
|
}
|
|
600
580
|
});
|
|
601
581
|
let foundSerialNumber = await this.trxMgr
|
|
602
582
|
.getRepository(warehouse_base_1.InventoryItem)
|
|
603
|
-
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } });
|
|
583
|
+
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, product: { id: worksheetDetailInfos.productId } } });
|
|
604
584
|
if (foundSerialNumber) {
|
|
605
|
-
if (foundSerialNumber.inventoryId !==
|
|
585
|
+
if (foundSerialNumber.inventoryId !== worksheetDetailInfos.inventoryId) {
|
|
606
586
|
throw new Error('Serial Number scanned is in another inventory');
|
|
607
587
|
}
|
|
608
588
|
if (foundSerialNumber.outboundOrderId) {
|
|
@@ -615,7 +595,7 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
|
|
|
615
595
|
}
|
|
616
596
|
foundSerialNumber.status = warehouse_base_1.INVENTORY_STATUS.PICKING;
|
|
617
597
|
foundSerialNumber.updater = this.user;
|
|
618
|
-
foundSerialNumber.outboundOrderId =
|
|
598
|
+
foundSerialNumber.outboundOrderId = worksheetDetailInfos.releaseGoodId;
|
|
619
599
|
await this.trxMgr.getRepository(warehouse_base_1.InventoryItem).save(foundSerialNumber);
|
|
620
600
|
}
|
|
621
601
|
else {
|
|
@@ -626,11 +606,11 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
|
|
|
626
606
|
inventoryItem.name = warehouse_base_1.InventoryNoGenerator.inventoryItemName();
|
|
627
607
|
inventoryItem.serialNumber = serialNumber;
|
|
628
608
|
inventoryItem.status = warehouse_base_1.INVENTORY_STATUS.PICKING;
|
|
629
|
-
inventoryItem.outboundOrderId =
|
|
609
|
+
inventoryItem.outboundOrderId = worksheetDetailInfos.releaseGoodId;
|
|
630
610
|
inventoryItem.source = warehouse_base_1.INVENTORY_ITEM_SOURCE.OUTBOUND;
|
|
631
|
-
inventoryItem.product =
|
|
632
|
-
inventoryItem.productDetail =
|
|
633
|
-
inventoryItem.inventory =
|
|
611
|
+
inventoryItem.product = { id: worksheetDetailInfos.productId };
|
|
612
|
+
inventoryItem.productDetail = { id: worksheetDetailInfos.productDetailId };
|
|
613
|
+
inventoryItem.inventory = { id: worksheetDetailInfos.inventoryId };
|
|
634
614
|
inventoryItem.domain = this.domain;
|
|
635
615
|
await this.trxMgr.getRepository(warehouse_base_1.InventoryItem).save(inventoryItem);
|
|
636
616
|
}
|
|
@@ -649,11 +629,9 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
|
|
|
649
629
|
updater: this.user,
|
|
650
630
|
pickedBy: this.user.name,
|
|
651
631
|
pickedByUser: this.user,
|
|
652
|
-
pickedAt: new Date()
|
|
632
|
+
pickedAt: new Date(),
|
|
633
|
+
status: () => `case when release_qty = "picked_qty" + ${pickedQty} then '${sales_base_1.ORDER_INVENTORY_STATUS.PICKED}' else status end`
|
|
653
634
|
};
|
|
654
|
-
if (targetInventory.pickedQty == releaseQty) {
|
|
655
|
-
updateOiObj['status'] = sales_base_1.ORDER_INVENTORY_STATUS.PICKED;
|
|
656
|
-
}
|
|
657
635
|
if (targetInventory.binLocation) {
|
|
658
636
|
updateOiObj['binLocation'] = targetInventory.binLocation;
|
|
659
637
|
}
|
|
@@ -666,68 +644,61 @@ class PickingWorksheetController extends vas_worksheet_controller_1.VasWorksheet
|
|
|
666
644
|
.andWhere(`picked_qty + :pickedQty <= release_qty`, { pickedQty })
|
|
667
645
|
.execute();
|
|
668
646
|
if (targetInventory.pickedQty == releaseQty) {
|
|
669
|
-
//update worksheet details only when line item picking complete
|
|
670
|
-
await this.trxMgr
|
|
671
|
-
.getRepository(entities_1.WorksheetDetail)
|
|
672
|
-
.createQueryBuilder()
|
|
673
|
-
.update(entities_1.WorksheetDetail)
|
|
674
|
-
.set({
|
|
675
|
-
status: constants_1.WORKSHEET_STATUS.DONE,
|
|
676
|
-
updater: this.user,
|
|
677
|
-
updatedAt: new Date()
|
|
678
|
-
})
|
|
679
|
-
.where('id = :id', { id: worksheetDetail.id })
|
|
680
|
-
.execute();
|
|
681
647
|
(0, typeorm_1.getConnection)().transaction(async (tx) => {
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
.find({ where: { outboundOrderId: releaseGood.id } });
|
|
706
|
-
if (inventoryItems.length > 0) {
|
|
707
|
-
inventoryItems.forEach((itm) => {
|
|
708
|
-
itm.status = warehouse_base_1.INVENTORY_STATUS.PICKED;
|
|
709
|
-
itm.updater = this.user;
|
|
710
|
-
});
|
|
711
|
-
await tx.getRepository(warehouse_base_1.InventoryItem).save(inventoryItems);
|
|
712
|
-
}
|
|
713
|
-
if (remainingQty === 0) {
|
|
648
|
+
try {
|
|
649
|
+
//update worksheet details only when line item picking complete
|
|
650
|
+
await tx
|
|
651
|
+
.getRepository(entities_1.WorksheetDetail)
|
|
652
|
+
.createQueryBuilder()
|
|
653
|
+
.update(entities_1.WorksheetDetail)
|
|
654
|
+
.set({
|
|
655
|
+
status: constants_1.WORKSHEET_STATUS.DONE,
|
|
656
|
+
updater: this.user,
|
|
657
|
+
updatedAt: new Date()
|
|
658
|
+
})
|
|
659
|
+
.where('id = :id', { id: worksheetDetailInfos.worksheetDetailId })
|
|
660
|
+
.execute();
|
|
661
|
+
let releaseUomValue = Math.round((pickedUomValue / pickedQty) * releaseQty * 100) / 100;
|
|
662
|
+
let updateInvObj = {
|
|
663
|
+
qty: () => `"qty" - ${releaseQty}`,
|
|
664
|
+
lockedQty: () => `"locked_qty" - ${releaseQty}`,
|
|
665
|
+
uomValue: () => `"uom_value" - ${releaseUomValue}`,
|
|
666
|
+
lockedUomValue: () => `"locked_uom_value" - ${releaseUomValue}`,
|
|
667
|
+
status: () => `case when "qty" - ${releaseQty} <= 0 then '${warehouse_base_1.INVENTORY_STATUS.TERMINATED}' else status end`,
|
|
668
|
+
updater: this.user,
|
|
669
|
+
updatedAt: new Date()
|
|
670
|
+
};
|
|
714
671
|
await tx
|
|
715
672
|
.getRepository(warehouse_base_1.Inventory)
|
|
716
673
|
.createQueryBuilder()
|
|
717
674
|
.update(warehouse_base_1.Inventory)
|
|
718
|
-
.set(
|
|
719
|
-
.where('id = :id', { id:
|
|
675
|
+
.set(updateInvObj)
|
|
676
|
+
.where('id = :id', { id: worksheetDetailInfos.inventoryId })
|
|
677
|
+
.returning(['qty'])
|
|
720
678
|
.execute();
|
|
679
|
+
await (0, warehouse_base_1.generateInventoryHistory)(inventory, releaseGood, warehouse_base_1.INVENTORY_TRANSACTION_TYPE.PICKING, -releaseQty, -releaseUomValue, this.user, tx);
|
|
680
|
+
let inventoryItems = await tx
|
|
681
|
+
.getRepository(warehouse_base_1.InventoryItem)
|
|
682
|
+
.find({ where: { outboundOrderId: worksheetDetailInfos.releaseGoodId } });
|
|
683
|
+
if (inventoryItems.length > 0) {
|
|
684
|
+
inventoryItems.forEach((itm) => {
|
|
685
|
+
itm.status = warehouse_base_1.INVENTORY_STATUS.PICKED;
|
|
686
|
+
itm.updater = this.user;
|
|
687
|
+
});
|
|
688
|
+
await tx.getRepository(warehouse_base_1.InventoryItem).save(inventoryItems);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
catch (error) {
|
|
692
|
+
throw error;
|
|
721
693
|
}
|
|
722
694
|
});
|
|
723
695
|
}
|
|
724
|
-
|
|
725
|
-
worksheetDetail = await this.trxMgr
|
|
696
|
+
let worksheetDetail = await this.trxMgr
|
|
726
697
|
.getRepository(entities_1.WorksheetDetail)
|
|
727
698
|
.createQueryBuilder('wd')
|
|
728
699
|
.innerJoin('wd.targetInventory', 'oi')
|
|
729
700
|
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
730
|
-
.where('wd.id = :id', { id:
|
|
701
|
+
.where('wd.id = :id', { id: worksheetDetailInfos.worksheetDetailId })
|
|
731
702
|
.getOne();
|
|
732
703
|
return worksheetDetail;
|
|
733
704
|
}
|