@things-factory/worksheet-base 4.3.82 → 4.3.83
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 +49 -49
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js +4 -2
- package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/loading-worksheet-controller.js +4 -10
- package/dist-server/controllers/outbound/loading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/packing-worksheet-controller.js +20 -22
- package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/picking-worksheet-controller.js +151 -71
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/sorting-worksheet-controller.js +14 -12
- package/dist-server/controllers/outbound/sorting-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/vas/vas-worksheet-controller.js +2 -1
- package/dist-server/controllers/vas/vas-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/worksheet-controller.js +37 -2
- package/dist-server/controllers/worksheet-controller.js.map +1 -1
- package/dist-server/entities/worksheet-detail.js +2 -1
- package/dist-server/entities/worksheet-detail.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/batch-picking-worksheet.js +0 -6
- package/dist-server/graphql/resolvers/worksheet/batch-picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/confirm-cancellation-release-order.js +2 -1
- package/dist-server/graphql/resolvers/worksheet/confirm-cancellation-release-order.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/cycle-count-adjustment.js +6 -6
- package/dist-server/graphql/resolvers/worksheet/cycle-count-adjustment.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +1 -2
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js +28 -67
- package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/activate-packing.js +8 -23
- package/dist-server/graphql/resolvers/worksheet/packing/activate-packing.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/complete-packing.js +7 -30
- package/dist-server/graphql/resolvers/worksheet/packing/complete-packing.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/packing.js +8 -23
- package/dist-server/graphql/resolvers/worksheet/packing/packing.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js +8 -25
- package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +12 -59
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/activate-picking.js +25 -51
- package/dist-server/graphql/resolvers/worksheet/picking/activate-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js +2 -2
- package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +118 -262
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/scan-product-picking.js +4 -7
- package/dist-server/graphql/resolvers/worksheet/picking/scan-product-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js +2 -3
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/proceed-extra-products.js +4 -6
- package/dist-server/graphql/resolvers/worksheet/proceed-extra-products.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/putaway/complete-putaway.js +14 -39
- package/dist-server/graphql/resolvers/worksheet/putaway/complete-putaway.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/transfer.js +9 -9
- package/dist-server/graphql/resolvers/worksheet/transfer.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/vas-transactions/common-utils.js +17 -17
- package/dist-server/graphql/resolvers/worksheet/vas-transactions/common-utils.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js +4 -4
- package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js.map +1 -1
- package/dist-server/graphql/types/worksheet-detail/index.js +0 -1
- package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
- package/dist-server/utils/inventory-util.js +98 -1
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +17 -17
- package/server/controllers/inbound/unloading-worksheet-controller.ts +70 -49
- package/server/controllers/inspect/cycle-count-worksheet-controller.ts +4 -2
- package/server/controllers/outbound/loading-worksheet-controller.ts +3 -9
- package/server/controllers/outbound/packing-worksheet-controller.ts +31 -23
- package/server/controllers/outbound/picking-worksheet-controller.ts +212 -85
- package/server/controllers/outbound/sorting-worksheet-controller.ts +12 -12
- package/server/controllers/vas/vas-worksheet-controller.ts +2 -2
- package/server/controllers/worksheet-controller.ts +49 -5
- package/server/entities/worksheet-detail.ts +5 -0
- package/server/graphql/resolvers/worksheet/batch-picking-worksheet.ts +0 -6
- package/server/graphql/resolvers/worksheet/confirm-cancellation-release-order.ts +2 -1
- package/server/graphql/resolvers/worksheet/cycle-count-adjustment.ts +2 -2
- package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +1 -3
- package/server/graphql/resolvers/worksheet/loading/complete-loading.ts +33 -77
- package/server/graphql/resolvers/worksheet/packing/activate-packing.ts +9 -26
- package/server/graphql/resolvers/worksheet/packing/complete-packing.ts +9 -34
- package/server/graphql/resolvers/worksheet/packing/packing.ts +9 -26
- package/server/graphql/resolvers/worksheet/packing/scan-product-packing.ts +9 -28
- package/server/graphql/resolvers/worksheet/packing-worksheet.ts +13 -68
- package/server/graphql/resolvers/worksheet/picking/activate-picking.ts +30 -60
- package/server/graphql/resolvers/worksheet/picking/complete-batch-picking.ts +2 -2
- package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +130 -288
- package/server/graphql/resolvers/worksheet/picking/scan-product-picking.ts +10 -30
- package/server/graphql/resolvers/worksheet/picking-worksheet.ts +2 -3
- package/server/graphql/resolvers/worksheet/proceed-extra-products.ts +4 -5
- package/server/graphql/resolvers/worksheet/putaway/complete-putaway.ts +15 -45
- package/server/graphql/resolvers/worksheet/transfer.ts +16 -18
- package/server/graphql/resolvers/worksheet/vas-transactions/common-utils.ts +2 -3
- package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts +1 -4
- package/server/graphql/types/worksheet-detail/index.ts +0 -1
- package/server/utils/inventory-util.ts +126 -1
|
@@ -93,15 +93,13 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
93
93
|
'targetInventory.releaseGood',
|
|
94
94
|
'targetInventory.inventory',
|
|
95
95
|
'targetInventory.inventory.location',
|
|
96
|
-
'targetInventory.product'
|
|
97
|
-
'targetInventory.productDetail'
|
|
96
|
+
'targetInventory.product'
|
|
98
97
|
]
|
|
99
98
|
)
|
|
100
|
-
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
101
|
-
let inventory: Inventory = targetInventory.inventory
|
|
102
99
|
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
100
|
+
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
103
101
|
const product: Product = targetInventory.product
|
|
104
|
-
|
|
102
|
+
let inventory: Inventory = targetInventory.inventory
|
|
105
103
|
const pickedQty: number = targetInventory.releaseQty
|
|
106
104
|
|
|
107
105
|
if (packedQty > pickedQty) {
|
|
@@ -116,7 +114,8 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
116
114
|
}
|
|
117
115
|
|
|
118
116
|
let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
119
|
-
where: { domain: this.domain, serialNumber: serialNumber,
|
|
117
|
+
where: { domain: this.domain, serialNumber: serialNumber, product },
|
|
118
|
+
relations: ['product', 'inventory']
|
|
120
119
|
})
|
|
121
120
|
|
|
122
121
|
if (foundSerialNumber) {
|
|
@@ -140,7 +139,6 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
140
139
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
141
140
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
142
141
|
inventoryItem.product = product
|
|
143
|
-
inventoryItem.productDetail = productDetail
|
|
144
142
|
inventoryItem.inventory = inventory
|
|
145
143
|
inventoryItem.domain = this.domain
|
|
146
144
|
|
|
@@ -196,28 +194,39 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
196
194
|
'targetInventory.inventory.product',
|
|
197
195
|
'targetInventory.inventory.product.productDetails',
|
|
198
196
|
'targetInventory.inventory.product.productDetails.childProductDetail',
|
|
199
|
-
'targetInventory.inventory.location'
|
|
200
|
-
'targetInventory.productDetail'
|
|
197
|
+
'targetInventory.inventory.location'
|
|
201
198
|
]
|
|
202
199
|
)
|
|
200
|
+
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
201
|
+
const product: Product = worksheetDetail.targetInventory.inventory.product
|
|
202
|
+
const filterProductDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
203
203
|
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
204
204
|
let inventory: Inventory = targetInventory.inventory
|
|
205
205
|
let packedQty: number = 1
|
|
206
206
|
let pickedQty: number = targetInventory.releaseQty
|
|
207
|
-
const releaseGood: ReleaseGood = targetInventory.releaseGood
|
|
208
|
-
const product: Product = targetInventory.inventory.product
|
|
209
|
-
const productDetail: ProductDetail = targetInventory.productDetail
|
|
210
207
|
|
|
211
208
|
// search for matching product barcode
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
209
|
+
const productDetail: ProductDetail = product?.productDetails
|
|
210
|
+
.filter(detail => !detail.deletedAt)
|
|
211
|
+
.find(
|
|
212
|
+
detail =>
|
|
213
|
+
detail.gtin === productBarcode &&
|
|
214
|
+
detail.packingType === inventory.packingType &&
|
|
215
|
+
detail.packingSize === inventory.packingSize
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
if (!productDetail && !product?.isRequireSerialNumberScanningOutbound) {
|
|
219
|
+
let roProductDetail: ProductDetail = product?.productDetails.find(
|
|
220
|
+
(parentDetail: ProductDetail) =>
|
|
221
|
+
parentDetail.packingType === inventory.packingType && parentDetail.packingSize == inventory.packingSize
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
roProductDetail.product = product
|
|
225
|
+
|
|
226
|
+
let childQty = await this.getChildQty(filterProductDetails, productBarcode, roProductDetail)
|
|
227
|
+
packedQty *= childQty
|
|
228
|
+
} else if (!productDetail) {
|
|
229
|
+
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
221
230
|
}
|
|
222
231
|
|
|
223
232
|
if (packedQty + targetInventory.packedQty > pickedQty) {
|
|
@@ -233,7 +242,7 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
233
242
|
|
|
234
243
|
let foundSerialNumber: InventoryItem = await this.trxMgr
|
|
235
244
|
.getRepository(InventoryItem)
|
|
236
|
-
.findOne({ where: { domain: this.domain, serialNumber: serialNumber,
|
|
245
|
+
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
|
|
237
246
|
|
|
238
247
|
if (foundSerialNumber) {
|
|
239
248
|
if (foundSerialNumber.inventoryId !== inventory.id) {
|
|
@@ -260,7 +269,6 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
260
269
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
261
270
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
262
271
|
inventoryItem.product = product
|
|
263
|
-
inventoryItem.productDetail = productDetail
|
|
264
272
|
inventoryItem.inventory = inventory
|
|
265
273
|
inventoryItem.domain = this.domain
|
|
266
274
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Equal, In, IsNull, Not
|
|
1
|
+
import { EntityManager, Equal, getConnection, In, IsNull, Not } from 'typeorm'
|
|
2
2
|
|
|
3
3
|
import { Bizplace } from '@things-factory/biz-base'
|
|
4
4
|
import { generateId } from '@things-factory/id-rule-base'
|
|
5
5
|
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
6
|
-
import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
|
|
7
|
-
import { logger } from '@things-factory/env'
|
|
8
6
|
import {
|
|
7
|
+
GenerateBatchPickInfo,
|
|
9
8
|
ORDER_INVENTORY_STATUS,
|
|
10
9
|
ORDER_PRODUCT_STATUS,
|
|
11
10
|
ORDER_STATUS,
|
|
@@ -16,8 +15,7 @@ import {
|
|
|
16
15
|
OrderToteItem,
|
|
17
16
|
OrderToteSeal,
|
|
18
17
|
OrderVas,
|
|
19
|
-
ReleaseGood
|
|
20
|
-
GenerateBatchPickInfo
|
|
18
|
+
ReleaseGood
|
|
21
19
|
} from '@things-factory/sales-base'
|
|
22
20
|
import { Setting } from '@things-factory/setting-base'
|
|
23
21
|
import {
|
|
@@ -35,9 +33,8 @@ import {
|
|
|
35
33
|
|
|
36
34
|
import { TASK_NUMBER_RULE_TYPE, TASK_NUMBER_SETTING_KEY, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
|
|
37
35
|
import { Worksheet, WorksheetDetail } from '../../entities'
|
|
38
|
-
import { WorksheetNoGenerator } from '../../utils'
|
|
36
|
+
import { generateInventoryHistory, WorksheetNoGenerator } from '../../utils'
|
|
39
37
|
import { VasWorksheetController } from '../vas/vas-worksheet-controller'
|
|
40
|
-
import { SellercraftController } from '../../controllers'
|
|
41
38
|
|
|
42
39
|
export class PickingWorksheetController extends VasWorksheetController {
|
|
43
40
|
async generatePickingWorksheet(releaseGoodNo: string, currentStatus: string = null): Promise<Worksheet> {
|
|
@@ -419,69 +416,74 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
419
416
|
binLocation?: string,
|
|
420
417
|
serialNumber?: string,
|
|
421
418
|
toteNo?: string,
|
|
422
|
-
|
|
423
|
-
): Promise<
|
|
419
|
+
pickedQty: number = 1
|
|
420
|
+
): Promise<WorksheetDetail> {
|
|
424
421
|
try {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
'
|
|
438
|
-
'
|
|
439
|
-
'
|
|
440
|
-
|
|
441
|
-
|
|
422
|
+
//find existing worksheet detail
|
|
423
|
+
let worksheetDetail: WorksheetDetail = await this.trxMgr
|
|
424
|
+
.getRepository(WorksheetDetail)
|
|
425
|
+
.createQueryBuilder('wd')
|
|
426
|
+
.innerJoinAndSelect('wd.worksheet', 'ws')
|
|
427
|
+
.innerJoinAndSelect('ws.bizplace', 'bz')
|
|
428
|
+
.innerJoinAndSelect('wd.targetInventory', 'oi')
|
|
429
|
+
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
430
|
+
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
431
|
+
.leftJoinAndSelect('oi.orderProduct', 'op')
|
|
432
|
+
.innerJoinAndSelect('oi.product', 'prd')
|
|
433
|
+
.leftJoinAndSelect(
|
|
434
|
+
'prd.productDetails',
|
|
435
|
+
'pd',
|
|
436
|
+
'pd.product_id = oi.product_id AND pd.deleted_at is null AND pd.packing_type = oi.packing_type AND pd.packing_size = oi.packing_size AND pd.uom = oi.uom'
|
|
437
|
+
)
|
|
438
|
+
.where('wd.name = :name', { name: worksheetDetailName })
|
|
439
|
+
.andWhere('wd.domain_id = :domainId', { domainId: this.domain.id })
|
|
440
|
+
.andWhere('wd.type = :type', { type: worksheetType })
|
|
441
|
+
.andWhere('wd.status = :status', { status: WORKSHEET_STATUS.EXECUTING })
|
|
442
|
+
.andWhere('inv.carton_id = :cartonId', { cartonId: cartonId })
|
|
443
|
+
.getOne()
|
|
442
444
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
const product: Product = targetInventory.product
|
|
447
|
-
const productDetail: ProductDetail = targetInventory.productDetail
|
|
448
|
-
let inventory: Inventory = targetInventory.inventory
|
|
449
|
-
let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
|
|
445
|
+
//validation to check matching worksheet detail based on name
|
|
446
|
+
if (!worksheetDetail || !worksheetDetail.targetInventory)
|
|
447
|
+
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
|
|
450
448
|
|
|
451
449
|
//validation to prevent duplicated picking
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
})
|
|
455
|
-
if (!oiValidate) throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`))
|
|
450
|
+
if (worksheetDetail?.targetInventory?.status != ORDER_INVENTORY_STATUS.PICKING)
|
|
451
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`))
|
|
456
452
|
|
|
457
|
-
|
|
458
|
-
|
|
453
|
+
let matchingProduct = await this.getDirectQty(
|
|
454
|
+
{
|
|
455
|
+
...worksheetDetail?.targetInventory?.product?.productDetails[0],
|
|
456
|
+
product: worksheetDetail?.targetInventory?.product
|
|
457
|
+
},
|
|
458
|
+
productBarcode,
|
|
459
|
+
pickedQty
|
|
460
|
+
)
|
|
459
461
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
+
//validate matching product details based on scanned barcode
|
|
463
|
+
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
462
464
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
+
pickedQty = matchingProduct.qty
|
|
466
|
+
let pickedUomValue = matchingProduct.uomValue
|
|
465
467
|
|
|
466
|
-
|
|
468
|
+
//validation to prevent over release
|
|
469
|
+
if (
|
|
470
|
+
!worksheetDetail?.targetInventory ||
|
|
471
|
+
worksheetDetail?.targetInventory.inventory.qty < 1 ||
|
|
472
|
+
pickedQty + (worksheetDetail.targetInventory?.pickedQty || 0) > worksheetDetail.targetInventory.releaseQty
|
|
473
|
+
)
|
|
474
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
467
475
|
|
|
468
|
-
|
|
469
|
-
const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
470
|
-
// scannedProductDetail can be child or gtin
|
|
471
|
-
const scannedProductDetail: ProductDetail = productDetails.find(detail => detail.gtin == productBarcode)
|
|
472
|
-
if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
473
|
-
|
|
474
|
-
// case for scanning parent packing type, packing size
|
|
475
|
-
// when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
|
|
476
|
-
if (scannedProductDetail.id !== productDetail.id && !product?.isRequireSerialNumberScanningOutbound) {
|
|
477
|
-
let childQty = await this.getChildQty(productDetails, productBarcode, productDetail, scannedProductDetail)
|
|
478
|
-
pickedQty *= childQty
|
|
479
|
-
}
|
|
476
|
+
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
480
477
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
478
|
+
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
479
|
+
let targetProduct: OrderProduct = targetInventory.orderProduct
|
|
480
|
+
let inventory: Inventory = targetInventory.inventory
|
|
481
|
+
let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
|
|
482
|
+
const product: Product = targetInventory.product
|
|
483
|
+
|
|
484
|
+
targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
|
|
484
485
|
|
|
486
|
+
// for required outbound serial number scanning
|
|
485
487
|
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
486
488
|
if (!serialNumber || serialNumber == '') {
|
|
487
489
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`))
|
|
@@ -527,7 +529,6 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
527
529
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
528
530
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
529
531
|
inventoryItem.product = product
|
|
530
|
-
inventoryItem.productDetail = productDetail
|
|
531
532
|
inventoryItem.inventory = inventory
|
|
532
533
|
inventoryItem.domain = this.domain
|
|
533
534
|
|
|
@@ -535,11 +536,133 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
535
536
|
}
|
|
536
537
|
}
|
|
537
538
|
|
|
539
|
+
// for tote scanning
|
|
538
540
|
if (toteNo) {
|
|
539
541
|
await this.toteScanning(toteNo, targetProduct, targetInventory, pickedQty, releaseGood, bizplace)
|
|
540
542
|
}
|
|
541
543
|
|
|
542
|
-
|
|
544
|
+
// temporarily override with separate logic to handle transaction to speed up function
|
|
545
|
+
// await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
|
|
546
|
+
|
|
547
|
+
const releaseQty: number = targetInventory.releaseQty
|
|
548
|
+
|
|
549
|
+
targetInventory.pickedQty = (targetInventory?.pickedQty || 0) + pickedQty
|
|
550
|
+
|
|
551
|
+
let updateOiObj = {
|
|
552
|
+
pickedQty: () => `"picked_qty" + ${pickedQty}`,
|
|
553
|
+
updatedAt: new Date(),
|
|
554
|
+
updater: this.user,
|
|
555
|
+
pickedBy: this.user.name,
|
|
556
|
+
pickedByUser: this.user,
|
|
557
|
+
pickedAt: new Date()
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (targetInventory.pickedQty == releaseQty) {
|
|
561
|
+
updateOiObj['status'] = ORDER_INVENTORY_STATUS.PICKED
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
await this.trxMgr
|
|
565
|
+
.getRepository(OrderInventory)
|
|
566
|
+
.createQueryBuilder()
|
|
567
|
+
.update(OrderInventory)
|
|
568
|
+
.set(updateOiObj)
|
|
569
|
+
.where({ id: targetInventory.id })
|
|
570
|
+
.andWhere(`picked_qty + :pickedQty <= release_qty`, { pickedQty })
|
|
571
|
+
.execute()
|
|
572
|
+
|
|
573
|
+
if (targetInventory.pickedQty == releaseQty) {
|
|
574
|
+
//update worksheet details only when line item picking complete
|
|
575
|
+
await this.trxMgr
|
|
576
|
+
.getRepository(WorksheetDetail)
|
|
577
|
+
.createQueryBuilder()
|
|
578
|
+
.update(WorksheetDetail)
|
|
579
|
+
.set({
|
|
580
|
+
status: WORKSHEET_STATUS.DONE,
|
|
581
|
+
updater: this.user,
|
|
582
|
+
updatedAt: new Date()
|
|
583
|
+
})
|
|
584
|
+
.where('id = :id', { id: worksheetDetail.id })
|
|
585
|
+
.execute()
|
|
586
|
+
|
|
587
|
+
getConnection().transaction(async (tx: EntityManager) => {
|
|
588
|
+
let releaseUomValue = Math.round((pickedUomValue / pickedQty) * releaseQty * 100) / 100
|
|
589
|
+
|
|
590
|
+
let updateInvObj = {
|
|
591
|
+
qty: () => `"qty" - ${releaseQty}`,
|
|
592
|
+
lockedQty: () => `"locked_qty" - ${releaseQty}`,
|
|
593
|
+
uomValue: () => `"uom_value" - ${releaseUomValue}`,
|
|
594
|
+
lockedUomValue: () => `"locked_uom_value" - ${releaseUomValue}`,
|
|
595
|
+
updater: this.user,
|
|
596
|
+
updatedAt: new Date()
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
let remainingQty = await tx
|
|
600
|
+
.getRepository(Inventory)
|
|
601
|
+
.createQueryBuilder()
|
|
602
|
+
.update(Inventory)
|
|
603
|
+
.set(updateInvObj)
|
|
604
|
+
.where('id = :id', { id: targetInventory.inventory.id })
|
|
605
|
+
.returning(['qty'])
|
|
606
|
+
.execute()
|
|
607
|
+
.then(dt => {
|
|
608
|
+
return dt.raw[0].qty
|
|
609
|
+
})
|
|
610
|
+
|
|
611
|
+
await generateInventoryHistory(
|
|
612
|
+
inventory,
|
|
613
|
+
releaseGood,
|
|
614
|
+
INVENTORY_TRANSACTION_TYPE.PICKING,
|
|
615
|
+
-releaseQty,
|
|
616
|
+
-releaseUomValue,
|
|
617
|
+
this.user,
|
|
618
|
+
tx
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
let inventoryItems: InventoryItem = await tx
|
|
622
|
+
.getRepository(InventoryItem)
|
|
623
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
624
|
+
|
|
625
|
+
if (inventoryItems.length > 0) {
|
|
626
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
627
|
+
itm.status = INVENTORY_STATUS.PICKED
|
|
628
|
+
itm.updater = this.user
|
|
629
|
+
})
|
|
630
|
+
|
|
631
|
+
await tx.getRepository(InventoryItem).save(inventoryItems)
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
if (remainingQty === 0) {
|
|
635
|
+
await tx
|
|
636
|
+
.getRepository(Inventory)
|
|
637
|
+
.createQueryBuilder()
|
|
638
|
+
.update(Inventory)
|
|
639
|
+
.set({ status: INVENTORY_STATUS.TERMINATED })
|
|
640
|
+
.where('id = :id', { id: targetInventory.inventory.id })
|
|
641
|
+
.execute()
|
|
642
|
+
|
|
643
|
+
await generateInventoryHistory(
|
|
644
|
+
inventory,
|
|
645
|
+
releaseGood,
|
|
646
|
+
INVENTORY_TRANSACTION_TYPE.TERMINATED,
|
|
647
|
+
0,
|
|
648
|
+
0,
|
|
649
|
+
this.user,
|
|
650
|
+
tx
|
|
651
|
+
)
|
|
652
|
+
}
|
|
653
|
+
})
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// return worksheet details
|
|
657
|
+
worksheetDetail = await this.trxMgr
|
|
658
|
+
.getRepository(WorksheetDetail)
|
|
659
|
+
.createQueryBuilder('wd')
|
|
660
|
+
.innerJoin('wd.targetInventory', 'oi')
|
|
661
|
+
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
662
|
+
.where('wd.id = :id', { id: worksheetDetail.id })
|
|
663
|
+
.getOne()
|
|
664
|
+
|
|
665
|
+
return worksheetDetail
|
|
543
666
|
} catch (error) {
|
|
544
667
|
throw error
|
|
545
668
|
}
|
|
@@ -567,15 +690,13 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
567
690
|
'targetInventory.orderProduct',
|
|
568
691
|
'targetInventory.inventory',
|
|
569
692
|
'targetInventory.inventory.location',
|
|
570
|
-
'targetInventory.product'
|
|
571
|
-
'targetInventory.productDetail'
|
|
693
|
+
'targetInventory.product'
|
|
572
694
|
]
|
|
573
695
|
)
|
|
574
696
|
|
|
575
697
|
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
576
698
|
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
577
699
|
const product: Product = targetInventory.product
|
|
578
|
-
const productDetail: ProductDetail = targetInventory.productDetail
|
|
579
700
|
let inventory: Inventory = targetInventory.inventory
|
|
580
701
|
let targetProduct: OrderProduct = targetInventory.orderProduct
|
|
581
702
|
let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
|
|
@@ -605,13 +726,13 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
605
726
|
})
|
|
606
727
|
|
|
607
728
|
let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
608
|
-
where: { domain: this.domain, serialNumber: serialNumber,
|
|
609
|
-
relations: ['product', '
|
|
729
|
+
where: { domain: this.domain, serialNumber: serialNumber, product },
|
|
730
|
+
relations: ['product', 'inventory']
|
|
610
731
|
})
|
|
611
732
|
|
|
612
733
|
let scannedPalletIdInventory: Inventory = await this.trxMgr
|
|
613
734
|
.getRepository(Inventory)
|
|
614
|
-
.findOne({ where: { domain: this.domain, palletId }, relations: ['
|
|
735
|
+
.findOne({ where: { domain: this.domain, palletId }, relations: ['product'] })
|
|
615
736
|
|
|
616
737
|
if (foundSerialNumber) {
|
|
617
738
|
if (foundSerialNumber.outboundOrderId) {
|
|
@@ -638,7 +759,6 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
638
759
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
639
760
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
640
761
|
inventoryItem.product = product
|
|
641
|
-
inventoryItem.productDetail = productDetail
|
|
642
762
|
inventoryItem.inventory = scannedPalletIdInventory
|
|
643
763
|
inventoryItem.domain = this.domain
|
|
644
764
|
|
|
@@ -664,7 +784,8 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
664
784
|
)
|
|
665
785
|
} else if (
|
|
666
786
|
scannedPalletIdInventory.batchId == inventory.batchId &&
|
|
667
|
-
scannedPalletIdInventory.
|
|
787
|
+
scannedPalletIdInventory.product.id == product.id &&
|
|
788
|
+
scannedPalletIdInventory.product.packingType == product.packingType
|
|
668
789
|
) {
|
|
669
790
|
//if replacement order inventory does not exist
|
|
670
791
|
await this.serialNumberReplacement(
|
|
@@ -672,7 +793,6 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
672
793
|
scannedPalletIdInventory,
|
|
673
794
|
releaseGood,
|
|
674
795
|
product,
|
|
675
|
-
productDetail,
|
|
676
796
|
worksheetDetail,
|
|
677
797
|
foundSerialNumber
|
|
678
798
|
)
|
|
@@ -848,19 +968,16 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
848
968
|
'worksheetDetails.targetInventory.releaseGood',
|
|
849
969
|
'worksheetDetails.targetInventory.inventory',
|
|
850
970
|
'worksheetDetails.targetInventory.inventory.location',
|
|
851
|
-
'worksheetDetails.targetInventory.
|
|
852
|
-
'worksheetDetails.targetInventory.productDetail.product',
|
|
971
|
+
'worksheetDetails.targetInventory.product',
|
|
853
972
|
'worksheetDetails.targetInventory.product.productDetails',
|
|
854
973
|
'worksheetDetails.targetInventory.product.productDetails.childProductDetail'
|
|
855
974
|
]
|
|
856
975
|
})
|
|
857
976
|
|
|
858
977
|
const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
|
|
859
|
-
const
|
|
978
|
+
const product: Product = worksheetDetails
|
|
860
979
|
.map((wsd: WorksheetDetail) => wsd.targetInventory.product)
|
|
861
|
-
.find((
|
|
862
|
-
|
|
863
|
-
const product: Product = productDetail.product
|
|
980
|
+
.find((product: Product) => product.id === inventory.product.id)
|
|
864
981
|
|
|
865
982
|
const batchId: string = inventory.batchId
|
|
866
983
|
const packingType: string = inventory.packingType
|
|
@@ -879,14 +996,26 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
879
996
|
|
|
880
997
|
// search for matching product barcode
|
|
881
998
|
const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
999
|
+
const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
|
|
1000
|
+
if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(`GTIN (${productBarcode})`))
|
|
885
1001
|
|
|
886
1002
|
// case for scanning parent packing type, packing size
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
1003
|
+
const foundProductDetail: ProductDetail = productDetails.find(
|
|
1004
|
+
(detail: ProductDetail) =>
|
|
1005
|
+
detail.gtin === productBarcode && detail.packingType === packingType && detail.packingSize == packingSize
|
|
1006
|
+
)
|
|
1007
|
+
|
|
1008
|
+
if (!foundProductDetail) {
|
|
1009
|
+
const roProductDetail: ProductDetail = productDetails.find(
|
|
1010
|
+
(parentDetail: ProductDetail) =>
|
|
1011
|
+
parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
|
|
1012
|
+
)
|
|
1013
|
+
if (!roProductDetail)
|
|
1014
|
+
throw new Error(
|
|
1015
|
+
this.ERROR_MSG.FIND.NO_RESULT(`Packing Type ( ${packingType}) or Packing Size (${packingSize})`)
|
|
1016
|
+
)
|
|
1017
|
+
|
|
1018
|
+
let childQty = await this.getChildQty(productDetails, productBarcode, roProductDetail)
|
|
890
1019
|
pickedQty *= childQty
|
|
891
1020
|
}
|
|
892
1021
|
|
|
@@ -1121,7 +1250,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1121
1250
|
private async updatePickingTransaction(releaseGood, orderInventory, worksheetDetail, inventory, pickedQty) {
|
|
1122
1251
|
const releaseQty: number = orderInventory.releaseQty
|
|
1123
1252
|
|
|
1124
|
-
orderInventory.pickedQty =
|
|
1253
|
+
orderInventory.pickedQty = (orderInventory?.pickedQty || 0) + pickedQty
|
|
1125
1254
|
if (orderInventory.pickedQty == releaseQty) {
|
|
1126
1255
|
const leftQty: number = inventory.qty - releaseQty
|
|
1127
1256
|
if (leftQty < 0) {
|
|
@@ -1281,7 +1410,6 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1281
1410
|
scannedPalletIdInventory,
|
|
1282
1411
|
releaseGood,
|
|
1283
1412
|
product,
|
|
1284
|
-
productDetail,
|
|
1285
1413
|
worksheetDetail,
|
|
1286
1414
|
foundSerialNumber
|
|
1287
1415
|
) {
|
|
@@ -1346,7 +1474,6 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1346
1474
|
releaseUomValue: newOrderInventoryReleaseUomValue,
|
|
1347
1475
|
pickedQty: 1,
|
|
1348
1476
|
product,
|
|
1349
|
-
productDetail,
|
|
1350
1477
|
inventory: scannedPalletIdInventory,
|
|
1351
1478
|
creator: this.user,
|
|
1352
1479
|
updater: this.user
|
|
@@ -95,8 +95,7 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
95
95
|
'worksheetDetails.targetInventory.inventory.product',
|
|
96
96
|
'worksheetDetails.targetInventory.inventory.product.productDetails',
|
|
97
97
|
'worksheetDetails.targetInventory.inventory.product.productDetails.product',
|
|
98
|
-
'worksheetDetails.targetInventory.releaseGood'
|
|
99
|
-
'worksheetDetails.targetInventory.productDetail'
|
|
98
|
+
'worksheetDetails.targetInventory.releaseGood'
|
|
100
99
|
]
|
|
101
100
|
})
|
|
102
101
|
|
|
@@ -119,12 +118,17 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
119
118
|
const matchingProductDetail: ProductDetail = productDetails.find(
|
|
120
119
|
(productDetail: ProductDetail) => productDetail.gtin === productBarcode
|
|
121
120
|
)
|
|
122
|
-
if (!matchingProductDetail) throw new Error(
|
|
121
|
+
if (!matchingProductDetail) throw new Error('Unable to find product barcode.')
|
|
123
122
|
const packingType: string = matchingProductDetail.packingType
|
|
124
123
|
const packingSize: number = matchingProductDetail.packingSize
|
|
124
|
+
if (!matchingProductDetail)
|
|
125
|
+
throw new Error(this.ERROR_MSG.PRODUCT.BARCODE_NOT_EXIST(productBarcode, packingType, packingSize))
|
|
125
126
|
|
|
126
127
|
let matchingOIs: OrderInventory[] = orderInventories.filter(
|
|
127
|
-
(oi: OrderInventory) =>
|
|
128
|
+
(oi: OrderInventory) =>
|
|
129
|
+
oi.packingType === packingType &&
|
|
130
|
+
oi.packingSize === packingSize &&
|
|
131
|
+
oi.product?.id === matchingProductDetail.product?.id
|
|
128
132
|
)
|
|
129
133
|
|
|
130
134
|
let sortedQty: number = 1
|
|
@@ -138,7 +142,6 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
138
142
|
const inventory: Inventory = matchingOI.inventory
|
|
139
143
|
const releaseGood: ReleaseGood = matchingOI.releaseGood
|
|
140
144
|
const product: Product = inventory.product
|
|
141
|
-
const productDetail: ProductDetail = matchingOI.productDetail
|
|
142
145
|
|
|
143
146
|
if (releaseQty != matchingOI?.sortedQty && sortedQty == 1) {
|
|
144
147
|
// Serial Number scanning for batch picking
|
|
@@ -150,7 +153,7 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
150
153
|
|
|
151
154
|
let foundSerialNumber: InventoryItem = await this.trxMgr
|
|
152
155
|
.getRepository(InventoryItem)
|
|
153
|
-
.findOne({ where: { domain: this.domain, serialNumber: serialNumber,
|
|
156
|
+
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
|
|
154
157
|
|
|
155
158
|
if (foundSerialNumber) {
|
|
156
159
|
if (foundSerialNumber.inventoryId !== inventory.id) {
|
|
@@ -177,7 +180,6 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
177
180
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
178
181
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
179
182
|
inventoryItem.product = product
|
|
180
|
-
inventoryItem.productDetail = productDetail
|
|
181
183
|
inventoryItem.inventory = inventory
|
|
182
184
|
inventoryItem.domain = this.domain
|
|
183
185
|
|
|
@@ -261,8 +263,7 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
261
263
|
'worksheetDetails.targetInventory.inventory.product',
|
|
262
264
|
'worksheetDetails.targetInventory.inventory.product.productDetails',
|
|
263
265
|
'worksheetDetails.targetInventory.inventory.product.productDetails.product',
|
|
264
|
-
'worksheetDetails.targetInventory.releaseGood'
|
|
265
|
-
'worksheetDetails.targetInventory.productDetail'
|
|
266
|
+
'worksheetDetails.targetInventory.releaseGood'
|
|
266
267
|
]
|
|
267
268
|
})
|
|
268
269
|
|
|
@@ -282,7 +283,6 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
282
283
|
const inventory: Inventory = matchingOI.inventory
|
|
283
284
|
const releaseGood: ReleaseGood = matchingOI.releaseGood
|
|
284
285
|
const product: Product = matchingOI.inventory.product
|
|
285
|
-
const productDetail: ProductDetail = matchingOI.productDetail
|
|
286
286
|
const packingType: string = matchingOI.packingType
|
|
287
287
|
const packingSize: number = matchingOI.packingSize
|
|
288
288
|
|
|
@@ -292,7 +292,8 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
295
|
-
where: { domain: this.domain, serialNumber: serialNumber,
|
|
295
|
+
where: { domain: this.domain, serialNumber: serialNumber, product },
|
|
296
|
+
relations: ['product', 'inventory']
|
|
296
297
|
})
|
|
297
298
|
|
|
298
299
|
if (foundSerialNumber) {
|
|
@@ -316,7 +317,6 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
316
317
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
317
318
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
318
319
|
inventoryItem.product = product
|
|
319
|
-
inventoryItem.productDetail = productDetail
|
|
320
320
|
inventoryItem.inventory = inventory
|
|
321
321
|
inventoryItem.domain = this.domain
|
|
322
322
|
|
|
@@ -22,8 +22,7 @@ import {
|
|
|
22
22
|
InventoryNoGenerator,
|
|
23
23
|
Location,
|
|
24
24
|
LOCATION_TYPE,
|
|
25
|
-
Warehouse
|
|
26
|
-
generateInventoryHistory
|
|
25
|
+
Warehouse
|
|
27
26
|
} from '@things-factory/warehouse-base'
|
|
28
27
|
|
|
29
28
|
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
|
|
@@ -37,6 +36,7 @@ import {
|
|
|
37
36
|
RefOrderType
|
|
38
37
|
} from '../../graphql/resolvers/worksheet/vas-transactions'
|
|
39
38
|
import { PackingUnits } from '../../graphql/resolvers/worksheet/vas-transactions/interfaces/repackaging'
|
|
39
|
+
import { generateInventoryHistory } from '../../utils'
|
|
40
40
|
import { ReferenceOrderType, WorksheetController } from '../worksheet-controller'
|
|
41
41
|
|
|
42
42
|
type CompleteTransactionType = (trxMgr: EntityManager, orderVas: OrderVas, user: User) => Promise<void>
|