@things-factory/worksheet-base 4.1.33 → 4.1.36
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 +299 -2
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/picking-worksheet-controller.js +327 -39
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/render-invoices.js +16 -14
- package/dist-server/controllers/render-invoices.js.map +1 -1
- package/dist-server/controllers/worksheet-controller.js +14 -0
- package/dist-server/controllers/worksheet-controller.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js +16 -2
- package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +0 -17
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
- 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/undo-serial-number-picking.js +15 -0
- package/dist-server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.js.map +1 -0
- package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js +3 -2
- package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/unloading/index.js +3 -1
- package/dist-server/graphql/resolvers/worksheet/unloading/index.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.js +15 -0
- package/dist-server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.js.map +1 -0
- package/dist-server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.js +15 -0
- package/dist-server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.js.map +1 -0
- package/dist-server/graphql/resolvers/worksheet/unloading/unload.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/unloading-worksheet.js +3 -1
- package/dist-server/graphql/resolvers/worksheet/unloading-worksheet.js.map +1 -1
- package/dist-server/graphql/types/worksheet/index.js +16 -0
- package/dist-server/graphql/types/worksheet/index.js.map +1 -1
- package/dist-server/graphql/types/worksheet/worksheet-detail-info.js +1 -0
- package/dist-server/graphql/types/worksheet/worksheet-detail-info.js.map +1 -1
- package/dist-server/graphql/types/worksheet/worksheet-info.js +1 -0
- package/dist-server/graphql/types/worksheet/worksheet-info.js.map +1 -1
- package/package.json +8 -8
- package/server/controllers/inbound/unloading-worksheet-controller.ts +361 -6
- package/server/controllers/outbound/picking-worksheet-controller.ts +433 -52
- package/server/controllers/render-invoices.ts +24 -27
- package/server/controllers/worksheet-controller.ts +17 -2
- package/server/graphql/resolvers/worksheet/loading/complete-loading.ts +25 -6
- package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +0 -18
- package/server/graphql/resolvers/worksheet/picking/index.ts +3 -1
- package/server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.ts +24 -0
- package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +6 -2
- package/server/graphql/resolvers/worksheet/unloading/index.ts +4 -0
- package/server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.ts +26 -0
- package/server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.ts +24 -0
- package/server/graphql/resolvers/worksheet/unloading/unload.ts +3 -1
- package/server/graphql/resolvers/worksheet/unloading-worksheet.ts +3 -1
- package/server/graphql/types/worksheet/index.ts +16 -0
- package/server/graphql/types/worksheet/worksheet-detail-info.ts +1 -0
- package/server/graphql/types/worksheet/worksheet-info.ts +1 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { In } from 'typeorm'
|
|
1
|
+
import { Equal, In, Not } from 'typeorm'
|
|
2
2
|
|
|
3
3
|
import { Bizplace } from '@things-factory/biz-base'
|
|
4
4
|
import { generateId } from '@things-factory/id-rule-base'
|
|
@@ -14,8 +14,11 @@ import {
|
|
|
14
14
|
import { Setting } from '@things-factory/setting-base'
|
|
15
15
|
import {
|
|
16
16
|
Inventory,
|
|
17
|
+
INVENTORY_ITEM_SOURCE,
|
|
17
18
|
INVENTORY_STATUS,
|
|
18
19
|
INVENTORY_TRANSACTION_TYPE,
|
|
20
|
+
InventoryItem,
|
|
21
|
+
InventoryNoGenerator,
|
|
19
22
|
Location,
|
|
20
23
|
LOCATION_TYPE
|
|
21
24
|
} from '@things-factory/warehouse-base'
|
|
@@ -190,7 +193,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
190
193
|
if (vasWorksheet) {
|
|
191
194
|
await this.activateVAS(vasWorksheet.name, vasWorksheet.worksheetDetails)
|
|
192
195
|
}
|
|
193
|
-
} catch (e) {
|
|
196
|
+
} catch (e) {}
|
|
194
197
|
|
|
195
198
|
const pendingSplitOIs: OrderInventory[] = await this.trxMgr.getRepository(OrderInventory).find({
|
|
196
199
|
where: { domain: this.domain, releaseGood, status: ORDER_INVENTORY_STATUS.PENDING_SPLIT }
|
|
@@ -443,7 +446,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
443
446
|
detail.product?.id === product.id
|
|
444
447
|
)
|
|
445
448
|
|
|
446
|
-
if (!foundProductDetail) {
|
|
449
|
+
if (!foundProductDetail && !product?.isRequireSerialNumberScanningOutbound) {
|
|
447
450
|
const roProductDetail: ProductDetail = productDetails.find(
|
|
448
451
|
(parentDetail: ProductDetail) =>
|
|
449
452
|
parentDetail.packingType === packingType && parentDetail.packingSize == packingSize
|
|
@@ -453,26 +456,57 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
453
456
|
if (pickedQty > releaseQty) {
|
|
454
457
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
455
458
|
}
|
|
459
|
+
} else if (!foundProductDetail) {
|
|
460
|
+
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
456
461
|
}
|
|
457
462
|
|
|
458
|
-
if (product?.
|
|
459
|
-
if (!serialNumber || serialNumber == '')
|
|
463
|
+
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
464
|
+
if (!serialNumber || serialNumber == '') {
|
|
460
465
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`))
|
|
461
|
-
|
|
462
|
-
if (serialNumber) {
|
|
463
|
-
targetInventory.serialNumber = JSON.stringify(
|
|
464
|
-
targetInventory.serialNumber ? [...JSON.parse(targetInventory.serialNumber), serialNumber] : [serialNumber]
|
|
465
|
-
)
|
|
466
466
|
}
|
|
467
|
-
}
|
|
468
467
|
|
|
469
|
-
|
|
470
|
-
|
|
468
|
+
let totalInventoryItems = await this.trxMgr.getRepository(InventoryItem).count({
|
|
469
|
+
where: {
|
|
470
|
+
inventory,
|
|
471
|
+
status: Not(Equal(INVENTORY_STATUS.TERMINATED))
|
|
472
|
+
}
|
|
473
|
+
})
|
|
474
|
+
|
|
475
|
+
let foundSerialNumber: InventoryItem = await this.trxMgr
|
|
476
|
+
.getRepository(InventoryItem)
|
|
477
|
+
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
|
|
478
|
+
|
|
479
|
+
if (foundSerialNumber) {
|
|
480
|
+
if (foundSerialNumber.inventoryId !== inventory.id) {
|
|
481
|
+
throw new Error('Serial Number scanned is in another inventory')
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (foundSerialNumber.status !== INVENTORY_STATUS.STORED || foundSerialNumber.outboundOrderId) {
|
|
485
|
+
throw new Error('Inventory Item is not available')
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
foundSerialNumber.status = INVENTORY_STATUS.PICKED
|
|
489
|
+
foundSerialNumber.updater = this.user
|
|
490
|
+
foundSerialNumber.outboundOrderId = releaseGood.id
|
|
471
491
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
492
|
+
await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
|
|
493
|
+
} else {
|
|
494
|
+
if (totalInventoryItems >= inventory.qty) {
|
|
495
|
+
throw new Error('Insufficient inventory quantity to scan new serial number')
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
let inventoryItem: InventoryItem = new InventoryItem()
|
|
499
|
+
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
500
|
+
inventoryItem.serialNumber = serialNumber
|
|
501
|
+
inventoryItem.status = INVENTORY_STATUS.PICKED
|
|
502
|
+
inventoryItem.outboundOrderId = releaseGood.id
|
|
503
|
+
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
504
|
+
inventoryItem.product = product
|
|
505
|
+
inventoryItem.inventory = inventory
|
|
506
|
+
inventoryItem.domain = this.domain
|
|
507
|
+
|
|
508
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
509
|
+
}
|
|
476
510
|
}
|
|
477
511
|
|
|
478
512
|
await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
|
|
@@ -518,32 +552,103 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
518
552
|
//validation to prevent over release
|
|
519
553
|
if (inventory.qty <= 0) throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
520
554
|
|
|
521
|
-
if (inventory.palletId !== palletId)
|
|
555
|
+
if (inventory.palletId !== palletId /*&& !product?.isRequireSerialNumberScanningOutbound*/)
|
|
556
|
+
//to be changed
|
|
522
557
|
throw new Error(this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE('Pallet ID', palletId, inventory.palletId))
|
|
523
558
|
|
|
524
|
-
if (product?.
|
|
525
|
-
if (!serialNumber || serialNumber == '')
|
|
559
|
+
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
560
|
+
if (!serialNumber || serialNumber == '') {
|
|
526
561
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `require serial number`))
|
|
562
|
+
}
|
|
527
563
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
564
|
+
let totalInventoryItems = await this.trxMgr.getRepository(InventoryItem).count({
|
|
565
|
+
where: {
|
|
566
|
+
inventory
|
|
567
|
+
}
|
|
568
|
+
})
|
|
569
|
+
|
|
570
|
+
let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
571
|
+
where: { domain: this.domain, serialNumber: serialNumber, product },
|
|
572
|
+
relations: ['product', 'inventory']
|
|
573
|
+
})
|
|
574
|
+
|
|
575
|
+
let scannedPalletIdInventory: Inventory = await this.trxMgr
|
|
576
|
+
.getRepository(Inventory)
|
|
577
|
+
.findOne({ where: { domain: this.domain, palletId }, relations: ['product'] })
|
|
578
|
+
|
|
579
|
+
if (foundSerialNumber) {
|
|
580
|
+
if (
|
|
581
|
+
foundSerialNumber.status !== INVENTORY_STATUS.STORED ||
|
|
582
|
+
foundSerialNumber.outboundOrderId ||
|
|
583
|
+
foundSerialNumber.inventory !== inventory
|
|
584
|
+
/*to be changed for replacement && inventory.palletId == palletId*/
|
|
585
|
+
) {
|
|
586
|
+
throw new Error('Inventory Item is not available')
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
foundSerialNumber.status = INVENTORY_STATUS.PICKED
|
|
590
|
+
foundSerialNumber.updater = this.user
|
|
591
|
+
foundSerialNumber.outboundOrderId = releaseGood.id
|
|
592
|
+
|
|
593
|
+
await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
|
|
594
|
+
} else {
|
|
595
|
+
if (totalInventoryItems >= inventory.qty) {
|
|
596
|
+
throw new Error('Insufficient inventory quantity to scan new serial number')
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
let inventoryItem: InventoryItem = new InventoryItem()
|
|
600
|
+
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
601
|
+
inventoryItem.serialNumber = serialNumber
|
|
602
|
+
inventoryItem.status = INVENTORY_STATUS.PICKED
|
|
603
|
+
inventoryItem.outboundOrderId = releaseGood.id
|
|
604
|
+
inventoryItem.product = product
|
|
605
|
+
inventoryItem.inventory = scannedPalletIdInventory
|
|
606
|
+
inventoryItem.domain = this.domain
|
|
607
|
+
|
|
608
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
532
609
|
}
|
|
533
|
-
}
|
|
534
|
-
targetInventory.pickedAt = new Date()
|
|
535
|
-
targetInventory.pickedByUser = this.user;
|
|
536
610
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
611
|
+
if (inventory.palletId !== palletId) {
|
|
612
|
+
let existingOrderInv = await this.trxMgr.getRepository(OrderInventory).findOne({
|
|
613
|
+
where: {
|
|
614
|
+
domain: this.domain,
|
|
615
|
+
inventory: scannedPalletIdInventory,
|
|
616
|
+
releaseGood: releaseGood
|
|
617
|
+
}
|
|
618
|
+
})
|
|
542
619
|
|
|
543
|
-
|
|
620
|
+
if (existingOrderInv) {
|
|
621
|
+
//if replacement order inventory already existed in worksheet detail
|
|
622
|
+
await this.serialNumberReplacementForExistingOrderInv(
|
|
623
|
+
existingOrderInv,
|
|
624
|
+
targetInventory,
|
|
625
|
+
worksheetDetail,
|
|
626
|
+
foundSerialNumber
|
|
627
|
+
)
|
|
628
|
+
} else if (
|
|
629
|
+
scannedPalletIdInventory.batchId == inventory.batchId &&
|
|
630
|
+
scannedPalletIdInventory.product.id == product.id &&
|
|
631
|
+
scannedPalletIdInventory.product.packingType == product.packingType
|
|
632
|
+
) {
|
|
633
|
+
//if replacement order inventory does not exist
|
|
634
|
+
await this.serialNumberReplacement(
|
|
635
|
+
targetInventory,
|
|
636
|
+
scannedPalletIdInventory,
|
|
637
|
+
releaseGood,
|
|
638
|
+
product,
|
|
639
|
+
worksheetDetail,
|
|
640
|
+
foundSerialNumber
|
|
641
|
+
)
|
|
642
|
+
} else {
|
|
643
|
+
throw new Error(this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE('Pallet ID', palletId, inventory.palletId))
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
544
647
|
|
|
545
648
|
await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
|
|
546
649
|
|
|
650
|
+
targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
|
|
651
|
+
|
|
547
652
|
const fromLocation: Location = targetInventory.inventory.location
|
|
548
653
|
if (locationName) {
|
|
549
654
|
const toLocation: Location = await this.trxMgr.getRepository(Location).findOne({
|
|
@@ -638,16 +743,6 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
638
743
|
|
|
639
744
|
targetInventory.pickedQty = targetInventory.releaseQty
|
|
640
745
|
targetInventory.status = ORDER_INVENTORY_STATUS.PICKED
|
|
641
|
-
|
|
642
|
-
targetInventory.pickedAt = new Date()
|
|
643
|
-
targetInventory.pickedByUser = this.user;
|
|
644
|
-
|
|
645
|
-
let pickedBy: string[] = targetInventory.pickedBy ? (targetInventory.pickedBy).split(',') : []
|
|
646
|
-
if (!pickedBy.find(x => x == this.user.name)) {
|
|
647
|
-
pickedBy.push(this.user.name)
|
|
648
|
-
targetInventory.pickedBy = pickedBy.join(',')
|
|
649
|
-
}
|
|
650
|
-
|
|
651
746
|
await this.updateOrderTargets([targetInventory])
|
|
652
747
|
|
|
653
748
|
inventory.qty -= targetInventory.releaseQty
|
|
@@ -802,15 +897,6 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
802
897
|
targetInventory.pickedQty += pickedQty > gapQtyRemaining ? gapQtyRemaining : pickedQty
|
|
803
898
|
remainingAssignedQty = remainingAssignedQty < 0 ? 0 : remainingAssignedQty
|
|
804
899
|
|
|
805
|
-
targetInventory.pickedAt = new Date()
|
|
806
|
-
targetInventory.pickedByUser = this.user;
|
|
807
|
-
|
|
808
|
-
let pickedBy: string[] = targetInventory.pickedBy ? (targetInventory.pickedBy).split(',') : []
|
|
809
|
-
if (!pickedBy.find(x => x == this.user.name)) {
|
|
810
|
-
pickedBy.push(this.user.name)
|
|
811
|
-
targetInventory.pickedBy = pickedBy.join(',')
|
|
812
|
-
}
|
|
813
|
-
|
|
814
900
|
if (targetInventory.pickedQty == targetReleaseQty) {
|
|
815
901
|
const leftQty: number = inventory.qty - targetInventory.releaseQty
|
|
816
902
|
if (leftQty < 0) {
|
|
@@ -865,6 +951,28 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
865
951
|
])
|
|
866
952
|
await this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
|
|
867
953
|
|
|
954
|
+
let InventoryItems: InventoryItem = await this.trxMgr
|
|
955
|
+
.getRepository(InventoryItem)
|
|
956
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
957
|
+
|
|
958
|
+
if (InventoryItems.length > 0) {
|
|
959
|
+
InventoryItems.forEach((itm: InventoryItem) => {
|
|
960
|
+
itm.status = INVENTORY_STATUS.TERMINATED
|
|
961
|
+
itm.updater = this.user
|
|
962
|
+
})
|
|
963
|
+
|
|
964
|
+
// let inventoryLists = InventoryItems.filter(
|
|
965
|
+
// (value, index, self) => index === self.findIndex(itm => itm.inventory.id === value.inventory.id)
|
|
966
|
+
// )
|
|
967
|
+
|
|
968
|
+
// inventoryLists.forEach((itm: Inventory) => {
|
|
969
|
+
// if (itm.inventory.qty - itm.releaseQty == 0)
|
|
970
|
+
// this.transactionInventory(itm, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
|
|
971
|
+
// })
|
|
972
|
+
|
|
973
|
+
await this.trxMgr.getRepository(InventoryItem).save(InventoryItems)
|
|
974
|
+
}
|
|
975
|
+
|
|
868
976
|
let orderStatus: string
|
|
869
977
|
if (releaseGood?.packingOption) {
|
|
870
978
|
orderStatus = ORDER_STATUS.READY_TO_PACK
|
|
@@ -1025,4 +1133,277 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1025
1133
|
|
|
1026
1134
|
return orderInventory
|
|
1027
1135
|
}
|
|
1136
|
+
|
|
1137
|
+
private async serialNumberReplacementForExistingOrderInv(
|
|
1138
|
+
existingOrderInv,
|
|
1139
|
+
targetInventory,
|
|
1140
|
+
worksheetDetail,
|
|
1141
|
+
foundSerialNumber
|
|
1142
|
+
) {
|
|
1143
|
+
try {
|
|
1144
|
+
//1. update replacement inventory, order inventory, old inventory, old order inventory quantity
|
|
1145
|
+
let newInventory: Inventory = await this.trxMgr
|
|
1146
|
+
.getRepository(Inventory)
|
|
1147
|
+
.findOne({ where: { domain: this.domain, id: existingOrderInv?.inventoryId } })
|
|
1148
|
+
|
|
1149
|
+
let newOrderInventory: OrderInventory = await this.trxMgr
|
|
1150
|
+
.getRepository(OrderInventory)
|
|
1151
|
+
.findOne({ where: { domain: this.domain, id: existingOrderInv?.id } })
|
|
1152
|
+
|
|
1153
|
+
let oldInventory: Inventory = await this.trxMgr
|
|
1154
|
+
.getRepository(Inventory)
|
|
1155
|
+
.findOne({ where: { domain: this.domain, id: targetInventory?.inventory.id } })
|
|
1156
|
+
|
|
1157
|
+
let oldOrderInventory: OrderInventory = await this.trxMgr
|
|
1158
|
+
.getRepository(OrderInventory)
|
|
1159
|
+
.findOne({ where: { domain: this.domain, id: targetInventory?.id } })
|
|
1160
|
+
|
|
1161
|
+
//if replacement inventory quantity insufficient
|
|
1162
|
+
if (newInventory.qty - newInventory.lockedQty < targetInventory.releaseQty - targetInventory.pickedQty) {
|
|
1163
|
+
newOrderInventory.releaseQty += newInventory.qty - newInventory.lockedQty
|
|
1164
|
+
newOrderInventory.releaseUomValue += newInventory.uomValue - newInventory.lockedUomValue
|
|
1165
|
+
|
|
1166
|
+
oldOrderInventory.releaseQty -= newOrderInventory.releaseQty
|
|
1167
|
+
oldOrderInventory.releaseUomValue -= newOrderInventory.releaseUomValue
|
|
1168
|
+
|
|
1169
|
+
oldInventory.lockedQty -= newOrderInventory.releaseQty
|
|
1170
|
+
oldInventory.lockedUomValue -= newOrderInventory.releaseUomValue
|
|
1171
|
+
|
|
1172
|
+
newInventory.lockedQty = newInventory.qty
|
|
1173
|
+
newInventory.lockedUomValue = newInventory.uomValue
|
|
1174
|
+
} else {
|
|
1175
|
+
newOrderInventory.releaseQty += targetInventory.releaseQty - targetInventory.pickedQty
|
|
1176
|
+
newOrderInventory.releaseUomValue +=
|
|
1177
|
+
newOrderInventory.releaseQty * (targetInventory.releaseUomValue / targetInventory.releaseQty)
|
|
1178
|
+
|
|
1179
|
+
oldOrderInventory.releaseQty = targetInventory.pickedQty
|
|
1180
|
+
oldOrderInventory.status = INVENTORY_STATUS.PICKED
|
|
1181
|
+
oldOrderInventory.releaseUomValue =
|
|
1182
|
+
(targetInventory.releaseUomValue / targetInventory.releaseQty) * oldOrderInventory.releaseQty
|
|
1183
|
+
|
|
1184
|
+
oldInventory.lockedQty -= targetInventory.releaseQty - targetInventory.pickedQty
|
|
1185
|
+
oldInventory.lockedUomValue =
|
|
1186
|
+
oldInventory.lockedQty * (targetInventory.releaseUomValue / targetInventory.releaseQty)
|
|
1187
|
+
|
|
1188
|
+
newInventory.lockedQty = newInventory.lockedQty + (targetInventory.releaseQty - targetInventory.pickedQty)
|
|
1189
|
+
newInventory.lockedUomValue =
|
|
1190
|
+
(targetInventory.releaseUomValue / targetInventory.releaseQty) * newInventory.lockedQty
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
newInventory = await this.trxMgr.getRepository(Inventory).save({ ...newInventory, updater: this.user })
|
|
1194
|
+
|
|
1195
|
+
newOrderInventory = await this.trxMgr.getRepository(OrderInventory).save({
|
|
1196
|
+
...newOrderInventory,
|
|
1197
|
+
status: INVENTORY_STATUS.PICKING,
|
|
1198
|
+
pickedQty: existingOrderInv.pickedQty++,
|
|
1199
|
+
updater: this.user
|
|
1200
|
+
})
|
|
1201
|
+
|
|
1202
|
+
oldInventory = await this.trxMgr.getRepository(Inventory).save({ ...oldInventory, updater: this.user })
|
|
1203
|
+
|
|
1204
|
+
foundSerialNumber = await this.trxMgr
|
|
1205
|
+
.getRepository(InventoryItem)
|
|
1206
|
+
.save({ ...foundSerialNumber, inventory: newInventory })
|
|
1207
|
+
|
|
1208
|
+
//2. update replacement worksheet detail
|
|
1209
|
+
await this.trxMgr.getRepository(WorksheetDetail).update(
|
|
1210
|
+
{
|
|
1211
|
+
targetInventory: existingOrderInv
|
|
1212
|
+
},
|
|
1213
|
+
{
|
|
1214
|
+
status: WORKSHEET_STATUS.EXECUTING,
|
|
1215
|
+
updater: this.user
|
|
1216
|
+
}
|
|
1217
|
+
)
|
|
1218
|
+
|
|
1219
|
+
if (oldOrderInventory.releaseQty !== 0) {
|
|
1220
|
+
oldOrderInventory = await this.trxMgr
|
|
1221
|
+
.getRepository(OrderInventory)
|
|
1222
|
+
.save({ ...oldOrderInventory, updater: this.user })
|
|
1223
|
+
|
|
1224
|
+
await this.trxMgr.getRepository(WorksheetDetail).update(
|
|
1225
|
+
{
|
|
1226
|
+
name: worksheetDetail.name
|
|
1227
|
+
},
|
|
1228
|
+
{
|
|
1229
|
+
status: WORKSHEET_STATUS.DONE,
|
|
1230
|
+
updater: this.user
|
|
1231
|
+
}
|
|
1232
|
+
)
|
|
1233
|
+
} else {
|
|
1234
|
+
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1235
|
+
await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.ild)
|
|
1236
|
+
}
|
|
1237
|
+
} catch (e) {}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
private async serialNumberReplacement(
|
|
1241
|
+
targetInventory,
|
|
1242
|
+
scannedPalletIdInventory,
|
|
1243
|
+
releaseGood,
|
|
1244
|
+
product,
|
|
1245
|
+
worksheetDetail,
|
|
1246
|
+
foundSerialNumber
|
|
1247
|
+
) {
|
|
1248
|
+
try {
|
|
1249
|
+
//1. create new inventory, new order inventory, update old inventory, old order inventory quantity
|
|
1250
|
+
let newInventory: Inventory = await this.trxMgr
|
|
1251
|
+
.getRepository(Inventory)
|
|
1252
|
+
.findOne({ where: { id: scannedPalletIdInventory?.id } })
|
|
1253
|
+
|
|
1254
|
+
let oldInventory: Inventory = await this.trxMgr
|
|
1255
|
+
.getRepository(Inventory)
|
|
1256
|
+
.findOne({ where: { domain: this.domain, id: targetInventory?.inventory.id } })
|
|
1257
|
+
|
|
1258
|
+
let oldOrderInventory: OrderInventory = await this.trxMgr
|
|
1259
|
+
.getRepository(OrderInventory)
|
|
1260
|
+
.findOne({ where: { domain: this.domain, id: targetInventory?.id } })
|
|
1261
|
+
|
|
1262
|
+
let newOrderInventoryReleaseQty = 0
|
|
1263
|
+
let newOrderInventoryReleaseUomValue = 0
|
|
1264
|
+
|
|
1265
|
+
//if replacement inventory quantity insufficient
|
|
1266
|
+
if (newInventory.qty - newInventory.lockedQty < targetInventory.releaseQty - targetInventory.pickedQty) {
|
|
1267
|
+
newOrderInventoryReleaseQty = newInventory.qty - newInventory.lockedQty
|
|
1268
|
+
newOrderInventoryReleaseUomValue = newInventory.uomValue - newInventory.lockedUomValue
|
|
1269
|
+
|
|
1270
|
+
oldOrderInventory.releaseQty -= newOrderInventoryReleaseQty
|
|
1271
|
+
oldOrderInventory.releaseUomValue -= newOrderInventoryReleaseUomValue
|
|
1272
|
+
|
|
1273
|
+
oldInventory.lockedQty -= newOrderInventoryReleaseQty
|
|
1274
|
+
oldInventory.lockedUomValue -= newOrderInventoryReleaseUomValue
|
|
1275
|
+
|
|
1276
|
+
newInventory.lockedQty = newInventory.qty
|
|
1277
|
+
newInventory.lockedUomValue = newInventory.uomValue
|
|
1278
|
+
} else {
|
|
1279
|
+
newOrderInventoryReleaseQty = targetInventory.releaseQty - targetInventory.pickedQty
|
|
1280
|
+
newOrderInventoryReleaseUomValue =
|
|
1281
|
+
newOrderInventoryReleaseQty * (targetInventory.releaseUomValue / targetInventory.releaseQty)
|
|
1282
|
+
|
|
1283
|
+
oldOrderInventory.releaseQty = targetInventory.pickedQty
|
|
1284
|
+
oldOrderInventory.status = INVENTORY_STATUS.PICKED
|
|
1285
|
+
oldOrderInventory.releaseUomValue =
|
|
1286
|
+
(targetInventory.releaseUomValue / targetInventory.releaseQty) * oldOrderInventory.releaseQty
|
|
1287
|
+
|
|
1288
|
+
oldInventory.lockedQty -= newOrderInventoryReleaseQty
|
|
1289
|
+
oldInventory.lockedUomValue -= newOrderInventoryReleaseUomValue
|
|
1290
|
+
|
|
1291
|
+
newInventory.lockedQty = newInventory.lockedQty + (targetInventory.releaseQty - targetInventory.pickedQty)
|
|
1292
|
+
newInventory.lockedUomValue =
|
|
1293
|
+
(targetInventory.releaseUomValue / targetInventory.releaseQty) * newInventory.lockedQty
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
newInventory = await this.trxMgr.getRepository(Inventory).save({ ...newInventory, updater: this.user })
|
|
1297
|
+
|
|
1298
|
+
let newTargetInventory = (({ id, ...targetInventory }) => targetInventory)(targetInventory)
|
|
1299
|
+
|
|
1300
|
+
let newOrderInventory = await this.trxMgr.getRepository(OrderInventory).save({
|
|
1301
|
+
...newTargetInventory,
|
|
1302
|
+
domain: this.domain,
|
|
1303
|
+
name: OrderNoGenerator.orderInventory(),
|
|
1304
|
+
releaseGood,
|
|
1305
|
+
releaseQty: newOrderInventoryReleaseQty,
|
|
1306
|
+
releaseUomValue: newOrderInventoryReleaseUomValue,
|
|
1307
|
+
pickedQty: 1,
|
|
1308
|
+
product,
|
|
1309
|
+
inventory: scannedPalletIdInventory,
|
|
1310
|
+
creator: this.user,
|
|
1311
|
+
updater: this.user
|
|
1312
|
+
})
|
|
1313
|
+
|
|
1314
|
+
oldInventory = await this.trxMgr.getRepository(Inventory).save({ ...oldInventory, updater: this.user })
|
|
1315
|
+
|
|
1316
|
+
foundSerialNumber = await this.trxMgr
|
|
1317
|
+
.getRepository(InventoryItem)
|
|
1318
|
+
.save({ ...foundSerialNumber, inventory: newInventory })
|
|
1319
|
+
|
|
1320
|
+
//3. create new worksheet detail
|
|
1321
|
+
let NewWorksheetDetail = (({ id, ...worksheetDetail }) => worksheetDetail)(worksheetDetail)
|
|
1322
|
+
await this.trxMgr.getRepository(WorksheetDetail).save({
|
|
1323
|
+
...NewWorksheetDetail,
|
|
1324
|
+
domain: this.domain,
|
|
1325
|
+
name: WorksheetNoGenerator.pickingDetail(),
|
|
1326
|
+
targetInventory: newOrderInventory,
|
|
1327
|
+
status: WORKSHEET_STATUS.EXECUTING,
|
|
1328
|
+
creator: this.user,
|
|
1329
|
+
updater: this.user
|
|
1330
|
+
})
|
|
1331
|
+
|
|
1332
|
+
//if old order inventory release quantity is 0 then delete
|
|
1333
|
+
if (oldOrderInventory.releaseQty !== 0) {
|
|
1334
|
+
oldOrderInventory = await this.trxMgr
|
|
1335
|
+
.getRepository(OrderInventory)
|
|
1336
|
+
.save({ ...oldOrderInventory, updater: this.user })
|
|
1337
|
+
|
|
1338
|
+
//4. update old worksheet detail
|
|
1339
|
+
worksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).update(
|
|
1340
|
+
{
|
|
1341
|
+
name: worksheetDetail.name
|
|
1342
|
+
},
|
|
1343
|
+
{
|
|
1344
|
+
status: WORKSHEET_STATUS.DONE,
|
|
1345
|
+
updater: this.user
|
|
1346
|
+
}
|
|
1347
|
+
)
|
|
1348
|
+
} else {
|
|
1349
|
+
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1350
|
+
await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.id)
|
|
1351
|
+
}
|
|
1352
|
+
} catch (e) {}
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
async undoSerialNumberPicking(worksheetDetailName: string, inventoryItemId: string): Promise<void> {
|
|
1356
|
+
const worksheetDetail: WorksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).findOne({
|
|
1357
|
+
where: { name: worksheetDetailName, domain: this.domain, status: Not(Equal(WORKSHEET_STATUS.DEACTIVATED)) },
|
|
1358
|
+
relations: [
|
|
1359
|
+
'worksheet',
|
|
1360
|
+
'worksheet.releaseGood',
|
|
1361
|
+
'targetInventory',
|
|
1362
|
+
'targetInventory.product',
|
|
1363
|
+
'targetInventory.inventory'
|
|
1364
|
+
]
|
|
1365
|
+
})
|
|
1366
|
+
|
|
1367
|
+
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
1368
|
+
|
|
1369
|
+
if (targetInventory.releaseQty == targetInventory.pickedQty && targetInventory.status == INVENTORY_STATUS.PICKED) {
|
|
1370
|
+
targetInventory.status = INVENTORY_STATUS.PICKING
|
|
1371
|
+
|
|
1372
|
+
await this.trxMgr
|
|
1373
|
+
.getRepository(WorksheetDetail)
|
|
1374
|
+
.update({ id: worksheetDetail.id }, { status: WORKSHEET_STATUS.EXECUTING })
|
|
1375
|
+
|
|
1376
|
+
targetInventory.inventory.qty += targetInventory.releaseQty
|
|
1377
|
+
targetInventory.inventory.uomValue =
|
|
1378
|
+
Math.round((targetInventory.inventory.uomValue + targetInventory.releaseUomValue) * 100) / 100
|
|
1379
|
+
targetInventory.inventory.lockedQty = targetInventory.inventory.lockedQty + targetInventory.releaseQty
|
|
1380
|
+
targetInventory.inventory.lockedUomValue =
|
|
1381
|
+
Math.round((targetInventory.inventory.lockedUomValue + targetInventory.releaseUomValue) * 100) / 100
|
|
1382
|
+
|
|
1383
|
+
await this.trxMgr.getRepository(Inventory).save(targetInventory.inventory)
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
let removeInventoryItem: InventoryItem = await this.trxMgr
|
|
1387
|
+
.getRepository(InventoryItem)
|
|
1388
|
+
.findOne({ where: { id: inventoryItemId } })
|
|
1389
|
+
|
|
1390
|
+
if (removeInventoryItem.source == 'OUTBOUND') {
|
|
1391
|
+
await this.trxMgr.getRepository(InventoryItem).delete(removeInventoryItem.id)
|
|
1392
|
+
} else {
|
|
1393
|
+
await this.trxMgr.getRepository(InventoryItem).update(
|
|
1394
|
+
{
|
|
1395
|
+
id: inventoryItemId
|
|
1396
|
+
},
|
|
1397
|
+
{
|
|
1398
|
+
status: INVENTORY_STATUS.STORED,
|
|
1399
|
+
outboundOrderId: null,
|
|
1400
|
+
updater: this.user
|
|
1401
|
+
}
|
|
1402
|
+
)
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
targetInventory.pickedQty--
|
|
1406
|
+
targetInventory.updater = this.user
|
|
1407
|
+
await this.updateOrderTargets([targetInventory])
|
|
1408
|
+
}
|
|
1028
1409
|
}
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import FormData from 'form-data'
|
|
2
2
|
import fetch from 'node-fetch'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from 'typeorm'
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
Attachment,
|
|
10
|
-
STORAGE
|
|
11
|
-
} from '@things-factory/attachment-base'
|
|
3
|
+
import { getRepository, SelectQueryBuilder } from 'typeorm'
|
|
4
|
+
|
|
5
|
+
import { Attachment, STORAGE } from '@things-factory/attachment-base'
|
|
12
6
|
import { Bizplace } from '@things-factory/biz-base'
|
|
13
7
|
import { config } from '@things-factory/env'
|
|
14
|
-
import { ReleaseGood } from '@things-factory/sales-base'
|
|
8
|
+
import { InvoiceProduct, ReleaseGood } from '@things-factory/sales-base'
|
|
15
9
|
import { Domain } from '@things-factory/shell'
|
|
16
10
|
|
|
17
11
|
import { TEMPLATE_TYPE } from '../constants'
|
|
@@ -28,31 +22,24 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
|
|
|
28
22
|
let result = await Promise.all(
|
|
29
23
|
req.roIds.map(async roId => {
|
|
30
24
|
try {
|
|
31
|
-
const qb: SelectQueryBuilder<ReleaseGood> = getRepository(ReleaseGood)
|
|
25
|
+
const qb: SelectQueryBuilder<ReleaseGood> = await getRepository(ReleaseGood)
|
|
32
26
|
.createQueryBuilder('rg')
|
|
33
27
|
.innerJoinAndSelect('rg.domain', 'domain')
|
|
34
28
|
.innerJoinAndSelect('rg.bizplace', 'bizplace')
|
|
35
29
|
.innerJoinAndSelect('bizplace.domain', 'bizplace_domain')
|
|
36
30
|
.innerJoinAndSelect('bizplace.company', 'company')
|
|
37
31
|
.innerJoinAndSelect('company.domain', 'company_domain')
|
|
38
|
-
.innerJoinAndSelect('invoices', 'iv', 'rg.
|
|
39
|
-
.innerJoinAndSelect('iv.invoiceProducts', 'ip')
|
|
32
|
+
.innerJoinAndSelect('invoices', 'iv', 'rg.ref_no = iv.ref_no_1')
|
|
40
33
|
.leftJoinAndSelect('marketplace_orders', 'mo', 'rg.id = mo.release_order_id::uuid')
|
|
41
|
-
.leftJoinAndSelect('mo.marketplaceOrderItems', 'moi')
|
|
42
|
-
.leftJoinAndSelect('marketplace_product_variations', 'mpv', 'moi.marketplace_product_variation_id = mpv.id')
|
|
43
|
-
.leftJoinAndSelect('products', 'p', 'mpv.sku = p.sku and p.domain_id = company.domain_id')
|
|
44
34
|
.leftJoinAndSelect('marketplace_order_shippings', 'mos', 'rg.id = mos.release_order_id::uuid')
|
|
45
35
|
.leftJoinAndSelect('mo.fulfillmentCenter', 'fc')
|
|
46
36
|
.where('rg.id = :roId')
|
|
47
|
-
.andWhere('ip.sku = p.sku')
|
|
48
37
|
.andWhere('rg.domain = :domainId')
|
|
49
38
|
.setParameters({ roId, domainId: domain.id })
|
|
50
39
|
|
|
51
|
-
let
|
|
52
|
-
|
|
53
|
-
if (items.length) {
|
|
54
|
-
let record: any = items[0]
|
|
40
|
+
let record: any = await qb.getRawOne()
|
|
55
41
|
|
|
42
|
+
if (record) {
|
|
56
43
|
const partnerBiz: Partial<Bizplace> = {
|
|
57
44
|
id: record.bizplace_id,
|
|
58
45
|
name: record.bizplace_name,
|
|
@@ -86,6 +73,16 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
|
|
|
86
73
|
record.iv_delivery_address_5
|
|
87
74
|
]
|
|
88
75
|
|
|
76
|
+
const qb: SelectQueryBuilder<InvoiceProduct> = await getRepository(InvoiceProduct)
|
|
77
|
+
.createQueryBuilder('ip')
|
|
78
|
+
.innerJoin('invoices', 'iv', 'iv.id = ip.invoice_id')
|
|
79
|
+
.leftJoin('release_goods', 'rg', 'rg.ref_no = iv.ref_no_1')
|
|
80
|
+
.where('rg.id = :roId')
|
|
81
|
+
.andWhere('rg.domain = :domainId')
|
|
82
|
+
.setParameters({ roId, domainId: domain.id })
|
|
83
|
+
|
|
84
|
+
let items: any[] = await qb.getRawMany()
|
|
85
|
+
|
|
89
86
|
const product_list = items.map((item, idx) => {
|
|
90
87
|
return {
|
|
91
88
|
list_no: idx + 1,
|
|
@@ -100,9 +97,9 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
|
|
|
100
97
|
(item.ip_paid_price || item.ip_unit_price) * parseInt(item.ip_qty || 0)
|
|
101
98
|
),
|
|
102
99
|
product_total_unit_price: getRoundedValue(item.ip_unit_price * parseInt(item.ip_qty || 0)),
|
|
103
|
-
original_price: getRoundedValue(parseFloat(item.
|
|
104
|
-
product_discount: getRoundedValue(parseFloat(item.
|
|
105
|
-
shipping_fee_paid_by_customer: getRoundedValue(parseFloat(item.
|
|
100
|
+
original_price: getRoundedValue(parseFloat(item.ip_unit_price || 0)),
|
|
101
|
+
product_discount: getRoundedValue(parseFloat(item.ip_discount || 0)),
|
|
102
|
+
shipping_fee_paid_by_customer: getRoundedValue(parseFloat(item.ip_shipping_fee_paid_by_customer || 0))
|
|
106
103
|
}
|
|
107
104
|
})
|
|
108
105
|
|
|
@@ -161,12 +158,12 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
|
|
|
161
158
|
.join(' '),
|
|
162
159
|
fulfillment_center: record.fc_name,
|
|
163
160
|
voucher_amount: getRoundedValue(parseFloat(record.mo_voucher_amount || 0)),
|
|
164
|
-
actual_shipping_fee: getRoundedValue(parseFloat(record.mos_actual_shipping_fee ||
|
|
161
|
+
actual_shipping_fee: getRoundedValue(parseFloat(record.mos_actual_shipping_fee || 0)),
|
|
165
162
|
sub_total: sumProductTotalPaidPrice,
|
|
166
163
|
grand_total: getRoundedValue(
|
|
167
164
|
sumProductTotalPaidPrice -
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
parseFloat(record.mo_voucher_amount || 0) +
|
|
166
|
+
parseFloat(record.mos_actual_shipping_fee || 0)
|
|
170
167
|
),
|
|
171
168
|
product_list
|
|
172
169
|
}
|