@things-factory/worksheet-base 4.3.137 → 4.3.139
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 +59 -73
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js +2 -4
- package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/loading-worksheet-controller.js +5 -4
- package/dist-server/controllers/outbound/loading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/packing-worksheet-controller.js +23 -23
- package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/picking-worksheet-controller.js +157 -120
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/sorting-worksheet-controller.js +14 -14
- package/dist-server/controllers/outbound/sorting-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/vas/vas-worksheet-controller.js +1 -2
- package/dist-server/controllers/vas/vas-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/worksheet-controller.js +7 -7
- package/dist-server/controllers/worksheet-controller.js.map +1 -1
- package/dist-server/entities/index.js +3 -2
- package/dist-server/entities/index.js.map +1 -1
- package/dist-server/entities/warehouse-bizplace-onhand-inventory.js +29 -62
- package/dist-server/entities/warehouse-bizplace-onhand-inventory.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/batch-picking-worksheet.js +6 -0
- package/dist-server/graphql/resolvers/worksheet/batch-picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/confirm-cancellation-release-order.js +1 -2
- 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/find-sorting-release-orders-by-task-no.js +2 -2
- package/dist-server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +2 -1
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +4 -1
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js +3 -2
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.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/unloaded-inventories.js +1 -1
- package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.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 +1 -0
- package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
- package/dist-server/utils/inventory-util.js +1 -98
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +16 -16
- package/server/controllers/inbound/unloading-worksheet-controller.ts +74 -86
- package/server/controllers/inspect/cycle-count-worksheet-controller.ts +2 -4
- package/server/controllers/outbound/loading-worksheet-controller.ts +13 -3
- package/server/controllers/outbound/packing-worksheet-controller.ts +32 -37
- package/server/controllers/outbound/picking-worksheet-controller.ts +186 -150
- package/server/controllers/outbound/sorting-worksheet-controller.ts +14 -21
- package/server/controllers/vas/vas-worksheet-controller.ts +2 -2
- package/server/controllers/worksheet-controller.ts +15 -10
- package/server/entities/index.ts +2 -2
- package/server/entities/warehouse-bizplace-onhand-inventory.ts +29 -63
- package/server/graphql/resolvers/worksheet/batch-picking-worksheet.ts +6 -0
- package/server/graphql/resolvers/worksheet/confirm-cancellation-release-order.ts +1 -2
- package/server/graphql/resolvers/worksheet/cycle-count-adjustment.ts +2 -2
- package/server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.ts +2 -2
- package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +3 -1
- package/server/graphql/resolvers/worksheet/packing-worksheet.ts +4 -2
- package/server/graphql/resolvers/worksheet/picking-worksheet.ts +3 -2
- package/server/graphql/resolvers/worksheet/transfer.ts +18 -16
- package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +1 -1
- package/server/graphql/resolvers/worksheet/vas-transactions/common-utils.ts +3 -2
- package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts +4 -1
- package/server/graphql/types/worksheet-detail/index.ts +1 -0
- package/server/utils/inventory-util.ts +1 -126
|
@@ -2,7 +2,7 @@ import { Equal, Not } from 'typeorm'
|
|
|
2
2
|
|
|
3
3
|
import { ApplicationType } from '@things-factory/auth-base'
|
|
4
4
|
import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
|
|
5
|
-
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
5
|
+
import { Product, ProductDetail, ProductBarcode } from '@things-factory/product-base'
|
|
6
6
|
import { logger } from '@things-factory/env'
|
|
7
7
|
import { ORDER_INVENTORY_STATUS, ORDER_STATUS, OrderInventory, ReleaseGood } from '@things-factory/sales-base'
|
|
8
8
|
import { Setting } from '@things-factory/setting-base'
|
|
@@ -141,13 +141,15 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
141
141
|
'targetInventory.releaseGood',
|
|
142
142
|
'targetInventory.inventory',
|
|
143
143
|
'targetInventory.inventory.location',
|
|
144
|
-
'targetInventory.product'
|
|
144
|
+
'targetInventory.product',
|
|
145
|
+
'targetInventory.productDetail'
|
|
145
146
|
]
|
|
146
147
|
)
|
|
147
|
-
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
148
148
|
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
149
|
-
const product: Product = targetInventory.product
|
|
150
149
|
let inventory: Inventory = targetInventory.inventory
|
|
150
|
+
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
151
|
+
const product: Product = targetInventory.product
|
|
152
|
+
const productDetail: ProductDetail = targetInventory.productDetail
|
|
151
153
|
const pickedQty: number = targetInventory.releaseQty
|
|
152
154
|
|
|
153
155
|
if (packedQty > pickedQty) {
|
|
@@ -162,8 +164,7 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
162
164
|
}
|
|
163
165
|
|
|
164
166
|
let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
165
|
-
where: { domain: this.domain, serialNumber: serialNumber,
|
|
166
|
-
relations: ['product', 'inventory']
|
|
167
|
+
where: { domain: this.domain, serialNumber: serialNumber, productDetail }
|
|
167
168
|
})
|
|
168
169
|
|
|
169
170
|
if (foundSerialNumber) {
|
|
@@ -187,6 +188,7 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
187
188
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
188
189
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
189
190
|
inventoryItem.product = product
|
|
191
|
+
inventoryItem.productDetail = productDetail
|
|
190
192
|
inventoryItem.inventory = inventory
|
|
191
193
|
inventoryItem.domain = this.domain
|
|
192
194
|
|
|
@@ -233,47 +235,39 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
233
235
|
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
234
236
|
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
235
237
|
.leftJoinAndSelect('oi.orderProduct', 'op')
|
|
236
|
-
.innerJoinAndSelect('
|
|
237
|
-
.
|
|
238
|
-
|
|
239
|
-
'pd',
|
|
240
|
-
'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'
|
|
241
|
-
)
|
|
238
|
+
.innerJoinAndSelect('oi.product', 'prd')
|
|
239
|
+
.innerJoinAndSelect('oi.productDetail', 'pd')
|
|
240
|
+
.innerJoinAndSelect('pd.productBarcodes', 'pb')
|
|
242
241
|
.where('wd.id = :id', { id: worksheetDetailName })
|
|
243
|
-
.andWhere('wd.type = :type', { type: WORKSHEET_TYPE.PACKING })
|
|
244
242
|
.getOne()
|
|
245
243
|
|
|
246
|
-
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
247
|
-
const product: Product = worksheetDetail.targetInventory.inventory.product
|
|
248
|
-
const filterProductDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
249
244
|
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
250
245
|
let inventory: Inventory = targetInventory.inventory
|
|
251
246
|
let packedQty: number = 1
|
|
252
247
|
let pickedQty: number = targetInventory.releaseQty
|
|
248
|
+
const releaseGood: ReleaseGood = targetInventory.releaseGood
|
|
249
|
+
const product: Product = targetInventory.product
|
|
250
|
+
const productDetail: ProductDetail = targetInventory.productDetail
|
|
251
|
+
const productBarcodes: [ProductBarcode] = productDetail.productBarcodes
|
|
252
|
+
let matchingProduct
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
.find(
|
|
258
|
-
detail =>
|
|
259
|
-
detail.gtin === productBarcode &&
|
|
260
|
-
detail.packingType === inventory.packingType &&
|
|
261
|
-
detail.packingSize === inventory.packingSize
|
|
262
|
-
)
|
|
254
|
+
if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
|
|
255
|
+
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
256
|
+
}
|
|
263
257
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
258
|
+
matchingProduct = await this.getDirectQty(
|
|
259
|
+
{
|
|
260
|
+
...productDetail,
|
|
261
|
+
product: targetInventory?.product
|
|
262
|
+
},
|
|
263
|
+
productBarcode,
|
|
264
|
+
packedQty
|
|
265
|
+
)
|
|
269
266
|
|
|
270
|
-
|
|
267
|
+
//validate matching product details based on scanned barcode
|
|
268
|
+
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
271
269
|
|
|
272
|
-
|
|
273
|
-
packedQty *= childQty
|
|
274
|
-
} else if (!productDetail) {
|
|
275
|
-
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
276
|
-
}
|
|
270
|
+
packedQty = matchingProduct.qty
|
|
277
271
|
|
|
278
272
|
if (packedQty + targetInventory.packedQty > pickedQty) {
|
|
279
273
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
@@ -288,7 +282,7 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
288
282
|
|
|
289
283
|
let foundSerialNumber: InventoryItem = await this.trxMgr
|
|
290
284
|
.getRepository(InventoryItem)
|
|
291
|
-
.findOne({ where: { domain: this.domain, serialNumber: serialNumber,
|
|
285
|
+
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, productDetail } })
|
|
292
286
|
|
|
293
287
|
if (foundSerialNumber) {
|
|
294
288
|
if (foundSerialNumber.inventoryId !== inventory.id) {
|
|
@@ -315,6 +309,7 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
315
309
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
316
310
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
317
311
|
inventoryItem.product = product
|
|
312
|
+
inventoryItem.productDetail = productDetail
|
|
318
313
|
inventoryItem.inventory = inventory
|
|
319
314
|
inventoryItem.domain = this.domain
|
|
320
315
|
|
|
@@ -2,7 +2,7 @@ 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
|
-
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
5
|
+
import { Product, ProductDetail, ProductBarcode } from '@things-factory/product-base'
|
|
6
6
|
import {
|
|
7
7
|
GenerateBatchPickInfo,
|
|
8
8
|
ORDER_INVENTORY_STATUS,
|
|
@@ -28,12 +28,14 @@ import {
|
|
|
28
28
|
Location,
|
|
29
29
|
LOCATION_TYPE,
|
|
30
30
|
Tote,
|
|
31
|
-
TOTE_STATUS
|
|
31
|
+
TOTE_STATUS,
|
|
32
|
+
generateInventoryHistory
|
|
32
33
|
} from '@things-factory/warehouse-base'
|
|
34
|
+
import { logger } from '@things-factory/env'
|
|
33
35
|
|
|
34
36
|
import { TASK_NUMBER_RULE_TYPE, TASK_NUMBER_SETTING_KEY, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
|
|
35
37
|
import { Worksheet, WorksheetDetail } from '../../entities'
|
|
36
|
-
import {
|
|
38
|
+
import { WorksheetNoGenerator } from '../../utils'
|
|
37
39
|
import { VasWorksheetController } from '../vas/vas-worksheet-controller'
|
|
38
40
|
|
|
39
41
|
export class PickingWorksheetController extends VasWorksheetController {
|
|
@@ -213,7 +215,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
213
215
|
if (vasWorksheet) {
|
|
214
216
|
await this.activateVAS(vasWorksheet.name, vasWorksheet.worksheetDetails)
|
|
215
217
|
}
|
|
216
|
-
} catch (e) {
|
|
218
|
+
} catch (e) {}
|
|
217
219
|
|
|
218
220
|
const pendingSplitOIs: OrderInventory[] = await this.trxMgr.getRepository(OrderInventory).find({
|
|
219
221
|
where: { domain: this.domain, releaseGood, status: ORDER_INVENTORY_STATUS.PENDING_SPLIT }
|
|
@@ -428,11 +430,8 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
428
430
|
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
429
431
|
.leftJoinAndSelect('oi.orderProduct', 'op')
|
|
430
432
|
.innerJoinAndSelect('oi.product', 'prd')
|
|
431
|
-
.
|
|
432
|
-
|
|
433
|
-
'pd',
|
|
434
|
-
'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'
|
|
435
|
-
)
|
|
433
|
+
.innerJoinAndSelect('oi.productDetail', 'pd')
|
|
434
|
+
.innerJoinAndSelect('pd.productBarcodes', 'pb')
|
|
436
435
|
.where('wd.name = :name', { name: worksheetDetailName })
|
|
437
436
|
.andWhere('wd.domain_id = :domainId', { domainId: this.domain.id })
|
|
438
437
|
.andWhere('wd.type = :type', { type: worksheetType })
|
|
@@ -441,17 +440,35 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
441
440
|
.getOne()
|
|
442
441
|
|
|
443
442
|
//validation to check matching worksheet detail based on name
|
|
444
|
-
if (!worksheetDetail
|
|
445
|
-
|
|
443
|
+
if (!worksheetDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(worksheetDetailName))
|
|
444
|
+
|
|
445
|
+
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
446
|
+
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
447
|
+
let targetProduct: OrderProduct = targetInventory.orderProduct
|
|
448
|
+
const product: Product = targetInventory.product
|
|
449
|
+
const matchProductBarcode: ProductBarcode = await this.trxMgr.getRepository(ProductBarcode).findOne({
|
|
450
|
+
where: { gtin: productBarcode },
|
|
451
|
+
relations: ['productDetail']
|
|
452
|
+
})
|
|
453
|
+
const productDetail: ProductDetail = targetInventory.productDetail
|
|
454
|
+
const productBarcodes: [ProductBarcode] = productDetail.productBarcodes
|
|
455
|
+
let inventory: Inventory = targetInventory.inventory
|
|
456
|
+
let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
|
|
457
|
+
let pickedUomValue = pickedQty * productDetail.uomValue
|
|
458
|
+
let matchingProduct
|
|
446
459
|
|
|
447
460
|
//validation to prevent duplicated picking
|
|
448
|
-
if (
|
|
461
|
+
if (targetInventory?.status != ORDER_INVENTORY_STATUS.PICKING)
|
|
449
462
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`))
|
|
450
463
|
|
|
451
|
-
|
|
464
|
+
if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
|
|
465
|
+
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
matchingProduct = await this.getDirectQty(
|
|
452
469
|
{
|
|
453
|
-
...
|
|
454
|
-
product:
|
|
470
|
+
...productDetail,
|
|
471
|
+
product: targetInventory?.product
|
|
455
472
|
},
|
|
456
473
|
productBarcode,
|
|
457
474
|
pickedQty
|
|
@@ -461,7 +478,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
461
478
|
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
462
479
|
|
|
463
480
|
pickedQty = matchingProduct.qty
|
|
464
|
-
|
|
481
|
+
pickedUomValue = matchingProduct.uomValue
|
|
465
482
|
|
|
466
483
|
//validation to prevent over release
|
|
467
484
|
if (
|
|
@@ -471,15 +488,24 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
471
488
|
)
|
|
472
489
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
473
490
|
|
|
474
|
-
|
|
491
|
+
targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
|
|
475
492
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
493
|
+
// // search for matching product barcode
|
|
494
|
+
// const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
495
|
+
// // scannedProductDetail can be child or gtin
|
|
496
|
+
// const scannedProductDetail: ProductDetail = productDetails.find(detail => detail.gtin == productBarcode)
|
|
497
|
+
// if (!scannedProductDetail) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
481
498
|
|
|
482
|
-
|
|
499
|
+
// // case for scanning parent packing type, packing size
|
|
500
|
+
// // when scannedProductDetail id is not the same as productDetail id, then it's not child gtin, proceed to get child qty
|
|
501
|
+
// if (scannedProductDetail.id !== productDetail.id && !product?.isRequireSerialNumberScanningOutbound) {
|
|
502
|
+
// let childQty = await this.getChildQty(productDetails, productBarcode, productDetail, scannedProductDetail)
|
|
503
|
+
// pickedQty *= childQty
|
|
504
|
+
// }
|
|
505
|
+
|
|
506
|
+
// if (pickedQty + targetInventory.pickedQty > releaseQty) {
|
|
507
|
+
// throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
508
|
+
// }
|
|
483
509
|
|
|
484
510
|
// for required outbound serial number scanning
|
|
485
511
|
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
@@ -527,6 +553,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
527
553
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
528
554
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
529
555
|
inventoryItem.product = product
|
|
556
|
+
inventoryItem.productDetail = productDetail
|
|
530
557
|
inventoryItem.inventory = inventory
|
|
531
558
|
inventoryItem.domain = this.domain
|
|
532
559
|
|
|
@@ -692,13 +719,15 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
692
719
|
'targetInventory.orderProduct',
|
|
693
720
|
'targetInventory.inventory',
|
|
694
721
|
'targetInventory.inventory.location',
|
|
695
|
-
'targetInventory.product'
|
|
722
|
+
'targetInventory.product',
|
|
723
|
+
'targetInventory.productDetail'
|
|
696
724
|
]
|
|
697
725
|
)
|
|
698
726
|
|
|
699
727
|
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
700
728
|
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
701
729
|
const product: Product = targetInventory.product
|
|
730
|
+
const productDetail: ProductDetail = targetInventory.productDetail
|
|
702
731
|
let inventory: Inventory = targetInventory.inventory
|
|
703
732
|
let targetProduct: OrderProduct = targetInventory.orderProduct
|
|
704
733
|
let bizplace: Bizplace = worksheetDetail.worksheet.bizplace
|
|
@@ -728,13 +757,13 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
728
757
|
})
|
|
729
758
|
|
|
730
759
|
let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
731
|
-
where: { domain: this.domain, serialNumber: serialNumber,
|
|
732
|
-
relations: ['product', 'inventory']
|
|
760
|
+
where: { domain: this.domain, serialNumber: serialNumber, productDetail },
|
|
761
|
+
relations: ['product', 'productDetail', 'inventory']
|
|
733
762
|
})
|
|
734
763
|
|
|
735
764
|
let scannedPalletIdInventory: Inventory = await this.trxMgr
|
|
736
765
|
.getRepository(Inventory)
|
|
737
|
-
.findOne({ where: { domain: this.domain, palletId }, relations: ['
|
|
766
|
+
.findOne({ where: { domain: this.domain, palletId }, relations: ['productDetail'] })
|
|
738
767
|
|
|
739
768
|
if (foundSerialNumber) {
|
|
740
769
|
if (foundSerialNumber.outboundOrderId) {
|
|
@@ -761,6 +790,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
761
790
|
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
762
791
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
763
792
|
inventoryItem.product = product
|
|
793
|
+
inventoryItem.productDetail = productDetail
|
|
764
794
|
inventoryItem.inventory = scannedPalletIdInventory
|
|
765
795
|
inventoryItem.domain = this.domain
|
|
766
796
|
|
|
@@ -786,8 +816,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
786
816
|
)
|
|
787
817
|
} else if (
|
|
788
818
|
scannedPalletIdInventory.batchId == inventory.batchId &&
|
|
789
|
-
scannedPalletIdInventory.
|
|
790
|
-
scannedPalletIdInventory.product.packingType == product.packingType
|
|
819
|
+
scannedPalletIdInventory.productDetail.id == productDetail.id
|
|
791
820
|
) {
|
|
792
821
|
//if replacement order inventory does not exist
|
|
793
822
|
await this.serialNumberReplacement(
|
|
@@ -795,6 +824,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
795
824
|
scannedPalletIdInventory,
|
|
796
825
|
releaseGood,
|
|
797
826
|
product,
|
|
827
|
+
productDetail,
|
|
798
828
|
worksheetDetail,
|
|
799
829
|
foundSerialNumber
|
|
800
830
|
)
|
|
@@ -962,144 +992,144 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
962
992
|
binLocationName: string,
|
|
963
993
|
pickingQty: number
|
|
964
994
|
): Promise<void> {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
'worksheetDetails
|
|
971
|
-
'worksheetDetails.targetInventory
|
|
972
|
-
'
|
|
973
|
-
'
|
|
974
|
-
'
|
|
975
|
-
'
|
|
976
|
-
|
|
977
|
-
|
|
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)
|
|
1016
|
+
|
|
1017
|
+
const product: Product = productDetail.product
|
|
1018
|
+
|
|
1019
|
+
const batchId: string = inventory.batchId
|
|
1020
|
+
let pickedQty: number = pickingQty ? pickingQty : 1
|
|
1021
|
+
let matchingProduct
|
|
1022
|
+
|
|
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
|
+
)
|
|
978
1031
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
const packingSize: number = inventory.packingSize
|
|
987
|
-
let pickedQty: number = pickingQty ? pickingQty : 1
|
|
988
|
-
|
|
989
|
-
const targetInventories: OrderInventory[] = worksheetDetails
|
|
990
|
-
.map((wsd: WorksheetDetail) => wsd.targetInventory)
|
|
991
|
-
.filter(
|
|
992
|
-
(targetInventory: OrderInventory) =>
|
|
993
|
-
targetInventory.batchId === batchId &&
|
|
994
|
-
targetInventory.packingType === packingType &&
|
|
995
|
-
targetInventory.inventory.cartonId === cartonId &&
|
|
996
|
-
targetInventory.product.id === product.id
|
|
1032
|
+
matchingProduct = await this.getDirectQty(
|
|
1033
|
+
{
|
|
1034
|
+
...productDetail,
|
|
1035
|
+
product
|
|
1036
|
+
},
|
|
1037
|
+
productBarcode,
|
|
1038
|
+
pickedQty
|
|
997
1039
|
)
|
|
998
1040
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
|
|
1002
|
-
if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(`GTIN (${productBarcode})`))
|
|
1003
|
-
|
|
1004
|
-
// case for scanning parent packing type, packing size
|
|
1005
|
-
const foundProductDetail: ProductDetail = productDetails.find(
|
|
1006
|
-
(detail: ProductDetail) =>
|
|
1007
|
-
detail.gtin === productBarcode && detail.packingType === packingType && detail.packingSize == packingSize
|
|
1008
|
-
)
|
|
1009
|
-
|
|
1010
|
-
if (!foundProductDetail) {
|
|
1011
|
-
const roProductDetail: ProductDetail = productDetails.find(
|
|
1012
|
-
(parentDetail: ProductDetail) =>
|
|
1013
|
-
parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
|
|
1014
|
-
)
|
|
1015
|
-
if (!roProductDetail)
|
|
1016
|
-
throw new Error(
|
|
1017
|
-
this.ERROR_MSG.FIND.NO_RESULT(`Packing Type ( ${packingType}) or Packing Size (${packingSize})`)
|
|
1018
|
-
)
|
|
1041
|
+
//validate matching product details based on scanned barcode
|
|
1042
|
+
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
1019
1043
|
|
|
1020
|
-
|
|
1021
|
-
pickedQty *= childQty
|
|
1022
|
-
}
|
|
1044
|
+
pickedQty = matchingProduct.qty
|
|
1023
1045
|
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1046
|
+
const sumOfReleaseQty: number = targetInventories
|
|
1047
|
+
.map((oi: OrderInventory) => oi.releaseQty)
|
|
1048
|
+
.reduce((a, b) => a + b, 0)
|
|
1027
1049
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1050
|
+
const sumOfPickedQty: number =
|
|
1051
|
+
targetInventories.map((oi: OrderInventory) => oi.pickedQty).reduce((a, b) => a + b, 0) + pickedQty
|
|
1030
1052
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1053
|
+
if (sumOfPickedQty > sumOfReleaseQty)
|
|
1054
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
|
|
1033
1055
|
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
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
|
+
})
|
|
1041
1076
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
targetReleaseQty > targetPickedQty &&
|
|
1045
|
-
pickedQty > 0
|
|
1046
|
-
) {
|
|
1047
|
-
let remainingAssignedQty: number = pickedQty - (targetReleaseQty - targetPickedQty) // -1, 0, 1
|
|
1048
|
-
const gapQtyRemaining: number = targetReleaseQty - targetPickedQty // > 0
|
|
1049
|
-
|
|
1050
|
-
if (binLocationName && !targetInventory?.binLocation) {
|
|
1051
|
-
const binLocation: Location = await this.trxMgr.getRepository(Location).findOne({
|
|
1052
|
-
where: { domain: this.domain, name: binLocationName, type: LOCATION_TYPE.BIN }
|
|
1053
|
-
})
|
|
1077
|
+
if (!binLocation)
|
|
1078
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`))
|
|
1054
1079
|
|
|
1055
|
-
|
|
1056
|
-
|
|
1080
|
+
targetInventory.binLocation = binLocation
|
|
1081
|
+
}
|
|
1057
1082
|
|
|
1058
|
-
|
|
1059
|
-
|
|
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
|
|
1060
1086
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
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
|
+
}
|
|
1064
1094
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
if (leftQty < 0) {
|
|
1068
|
-
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
|
|
1069
|
-
}
|
|
1095
|
+
targetInventory.status = ORDER_INVENTORY_STATUS.PICKED
|
|
1096
|
+
await this.updateOrderTargets([targetInventory])
|
|
1070
1097
|
|
|
1071
|
-
|
|
1072
|
-
|
|
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
|
+
)
|
|
1073
1110
|
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
Math.round((inventory.lockedUomValue - targetInventory.releaseUomValue) * 100) / 100
|
|
1079
|
-
await this.transactionInventory(
|
|
1080
|
-
inventory,
|
|
1081
|
-
releaseGood,
|
|
1082
|
-
-targetInventory.releaseQty,
|
|
1083
|
-
-targetInventory.releaseUomValue,
|
|
1084
|
-
INVENTORY_TRANSACTION_TYPE.PICKING
|
|
1085
|
-
)
|
|
1111
|
+
if (leftQty === 0) {
|
|
1112
|
+
inventory.status = INVENTORY_STATUS.TERMINATED
|
|
1113
|
+
await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
|
|
1114
|
+
}
|
|
1086
1115
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
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])
|
|
1090
1124
|
}
|
|
1091
|
-
|
|
1092
|
-
let worksheetDetail: WorksheetDetail = worksheetDetails.find(
|
|
1093
|
-
(wsd: WorksheetDetail) => wsd.targetInventory.id === targetInventory.id
|
|
1094
|
-
)
|
|
1095
|
-
worksheetDetail.status = WORKSHEET_STATUS.DONE
|
|
1096
|
-
worksheetDetail.updater = this.user
|
|
1097
|
-
await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
1098
|
-
} else {
|
|
1099
|
-
await this.updateOrderTargets([targetInventory])
|
|
1125
|
+
pickedQty = pickedQty - (targetReleaseQty - targetPickedQty)
|
|
1100
1126
|
}
|
|
1101
|
-
pickedQty = pickedQty - (targetReleaseQty - targetPickedQty)
|
|
1102
1127
|
}
|
|
1128
|
+
} catch (error) {
|
|
1129
|
+
logger.error(`picking-worksheet-controller[scanProductBatchPicking]: ${error}`)
|
|
1130
|
+
throw new Error(error)
|
|
1131
|
+
} finally {
|
|
1132
|
+
console.timeEnd(`scanProductBatchPicking:${taskNo}`)
|
|
1103
1133
|
}
|
|
1104
1134
|
}
|
|
1105
1135
|
|
|
@@ -1404,7 +1434,9 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1404
1434
|
await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.ild)
|
|
1405
1435
|
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1406
1436
|
}
|
|
1407
|
-
} catch (e) {
|
|
1437
|
+
} catch (e) {
|
|
1438
|
+
logger.error(`picking-worksheet-controller[serialNumberReplacementForExistingOrderInv]: ${e}`)
|
|
1439
|
+
}
|
|
1408
1440
|
}
|
|
1409
1441
|
|
|
1410
1442
|
private async serialNumberReplacement(
|
|
@@ -1412,6 +1444,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1412
1444
|
scannedPalletIdInventory,
|
|
1413
1445
|
releaseGood,
|
|
1414
1446
|
product,
|
|
1447
|
+
productDetail,
|
|
1415
1448
|
worksheetDetail,
|
|
1416
1449
|
foundSerialNumber
|
|
1417
1450
|
) {
|
|
@@ -1476,6 +1509,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1476
1509
|
releaseUomValue: newOrderInventoryReleaseUomValue,
|
|
1477
1510
|
pickedQty: 1,
|
|
1478
1511
|
product,
|
|
1512
|
+
productDetail,
|
|
1479
1513
|
inventory: scannedPalletIdInventory,
|
|
1480
1514
|
creator: this.user,
|
|
1481
1515
|
updater: this.user
|
|
@@ -1519,7 +1553,9 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1519
1553
|
await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.id)
|
|
1520
1554
|
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1521
1555
|
}
|
|
1522
|
-
} catch (e) {
|
|
1556
|
+
} catch (e) {
|
|
1557
|
+
logger.error(`picking-worksheet-controller[serialNumberReplacement]: ${e}`)
|
|
1558
|
+
}
|
|
1523
1559
|
}
|
|
1524
1560
|
|
|
1525
1561
|
private async toteScanning(toteNo, targetProduct, targetInventory, pickedQty, releaseGood, bizplace) {
|