@things-factory/worksheet-base 4.0.7 → 4.0.12
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/constants/template.js +1 -0
- package/dist-server/constants/template.js.map +1 -1
- package/dist-server/controllers/ecommerce/sellercraft-controller.js +3 -3
- package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
- package/dist-server/controllers/inbound/putaway-worksheet-controller.js +24 -5
- package/dist-server/controllers/inbound/putaway-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js +67 -28
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/index.js +1 -0
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/controllers/outbound/loading-worksheet-controller.js +4 -0
- package/dist-server/controllers/outbound/loading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/packing-worksheet-controller.js +1 -3
- package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/picking-worksheet-controller.js +158 -113
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/render-elccl-grn.js +6 -6
- package/dist-server/controllers/render-elccl-grn.js.map +1 -1
- package/dist-server/controllers/render-manifest.js +64 -0
- package/dist-server/controllers/render-manifest.js.map +1 -0
- package/dist-server/controllers/worksheet-controller.js +28 -2
- package/dist-server/controllers/worksheet-controller.js.map +1 -1
- package/dist-server/graphql/resolvers/pallet/pallet-outbound.js +1 -1
- package/dist-server/graphql/resolvers/pallet/pallet-outbound.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +6 -5
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/loading-worksheet.js +23 -2
- package/dist-server/graphql/resolvers/worksheet/loading-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +22 -0
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/pending-cancellation-release-order.js +6 -3
- package/dist-server/graphql/resolvers/worksheet/pending-cancellation-release-order.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/activate-picking.js +0 -4
- package/dist-server/graphql/resolvers/worksheet/picking/activate-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +30 -5
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.js +72 -0
- package/dist-server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.js.map +1 -0
- package/dist-server/graphql/resolvers/worksheet/picking/index.js +2 -1
- package/dist-server/graphql/resolvers/worksheet/picking/index.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/picking.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/picking/picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/scan-product-picking.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/picking/scan-product-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js +86 -57
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/recommend-putway-location.js +2 -2
- package/dist-server/graphql/resolvers/worksheet/recommend-putway-location.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js +6 -1
- package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/unloading-return-worksheet.js +2 -2
- package/dist-server/graphql/resolvers/worksheet/unloading-return-worksheet.js.map +1 -1
- package/dist-server/graphql/types/index.js +1 -2
- package/dist-server/graphql/types/index.js.map +1 -1
- package/dist-server/graphql/types/worksheet/index.js +7 -1
- package/dist-server/graphql/types/worksheet/index.js.map +1 -1
- package/dist-server/routes.js +4 -0
- package/dist-server/routes.js.map +1 -1
- package/dist-server/utils/inventory-util.js +29 -4
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +16 -16
- package/server/constants/template.ts +1 -0
- package/server/controllers/ecommerce/sellercraft-controller.ts +3 -3
- package/server/controllers/inbound/putaway-worksheet-controller.ts +29 -8
- package/server/controllers/inbound/unloading-worksheet-controller.ts +83 -29
- package/server/controllers/index.ts +1 -0
- package/server/controllers/outbound/loading-worksheet-controller.ts +20 -0
- package/server/controllers/outbound/packing-worksheet-controller.ts +3 -5
- package/server/controllers/outbound/picking-worksheet-controller.ts +201 -143
- package/server/controllers/render-elccl-grn.ts +8 -6
- package/server/controllers/render-manifest.ts +68 -0
- package/server/controllers/worksheet-controller.ts +41 -2
- package/server/graphql/resolvers/pallet/pallet-outbound.ts +1 -2
- package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +10 -8
- package/server/graphql/resolvers/worksheet/loading-worksheet.ts +30 -4
- package/server/graphql/resolvers/worksheet/packing-worksheet.ts +28 -3
- package/server/graphql/resolvers/worksheet/pending-cancellation-release-order.ts +13 -7
- package/server/graphql/resolvers/worksheet/picking/activate-picking.ts +1 -6
- package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +35 -4
- package/server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.ts +78 -0
- package/server/graphql/resolvers/worksheet/picking/index.ts +3 -1
- package/server/graphql/resolvers/worksheet/picking/picking.ts +6 -4
- package/server/graphql/resolvers/worksheet/picking/scan-product-picking.ts +7 -4
- package/server/graphql/resolvers/worksheet/picking-worksheet.ts +102 -62
- package/server/graphql/resolvers/worksheet/recommend-putway-location.ts +4 -2
- package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +10 -1
- package/server/graphql/resolvers/worksheet/unloading-return-worksheet.ts +6 -4
- package/server/graphql/types/index.ts +1 -2
- package/server/graphql/types/worksheet/index.ts +8 -2
- package/server/routes.ts +5 -0
- package/server/utils/inventory-util.ts +31 -9
- package/dist-server/graphql/types/pallet/index.js +0 -10
- package/dist-server/graphql/types/pallet/index.js.map +0 -1
- package/server/graphql/types/pallet/index.ts +0 -6
|
@@ -17,7 +17,8 @@ import {
|
|
|
17
17
|
INVENTORY_STATUS,
|
|
18
18
|
INVENTORY_TRANSACTION_TYPE,
|
|
19
19
|
Location,
|
|
20
|
-
LOCATION_TYPE
|
|
20
|
+
LOCATION_TYPE,
|
|
21
|
+
LOCATION_STATUS
|
|
21
22
|
} from '@things-factory/warehouse-base'
|
|
22
23
|
|
|
23
24
|
import { TASK_NUMBER_RULE_TYPE, TASK_NUMBER_SETTING_KEY, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
|
|
@@ -190,7 +191,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
190
191
|
if (vasWorksheet) {
|
|
191
192
|
await this.activateVAS(vasWorksheet.name, vasWorksheet.worksheetDetails)
|
|
192
193
|
}
|
|
193
|
-
} catch (e) {}
|
|
194
|
+
} catch (e) { }
|
|
194
195
|
|
|
195
196
|
const pendingSplitOIs: OrderInventory[] = await this.trxMgr.getRepository(OrderInventory).find({
|
|
196
197
|
where: { domain: this.domain, releaseGood, status: ORDER_INVENTORY_STATUS.PENDING_SPLIT }
|
|
@@ -386,106 +387,92 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
386
387
|
worksheetType: string,
|
|
387
388
|
productBarcode: string,
|
|
388
389
|
cartonId: string,
|
|
389
|
-
binLocation?: string
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
390
|
+
binLocation?: string,
|
|
391
|
+
serialNumber?: string
|
|
392
|
+
): Promise<OrderInventory> {
|
|
393
|
+
try {
|
|
394
|
+
let worksheetDetail: WorksheetDetail = await this.findExecutableWorksheetDetailByName(
|
|
395
|
+
worksheetDetailName,
|
|
396
|
+
worksheetType,
|
|
397
|
+
[
|
|
398
|
+
'worksheet',
|
|
399
|
+
'worksheet.bizplace',
|
|
400
|
+
'targetInventory',
|
|
401
|
+
'targetInventory.releaseGood',
|
|
402
|
+
'targetInventory.inventory',
|
|
403
|
+
'targetInventory.product',
|
|
404
|
+
'targetInventory.product.productDetails',
|
|
405
|
+
'targetInventory.product.productDetails.product',
|
|
406
|
+
'targetInventory.product.productDetails.childProductDetail'
|
|
407
|
+
]
|
|
408
|
+
)
|
|
406
409
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const packingType: string = inventory.packingType
|
|
412
|
-
const packingSize: number = inventory.packingSize
|
|
410
|
+
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
411
|
+
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
412
|
+
const product: Product = targetInventory.product
|
|
413
|
+
let inventory: Inventory = targetInventory.inventory
|
|
413
414
|
|
|
414
|
-
|
|
415
|
-
|
|
415
|
+
//validation to prevent duplicated picking
|
|
416
|
+
let oiValidate: OrderInventory = await this.trxMgr.getRepository(OrderInventory).findOne({
|
|
417
|
+
where: { domain: this.domain, id: targetInventory.id, status: ORDER_INVENTORY_STATUS.PICKING }
|
|
418
|
+
})
|
|
419
|
+
if (!oiValidate)
|
|
420
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`))
|
|
416
421
|
|
|
417
|
-
|
|
418
|
-
|
|
422
|
+
//validation to prevent over release
|
|
423
|
+
if (inventory.qty <= 0)
|
|
424
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
419
425
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
|
|
423
|
-
if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
426
|
+
if (inventory.cartonId !== cartonId)
|
|
427
|
+
throw new Error(this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE('Carton ID', cartonId, inventory.cartonId))
|
|
424
428
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
(detail: ProductDetail) =>
|
|
428
|
-
detail.gtin === productBarcode &&
|
|
429
|
-
detail.packingType === packingType &&
|
|
430
|
-
detail.packingSize == packingSize &&
|
|
431
|
-
detail.product?.id === product.id
|
|
432
|
-
)
|
|
429
|
+
const packingType: string = inventory.packingType
|
|
430
|
+
const packingSize: number = inventory.packingSize
|
|
433
431
|
|
|
434
|
-
|
|
435
|
-
const
|
|
436
|
-
(parentDetail: ProductDetail) =>
|
|
437
|
-
parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
|
|
438
|
-
)
|
|
439
|
-
|
|
440
|
-
pickedQty = await this.getChildQty(productDetails, productBarcode, roProductDetail)
|
|
441
|
-
if (pickedQty > releaseQty) {
|
|
442
|
-
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
443
|
-
}
|
|
444
|
-
}
|
|
432
|
+
let pickedQty: number = 1
|
|
433
|
+
const releaseQty: number = targetInventory.releaseQty
|
|
445
434
|
|
|
446
|
-
|
|
447
|
-
if (targetInventory.pickedQty == releaseQty) {
|
|
448
|
-
const leftQty: number = inventory.qty - releaseQty
|
|
449
|
-
if (leftQty < 0) {
|
|
450
|
-
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
|
|
451
|
-
}
|
|
435
|
+
targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
|
|
452
436
|
|
|
453
|
-
|
|
437
|
+
// search for matching product barcode
|
|
438
|
+
const productDetails: ProductDetail[] = product?.productDetails.filter(detail => !detail.deletedAt)
|
|
439
|
+
const isMatchingBarcode: boolean = productDetails.map(detail => detail.gtin).includes(productBarcode)
|
|
440
|
+
if (!isMatchingBarcode) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
454
441
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
442
|
+
// case for scanning parent packing type, packing size
|
|
443
|
+
const foundProductDetail: ProductDetail = productDetails.find(
|
|
444
|
+
(detail: ProductDetail) =>
|
|
445
|
+
detail.gtin === productBarcode &&
|
|
446
|
+
detail.packingType === packingType &&
|
|
447
|
+
detail.packingSize == packingSize &&
|
|
448
|
+
detail.product?.id === product.id
|
|
449
|
+
)
|
|
459
450
|
|
|
460
|
-
|
|
461
|
-
|
|
451
|
+
if (!foundProductDetail) {
|
|
452
|
+
const roProductDetail: ProductDetail = productDetails.find(
|
|
453
|
+
(parentDetail: ProductDetail) =>
|
|
454
|
+
parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
|
|
455
|
+
)
|
|
462
456
|
|
|
463
|
-
|
|
457
|
+
pickedQty = await this.getChildQty(productDetails, productBarcode, roProductDetail)
|
|
458
|
+
if (pickedQty > releaseQty) {
|
|
459
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
460
|
+
}
|
|
464
461
|
}
|
|
465
|
-
await this.updateOrderTargets([targetInventory])
|
|
466
462
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
inventory.lockedUomValue = Math.round((inventory.lockedUomValue - targetInventory.releaseUomValue) * 100) / 100
|
|
471
|
-
inventory = await this.transactionInventory(
|
|
472
|
-
inventory,
|
|
473
|
-
releaseGood,
|
|
474
|
-
-targetInventory.releaseQty,
|
|
475
|
-
-targetInventory.releaseUomValue,
|
|
476
|
-
INVENTORY_TRANSACTION_TYPE.PICKING
|
|
477
|
-
)
|
|
463
|
+
if (product?.isRequireSerialNumberScanning) {
|
|
464
|
+
if ((!serialNumber || serialNumber == ''))
|
|
465
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`))
|
|
478
466
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
if (leftQty === 0) {
|
|
484
|
-
inventory.status = INVENTORY_STATUS.TERMINATED
|
|
485
|
-
await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
|
|
467
|
+
if (serialNumber) {
|
|
468
|
+
targetInventory.serialNumber = JSON.stringify(targetInventory.serialNumber ? [...(JSON.parse(targetInventory.serialNumber)), serialNumber] : [serialNumber])
|
|
469
|
+
}
|
|
486
470
|
}
|
|
487
|
-
|
|
488
|
-
await this.
|
|
471
|
+
|
|
472
|
+
await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
|
|
473
|
+
|
|
474
|
+
} catch (error) {
|
|
475
|
+
throw error
|
|
489
476
|
}
|
|
490
477
|
}
|
|
491
478
|
|
|
@@ -494,70 +481,75 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
494
481
|
worksheetType: string,
|
|
495
482
|
palletId: string,
|
|
496
483
|
locationName: string,
|
|
497
|
-
|
|
484
|
+
pickedQty: number,
|
|
485
|
+
binLocation?: string,
|
|
486
|
+
serialNumber?: string
|
|
498
487
|
): Promise<void> {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
let inventory: Inventory = targetInventory.inventory
|
|
513
|
-
if (inventory.palletId !== palletId)
|
|
514
|
-
throw new Error(this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE('Pallet ID', palletId, inventory.palletId))
|
|
515
|
-
|
|
516
|
-
const leftQty: number = inventory.qty - releaseQty
|
|
517
|
-
if (leftQty < 0) {
|
|
518
|
-
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
|
|
519
|
-
}
|
|
488
|
+
try {
|
|
489
|
+
let worksheetDetail: WorksheetDetail = await this.findExecutableWorksheetDetailByName(
|
|
490
|
+
worksheetDetailName,
|
|
491
|
+
worksheetType,
|
|
492
|
+
[
|
|
493
|
+
'worksheet',
|
|
494
|
+
'targetInventory',
|
|
495
|
+
'targetInventory.releaseGood',
|
|
496
|
+
'targetInventory.inventory',
|
|
497
|
+
'targetInventory.inventory.location',
|
|
498
|
+
'targetInventory.product',
|
|
499
|
+
]
|
|
500
|
+
)
|
|
520
501
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
inventory.qty -= targetInventory.releaseQty
|
|
526
|
-
inventory.uomValue = Math.round((inventory.uomValue - targetInventory.releaseUomValue) * 100) / 100
|
|
527
|
-
inventory.lockedQty = inventory.lockedQty - targetInventory.releaseQty
|
|
528
|
-
inventory.lockedUomValue = Math.round((inventory.lockedUomValue - targetInventory.releaseUomValue) * 100) / 100
|
|
529
|
-
inventory = await this.transactionInventory(
|
|
530
|
-
inventory,
|
|
531
|
-
releaseGood,
|
|
532
|
-
-targetInventory.releaseQty,
|
|
533
|
-
-targetInventory.releaseUomValue,
|
|
534
|
-
INVENTORY_TRANSACTION_TYPE.PICKING
|
|
535
|
-
)
|
|
502
|
+
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
503
|
+
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
504
|
+
const product: Product = targetInventory.product
|
|
505
|
+
let inventory: Inventory = targetInventory.inventory
|
|
536
506
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
507
|
+
//validation to prevent duplicated picking
|
|
508
|
+
let oiValidate: OrderInventory = await this.trxMgr.getRepository(OrderInventory).findOne({
|
|
509
|
+
where: { domain: this.domain, id: targetInventory.id, status: ORDER_INVENTORY_STATUS.PICKING }
|
|
510
|
+
})
|
|
511
|
+
if (!oiValidate)
|
|
512
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `is done`))
|
|
540
513
|
|
|
541
|
-
|
|
542
|
-
inventory.
|
|
543
|
-
|
|
544
|
-
}
|
|
514
|
+
//validation to prevent over release
|
|
515
|
+
if (inventory.qty <= 0)
|
|
516
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
545
517
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
const toLocation: Location = await this.trxMgr.getRepository(Location).findOne({
|
|
549
|
-
where: { domain: this.domain, name: locationName },
|
|
550
|
-
relations: ['warehouse']
|
|
551
|
-
})
|
|
518
|
+
if (inventory.palletId !== palletId)
|
|
519
|
+
throw new Error(this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE('Pallet ID', palletId, inventory.palletId))
|
|
552
520
|
|
|
553
|
-
if (!toLocation) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(locationName))
|
|
554
521
|
|
|
555
|
-
if (
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
522
|
+
if (product?.isRequireSerialNumberScanning) {
|
|
523
|
+
if ((!serialNumber || serialNumber == ''))
|
|
524
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`))
|
|
525
|
+
|
|
526
|
+
if (serialNumber) {
|
|
527
|
+
targetInventory.serialNumber = JSON.stringify(targetInventory.serialNumber ? [...(JSON.parse(targetInventory.serialNumber)), serialNumber] : [serialNumber])
|
|
528
|
+
}
|
|
560
529
|
}
|
|
530
|
+
|
|
531
|
+
targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
|
|
532
|
+
|
|
533
|
+
await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
|
|
534
|
+
|
|
535
|
+
const fromLocation: Location = targetInventory.inventory.location
|
|
536
|
+
if (locationName) {
|
|
537
|
+
const toLocation: Location = await this.trxMgr.getRepository(Location).findOne({
|
|
538
|
+
where: { domain: this.domain, name: locationName },
|
|
539
|
+
relations: ['warehouse']
|
|
540
|
+
})
|
|
541
|
+
|
|
542
|
+
if (!toLocation) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(locationName))
|
|
543
|
+
|
|
544
|
+
if (fromLocation.id !== toLocation.id) {
|
|
545
|
+
inventory.location = toLocation
|
|
546
|
+
inventory.warehouse = toLocation.warehouse
|
|
547
|
+
inventory.zone = toLocation.zone
|
|
548
|
+
inventory = await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.RELOCATE)
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
} catch (error) {
|
|
552
|
+
throw error
|
|
561
553
|
}
|
|
562
554
|
}
|
|
563
555
|
|
|
@@ -937,4 +929,70 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
937
929
|
|
|
938
930
|
return worksheetDetails
|
|
939
931
|
}
|
|
932
|
+
|
|
933
|
+
private async checkAndSetBinPicking(orderInventory, binLocation) {
|
|
934
|
+
// bin picking validation
|
|
935
|
+
const binPickingSetting: Setting = await this.trxMgr.getRepository(Setting).findOne({
|
|
936
|
+
where: {
|
|
937
|
+
domain: this.domain,
|
|
938
|
+
name: 'enable-bin-picking'
|
|
939
|
+
}
|
|
940
|
+
})
|
|
941
|
+
if (binPickingSetting != undefined && (binPickingSetting.value).toLowerCase() == 'true') {
|
|
942
|
+
if (binLocation) {
|
|
943
|
+
const foundBinLocation: Location = await this.trxMgr.getRepository(Location).findOne({
|
|
944
|
+
where: { domain: this.domain, name: binLocation, type: LOCATION_TYPE.BIN }
|
|
945
|
+
})
|
|
946
|
+
|
|
947
|
+
if (!foundBinLocation)
|
|
948
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`))
|
|
949
|
+
|
|
950
|
+
orderInventory.binLocation = foundBinLocation
|
|
951
|
+
} else {
|
|
952
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`))
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
return orderInventory
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
private async updatePickingTransaction(releaseGood, orderInventory, worksheetDetail, inventory, pickedQty) {
|
|
960
|
+
const releaseQty: number = orderInventory.releaseQty
|
|
961
|
+
|
|
962
|
+
orderInventory.pickedQty = Boolean(orderInventory?.pickedQty) ? orderInventory.pickedQty + pickedQty : pickedQty
|
|
963
|
+
if (orderInventory.pickedQty == releaseQty) {
|
|
964
|
+
const leftQty: number = inventory.qty - releaseQty
|
|
965
|
+
if (leftQty < 0) {
|
|
966
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`))
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
orderInventory.status = ORDER_INVENTORY_STATUS.PICKED
|
|
970
|
+
|
|
971
|
+
inventory.qty -= orderInventory.releaseQty
|
|
972
|
+
inventory.uomValue = Math.round((inventory.uomValue - orderInventory.releaseUomValue) * 100) / 100
|
|
973
|
+
inventory.lockedQty = inventory.lockedQty - orderInventory.releaseQty
|
|
974
|
+
inventory.lockedUomValue = Math.round((inventory.lockedUomValue - orderInventory.releaseUomValue) * 100) / 100
|
|
975
|
+
inventory = await this.transactionInventory(
|
|
976
|
+
inventory,
|
|
977
|
+
releaseGood,
|
|
978
|
+
-orderInventory.releaseQty,
|
|
979
|
+
-orderInventory.releaseUomValue,
|
|
980
|
+
INVENTORY_TRANSACTION_TYPE.PICKING
|
|
981
|
+
)
|
|
982
|
+
|
|
983
|
+
worksheetDetail.status = WORKSHEET_STATUS.DONE
|
|
984
|
+
worksheetDetail.updater = this.user
|
|
985
|
+
await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
986
|
+
|
|
987
|
+
if (leftQty === 0) {
|
|
988
|
+
inventory.status = INVENTORY_STATUS.TERMINATED
|
|
989
|
+
await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
await this.updateOrderTargets([orderInventory])
|
|
994
|
+
|
|
995
|
+
return orderInventory
|
|
996
|
+
}
|
|
940
997
|
}
|
|
998
|
+
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import FormData from 'form-data'
|
|
2
|
+
import fetch from 'node-fetch'
|
|
3
|
+
import { EntityManager, getManager, getRepository } from 'typeorm'
|
|
4
|
+
|
|
1
5
|
import { Attachment, STORAGE } from '@things-factory/attachment-base'
|
|
2
6
|
import { Bizplace, ContactPoint } from '@things-factory/biz-base'
|
|
3
7
|
import { config } from '@things-factory/env'
|
|
4
8
|
import { ArrivalNotice, GoodsReceivalNote, ORDER_PRODUCT_STATUS, ORDER_STATUS } from '@things-factory/sales-base'
|
|
5
9
|
import { Domain } from '@things-factory/shell'
|
|
6
|
-
|
|
7
|
-
import fetch from 'node-fetch'
|
|
8
|
-
import { EntityManager, getManager, getRepository } from 'typeorm'
|
|
10
|
+
|
|
9
11
|
import { TEMPLATE_TYPE, TRANSACTION_TYPE } from '../constants'
|
|
10
12
|
import { Worksheet } from '../entities'
|
|
11
13
|
import { DateTimeConverter } from '../utils/datetime-util'
|
|
@@ -117,19 +119,19 @@ export async function renderElcclGRN({ grnNo }, context: any) {
|
|
|
117
119
|
`
|
|
118
120
|
create temp table tmp2 on commit drop as(
|
|
119
121
|
select id,seq,ref_order_id,order_no,"name",pallet_id,batch_id,product_id,warehouse_id,location_id,"zone",order_ref_no,packing_type,uom as unit,qty,
|
|
120
|
-
opening_qty,uom_value,
|
|
122
|
+
opening_qty,uom_value,description,status,transaction_type,created_at,updated_at,domain_id,bizplace_id,creator_id,updater_id,
|
|
121
123
|
reusable_pallet_id,release_order_id,release_qty,inbound_qty,remaining_qty, inbound_qty as loose_amt, release_uom_value, inbound_uom_value,remaining_uom_value,
|
|
122
124
|
inbound_uom_value as loose_wgt, null as cross_dock, inventory_id
|
|
123
125
|
from tmp where release_qty > 0 or release_qty is null
|
|
124
126
|
union all
|
|
125
127
|
select id,seq,ref_order_id,order_no,"name",pallet_id,batch_id,product_id,warehouse_id,location_id,"zone",order_ref_no,packing_type,uom as unit,qty,
|
|
126
|
-
opening_qty,uom_value,
|
|
128
|
+
opening_qty,uom_value,description,status,transaction_type,created_at,updated_at,domain_id,bizplace_id,creator_id,updater_id,
|
|
127
129
|
reusable_pallet_id,release_order_id,release_qty,inbound_qty,remaining_qty, remaining_qty as loose_amt, release_uom_value, inbound_uom_value,remaining_uom_value,
|
|
128
130
|
remaining_uom_value as loose_wgt, null as cross_dock, inventory_id
|
|
129
131
|
from tmp where release_qty < 0 and remaining_qty > 0
|
|
130
132
|
union all
|
|
131
133
|
select id,seq,ref_order_id,order_no,"name",pallet_id,batch_id,product_id,warehouse_id,location_id,"zone",order_ref_no,packing_type,uom as unit,qty,
|
|
132
|
-
opening_qty,uom_value,
|
|
134
|
+
opening_qty,uom_value,description,status,transaction_type,created_at,updated_at,domain_id,bizplace_id,creator_id,updater_id,
|
|
133
135
|
reusable_pallet_id,release_order_id,release_qty,inbound_qty,remaining_qty, -release_qty as loose_amt, release_uom_value,inbound_uom_value,remaining_uom_value,
|
|
134
136
|
-release_uom_value as loose_wgt, '[C/D]' as cross_dock, inventory_id
|
|
135
137
|
from tmp where release_qty < 0
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import FormData from 'form-data'
|
|
2
|
+
import fetch from 'node-fetch'
|
|
3
|
+
import { getRepository } from 'typeorm'
|
|
4
|
+
|
|
5
|
+
import { Attachment, STORAGE } from '@things-factory/attachment-base'
|
|
6
|
+
import { config } from '@things-factory/env'
|
|
7
|
+
import { Manifest, ReleaseGood } from '@things-factory/sales-base'
|
|
8
|
+
import { Domain } from '@things-factory/shell'
|
|
9
|
+
|
|
10
|
+
import { TEMPLATE_TYPE } from '../constants'
|
|
11
|
+
import { DateTimeConverter } from '../utils/datetime-util'
|
|
12
|
+
|
|
13
|
+
const REPORT_API_URL = config.get('reportApiUrl', 'http://localhost:8888/rest/report/show_html')
|
|
14
|
+
|
|
15
|
+
export async function renderManifest({ manifestNo }, context: any) {
|
|
16
|
+
// 1. find domain
|
|
17
|
+
const domain: Domain = await getRepository(Domain).findOne({
|
|
18
|
+
where: { id: context.state.domain.id }
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// 2. find manifest
|
|
22
|
+
const manifest: Manifest = await getRepository(Manifest).findOne({
|
|
23
|
+
where: { domain, name: manifestNo },
|
|
24
|
+
relations: ['domain']
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// find release good
|
|
28
|
+
const releaseGoods: ReleaseGood[] = await getRepository(ReleaseGood).find({
|
|
29
|
+
where: { domain, manifest }
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// 7. find grn template based on category
|
|
33
|
+
const foundTemplate: Attachment = await getRepository(Attachment).findOne({
|
|
34
|
+
where: { domain, category: TEMPLATE_TYPE.MANIFEST_TEMPLATE }
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const template = await STORAGE.readFile(foundTemplate.path, 'utf-8')
|
|
38
|
+
|
|
39
|
+
const data = {
|
|
40
|
+
shipping_provider: manifest?.shippingProvider,
|
|
41
|
+
manifest_no: manifest?.name,
|
|
42
|
+
manifest_date: DateTimeConverter.date(manifest?.createdAt).toString(),
|
|
43
|
+
total_list: releaseGoods?.length || 0,
|
|
44
|
+
product_list: releaseGoods.map((item, idx) => {
|
|
45
|
+
return {
|
|
46
|
+
list_no: idx + 1,
|
|
47
|
+
order_no: item?.refNo,
|
|
48
|
+
tracking_no: item?.trackingNo,
|
|
49
|
+
phone: item?.phone1,
|
|
50
|
+
delivery_date: DateTimeConverter.date(manifest?.dispatchedAt).toString(),
|
|
51
|
+
attention_to: item?.attentionTo,
|
|
52
|
+
delivery_address: item?.deliveryAddress1,
|
|
53
|
+
postal_code_city: `${item?.postalCode}, ${item?.city}`
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const formData = new FormData()
|
|
59
|
+
formData.append('template', template)
|
|
60
|
+
formData.append('jsonString', JSON.stringify(data))
|
|
61
|
+
|
|
62
|
+
const response = await fetch(REPORT_API_URL, {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
body: formData
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
return await response.text()
|
|
68
|
+
}
|
|
@@ -555,6 +555,44 @@ export class WorksheetController {
|
|
|
555
555
|
return worksheet
|
|
556
556
|
}
|
|
557
557
|
|
|
558
|
+
// @chernhaoee I think the naming of this function is not proper. Seems like it should be something like "updateLoadingWorksheet" since the logic targets only Loading Order Target
|
|
559
|
+
async updateWorksheet(
|
|
560
|
+
worksheetType: string,
|
|
561
|
+
refOrder: ReferenceOrderType,
|
|
562
|
+
worksheet: Worksheet,
|
|
563
|
+
orderTargets: OrderTargetTypes[],
|
|
564
|
+
refOrderStatus: string,
|
|
565
|
+
orderTargetStatus: string
|
|
566
|
+
): Promise<Worksheet> {
|
|
567
|
+
let newOrderTarget = []
|
|
568
|
+
|
|
569
|
+
orderTargets.forEach((orderTarget: OrderTargetTypes) => {
|
|
570
|
+
orderTarget.status = orderTargetStatus
|
|
571
|
+
})
|
|
572
|
+
orderTargets = await this.updateOrderTargets(orderTargets)
|
|
573
|
+
|
|
574
|
+
for (let orderTarget of orderTargets) {
|
|
575
|
+
try {
|
|
576
|
+
await this.findWorksheetDetail({
|
|
577
|
+
targetInventory: orderTarget.id,
|
|
578
|
+
type: WORKSHEET_TYPE.LOADING
|
|
579
|
+
})
|
|
580
|
+
} catch (e) {
|
|
581
|
+
newOrderTarget.push(orderTarget)
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
worksheet.worksheetDetails = await this.createWorksheetDetails(worksheet, worksheetType, newOrderTarget)
|
|
586
|
+
|
|
587
|
+
// find worksheet details that doesnt exist based on order inventory
|
|
588
|
+
//worksheet.worksheetDetails = await this.findWorksheetDetail(worksheet.id)
|
|
589
|
+
|
|
590
|
+
refOrder.status = refOrderStatus
|
|
591
|
+
await this.updateRefOrder(refOrder)
|
|
592
|
+
|
|
593
|
+
return worksheet
|
|
594
|
+
}
|
|
595
|
+
|
|
558
596
|
async generateBatchWorksheet(
|
|
559
597
|
worksheetType: string,
|
|
560
598
|
batchPickingWorksheet: Worksheet,
|
|
@@ -669,6 +707,7 @@ export class WorksheetController {
|
|
|
669
707
|
} else if (
|
|
670
708
|
worksheetType === WORKSHEET_TYPE.PUTAWAY ||
|
|
671
709
|
worksheetType === WORKSHEET_TYPE.PICKING ||
|
|
710
|
+
worksheetType === WORKSHEET_TYPE.PACKING ||
|
|
672
711
|
worksheetType === WORKSHEET_TYPE.LOADING ||
|
|
673
712
|
worksheetType === WORKSHEET_TYPE.WAREHOUSE_RETURN ||
|
|
674
713
|
worksheetType === WORKSHEET_TYPE.UNLOADING_RETURN
|
|
@@ -928,13 +967,13 @@ export class WorksheetController {
|
|
|
928
967
|
)
|
|
929
968
|
if (!currentProductDetail)
|
|
930
969
|
throw new Error(this.ERROR_MSG.FIND.NOT_MATCH('inner pack', `GTIN (${productBarcode})`))
|
|
931
|
-
childQty = scannedProductDetail.
|
|
970
|
+
childQty = scannedProductDetail.packingSize
|
|
932
971
|
} else {
|
|
933
972
|
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
934
973
|
}
|
|
935
974
|
|
|
936
975
|
if (hasMatchingChild) {
|
|
937
|
-
childQty = scannedProductDetail.
|
|
976
|
+
childQty = scannedProductDetail.packingSize
|
|
938
977
|
} else {
|
|
939
978
|
while (hasChildRelation && !hasMatchingChild) {
|
|
940
979
|
hasChildRelation = Boolean(currentProductDetail?.childProductDetail)
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { EntityManager, In } from 'typeorm'
|
|
2
|
-
|
|
3
1
|
import { User } from '@things-factory/auth-base'
|
|
4
2
|
import { Bizplace } from '@things-factory/biz-base'
|
|
5
3
|
import { ReleaseGood } from '@things-factory/sales-base'
|
|
6
4
|
import { Domain } from '@things-factory/shell'
|
|
7
5
|
import { Pallet, PalletHistory } from '@things-factory/warehouse-base'
|
|
6
|
+
import { EntityManager, getRepository, In } from 'typeorm'
|
|
8
7
|
|
|
9
8
|
export const palletOutbound = {
|
|
10
9
|
async palletOutbound(_: any, { refOrderNo, patches }, context: any) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
1
|
+
import { Brackets, getRepository, SelectQueryBuilder } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
import { User } from '@things-factory/auth-base'
|
|
4
4
|
import { getPermittedBizplaceIds } from '@things-factory/biz-base'
|
|
5
|
-
import { Inventory } from '@things-factory/warehouse-base'
|
|
6
5
|
import { ORDER_INVENTORY_STATUS } from '@things-factory/sales-base'
|
|
7
|
-
import {
|
|
6
|
+
import { buildCondition, buildQuery, Domain } from '@things-factory/shell'
|
|
7
|
+
import { Inventory, LOCATION_TYPE } from '@things-factory/warehouse-base'
|
|
8
8
|
|
|
9
9
|
export const inventoriesByPalletResolver = {
|
|
10
10
|
async inventoriesByPallet(_: any, { filters, pagination, sortings, locationSortingRules }, context: any) {
|
|
@@ -41,10 +41,11 @@ export const inventoriesByPalletResolver = {
|
|
|
41
41
|
.andWhere('iv.qty > 0')
|
|
42
42
|
.andWhere('CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END >= 0')
|
|
43
43
|
.andWhere('iv.qty - CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END > 0')
|
|
44
|
+
.andWhere(`location.type NOT IN ('${LOCATION_TYPE.QUARANTINE}', '${LOCATION_TYPE.RESERVE}')`)
|
|
44
45
|
.andWhere(
|
|
45
|
-
`(iv.batch_id, product.name, iv.packing_type) NOT IN (
|
|
46
|
+
`(iv.batch_id, product.name, iv.packing_type, product.brand) NOT IN (
|
|
46
47
|
SELECT
|
|
47
|
-
oi.batch_id, p2.name, oi.packing_type
|
|
48
|
+
oi.batch_id, p2.name, oi.packing_type, p2.brand
|
|
48
49
|
FROM
|
|
49
50
|
order_inventories oi
|
|
50
51
|
LEFT JOIN
|
|
@@ -112,7 +113,8 @@ export const inventoriesByPalletResolver = {
|
|
|
112
113
|
remainUomValueWithUom: remainUomValue + ' ' + item.uom,
|
|
113
114
|
// product: item.product,
|
|
114
115
|
productName: item.product.name,
|
|
115
|
-
productSKU: item.product.sku
|
|
116
|
+
productSKU: item.product.sku,
|
|
117
|
+
productBrand: item.product.brand
|
|
116
118
|
}
|
|
117
119
|
})
|
|
118
120
|
)
|