@things-factory/worksheet-base 4.3.144 → 4.3.146
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/controllers/ecommerce/ecommerce-controller.js +48 -0
- package/dist-server/controllers/ecommerce/ecommerce-controller.js.map +1 -1
- package/dist-server/controllers/ecommerce/sellercraft-controller.js +82 -31
- package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
- package/dist-server/controllers/outbound/packing-worksheet-controller.js +265 -189
- package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/complete-packing.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/packing/complete-packing.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing/packing.js +6 -7
- 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-worksheet.js +84 -38
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js +44 -9
- package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +41 -11
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
- package/dist-server/graphql/types/worksheet/index.js +6 -5
- package/dist-server/graphql/types/worksheet/index.js.map +1 -1
- package/dist-server/graphql/types/worksheet/worksheet-info.js +2 -0
- package/dist-server/graphql/types/worksheet/worksheet-info.js.map +1 -1
- package/package.json +18 -18
- package/server/controllers/ecommerce/ecommerce-controller.ts +52 -1
- package/server/controllers/ecommerce/sellercraft-controller.ts +119 -46
- package/server/controllers/outbound/packing-worksheet-controller.ts +314 -211
- package/server/graphql/resolvers/worksheet/packing/complete-packing.ts +5 -4
- package/server/graphql/resolvers/worksheet/packing/packing.ts +6 -8
- package/server/graphql/resolvers/worksheet/packing/scan-product-packing.ts +6 -9
- package/server/graphql/resolvers/worksheet/packing-worksheet.ts +124 -42
- package/server/graphql/resolvers/worksheet/picking/complete-batch-picking.ts +59 -11
- package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +47 -12
- package/server/graphql/types/worksheet/index.ts +6 -5
- package/server/graphql/types/worksheet/worksheet-info.ts +2 -0
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { Equal, Not } from 'typeorm'
|
|
2
2
|
|
|
3
3
|
import { ApplicationType } from '@things-factory/auth-base'
|
|
4
|
-
import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
|
|
5
|
-
import { Product, ProductDetail, ProductBarcode } from '@things-factory/product-base'
|
|
6
4
|
import { logger } from '@things-factory/env'
|
|
7
|
-
import {
|
|
5
|
+
import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
|
|
6
|
+
import { Product, ProductBarcode, ProductDetail } from '@things-factory/product-base'
|
|
7
|
+
import {
|
|
8
|
+
ORDER_INVENTORY_STATUS,
|
|
9
|
+
ORDER_STATUS,
|
|
10
|
+
OrderInventory,
|
|
11
|
+
OrderPackage,
|
|
12
|
+
OrderPackageItem,
|
|
13
|
+
OrderProduct,
|
|
14
|
+
ReleaseGood
|
|
15
|
+
} from '@things-factory/sales-base'
|
|
8
16
|
import { Setting } from '@things-factory/setting-base'
|
|
9
17
|
import {
|
|
10
18
|
Inventory,
|
|
@@ -129,252 +137,339 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
129
137
|
return worksheet
|
|
130
138
|
}
|
|
131
139
|
|
|
132
|
-
async packing(
|
|
133
|
-
let
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
'
|
|
138
|
-
'
|
|
139
|
-
'
|
|
140
|
-
'
|
|
141
|
-
'
|
|
142
|
-
'targetInventory.inventory',
|
|
143
|
-
'targetInventory.inventory.location',
|
|
144
|
-
'targetInventory.product',
|
|
145
|
-
'targetInventory.productDetail'
|
|
140
|
+
async packing(orderPackageItemId: string, packedQty: number, serialNumber: string): Promise<any> {
|
|
141
|
+
let orderPackageItem: OrderPackageItem = await this.trxMgr.getRepository(OrderPackageItem).findOne({
|
|
142
|
+
where: { id: orderPackageItemId },
|
|
143
|
+
relations: [
|
|
144
|
+
'orderProduct',
|
|
145
|
+
'orderProduct.orderInventories',
|
|
146
|
+
'orderPackage',
|
|
147
|
+
'orderPackage.bizplace',
|
|
148
|
+
'orderPackage.bizplace.domain',
|
|
149
|
+
'orderPackage.releaseGood'
|
|
146
150
|
]
|
|
147
|
-
)
|
|
148
|
-
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
149
|
-
let inventory: Inventory = targetInventory.inventory
|
|
150
|
-
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
151
|
-
const product: Product = targetInventory.product
|
|
152
|
-
const productDetail: ProductDetail = targetInventory.productDetail
|
|
153
|
-
const pickedQty: number = targetInventory.releaseQty
|
|
154
|
-
|
|
155
|
-
if (packedQty > pickedQty) {
|
|
156
|
-
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('pack', `packed quantity can't exceed release qty`))
|
|
157
|
-
}
|
|
151
|
+
})
|
|
158
152
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
162
|
-
if (!serialNumber || serialNumber == '') {
|
|
163
|
-
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('packing', `require serial number`))
|
|
164
|
-
}
|
|
153
|
+
const orderProduct: OrderProduct = orderPackageItem.orderProduct
|
|
154
|
+
const orderInventories: OrderInventory[] = orderProduct.orderInventories.filter(oi => oi.packedQty != oi.pickedQty)
|
|
165
155
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
156
|
+
let remainingPackQty: number = packedQty
|
|
157
|
+
let qtyToPack: number = 0
|
|
158
|
+
for (let orderInventory of orderInventories) {
|
|
159
|
+
const remainPackedQty: number = orderInventory.pickedQty - orderInventory.packedQty
|
|
160
|
+
let worksheetDetail: WorksheetDetail = await this.trxMgr
|
|
161
|
+
.getRepository(WorksheetDetail)
|
|
162
|
+
.createQueryBuilder('wd')
|
|
163
|
+
.innerJoinAndSelect('wd.bizplace', 'b')
|
|
164
|
+
.innerJoinAndSelect('wd.targetInventory', 'oi')
|
|
165
|
+
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
166
|
+
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
167
|
+
.innerJoinAndSelect('oi.product', 'prd')
|
|
168
|
+
.innerJoinAndSelect('oi.productDetail', 'pd')
|
|
169
|
+
.where('oi.id = :id', { id: orderInventory.id })
|
|
170
|
+
.andWhere('wd.type = :type', { type: WORKSHEET_TYPE.PACKING })
|
|
171
|
+
.getOne()
|
|
172
|
+
|
|
173
|
+
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
174
|
+
let inventory: Inventory = targetInventory.inventory
|
|
175
|
+
const releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
|
|
176
|
+
const product: Product = targetInventory.product
|
|
177
|
+
const productDetail: ProductDetail = targetInventory.productDetail
|
|
178
|
+
const pickedQty: number = targetInventory.releaseQty
|
|
179
|
+
if (remainPackedQty >= packedQty) {
|
|
180
|
+
qtyToPack = packedQty
|
|
181
|
+
remainingPackQty = 0
|
|
182
|
+
} else {
|
|
183
|
+
qtyToPack = remainPackedQty
|
|
184
|
+
remainingPackQty -= remainPackedQty
|
|
185
|
+
}
|
|
169
186
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
187
|
+
if (qtyToPack > pickedQty) {
|
|
188
|
+
throw new Error(
|
|
189
|
+
this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('pack', `packed quantity can't exceed release qty`)
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Serial Number scanning for batch picking
|
|
194
|
+
if (targetInventory?.refWorksheetId) {
|
|
195
|
+
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
196
|
+
if (!serialNumber || serialNumber == '') {
|
|
197
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('packing', `require serial number`))
|
|
176
198
|
}
|
|
177
199
|
|
|
178
|
-
foundSerialNumber
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
200
|
+
let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
|
|
201
|
+
where: { domain: this.domain, serialNumber: serialNumber, productDetail }
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
if (foundSerialNumber) {
|
|
205
|
+
if (foundSerialNumber.outboundOrderId) {
|
|
206
|
+
let releaseGood: ReleaseGood = await this.trxMgr
|
|
207
|
+
.getRepository(ReleaseGood)
|
|
208
|
+
.findOne({ where: { id: foundSerialNumber.outboundOrderId } })
|
|
209
|
+
throw new Error(`Inventory Item is already picked/packed in ${releaseGood.name}`)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
foundSerialNumber.status = INVENTORY_STATUS.PACKING
|
|
213
|
+
foundSerialNumber.updater = this.user
|
|
214
|
+
foundSerialNumber.outboundOrderId = releaseGood.id
|
|
215
|
+
|
|
216
|
+
await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
|
|
217
|
+
} else {
|
|
218
|
+
let inventoryItem: InventoryItem = new InventoryItem()
|
|
219
|
+
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
220
|
+
inventoryItem.serialNumber = serialNumber
|
|
221
|
+
inventoryItem.status = INVENTORY_STATUS.PACKING
|
|
222
|
+
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
223
|
+
inventoryItem.outboundOrderId = releaseGood.id
|
|
224
|
+
inventoryItem.product = product
|
|
225
|
+
inventoryItem.productDetail = productDetail
|
|
226
|
+
inventoryItem.inventory = inventory
|
|
227
|
+
inventoryItem.domain = this.domain
|
|
228
|
+
|
|
229
|
+
foundSerialNumber = await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
230
|
+
}
|
|
196
231
|
}
|
|
197
232
|
}
|
|
198
|
-
}
|
|
199
233
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
234
|
+
targetInventory.packedQty = Boolean(targetInventory.packedQty) ? targetInventory.packedQty + qtyToPack : qtyToPack
|
|
235
|
+
if (targetInventory.packedQty == targetInventory.releaseQty) {
|
|
236
|
+
targetInventory.status = ORDER_INVENTORY_STATUS.PACKED
|
|
203
237
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
238
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
239
|
+
.getRepository(InventoryItem)
|
|
240
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
207
241
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
242
|
+
if (inventoryItems.length > 0) {
|
|
243
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
244
|
+
itm.status = INVENTORY_STATUS.PACKED
|
|
245
|
+
itm.updater = this.user
|
|
246
|
+
})
|
|
213
247
|
|
|
214
|
-
|
|
248
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.PACKING)
|
|
252
|
+
|
|
253
|
+
worksheetDetail.status = WORKSHEET_STATUS.DONE
|
|
215
254
|
}
|
|
216
255
|
|
|
217
|
-
await this.
|
|
256
|
+
await this.updateOrderTargets([targetInventory])
|
|
257
|
+
|
|
258
|
+
worksheetDetail.updater = this.user
|
|
259
|
+
worksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
218
260
|
|
|
219
|
-
|
|
261
|
+
if (!remainingPackQty) {
|
|
262
|
+
break
|
|
263
|
+
}
|
|
220
264
|
}
|
|
221
265
|
|
|
222
|
-
|
|
266
|
+
orderPackageItem.packedQty = Boolean(orderPackageItem?.packedQty)
|
|
267
|
+
? orderPackageItem.packedQty + packedQty
|
|
268
|
+
: packedQty
|
|
223
269
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
270
|
+
if (orderPackageItem.packedQty == orderPackageItem.releaseQty) {
|
|
271
|
+
orderPackageItem.status = ORDER_STATUS.DONE
|
|
272
|
+
}
|
|
228
273
|
|
|
229
|
-
|
|
230
|
-
let worksheetDetail: WorksheetDetail = await this.trxMgr
|
|
231
|
-
.getRepository(WorksheetDetail)
|
|
232
|
-
.createQueryBuilder('wd')
|
|
233
|
-
.innerJoinAndSelect('wd.bizplace', 'b') //
|
|
234
|
-
.innerJoinAndSelect('wd.targetInventory', 'oi')
|
|
235
|
-
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
236
|
-
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
237
|
-
.leftJoinAndSelect('oi.orderProduct', 'op')
|
|
238
|
-
.innerJoinAndSelect('oi.product', 'prd')
|
|
239
|
-
.innerJoinAndSelect('oi.productDetail', 'pd')
|
|
240
|
-
.innerJoinAndSelect('pd.productBarcodes', 'pb')
|
|
241
|
-
.where('wd.id = :id', { id: worksheetDetailName })
|
|
242
|
-
.getOne()
|
|
274
|
+
await this.trxMgr.getRepository(OrderPackageItem).save(orderPackageItem)
|
|
243
275
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const releaseGood: ReleaseGood = targetInventory.releaseGood
|
|
249
|
-
const product: Product = targetInventory.product
|
|
250
|
-
const productDetail: ProductDetail = targetInventory.productDetail
|
|
251
|
-
const productBarcodes: [ProductBarcode] = productDetail.productBarcodes
|
|
252
|
-
let matchingProduct
|
|
253
|
-
|
|
254
|
-
if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
|
|
255
|
-
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
276
|
+
return {
|
|
277
|
+
releaseGood: orderPackageItem.orderPackage.releaseGood,
|
|
278
|
+
bizplace: orderPackageItem.orderPackage.bizplace,
|
|
279
|
+
bizplaceDomain: orderPackageItem.orderPackage.bizplace.domain
|
|
256
280
|
}
|
|
281
|
+
}
|
|
257
282
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
productBarcode,
|
|
264
|
-
packedQty
|
|
265
|
-
)
|
|
283
|
+
async scanProductPacking(orderPackageItemId: string, productBarcode: string, serialNumber?: string): Promise<any> {
|
|
284
|
+
let orderPackageItem: OrderPackageItem = await this.trxMgr.getRepository(OrderPackageItem).findOne({
|
|
285
|
+
where: { id: orderPackageItemId },
|
|
286
|
+
relations: ['orderPackage', 'orderProduct', 'orderProduct.orderInventories']
|
|
287
|
+
})
|
|
266
288
|
|
|
267
|
-
|
|
268
|
-
|
|
289
|
+
const orderProduct: OrderProduct = orderPackageItem.orderProduct
|
|
290
|
+
const orderInventories: OrderInventory[] = orderProduct.orderInventories.filter(oi => oi.packedQty != oi.pickedQty)
|
|
291
|
+
let packedQty: number = 1
|
|
269
292
|
|
|
270
|
-
|
|
293
|
+
for (let orderInventory of orderInventories) {
|
|
294
|
+
let worksheetDetail: WorksheetDetail = await this.trxMgr
|
|
295
|
+
.getRepository(WorksheetDetail)
|
|
296
|
+
.createQueryBuilder('wd')
|
|
297
|
+
.innerJoinAndSelect('wd.bizplace', 'b')
|
|
298
|
+
.innerJoinAndSelect('wd.targetInventory', 'oi')
|
|
299
|
+
.innerJoinAndSelect('oi.releaseGood', 'rg')
|
|
300
|
+
.innerJoinAndSelect('oi.inventory', 'inv')
|
|
301
|
+
.leftJoinAndSelect('oi.orderProduct', 'op')
|
|
302
|
+
.innerJoinAndSelect('oi.product', 'prd')
|
|
303
|
+
.innerJoinAndSelect('oi.productDetail', 'pd')
|
|
304
|
+
.innerJoinAndSelect('pd.productBarcodes', 'pb')
|
|
305
|
+
.where('oi.id = :id', { id: orderInventory.id })
|
|
306
|
+
.getOne()
|
|
307
|
+
|
|
308
|
+
let targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
309
|
+
|
|
310
|
+
let inventory: Inventory = targetInventory.inventory
|
|
311
|
+
let pickedQty: number = targetInventory.releaseQty
|
|
312
|
+
const releaseGood: ReleaseGood = targetInventory.releaseGood
|
|
313
|
+
const product: Product = targetInventory.product
|
|
314
|
+
const productDetail: ProductDetail = targetInventory.productDetail
|
|
315
|
+
const productBarcodes: [ProductBarcode] = productDetail.productBarcodes
|
|
316
|
+
let matchingProduct
|
|
317
|
+
|
|
318
|
+
if (!productBarcodes.find(itm => itm.gtin == productBarcode) && product?.isRequireSerialNumberScanningOutbound) {
|
|
319
|
+
throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
320
|
+
}
|
|
271
321
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
322
|
+
matchingProduct = await this.getDirectQty(
|
|
323
|
+
{
|
|
324
|
+
...productDetail,
|
|
325
|
+
product: targetInventory?.product
|
|
326
|
+
},
|
|
327
|
+
productBarcode,
|
|
328
|
+
packedQty
|
|
329
|
+
)
|
|
275
330
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
279
|
-
if (!serialNumber || serialNumber == '') {
|
|
280
|
-
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('packing', `require serial number`))
|
|
281
|
-
}
|
|
331
|
+
//validate matching product details based on scanned barcode
|
|
332
|
+
if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
|
|
282
333
|
|
|
283
|
-
|
|
284
|
-
.getRepository(InventoryItem)
|
|
285
|
-
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, productDetail } })
|
|
334
|
+
packedQty = matchingProduct.qty
|
|
286
335
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
336
|
+
if (packedQty + targetInventory.packedQty > pickedQty) {
|
|
337
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
|
|
338
|
+
}
|
|
291
339
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
throw new Error(`
|
|
340
|
+
// Serial Number scanning for batch picking
|
|
341
|
+
if (targetInventory?.refWorksheetId) {
|
|
342
|
+
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
343
|
+
if (!serialNumber || serialNumber == '') {
|
|
344
|
+
throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('packing', `require serial number`))
|
|
297
345
|
}
|
|
298
346
|
|
|
299
|
-
foundSerialNumber
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
347
|
+
let foundSerialNumber: InventoryItem = await this.trxMgr
|
|
348
|
+
.getRepository(InventoryItem)
|
|
349
|
+
.findOne({ where: { domain: this.domain, serialNumber: serialNumber, productDetail } })
|
|
350
|
+
|
|
351
|
+
if (foundSerialNumber) {
|
|
352
|
+
if (foundSerialNumber.inventoryId !== inventory.id) {
|
|
353
|
+
throw new Error('Serial Number scanned is in another inventory')
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (foundSerialNumber.outboundOrderId) {
|
|
357
|
+
let releaseGood: ReleaseGood = await this.trxMgr
|
|
358
|
+
.getRepository(ReleaseGood)
|
|
359
|
+
.findOne({ where: { id: foundSerialNumber.outboundOrderId } })
|
|
360
|
+
throw new Error(`Inventory Item is already picked/packed in ${releaseGood.name}`)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
foundSerialNumber.status = INVENTORY_STATUS.PACKING
|
|
364
|
+
foundSerialNumber.updater = this.user
|
|
365
|
+
foundSerialNumber.outboundOrderId = releaseGood.id
|
|
366
|
+
|
|
367
|
+
await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
|
|
368
|
+
} else {
|
|
369
|
+
let inventoryItem: InventoryItem = new InventoryItem()
|
|
370
|
+
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
371
|
+
inventoryItem.serialNumber = serialNumber
|
|
372
|
+
inventoryItem.status = INVENTORY_STATUS.PACKING
|
|
373
|
+
inventoryItem.outboundOrderId = releaseGood.id
|
|
374
|
+
inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
|
|
375
|
+
inventoryItem.product = product
|
|
376
|
+
inventoryItem.productDetail = productDetail
|
|
377
|
+
inventoryItem.inventory = inventory
|
|
378
|
+
inventoryItem.domain = this.domain
|
|
379
|
+
|
|
380
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
|
|
381
|
+
}
|
|
317
382
|
}
|
|
318
383
|
}
|
|
319
|
-
}
|
|
320
384
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
385
|
+
targetInventory.packedQty = Boolean(targetInventory?.packedQty)
|
|
386
|
+
? targetInventory.packedQty + packedQty
|
|
387
|
+
: packedQty
|
|
388
|
+
if (targetInventory.packedQty > pickedQty) {
|
|
389
|
+
throw new Error(
|
|
390
|
+
this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('pack', `packed quantity can't exceed release qty`)
|
|
391
|
+
)
|
|
392
|
+
}
|
|
325
393
|
|
|
326
|
-
|
|
327
|
-
|
|
394
|
+
targetInventory.packedAt = new Date()
|
|
395
|
+
targetInventory.packedByUser = this.user
|
|
328
396
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
397
|
+
let packedBy: string[] = targetInventory.packedBy ? targetInventory.packedBy.split(',') : []
|
|
398
|
+
if (!packedBy.find(x => x == this.user.name)) {
|
|
399
|
+
packedBy.push(this.user.name)
|
|
400
|
+
targetInventory.packedBy = packedBy.join(',')
|
|
401
|
+
}
|
|
334
402
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
403
|
+
if (targetInventory.packedQty == pickedQty) {
|
|
404
|
+
targetInventory.status = ORDER_INVENTORY_STATUS.PACKED
|
|
405
|
+
await this.updateOrderTargets([targetInventory])
|
|
406
|
+
await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.PACKING)
|
|
339
407
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
408
|
+
worksheetDetail.status = WORKSHEET_STATUS.DONE
|
|
409
|
+
worksheetDetail.updater = this.user
|
|
410
|
+
await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
343
411
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
412
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
413
|
+
.getRepository(InventoryItem)
|
|
414
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
347
415
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
416
|
+
if (inventoryItems.length > 0) {
|
|
417
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
418
|
+
itm.status = INVENTORY_STATUS.PACKED
|
|
419
|
+
itm.updater = this.user
|
|
420
|
+
})
|
|
353
421
|
|
|
354
|
-
|
|
422
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
423
|
+
}
|
|
424
|
+
} else {
|
|
425
|
+
await this.trxMgr.getRepository(OrderInventory).save(targetInventory)
|
|
355
426
|
}
|
|
356
|
-
|
|
357
|
-
await this.trxMgr.getRepository(OrderInventory).save(targetInventory)
|
|
427
|
+
break
|
|
358
428
|
}
|
|
359
429
|
|
|
430
|
+
orderPackageItem.packedQty = Boolean(orderPackageItem?.packedQty)
|
|
431
|
+
? orderPackageItem.packedQty + packedQty
|
|
432
|
+
: packedQty
|
|
433
|
+
|
|
434
|
+
if (orderPackageItem.packedQty == orderPackageItem.releaseQty) {
|
|
435
|
+
orderPackageItem.status = ORDER_STATUS.DONE
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
await this.trxMgr.getRepository(OrderPackageItem).save(orderPackageItem)
|
|
439
|
+
await this.trxMgr
|
|
440
|
+
.getRepository(OrderPackage)
|
|
441
|
+
.update({ id: orderPackageItem.orderPackage.id }, { updatedAt: new Date() })
|
|
442
|
+
|
|
360
443
|
return {
|
|
361
444
|
worksheetDetailInfos: [
|
|
362
445
|
{
|
|
363
|
-
id:
|
|
364
|
-
releaseQty:
|
|
365
|
-
packedQty:
|
|
366
|
-
status:
|
|
446
|
+
id: orderPackageItem.id,
|
|
447
|
+
releaseQty: orderPackageItem.releaseQty,
|
|
448
|
+
packedQty: orderPackageItem.packedQty,
|
|
449
|
+
status: orderPackageItem.status
|
|
367
450
|
}
|
|
368
451
|
]
|
|
369
452
|
}
|
|
370
453
|
}
|
|
371
454
|
|
|
372
|
-
async completePacking(releaseGoodNo: string): Promise<Worksheet> {
|
|
373
|
-
let
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
455
|
+
async completePacking(releaseGoodNo: string, orderPackageId: string): Promise<Worksheet> {
|
|
456
|
+
let orderPackage: OrderPackage = await this.trxMgr
|
|
457
|
+
.getRepository(OrderPackage)
|
|
458
|
+
.findOne({ where: { id: orderPackageId } })
|
|
459
|
+
|
|
460
|
+
await this.trxMgr
|
|
461
|
+
.getRepository(OrderPackage)
|
|
462
|
+
.update({ id: orderPackage.id }, { status: ORDER_STATUS.DONE, updater: this.user, updatedAt: new Date() })
|
|
463
|
+
|
|
464
|
+
let releaseGood: ReleaseGood = await this.findRefOrder(
|
|
465
|
+
ReleaseGood,
|
|
466
|
+
{
|
|
467
|
+
domain: this.domain,
|
|
468
|
+
name: releaseGoodNo,
|
|
469
|
+
status: ORDER_STATUS.PACKING
|
|
470
|
+
},
|
|
471
|
+
['bizplace']
|
|
472
|
+
)
|
|
378
473
|
|
|
379
474
|
const worksheet: Worksheet = await this.findWorksheetByRefOrder(releaseGood, WORKSHEET_TYPE.PACKING, [
|
|
380
475
|
'worksheetDetails',
|
|
@@ -382,24 +477,32 @@ export class PackingWorksheetController extends VasWorksheetController {
|
|
|
382
477
|
])
|
|
383
478
|
this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
|
|
384
479
|
|
|
385
|
-
let
|
|
386
|
-
.getRepository(
|
|
387
|
-
.find({ where: {
|
|
480
|
+
let orderPackages: OrderPackage[] = await this.trxMgr
|
|
481
|
+
.getRepository(OrderPackage)
|
|
482
|
+
.find({ where: { releaseGood, domain: this.domain, bizplace: releaseGood.bizplace } })
|
|
388
483
|
|
|
389
|
-
if (
|
|
390
|
-
inventoryItems
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
})
|
|
484
|
+
if (orderPackages.every(op => op.status == ORDER_STATUS.DONE)) {
|
|
485
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
486
|
+
.getRepository(InventoryItem)
|
|
487
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
394
488
|
|
|
395
|
-
|
|
396
|
-
|
|
489
|
+
if (inventoryItems.length > 0) {
|
|
490
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
491
|
+
itm.status = INVENTORY_STATUS.TERMINATED
|
|
492
|
+
itm.updater = this.user
|
|
493
|
+
})
|
|
397
494
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
else orderStatus = ORDER_STATUS.LOADING
|
|
495
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
496
|
+
}
|
|
401
497
|
|
|
402
|
-
|
|
498
|
+
let orderStatus: string
|
|
499
|
+
if (releaseGood?.courierOption) orderStatus = ORDER_STATUS.DONE
|
|
500
|
+
else orderStatus = ORDER_STATUS.LOADING
|
|
501
|
+
|
|
502
|
+
return await this.completeWorksheet(worksheet, orderStatus)
|
|
503
|
+
} else {
|
|
504
|
+
return worksheet
|
|
505
|
+
}
|
|
403
506
|
}
|
|
404
507
|
|
|
405
508
|
async undoSerialNumberPacking(worksheetDetailName: string, inventoryItemId: string): Promise<void> {
|
|
@@ -12,9 +12,9 @@ import { XilnexController } from '../../../../controllers/pos'
|
|
|
12
12
|
import { WorksheetController } from '../../../../controllers/worksheet-controller'
|
|
13
13
|
|
|
14
14
|
export const completePackingResolver = {
|
|
15
|
-
async completePacking(_: any, { releaseGoodNo }, context: any) {
|
|
15
|
+
async completePacking(_: any, { releaseGoodNo, orderPackageId }, context: any) {
|
|
16
16
|
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
17
|
-
await completePacking(tx, domain, user, releaseGoodNo)
|
|
17
|
+
await completePacking(tx, domain, user, releaseGoodNo, orderPackageId)
|
|
18
18
|
|
|
19
19
|
const releaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
20
20
|
where: { name: releaseGoodNo, domain },
|
|
@@ -51,8 +51,9 @@ export async function completePacking(
|
|
|
51
51
|
tx: EntityManager,
|
|
52
52
|
domain: Domain,
|
|
53
53
|
user: User,
|
|
54
|
-
releaseGoodNo: string
|
|
54
|
+
releaseGoodNo: string,
|
|
55
|
+
orderPackageId: string
|
|
55
56
|
): Promise<void> {
|
|
56
57
|
const packingWSCtrl: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
|
|
57
|
-
await packingWSCtrl.completePacking(releaseGoodNo)
|
|
58
|
+
await packingWSCtrl.completePacking(releaseGoodNo, orderPackageId)
|
|
58
59
|
}
|