@things-factory/worksheet-base 4.3.285 → 4.3.287
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/ecommerce/ecommerce-controller.js +49 -21
- package/dist-server/controllers/ecommerce/ecommerce-controller.js.map +1 -1
- package/dist-server/controllers/outbound/packing-worksheet-controller.js +105 -130
- package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/worksheet-controller.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js +7 -3
- package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js.map +1 -1
- package/dist-server/utils/lmd-util.js +3 -2
- package/dist-server/utils/lmd-util.js.map +1 -1
- package/package.json +9 -9
- package/server/controllers/ecommerce/ecommerce-controller.ts +47 -21
- package/server/controllers/outbound/packing-worksheet-controller.ts +122 -142
- package/server/controllers/worksheet-controller.ts +1 -1
- package/server/graphql/resolvers/worksheet/packing/scan-product-packing.ts +7 -3
- package/server/utils/lmd-util.ts +3 -2
|
@@ -306,176 +306,154 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
async scanProductPacking(orderPackageItemId: string, productBarcode: string, serialNumber?: string): Promise<any> {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
let packedQty: number = 1
|
|
309
|
+
try {
|
|
310
|
+
let packedQty: number = 1
|
|
311
|
+
let orderPackageItem: OrderPackageItem = await this.trxMgr.getRepository(OrderPackageItem).findOne({
|
|
312
|
+
where: { id: orderPackageItemId }, relations: ['orderProduct', 'orderProduct.releaseGood']
|
|
313
|
+
})
|
|
314
|
+
const orderProduct: OrderProduct = orderPackageItem.orderProduct
|
|
315
|
+
const releaseGood: ReleaseGood = orderProduct.releaseGood
|
|
317
316
|
|
|
318
|
-
|
|
319
|
-
let worksheetDetail: WorksheetDetail = await this.trxMgr
|
|
320
|
-
.getRepository(WorksheetDetail)
|
|
321
|
-
.createQueryBuilder('wd')
|
|
322
|
-
.innerJoinAndSelect('wd.bizplace', 'b')
|
|
323
|
-
.innerJoinAndSelect('wd.targetInventory', 'oi')
|
|
324
|
-
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
325
|
-
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
326
|
-
.leftJoinAndSelect('oi.orderProduct', 'op')
|
|
317
|
+
let orderInventory: OrderInventory = await this.trxMgr.getRepository(OrderInventory).createQueryBuilder('oi')
|
|
327
318
|
.innerJoinAndSelect('oi.product', 'prd')
|
|
328
319
|
.innerJoinAndSelect('oi.productDetail', 'pd')
|
|
329
|
-
.innerJoinAndSelect('
|
|
330
|
-
.where('oi.
|
|
320
|
+
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
321
|
+
.where('oi.order_product_id = :id', { id: orderProduct.id })
|
|
322
|
+
.andWhere('oi.packed_qty <> oi.picked_qty')
|
|
323
|
+
.orderBy('oi.created_at')
|
|
324
|
+
.addOrderBy('oi.name')
|
|
331
325
|
.getOne()
|
|
332
326
|
|
|
333
|
-
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
334
|
-
|
|
335
|
-
let inventory: Inventory = targetInventory.inventory
|
|
336
|
-
let pickedQty: number = targetInventory.releaseQty
|
|
337
|
-
const releaseGood: ReleaseGood = targetInventory.releaseGood
|
|
338
|
-
const product: Product = targetInventory.product
|
|
339
|
-
const productDetail: ProductDetail = targetInventory.productDetail
|
|
340
|
-
const productBarcodes: [ProductBarcode] = productDetail.productBarcodes
|
|
341
|
-
let matchingProduct
|
|
342
327
|
|
|
343
|
-
|
|
344
|
-
|
|
328
|
+
// Validation: PackQty cannot be more than ReleaseQty
|
|
329
|
+
if (orderPackageItem !== null && orderInventory == null) {
|
|
330
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('packing', `unable to find suitable item`))
|
|
345
331
|
}
|
|
346
332
|
|
|
347
|
-
|
|
333
|
+
const product: Product = orderInventory.product
|
|
334
|
+
const productDetail: ProductDetail = orderInventory.productDetail
|
|
335
|
+
const inventory: Inventory = orderInventory.inventory
|
|
336
|
+
const releaseQty: number = orderInventory.releaseQty
|
|
337
|
+
|
|
338
|
+
const matchingProduct = await this.getDirectQty(
|
|
348
339
|
{
|
|
349
340
|
...productDetail,
|
|
350
|
-
product:
|
|
341
|
+
product: product
|
|
351
342
|
},
|
|
352
343
|
productBarcode,
|
|
353
344
|
packedQty
|
|
354
345
|
)
|
|
355
|
-
|
|
356
|
-
//validate matching product details based on scanned barcode
|
|
357
|
-
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
358
|
-
|
|
359
346
|
packedQty = matchingProduct.qty
|
|
360
347
|
|
|
361
|
-
|
|
362
|
-
|
|
348
|
+
// Validation: PackQty cannot be more than ReleaseQty
|
|
349
|
+
if ((packedQty + orderInventory.packedQty) > orderInventory.releaseQty) {
|
|
350
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('packing', `packed quantity can't exceed release qty`))
|
|
363
351
|
}
|
|
364
352
|
|
|
365
|
-
// Serial Number scanning for batch picking
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
let foundSerialNumber: InventoryItem = await this.trxMgr
|
|
373
|
-
.getRepository(InventoryItem)
|
|
374
|
-
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, productDetail } })
|
|
375
|
-
|
|
376
|
-
if (foundSerialNumber) {
|
|
377
|
-
if (foundSerialNumber.inventoryId !== inventory.id) {
|
|
378
|
-
throw new Error('Serial Number scanned is in another inventory')
|
|
379
|
-
}
|
|
353
|
+
// Validation: Serial Number scanning for batch picking
|
|
354
|
+
let inventoryItem: Partial<InventoryItem>
|
|
355
|
+
if (orderInventory?.refWorksheetId && product?.isRequireSerialNumberScanningOutbound) {
|
|
356
|
+
if (!serialNumber || serialNumber == '') {
|
|
357
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('packing', `require serial number`))
|
|
358
|
+
}
|
|
380
359
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
.findOne({ where: { id: foundSerialNumber.outboundOrderId } })
|
|
385
|
-
throw new Error(`Inventory Item is already picked/packed in ${releaseGood.name}`)
|
|
386
|
-
}
|
|
360
|
+
inventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
361
|
+
where: { domain: this.domain, serialNumber: serialNumber, productDetail }
|
|
362
|
+
})
|
|
387
363
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
364
|
+
if (inventoryItem) {
|
|
365
|
+
if (inventoryItem.inventoryId !== inventory.id) {
|
|
366
|
+
throw new Error('Serial Number scanned is in another inventory')
|
|
367
|
+
}
|
|
391
368
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
396
|
-
inventoryItem.serialNumber = serialNumber
|
|
397
|
-
inventoryItem.status = INVENTORY_STATUS.PACKING
|
|
398
|
-
inventoryItem.outboundOrderId = releaseGood.id
|
|
399
|
-
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
400
|
-
inventoryItem.product = product
|
|
401
|
-
inventoryItem.productDetail = productDetail
|
|
402
|
-
inventoryItem.inventory = inventory
|
|
403
|
-
inventoryItem.domain = this.domain
|
|
369
|
+
if (inventoryItem.outboundOrderId !== releaseGood.id) {
|
|
370
|
+
throw new Error(`Inventory Item is already picked/packed in ${releaseGood.name}`)
|
|
371
|
+
}
|
|
404
372
|
|
|
405
|
-
|
|
373
|
+
inventoryItem = {
|
|
374
|
+
...inventoryItem,
|
|
375
|
+
status: INVENTORY_STATUS.PACKING,
|
|
376
|
+
updater: this.user,
|
|
377
|
+
}
|
|
378
|
+
} else {
|
|
379
|
+
inventoryItem = {
|
|
380
|
+
name: InventoryNoGenerator.inventoryItemName(),
|
|
381
|
+
serialNumber: serialNumber,
|
|
382
|
+
status: INVENTORY_STATUS.PACKING,
|
|
383
|
+
outboundOrderId: releaseGood.id,
|
|
384
|
+
source: INVENTORY_ITEM_SOURCE.OUTBOUND,
|
|
385
|
+
product: product,
|
|
386
|
+
productDetail: productDetail,
|
|
387
|
+
inventory: inventory,
|
|
388
|
+
domain: this.domain,
|
|
406
389
|
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
390
|
|
|
410
|
-
|
|
411
|
-
? targetInventory.packedQty + packedQty
|
|
412
|
-
: packedQty
|
|
413
|
-
if (targetInventory.packedQty > pickedQty) {
|
|
414
|
-
throw new Error(
|
|
415
|
-
this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('pack', `packed quantity can't exceed release qty`)
|
|
416
|
-
)
|
|
391
|
+
}
|
|
417
392
|
}
|
|
418
393
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
let packedBy: string[] =
|
|
394
|
+
// set orderInventory Value
|
|
395
|
+
orderInventory.packedQty = (orderInventory?.packedQty || 0) + packedQty
|
|
396
|
+
orderInventory.packedAt = new Date()
|
|
397
|
+
let packedBy: string[] = orderInventory.packedBy ? orderInventory.packedBy.split(',') : []
|
|
423
398
|
if (!packedBy.find(x => x == this.user.name)) {
|
|
424
399
|
packedBy.push(this.user.name)
|
|
425
|
-
|
|
400
|
+
orderInventory.packedBy = packedBy.join(',')
|
|
426
401
|
}
|
|
427
402
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
403
|
+
// set orderPackageItem Value
|
|
404
|
+
let updateOrderPackageItem: Partial<OrderPackageItem> = {
|
|
405
|
+
packedQty: (orderPackageItem?.packedQty || 0) + packedQty,
|
|
406
|
+
updatedAt: new Date(),
|
|
407
|
+
updater: this.user
|
|
408
|
+
}
|
|
409
|
+
if (updateOrderPackageItem.packedQty === orderPackageItem.releaseQty) {
|
|
410
|
+
updateOrderPackageItem.status = ORDER_STATUS.DONE
|
|
411
|
+
}
|
|
432
412
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
413
|
+
if (inventoryItem) {
|
|
414
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
415
|
+
}
|
|
416
|
+
orderInventory = (await this.updateOrderTargets([orderInventory]))[0]
|
|
436
417
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
418
|
+
await this.trxMgr.getRepository(OrderPackageItem).update({ id: orderPackageItem.id }, updateOrderPackageItem)
|
|
419
|
+
updateOrderPackageItem = await this.trxMgr.getRepository(OrderPackageItem).findOne({ where: { id: orderPackageItem.id } })
|
|
440
420
|
|
|
441
|
-
|
|
442
|
-
inventoryItems.forEach((itm: InventoryItem) => {
|
|
443
|
-
itm.status = INVENTORY_STATUS.PACKED
|
|
444
|
-
itm.updater = this.user
|
|
445
|
-
})
|
|
421
|
+
await this.trxMgr.getRepository(OrderPackage).update({ id: orderPackageItem.orderPackageId }, { updatedAt: new Date(), updater: this.user })
|
|
446
422
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
await this.trxMgr.getRepository(
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
: packedQty
|
|
423
|
+
if (orderInventory.packedQty === releaseQty) {
|
|
424
|
+
orderInventory.status = ORDER_INVENTORY_STATUS.PACKED
|
|
425
|
+
await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.PACKING)
|
|
426
|
+
await this.trxMgr.getRepository(WorksheetDetail).update({ targetInventory: { id: orderInventory.id }, type: 'PACKING' },
|
|
427
|
+
{
|
|
428
|
+
status: WORKSHEET_STATUS.DONE,
|
|
429
|
+
updater: this.user,
|
|
430
|
+
updatedAt: new Date()
|
|
431
|
+
}
|
|
432
|
+
)
|
|
458
433
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
434
|
+
//// update related inventoryItems related with the releaseOrder
|
|
435
|
+
await this.trxMgr.getRepository(InventoryItem).update({ outboundOrderId: releaseGood.id },
|
|
436
|
+
{
|
|
437
|
+
status: INVENTORY_STATUS.PACKED,
|
|
438
|
+
updater: this.user,
|
|
439
|
+
updatedAt: new Date()
|
|
440
|
+
}
|
|
441
|
+
)
|
|
442
|
+
}
|
|
464
443
|
|
|
465
|
-
await this.trxMgr.getRepository(OrderPackageItem).save(orderPackageItem)
|
|
466
|
-
await this.trxMgr
|
|
467
|
-
.getRepository(OrderPackage)
|
|
468
|
-
.update({ id: orderPackageItem.orderPackage.id }, { updatedAt: new Date() })
|
|
469
444
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
445
|
+
return {
|
|
446
|
+
worksheetDetailInfos: [
|
|
447
|
+
{
|
|
448
|
+
id: updateOrderPackageItem.id,
|
|
449
|
+
releaseQty: updateOrderPackageItem.releaseQty,
|
|
450
|
+
packedQty: updateOrderPackageItem.packedQty,
|
|
451
|
+
status: updateOrderPackageItem.status
|
|
452
|
+
}
|
|
453
|
+
]
|
|
454
|
+
}
|
|
455
|
+
} catch (error) {
|
|
456
|
+
throw error
|
|
479
457
|
}
|
|
480
458
|
}
|
|
481
459
|
|
|
@@ -484,9 +462,7 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
484
462
|
.getRepository(OrderPackage)
|
|
485
463
|
.findOne({ where: { id: orderPackageId } })
|
|
486
464
|
|
|
487
|
-
await this.trxMgr
|
|
488
|
-
.getRepository(OrderPackage)
|
|
489
|
-
.update({ id: orderPackage.id }, { status: ORDER_STATUS.DONE, updater: this.user, updatedAt: new Date() })
|
|
465
|
+
await this.trxMgr.getRepository(OrderPackage).update({ id: orderPackage.id }, { status: ORDER_STATUS.DONE, updater: this.user, updatedAt: new Date() })
|
|
490
466
|
|
|
491
467
|
let releaseGood: ReleaseGood = await this.findRefOrder(
|
|
492
468
|
ReleaseGood,
|
|
@@ -504,14 +480,10 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
504
480
|
])
|
|
505
481
|
this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
|
|
506
482
|
|
|
507
|
-
let orderPackages: OrderPackage[] = await this.trxMgr
|
|
508
|
-
.getRepository(OrderPackage)
|
|
509
|
-
.find({ where: { releaseGood, domain: this.domain, bizplace: releaseGood.bizplace } })
|
|
483
|
+
let orderPackages: OrderPackage[] = await this.trxMgr.getRepository(OrderPackage).find({ where: { releaseGood, domain: this.domain, bizplace: releaseGood.bizplace } })
|
|
510
484
|
|
|
511
485
|
if (orderPackages.every(op => op.status == ORDER_STATUS.DONE)) {
|
|
512
|
-
let inventoryItems: InventoryItem = await this.trxMgr
|
|
513
|
-
.getRepository(InventoryItem)
|
|
514
|
-
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
486
|
+
let inventoryItems: InventoryItem = await this.trxMgr.getRepository(InventoryItem).find({ where: { outboundOrderId: releaseGood.id } })
|
|
515
487
|
|
|
516
488
|
if (inventoryItems.length > 0) {
|
|
517
489
|
inventoryItems.forEach((itm: InventoryItem) => {
|
|
@@ -526,6 +498,14 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
526
498
|
if (releaseGood?.courierOption) orderStatus = ORDER_STATUS.DONE
|
|
527
499
|
else orderStatus = ORDER_STATUS.LOADING
|
|
528
500
|
|
|
501
|
+
//update releaseGood TrackingNo
|
|
502
|
+
if (orderPackage.trackingNo && releaseGood) {
|
|
503
|
+
await this.trxMgr.getRepository(ReleaseGood).update(
|
|
504
|
+
{ id: releaseGood.id },
|
|
505
|
+
{ trackingNo: `${releaseGood?.trackingNo ? releaseGood?.trackingNo.split(',').push(orderPackage.trackingNo).join(',') : orderPackage.trackingNo}` }
|
|
506
|
+
)
|
|
507
|
+
}
|
|
508
|
+
|
|
529
509
|
return await this.completeWorksheet(worksheet, orderStatus)
|
|
530
510
|
} else {
|
|
531
511
|
return worksheet
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { EntityManager } from 'typeorm'
|
|
2
2
|
|
|
3
|
+
const { PerformanceObserver, performance } = require('node:perf_hooks');
|
|
4
|
+
|
|
3
5
|
import { User } from '@things-factory/auth-base'
|
|
4
6
|
import { Domain } from '@things-factory/shell'
|
|
5
7
|
|
|
@@ -20,7 +22,7 @@ export async function scanProductPacking(
|
|
|
20
22
|
productBarcode: string,
|
|
21
23
|
serialNumber?: string
|
|
22
24
|
) {
|
|
23
|
-
|
|
25
|
+
performance.mark(`start:${orderPackageItemId} - ${productBarcode}`)
|
|
24
26
|
try {
|
|
25
27
|
const worksheetController: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
|
|
26
28
|
const inventoryItems = await worksheetController.scanProductPacking(
|
|
@@ -29,10 +31,12 @@ export async function scanProductPacking(
|
|
|
29
31
|
serialNumber
|
|
30
32
|
)
|
|
31
33
|
|
|
32
|
-
console.timeEnd(`execution time to scan for packing ${orderPackageItemId} - ${productBarcode}`)
|
|
33
34
|
return inventoryItems
|
|
34
35
|
} catch (error) {
|
|
35
|
-
console.timeEnd(`execution time to scan for packing ${orderPackageItemId} - ${productBarcode}`)
|
|
36
36
|
throw error
|
|
37
|
+
} finally {
|
|
38
|
+
performance.mark(`end:${orderPackageItemId} - ${productBarcode}`)
|
|
39
|
+
let perf = performance.measure(`scanProductPacking: ${orderPackageItemId} - ${productBarcode}`, `start:${orderPackageItemId} - ${productBarcode}`, `end:${orderPackageItemId} - ${productBarcode}`)
|
|
40
|
+
console.info(perf.toJSON())
|
|
37
41
|
}
|
|
38
42
|
}
|
package/server/utils/lmd-util.ts
CHANGED
|
@@ -20,7 +20,7 @@ export async function createLmdParcel(releaseGoods, tx) {
|
|
|
20
20
|
try {
|
|
21
21
|
let parcelsRequest = []
|
|
22
22
|
for (let releaseGood of releaseGoods) {
|
|
23
|
-
|
|
23
|
+
let lmd: LastMileDelivery = releaseGood.lastMileDelivery
|
|
24
24
|
|
|
25
25
|
const bizplace: Bizplace = await tx.getRepository(Bizplace).findOne({
|
|
26
26
|
where: { domain: releaseGood.domain },
|
|
@@ -38,7 +38,8 @@ export async function createLmdParcel(releaseGoods, tx) {
|
|
|
38
38
|
if(lmd?.platform=='NINJA_VAN'){
|
|
39
39
|
const currentTimestamp: number = Math.floor(Date.now() / 1000)
|
|
40
40
|
if (currentTimestamp >= lmd?.expiresIn) {
|
|
41
|
-
await refreshAccessTokenNinjavan(lmd?.id,{state:{ tx }})
|
|
41
|
+
const lastMileDelivery= await refreshAccessTokenNinjavan(lmd?.id,{state:{ tx }})
|
|
42
|
+
lmd.accessToken=lastMileDelivery.accessToken
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
|