@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
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getManager,
|
|
6
6
|
In,
|
|
7
7
|
IsNull,
|
|
8
|
-
Not
|
|
8
|
+
Not,
|
|
9
9
|
} from 'typeorm'
|
|
10
10
|
|
|
11
11
|
import { ApplicationType } from '@things-factory/auth-base'
|
|
@@ -67,7 +67,8 @@ import {
|
|
|
67
67
|
import { SellercraftController } from '../../controllers'
|
|
68
68
|
import {
|
|
69
69
|
Worksheet,
|
|
70
|
-
WorksheetDetail
|
|
70
|
+
WorksheetDetail,
|
|
71
|
+
ActiveWorksheetPickingView
|
|
71
72
|
} from '../../entities'
|
|
72
73
|
import {
|
|
73
74
|
inventoriesByStrategy,
|
|
@@ -423,6 +424,8 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
423
424
|
)
|
|
424
425
|
} catch (error) {
|
|
425
426
|
throw error
|
|
427
|
+
} finally {
|
|
428
|
+
ActiveWorksheetPickingView.refreshView()
|
|
426
429
|
}
|
|
427
430
|
return worksheets
|
|
428
431
|
}
|
|
@@ -715,135 +718,109 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
715
718
|
): Promise<WorksheetDetail> {
|
|
716
719
|
try {
|
|
717
720
|
//find existing worksheet detail
|
|
718
|
-
let
|
|
719
|
-
.
|
|
720
|
-
.
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
725
|
-
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
726
|
-
.leftJoinAndSelect('oi.orderProduct', 'op')
|
|
727
|
-
.innerJoinAndSelect('oi.product', 'prd')
|
|
728
|
-
.innerJoinAndSelect('oi.productDetail', 'pd')
|
|
729
|
-
.innerJoinAndSelect('pd.productBarcodes', 'pb')
|
|
730
|
-
.where('wd.name = :name', { name: worksheetDetailName })
|
|
731
|
-
.andWhere('wd.domain_id = :domainId', { domainId: this.domain.id })
|
|
732
|
-
.andWhere('wd.type = :type', { type: worksheetType })
|
|
733
|
-
.andWhere('wd.status = :status', { status: WORKSHEET_STATUS.EXECUTING })
|
|
734
|
-
.andWhere('inv.carton_id = :cartonId', { cartonId: cartonId })
|
|
735
|
-
.getOne()
|
|
736
|
-
|
|
737
|
-
//validation to check matching worksheet detail based on name
|
|
738
|
-
if (!worksheetDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
|
|
739
|
-
|
|
740
|
-
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
741
|
-
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
742
|
-
let targetProduct: OrderProduct = targetInventory.orderProduct
|
|
743
|
-
const product: Product = targetInventory.product
|
|
744
|
-
const matchProductBarcode: ProductBarcode = await this.trxMgr.getRepository(ProductBarcode).findOne({
|
|
745
|
-
where: { gtin: productBarcode },
|
|
746
|
-
relations: ['productDetail']
|
|
747
|
-
})
|
|
748
|
-
const productDetail: ProductDetail = targetInventory.productDetail
|
|
749
|
-
const productBarcodes: [ProductBarcode] = productDetail.productBarcodes
|
|
750
|
-
let inventory: Inventory = targetInventory.inventory
|
|
751
|
-
let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
|
|
752
|
-
let pickedUomValue = pickedQty * productDetail.uomValue
|
|
753
|
-
let matchingProduct
|
|
721
|
+
let worksheetDetailFilters = [
|
|
722
|
+
{ query: 'mawp."worksheetDetailName"', value: worksheetDetailName },
|
|
723
|
+
{ query: 'mawp."domainId"', value: this.domain.id },
|
|
724
|
+
{ query: 'mawp."inventoryCartonId"', value: cartonId }
|
|
725
|
+
// { query: 'mawp."gtin"', value: productBarcode }
|
|
726
|
+
]
|
|
754
727
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
where
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
INVENTORY_CHECK_ITEM_STATUS.NOT_TALLY,
|
|
765
|
-
INVENTORY_CHECK_ITEM_STATUS.GROUP_NOT_TALLY,
|
|
766
|
-
INVENTORY_CHECK_ITEM_STATUS.MISSING,
|
|
767
|
-
INVENTORY_CHECK_ITEM_STATUS.ADDED
|
|
768
|
-
])
|
|
769
|
-
}
|
|
728
|
+
let worksheetDetailRaw = await this.trxMgr.query(`
|
|
729
|
+
select * from active_worksheet_picking_views mawp
|
|
730
|
+
where 1 = 1
|
|
731
|
+
and
|
|
732
|
+
${worksheetDetailFilters.map((data, idx) => {
|
|
733
|
+
return `${data.query} = $${idx + 1}`
|
|
734
|
+
}).join(' AND ')}
|
|
735
|
+
`, worksheetDetailFilters.map((data, idx) => {
|
|
736
|
+
return data.value
|
|
770
737
|
})
|
|
738
|
+
)
|
|
771
739
|
|
|
772
|
-
|
|
740
|
+
//validation to check matching worksheet detail based on name
|
|
741
|
+
if ((worksheetDetailRaw.length < 1)) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
|
|
742
|
+
|
|
743
|
+
let worksheetDetailInfos: ActiveWorksheetPickingView = worksheetDetailRaw[0]
|
|
744
|
+
let targetInventory: OrderInventory = await this.trxMgr.getRepository(OrderInventory).findOne({ where: { id: worksheetDetailInfos.orderInventoryId } })
|
|
745
|
+
const inventory: Inventory = await this.trxMgr.getRepository(Inventory).findOne({ where: { id: worksheetDetailInfos.inventoryId } })
|
|
746
|
+
|
|
747
|
+
let targetProduct = { id: worksheetDetailInfos.targetProductId }
|
|
748
|
+
let bizplace: Partial<Bizplace> = { id: worksheetDetailInfos.bizplaceId }
|
|
749
|
+
const releaseGood: Partial<ReleaseGood> = { id: worksheetDetailInfos.releaseGoodId }
|
|
750
|
+
|
|
751
|
+
let matchingProduct, pickedUomValue
|
|
752
|
+
|
|
753
|
+
// // validation to prevent picking if the inventory is involved in cycle count
|
|
754
|
+
const inventoryCheckStatus = new Set([
|
|
755
|
+
INVENTORY_CHECK_ITEM_STATUS.PENDING,
|
|
756
|
+
INVENTORY_CHECK_ITEM_STATUS.INSPECTING,
|
|
757
|
+
INVENTORY_CHECK_ITEM_STATUS.INSPECTED,
|
|
758
|
+
INVENTORY_CHECK_ITEM_STATUS.NOT_TALLY,
|
|
759
|
+
INVENTORY_CHECK_ITEM_STATUS.GROUP_NOT_TALLY,
|
|
760
|
+
INVENTORY_CHECK_ITEM_STATUS.MISSING,
|
|
761
|
+
INVENTORY_CHECK_ITEM_STATUS.ADDED
|
|
762
|
+
]);
|
|
763
|
+
if (inventoryCheckStatus.has(worksheetDetailInfos.inventoryCheckItemStatus)) {
|
|
773
764
|
throw new Error(
|
|
774
765
|
`Inventory currently involved in an ongoing cycle count. Please complete the cycle count to proceed with picking.`
|
|
775
766
|
)
|
|
776
767
|
}
|
|
777
768
|
|
|
778
769
|
//validation to prevent duplicated picking
|
|
779
|
-
if (targetInventory
|
|
770
|
+
if (targetInventory.status != ORDER_INVENTORY_STATUS.PICKING)
|
|
780
771
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`))
|
|
781
772
|
|
|
782
|
-
if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
|
|
783
|
-
|
|
784
|
-
}
|
|
773
|
+
// if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
|
|
774
|
+
// throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
775
|
+
// }
|
|
776
|
+
matchingProduct = worksheetDetailRaw.find(x => x.gtin === productBarcode)
|
|
777
|
+
if (matchingProduct) {
|
|
778
|
+
pickedUomValue = pickedQty * (matchingProduct.uomValue || 1)
|
|
779
|
+
} else {
|
|
780
|
+
matchingProduct = await this.getDirectQty(
|
|
781
|
+
{ id: worksheetDetailInfos.productDetailId },
|
|
782
|
+
productBarcode,
|
|
783
|
+
pickedQty
|
|
784
|
+
)
|
|
785
785
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
...productDetail,
|
|
789
|
-
product: targetInventory?.product
|
|
790
|
-
},
|
|
791
|
-
productBarcode,
|
|
792
|
-
pickedQty
|
|
793
|
-
)
|
|
786
|
+
//validate matching product details based on scanned barcode
|
|
787
|
+
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
794
788
|
|
|
795
|
-
|
|
796
|
-
|
|
789
|
+
pickedQty = matchingProduct.qty
|
|
790
|
+
pickedUomValue = matchingProduct.uomValue
|
|
791
|
+
}
|
|
797
792
|
|
|
798
|
-
|
|
799
|
-
|
|
793
|
+
// //validation to prevent over release
|
|
794
|
+
if (!targetInventory)
|
|
795
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `inventory not assigned`))
|
|
800
796
|
|
|
801
|
-
//validation to prevent over release
|
|
797
|
+
// //validation to prevent over release
|
|
802
798
|
if (
|
|
803
|
-
|
|
804
|
-
worksheetDetail?.targetInventory.inventory.qty < 1 ||
|
|
805
|
-
pickedQty + (worksheetDetail.targetInventory?.pickedQty || 0) > worksheetDetail.targetInventory.releaseQty
|
|
799
|
+
inventory.qty < 1 || pickedQty + (targetInventory?.pickedQty || 0) > targetInventory.releaseQty
|
|
806
800
|
)
|
|
807
801
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
808
802
|
|
|
809
803
|
targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
|
|
810
804
|
|
|
811
|
-
// // search for matching product barcode
|
|
812
|
-
// const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
813
|
-
// // scannedProductDetail can be child or gtin
|
|
814
|
-
// const scannedProductDetail: ProductDetail = productDetails.find(detail => detail.gtin == productBarcode)
|
|
815
|
-
// if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
816
|
-
|
|
817
|
-
// // case for scanning parent packing type, packing size
|
|
818
|
-
// // when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
|
|
819
|
-
// if (scannedProductDetail.id !== productDetail.id && !product?.isRequireSerialNumberScanningOutbound) {
|
|
820
|
-
// let childQty = await this.getChildQty(productDetails, productBarcode, productDetail, scannedProductDetail)
|
|
821
|
-
// pickedQty *= childQty
|
|
822
|
-
// }
|
|
823
|
-
|
|
824
|
-
// if (pickedQty + targetInventory.pickedQty > releaseQty) {
|
|
825
|
-
// throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
826
|
-
// }
|
|
827
|
-
|
|
828
805
|
// for required outbound serial number scanning
|
|
829
|
-
if (
|
|
806
|
+
if (worksheetDetailInfos?.productIsRequireSerialNumberScanningOutbound) {
|
|
830
807
|
if (!serialNumber || serialNumber == '') {
|
|
831
808
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`))
|
|
832
809
|
}
|
|
833
810
|
|
|
834
811
|
let totalInventoryItems = await this.trxMgr.getRepository(InventoryItem).count({
|
|
835
812
|
where: {
|
|
836
|
-
inventory,
|
|
813
|
+
inventory: { id: worksheetDetailInfos.inventoryId },
|
|
837
814
|
status: Not(In([INVENTORY_STATUS.TERMINATED, INVENTORY_STATUS.PICKED]))
|
|
838
815
|
}
|
|
839
816
|
})
|
|
840
817
|
|
|
841
818
|
let foundSerialNumber: InventoryItem = await this.trxMgr
|
|
842
819
|
.getRepository(InventoryItem)
|
|
843
|
-
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
|
|
820
|
+
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, product: { id: worksheetDetailInfos.productId } } })
|
|
844
821
|
|
|
845
822
|
if (foundSerialNumber) {
|
|
846
|
-
if (foundSerialNumber.inventoryId !==
|
|
823
|
+
if (foundSerialNumber.inventoryId !== worksheetDetailInfos.inventoryId) {
|
|
847
824
|
throw new Error('Serial Number scanned is in another inventory')
|
|
848
825
|
}
|
|
849
826
|
|
|
@@ -859,7 +836,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
859
836
|
|
|
860
837
|
foundSerialNumber.status = INVENTORY_STATUS.PICKING
|
|
861
838
|
foundSerialNumber.updater = this.user
|
|
862
|
-
foundSerialNumber.outboundOrderId =
|
|
839
|
+
foundSerialNumber.outboundOrderId = worksheetDetailInfos.releaseGoodId
|
|
863
840
|
|
|
864
841
|
await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
|
|
865
842
|
} else {
|
|
@@ -871,11 +848,11 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
871
848
|
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
872
849
|
inventoryItem.serialNumber = serialNumber
|
|
873
850
|
inventoryItem.status = INVENTORY_STATUS.PICKING
|
|
874
|
-
inventoryItem.outboundOrderId =
|
|
851
|
+
inventoryItem.outboundOrderId = worksheetDetailInfos.releaseGoodId
|
|
875
852
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
876
|
-
inventoryItem.product =
|
|
877
|
-
inventoryItem.productDetail =
|
|
878
|
-
inventoryItem.inventory =
|
|
853
|
+
inventoryItem.product = { id: worksheetDetailInfos.productId }
|
|
854
|
+
inventoryItem.productDetail = { id: worksheetDetailInfos.productDetailId }
|
|
855
|
+
inventoryItem.inventory = { id: worksheetDetailInfos.inventoryId }
|
|
879
856
|
inventoryItem.domain = this.domain
|
|
880
857
|
|
|
881
858
|
await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
@@ -900,11 +877,8 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
900
877
|
updater: this.user,
|
|
901
878
|
pickedBy: this.user.name,
|
|
902
879
|
pickedByUser: this.user,
|
|
903
|
-
pickedAt: new Date()
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
if (targetInventory.pickedQty == releaseQty) {
|
|
907
|
-
updateOiObj['status'] = ORDER_INVENTORY_STATUS.PICKED
|
|
880
|
+
pickedAt: new Date(),
|
|
881
|
+
status: () => `case when release_qty = "picked_qty" + ${pickedQty} then '${ORDER_INVENTORY_STATUS.PICKED}' else status end`
|
|
908
882
|
}
|
|
909
883
|
|
|
910
884
|
if (targetInventory.binLocation) {
|
|
@@ -921,85 +895,78 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
921
895
|
.execute()
|
|
922
896
|
|
|
923
897
|
if (targetInventory.pickedQty == releaseQty) {
|
|
924
|
-
//update worksheet details only when line item picking complete
|
|
925
|
-
await this.trxMgr
|
|
926
|
-
.getRepository(WorksheetDetail)
|
|
927
|
-
.createQueryBuilder()
|
|
928
|
-
.update(WorksheetDetail)
|
|
929
|
-
.set({
|
|
930
|
-
status: WORKSHEET_STATUS.DONE,
|
|
931
|
-
updater: this.user,
|
|
932
|
-
updatedAt: new Date()
|
|
933
|
-
})
|
|
934
|
-
.where('id = :id', { id: worksheetDetail.id })
|
|
935
|
-
.execute()
|
|
936
|
-
|
|
937
898
|
getConnection().transaction(async (tx: EntityManager) => {
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
.createQueryBuilder()
|
|
952
|
-
.update(Inventory)
|
|
953
|
-
.set(updateInvObj)
|
|
954
|
-
.where('id = :id', { id: targetInventory.inventory.id })
|
|
955
|
-
.returning(['qty'])
|
|
956
|
-
.execute()
|
|
957
|
-
.then(dt => {
|
|
958
|
-
return dt.raw[0].qty
|
|
959
|
-
})
|
|
960
|
-
|
|
961
|
-
await generateInventoryHistory(
|
|
962
|
-
inventory,
|
|
963
|
-
releaseGood,
|
|
964
|
-
INVENTORY_TRANSACTION_TYPE.PICKING,
|
|
965
|
-
-releaseQty,
|
|
966
|
-
-releaseUomValue,
|
|
967
|
-
this.user,
|
|
968
|
-
tx
|
|
969
|
-
)
|
|
970
|
-
|
|
971
|
-
let inventoryItems: InventoryItem = await tx
|
|
972
|
-
.getRepository(InventoryItem)
|
|
973
|
-
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
899
|
+
try {
|
|
900
|
+
//update worksheet details only when line item picking complete
|
|
901
|
+
await tx
|
|
902
|
+
.getRepository(WorksheetDetail)
|
|
903
|
+
.createQueryBuilder()
|
|
904
|
+
.update(WorksheetDetail)
|
|
905
|
+
.set({
|
|
906
|
+
status: WORKSHEET_STATUS.DONE,
|
|
907
|
+
updater: this.user,
|
|
908
|
+
updatedAt: new Date()
|
|
909
|
+
})
|
|
910
|
+
.where('id = :id', { id: worksheetDetailInfos.worksheetDetailId })
|
|
911
|
+
.execute()
|
|
974
912
|
|
|
975
|
-
|
|
976
|
-
inventoryItems.forEach((itm: InventoryItem) => {
|
|
977
|
-
itm.status = INVENTORY_STATUS.PICKED
|
|
978
|
-
itm.updater = this.user
|
|
979
|
-
})
|
|
913
|
+
let releaseUomValue = Math.round((pickedUomValue / pickedQty) * releaseQty * 100) / 100
|
|
980
914
|
|
|
981
|
-
|
|
982
|
-
|
|
915
|
+
let updateInvObj = {
|
|
916
|
+
qty: () => `"qty" - ${releaseQty}`,
|
|
917
|
+
lockedQty: () => `"locked_qty" - ${releaseQty}`,
|
|
918
|
+
uomValue: () => `"uom_value" - ${releaseUomValue}`,
|
|
919
|
+
lockedUomValue: () => `"locked_uom_value" - ${releaseUomValue}`,
|
|
920
|
+
status: () => `case when "qty" - ${releaseQty} <= 0 then '${INVENTORY_STATUS.TERMINATED}' else status end`,
|
|
921
|
+
updater: this.user,
|
|
922
|
+
updatedAt: new Date()
|
|
923
|
+
}
|
|
983
924
|
|
|
984
|
-
if (remainingQty === 0) {
|
|
985
925
|
await tx
|
|
986
926
|
.getRepository(Inventory)
|
|
987
927
|
.createQueryBuilder()
|
|
988
928
|
.update(Inventory)
|
|
989
|
-
.set(
|
|
990
|
-
.where('id = :id', { id:
|
|
929
|
+
.set(updateInvObj)
|
|
930
|
+
.where('id = :id', { id: worksheetDetailInfos.inventoryId })
|
|
931
|
+
.returning(['qty'])
|
|
991
932
|
.execute()
|
|
933
|
+
|
|
934
|
+
await generateInventoryHistory(
|
|
935
|
+
inventory,
|
|
936
|
+
releaseGood,
|
|
937
|
+
INVENTORY_TRANSACTION_TYPE.PICKING,
|
|
938
|
+
-releaseQty,
|
|
939
|
+
-releaseUomValue,
|
|
940
|
+
this.user,
|
|
941
|
+
tx
|
|
942
|
+
)
|
|
943
|
+
|
|
944
|
+
let inventoryItems: InventoryItem = await tx
|
|
945
|
+
.getRepository(InventoryItem)
|
|
946
|
+
.find({ where: { outboundOrderId: worksheetDetailInfos.releaseGoodId } })
|
|
947
|
+
|
|
948
|
+
if (inventoryItems.length > 0) {
|
|
949
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
950
|
+
itm.status = INVENTORY_STATUS.PICKED
|
|
951
|
+
itm.updater = this.user
|
|
952
|
+
})
|
|
953
|
+
|
|
954
|
+
await tx.getRepository(InventoryItem).save(inventoryItems)
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
} catch (error) {
|
|
958
|
+
throw error
|
|
959
|
+
|
|
992
960
|
}
|
|
993
961
|
})
|
|
994
962
|
}
|
|
995
963
|
|
|
996
|
-
|
|
997
|
-
worksheetDetail = await this.trxMgr
|
|
964
|
+
let worksheetDetail = await this.trxMgr
|
|
998
965
|
.getRepository(WorksheetDetail)
|
|
999
966
|
.createQueryBuilder('wd')
|
|
1000
967
|
.innerJoin('wd.targetInventory', 'oi')
|
|
1001
968
|
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
1002
|
-
.where('wd.id = :id', { id:
|
|
969
|
+
.where('wd.id = :id', { id: worksheetDetailInfos.worksheetDetailId })
|
|
1003
970
|
.getOne()
|
|
1004
971
|
|
|
1005
972
|
return worksheetDetail
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { ViewColumn, ViewEntity, Index, getConnection, EntityManager } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
@ViewEntity({
|
|
4
|
+
materialized: true,
|
|
5
|
+
expression: `
|
|
6
|
+
select
|
|
7
|
+
wd.id AS "worksheetDetailId",
|
|
8
|
+
wd.name as "worksheetDetailName",
|
|
9
|
+
w.id as "worksheetId",
|
|
10
|
+
w.domain_id as "domainId",
|
|
11
|
+
op.id as "targetProductId",
|
|
12
|
+
op.product_id as "productId",
|
|
13
|
+
op.product_detail_id as "productDetailId",
|
|
14
|
+
op.uom_value as "uomValue",
|
|
15
|
+
pb.id as "productBarcodeId",
|
|
16
|
+
pb.gtin,
|
|
17
|
+
p.is_require_serial_number_scanning_outbound as "productIsRequireSerialNumberScanningOutbound",
|
|
18
|
+
oi.release_good_id as "releaseGoodId",
|
|
19
|
+
oi.id as "orderInventoryId",
|
|
20
|
+
oi.status as "orderInventoryStatus",
|
|
21
|
+
oi.bizplace_id as "bizplaceId",
|
|
22
|
+
i.id as "inventoryId",
|
|
23
|
+
i.carton_id as "inventoryCartonId",
|
|
24
|
+
i.status as "inventoryStatus",
|
|
25
|
+
ici.status as "inventoryCheckItemStatus"
|
|
26
|
+
FROM worksheet_details wd
|
|
27
|
+
INNER JOIN worksheets w ON wd.worksheet_id = w.id
|
|
28
|
+
inner JOIN order_inventories oi ON oi.id = wd.target_inventory_id
|
|
29
|
+
inner JOIN order_products op ON op.id = oi.order_product_id
|
|
30
|
+
inner join inventories i on i.id = oi.inventory_id
|
|
31
|
+
left join inventory_check_items ici on ici.inventory_id = oi.inventory_id
|
|
32
|
+
inner join products p on p.id = oi.product_id
|
|
33
|
+
LEFT JOIN product_barcodes pb ON pb.product_detail_id = op.product_detail_id
|
|
34
|
+
WHERE w.type::text = 'PICKING'::text AND w.status::text = 'EXECUTING'::text
|
|
35
|
+
ORDER BY w.domain_id, w.bizplace_id, wd.id
|
|
36
|
+
`
|
|
37
|
+
})
|
|
38
|
+
export class ActiveWorksheetPickingView {
|
|
39
|
+
static async refreshView() {
|
|
40
|
+
await getConnection().transaction(async (tx: EntityManager) => {
|
|
41
|
+
await tx.getRepository(ActiveWorksheetPickingView).query('REFRESH MATERIALIZED VIEW CONCURRENTLY active_worksheet_picking_views')
|
|
42
|
+
.then(resp => console.log('update active_worksheet_picking_views ok'))
|
|
43
|
+
.catch(err => console.error('update active_worksheet_picking_views error'))
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Index(
|
|
48
|
+
'ix_active-worksheet-picking_0',
|
|
49
|
+
(ActiveWorksheetPickingView: ActiveWorksheetPickingView) => [ActiveWorksheetPickingView.orderInventoryId, ActiveWorksheetPickingView.productBarcodeId],
|
|
50
|
+
{ unique: true }
|
|
51
|
+
)
|
|
52
|
+
@Index(
|
|
53
|
+
'ix_active-worksheet-picking_1',
|
|
54
|
+
(ActiveWorksheetPickingView: ActiveWorksheetPickingView) => [ActiveWorksheetPickingView.worksheetDetailId]
|
|
55
|
+
)
|
|
56
|
+
@Index(
|
|
57
|
+
'ix_active-worksheet-picking_2',
|
|
58
|
+
(ActiveWorksheetPickingView: ActiveWorksheetPickingView) => [ActiveWorksheetPickingView.domainId, ActiveWorksheetPickingView.worksheetDetailName]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@ViewColumn()
|
|
62
|
+
worksheetDetailId: string
|
|
63
|
+
|
|
64
|
+
@ViewColumn()
|
|
65
|
+
worksheetDetailName: string
|
|
66
|
+
|
|
67
|
+
@ViewColumn()
|
|
68
|
+
worksheetId: string
|
|
69
|
+
|
|
70
|
+
@ViewColumn()
|
|
71
|
+
domainId: string
|
|
72
|
+
|
|
73
|
+
@ViewColumn()
|
|
74
|
+
bizplaceId: string
|
|
75
|
+
|
|
76
|
+
@ViewColumn()
|
|
77
|
+
targetProductId: string
|
|
78
|
+
|
|
79
|
+
@ViewColumn()
|
|
80
|
+
productId: string
|
|
81
|
+
|
|
82
|
+
@ViewColumn()
|
|
83
|
+
productDetailId: string
|
|
84
|
+
|
|
85
|
+
@ViewColumn()
|
|
86
|
+
uomValue: number
|
|
87
|
+
|
|
88
|
+
@ViewColumn()
|
|
89
|
+
productBarcodeId: string
|
|
90
|
+
|
|
91
|
+
@ViewColumn()
|
|
92
|
+
gtin: string
|
|
93
|
+
|
|
94
|
+
@ViewColumn()
|
|
95
|
+
productIsRequireSerialNumberScanningOutbound: string
|
|
96
|
+
|
|
97
|
+
@ViewColumn()
|
|
98
|
+
releaseGoodId: string
|
|
99
|
+
|
|
100
|
+
@ViewColumn()
|
|
101
|
+
orderInventoryId: string
|
|
102
|
+
|
|
103
|
+
@ViewColumn()
|
|
104
|
+
orderInventoryStatus: string
|
|
105
|
+
|
|
106
|
+
@ViewColumn()
|
|
107
|
+
inventoryId: string
|
|
108
|
+
|
|
109
|
+
@ViewColumn()
|
|
110
|
+
inventoryCartonId: string
|
|
111
|
+
|
|
112
|
+
@ViewColumn()
|
|
113
|
+
inventoryStatus: string
|
|
114
|
+
|
|
115
|
+
@ViewColumn()
|
|
116
|
+
inventoryCheckItemStatus: string
|
|
117
|
+
|
|
118
|
+
}
|
package/server/entities/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
import { ActiveWorksheetPickingView } from './active-worksheet-picking-view'
|
|
1
3
|
import { WarehouseBizplaceOnhandInventory } from './warehouse-bizplace-onhand-inventory'
|
|
2
4
|
import { WarehouseInventoryAssignmentRanking } from './warehouse-inventory-assignment-ranking'
|
|
3
5
|
import { Worksheet } from './worksheet'
|
|
@@ -5,6 +7,7 @@ import { WorksheetDetail } from './worksheet-detail'
|
|
|
5
7
|
import { WorksheetMovement } from './worksheet-movement'
|
|
6
8
|
|
|
7
9
|
export const entities = [
|
|
10
|
+
ActiveWorksheetPickingView,
|
|
8
11
|
Worksheet,
|
|
9
12
|
WorksheetDetail,
|
|
10
13
|
WorksheetMovement,
|
|
@@ -13,6 +16,7 @@ export const entities = [
|
|
|
13
16
|
]
|
|
14
17
|
|
|
15
18
|
export {
|
|
19
|
+
ActiveWorksheetPickingView,
|
|
16
20
|
WarehouseBizplaceOnhandInventory,
|
|
17
21
|
WarehouseInventoryAssignmentRanking,
|
|
18
22
|
Worksheet,
|