@things-factory/worksheet-base 4.3.693 → 4.3.695
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/controllers/inbound/putaway-worksheet-controller.js +83 -0
- package/dist-server/controllers/inbound/putaway-worksheet-controller.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/index.js +2 -2
- package/dist-server/graphql/resolvers/worksheet/index.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/recommend-putaway-location.js +331 -0
- package/dist-server/graphql/resolvers/worksheet/recommend-putaway-location.js.map +1 -0
- package/package.json +21 -21
- package/server/controllers/inbound/putaway-worksheet-controller.ts +87 -0
- package/server/graphql/resolvers/worksheet/index.ts +1 -1
- package/server/graphql/resolvers/worksheet/recommend-putaway-location.ts +423 -0
- package/dist-server/graphql/resolvers/worksheet/recommend-putway-location.js +0 -157
- package/dist-server/graphql/resolvers/worksheet/recommend-putway-location.js.map +0 -1
- package/server/graphql/resolvers/worksheet/recommend-putway-location.ts +0 -212
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getLevel2Location = exports.getEmptyLocations = exports.recommendQuarantineLocationLevel1 = exports.recommendLocationLevel2 = exports.recommendLocationLevel1 = exports.recommendPutawayLocationResolver = void 0;
|
|
4
|
-
const typeorm_1 = require("typeorm");
|
|
5
|
-
const setting_base_1 = require("@things-factory/setting-base");
|
|
6
|
-
const warehouse_base_1 = require("@things-factory/warehouse-base");
|
|
7
|
-
const constants_1 = require("../../../constants");
|
|
8
|
-
const entities_1 = require("../../../entities");
|
|
9
|
-
const inventory_util_1 = require("../../../utils/inventory-util");
|
|
10
|
-
exports.recommendPutawayLocationResolver = {
|
|
11
|
-
async recommendPutawayLocation(_, { worksheetDetailName, optCnt = 1 }, context) {
|
|
12
|
-
const domain = context.state.domain;
|
|
13
|
-
const worksheetDetail = await (0, typeorm_1.getRepository)(entities_1.WorksheetDetail).findOne({ domain, name: worksheetDetailName }, {
|
|
14
|
-
relations: [
|
|
15
|
-
'worksheet',
|
|
16
|
-
'worksheet.arrivalNotice',
|
|
17
|
-
'worksheet.returnOrder',
|
|
18
|
-
'targetInventory',
|
|
19
|
-
'targetInventory.inventory',
|
|
20
|
-
'targetInventory.inventory.product'
|
|
21
|
-
]
|
|
22
|
-
});
|
|
23
|
-
const inventory = worksheetDetail.targetInventory.inventory;
|
|
24
|
-
if (worksheetDetail.status !== constants_1.WORKSHEET_STATUS.EXECUTING)
|
|
25
|
-
throw new Error('Current target is not processing');
|
|
26
|
-
const arrivalNotice = worksheetDetail.worksheet.arrivalNotice;
|
|
27
|
-
const returnOrder = worksheetDetail.worksheet.returnOrder;
|
|
28
|
-
let unloadingWS;
|
|
29
|
-
if (arrivalNotice) {
|
|
30
|
-
unloadingWS = await (0, typeorm_1.getRepository)(entities_1.Worksheet).findOne({
|
|
31
|
-
where: { domain, arrivalNotice, type: constants_1.WORKSHEET_TYPE.UNLOADING },
|
|
32
|
-
relations: ['bufferLocation', 'bufferLocation.warehouse']
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
else if (returnOrder) {
|
|
36
|
-
unloadingWS = await (0, typeorm_1.getRepository)(entities_1.Worksheet).findOne({
|
|
37
|
-
where: { domain, returnOrder, type: constants_1.WORKSHEET_TYPE.UNLOADING_RETURN },
|
|
38
|
-
relations: ['bufferLocation', 'bufferLocation.warehouse']
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
const targetWarehouse = unloadingWS.bufferLocation.warehouse;
|
|
42
|
-
const sortingLevelSetting = await (0, typeorm_1.getRepository)(setting_base_1.Setting).findOne({
|
|
43
|
-
where: { domain, name: 'location-recommendation-level' }
|
|
44
|
-
});
|
|
45
|
-
const sortingLevel = sortingLevelSetting === null || sortingLevelSetting === void 0 ? void 0 : sortingLevelSetting.value;
|
|
46
|
-
const isExpiring = await (0, inventory_util_1.isInventoryExpiring)(inventory);
|
|
47
|
-
let recommendedLocations = [];
|
|
48
|
-
if (isExpiring) {
|
|
49
|
-
switch (sortingLevel) {
|
|
50
|
-
case 'level 1':
|
|
51
|
-
case 'level 2':
|
|
52
|
-
recommendedLocations = await recommendQuarantineLocationLevel1(domain, targetWarehouse, optCnt);
|
|
53
|
-
break;
|
|
54
|
-
default:
|
|
55
|
-
recommendedLocations = await recommendQuarantineLocationLevel1(domain, targetWarehouse, optCnt);
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (recommendedLocations.length > 0)
|
|
60
|
-
return recommendedLocations;
|
|
61
|
-
switch (sortingLevel) {
|
|
62
|
-
case 'level 1':
|
|
63
|
-
recommendedLocations = await recommendLocationLevel1(domain, targetWarehouse, optCnt);
|
|
64
|
-
break;
|
|
65
|
-
case 'level 2':
|
|
66
|
-
recommendedLocations = await recommendLocationLevel2(domain, targetWarehouse, optCnt, inventory.product.id);
|
|
67
|
-
break;
|
|
68
|
-
default:
|
|
69
|
-
recommendedLocations = await recommendLocationLevel1(domain, targetWarehouse, optCnt);
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
return recommendedLocations;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
async function recommendLocationLevel1(domain, warehouse, optCnt) {
|
|
76
|
-
return await getEmptyLocations(domain, warehouse, optCnt, [warehouse_base_1.LOCATION_TYPE.SHELF, warehouse_base_1.LOCATION_TYPE.FLOOR]);
|
|
77
|
-
}
|
|
78
|
-
exports.recommendLocationLevel1 = recommendLocationLevel1;
|
|
79
|
-
async function recommendLocationLevel2(domain, warehouse, optCnt, productId) {
|
|
80
|
-
return await getLevel2Location(domain, warehouse, optCnt, [warehouse_base_1.LOCATION_TYPE.STORAGE, warehouse_base_1.LOCATION_TYPE.SHELF, warehouse_base_1.LOCATION_TYPE.FLOOR], productId);
|
|
81
|
-
}
|
|
82
|
-
exports.recommendLocationLevel2 = recommendLocationLevel2;
|
|
83
|
-
async function recommendQuarantineLocationLevel1(domain, warehouse, optCnt) {
|
|
84
|
-
return await getEmptyLocations(domain, warehouse, optCnt, [warehouse_base_1.LOCATION_TYPE.QUARANTINE]);
|
|
85
|
-
}
|
|
86
|
-
exports.recommendQuarantineLocationLevel1 = recommendQuarantineLocationLevel1;
|
|
87
|
-
async function getEmptyLocations(domain, warehouse, optCnt, allowedTypes) {
|
|
88
|
-
const orderSetting = await (0, typeorm_1.getRepository)(setting_base_1.Setting).findOne({
|
|
89
|
-
where: { domain, name: 'rule-for-storing-product' }
|
|
90
|
-
});
|
|
91
|
-
let order = {};
|
|
92
|
-
if (orderSetting === null || orderSetting === void 0 ? void 0 : orderSetting.value)
|
|
93
|
-
order = JSON.parse(orderSetting.value);
|
|
94
|
-
return await (0, typeorm_1.getRepository)(warehouse_base_1.Location).find({
|
|
95
|
-
where: {
|
|
96
|
-
domain,
|
|
97
|
-
warehouse,
|
|
98
|
-
status: warehouse_base_1.LOCATION_STATUS.EMPTY,
|
|
99
|
-
type: (0, typeorm_1.In)(allowedTypes)
|
|
100
|
-
},
|
|
101
|
-
order,
|
|
102
|
-
take: optCnt
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
exports.getEmptyLocations = getEmptyLocations;
|
|
106
|
-
async function getLevel2Location(domain, warehouse, optCnt, allowedTypes, productId) {
|
|
107
|
-
let sortLocation = {};
|
|
108
|
-
let sortInventoryLocation = {};
|
|
109
|
-
let recommendedLocation = [];
|
|
110
|
-
const orderSetting = await (0, typeorm_1.getRepository)(setting_base_1.Setting).findOne({
|
|
111
|
-
where: { domain, name: 'rule-for-storing-product' }
|
|
112
|
-
});
|
|
113
|
-
if (orderSetting === null || orderSetting === void 0 ? void 0 : orderSetting.value) {
|
|
114
|
-
sortLocation = JSON.parse(orderSetting.value);
|
|
115
|
-
sortInventoryLocation = Object.fromEntries(Object.entries(sortLocation).map(([key, value]) => [`location.${key}`, value]));
|
|
116
|
-
}
|
|
117
|
-
for (const type of allowedTypes) {
|
|
118
|
-
const qb = await (0, typeorm_1.getRepository)(warehouse_base_1.Inventory)
|
|
119
|
-
.createQueryBuilder('inventory')
|
|
120
|
-
.leftJoinAndSelect('inventory.location', 'location')
|
|
121
|
-
.leftJoin('inventory.product', 'product')
|
|
122
|
-
.where('inventory.domain = :domain', { domain: domain.id })
|
|
123
|
-
.andWhere('inventory.status = :inventoryStatus', { inventoryStatus: 'STORED' })
|
|
124
|
-
.andWhere('product.id = :productId', { productId: productId })
|
|
125
|
-
.andWhere('location.warehouse = :warehouse', { warehouse: warehouse.id })
|
|
126
|
-
.andWhere('location.status = :status', { status: warehouse_base_1.LOCATION_STATUS.OCCUPIED })
|
|
127
|
-
.andWhere('location.type = :type', { type })
|
|
128
|
-
.orderBy('inventory.qty', 'ASC');
|
|
129
|
-
Object.entries(sortInventoryLocation).forEach(([key, value]) => {
|
|
130
|
-
qb.addOrderBy(key, value);
|
|
131
|
-
});
|
|
132
|
-
qb.take(optCnt);
|
|
133
|
-
const inventories = await qb.getMany();
|
|
134
|
-
if (inventories.length > 0) {
|
|
135
|
-
recommendedLocation = inventories.map(inventory => inventory.location);
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
recommendedLocation = await (0, typeorm_1.getRepository)(warehouse_base_1.Location).find({
|
|
140
|
-
where: {
|
|
141
|
-
domain,
|
|
142
|
-
warehouse,
|
|
143
|
-
status: warehouse_base_1.LOCATION_STATUS.EMPTY,
|
|
144
|
-
type
|
|
145
|
-
},
|
|
146
|
-
sortLocation,
|
|
147
|
-
take: optCnt
|
|
148
|
-
});
|
|
149
|
-
if (recommendedLocation.length > 0) {
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return recommendedLocation;
|
|
155
|
-
}
|
|
156
|
-
exports.getLevel2Location = getLevel2Location;
|
|
157
|
-
//# sourceMappingURL=recommend-putway-location.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"recommend-putway-location.js","sourceRoot":"","sources":["../../../../server/graphql/resolvers/worksheet/recommend-putway-location.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import { getRepository, In } from 'typeorm'
|
|
2
|
-
|
|
3
|
-
import { ArrivalNotice, ReturnOrder } from '@things-factory/sales-base'
|
|
4
|
-
import { Setting } from '@things-factory/setting-base'
|
|
5
|
-
import { Domain } from '@things-factory/shell'
|
|
6
|
-
import { Inventory, Location, LOCATION_STATUS, LOCATION_TYPE, Warehouse } from '@things-factory/warehouse-base'
|
|
7
|
-
|
|
8
|
-
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
|
|
9
|
-
import { Worksheet, WorksheetDetail } from '../../../entities'
|
|
10
|
-
import { isInventoryExpiring } from '../../../utils/inventory-util'
|
|
11
|
-
|
|
12
|
-
export const recommendPutawayLocationResolver = {
|
|
13
|
-
async recommendPutawayLocation(
|
|
14
|
-
_: void,
|
|
15
|
-
{ worksheetDetailName, optCnt = 1 }: { worksheetDetailName: string; optCnt: number },
|
|
16
|
-
context: any
|
|
17
|
-
): Promise<Location[]> {
|
|
18
|
-
const domain: Domain = context.state.domain
|
|
19
|
-
|
|
20
|
-
const worksheetDetail: WorksheetDetail = await getRepository(WorksheetDetail).findOne(
|
|
21
|
-
{ domain, name: worksheetDetailName },
|
|
22
|
-
{
|
|
23
|
-
relations: [
|
|
24
|
-
'worksheet',
|
|
25
|
-
'worksheet.arrivalNotice',
|
|
26
|
-
'worksheet.returnOrder',
|
|
27
|
-
'targetInventory',
|
|
28
|
-
'targetInventory.inventory',
|
|
29
|
-
'targetInventory.inventory.product'
|
|
30
|
-
]
|
|
31
|
-
}
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
const inventory: Inventory = worksheetDetail.targetInventory.inventory
|
|
35
|
-
if (worksheetDetail.status !== WORKSHEET_STATUS.EXECUTING) throw new Error('Current target is not processing')
|
|
36
|
-
|
|
37
|
-
const arrivalNotice: ArrivalNotice = worksheetDetail.worksheet.arrivalNotice
|
|
38
|
-
const returnOrder: ReturnOrder = worksheetDetail.worksheet.returnOrder
|
|
39
|
-
|
|
40
|
-
let unloadingWS: Worksheet
|
|
41
|
-
if (arrivalNotice) {
|
|
42
|
-
unloadingWS = await getRepository(Worksheet).findOne({
|
|
43
|
-
where: { domain, arrivalNotice, type: WORKSHEET_TYPE.UNLOADING },
|
|
44
|
-
relations: ['bufferLocation', 'bufferLocation.warehouse']
|
|
45
|
-
})
|
|
46
|
-
} else if (returnOrder) {
|
|
47
|
-
unloadingWS = await getRepository(Worksheet).findOne({
|
|
48
|
-
where: { domain, returnOrder, type: WORKSHEET_TYPE.UNLOADING_RETURN },
|
|
49
|
-
relations: ['bufferLocation', 'bufferLocation.warehouse']
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const targetWarehouse: Warehouse = unloadingWS.bufferLocation.warehouse
|
|
54
|
-
const sortingLevelSetting: Setting = await getRepository(Setting).findOne({
|
|
55
|
-
where: { domain, name: 'location-recommendation-level' }
|
|
56
|
-
})
|
|
57
|
-
const sortingLevel = sortingLevelSetting?.value
|
|
58
|
-
|
|
59
|
-
const isExpiring: boolean = await isInventoryExpiring(inventory)
|
|
60
|
-
|
|
61
|
-
let recommendedLocations: Location[] = []
|
|
62
|
-
if (isExpiring) {
|
|
63
|
-
switch (sortingLevel) {
|
|
64
|
-
case 'level 1':
|
|
65
|
-
case 'level 2':
|
|
66
|
-
recommendedLocations = await recommendQuarantineLocationLevel1(domain, targetWarehouse, optCnt)
|
|
67
|
-
break
|
|
68
|
-
|
|
69
|
-
default:
|
|
70
|
-
recommendedLocations = await recommendQuarantineLocationLevel1(domain, targetWarehouse, optCnt)
|
|
71
|
-
break
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (recommendedLocations.length > 0) return recommendedLocations
|
|
76
|
-
|
|
77
|
-
switch (sortingLevel) {
|
|
78
|
-
case 'level 1':
|
|
79
|
-
recommendedLocations = await recommendLocationLevel1(domain, targetWarehouse, optCnt)
|
|
80
|
-
break
|
|
81
|
-
|
|
82
|
-
case 'level 2':
|
|
83
|
-
recommendedLocations = await recommendLocationLevel2(domain, targetWarehouse, optCnt, inventory.product.id)
|
|
84
|
-
break
|
|
85
|
-
|
|
86
|
-
default:
|
|
87
|
-
recommendedLocations = await recommendLocationLevel1(domain, targetWarehouse, optCnt)
|
|
88
|
-
break
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return recommendedLocations
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function recommendLocationLevel1(
|
|
96
|
-
domain: Domain,
|
|
97
|
-
warehouse: Warehouse,
|
|
98
|
-
optCnt: number
|
|
99
|
-
): Promise<Location[]> {
|
|
100
|
-
return await getEmptyLocations(domain, warehouse, optCnt, [LOCATION_TYPE.SHELF, LOCATION_TYPE.FLOOR])
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export async function recommendLocationLevel2(
|
|
104
|
-
domain: Domain,
|
|
105
|
-
warehouse: Warehouse,
|
|
106
|
-
optCnt: number,
|
|
107
|
-
productId: string
|
|
108
|
-
): Promise<Location[]> {
|
|
109
|
-
return await getLevel2Location(
|
|
110
|
-
domain,
|
|
111
|
-
warehouse,
|
|
112
|
-
optCnt,
|
|
113
|
-
[LOCATION_TYPE.STORAGE, LOCATION_TYPE.SHELF, LOCATION_TYPE.FLOOR],
|
|
114
|
-
productId
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export async function recommendQuarantineLocationLevel1(
|
|
119
|
-
domain: Domain,
|
|
120
|
-
warehouse: Warehouse,
|
|
121
|
-
optCnt: number
|
|
122
|
-
): Promise<Location[]> {
|
|
123
|
-
return await getEmptyLocations(domain, warehouse, optCnt, [LOCATION_TYPE.QUARANTINE])
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export async function getEmptyLocations(
|
|
127
|
-
domain: Domain,
|
|
128
|
-
warehouse: Warehouse,
|
|
129
|
-
optCnt: number,
|
|
130
|
-
allowedTypes: LOCATION_TYPE[]
|
|
131
|
-
): Promise<Location[]> {
|
|
132
|
-
const orderSetting: Setting = await getRepository(Setting).findOne({
|
|
133
|
-
where: { domain, name: 'rule-for-storing-product' }
|
|
134
|
-
})
|
|
135
|
-
let order = {}
|
|
136
|
-
if (orderSetting?.value) order = JSON.parse(orderSetting.value)
|
|
137
|
-
|
|
138
|
-
return await getRepository(Location).find({
|
|
139
|
-
where: {
|
|
140
|
-
domain,
|
|
141
|
-
warehouse,
|
|
142
|
-
status: LOCATION_STATUS.EMPTY,
|
|
143
|
-
type: In(allowedTypes)
|
|
144
|
-
},
|
|
145
|
-
order,
|
|
146
|
-
take: optCnt
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export async function getLevel2Location(
|
|
151
|
-
domain: Domain,
|
|
152
|
-
warehouse: Warehouse,
|
|
153
|
-
optCnt: number,
|
|
154
|
-
allowedTypes: LOCATION_TYPE[],
|
|
155
|
-
productId: string
|
|
156
|
-
): Promise<Location[]> {
|
|
157
|
-
let sortLocation = {}
|
|
158
|
-
let sortInventoryLocation = {}
|
|
159
|
-
let recommendedLocation: Location[] = []
|
|
160
|
-
const orderSetting: Setting = await getRepository(Setting).findOne({
|
|
161
|
-
where: { domain, name: 'rule-for-storing-product' }
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
if (orderSetting?.value) {
|
|
165
|
-
sortLocation = JSON.parse(orderSetting.value)
|
|
166
|
-
sortInventoryLocation = Object.fromEntries(Object.entries(sortLocation).map(([key, value]) => [`location.${key}`, value]))
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
for (const type of allowedTypes) {
|
|
170
|
-
const qb = await getRepository(Inventory)
|
|
171
|
-
.createQueryBuilder('inventory')
|
|
172
|
-
.leftJoinAndSelect('inventory.location', 'location')
|
|
173
|
-
.leftJoin('inventory.product', 'product')
|
|
174
|
-
.where('inventory.domain = :domain', { domain: domain.id })
|
|
175
|
-
.andWhere('inventory.status = :inventoryStatus', { inventoryStatus: 'STORED' })
|
|
176
|
-
.andWhere('product.id = :productId', { productId: productId })
|
|
177
|
-
.andWhere('location.warehouse = :warehouse', { warehouse: warehouse.id })
|
|
178
|
-
.andWhere('location.status = :status', { status: LOCATION_STATUS.OCCUPIED })
|
|
179
|
-
.andWhere('location.type = :type', { type })
|
|
180
|
-
.orderBy('inventory.qty', 'ASC')
|
|
181
|
-
|
|
182
|
-
Object.entries(sortInventoryLocation).forEach(([key, value]) => {
|
|
183
|
-
qb.addOrderBy(key, value as 'ASC' | 'DESC')
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
qb.take(optCnt)
|
|
187
|
-
|
|
188
|
-
const inventories: Inventory[] = await qb.getMany()
|
|
189
|
-
|
|
190
|
-
if (inventories.length > 0) {
|
|
191
|
-
recommendedLocation = inventories.map(inventory => inventory.location)
|
|
192
|
-
break
|
|
193
|
-
} else {
|
|
194
|
-
recommendedLocation = await getRepository(Location).find({
|
|
195
|
-
where: {
|
|
196
|
-
domain,
|
|
197
|
-
warehouse,
|
|
198
|
-
status: LOCATION_STATUS.EMPTY,
|
|
199
|
-
type
|
|
200
|
-
},
|
|
201
|
-
sortLocation,
|
|
202
|
-
take: optCnt
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
if (recommendedLocation.length > 0) {
|
|
206
|
-
break
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return recommendedLocation
|
|
212
|
-
}
|