@things-factory/worksheet-base 4.3.59 → 4.3.62
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/picking-worksheet-controller.js +86 -88
- package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/outbound/returning-worksheet-controller.js +16 -0
- package/dist-server/controllers/outbound/returning-worksheet-controller.js.map +1 -1
- package/dist-server/entities/worksheet-detail.js +2 -1
- package/dist-server/entities/worksheet-detail.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js +1 -34
- package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.js +70 -0
- package/dist-server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.js.map +1 -0
- package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-batch-picking-worksheet.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-batch-picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/index.js +2 -1
- package/dist-server/graphql/resolvers/worksheet/index.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +18 -8
- package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.js +6 -2
- package/dist-server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/scan-product-batch-picking.js +4 -4
- package/dist-server/graphql/resolvers/worksheet/picking/scan-product-batch-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-worksheet.js +1 -0
- package/dist-server/graphql/resolvers/worksheet/picking-worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/worksheet.js +11 -3
- package/dist-server/graphql/resolvers/worksheet/worksheet.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet-detail/index.js +2 -1
- package/dist-server/graphql/resolvers/worksheet-detail/index.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js +81 -0
- package/dist-server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.js.map +1 -0
- package/dist-server/graphql/types/worksheet/batch-pick-worksheet-info.js +12 -0
- package/dist-server/graphql/types/worksheet/batch-pick-worksheet-info.js.map +1 -0
- package/dist-server/graphql/types/worksheet/index.js +9 -4
- package/dist-server/graphql/types/worksheet/index.js.map +1 -1
- package/dist-server/graphql/types/worksheet-detail/index.js +10 -0
- package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
- package/package.json +12 -12
- package/server/controllers/outbound/picking-worksheet-controller.ts +111 -109
- package/server/controllers/outbound/returning-worksheet-controller.ts +23 -0
- package/server/entities/worksheet-detail.ts +4 -0
- package/server/graphql/resolvers/worksheet/find-release-orders-by-task-no.ts +2 -42
- package/server/graphql/resolvers/worksheet/find-sorting-release-orders-by-task-no.ts +80 -0
- package/server/graphql/resolvers/worksheet/generate-worksheet/generate-batch-picking-worksheet.ts +7 -8
- package/server/graphql/resolvers/worksheet/index.ts +2 -0
- package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +32 -11
- package/server/graphql/resolvers/worksheet/picking/fetch-and-assign-picking-task.ts +4 -0
- package/server/graphql/resolvers/worksheet/picking/scan-product-batch-picking.ts +7 -4
- package/server/graphql/resolvers/worksheet/picking/scan-product-picking.ts +7 -4
- package/server/graphql/resolvers/worksheet/picking-worksheet.ts +5 -4
- package/server/graphql/resolvers/worksheet/worksheet.ts +16 -3
- package/server/graphql/resolvers/worksheet-detail/index.ts +3 -1
- package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts +164 -0
- package/server/graphql/types/worksheet/batch-pick-worksheet-info.ts +9 -0
- package/server/graphql/types/worksheet/index.ts +10 -5
- package/server/graphql/types/worksheet-detail/index.ts +10 -0
|
@@ -1,54 +1,17 @@
|
|
|
1
1
|
import { EntityManager, SelectQueryBuilder } from 'typeorm'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
ORDER_STATUS, ORDER_INVENTORY_STATUS,
|
|
5
|
-
OrderInventory as OrderInventoryEntity,
|
|
6
|
-
ReleaseGood as ReleaseGoodEntity
|
|
7
|
-
} from '@things-factory/sales-base'
|
|
3
|
+
import { OrderInventory as OrderInventoryEntity, ReleaseGood as ReleaseGoodEntity } from '@things-factory/sales-base'
|
|
8
4
|
import { Domain } from '@things-factory/shell'
|
|
9
|
-
import { Location } from '@things-factory/warehouse-base'
|
|
10
5
|
|
|
11
|
-
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
|
|
12
6
|
import { Worksheet as WorksheetEntity, WorksheetDetail as WorksheetDetailEntity } from '../../../entities'
|
|
13
7
|
|
|
14
8
|
export const findReleaseOrdersByTaskNoResolver = {
|
|
15
9
|
async findReleaseOrdersByTaskNo(_: any, { taskNo }, context: any) {
|
|
16
10
|
const { domain, tx }: { domain: Domain; tx: EntityManager } = context.state
|
|
17
11
|
let task = await tx.getRepository(WorksheetEntity).findOne({
|
|
18
|
-
where: { taskNo
|
|
12
|
+
where: { taskNo }
|
|
19
13
|
})
|
|
20
14
|
|
|
21
|
-
// Find Task based on Bin
|
|
22
|
-
if (!task) {
|
|
23
|
-
const binLocation: Location = await tx.getRepository(Location).findOne({
|
|
24
|
-
where: { domain, name: taskNo }
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const qb: SelectQueryBuilder<OrderInventoryEntity> = tx.getRepository(OrderInventoryEntity).createQueryBuilder('orderInventory')
|
|
28
|
-
|
|
29
|
-
qb.innerJoinAndSelect('orderInventory.releaseGood', 'releaseGood')
|
|
30
|
-
.innerJoinAndSelect('worksheets', 'ws', `orderInventory.ref_worksheet_id = ws.id AND ws.type = 'BATCH_PICKING'`)
|
|
31
|
-
.innerJoinAndSelect('worksheets', 'ws2', `ws2.task_no = ws.task_no AND ws2.type = 'SORTING'`)
|
|
32
|
-
.innerJoinAndSelect('releaseGood.bizplace', 'bizplace')
|
|
33
|
-
.innerJoinAndSelect('bizplace.domain', 'domain')
|
|
34
|
-
.where('orderInventory.domain_id = :domainId', { domainId: domain.id })
|
|
35
|
-
.andWhere('orderInventory.status IN (:...orderInventoryStatus)', {
|
|
36
|
-
orderInventoryStatus: [ORDER_INVENTORY_STATUS.SORTING]
|
|
37
|
-
})
|
|
38
|
-
.andWhere('orderInventory.bin_location_id = :locationId', { locationId: binLocation.id })
|
|
39
|
-
.andWhere('releaseGood.status = :status', { status: ORDER_STATUS.SORTING })
|
|
40
|
-
|
|
41
|
-
const orderInventoryByBin = await qb.getRawOne()
|
|
42
|
-
if (orderInventoryByBin?.releaseGood_id) {
|
|
43
|
-
taskNo = orderInventoryByBin.ws_task_no
|
|
44
|
-
task = await tx.getRepository(WorksheetEntity).findOne({
|
|
45
|
-
where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
|
|
46
|
-
})
|
|
47
|
-
} else {
|
|
48
|
-
throw new Error(`Bin do not have any batch picking order.`)
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
15
|
if (!task) throw new Error('Unable to find task no.')
|
|
53
16
|
|
|
54
17
|
const qb: SelectQueryBuilder<WorksheetEntity> = tx
|
|
@@ -63,9 +26,6 @@ export const findReleaseOrdersByTaskNoResolver = {
|
|
|
63
26
|
.innerJoin(ReleaseGoodEntity, 'rg', 'rg.id = oi.release_good_id')
|
|
64
27
|
.where('domain.id = :domainId', { domainId: domain.id })
|
|
65
28
|
.andWhere('ws.taskNo = :taskNo', { taskNo: taskNo })
|
|
66
|
-
.andWhere('ws.type = :worksheetType', { worksheetType: WORKSHEET_TYPE.SORTING })
|
|
67
|
-
.andWhere('ws.status = :worksheetStatus', { worksheetStatus: WORKSHEET_STATUS.EXECUTING })
|
|
68
|
-
.andWhere('rg.status = :roStatus', { roStatus: ORDER_STATUS.SORTING })
|
|
69
29
|
.groupBy('rg.id')
|
|
70
30
|
.addGroupBy('rg.name')
|
|
71
31
|
.addGroupBy('rg.status')
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { EntityManager, SelectQueryBuilder } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ORDER_INVENTORY_STATUS,
|
|
5
|
+
ORDER_STATUS,
|
|
6
|
+
OrderInventory as OrderInventoryEntity,
|
|
7
|
+
ReleaseGood as ReleaseGoodEntity
|
|
8
|
+
} from '@things-factory/sales-base'
|
|
9
|
+
import { Domain } from '@things-factory/shell'
|
|
10
|
+
import { Location } from '@things-factory/warehouse-base'
|
|
11
|
+
|
|
12
|
+
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
|
|
13
|
+
import { Worksheet as WorksheetEntity, WorksheetDetail as WorksheetDetailEntity } from '../../../entities'
|
|
14
|
+
|
|
15
|
+
export const findSortingReleaseOrdersByTaskNoResolver = {
|
|
16
|
+
async findSortingReleaseOrdersByTaskNo(_: any, { taskNo }, context: any) {
|
|
17
|
+
const { domain, tx }: { domain: Domain; tx: EntityManager } = context.state
|
|
18
|
+
let task = await tx.getRepository(WorksheetEntity).findOne({
|
|
19
|
+
where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
// Find Task based on Bin
|
|
23
|
+
if (!task) {
|
|
24
|
+
const binLocation: Location = await tx.getRepository(Location).findOne({
|
|
25
|
+
where: { domain, name: taskNo }
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const qb: SelectQueryBuilder<OrderInventoryEntity> = tx
|
|
29
|
+
.getRepository(OrderInventoryEntity)
|
|
30
|
+
.createQueryBuilder('orderInventory')
|
|
31
|
+
|
|
32
|
+
qb.innerJoinAndSelect('orderInventory.releaseGood', 'releaseGood')
|
|
33
|
+
.innerJoinAndSelect('worksheets', 'ws', `orderInventory.ref_worksheet_id = ws.id AND ws.type = 'BATCH_PICKING'`)
|
|
34
|
+
.innerJoinAndSelect('worksheets', 'ws2', `ws2.task_no = ws.task_no AND ws2.type = 'SORTING'`)
|
|
35
|
+
.innerJoinAndSelect('releaseGood.bizplace', 'bizplace')
|
|
36
|
+
.innerJoinAndSelect('bizplace.domain', 'domain')
|
|
37
|
+
.where('orderInventory.domain_id = :domainId', { domainId: domain.id })
|
|
38
|
+
.andWhere('orderInventory.status IN (:...orderInventoryStatus)', {
|
|
39
|
+
orderInventoryStatus: [ORDER_INVENTORY_STATUS.SORTING]
|
|
40
|
+
})
|
|
41
|
+
.andWhere('orderInventory.bin_location_id = :locationId', { locationId: binLocation.id })
|
|
42
|
+
.andWhere('releaseGood.status = :status', { status: ORDER_STATUS.SORTING })
|
|
43
|
+
|
|
44
|
+
const orderInventoryByBin = await qb.getRawOne()
|
|
45
|
+
if (orderInventoryByBin?.releaseGood_id) {
|
|
46
|
+
taskNo = orderInventoryByBin.ws_task_no
|
|
47
|
+
task = await tx.getRepository(WorksheetEntity).findOne({
|
|
48
|
+
where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
|
|
49
|
+
})
|
|
50
|
+
} else {
|
|
51
|
+
throw new Error(`Bin do not have any batch picking order.`)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!task) throw new Error('Unable to find task no.')
|
|
56
|
+
|
|
57
|
+
const qb: SelectQueryBuilder<WorksheetEntity> = tx
|
|
58
|
+
.getRepository(WorksheetEntity)
|
|
59
|
+
.createQueryBuilder('ws')
|
|
60
|
+
.select('rg.id as id')
|
|
61
|
+
.addSelect('rg.name as name')
|
|
62
|
+
.addSelect('rg.status as status')
|
|
63
|
+
.innerJoin(Domain, 'domain', 'ws.domain_id = domain.id')
|
|
64
|
+
.innerJoin(WorksheetDetailEntity, 'wsd', 'ws.id = wsd.worksheet_id')
|
|
65
|
+
.innerJoin(OrderInventoryEntity, 'oi', 'oi.id = wsd.target_inventory_id')
|
|
66
|
+
.innerJoin(ReleaseGoodEntity, 'rg', 'rg.id = oi.release_good_id')
|
|
67
|
+
.where('domain.id = :domainId', { domainId: domain.id })
|
|
68
|
+
.andWhere('ws.taskNo = :taskNo', { taskNo: taskNo })
|
|
69
|
+
.andWhere('ws.type = :worksheetType', { worksheetType: WORKSHEET_TYPE.SORTING })
|
|
70
|
+
.andWhere('ws.status = :worksheetStatus', { worksheetStatus: WORKSHEET_STATUS.EXECUTING })
|
|
71
|
+
.andWhere('rg.status = :roStatus', { roStatus: ORDER_STATUS.SORTING })
|
|
72
|
+
.groupBy('rg.id')
|
|
73
|
+
.addGroupBy('rg.name')
|
|
74
|
+
.addGroupBy('rg.status')
|
|
75
|
+
.orderBy('rg.createdAt', 'ASC')
|
|
76
|
+
|
|
77
|
+
const releaseGoods: ReleaseGoodEntity[] = await qb.getRawMany()
|
|
78
|
+
return { releaseGoods, taskNo }
|
|
79
|
+
}
|
|
80
|
+
}
|
package/server/graphql/resolvers/worksheet/generate-worksheet/generate-batch-picking-worksheet.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { User } from '@things-factory/auth-base'
|
|
2
|
-
import { OrderInventory } from '@things-factory/sales-base'
|
|
3
|
-
import { Domain } from '@things-factory/shell'
|
|
2
|
+
import { OrderInventory, GenerateBatchPickInfo } from '@things-factory/sales-base'
|
|
3
|
+
import { Domain, ObjectRef } from '@things-factory/shell'
|
|
4
4
|
import { EntityManager } from 'typeorm'
|
|
5
5
|
import { PickingWorksheetController } from '../../../../controllers/'
|
|
6
6
|
import { Worksheet, WorksheetDetail } from '../../../../entities'
|
|
7
7
|
|
|
8
8
|
export const generateBatchPickingWorksheetResolver = {
|
|
9
|
-
async generateBatchPickingWorksheet(_: any, {
|
|
9
|
+
async generateBatchPickingWorksheet(_: any, { releaseGoodWithBiz }, context: any) {
|
|
10
10
|
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
11
|
-
return await generateBatchPickingWorksheet(tx, domain, user,
|
|
11
|
+
return await generateBatchPickingWorksheet(tx, domain, user, releaseGoodWithBiz)
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -16,9 +16,8 @@ export async function generateBatchPickingWorksheet(
|
|
|
16
16
|
tx: EntityManager,
|
|
17
17
|
domain: Domain,
|
|
18
18
|
user: User,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
): Promise<Worksheet> {
|
|
19
|
+
releaseGoodWithBiz: [[GenerateBatchPickInfo]]
|
|
20
|
+
): Promise<Worksheet[]> {
|
|
22
21
|
const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
|
|
23
|
-
return await worksheetController.generateBatchPickingWorksheet(
|
|
22
|
+
return await worksheetController.generateBatchPickingWorksheet(releaseGoodWithBiz)
|
|
24
23
|
}
|
|
@@ -11,6 +11,7 @@ import { deliveryOrderByWorksheetResolver } from './delivery-order-by-worksheet'
|
|
|
11
11
|
import { fetchDeliveryOrderROResolver } from './fetch-delivery-order-ro'
|
|
12
12
|
import { fetchSellercraftAirwayBillResolver } from './fetch-sellercraft-airway-bill'
|
|
13
13
|
import { findReleaseOrdersByTaskNoResolver } from './find-release-orders-by-task-no'
|
|
14
|
+
import { findSortingReleaseOrdersByTaskNoResolver } from './find-sorting-release-orders-by-task-no'
|
|
14
15
|
import { Mutations as GenerateWorksheetMutations } from './generate-worksheet'
|
|
15
16
|
import { havingVasResolver } from './having-vas'
|
|
16
17
|
import { Mutations as InspectMutations } from './inspecting'
|
|
@@ -99,6 +100,7 @@ export const Query = {
|
|
|
99
100
|
...myPickingAssignmentStatusResolver,
|
|
100
101
|
...recommendPutawayLocationResolver,
|
|
101
102
|
...sortingWorksheetResolver,
|
|
103
|
+
...findSortingReleaseOrdersByTaskNoResolver,
|
|
102
104
|
...findReleaseOrdersByTaskNoResolver,
|
|
103
105
|
...fetchDeliveryOrderROResolver
|
|
104
106
|
}
|
|
@@ -11,8 +11,11 @@ export const inventoriesByPalletResolver = {
|
|
|
11
11
|
const { domain, user }: { domain: Domain; user: User } = context.state
|
|
12
12
|
const params = { filters, pagination }
|
|
13
13
|
let permittedBizplaceIds: string[] = await getPermittedBizplaceIds(domain, user)
|
|
14
|
-
|
|
15
14
|
const productFilters = params.filters.filter(x => x.name == 'productName')
|
|
15
|
+
const recallFilters = params.filters.find(x => x.name === 'recall')
|
|
16
|
+
const skipLockCheckFilters = params.filters.find(x => x.name === 'skipLockCheck')
|
|
17
|
+
let skipLockCheck: Boolean =
|
|
18
|
+
skipLockCheckFilters && skipLockCheckFilters?.value ? skipLockCheckFilters?.value : false
|
|
16
19
|
const productFilterColumns = ['sku', 'brandSku', 'name', 'description', 'brand', 'subBrand']
|
|
17
20
|
params.filters = params.filters.filter(x => x.name != 'productName')
|
|
18
21
|
|
|
@@ -28,6 +31,12 @@ export const inventoriesByPalletResolver = {
|
|
|
28
31
|
params.filters.find(filter => filter.name === 'bizplace').relation = true
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
const locationFilters = params.filters.find(x => x.name == 'location')
|
|
35
|
+
|
|
36
|
+
const removeLocationIndex = params.filters.findIndex(x => x.name == 'location')
|
|
37
|
+
|
|
38
|
+
params.filters.splice(removeLocationIndex, 1)
|
|
39
|
+
|
|
31
40
|
const qb: SelectQueryBuilder<Inventory> = getRepository(Inventory).createQueryBuilder('iv')
|
|
32
41
|
buildQuery(qb, params, context)
|
|
33
42
|
|
|
@@ -39,9 +48,11 @@ export const inventoriesByPalletResolver = {
|
|
|
39
48
|
.leftJoinAndSelect('iv.creator', 'creator')
|
|
40
49
|
.leftJoinAndSelect('iv.updater', 'updater')
|
|
41
50
|
.andWhere('iv.qty > 0')
|
|
42
|
-
.andWhere(
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
.andWhere(
|
|
52
|
+
`location.type ${recallFilters?.value === true ? '' : 'NOT'} IN ('${LOCATION_TYPE.QUARANTINE}', '${
|
|
53
|
+
LOCATION_TYPE.RESERVE
|
|
54
|
+
}')`
|
|
55
|
+
)
|
|
45
56
|
.andWhere(
|
|
46
57
|
`(iv.batch_id, product.name, iv.packing_type, product.brand) NOT IN (
|
|
47
58
|
SELECT
|
|
@@ -60,14 +71,24 @@ export const inventoriesByPalletResolver = {
|
|
|
60
71
|
{ permittedBizplaceIds, domainId: domain.id }
|
|
61
72
|
)
|
|
62
73
|
|
|
74
|
+
if (!skipLockCheck) {
|
|
75
|
+
qb.andWhere('CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END >= 0')
|
|
76
|
+
qb.andWhere('iv.qty - CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END > 0')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (locationFilters) {
|
|
80
|
+
qb.andWhere(`location.name ilike '${locationFilters.value}'`)
|
|
81
|
+
}
|
|
82
|
+
|
|
63
83
|
if (sortings?.length !== 0) {
|
|
64
|
-
const arrChildSortData = ['
|
|
84
|
+
const arrChildSortData = ['productName', 'productSKU']
|
|
85
|
+
|
|
86
|
+
const remapChildSortData = ['name', 'sku']
|
|
65
87
|
const sort = (sortings || []).reduce(
|
|
66
|
-
(acc, sort) => ({
|
|
88
|
+
(acc, sort, idx) => ({
|
|
67
89
|
...acc,
|
|
68
|
-
[arrChildSortData.indexOf(sort.name) >= 0 ?
|
|
69
|
-
? 'DESC'
|
|
70
|
-
: 'ASC'
|
|
90
|
+
[arrChildSortData.indexOf(sort.name) >= 0 ? 'product' + '.' + remapChildSortData[idx] : 'iv.' + sort.name]:
|
|
91
|
+
sort.desc ? 'DESC' : 'ASC'
|
|
71
92
|
}),
|
|
72
93
|
{}
|
|
73
94
|
)
|
|
@@ -101,7 +122,6 @@ export const inventoriesByPalletResolver = {
|
|
|
101
122
|
})
|
|
102
123
|
)
|
|
103
124
|
}
|
|
104
|
-
|
|
105
125
|
let [items, total] = await qb.getManyAndCount()
|
|
106
126
|
|
|
107
127
|
items = await Promise.all(
|
|
@@ -116,7 +136,8 @@ export const inventoriesByPalletResolver = {
|
|
|
116
136
|
// product: item.product,
|
|
117
137
|
productName: item.product.name,
|
|
118
138
|
productSKU: item.product.sku,
|
|
119
|
-
productBrand: item.product.brand
|
|
139
|
+
productBrand: item.product.brand,
|
|
140
|
+
productId: item.product.id
|
|
120
141
|
}
|
|
121
142
|
})
|
|
122
143
|
)
|
|
@@ -28,6 +28,7 @@ export const fetchAndAssignPickingTaskResolver = {
|
|
|
28
28
|
.addSelect('ws.name')
|
|
29
29
|
.addSelect('ws.status')
|
|
30
30
|
.addSelect('ws.release_good_id')
|
|
31
|
+
.innerJoin('ws.releaseGood', 'rg')
|
|
31
32
|
.where(
|
|
32
33
|
'(ws.domain_id = :domain_id AND ws.type = :type AND ws.assignee_id =:assignee AND (ws.status = :status1 OR ws.status = :status2))',
|
|
33
34
|
{
|
|
@@ -50,6 +51,7 @@ export const fetchAndAssignPickingTaskResolver = {
|
|
|
50
51
|
.getQuery()
|
|
51
52
|
return 'NOT EXISTS ' + subQuery
|
|
52
53
|
})
|
|
54
|
+
.orderBy('"rg"."created_at"', 'ASC')
|
|
53
55
|
|
|
54
56
|
worksheet = await worksheetQb.getRawOne()
|
|
55
57
|
|
|
@@ -61,6 +63,7 @@ export const fetchAndAssignPickingTaskResolver = {
|
|
|
61
63
|
.addSelect('ws.name')
|
|
62
64
|
.addSelect('ws.status')
|
|
63
65
|
.addSelect('ws.release_good_id')
|
|
66
|
+
.innerJoin('ws.releaseGood', 'rg')
|
|
64
67
|
.where(
|
|
65
68
|
'(ws.domain_id = :domain_id AND ws.type = :type AND ws.assignee_id IS NULL AND (ws.status = :status1 OR ws.status = :status2))',
|
|
66
69
|
{
|
|
@@ -82,6 +85,7 @@ export const fetchAndAssignPickingTaskResolver = {
|
|
|
82
85
|
.getQuery()
|
|
83
86
|
return 'NOT EXISTS ' + subQuery
|
|
84
87
|
})
|
|
88
|
+
.orderBy('"rg"."created_at"', 'ASC')
|
|
85
89
|
|
|
86
90
|
worksheet = await worksheetQb.getRawOne()
|
|
87
91
|
|
|
@@ -6,7 +6,7 @@ import { PickingWorksheetController } from '../../../../controllers'
|
|
|
6
6
|
export const scanProductBatchPickingResolver = {
|
|
7
7
|
async scanProductBatchPicking(
|
|
8
8
|
_: any,
|
|
9
|
-
{ taskNo, worksheetType, cartonId, productBarcode, inventory, binLocationName },
|
|
9
|
+
{ taskNo, worksheetType, cartonId, productBarcode, inventory, binLocationName, pickingQty },
|
|
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 scanProductBatchPickingResolver = {
|
|
|
19
19
|
cartonId,
|
|
20
20
|
productBarcode,
|
|
21
21
|
inventory,
|
|
22
|
-
binLocationName
|
|
22
|
+
binLocationName,
|
|
23
|
+
pickingQty
|
|
23
24
|
)
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -33,7 +34,8 @@ export async function scanProductBatchPicking(
|
|
|
33
34
|
cartonId: string,
|
|
34
35
|
productBarcode: string,
|
|
35
36
|
inventory: any,
|
|
36
|
-
binLocationName?: string
|
|
37
|
+
binLocationName?: string,
|
|
38
|
+
pickingQty?: number
|
|
37
39
|
) {
|
|
38
40
|
const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
|
|
39
41
|
await worksheetController.scanProductBatchPicking(
|
|
@@ -42,6 +44,7 @@ export async function scanProductBatchPicking(
|
|
|
42
44
|
cartonId,
|
|
43
45
|
productBarcode,
|
|
44
46
|
inventory,
|
|
45
|
-
binLocationName
|
|
47
|
+
binLocationName,
|
|
48
|
+
pickingQty
|
|
46
49
|
)
|
|
47
50
|
}
|
|
@@ -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, toteNo },
|
|
9
|
+
{ worksheetDetailName, worksheetType, productBarcode, cartonId, binLocation, serialNumber, toteNo, pickingQty },
|
|
10
10
|
context: any
|
|
11
11
|
) {
|
|
12
12
|
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
@@ -20,7 +20,8 @@ export const scanProductPickingResolver = {
|
|
|
20
20
|
cartonId,
|
|
21
21
|
binLocation,
|
|
22
22
|
serialNumber,
|
|
23
|
-
toteNo
|
|
23
|
+
toteNo,
|
|
24
|
+
pickingQty
|
|
24
25
|
)
|
|
25
26
|
}
|
|
26
27
|
}
|
|
@@ -35,7 +36,8 @@ export async function scanProductPicking(
|
|
|
35
36
|
cartonId: string,
|
|
36
37
|
binLocation?: string,
|
|
37
38
|
serialNumber?: string,
|
|
38
|
-
toteNo?: string
|
|
39
|
+
toteNo?: string,
|
|
40
|
+
pickingQty?: number
|
|
39
41
|
) {
|
|
40
42
|
const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
|
|
41
43
|
await worksheetController.scanProductPicking(
|
|
@@ -45,6 +47,7 @@ export async function scanProductPicking(
|
|
|
45
47
|
cartonId,
|
|
46
48
|
binLocation,
|
|
47
49
|
serialNumber,
|
|
48
|
-
toteNo
|
|
50
|
+
toteNo,
|
|
51
|
+
pickingQty
|
|
49
52
|
)
|
|
50
53
|
}
|
|
@@ -100,6 +100,7 @@ export async function pickingWorksheet(
|
|
|
100
100
|
refNo: releaseGood.refNo,
|
|
101
101
|
refNo2: releaseGood.refNo2,
|
|
102
102
|
refNo3: releaseGood.refNo3,
|
|
103
|
+
type: releaseGood.type,
|
|
103
104
|
containerNo: shippingOrder?.containerNo,
|
|
104
105
|
marketplaceStatus: releaseGood.marketplaceOrderStatus,
|
|
105
106
|
shippingProvider: releaseGood.transporter,
|
|
@@ -113,10 +114,10 @@ export async function pickingWorksheet(
|
|
|
113
114
|
const inventoryChangesCount: number = await tx.getRepository(InventoryChange).count({
|
|
114
115
|
where: {
|
|
115
116
|
inventory: inventory.id,
|
|
116
|
-
status:"PENDING",
|
|
117
|
-
transactionType:"MISSING"
|
|
117
|
+
status: "PENDING",
|
|
118
|
+
transactionType: "MISSING"
|
|
118
119
|
},
|
|
119
|
-
relations:['inventory','product']
|
|
120
|
+
relations: ['inventory', 'product']
|
|
120
121
|
})
|
|
121
122
|
|
|
122
123
|
return {
|
|
@@ -138,7 +139,7 @@ export async function pickingWorksheet(
|
|
|
138
139
|
expirationDate: inventory?.expirationDate,
|
|
139
140
|
location: inventory?.location,
|
|
140
141
|
relatedOrderInv: targetInventory,
|
|
141
|
-
hasMissingInventoryChanges:inventoryChangesCount > 0 ? true:false
|
|
142
|
+
hasMissingInventoryChanges: inventoryChangesCount > 0 ? true : false
|
|
142
143
|
}
|
|
143
144
|
})
|
|
144
145
|
}
|
|
@@ -91,7 +91,7 @@ export const worksheetResolver = {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
let pWorksheetPickingItemSorting = getRepository(Setting).findOne({
|
|
94
|
-
where: { domain, category: 'location', name: 'rule-for-
|
|
94
|
+
where: { domain, category: 'location', name: 'rule-for-picking-product' }
|
|
95
95
|
})
|
|
96
96
|
|
|
97
97
|
if (worksheet?.arrivalNotice?.id) {
|
|
@@ -172,10 +172,12 @@ export const worksheetResolver = {
|
|
|
172
172
|
if (sortingSetting?.value) {
|
|
173
173
|
let settingValue = JSON.parse(sortingSetting.value)
|
|
174
174
|
for (const key in settingValue) {
|
|
175
|
-
qbOrderInventories.addOrderBy(`location.${key}`, settingValue[key] ? 'ASC' : 'DESC')
|
|
175
|
+
qbOrderInventories.addOrderBy(`location.${key}`, settingValue[key] == 'ASC' ? 'ASC' : 'DESC')
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
qbOrderInventories.addOrderBy(`product.name`, 'ASC')
|
|
180
|
+
|
|
179
181
|
let orderInventories: OrderInventory[] = await qbOrderInventories.getMany()
|
|
180
182
|
worksheet.orderInventories = orderInventories
|
|
181
183
|
}
|
|
@@ -204,10 +206,12 @@ export const worksheetResolver = {
|
|
|
204
206
|
if (sortingSetting?.value) {
|
|
205
207
|
let settingValue = JSON.parse(sortingSetting.value)
|
|
206
208
|
for (const key in settingValue) {
|
|
207
|
-
qbOrderInventories.addOrderBy(`location.${key}`, settingValue[key] ? 'ASC' : 'DESC')
|
|
209
|
+
qbOrderInventories.addOrderBy(`location.${key}`, settingValue[key] == 'ASC' ? 'ASC' : 'DESC')
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
212
|
|
|
213
|
+
qbOrderInventories.addOrderBy(`product.name`, 'ASC')
|
|
214
|
+
|
|
211
215
|
let orderInventories: OrderInventory[] = await qbOrderInventories.getMany()
|
|
212
216
|
worksheet.orderInventories = orderInventories
|
|
213
217
|
|
|
@@ -248,6 +252,15 @@ export const worksheetResolver = {
|
|
|
248
252
|
})
|
|
249
253
|
}
|
|
250
254
|
|
|
255
|
+
if (worksheet.orderInventories) {
|
|
256
|
+
worksheet.worksheetDetails.sort(function (a, b) {
|
|
257
|
+
return (
|
|
258
|
+
worksheet.orderInventories.map(oi => oi.id).indexOf(a.targetInventory.id) -
|
|
259
|
+
worksheet.orderInventories.map(oi => oi.id).indexOf(b.targetInventory.id)
|
|
260
|
+
)
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
|
|
251
264
|
if (worksheet?.returnOrder?.id) {
|
|
252
265
|
worksheet.orderInventories = await getRepository(OrderInventory).find({
|
|
253
266
|
where: {
|
|
@@ -7,6 +7,7 @@ import { generateCartonIdResolver } from './generate-carton-id'
|
|
|
7
7
|
import { generatePalletIdResolver } from './generate-pallet-id'
|
|
8
8
|
import { generatePickingWorksheetDetailsResolver } from './generate-picking-worksheet-details'
|
|
9
9
|
import { generateReleaseGoodWorksheetDetailsResolver } from './generate-release-good-worksheet-details'
|
|
10
|
+
import { regenerateReleaseGoodWorksheetDetailsResolver } from './regenerate-release-good-worksheet-details'
|
|
10
11
|
import { updateWorksheetDetail } from './update-worksheet-detail'
|
|
11
12
|
import { worksheetDetailResolver } from './worksheet-detail'
|
|
12
13
|
import { worksheetDetailsResolver } from './worksheet-details'
|
|
@@ -28,5 +29,6 @@ export const Mutation = {
|
|
|
28
29
|
...generateBatchPickingWorksheetDetailsResolver,
|
|
29
30
|
...generateBatchPickingWorksheetDetailsByBulkResolver,
|
|
30
31
|
...generatePickingWorksheetDetailsResolver,
|
|
31
|
-
...generateReleaseGoodWorksheetDetailsResolver
|
|
32
|
+
...generateReleaseGoodWorksheetDetailsResolver,
|
|
33
|
+
...regenerateReleaseGoodWorksheetDetailsResolver
|
|
32
34
|
}
|
package/server/graphql/resolvers/worksheet-detail/regenerate-release-good-worksheet-details.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
import { User } from '@things-factory/auth-base'
|
|
4
|
+
import { Product } from '@things-factory/product-base'
|
|
5
|
+
import {
|
|
6
|
+
ORDER_INVENTORY_STATUS,
|
|
7
|
+
ORDER_PRODUCT_STATUS,
|
|
8
|
+
OrderInventory,
|
|
9
|
+
OrderNoGenerator,
|
|
10
|
+
OrderProduct
|
|
11
|
+
} from '@things-factory/sales-base'
|
|
12
|
+
import { Domain } from '@things-factory/shell'
|
|
13
|
+
import { Inventory } from '@things-factory/warehouse-base'
|
|
14
|
+
|
|
15
|
+
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
|
|
16
|
+
import { Worksheet, WorksheetDetail } from '../../../entities'
|
|
17
|
+
import { WorksheetNoGenerator } from '../../../utils'
|
|
18
|
+
|
|
19
|
+
export const regenerateReleaseGoodWorksheetDetailsResolver = {
|
|
20
|
+
async regenerateReleaseGoodWorksheetDetails(
|
|
21
|
+
_: any,
|
|
22
|
+
{ worksheetNo, batchId, productId, packingType, packingSize, orderProductId, worksheetDetails },
|
|
23
|
+
context: any
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
|
|
26
|
+
return await regenerateReleaseGoodWorksheetDetails(
|
|
27
|
+
tx,
|
|
28
|
+
domain,
|
|
29
|
+
user,
|
|
30
|
+
worksheetNo,
|
|
31
|
+
batchId,
|
|
32
|
+
productId,
|
|
33
|
+
packingType,
|
|
34
|
+
packingSize,
|
|
35
|
+
orderProductId,
|
|
36
|
+
worksheetDetails
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function regenerateReleaseGoodWorksheetDetails(
|
|
42
|
+
tx: EntityManager,
|
|
43
|
+
domain: Domain,
|
|
44
|
+
user: User,
|
|
45
|
+
worksheetNo: string,
|
|
46
|
+
batchId: string,
|
|
47
|
+
productId: string,
|
|
48
|
+
packingType: string,
|
|
49
|
+
packingSize: number,
|
|
50
|
+
orderProductId: string,
|
|
51
|
+
worksheetDetails: Partial<WorksheetDetail>[]
|
|
52
|
+
): Promise<void> {
|
|
53
|
+
// 1. Remove prev worksheet details if it's exists
|
|
54
|
+
const worksheet: Worksheet = await tx.getRepository(Worksheet).findOne({
|
|
55
|
+
where: { name: worksheetNo, domain },
|
|
56
|
+
relations: [
|
|
57
|
+
'bizplace',
|
|
58
|
+
'releaseGood',
|
|
59
|
+
'worksheetDetails',
|
|
60
|
+
'worksheetDetails.targetInventory',
|
|
61
|
+
'worksheetDetails.targetInventory.inventory',
|
|
62
|
+
'worksheetDetails.targetInventory.product',
|
|
63
|
+
'worksheetDetails.targetInventory.releaseGood',
|
|
64
|
+
'worksheetDetails.targetInventory.orderProduct',
|
|
65
|
+
'worksheetDetails.targetInventory.bizplace'
|
|
66
|
+
]
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
const prevWSDs: WorksheetDetail[] = worksheet.worksheetDetails.filter((wsd: WorksheetDetail) => {
|
|
70
|
+
const targetInv: OrderInventory = wsd.targetInventory
|
|
71
|
+
if (targetInv.orderProductId === orderProductId) return wsd.id
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// TODO: Update prev inventory locked qty and delete order inventories
|
|
75
|
+
if (prevWSDs?.length) {
|
|
76
|
+
const wsdIds: string[] = prevWSDs.map((wsd: WorksheetDetail) => wsd.id)
|
|
77
|
+
const prevOrderInvIds: string[] = prevWSDs.map((wsd: WorksheetDetail) => wsd.targetInventory.id)
|
|
78
|
+
const prevOrderInventories: OrderInventory[] = prevWSDs.map((wsd: WorksheetDetail) => wsd.targetInventory)
|
|
79
|
+
await Promise.all(
|
|
80
|
+
prevOrderInventories.map(async prevOI => {
|
|
81
|
+
if (prevOI?.inventory) {
|
|
82
|
+
await tx.getRepository(Inventory).update(
|
|
83
|
+
{ id: prevOI.inventory.id },
|
|
84
|
+
{
|
|
85
|
+
lockedQty: prevOI.inventory.lockedQty - prevOI.releaseQty,
|
|
86
|
+
lockedUomValue: prevOI.inventory.lockedUomValue - prevOI.releaseUomValue
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
await tx.getRepository(WorksheetDetail).delete(wsdIds)
|
|
94
|
+
await tx.getRepository(OrderInventory).delete(prevOrderInvIds)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await Promise.all(
|
|
98
|
+
worksheetDetails.map(async (wsd: WorksheetDetail) => {
|
|
99
|
+
// 2. Create order inventory
|
|
100
|
+
let targetInventory: OrderInventory = wsd.targetInventory
|
|
101
|
+
const inventory: Inventory = await tx.getRepository(Inventory).findOne(targetInventory.inventory.id)
|
|
102
|
+
|
|
103
|
+
let targetProduct: OrderProduct = await tx
|
|
104
|
+
.getRepository(OrderProduct)
|
|
105
|
+
.findOne({ where: { id: wsd.targetProduct.id }, relations: ['releaseGood'] })
|
|
106
|
+
|
|
107
|
+
targetInventory = await tx.getRepository(OrderInventory).save({
|
|
108
|
+
...targetInventory,
|
|
109
|
+
domain,
|
|
110
|
+
bizplace: worksheet.bizplace,
|
|
111
|
+
name: OrderNoGenerator.orderInventory(),
|
|
112
|
+
releaseGood: worksheet.type == WORKSHEET_TYPE.BATCH_PICKING ? targetProduct.releaseGood : worksheet.releaseGood,
|
|
113
|
+
inventory,
|
|
114
|
+
batchId: inventory.batchId,
|
|
115
|
+
batchIdRef: inventory.batchIdRef,
|
|
116
|
+
status: ORDER_INVENTORY_STATUS.READY_TO_PICK,
|
|
117
|
+
product: await tx.getRepository(Product).findOne(productId),
|
|
118
|
+
packingType,
|
|
119
|
+
packingSize,
|
|
120
|
+
orderProduct: targetProduct,
|
|
121
|
+
refWorksheetId: worksheet.type == WORKSHEET_TYPE.BATCH_PICKING ? worksheet.id : null,
|
|
122
|
+
creator: user,
|
|
123
|
+
updater: user
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
const currentLockedQty: any = inventory.lockedQty
|
|
127
|
+
const currentLockedUomValue: any = inventory.lockedUomValue
|
|
128
|
+
|
|
129
|
+
await tx.getRepository(Inventory).save({
|
|
130
|
+
...targetInventory.inventory,
|
|
131
|
+
lockedQty: Boolean(currentLockedQty)
|
|
132
|
+
? targetInventory.releaseQty + currentLockedQty
|
|
133
|
+
: targetInventory.releaseQty,
|
|
134
|
+
lockedUomValue: Boolean(currentLockedUomValue)
|
|
135
|
+
? targetInventory.releaseUomValue + currentLockedUomValue
|
|
136
|
+
: targetInventory.releaseUomValue,
|
|
137
|
+
updater: user
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
// update order product status to ASSIGNED
|
|
141
|
+
await tx
|
|
142
|
+
.getRepository(OrderProduct)
|
|
143
|
+
.update({ id: targetProduct.id }, { status: ORDER_PRODUCT_STATUS.ASSIGNED, updater: user })
|
|
144
|
+
|
|
145
|
+
// 3. Create worksheet details
|
|
146
|
+
await tx.getRepository(WorksheetDetail).save({
|
|
147
|
+
...wsd,
|
|
148
|
+
domain,
|
|
149
|
+
bizplace: worksheet.bizplace,
|
|
150
|
+
worksheet,
|
|
151
|
+
name:
|
|
152
|
+
worksheet.type == WORKSHEET_TYPE.BATCH_PICKING
|
|
153
|
+
? WorksheetNoGenerator.batchPickingDetail()
|
|
154
|
+
: WorksheetNoGenerator.pickingDetail(),
|
|
155
|
+
targetProduct,
|
|
156
|
+
targetInventory,
|
|
157
|
+
type: worksheet.type == WORKSHEET_TYPE.BATCH_PICKING ? WORKSHEET_TYPE.BATCH_PICKING : WORKSHEET_TYPE.PICKING,
|
|
158
|
+
status: WORKSHEET_STATUS.DEACTIVATED,
|
|
159
|
+
creator: user,
|
|
160
|
+
updater: user
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
)
|
|
164
|
+
}
|