@things-factory/worksheet-base 4.3.138 → 4.3.140
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/inbound/unloading-worksheet-controller.js +37 -24
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/picking-worksheet-controller.js +103 -99
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/package.json +4 -4
- package/server/controllers/inbound/unloading-worksheet-controller.ts +50 -36
- package/server/controllers/outbound/picking-worksheet-controller.ts +123 -122
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
TOTE_STATUS,
|
|
32
32
|
generateInventoryHistory
|
|
33
33
|
} from '@things-factory/warehouse-base'
|
|
34
|
+
import { logger } from '@things-factory/env'
|
|
34
35
|
|
|
35
36
|
import { TASK_NUMBER_RULE_TYPE, TASK_NUMBER_SETTING_KEY, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
|
|
36
37
|
import { Worksheet, WorksheetDetail } from '../../entities'
|
|
@@ -991,148 +992,144 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
991
992
|
binLocationName: string,
|
|
992
993
|
pickingQty: number
|
|
993
994
|
): Promise<void> {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
'worksheetDetails
|
|
1000
|
-
'worksheetDetails.targetInventory
|
|
1001
|
-
'
|
|
1002
|
-
'
|
|
1003
|
-
'
|
|
1004
|
-
'
|
|
1005
|
-
'
|
|
1006
|
-
'
|
|
1007
|
-
|
|
1008
|
-
|
|
995
|
+
try {
|
|
996
|
+
console.time(`scanProductBatchPicking:${taskNo}`)
|
|
997
|
+
const worksheet: Worksheet = await this.trxMgr
|
|
998
|
+
.getRepository(Worksheet)
|
|
999
|
+
.createQueryBuilder('worksheet')
|
|
1000
|
+
.innerJoinAndSelect('worksheet.worksheetDetails', 'worksheetDetails')
|
|
1001
|
+
.innerJoinAndSelect('worksheetDetails.targetInventory', 'targetInventory')
|
|
1002
|
+
.innerJoinAndSelect('targetInventory.product', 'product')
|
|
1003
|
+
.leftJoinAndSelect('targetInventory.productDetail', 'productDetail')
|
|
1004
|
+
.leftJoinAndSelect('targetInventory.inventory', 'inventory')
|
|
1005
|
+
.leftJoinAndSelect('inventory.location', 'location')
|
|
1006
|
+
.leftJoinAndSelect('targetInventory.releaseGood', 'releaseGood')
|
|
1007
|
+
.where('worksheet.domain_id = :domainId', { domainId: this.domain.id })
|
|
1008
|
+
.andWhere('worksheet.task_no = :taskNo', { taskNo })
|
|
1009
|
+
.andWhere('worksheet.type = :type', { type: worksheetType })
|
|
1010
|
+
.andWhere('worksheet.status = :status', { status: WORKSHEET_STATUS.EXECUTING })
|
|
1011
|
+
.getOne()
|
|
1012
|
+
const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
|
|
1013
|
+
const productDetail: ProductDetail = worksheetDetails
|
|
1014
|
+
.map(wsd => wsd.targetInventory.productDetail)
|
|
1015
|
+
.find(productDetail => productDetail.id === inventory.productDetail.id)
|
|
1009
1016
|
|
|
1010
|
-
|
|
1011
|
-
const productDetail: ProductDetail = worksheetDetails
|
|
1012
|
-
.map(wsd => wsd.targetInventory.productDetail)
|
|
1013
|
-
.find(productDetail => productDetail.id === inventory.productDetail.id)
|
|
1017
|
+
const product: Product = productDetail.product
|
|
1014
1018
|
|
|
1015
|
-
|
|
1019
|
+
const batchId: string = inventory.batchId
|
|
1020
|
+
let pickedQty: number = pickingQty ? pickingQty : 1
|
|
1021
|
+
let matchingProduct
|
|
1016
1022
|
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1023
|
+
const targetInventories: OrderInventory[] = worksheetDetails
|
|
1024
|
+
.map((wsd: WorksheetDetail) => wsd.targetInventory)
|
|
1025
|
+
.filter(
|
|
1026
|
+
(targetInventory: OrderInventory) =>
|
|
1027
|
+
targetInventory.batchId === batchId &&
|
|
1028
|
+
targetInventory.inventory.cartonId === cartonId &&
|
|
1029
|
+
targetInventory.productDetail.id === productDetail.id
|
|
1030
|
+
)
|
|
1020
1031
|
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1032
|
+
matchingProduct = await this.getDirectQty(
|
|
1033
|
+
{
|
|
1034
|
+
...productDetail,
|
|
1035
|
+
product
|
|
1036
|
+
},
|
|
1037
|
+
productBarcode,
|
|
1038
|
+
pickedQty
|
|
1028
1039
|
)
|
|
1029
1040
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
...productDetail,
|
|
1033
|
-
product
|
|
1034
|
-
},
|
|
1035
|
-
productBarcode,
|
|
1036
|
-
pickedQty
|
|
1037
|
-
)
|
|
1038
|
-
|
|
1039
|
-
//validate matching product details based on scanned barcode
|
|
1040
|
-
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
1041
|
-
|
|
1042
|
-
pickedQty = matchingProduct.qty
|
|
1043
|
-
|
|
1044
|
-
// // search for matching product barcode
|
|
1045
|
-
// const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
1046
|
-
// // scannedProductDetail can be child or gtin
|
|
1047
|
-
// const scannedProductDetail: ProductDetail = productDetails.find(detail => detail.gtin == productBarcode)
|
|
1048
|
-
// if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
1041
|
+
//validate matching product details based on scanned barcode
|
|
1042
|
+
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
1049
1043
|
|
|
1050
|
-
|
|
1051
|
-
// // when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
|
|
1052
|
-
// if (scannedProductDetail.id !== productDetail.id) {
|
|
1053
|
-
// let childQty = await this.getChildQty(productDetails, productBarcode, productDetail, scannedProductDetail)
|
|
1054
|
-
// pickedQty *= childQty
|
|
1055
|
-
// }
|
|
1044
|
+
pickedQty = matchingProduct.qty
|
|
1056
1045
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1046
|
+
const sumOfReleaseQty: number = targetInventories
|
|
1047
|
+
.map((oi: OrderInventory) => oi.releaseQty)
|
|
1048
|
+
.reduce((a, b) => a + b, 0)
|
|
1060
1049
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1050
|
+
const sumOfPickedQty: number =
|
|
1051
|
+
targetInventories.map((oi: OrderInventory) => oi.pickedQty).reduce((a, b) => a + b, 0) + pickedQty
|
|
1063
1052
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1053
|
+
if (sumOfPickedQty > sumOfReleaseQty)
|
|
1054
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
|
|
1066
1055
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1056
|
+
for (var i = 0; i < targetInventories.length; i++) {
|
|
1057
|
+
let targetInventory: OrderInventory = targetInventories[i]
|
|
1058
|
+
let inventory: Inventory = targetInventory.inventory
|
|
1059
|
+
const targetReleaseQty: number = targetInventory.releaseQty
|
|
1060
|
+
const targetPickedQty: number = targetInventory.pickedQty
|
|
1061
|
+
const releaseGood: ReleaseGood = targetInventory.releaseGood
|
|
1062
|
+
if (pickedQty <= 0) break
|
|
1063
|
+
|
|
1064
|
+
if (
|
|
1065
|
+
targetInventory.status === ORDER_INVENTORY_STATUS.PICKING &&
|
|
1066
|
+
targetReleaseQty > targetPickedQty &&
|
|
1067
|
+
pickedQty > 0
|
|
1068
|
+
) {
|
|
1069
|
+
let remainingAssignedQty: number = pickedQty - (targetReleaseQty - targetPickedQty) // -1, 0, 1
|
|
1070
|
+
const gapQtyRemaining: number = targetReleaseQty - targetPickedQty // > 0
|
|
1071
|
+
|
|
1072
|
+
if (binLocationName && !targetInventory?.binLocation) {
|
|
1073
|
+
const binLocation: Location = await this.trxMgr.getRepository(Location).findOne({
|
|
1074
|
+
where: { domain: this.domain, name: binLocationName, type: LOCATION_TYPE.BIN }
|
|
1075
|
+
})
|
|
1074
1076
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
targetReleaseQty > targetPickedQty &&
|
|
1078
|
-
pickedQty > 0
|
|
1079
|
-
) {
|
|
1080
|
-
let remainingAssignedQty: number = pickedQty - (targetReleaseQty - targetPickedQty) // -1, 0, 1
|
|
1081
|
-
const gapQtyRemaining: number = targetReleaseQty - targetPickedQty // > 0
|
|
1082
|
-
|
|
1083
|
-
if (binLocationName && !targetInventory?.binLocation) {
|
|
1084
|
-
const binLocation: Location = await this.trxMgr.getRepository(Location).findOne({
|
|
1085
|
-
where: { domain: this.domain, name: binLocationName, type: LOCATION_TYPE.BIN }
|
|
1086
|
-
})
|
|
1077
|
+
if (!binLocation)
|
|
1078
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`))
|
|
1087
1079
|
|
|
1088
|
-
|
|
1089
|
-
|
|
1080
|
+
targetInventory.binLocation = binLocation
|
|
1081
|
+
}
|
|
1090
1082
|
|
|
1091
|
-
|
|
1092
|
-
|
|
1083
|
+
// pickedQty = 1, gap = 5 || pickedQty = 12, gap = 5 || pickedQty = 5, gap = 5
|
|
1084
|
+
targetInventory.pickedQty += pickedQty > gapQtyRemaining ? gapQtyRemaining : pickedQty
|
|
1085
|
+
remainingAssignedQty = remainingAssignedQty < 0 ? 0 : remainingAssignedQty
|
|
1093
1086
|
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1087
|
+
if (targetInventory.pickedQty == targetReleaseQty) {
|
|
1088
|
+
const leftQty: number = inventory.qty - targetInventory.releaseQty
|
|
1089
|
+
if (leftQty < 0) {
|
|
1090
|
+
throw new Error(
|
|
1091
|
+
this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`)
|
|
1092
|
+
)
|
|
1093
|
+
}
|
|
1097
1094
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
if (leftQty < 0) {
|
|
1101
|
-
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
|
|
1102
|
-
}
|
|
1095
|
+
targetInventory.status = ORDER_INVENTORY_STATUS.PICKED
|
|
1096
|
+
await this.updateOrderTargets([targetInventory])
|
|
1103
1097
|
|
|
1104
|
-
|
|
1105
|
-
|
|
1098
|
+
inventory.qty -= targetInventory.releaseQty
|
|
1099
|
+
inventory.uomValue = Math.round((inventory.uomValue - targetInventory.releaseUomValue) * 100) / 100
|
|
1100
|
+
inventory.lockedQty = inventory.lockedQty - targetInventory.releaseQty
|
|
1101
|
+
inventory.lockedUomValue =
|
|
1102
|
+
Math.round((inventory.lockedUomValue - targetInventory.releaseUomValue) * 100) / 100
|
|
1103
|
+
await this.transactionInventory(
|
|
1104
|
+
inventory,
|
|
1105
|
+
releaseGood,
|
|
1106
|
+
-targetInventory.releaseQty,
|
|
1107
|
+
-targetInventory.releaseUomValue,
|
|
1108
|
+
INVENTORY_TRANSACTION_TYPE.PICKING
|
|
1109
|
+
)
|
|
1106
1110
|
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
Math.round((inventory.lockedUomValue - targetInventory.releaseUomValue) * 100) / 100
|
|
1112
|
-
await this.transactionInventory(
|
|
1113
|
-
inventory,
|
|
1114
|
-
releaseGood,
|
|
1115
|
-
-targetInventory.releaseQty,
|
|
1116
|
-
-targetInventory.releaseUomValue,
|
|
1117
|
-
INVENTORY_TRANSACTION_TYPE.PICKING
|
|
1118
|
-
)
|
|
1111
|
+
if (leftQty === 0) {
|
|
1112
|
+
inventory.status = INVENTORY_STATUS.TERMINATED
|
|
1113
|
+
await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
|
|
1114
|
+
}
|
|
1119
1115
|
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1116
|
+
let worksheetDetail: WorksheetDetail = worksheetDetails.find(
|
|
1117
|
+
(wsd: WorksheetDetail) => wsd.targetInventory.id === targetInventory.id
|
|
1118
|
+
)
|
|
1119
|
+
worksheetDetail.status = WORKSHEET_STATUS.DONE
|
|
1120
|
+
worksheetDetail.updater = this.user
|
|
1121
|
+
await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
1122
|
+
} else {
|
|
1123
|
+
await this.updateOrderTargets([targetInventory])
|
|
1123
1124
|
}
|
|
1124
|
-
|
|
1125
|
-
let worksheetDetail: WorksheetDetail = worksheetDetails.find(
|
|
1126
|
-
(wsd: WorksheetDetail) => wsd.targetInventory.id === targetInventory.id
|
|
1127
|
-
)
|
|
1128
|
-
worksheetDetail.status = WORKSHEET_STATUS.DONE
|
|
1129
|
-
worksheetDetail.updater = this.user
|
|
1130
|
-
await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
1131
|
-
} else {
|
|
1132
|
-
await this.updateOrderTargets([targetInventory])
|
|
1125
|
+
pickedQty = pickedQty - (targetReleaseQty - targetPickedQty)
|
|
1133
1126
|
}
|
|
1134
|
-
pickedQty = pickedQty - (targetReleaseQty - targetPickedQty)
|
|
1135
1127
|
}
|
|
1128
|
+
} catch (error) {
|
|
1129
|
+
logger.error(`picking-worksheet-controller[scanProductBatchPicking]: ${error}`)
|
|
1130
|
+
throw new Error(error)
|
|
1131
|
+
} finally {
|
|
1132
|
+
console.timeEnd(`scanProductBatchPicking:${taskNo}`)
|
|
1136
1133
|
}
|
|
1137
1134
|
}
|
|
1138
1135
|
|
|
@@ -1437,7 +1434,9 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1437
1434
|
await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.ild)
|
|
1438
1435
|
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1439
1436
|
}
|
|
1440
|
-
} catch (e) {
|
|
1437
|
+
} catch (e) {
|
|
1438
|
+
logger.error(`picking-worksheet-controller[serialNumberReplacementForExistingOrderInv]: ${e}`)
|
|
1439
|
+
}
|
|
1441
1440
|
}
|
|
1442
1441
|
|
|
1443
1442
|
private async serialNumberReplacement(
|
|
@@ -1554,7 +1553,9 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1554
1553
|
await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.id)
|
|
1555
1554
|
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1556
1555
|
}
|
|
1557
|
-
} catch (e) {
|
|
1556
|
+
} catch (e) {
|
|
1557
|
+
logger.error(`picking-worksheet-controller[serialNumberReplacement]: ${e}`)
|
|
1558
|
+
}
|
|
1558
1559
|
}
|
|
1559
1560
|
|
|
1560
1561
|
private async toteScanning(toteNo, targetProduct, targetInventory, pickedQty, releaseGood, bizplace) {
|