@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.
@@ -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
- let orderPackageItem: OrderPackageItem = await this.trxMgr.getRepository(OrderPackageItem).findOne({
310
- where: { id: orderPackageItemId },
311
- relations: ['orderPackage', 'orderProduct', 'orderProduct.orderInventories']
312
- })
313
-
314
- const orderProduct: OrderProduct = orderPackageItem.orderProduct
315
- const orderInventories: OrderInventory[] = orderProduct.orderInventories.filter(oi => oi.packedQty != oi.pickedQty)
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
- for (let orderInventory of orderInventories) {
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('pd.productBarcodes', 'pb')
330
- .where('oi.id = :id', { id: orderInventory.id })
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
- if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
344
- throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
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
- matchingProduct = await this.getDirectQty(
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: targetInventory?.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
- if (packedQty + targetInventory.packedQty > pickedQty) {
362
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
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
- if (targetInventory?.refWorksheetId) {
367
- if (product?.isRequireSerialNumberScanningOutbound) {
368
- if (!serialNumber || serialNumber == '') {
369
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('packing', `require serial number`))
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
- if (foundSerialNumber.outboundOrderId) {
382
- let releaseGood: ReleaseGood = await this.trxMgr
383
- .getRepository(ReleaseGood)
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
- foundSerialNumber.status = INVENTORY_STATUS.PACKING
389
- foundSerialNumber.updater = this.user
390
- foundSerialNumber.outboundOrderId = releaseGood.id
364
+ if (inventoryItem) {
365
+ if (inventoryItem.inventoryId !== inventory.id) {
366
+ throw new Error('Serial Number scanned is in another inventory')
367
+ }
391
368
 
392
- await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
393
- } else {
394
- let inventoryItem: InventoryItem = new InventoryItem()
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
- await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
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
- targetInventory.packedQty = Boolean(targetInventory?.packedQty)
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
- targetInventory.packedAt = new Date()
420
- targetInventory.packedByUser = this.user
421
-
422
- let packedBy: string[] = targetInventory.packedBy ? targetInventory.packedBy.split(',') : []
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
- targetInventory.packedBy = packedBy.join(',')
400
+ orderInventory.packedBy = packedBy.join(',')
426
401
  }
427
402
 
428
- if (targetInventory.packedQty == pickedQty) {
429
- targetInventory.status = ORDER_INVENTORY_STATUS.PACKED
430
- await this.updateOrderTargets([targetInventory])
431
- await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.PACKING)
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
- worksheetDetail.status = WORKSHEET_STATUS.DONE
434
- worksheetDetail.updater = this.user
435
- await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
413
+ if (inventoryItem) {
414
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
415
+ }
416
+ orderInventory = (await this.updateOrderTargets([orderInventory]))[0]
436
417
 
437
- let inventoryItems: InventoryItem = await this.trxMgr
438
- .getRepository(InventoryItem)
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
- if (inventoryItems.length > 0) {
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
- await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
448
- }
449
- } else {
450
- await this.trxMgr.getRepository(OrderInventory).save(targetInventory)
451
- }
452
- break
453
- }
454
-
455
- orderPackageItem.packedQty = Boolean(orderPackageItem?.packedQty)
456
- ? orderPackageItem.packedQty + packedQty
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
- if (orderPackageItem.packedQty == orderPackageItem.releaseQty) {
460
- orderPackageItem.status = ORDER_STATUS.DONE
461
- } else if (orderPackageItem.packedQty > orderPackageItem.releaseQty) {
462
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('pack', `packed quantity can't exceed release qty`))
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
- return {
471
- worksheetDetailInfos: [
472
- {
473
- id: orderPackageItem.id,
474
- releaseQty: orderPackageItem.releaseQty,
475
- packedQty: orderPackageItem.packedQty,
476
- status: orderPackageItem.status
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
@@ -416,7 +416,7 @@ export class WorksheetController {
416
416
  let existingWorksheet: Worksheet
417
417
  try {
418
418
  existingWorksheet = await this.findWorksheetByRefOrder(refOrder, type)
419
- } catch (e) {}
419
+ } catch (e) { }
420
420
 
421
421
  if (existingWorksheet)
422
422
  throw new Error(
@@ -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
- console.time(`execution time to scan for packing ${orderPackageItemId} - ${productBarcode}`)
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
  }
@@ -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
- const lmd: LastMileDelivery = releaseGood.lastMileDelivery
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