@things-factory/worksheet-base 4.1.41 → 4.2.0
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 +2 -0
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/packing-worksheet-controller.js +166 -8
- package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/picking-worksheet-controller.js +22 -22
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/sorting-worksheet-controller.js +110 -3
- package/dist-server/controllers/outbound/sorting-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/worksheet-controller.js +2 -1
- package/dist-server/controllers/worksheet-controller.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js +30 -1
- package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +3 -0
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/index.js +2 -1
- package/dist-server/graphql/resolvers/worksheet/packing/index.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/packing.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/packing/packing.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.js +15 -0
- package/dist-server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.js.map +1 -0
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +152 -133
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/sorting/scan-product-sorting.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/sorting/scan-product-sorting.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/sorting/sorting-product.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/sorting/sorting-product.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/sorting-worksheet.js +6 -0
- package/dist-server/graphql/resolvers/worksheet/sorting-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.js +4 -5
- package/dist-server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.js +4 -2
- package/dist-server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.js.map +1 -1
- package/dist-server/graphql/types/worksheet/find-release-orders-by-task-no.js +11 -0
- package/dist-server/graphql/types/worksheet/find-release-orders-by-task-no.js.map +1 -0
- package/dist-server/graphql/types/worksheet/index.js +13 -2
- package/dist-server/graphql/types/worksheet/index.js.map +1 -1
- package/dist-server/graphql/types/worksheet/worksheet-detail-info.js +2 -0
- package/dist-server/graphql/types/worksheet/worksheet-detail-info.js.map +1 -1
- package/dist-server/graphql/types/worksheet-detail/index.js +0 -2
- package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
- package/dist-server/utils/inventory-util.js +14 -25
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +9 -9
- package/server/controllers/inbound/unloading-worksheet-controller.ts +2 -0
- package/server/controllers/outbound/packing-worksheet-controller.ts +217 -11
- package/server/controllers/outbound/picking-worksheet-controller.ts +23 -24
- package/server/controllers/outbound/sorting-worksheet-controller.ts +149 -4
- package/server/controllers/worksheet-controller.ts +2 -1
- package/server/graphql/resolvers/worksheet/find-release-orders-by-task-no.ts +35 -2
- package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +2 -0
- package/server/graphql/resolvers/worksheet/packing/index.ts +3 -1
- package/server/graphql/resolvers/worksheet/packing/packing.ts +5 -4
- package/server/graphql/resolvers/worksheet/packing/scan-product-packing.ts +9 -4
- package/server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.ts +24 -0
- package/server/graphql/resolvers/worksheet/packing-worksheet.ts +166 -144
- package/server/graphql/resolvers/worksheet/sorting/scan-product-sorting.ts +5 -4
- package/server/graphql/resolvers/worksheet/sorting/sorting-product.ts +5 -4
- package/server/graphql/resolvers/worksheet/sorting-worksheet.ts +6 -0
- package/server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.ts +10 -12
- package/server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.ts +4 -2
- package/server/graphql/types/worksheet/find-release-orders-by-task-no.ts +8 -0
- package/server/graphql/types/worksheet/index.ts +13 -2
- package/server/graphql/types/worksheet/worksheet-detail-info.ts +2 -0
- package/server/graphql/types/worksheet-detail/index.ts +0 -2
- package/server/utils/inventory-util.ts +15 -23
|
@@ -453,7 +453,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
453
453
|
)
|
|
454
454
|
|
|
455
455
|
pickedQty = await this.getChildQty(productDetails, productBarcode, roProductDetail)
|
|
456
|
-
if (pickedQty > releaseQty) {
|
|
456
|
+
if (pickedQty + targetInventory.pickedQty > releaseQty) {
|
|
457
457
|
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
458
458
|
}
|
|
459
459
|
} else if (!foundProductDetail) {
|
|
@@ -555,8 +555,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
555
555
|
//validation to prevent over release
|
|
556
556
|
if (inventory.qty <= 0) throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
557
557
|
|
|
558
|
-
if (inventory.palletId !== palletId
|
|
559
|
-
//to be changed
|
|
558
|
+
if (inventory.palletId !== palletId && !product?.isRequireSerialNumberScanningOutbound)
|
|
560
559
|
throw new Error(this.ERROR_MSG.VALIDITY.UNEXPECTED_FIELD_VALUE('Pallet ID', palletId, inventory.palletId))
|
|
561
560
|
|
|
562
561
|
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
@@ -566,7 +565,8 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
566
565
|
|
|
567
566
|
let totalInventoryItems = await this.trxMgr.getRepository(InventoryItem).count({
|
|
568
567
|
where: {
|
|
569
|
-
inventory
|
|
568
|
+
inventory,
|
|
569
|
+
status: Not(In([INVENTORY_STATUS.TERMINATED, INVENTORY_STATUS.PICKED]))
|
|
570
570
|
}
|
|
571
571
|
})
|
|
572
572
|
|
|
@@ -580,13 +580,11 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
580
580
|
.findOne({ where: { domain: this.domain, palletId }, relations: ['product'] })
|
|
581
581
|
|
|
582
582
|
if (foundSerialNumber) {
|
|
583
|
-
if (
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
) {
|
|
589
|
-
throw new Error('Inventory Item is not available')
|
|
583
|
+
if (foundSerialNumber.outboundOrderId) {
|
|
584
|
+
let releaseGood: ReleaseGood = await this.trxMgr
|
|
585
|
+
.getRepository(ReleaseGood)
|
|
586
|
+
.findOne({ where: { id: foundSerialNumber.outboundOrderId } })
|
|
587
|
+
throw new Error(`Inventory Item is already picked in ${releaseGood.name}`)
|
|
590
588
|
}
|
|
591
589
|
|
|
592
590
|
foundSerialNumber.status = INVENTORY_STATUS.PICKING
|
|
@@ -603,12 +601,13 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
603
601
|
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
604
602
|
inventoryItem.serialNumber = serialNumber
|
|
605
603
|
inventoryItem.status = INVENTORY_STATUS.PICKING
|
|
604
|
+
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
606
605
|
inventoryItem.outboundOrderId = releaseGood.id
|
|
607
606
|
inventoryItem.product = product
|
|
608
607
|
inventoryItem.inventory = scannedPalletIdInventory
|
|
609
608
|
inventoryItem.domain = this.domain
|
|
610
609
|
|
|
611
|
-
await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
610
|
+
foundSerialNumber = await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
612
611
|
}
|
|
613
612
|
|
|
614
613
|
if (inventory.palletId !== palletId) {
|
|
@@ -648,10 +647,10 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
648
647
|
}
|
|
649
648
|
}
|
|
650
649
|
|
|
651
|
-
await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
|
|
652
|
-
|
|
653
650
|
targetInventory = await this.checkAndSetBinPicking(targetInventory, binLocation)
|
|
654
651
|
|
|
652
|
+
await this.updatePickingTransaction(releaseGood, targetInventory, worksheetDetail, inventory, pickedQty)
|
|
653
|
+
|
|
655
654
|
const fromLocation: Location = targetInventory.inventory.location
|
|
656
655
|
if (locationName) {
|
|
657
656
|
const toLocation: Location = await this.trxMgr.getRepository(Location).findOne({
|
|
@@ -954,12 +953,12 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
954
953
|
])
|
|
955
954
|
await this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
|
|
956
955
|
|
|
957
|
-
let
|
|
956
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
958
957
|
.getRepository(InventoryItem)
|
|
959
958
|
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
960
959
|
|
|
961
|
-
if (
|
|
962
|
-
|
|
960
|
+
if (inventoryItems.length > 0) {
|
|
961
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
963
962
|
itm.status = INVENTORY_STATUS.TERMINATED
|
|
964
963
|
itm.updater = this.user
|
|
965
964
|
})
|
|
@@ -973,7 +972,7 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
973
972
|
// this.transactionInventory(itm, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.TERMINATED)
|
|
974
973
|
// })
|
|
975
974
|
|
|
976
|
-
await this.trxMgr.getRepository(InventoryItem).save(
|
|
975
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
977
976
|
}
|
|
978
977
|
|
|
979
978
|
let orderStatus: string
|
|
@@ -1126,17 +1125,17 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1126
1125
|
worksheetDetail.updater = this.user
|
|
1127
1126
|
await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
1128
1127
|
|
|
1129
|
-
let
|
|
1128
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
1130
1129
|
.getRepository(InventoryItem)
|
|
1131
1130
|
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
1132
1131
|
|
|
1133
|
-
if (
|
|
1134
|
-
|
|
1132
|
+
if (inventoryItems.length > 0) {
|
|
1133
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
1135
1134
|
itm.status = INVENTORY_STATUS.PICKED
|
|
1136
1135
|
itm.updater = this.user
|
|
1137
1136
|
})
|
|
1138
1137
|
|
|
1139
|
-
await this.trxMgr.getRepository(InventoryItem).save(
|
|
1138
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
1140
1139
|
}
|
|
1141
1140
|
|
|
1142
1141
|
if (leftQty === 0) {
|
|
@@ -1247,8 +1246,8 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1247
1246
|
}
|
|
1248
1247
|
)
|
|
1249
1248
|
} else {
|
|
1250
|
-
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1251
1249
|
await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.ild)
|
|
1250
|
+
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1252
1251
|
}
|
|
1253
1252
|
} catch (e) {}
|
|
1254
1253
|
}
|
|
@@ -1362,8 +1361,8 @@ export class PickingWorksheetController extends VasWorksheetController {
|
|
|
1362
1361
|
}
|
|
1363
1362
|
)
|
|
1364
1363
|
} else {
|
|
1365
|
-
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1366
1364
|
await this.trxMgr.getRepository(WorksheetDetail).delete(worksheetDetail.id)
|
|
1365
|
+
await this.trxMgr.getRepository(OrderInventory).delete(targetInventory.id)
|
|
1367
1366
|
}
|
|
1368
1367
|
} catch (e) {}
|
|
1369
1368
|
}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { VasWorksheetController } from '../vas/vas-worksheet-controller'
|
|
2
2
|
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Inventory,
|
|
5
|
+
INVENTORY_TRANSACTION_TYPE,
|
|
6
|
+
InventoryItem,
|
|
7
|
+
INVENTORY_STATUS,
|
|
8
|
+
InventoryNoGenerator,
|
|
9
|
+
INVENTORY_ITEM_SOURCE
|
|
10
|
+
} from '@things-factory/warehouse-base'
|
|
4
11
|
import { ReleaseGood, OrderInventory, ORDER_INVENTORY_STATUS, ORDER_STATUS } from '@things-factory/sales-base'
|
|
5
12
|
import { Worksheet, WorksheetDetail } from '../../entities'
|
|
6
13
|
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
|
|
@@ -51,7 +58,12 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
51
58
|
return await this.activateWorksheet(worksheet, worksheetDetails, sortingWorksheetDetails)
|
|
52
59
|
}
|
|
53
60
|
|
|
54
|
-
async scanProductSorting(
|
|
61
|
+
async scanProductSorting(
|
|
62
|
+
taskNo: string,
|
|
63
|
+
releaseGoodNo: string,
|
|
64
|
+
productBarcode: string,
|
|
65
|
+
serialNumber: string
|
|
66
|
+
): Promise<void> {
|
|
55
67
|
const worksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
|
|
56
68
|
where: {
|
|
57
69
|
domain: this.domain,
|
|
@@ -113,8 +125,53 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
113
125
|
const releaseQty: number = matchingOI.releaseQty
|
|
114
126
|
const inventory: Inventory = matchingOI.inventory
|
|
115
127
|
const releaseGood: ReleaseGood = matchingOI.releaseGood
|
|
128
|
+
const product: Product = inventory.product
|
|
116
129
|
|
|
117
130
|
if (releaseQty != matchingOI?.sortedQty && sortedQty == 1) {
|
|
131
|
+
// Serial Number scanning for batch picking
|
|
132
|
+
if (matchingOI?.refWorksheetId) {
|
|
133
|
+
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
134
|
+
if (!serialNumber || serialNumber == '') {
|
|
135
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('sorting', `require serial number`))
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
let foundSerialNumber: InventoryItem = await this.trxMgr
|
|
139
|
+
.getRepository(InventoryItem)
|
|
140
|
+
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, product } })
|
|
141
|
+
|
|
142
|
+
if (foundSerialNumber) {
|
|
143
|
+
if (foundSerialNumber.inventoryId !== inventory.id) {
|
|
144
|
+
throw new Error('Serial Number scanned is in another inventory')
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (foundSerialNumber.outboundOrderId) {
|
|
148
|
+
let releaseGood: ReleaseGood = await this.trxMgr
|
|
149
|
+
.getRepository(ReleaseGood)
|
|
150
|
+
.findOne({ where: { id: foundSerialNumber.outboundOrderId } })
|
|
151
|
+
throw new Error(`Inventory Item is already picked/sorted in ${releaseGood.name}`)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
foundSerialNumber.status = INVENTORY_STATUS.SORTING
|
|
155
|
+
foundSerialNumber.updater = this.user
|
|
156
|
+
foundSerialNumber.outboundOrderId = releaseGood.id
|
|
157
|
+
|
|
158
|
+
await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
|
|
159
|
+
} else {
|
|
160
|
+
let inventoryItem: InventoryItem = new InventoryItem()
|
|
161
|
+
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
162
|
+
inventoryItem.serialNumber = serialNumber
|
|
163
|
+
inventoryItem.status = INVENTORY_STATUS.SORTING
|
|
164
|
+
inventoryItem.outboundOrderId = releaseGood.id
|
|
165
|
+
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
166
|
+
inventoryItem.product = product
|
|
167
|
+
inventoryItem.inventory = inventory
|
|
168
|
+
inventoryItem.domain = this.domain
|
|
169
|
+
|
|
170
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
118
175
|
matchingOI.sortedQty = Boolean(matchingOI?.sortedQty) ? matchingOI.sortedQty + sortedQty : sortedQty
|
|
119
176
|
sortedQty -= 1
|
|
120
177
|
if (matchingOI.sortedQty == releaseQty) {
|
|
@@ -128,6 +185,19 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
128
185
|
worksheetDetail.status = WORKSHEET_STATUS.DONE
|
|
129
186
|
worksheetDetail.updater = this.user
|
|
130
187
|
await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
188
|
+
|
|
189
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
190
|
+
.getRepository(InventoryItem)
|
|
191
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
192
|
+
|
|
193
|
+
if (inventoryItems.length > 0) {
|
|
194
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
195
|
+
itm.status = INVENTORY_STATUS.SORTED
|
|
196
|
+
itm.updater = this.user
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
200
|
+
}
|
|
131
201
|
} else if (matchingOI?.sortedQty > releaseQty) {
|
|
132
202
|
const product: Product = matchingOI.inventory.product
|
|
133
203
|
throw new Error(this.ERROR_MSG.ORDER_ITEM.EXCESS_QTY(product.sku, packingType, packingSize))
|
|
@@ -141,7 +211,13 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
141
211
|
}
|
|
142
212
|
}
|
|
143
213
|
|
|
144
|
-
async sortingProduct(
|
|
214
|
+
async sortingProduct(
|
|
215
|
+
taskNo: string,
|
|
216
|
+
releaseGoodNo: string,
|
|
217
|
+
productId: string,
|
|
218
|
+
sortingQty: number,
|
|
219
|
+
serialNumber: string
|
|
220
|
+
): Promise<void> {
|
|
145
221
|
const worksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
|
|
146
222
|
where: {
|
|
147
223
|
domain: this.domain,
|
|
@@ -180,14 +256,70 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
180
256
|
const packingType: string = matchingOI.packingType
|
|
181
257
|
const packingSize: number = matchingOI.packingSize
|
|
182
258
|
|
|
259
|
+
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
260
|
+
if (!serialNumber || serialNumber == '') {
|
|
261
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('sorting', `require serial number`))
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
265
|
+
where: { domain: this.domain, serialNumber: serialNumber, product },
|
|
266
|
+
relations: ['product', 'inventory']
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
if (foundSerialNumber) {
|
|
270
|
+
if (foundSerialNumber.outboundOrderId) {
|
|
271
|
+
let releaseGood: ReleaseGood = await this.trxMgr
|
|
272
|
+
.getRepository(ReleaseGood)
|
|
273
|
+
.findOne({ where: { id: foundSerialNumber.outboundOrderId } })
|
|
274
|
+
throw new Error(`Inventory Item is already picked/sorted in ${releaseGood.name}`)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
foundSerialNumber.status = INVENTORY_STATUS.SORTING
|
|
278
|
+
foundSerialNumber.updater = this.user
|
|
279
|
+
foundSerialNumber.outboundOrderId = releaseGood.id
|
|
280
|
+
|
|
281
|
+
await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
|
|
282
|
+
} else {
|
|
283
|
+
let inventoryItem: InventoryItem = new InventoryItem()
|
|
284
|
+
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
285
|
+
inventoryItem.serialNumber = serialNumber
|
|
286
|
+
inventoryItem.status = INVENTORY_STATUS.SORTING
|
|
287
|
+
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
288
|
+
inventoryItem.outboundOrderId = releaseGood.id
|
|
289
|
+
inventoryItem.product = product
|
|
290
|
+
inventoryItem.inventory = inventory
|
|
291
|
+
inventoryItem.domain = this.domain
|
|
292
|
+
|
|
293
|
+
foundSerialNumber = await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
183
297
|
if (releaseQty != matchingOI?.sortedQty && sortingQty != 0) {
|
|
184
|
-
|
|
298
|
+
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
299
|
+
matchingOI.sortedQty += sortingQty
|
|
300
|
+
} else {
|
|
301
|
+
matchingOI.sortedQty = releaseQty
|
|
302
|
+
}
|
|
303
|
+
|
|
185
304
|
sortingQty -= releaseQty
|
|
186
305
|
if (matchingOI.sortedQty == releaseQty) {
|
|
187
306
|
matchingOI.status = ORDER_INVENTORY_STATUS.SORTED
|
|
188
307
|
await this.updateOrderTargets([matchingOI])
|
|
189
308
|
await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.SORTING)
|
|
190
309
|
|
|
310
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
311
|
+
.getRepository(InventoryItem)
|
|
312
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
313
|
+
|
|
314
|
+
if (inventoryItems.length > 0) {
|
|
315
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
316
|
+
itm.status = INVENTORY_STATUS.PACKED
|
|
317
|
+
itm.updater = this.user
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
321
|
+
}
|
|
322
|
+
|
|
191
323
|
let worksheetDetail: WorksheetDetail = worksheetDetails.find(
|
|
192
324
|
wsd => wsd.targetInventory.id === matchingOI.id
|
|
193
325
|
)
|
|
@@ -220,6 +352,19 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
220
352
|
releaseGood.updater = this.user
|
|
221
353
|
await this.trxMgr.getRepository(ReleaseGood).save(releaseGood)
|
|
222
354
|
|
|
355
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
356
|
+
.getRepository(InventoryItem)
|
|
357
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
358
|
+
|
|
359
|
+
if (inventoryItems.length > 0) {
|
|
360
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
361
|
+
itm.status = INVENTORY_STATUS.TERMINATED
|
|
362
|
+
itm.updater = this.user
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
366
|
+
}
|
|
367
|
+
|
|
223
368
|
return releaseGood
|
|
224
369
|
}
|
|
225
370
|
|
|
@@ -950,7 +950,8 @@ export class WorksheetController {
|
|
|
950
950
|
const duplicatedSerialNumberCnt: number = await this.trxMgr.getRepository(InventoryItem).count({
|
|
951
951
|
domain: this.domain,
|
|
952
952
|
product,
|
|
953
|
-
serialNumber
|
|
953
|
+
serialNumber,
|
|
954
|
+
status: Not(Equal(INVENTORY_STATUS.DELETED))
|
|
954
955
|
})
|
|
955
956
|
|
|
956
957
|
if (duplicatedSerialNumberCnt) throw new Error(this.ERROR_MSG.VALIDITY.DUPLICATED('Serial Number', serialNumber))
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { EntityManager, SelectQueryBuilder } from 'typeorm'
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
ORDER_STATUS,
|
|
4
|
+
ORDER_STATUS, ORDER_INVENTORY_STATUS,
|
|
5
5
|
OrderInventory as OrderInventoryEntity,
|
|
6
6
|
ReleaseGood as ReleaseGoodEntity
|
|
7
7
|
} from '@things-factory/sales-base'
|
|
8
8
|
import { Domain } from '@things-factory/shell'
|
|
9
|
+
import { Location } from '@things-factory/warehouse-base'
|
|
9
10
|
|
|
10
11
|
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
|
|
11
12
|
import { Worksheet as WorksheetEntity, WorksheetDetail as WorksheetDetailEntity } from '../../../entities'
|
|
@@ -16,6 +17,38 @@ export const findReleaseOrdersByTaskNoResolver = {
|
|
|
16
17
|
let task = await tx.getRepository(WorksheetEntity).findOne({
|
|
17
18
|
where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
|
|
18
19
|
})
|
|
20
|
+
|
|
21
|
+
// Find Task based on Bin
|
|
22
|
+
if (!task) {
|
|
23
|
+
const binLocation: Location = await tx.getRepository(Location).findOne({
|
|
24
|
+
where: { domain, name: taskNo }
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const qb: SelectQueryBuilder<OrderInventoryEntity> = tx.getRepository(OrderInventoryEntity).createQueryBuilder('orderInventory')
|
|
28
|
+
|
|
29
|
+
qb.innerJoinAndSelect('orderInventory.releaseGood', 'releaseGood')
|
|
30
|
+
.innerJoinAndSelect('worksheets', 'ws', `orderInventory.ref_worksheet_id = ws.id AND ws.type = 'BATCH_PICKING'`)
|
|
31
|
+
.innerJoinAndSelect('worksheets', 'ws2', `ws2.task_no = ws.task_no AND ws2.type = 'SORTING'`)
|
|
32
|
+
.innerJoinAndSelect('releaseGood.bizplace', 'bizplace')
|
|
33
|
+
.innerJoinAndSelect('bizplace.domain', 'domain')
|
|
34
|
+
.where('orderInventory.domain_id = :domainId', { domainId: domain.id })
|
|
35
|
+
.andWhere('orderInventory.status IN (:...orderInventoryStatus)', {
|
|
36
|
+
orderInventoryStatus: [ORDER_INVENTORY_STATUS.SORTING]
|
|
37
|
+
})
|
|
38
|
+
.andWhere('orderInventory.bin_location_id = :locationId', { locationId: binLocation.id })
|
|
39
|
+
.andWhere('releaseGood.status = :status', { status: ORDER_STATUS.SORTING })
|
|
40
|
+
|
|
41
|
+
const orderInventoryByBin = await qb.getRawOne()
|
|
42
|
+
if (orderInventoryByBin?.releaseGood_id) {
|
|
43
|
+
taskNo = orderInventoryByBin.ws_task_no
|
|
44
|
+
task = await tx.getRepository(WorksheetEntity).findOne({
|
|
45
|
+
where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
|
|
46
|
+
})
|
|
47
|
+
} else {
|
|
48
|
+
throw new Error(`Bin do not have any batch picking order.`)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
19
52
|
if (!task) throw new Error('Unable to find task no.')
|
|
20
53
|
|
|
21
54
|
const qb: SelectQueryBuilder<WorksheetEntity> = tx
|
|
@@ -38,6 +71,6 @@ export const findReleaseOrdersByTaskNoResolver = {
|
|
|
38
71
|
.addGroupBy('rg.status')
|
|
39
72
|
|
|
40
73
|
const releaseGoods: ReleaseGoodEntity[] = await qb.getRawMany()
|
|
41
|
-
return releaseGoods
|
|
74
|
+
return { releaseGoods, taskNo }
|
|
42
75
|
}
|
|
43
76
|
}
|
|
@@ -78,6 +78,8 @@ export const inventoriesByPalletResolver = {
|
|
|
78
78
|
locationSortingRules.forEach((rule: { name: string; desc: boolean }) => {
|
|
79
79
|
qb.addOrderBy(`location.${rule.name}`, rule.desc ? 'DESC' : 'ASC')
|
|
80
80
|
})
|
|
81
|
+
} else {
|
|
82
|
+
qb.addOrderBy('location.name', 'DESC')
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
if (productFilters && productFilters.length > 0) {
|
|
@@ -2,10 +2,12 @@ import { activatePackingResolver } from './activate-packing'
|
|
|
2
2
|
import { completePackingResolver } from './complete-packing'
|
|
3
3
|
import { packingResolver } from './packing'
|
|
4
4
|
import { scanProductPackingResolver } from './scan-product-packing'
|
|
5
|
+
import { undoSerialNumberPackingResolver } from './undo-serial-number-packing'
|
|
5
6
|
|
|
6
7
|
export const Mutations = {
|
|
7
8
|
...activatePackingResolver,
|
|
8
9
|
...completePackingResolver,
|
|
9
10
|
...packingResolver,
|
|
10
|
-
...scanProductPackingResolver
|
|
11
|
+
...scanProductPackingResolver,
|
|
12
|
+
...undoSerialNumberPackingResolver
|
|
11
13
|
}
|
|
@@ -9,9 +9,9 @@ import { PackingWorksheetController, SellercraftController } from '../../../../c
|
|
|
9
9
|
import { Worksheet } from '../../../../entities'
|
|
10
10
|
|
|
11
11
|
export const packingResolver = {
|
|
12
|
-
async packing(_: any, { worksheetDetailName, releaseQty }, context: any) {
|
|
12
|
+
async packing(_: any, { worksheetDetailName, releaseQty, serialNumber }, context: any) {
|
|
13
13
|
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
14
|
-
await packing(tx, domain, user, worksheetDetailName, releaseQty)
|
|
14
|
+
await packing(tx, domain, user, worksheetDetailName, releaseQty, serialNumber)
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -20,10 +20,11 @@ export async function packing(
|
|
|
20
20
|
domain: Domain,
|
|
21
21
|
user: User,
|
|
22
22
|
worksheetDetailName: string,
|
|
23
|
-
releaseQty: number
|
|
23
|
+
releaseQty: number,
|
|
24
|
+
serialNumber: string
|
|
24
25
|
) {
|
|
25
26
|
const worksheetController: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
|
|
26
|
-
const worksheetDetail = await worksheetController.packing(worksheetDetailName, releaseQty)
|
|
27
|
+
const worksheetDetail = await worksheetController.packing(worksheetDetailName, releaseQty, serialNumber)
|
|
27
28
|
|
|
28
29
|
let releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
29
30
|
const worksheet: Worksheet = worksheetDetail.worksheet
|
|
@@ -9,9 +9,9 @@ import { PackingWorksheetController, SellercraftController } from '../../../../c
|
|
|
9
9
|
import { Worksheet } from '../../../../entities'
|
|
10
10
|
|
|
11
11
|
export const scanProductPackingResolver = {
|
|
12
|
-
async scanProductPacking(_: any, { worksheetDetailName, productBarcode }, context: any) {
|
|
12
|
+
async scanProductPacking(_: any, { worksheetDetailName, productBarcode, serialNumber }, context: any) {
|
|
13
13
|
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
14
|
-
await scanProductPacking(tx, domain, user, worksheetDetailName, productBarcode)
|
|
14
|
+
await scanProductPacking(tx, domain, user, worksheetDetailName, productBarcode, serialNumber)
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -20,10 +20,15 @@ export async function scanProductPacking(
|
|
|
20
20
|
domain: Domain,
|
|
21
21
|
user: User,
|
|
22
22
|
worksheetDetailName: string,
|
|
23
|
-
productBarcode: string
|
|
23
|
+
productBarcode: string,
|
|
24
|
+
serialNumber?: string
|
|
24
25
|
) {
|
|
25
26
|
const worksheetController: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
|
|
26
|
-
const worksheetDetail = await worksheetController.scanProductPacking(
|
|
27
|
+
const worksheetDetail = await worksheetController.scanProductPacking(
|
|
28
|
+
worksheetDetailName,
|
|
29
|
+
productBarcode,
|
|
30
|
+
serialNumber
|
|
31
|
+
)
|
|
27
32
|
|
|
28
33
|
let releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
29
34
|
const worksheet: Worksheet = worksheetDetail.worksheet
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
import { User } from '@things-factory/auth-base'
|
|
4
|
+
import { Domain } from '@things-factory/shell'
|
|
5
|
+
|
|
6
|
+
import { PackingWorksheetController } from '../../../../controllers'
|
|
7
|
+
|
|
8
|
+
export const undoSerialNumberPackingResolver = {
|
|
9
|
+
async undoSerialNumberPacking(_: any, { worksheetDetailName, inventoryItemId }, context: any) {
|
|
10
|
+
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
11
|
+
await undoSerialNumberPacking(tx, domain, user, worksheetDetailName, inventoryItemId)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function undoSerialNumberPacking(
|
|
16
|
+
tx: EntityManager,
|
|
17
|
+
domain: Domain,
|
|
18
|
+
user: User,
|
|
19
|
+
worksheetDetailName: string,
|
|
20
|
+
inventoryItemId: string
|
|
21
|
+
): Promise<void> {
|
|
22
|
+
const worksheetController: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
|
|
23
|
+
await worksheetController.undoSerialNumberPacking(worksheetDetailName, inventoryItemId)
|
|
24
|
+
}
|