@things-factory/worksheet-base 4.3.143 → 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.
Files changed (34) hide show
  1. package/dist-server/controllers/ecommerce/ecommerce-controller.js +48 -0
  2. package/dist-server/controllers/ecommerce/ecommerce-controller.js.map +1 -1
  3. package/dist-server/controllers/ecommerce/sellercraft-controller.js +82 -31
  4. package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
  5. package/dist-server/controllers/outbound/packing-worksheet-controller.js +265 -189
  6. package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
  7. package/dist-server/graphql/resolvers/worksheet/packing/complete-packing.js +4 -4
  8. package/dist-server/graphql/resolvers/worksheet/packing/complete-packing.js.map +1 -1
  9. package/dist-server/graphql/resolvers/worksheet/packing/packing.js +6 -7
  10. package/dist-server/graphql/resolvers/worksheet/packing/packing.js.map +1 -1
  11. package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js +4 -4
  12. package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js.map +1 -1
  13. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +84 -38
  14. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
  15. package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js +44 -9
  16. package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js.map +1 -1
  17. package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +41 -11
  18. package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
  19. package/dist-server/graphql/types/worksheet/index.js +6 -5
  20. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  21. package/dist-server/graphql/types/worksheet/worksheet-info.js +2 -0
  22. package/dist-server/graphql/types/worksheet/worksheet-info.js.map +1 -1
  23. package/package.json +18 -18
  24. package/server/controllers/ecommerce/ecommerce-controller.ts +52 -1
  25. package/server/controllers/ecommerce/sellercraft-controller.ts +119 -46
  26. package/server/controllers/outbound/packing-worksheet-controller.ts +314 -211
  27. package/server/graphql/resolvers/worksheet/packing/complete-packing.ts +5 -4
  28. package/server/graphql/resolvers/worksheet/packing/packing.ts +6 -8
  29. package/server/graphql/resolvers/worksheet/packing/scan-product-packing.ts +6 -9
  30. package/server/graphql/resolvers/worksheet/packing-worksheet.ts +124 -42
  31. package/server/graphql/resolvers/worksheet/picking/complete-batch-picking.ts +59 -11
  32. package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +47 -12
  33. package/server/graphql/types/worksheet/index.ts +6 -5
  34. 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 { ORDER_INVENTORY_STATUS, ORDER_STATUS, OrderInventory, ReleaseGood } from '@things-factory/sales-base'
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(worksheetDetailName: string, packedQty: number, serialNumber: string): Promise<WorksheetDetail> {
133
- let worksheetDetail: WorksheetDetail = await this.findExecutableWorksheetDetailByName(
134
- worksheetDetailName,
135
- WORKSHEET_TYPE.PACKING,
136
- [
137
- 'worksheet',
138
- 'worksheet.bizplace',
139
- 'worksheet.bizplace.domain',
140
- 'targetInventory',
141
- 'targetInventory.releaseGood',
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
- // Serial Number scanning for batch picking
160
- if (targetInventory?.refWorksheetId) {
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
- let foundSerialNumber: InventoryItem = await this.trxMgr.getRepository(InventoryItem).findOne({
167
- where: { domain: this.domain, serialNumber: serialNumber, productDetail }
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
- if (foundSerialNumber) {
171
- if (foundSerialNumber.outboundOrderId) {
172
- let releaseGood: ReleaseGood = await this.trxMgr
173
- .getRepository(ReleaseGood)
174
- .findOne({ where: { id: foundSerialNumber.outboundOrderId } })
175
- throw new Error(`Inventory Item is already picked/packed in ${releaseGood.name}`)
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.status = INVENTORY_STATUS.PACKING
179
- foundSerialNumber.updater = this.user
180
- foundSerialNumber.outboundOrderId = releaseGood.id
181
-
182
- await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
183
- } else {
184
- let inventoryItem: InventoryItem = new InventoryItem()
185
- inventoryItem.name = InventoryNoGenerator.inventoryItemName()
186
- inventoryItem.serialNumber = serialNumber
187
- inventoryItem.status = INVENTORY_STATUS.PACKING
188
- inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
189
- inventoryItem.outboundOrderId = releaseGood.id
190
- inventoryItem.product = product
191
- inventoryItem.productDetail = productDetail
192
- inventoryItem.inventory = inventory
193
- inventoryItem.domain = this.domain
194
-
195
- foundSerialNumber = await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
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
- targetInventory.packedQty = Boolean(targetInventory.packedQty) ? targetInventory.packedQty + packedQty : packedQty
201
- if (targetInventory.packedQty == targetInventory.releaseQty) {
202
- targetInventory.status = ORDER_INVENTORY_STATUS.PACKED
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
- let inventoryItems: InventoryItem = await this.trxMgr
205
- .getRepository(InventoryItem)
206
- .find({ where: { outboundOrderId: releaseGood.id } })
238
+ let inventoryItems: InventoryItem = await this.trxMgr
239
+ .getRepository(InventoryItem)
240
+ .find({ where: { outboundOrderId: releaseGood.id } })
207
241
 
208
- if (inventoryItems.length > 0) {
209
- inventoryItems.forEach((itm: InventoryItem) => {
210
- itm.status = INVENTORY_STATUS.PACKED
211
- itm.updater = this.user
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
- await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
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.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.PACKING)
256
+ await this.updateOrderTargets([targetInventory])
257
+
258
+ worksheetDetail.updater = this.user
259
+ worksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
218
260
 
219
- worksheetDetail.status = WORKSHEET_STATUS.DONE
261
+ if (!remainingPackQty) {
262
+ break
263
+ }
220
264
  }
221
265
 
222
- await this.updateOrderTargets([targetInventory])
266
+ orderPackageItem.packedQty = Boolean(orderPackageItem?.packedQty)
267
+ ? orderPackageItem.packedQty + packedQty
268
+ : packedQty
223
269
 
224
- worksheetDetail.updater = this.user
225
- worksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
226
- return worksheetDetail
227
- }
270
+ if (orderPackageItem.packedQty == orderPackageItem.releaseQty) {
271
+ orderPackageItem.status = ORDER_STATUS.DONE
272
+ }
228
273
 
229
- async scanProductPacking(worksheetDetailName: string, productBarcode: string, serialNumber?: string): Promise<any> {
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
- let targetInventory: OrderInventory = worksheetDetail.targetInventory
245
- let inventory: Inventory = targetInventory.inventory
246
- let packedQty: number = 1
247
- let pickedQty: number = targetInventory.releaseQty
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
- matchingProduct = await this.getDirectQty(
259
- {
260
- ...productDetail,
261
- product: targetInventory?.product
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
- //validate matching product details based on scanned barcode
268
- if (!matchingProduct) throw new Error(this.ERROR_MSG.FIND.NO_RESULT(productBarcode))
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
- packedQty = matchingProduct.qty
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
- if (packedQty + targetInventory.packedQty > pickedQty) {
273
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `over release`))
274
- }
322
+ matchingProduct = await this.getDirectQty(
323
+ {
324
+ ...productDetail,
325
+ product: targetInventory?.product
326
+ },
327
+ productBarcode,
328
+ packedQty
329
+ )
275
330
 
276
- // Serial Number scanning for batch picking
277
- if (targetInventory?.refWorksheetId) {
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
- let foundSerialNumber: InventoryItem = await this.trxMgr
284
- .getRepository(InventoryItem)
285
- .findOne({ where: { domain: this.domain, serialNumber: serialNumber, productDetail } })
334
+ packedQty = matchingProduct.qty
286
335
 
287
- if (foundSerialNumber) {
288
- if (foundSerialNumber.inventoryId !== inventory.id) {
289
- throw new Error('Serial Number scanned is in another inventory')
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
- if (foundSerialNumber.outboundOrderId) {
293
- let releaseGood: ReleaseGood = await this.trxMgr
294
- .getRepository(ReleaseGood)
295
- .findOne({ where: { id: foundSerialNumber.outboundOrderId } })
296
- throw new Error(`Inventory Item is already picked/packed in ${releaseGood.name}`)
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.status = INVENTORY_STATUS.PACKING
300
- foundSerialNumber.updater = this.user
301
- foundSerialNumber.outboundOrderId = releaseGood.id
302
-
303
- await this.trxMgr.getRepository(InventoryItem).save(foundSerialNumber)
304
- } else {
305
- let inventoryItem: InventoryItem = new InventoryItem()
306
- inventoryItem.name = InventoryNoGenerator.inventoryItemName()
307
- inventoryItem.serialNumber = serialNumber
308
- inventoryItem.status = INVENTORY_STATUS.PACKING
309
- inventoryItem.outboundOrderId = releaseGood.id
310
- inventoryItem.source = INVENTORY_ITEM_SOURCE.OUTBOUND
311
- inventoryItem.product = product
312
- inventoryItem.productDetail = productDetail
313
- inventoryItem.inventory = inventory
314
- inventoryItem.domain = this.domain
315
-
316
- await this.trxMgr.getRepository(InventoryItem).save(inventoryItem)
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
- targetInventory.packedQty = Boolean(targetInventory?.packedQty) ? targetInventory.packedQty + packedQty : packedQty
322
- if (targetInventory.packedQty > pickedQty) {
323
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('pack', `packed quantity can't exceed release qty`))
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
- targetInventory.packedAt = new Date()
327
- targetInventory.packedByUser = this.user
394
+ targetInventory.packedAt = new Date()
395
+ targetInventory.packedByUser = this.user
328
396
 
329
- let packedBy: string[] = targetInventory.packedBy ? targetInventory.packedBy.split(',') : []
330
- if (!packedBy.find(x => x == this.user.name)) {
331
- packedBy.push(this.user.name)
332
- targetInventory.packedBy = packedBy.join(',')
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
- if (targetInventory.packedQty == pickedQty) {
336
- targetInventory.status = ORDER_INVENTORY_STATUS.PACKED
337
- await this.updateOrderTargets([targetInventory])
338
- await this.transactionInventory(inventory, releaseGood, 0, 0, INVENTORY_TRANSACTION_TYPE.PACKING)
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
- worksheetDetail.status = WORKSHEET_STATUS.DONE
341
- worksheetDetail.updater = this.user
342
- await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
408
+ worksheetDetail.status = WORKSHEET_STATUS.DONE
409
+ worksheetDetail.updater = this.user
410
+ await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
343
411
 
344
- let inventoryItems: InventoryItem = await this.trxMgr
345
- .getRepository(InventoryItem)
346
- .find({ where: { outboundOrderId: releaseGood.id } })
412
+ let inventoryItems: InventoryItem = await this.trxMgr
413
+ .getRepository(InventoryItem)
414
+ .find({ where: { outboundOrderId: releaseGood.id } })
347
415
 
348
- if (inventoryItems.length > 0) {
349
- inventoryItems.forEach((itm: InventoryItem) => {
350
- itm.status = INVENTORY_STATUS.PACKED
351
- itm.updater = this.user
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
- await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
422
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
423
+ }
424
+ } else {
425
+ await this.trxMgr.getRepository(OrderInventory).save(targetInventory)
355
426
  }
356
- } else {
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: worksheetDetail.id,
364
- releaseQty: worksheetDetail.targetInventory.releaseQty,
365
- packedQty: worksheetDetail.targetInventory.packedQty,
366
- status: worksheetDetail.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 releaseGood: ReleaseGood = await this.findRefOrder(ReleaseGood, {
374
- domain: this.domain,
375
- name: releaseGoodNo,
376
- status: ORDER_STATUS.PACKING
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 inventoryItems: InventoryItem = await this.trxMgr
386
- .getRepository(InventoryItem)
387
- .find({ where: { outboundOrderId: releaseGood.id } })
480
+ let orderPackages: OrderPackage[] = await this.trxMgr
481
+ .getRepository(OrderPackage)
482
+ .find({ where: { releaseGood, domain: this.domain, bizplace: releaseGood.bizplace } })
388
483
 
389
- if (inventoryItems.length > 0) {
390
- inventoryItems.forEach((itm: InventoryItem) => {
391
- itm.status = INVENTORY_STATUS.TERMINATED
392
- itm.updater = this.user
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
- await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
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
- let orderStatus: string
399
- if (releaseGood?.courierOption) orderStatus = ORDER_STATUS.DONE
400
- else orderStatus = ORDER_STATUS.LOADING
495
+ await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
496
+ }
401
497
 
402
- return await this.completeWorksheet(worksheet, orderStatus)
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
  }