@things-factory/worksheet-base 4.2.12 → 4.3.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/outbound/loading-worksheet-controller.js +47 -10
- package/dist-server/controllers/outbound/loading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/picking-worksheet-controller.js +142 -5
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/sorting-worksheet-controller.js +116 -20
- package/dist-server/controllers/outbound/sorting-worksheet-controller.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/batch-picking-worksheet.js +14 -1
- package/dist-server/graphql/resolvers/worksheet/batch-picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/loading/loading.js +3 -10
- package/dist-server/graphql/resolvers/worksheet/loading/loading.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/loading-worksheet.js +55 -21
- package/dist-server/graphql/resolvers/worksheet/loading-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +1 -0
- package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +8 -6
- 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/picking.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/picking/picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/scan-product-picking.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/picking/scan-product-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/seal-tote.js +15 -0
- package/dist-server/graphql/resolvers/worksheet/picking/seal-tote.js.map +1 -0
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js +10 -1
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/sorting/complete-order-sorting.js +11 -6
- package/dist-server/graphql/resolvers/worksheet/sorting/complete-order-sorting.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/worksheet.js +2 -0
- package/dist-server/graphql/resolvers/worksheet/worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/worksheets.js +17 -2
- package/dist-server/graphql/resolvers/worksheet/worksheets.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.js +5 -3
- 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-batch-picking-worksheet-details.js +15 -4
- package/dist-server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.js +4 -1
- package/dist-server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet-detail/generate-release-good-worksheet-details.js +6 -2
- package/dist-server/graphql/resolvers/worksheet-detail/generate-release-good-worksheet-details.js.map +1 -1
- package/dist-server/graphql/types/worksheet/index.js +10 -0
- package/dist-server/graphql/types/worksheet/index.js.map +1 -1
- package/dist-server/graphql/types/worksheet/loaded-worksheet-detail.js +1 -0
- package/dist-server/graphql/types/worksheet/loaded-worksheet-detail.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/worksheet-info.js +2 -0
- package/dist-server/graphql/types/worksheet/worksheet-info.js.map +1 -1
- package/dist-server/graphql/types/worksheet/worksheet.js +1 -0
- package/dist-server/graphql/types/worksheet/worksheet.js.map +1 -1
- package/package.json +17 -17
- package/server/controllers/outbound/loading-worksheet-controller.ts +83 -17
- package/server/controllers/outbound/picking-worksheet-controller.ts +178 -7
- package/server/controllers/outbound/sorting-worksheet-controller.ts +167 -27
- package/server/graphql/resolvers/worksheet/batch-picking-worksheet.ts +14 -0
- package/server/graphql/resolvers/worksheet/loading/loading.ts +5 -12
- package/server/graphql/resolvers/worksheet/loading-worksheet.ts +66 -13
- package/server/graphql/resolvers/worksheet/packing-worksheet.ts +1 -1
- package/server/graphql/resolvers/worksheet/picking/complete-batch-picking.ts +1 -1
- package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +13 -11
- package/server/graphql/resolvers/worksheet/picking/index.ts +3 -1
- package/server/graphql/resolvers/worksheet/picking/picking.ts +30 -4
- package/server/graphql/resolvers/worksheet/picking/scan-product-picking.ts +7 -4
- package/server/graphql/resolvers/worksheet/picking/seal-tote.ts +25 -0
- package/server/graphql/resolvers/worksheet/picking-worksheet.ts +13 -2
- package/server/graphql/resolvers/worksheet/sorting/complete-order-sorting.ts +13 -9
- 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/worksheet.ts +2 -0
- package/server/graphql/resolvers/worksheet/worksheets.ts +26 -2
- package/server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.ts +12 -3
- package/server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details.ts +22 -7
- package/server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.ts +6 -2
- package/server/graphql/resolvers/worksheet-detail/generate-release-good-worksheet-details.ts +7 -1
- package/server/graphql/types/worksheet/index.ts +10 -0
- package/server/graphql/types/worksheet/loaded-worksheet-detail.ts +1 -0
- package/server/graphql/types/worksheet/worksheet-detail-info.ts +2 -0
- package/server/graphql/types/worksheet/worksheet-info.ts +2 -0
- package/server/graphql/types/worksheet/worksheet.ts +1 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IsNull, In } from 'typeorm'
|
|
2
|
+
|
|
1
3
|
import { VasWorksheetController } from '../vas/vas-worksheet-controller'
|
|
2
4
|
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
3
5
|
import {
|
|
@@ -6,11 +8,22 @@ import {
|
|
|
6
8
|
InventoryItem,
|
|
7
9
|
INVENTORY_STATUS,
|
|
8
10
|
InventoryNoGenerator,
|
|
9
|
-
INVENTORY_ITEM_SOURCE
|
|
11
|
+
INVENTORY_ITEM_SOURCE,
|
|
12
|
+
Tote,
|
|
13
|
+
TOTE_STATUS
|
|
10
14
|
} from '@things-factory/warehouse-base'
|
|
11
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
ReleaseGood,
|
|
17
|
+
OrderInventory,
|
|
18
|
+
ORDER_INVENTORY_STATUS,
|
|
19
|
+
ORDER_STATUS,
|
|
20
|
+
OrderTote,
|
|
21
|
+
OrderToteItem,
|
|
22
|
+
OrderNoGenerator
|
|
23
|
+
} from '@things-factory/sales-base'
|
|
12
24
|
import { Worksheet, WorksheetDetail } from '../../entities'
|
|
13
25
|
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../constants'
|
|
26
|
+
import { temporaryGetRemainInventoryAmount } from 'server/graphql/resolvers/worksheet/vas-transactions/common-utils'
|
|
14
27
|
|
|
15
28
|
export class SortingWorksheetController extends VasWorksheetController {
|
|
16
29
|
async generateSortingWorksheet(
|
|
@@ -62,7 +75,8 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
62
75
|
taskNo: string,
|
|
63
76
|
releaseGoodNo: string,
|
|
64
77
|
productBarcode: string,
|
|
65
|
-
serialNumber: string
|
|
78
|
+
serialNumber: string,
|
|
79
|
+
toteNo: string
|
|
66
80
|
): Promise<void> {
|
|
67
81
|
const worksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
|
|
68
82
|
where: {
|
|
@@ -75,6 +89,8 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
75
89
|
'worksheetDetails',
|
|
76
90
|
'worksheetDetails.targetInventory',
|
|
77
91
|
'worksheetDetails.targetInventory.product',
|
|
92
|
+
'worksheetDetails.targetInventory.orderProduct',
|
|
93
|
+
'worksheetDetails.targetInventory.bizplace',
|
|
78
94
|
'worksheetDetails.targetInventory.inventory',
|
|
79
95
|
'worksheetDetails.targetInventory.inventory.product',
|
|
80
96
|
'worksheetDetails.targetInventory.inventory.product.productDetails',
|
|
@@ -204,6 +220,17 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
204
220
|
} else {
|
|
205
221
|
await this.updateOrderTargets([matchingOI])
|
|
206
222
|
}
|
|
223
|
+
|
|
224
|
+
if (toteNo) {
|
|
225
|
+
await this.toteScanning(
|
|
226
|
+
toteNo,
|
|
227
|
+
matchingOI.orderProduct,
|
|
228
|
+
matchingOI,
|
|
229
|
+
1,
|
|
230
|
+
releaseGood,
|
|
231
|
+
matchingOI.bizplace
|
|
232
|
+
)
|
|
233
|
+
}
|
|
207
234
|
}
|
|
208
235
|
})
|
|
209
236
|
)
|
|
@@ -216,7 +243,8 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
216
243
|
releaseGoodNo: string,
|
|
217
244
|
productId: string,
|
|
218
245
|
sortingQty: number,
|
|
219
|
-
serialNumber: string
|
|
246
|
+
serialNumber: string,
|
|
247
|
+
toteNo: string
|
|
220
248
|
): Promise<void> {
|
|
221
249
|
const worksheet: Worksheet = await this.trxMgr.getRepository(Worksheet).findOne({
|
|
222
250
|
where: {
|
|
@@ -229,6 +257,8 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
229
257
|
'worksheetDetails',
|
|
230
258
|
'worksheetDetails.targetInventory',
|
|
231
259
|
'worksheetDetails.targetInventory.product',
|
|
260
|
+
'worksheetDetails.targetInventory.orderProduct',
|
|
261
|
+
'worksheetDetails.targetInventory.bizplace',
|
|
232
262
|
'worksheetDetails.targetInventory.inventory',
|
|
233
263
|
'worksheetDetails.targetInventory.inventory.product',
|
|
234
264
|
'worksheetDetails.targetInventory.inventory.product.productDetails',
|
|
@@ -294,6 +324,17 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
294
324
|
}
|
|
295
325
|
}
|
|
296
326
|
|
|
327
|
+
if (toteNo) {
|
|
328
|
+
await this.toteScanning(
|
|
329
|
+
toteNo,
|
|
330
|
+
matchingOI.orderProduct,
|
|
331
|
+
matchingOI,
|
|
332
|
+
sortingQty,
|
|
333
|
+
releaseGood,
|
|
334
|
+
matchingOI.bizplace
|
|
335
|
+
)
|
|
336
|
+
}
|
|
337
|
+
|
|
297
338
|
if (releaseQty != matchingOI?.sortedQty && sortingQty != 0) {
|
|
298
339
|
if (product?.isRequireSerialNumberScanningOutbound) {
|
|
299
340
|
matchingOI.sortedQty += sortingQty
|
|
@@ -338,34 +379,50 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
338
379
|
}
|
|
339
380
|
|
|
340
381
|
async completeOrderSorting(releaseGoodNo: string): Promise<ReleaseGood> {
|
|
341
|
-
|
|
342
|
-
ReleaseGood
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
382
|
+
try {
|
|
383
|
+
let releaseGood: ReleaseGood = await this.findRefOrder(
|
|
384
|
+
ReleaseGood,
|
|
385
|
+
{
|
|
386
|
+
domain: this.domain,
|
|
387
|
+
name: releaseGoodNo,
|
|
388
|
+
status: ORDER_STATUS.SORTING
|
|
389
|
+
},
|
|
390
|
+
['bizplace', 'orderInventories']
|
|
391
|
+
)
|
|
350
392
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
393
|
+
if (!releaseGood) {
|
|
394
|
+
throw new Error('Order is already sorted')
|
|
395
|
+
}
|
|
354
396
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
397
|
+
const foundNotSealedOrderTote = await this.trxMgr
|
|
398
|
+
.getRepository(OrderTote)
|
|
399
|
+
.findOne({ where: { releaseGood, closedDate: IsNull() } })
|
|
358
400
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
itm.updater = this.user
|
|
363
|
-
})
|
|
401
|
+
if (foundNotSealedOrderTote) {
|
|
402
|
+
throw new Error('Please seal the tote(s) before proceeding')
|
|
403
|
+
}
|
|
364
404
|
|
|
365
|
-
|
|
366
|
-
|
|
405
|
+
releaseGood.status = ORDER_STATUS.READY_TO_LOAD
|
|
406
|
+
releaseGood.updater = this.user
|
|
407
|
+
await this.trxMgr.getRepository(ReleaseGood).save(releaseGood)
|
|
408
|
+
|
|
409
|
+
let inventoryItems: InventoryItem = await this.trxMgr
|
|
410
|
+
.getRepository(InventoryItem)
|
|
411
|
+
.find({ where: { outboundOrderId: releaseGood.id } })
|
|
412
|
+
|
|
413
|
+
if (inventoryItems.length > 0) {
|
|
414
|
+
inventoryItems.forEach((itm: InventoryItem) => {
|
|
415
|
+
itm.status = INVENTORY_STATUS.TERMINATED
|
|
416
|
+
itm.updater = this.user
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
await this.trxMgr.getRepository(InventoryItem).save(inventoryItems)
|
|
420
|
+
}
|
|
367
421
|
|
|
368
|
-
|
|
422
|
+
return releaseGood
|
|
423
|
+
} catch (e) {
|
|
424
|
+
throw e
|
|
425
|
+
}
|
|
369
426
|
}
|
|
370
427
|
|
|
371
428
|
async completeWorksheetSorting(taskNo: string): Promise<Worksheet> {
|
|
@@ -383,6 +440,16 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
383
440
|
]
|
|
384
441
|
})
|
|
385
442
|
|
|
443
|
+
let releaseGoodIds = worksheet.worksheetDetails.map(itm => itm.targetInventory.releaseGood.id)
|
|
444
|
+
|
|
445
|
+
const foundNotSealedOrderTote = await this.trxMgr
|
|
446
|
+
.getRepository(OrderTote)
|
|
447
|
+
.findOne({ where: { releaseGood: In(releaseGoodIds), closedDate: IsNull() } })
|
|
448
|
+
|
|
449
|
+
if (foundNotSealedOrderTote) {
|
|
450
|
+
throw new Error('Please seal the tote(s) before proceeding')
|
|
451
|
+
}
|
|
452
|
+
|
|
386
453
|
this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
|
|
387
454
|
|
|
388
455
|
const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
|
|
@@ -398,4 +465,77 @@ export class SortingWorksheetController extends VasWorksheetController {
|
|
|
398
465
|
|
|
399
466
|
return worksheet
|
|
400
467
|
}
|
|
468
|
+
|
|
469
|
+
private async toteScanning(toteNo, targetProduct, targetInventory, pickedQty, releaseGood, bizplace) {
|
|
470
|
+
//1. find tote
|
|
471
|
+
let foundTote: Tote = await this.trxMgr
|
|
472
|
+
.getRepository(Tote)
|
|
473
|
+
.findOne({ where: { bizplace, name: toteNo, deletedAt: IsNull() } })
|
|
474
|
+
|
|
475
|
+
if (foundTote?.status == TOTE_STATUS.DAMAGED) {
|
|
476
|
+
throw new Error('Tote is damaged')
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (foundTote?.status == TOTE_STATUS.DISPATCHED) {
|
|
480
|
+
throw new Error('Tote is dispatched')
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
//2. find order tote
|
|
484
|
+
let foundOrderTote: OrderTote = await this.trxMgr
|
|
485
|
+
.getRepository(OrderTote)
|
|
486
|
+
.findOne({ where: { domain: this.domain, name: toteNo, releaseGood } })
|
|
487
|
+
|
|
488
|
+
//if order tote not found the create one, if tote not found means it's tote box
|
|
489
|
+
//create order tote item
|
|
490
|
+
if (!foundOrderTote) {
|
|
491
|
+
const orderTote = await this.trxMgr.getRepository(OrderTote).save({
|
|
492
|
+
name: toteNo,
|
|
493
|
+
domain: this.domain,
|
|
494
|
+
releaseGood,
|
|
495
|
+
tote: foundTote ? foundTote : null,
|
|
496
|
+
updater: this.user
|
|
497
|
+
})
|
|
498
|
+
|
|
499
|
+
const orderToteItem = await this.trxMgr.getRepository(OrderToteItem).save({
|
|
500
|
+
domain: this.domain,
|
|
501
|
+
name: OrderNoGenerator.orderToteItem(),
|
|
502
|
+
orderProduct: targetProduct,
|
|
503
|
+
orderInventory: targetInventory,
|
|
504
|
+
orderTote,
|
|
505
|
+
qty: pickedQty,
|
|
506
|
+
updater: this.user
|
|
507
|
+
})
|
|
508
|
+
} else {
|
|
509
|
+
if (foundOrderTote.closedDate) {
|
|
510
|
+
throw new Error('Tote has been sealed, please try another tote!')
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
//if found order tote then check if order tote item exist
|
|
514
|
+
const foundOrderToteItem: OrderToteItem = await this.trxMgr.getRepository(OrderToteItem).findOne({
|
|
515
|
+
domain: this.domain,
|
|
516
|
+
orderProduct: targetProduct,
|
|
517
|
+
orderInventory: targetInventory,
|
|
518
|
+
orderTote: foundOrderTote
|
|
519
|
+
})
|
|
520
|
+
|
|
521
|
+
//if not order tote item doesnt exist then create one
|
|
522
|
+
if (!foundOrderToteItem) {
|
|
523
|
+
const orderToteItem = await this.trxMgr.getRepository(OrderToteItem).save({
|
|
524
|
+
domain: this.domain,
|
|
525
|
+
name: OrderNoGenerator.orderToteItem(),
|
|
526
|
+
orderProduct: targetProduct,
|
|
527
|
+
orderInventory: targetInventory,
|
|
528
|
+
orderTote: foundOrderTote,
|
|
529
|
+
qty: pickedQty,
|
|
530
|
+
updater: this.user
|
|
531
|
+
})
|
|
532
|
+
} else {
|
|
533
|
+
//if found order tote item found then add the quantity
|
|
534
|
+
const orderToteItem = await this.trxMgr.getRepository(OrderToteItem).save({
|
|
535
|
+
...foundOrderToteItem,
|
|
536
|
+
qty: foundOrderToteItem.qty + pickedQty
|
|
537
|
+
})
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
401
541
|
}
|
|
@@ -3,6 +3,7 @@ import { getRepository, SelectQueryBuilder } from 'typeorm'
|
|
|
3
3
|
import { ORDER_INVENTORY_STATUS } from '@things-factory/sales-base'
|
|
4
4
|
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
|
|
5
5
|
import { Worksheet, WorksheetDetail } from '../../../entities'
|
|
6
|
+
import { InventoryChange } from '@things-factory/warehouse-base'
|
|
6
7
|
|
|
7
8
|
export const batchPickingWorksheetResolver = {
|
|
8
9
|
async batchPickingWorksheet(_: any, { taskNo, locationSortingRules }, context: any) {
|
|
@@ -42,6 +43,7 @@ export const batchPickingWorksheetResolver = {
|
|
|
42
43
|
.addSelect('LOC.column', 'column')
|
|
43
44
|
.addSelect('LOC.shelf', 'shelf')
|
|
44
45
|
.addSelect('BIN_LOC.name', 'binLocationName')
|
|
46
|
+
.addSelect('WSD.status', 'status')
|
|
45
47
|
.leftJoin('WSD.targetInventory', 'T_INV')
|
|
46
48
|
.leftJoin('T_INV.inventory', 'INV')
|
|
47
49
|
.leftJoin('T_INV.product', 'PROD')
|
|
@@ -70,6 +72,7 @@ export const batchPickingWorksheetResolver = {
|
|
|
70
72
|
.addGroupBy('LOC.column')
|
|
71
73
|
.addGroupBy('LOC.row')
|
|
72
74
|
.addGroupBy('LOC.shelf')
|
|
75
|
+
.addGroupBy('WSD.status')
|
|
73
76
|
|
|
74
77
|
if (locationSortingRules?.length > 0) {
|
|
75
78
|
locationSortingRules.forEach((rule: { name: string; desc: boolean }) => {
|
|
@@ -86,6 +89,15 @@ export const batchPickingWorksheetResolver = {
|
|
|
86
89
|
partnerDomainId: worksheet.bizplace?.domain.id
|
|
87
90
|
},
|
|
88
91
|
worksheetDetailInfos: items.map(async (item: any) => {
|
|
92
|
+
const inventoryChangesCount: number = await getRepository(InventoryChange).count({
|
|
93
|
+
where: {
|
|
94
|
+
inventory: item.inventoryId,
|
|
95
|
+
status: 'PENDING',
|
|
96
|
+
transactionType: 'MISSING'
|
|
97
|
+
},
|
|
98
|
+
relations: ['inventory', 'product']
|
|
99
|
+
})
|
|
100
|
+
|
|
89
101
|
return {
|
|
90
102
|
palletId: item?.palletId,
|
|
91
103
|
cartonId: item?.cartonId,
|
|
@@ -98,6 +110,8 @@ export const batchPickingWorksheetResolver = {
|
|
|
98
110
|
},
|
|
99
111
|
qty: item?.qty,
|
|
100
112
|
releaseQty: item.releaseQty,
|
|
113
|
+
hasMissingInventoryChanges: inventoryChangesCount > 0 ? true : false,
|
|
114
|
+
status: item.status,
|
|
101
115
|
pickedQty: item.pickedQty,
|
|
102
116
|
packingType: item?.packingType,
|
|
103
117
|
packingSize: item?.packingSize,
|
|
@@ -9,7 +9,7 @@ import { WorksheetDetail } from '../../../../entities'
|
|
|
9
9
|
export const loadingResolver = {
|
|
10
10
|
async loading(_: any, { loadedWorksheetDetails, releaseGoodNo, orderInfo }, context: any) {
|
|
11
11
|
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
12
|
-
await loading(tx, domain, user, loadedWorksheetDetails, releaseGoodNo)
|
|
12
|
+
const worksheetDetails = await loading(tx, domain, user, loadedWorksheetDetails, releaseGoodNo)
|
|
13
13
|
const worksheetController: WorksheetController = new WorksheetController(tx, domain, user)
|
|
14
14
|
const releaseGood: ReleaseGood = await worksheetController.findRefOrder(
|
|
15
15
|
ReleaseGood,
|
|
@@ -18,14 +18,7 @@ export const loadingResolver = {
|
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
const loadingWorksheetController: LoadingWorksheetController = new LoadingWorksheetController(tx, domain, user)
|
|
21
|
-
let targetInventories: OrderInventory[] =
|
|
22
|
-
for (let worksheetDetail of loadedWorksheetDetails) {
|
|
23
|
-
worksheetDetail = await loadingWorksheetController.findWorksheetDetailByName(worksheetDetail.name, [
|
|
24
|
-
'targetInventory'
|
|
25
|
-
])
|
|
26
|
-
const targetInventory = worksheetDetail.targetInventory
|
|
27
|
-
targetInventories.push(targetInventory)
|
|
28
|
-
}
|
|
21
|
+
let targetInventories: OrderInventory[] = worksheetDetails.map(itm => itm.targetInventory)
|
|
29
22
|
|
|
30
23
|
const bizplace: Bizplace = releaseGood.bizplace
|
|
31
24
|
orderInfo = {
|
|
@@ -41,9 +34,9 @@ export async function loading(
|
|
|
41
34
|
tx: EntityManager,
|
|
42
35
|
domain: Domain,
|
|
43
36
|
user: User,
|
|
44
|
-
worksheetDetails: Partial<WorksheetDetail & { loadedQty: number }>[],
|
|
37
|
+
worksheetDetails: Partial<WorksheetDetail & { loadedQty: number } & { toteName: string }>[],
|
|
45
38
|
releaseGoodNo: string
|
|
46
|
-
): Promise<
|
|
39
|
+
): Promise<any> {
|
|
47
40
|
const worksheetController: LoadingWorksheetController = new LoadingWorksheetController(tx, domain, user)
|
|
48
|
-
await worksheetController.loading(releaseGoodNo, worksheetDetails)
|
|
41
|
+
return await worksheetController.loading(releaseGoodNo, worksheetDetails)
|
|
49
42
|
}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Equal, getRepository, In, Not, SelectQueryBuilder } from 'typeorm'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ORDER_STATUS,
|
|
5
|
+
ORDER_INVENTORY_STATUS,
|
|
6
|
+
OrderInventory,
|
|
7
|
+
ReleaseGood,
|
|
8
|
+
OrderTote,
|
|
9
|
+
OrderToteItem
|
|
10
|
+
} from '@things-factory/sales-base'
|
|
4
11
|
import { Domain } from '@things-factory/shell'
|
|
5
12
|
import { Inventory, Location } from '@things-factory/warehouse-base'
|
|
6
13
|
|
|
@@ -27,7 +34,9 @@ export const loadingWorksheetResolver = {
|
|
|
27
34
|
.innerJoinAndSelect('releaseGood.bizplace', 'bizplace')
|
|
28
35
|
.innerJoinAndSelect('bizplace.domain', 'domain')
|
|
29
36
|
.where('orderInventory.domain_id = :domainId', { domainId: domain.id })
|
|
30
|
-
.andWhere('orderInventory.status IN (:...orderInventoryStatus)', {
|
|
37
|
+
.andWhere('orderInventory.status IN (:...orderInventoryStatus)', {
|
|
38
|
+
orderInventoryStatus: [ORDER_INVENTORY_STATUS.LOADING, ORDER_INVENTORY_STATUS.LOADED]
|
|
39
|
+
})
|
|
31
40
|
.andWhere('orderInventory.bin_location_id = :locationId', { locationId: binLocation.id })
|
|
32
41
|
.andWhere('releaseGood.status = :status', { status: ORDER_STATUS.LOADING })
|
|
33
42
|
|
|
@@ -41,6 +50,10 @@ export const loadingWorksheetResolver = {
|
|
|
41
50
|
|
|
42
51
|
if (!releaseGood) throw new Error(`Release good doesn't exists.`)
|
|
43
52
|
|
|
53
|
+
let [orderTotes, orderTotesTotal]: OrderTote = await getRepository(OrderTote).findAndCount({
|
|
54
|
+
where: { releaseGood: releaseGood.id }
|
|
55
|
+
})
|
|
56
|
+
|
|
44
57
|
const foundWorksheet: Worksheet = await fetchExecutingWorksheet(
|
|
45
58
|
domain,
|
|
46
59
|
releaseGood.bizplace,
|
|
@@ -48,7 +61,7 @@ export const loadingWorksheetResolver = {
|
|
|
48
61
|
WORKSHEET_TYPE.LOADING,
|
|
49
62
|
releaseGood
|
|
50
63
|
)
|
|
51
|
-
|
|
64
|
+
let foundWSD: any[] = await getRepository(WorksheetDetail).find({
|
|
52
65
|
where: {
|
|
53
66
|
domain,
|
|
54
67
|
worksheet: foundWorksheet,
|
|
@@ -57,21 +70,50 @@ export const loadingWorksheetResolver = {
|
|
|
57
70
|
},
|
|
58
71
|
relations: [
|
|
59
72
|
'targetInventory',
|
|
73
|
+
'targetInventory.orderProduct',
|
|
60
74
|
'targetInventory.inventory',
|
|
61
75
|
'targetInventory.inventory.location',
|
|
62
76
|
'targetInventory.inventory.product'
|
|
63
77
|
]
|
|
64
78
|
})
|
|
65
79
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
if (orderTotesTotal > 0) {
|
|
81
|
+
let [toteItems, toteItemsTotal]: OrderToteItem = await getRepository(OrderToteItem).findAndCount({
|
|
82
|
+
where: { orderTote: In(orderTotes.map(itm => itm.id)) },
|
|
83
|
+
relations: ['orderTote', 'orderInventory']
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
let toteWsd = []
|
|
87
|
+
|
|
88
|
+
for (let i = 0; i < toteItemsTotal; i++) {
|
|
89
|
+
let wsdIndex = foundWSD.findIndex(
|
|
90
|
+
itm => !itm?.toteName && itm.targetInventory.id == toteItems[i].orderInventory.id
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
if (wsdIndex >= 0) {
|
|
94
|
+
let filterWSD: any = JSON.parse(JSON.stringify(foundWSD[wsdIndex]))
|
|
95
|
+
let uomValue =
|
|
96
|
+
Math.round((filterWSD.targetInventory.releaseUomValue / filterWSD.targetInventory.releaseQty) * 100) / 100
|
|
97
|
+
|
|
98
|
+
foundWSD[wsdIndex].targetInventory.releaseQty -= toteItems[i].qty
|
|
99
|
+
foundWSD[wsdIndex].targetInventory.pickedQty -= toteItems[i].qty
|
|
100
|
+
foundWSD[wsdIndex].targetInventory.releaseUomValue = foundWSD[wsdIndex].targetInventory.releaseQty * uomValue
|
|
101
|
+
|
|
102
|
+
filterWSD.targetInventory.releaseQty = toteItems[i].qty
|
|
103
|
+
filterWSD.targetInventory.pickedQty = toteItems[i].qty
|
|
104
|
+
filterWSD.targetInventory.releaseUomValue = toteItems[i].qty * uomValue
|
|
105
|
+
filterWSD.toteName = toteItems[i].orderTote.name
|
|
106
|
+
toteWsd.push(filterWSD)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
foundWSD = foundWSD.concat(toteWsd)
|
|
111
|
+
foundWSD.sort((a, b) => (a.toteName > b.toteName ? 1 : -1))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let worksheetDetailInfos = foundWSD
|
|
115
|
+
.filter(itm => itm.targetInventory.releaseQty > 0)
|
|
116
|
+
.map((loadingWSD: any) => {
|
|
75
117
|
const targetInventory: OrderInventory = loadingWSD.targetInventory
|
|
76
118
|
const inventory: Inventory = targetInventory.inventory
|
|
77
119
|
return {
|
|
@@ -87,9 +129,20 @@ export const loadingWorksheetResolver = {
|
|
|
87
129
|
targetName: targetInventory.name,
|
|
88
130
|
packingType: inventory.packingType,
|
|
89
131
|
packingSize: inventory.packingSize,
|
|
90
|
-
inventory: targetInventory.inventory
|
|
132
|
+
inventory: targetInventory.inventory,
|
|
133
|
+
toteName: loadingWSD.toteName
|
|
91
134
|
}
|
|
92
135
|
})
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
worksheetInfo: {
|
|
139
|
+
releaseGood,
|
|
140
|
+
bizplaceName: releaseGood.bizplace.name,
|
|
141
|
+
startedAt: foundWorksheet.startedAt,
|
|
142
|
+
refNo: releaseGood.refNo,
|
|
143
|
+
ownCollection: releaseGood.ownTransport
|
|
144
|
+
},
|
|
145
|
+
worksheetDetailInfos
|
|
93
146
|
}
|
|
94
147
|
}
|
|
95
148
|
}
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
import { ORDER_INVENTORY_STATUS, ORDER_STATUS, OrderInventory, ReleaseGood } from '@things-factory/sales-base'
|
|
12
12
|
import { Domain } from '@things-factory/shell'
|
|
13
13
|
import { Inventory, Location } from '@things-factory/warehouse-base'
|
|
14
|
-
import { ProductDetail } from '@things-factory/product-base'
|
|
15
14
|
|
|
16
15
|
import { WORKSHEET_TYPE } from '../../../constants'
|
|
17
16
|
import { SellercraftController } from '../../../controllers'
|
|
@@ -167,6 +166,7 @@ export const packingWorksheetResolver = {
|
|
|
167
166
|
shippingProvider: shippingProvider ? shippingProvider : '',
|
|
168
167
|
trackingNo: trackingNo ? trackingNo : '',
|
|
169
168
|
airwayBill: releaseGood?.airwayBill,
|
|
169
|
+
checkedRemarkBy: releaseGood?.checkedRemarkBy,
|
|
170
170
|
invoice: releaseGood?.invoice,
|
|
171
171
|
platform: marketplaceOrder ? marketplaceOrder.marketplaceStore.platform : 'operato',
|
|
172
172
|
marketplaceStoreId: marketplaceOrder ? marketplaceOrder.marketplaceStore.id : '',
|
|
@@ -42,7 +42,7 @@ export async function completeBatchPicking(
|
|
|
42
42
|
const worksheet = await pickingWSCtrl.completeBatchPicking(taskNo)
|
|
43
43
|
|
|
44
44
|
const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
|
|
45
|
-
const targetInventories: OrderInventory[] = worksheetDetails.map((wsd: WorksheetDetail) => wsd.targetInventory)
|
|
45
|
+
const targetInventories: OrderInventory[] = worksheetDetails.filter(wsd=>wsd.status != 'MISSING').map((wsd: WorksheetDetail) => wsd.targetInventory)
|
|
46
46
|
|
|
47
47
|
const sellercraft: Sellercraft = await tx
|
|
48
48
|
.getRepository(Sellercraft)
|
|
@@ -248,18 +248,20 @@ export async function completePicking(
|
|
|
248
248
|
})
|
|
249
249
|
|
|
250
250
|
if (!existLoadingWorksheet && !releaseGood.courierOption && !releaseGood.packingOption) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
251
|
+
if(pickedTargetInventories.length>0){
|
|
252
|
+
const loadingWSCtrl: LoadingWorksheetController = new LoadingWorksheetController(tx, domain, user)
|
|
253
|
+
let loadingWorksheet: Worksheet = await loadingWSCtrl.generateLoadingWorksheet(
|
|
254
|
+
releaseGoodNo,
|
|
255
|
+
pickedTargetInventories
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
if (!loadingWorksheet.worksheetDetails?.length) {
|
|
259
|
+
loadingWorksheet = await pickingWSCtrl.findWorksheetById(loadingWorksheet.id)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const loadingWorksheetDetails: WorksheetDetail[] = loadingWorksheet.worksheetDetails
|
|
263
|
+
await loadingWSCtrl.activateLoading(loadingWorksheet.name, loadingWorksheetDetails)
|
|
259
264
|
}
|
|
260
|
-
|
|
261
|
-
const loadingWorksheetDetails: WorksheetDetail[] = loadingWorksheet.worksheetDetails
|
|
262
|
-
await loadingWSCtrl.activateLoading(loadingWorksheet.name, loadingWorksheetDetails)
|
|
263
265
|
} else {
|
|
264
266
|
const loadingWSCtrl: LoadingWorksheetController = new LoadingWorksheetController(tx, domain, user)
|
|
265
267
|
let loadingWorksheet: Worksheet = await loadingWSCtrl.updateLoadingWorksheet(
|
|
@@ -11,6 +11,7 @@ import { scanProductPickingResolver } from './scan-product-picking'
|
|
|
11
11
|
import { scanProductBatchPickingResolver } from './scan-product-batch-picking'
|
|
12
12
|
import { undoPickingAssigmentResolver } from './undo-picking-assignment'
|
|
13
13
|
import { undoSerialNumberPickingResolver } from './undo-serial-number-picking'
|
|
14
|
+
import { sealToteResolver } from './seal-tote'
|
|
14
15
|
|
|
15
16
|
export const Mutations = {
|
|
16
17
|
...assignPickingInventoriesResolver,
|
|
@@ -25,5 +26,6 @@ export const Mutations = {
|
|
|
25
26
|
...completeBatchPickingResolver,
|
|
26
27
|
...assignPickingWorkerResolver,
|
|
27
28
|
...fetchAndAssignPickingTaskResolver,
|
|
28
|
-
...undoSerialNumberPickingResolver
|
|
29
|
+
...undoSerialNumberPickingResolver,
|
|
30
|
+
...sealToteResolver
|
|
29
31
|
}
|
|
@@ -4,9 +4,25 @@ import { EntityManager } from 'typeorm'
|
|
|
4
4
|
import { PickingWorksheetController } from '../../../../controllers'
|
|
5
5
|
|
|
6
6
|
export const pickingResolver = {
|
|
7
|
-
async picking(
|
|
7
|
+
async picking(
|
|
8
|
+
_: any,
|
|
9
|
+
{ worksheetDetailName, worksheetType, palletId, locationName, releaseQty, binLocation, serialNumber, toteNo },
|
|
10
|
+
context: any
|
|
11
|
+
) {
|
|
8
12
|
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
9
|
-
await picking(
|
|
13
|
+
await picking(
|
|
14
|
+
tx,
|
|
15
|
+
domain,
|
|
16
|
+
user,
|
|
17
|
+
worksheetDetailName,
|
|
18
|
+
worksheetType,
|
|
19
|
+
palletId,
|
|
20
|
+
locationName,
|
|
21
|
+
releaseQty,
|
|
22
|
+
binLocation,
|
|
23
|
+
serialNumber,
|
|
24
|
+
toteNo
|
|
25
|
+
)
|
|
10
26
|
}
|
|
11
27
|
}
|
|
12
28
|
|
|
@@ -20,8 +36,18 @@ export async function picking(
|
|
|
20
36
|
locationName: string,
|
|
21
37
|
releaseQty: number,
|
|
22
38
|
binLocation?: string,
|
|
23
|
-
serialNumber?: string
|
|
39
|
+
serialNumber?: string,
|
|
40
|
+
toteNo?: string
|
|
24
41
|
) {
|
|
25
42
|
const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
|
|
26
|
-
await worksheetController.picking(
|
|
43
|
+
await worksheetController.picking(
|
|
44
|
+
worksheetDetailName,
|
|
45
|
+
worksheetType,
|
|
46
|
+
palletId,
|
|
47
|
+
locationName,
|
|
48
|
+
releaseQty,
|
|
49
|
+
binLocation,
|
|
50
|
+
serialNumber,
|
|
51
|
+
toteNo
|
|
52
|
+
)
|
|
27
53
|
}
|
|
@@ -6,7 +6,7 @@ import { PickingWorksheetController } from '../../../../controllers'
|
|
|
6
6
|
export const scanProductPickingResolver = {
|
|
7
7
|
async scanProductPicking(
|
|
8
8
|
_: any,
|
|
9
|
-
{ worksheetDetailName, worksheetType, productBarcode, cartonId, binLocation, serialNumber },
|
|
9
|
+
{ worksheetDetailName, worksheetType, productBarcode, cartonId, binLocation, serialNumber, toteNo },
|
|
10
10
|
context: any
|
|
11
11
|
) {
|
|
12
12
|
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
@@ -19,7 +19,8 @@ export const scanProductPickingResolver = {
|
|
|
19
19
|
productBarcode,
|
|
20
20
|
cartonId,
|
|
21
21
|
binLocation,
|
|
22
|
-
serialNumber
|
|
22
|
+
serialNumber,
|
|
23
|
+
toteNo
|
|
23
24
|
)
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -33,7 +34,8 @@ export async function scanProductPicking(
|
|
|
33
34
|
productBarcode: string,
|
|
34
35
|
cartonId: string,
|
|
35
36
|
binLocation?: string,
|
|
36
|
-
serialNumber?: string
|
|
37
|
+
serialNumber?: string,
|
|
38
|
+
toteNo?: string
|
|
37
39
|
) {
|
|
38
40
|
const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
|
|
39
41
|
await worksheetController.scanProductPicking(
|
|
@@ -42,6 +44,7 @@ export async function scanProductPicking(
|
|
|
42
44
|
productBarcode,
|
|
43
45
|
cartonId,
|
|
44
46
|
binLocation,
|
|
45
|
-
serialNumber
|
|
47
|
+
serialNumber,
|
|
48
|
+
toteNo
|
|
46
49
|
)
|
|
47
50
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
import { User } from '@things-factory/auth-base'
|
|
4
|
+
import { Domain } from '@things-factory/shell'
|
|
5
|
+
|
|
6
|
+
import { PickingWorksheetController } from '../../../../controllers'
|
|
7
|
+
|
|
8
|
+
export const sealToteResolver = {
|
|
9
|
+
async sealTote(_: any, { sealNo, toteNo, orderNo }, context: any) {
|
|
10
|
+
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
11
|
+
await sealTote(tx, domain, user, sealNo, toteNo, orderNo)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function sealTote(
|
|
16
|
+
tx: EntityManager,
|
|
17
|
+
domain: Domain,
|
|
18
|
+
user: User,
|
|
19
|
+
sealNo: string,
|
|
20
|
+
toteNo: string,
|
|
21
|
+
orderNo: string
|
|
22
|
+
): Promise<void> {
|
|
23
|
+
const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
|
|
24
|
+
await worksheetController.sealTote(sealNo, toteNo, orderNo)
|
|
25
|
+
}
|