@things-factory/operato-hub 4.3.676 → 4.3.678
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/graphql/resolvers/reports/inbound-order-details-report.js +2 -1
- package/dist-server/graphql/resolvers/reports/inbound-order-details-report.js.map +1 -1
- package/dist-server/graphql/resolvers/reports/outbound-order-details-report.js +9 -10
- package/dist-server/graphql/resolvers/reports/outbound-order-details-report.js.map +1 -1
- package/dist-server/routers/api/restful-apis/v1/utils/params.js +6 -0
- package/dist-server/routers/api/restful-apis/v1/utils/params.js.map +1 -1
- package/dist-server/routers/api/restful-apis/v1/warehouse/add-release-order.js +238 -53
- package/dist-server/routers/api/restful-apis/v1/warehouse/add-release-order.js.map +1 -1
- package/openapi/v1/outbound.yaml +10 -0
- package/package.json +31 -31
- package/server/graphql/resolvers/reports/inbound-order-details-report.ts +5 -4
- package/server/graphql/resolvers/reports/outbound-order-details-report.ts +9 -10
- package/server/routers/api/restful-apis/v1/utils/params.ts +6 -0
- package/server/routers/api/restful-apis/v1/warehouse/add-release-order.ts +269 -54
|
@@ -17,7 +17,7 @@ const warehouse_base_1 = require("@things-factory/warehouse-base");
|
|
|
17
17
|
const middlewares_1 = require("../middlewares");
|
|
18
18
|
const error_util_1 = require("../utils/error-util");
|
|
19
19
|
const integration_lmd_2 = require("@things-factory/integration-lmd");
|
|
20
|
-
const debug = require('debug')('things-factory:operato-hub:restful-api:
|
|
20
|
+
const debug = require('debug')('things-factory:operato-hub:restful-api:v1:add-release-order');
|
|
21
21
|
const apiVersion = 'v1';
|
|
22
22
|
api_1.restfulApiRouter.post(`/${apiVersion}/warehouse/add-release-order`, middlewares_1.businessMiddleware, middlewares_1.validationMiddleware, middlewares_1.loggingMiddleware, async (context, next) => {
|
|
23
23
|
return await (0, typeorm_1.getConnection)().transaction(async (tx) => {
|
|
@@ -152,6 +152,20 @@ api_1.restfulApiRouter.post(`/${apiVersion}/warehouse/add-release-order`, middle
|
|
|
152
152
|
if (batchIdStates.withBatchId && batchIdStates.withoutBatchId) {
|
|
153
153
|
throw new error_util_1.ApiError('E01', 'Please provide batch id for all inventories');
|
|
154
154
|
}
|
|
155
|
+
// validate warehouseCode (name in warehouses table) if provided on any line
|
|
156
|
+
const providedWarehouseCodes = Array.from(new Set((bodyReq.orderInventories || [])
|
|
157
|
+
.map((it) => (it === null || it === void 0 ? void 0 : it.warehouseCode) && String(it.warehouseCode).trim())
|
|
158
|
+
.filter(Boolean)));
|
|
159
|
+
if (providedWarehouseCodes.length > 0) {
|
|
160
|
+
const warehouses = await tx.getRepository(warehouse_base_1.Warehouse).find({
|
|
161
|
+
where: { domain, name: (0, typeorm_1.In)(providedWarehouseCodes) }
|
|
162
|
+
});
|
|
163
|
+
const foundNames = new Set(warehouses.map(w => w.name));
|
|
164
|
+
const missing = providedWarehouseCodes.filter(code => !foundNames.has(code));
|
|
165
|
+
if (missing.length > 0) {
|
|
166
|
+
throw new error_util_1.ApiError('E04', `warehouseCode not exist in master: ${missing.join(', ')}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
155
169
|
// massage data
|
|
156
170
|
massagedData = await massageOrderItems(releaseGood, bodyReq.orderInventories, context); //double check this function
|
|
157
171
|
const invWithoutBatchId = batchIdStates.withoutBatchId;
|
|
@@ -159,48 +173,195 @@ api_1.restfulApiRouter.post(`/${apiVersion}/warehouse/add-release-order`, middle
|
|
|
159
173
|
if (invWithoutBatchId) {
|
|
160
174
|
// validation
|
|
161
175
|
await Promise.all(massagedData.combinedItems.map(async (item) => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
176
|
+
var _a, _b;
|
|
177
|
+
const hasWarehouse = !!item.warehouseCode;
|
|
178
|
+
if (hasWarehouse) {
|
|
179
|
+
// Validate availability within the specific warehouse across pickable locations (exclude Q/R/D/STORAGE)
|
|
180
|
+
const rows = await tx.query(`
|
|
181
|
+
select
|
|
182
|
+
coalesce(sum(
|
|
183
|
+
case when (iv.qty - greatest(coalesce(iv.locked_qty,0),0) - greatest(coalesce(pds.unassigned_qty,0),0)) < 0
|
|
184
|
+
then 0
|
|
185
|
+
else (iv.qty - greatest(coalesce(iv.locked_qty,0),0) - greatest(coalesce(pds.unassigned_qty,0),0))
|
|
186
|
+
end
|
|
187
|
+
), 0) as total_available_qty,
|
|
188
|
+
coalesce(sum(
|
|
189
|
+
case when (iv.uom_value - greatest(coalesce(iv.locked_uom_value,0),0) - greatest(coalesce(pds.unassigned_uom_value,0),0)) < 0
|
|
190
|
+
then 0
|
|
191
|
+
else (iv.uom_value - greatest(coalesce(iv.locked_uom_value,0),0) - greatest(coalesce(pds.unassigned_uom_value,0),0))
|
|
192
|
+
end
|
|
193
|
+
), 0) as total_available_uom_value
|
|
194
|
+
from inventories iv
|
|
195
|
+
left join product_detail_stocks pds on pds.product_detail_id = iv.product_detail_id
|
|
196
|
+
inner join locations loc on loc.id = iv.location_id
|
|
197
|
+
inner join warehouses w on w.id = loc.warehouse_id
|
|
198
|
+
inner join products p on p.id = iv.product_id
|
|
199
|
+
where iv.domain_id = $1
|
|
200
|
+
and iv.bizplace_id = $2
|
|
201
|
+
and iv.product_id = $3
|
|
202
|
+
and iv.packing_type = $4
|
|
203
|
+
and iv.packing_size = $5
|
|
204
|
+
and iv.uom = $6
|
|
205
|
+
and iv.status = 'STORED'
|
|
206
|
+
and loc.type not in ('QUARANTINE','RESERVE','DAMAGE','STORAGE')
|
|
207
|
+
and iv.obsolete = false
|
|
208
|
+
and (case when iv.expiration_date is not null and p.min_outbound_shelf_life is not null then CURRENT_DATE < iv.expiration_date - p.min_outbound_shelf_life else true end)
|
|
209
|
+
and w.name = $7
|
|
210
|
+
and not exists (
|
|
211
|
+
select 1 from inventories i
|
|
212
|
+
where i.domain_id = $1 and i.bizplace_id = $2 and i.product_id = $3 and i.packing_type = $4 and i.packing_size = $5 and i.uom = $6 and i.status = 'STORED' and i.lock_inventory is true
|
|
213
|
+
)
|
|
214
|
+
`, [
|
|
215
|
+
domain.id,
|
|
216
|
+
customerBizplace.id,
|
|
217
|
+
item.product.id,
|
|
218
|
+
item.packingType,
|
|
219
|
+
item.packingSize,
|
|
220
|
+
item.uom,
|
|
221
|
+
String(item.warehouseCode).trim()
|
|
222
|
+
]);
|
|
223
|
+
const totalQty = parseFloat(((_a = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _a === void 0 ? void 0 : _a.total_available_qty) || '0');
|
|
224
|
+
const totalUomVal = parseFloat(((_b = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _b === void 0 ? void 0 : _b.total_available_uom_value) || '0');
|
|
225
|
+
let reqQty = item.releaseQty;
|
|
226
|
+
let reqUomVal = item.releaseUomValue;
|
|
227
|
+
if (!item.product.isInventoryDecimal) {
|
|
228
|
+
reqQty = Math.round(reqQty);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
reqQty = Math.round(reqQty * 1000) / 1000;
|
|
232
|
+
}
|
|
233
|
+
if (totalQty + 1e-6 < reqQty || totalUomVal + 1e-6 < reqUomVal) {
|
|
234
|
+
throw new error_util_1.ApiError('E01', 'INSUFFICIENT_STOCK');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
// Fallback to existing global view-based validation when no warehouseCode provided
|
|
239
|
+
let itemList = await tx.query(`
|
|
240
|
+
select wboi.*
|
|
241
|
+
from warehouse_bizplace_onhand_inventories wboi
|
|
242
|
+
left join (
|
|
243
|
+
select i2.product_id, i2.domain_id, i2.bizplace_id, i2.packing_type, i2.packing_size, i2.uom,
|
|
244
|
+
sum(i2.qty) as storage_qty,
|
|
245
|
+
sum(i2.uom_value) as storage_uom_value
|
|
246
|
+
from inventories i2
|
|
247
|
+
inner join locations l2 on l2.id = i2.location_id
|
|
248
|
+
inner join warehouses w on w.id = l2.warehouse_id
|
|
249
|
+
where i2.domain_id = $1
|
|
250
|
+
and i2.bizplace_id = $2
|
|
251
|
+
and i2.product_id = $3
|
|
252
|
+
and i2.packing_type = $4
|
|
253
|
+
and i2.packing_size = $5
|
|
254
|
+
and i2.uom = $6
|
|
255
|
+
and i2.status = 'STORED'
|
|
256
|
+
and l2.type = 'STORAGE'
|
|
257
|
+
group by i2.product_id, i2.domain_id, i2.bizplace_id, i2.packing_type, i2.packing_size, i2.uom
|
|
258
|
+
) storageInv
|
|
259
|
+
on storageInv.product_id = wboi.product_id
|
|
260
|
+
and storageInv.domain_id = wboi.domain_id
|
|
261
|
+
and storageInv.bizplace_id = wboi.bizplace_id
|
|
262
|
+
and storageInv.packing_type = wboi.packing_type
|
|
263
|
+
and storageInv.packing_size = wboi.packing_size
|
|
264
|
+
and storageInv.uom = wboi.uom
|
|
265
|
+
left join (
|
|
266
|
+
select i.product_id, i.domain_id, i.bizplace_id, i.packing_type, i.packing_size, i.uom, i.lock_inventory
|
|
267
|
+
from inventories i
|
|
268
|
+
where i.domain_id = $1
|
|
269
|
+
and i.bizplace_id = $2
|
|
270
|
+
and i.product_id = $3
|
|
271
|
+
and i.packing_type = $4
|
|
272
|
+
and i.packing_size = $5
|
|
273
|
+
and i.uom = $6
|
|
274
|
+
and i.status = 'STORED'
|
|
275
|
+
group by i.product_id, i.domain_id, i.bizplace_id, i.packing_type, i.packing_size, i.uom, i.lock_inventory
|
|
276
|
+
) lockInv
|
|
277
|
+
on lockInv.product_id = wboi.product_id
|
|
278
|
+
and lockInv.domain_id = wboi.domain_id
|
|
279
|
+
and lockInv.bizplace_id = wboi.bizplace_id
|
|
280
|
+
and lockInv.packing_type = wboi.packing_type
|
|
281
|
+
and lockInv.packing_size = wboi.packing_size
|
|
282
|
+
and lockInv.uom = wboi.uom
|
|
283
|
+
where wboi.domain_id = $1
|
|
284
|
+
and wboi.bizplace_id = $2
|
|
285
|
+
and wboi.group_type = 'SINGLE'
|
|
286
|
+
and wboi.product_id = $3
|
|
287
|
+
and wboi.packing_type = $4
|
|
288
|
+
and wboi.packing_size = $5
|
|
289
|
+
and wboi.uom = $6
|
|
290
|
+
and lockInv.lock_inventory is not true
|
|
291
|
+
and (wboi.remain_qty - wboi.transfer_qty - coalesce(storageInv.storage_qty, 0)) >= $7
|
|
292
|
+
and (wboi.remain_uom_value - wboi.transfer_uom_value - coalesce(storageInv.storage_uom_value, 0)) >= $8
|
|
293
|
+
`, [
|
|
294
|
+
domain.id,
|
|
295
|
+
customerBizplace.id,
|
|
296
|
+
item.product.id,
|
|
297
|
+
item.packingType,
|
|
298
|
+
item.packingSize,
|
|
299
|
+
item.uom,
|
|
300
|
+
item.releaseQty,
|
|
301
|
+
item.releaseUomValue
|
|
302
|
+
]);
|
|
303
|
+
if (itemList.length <= 0) {
|
|
304
|
+
throw new error_util_1.ApiError('E01', 'INSUFFICIENT_STOCK');
|
|
305
|
+
}
|
|
306
|
+
console.log();
|
|
307
|
+
}
|
|
308
|
+
}));
|
|
309
|
+
}
|
|
310
|
+
// inv with batchId and assignment enabled: validate availability by batch before creating order
|
|
311
|
+
if (!invWithoutBatchId && (worksheetPickingAssignment === null || worksheetPickingAssignment === void 0 ? void 0 : worksheetPickingAssignment.value) === 'true') {
|
|
312
|
+
await Promise.all(massagedData.combinedItems.map(async (item) => {
|
|
313
|
+
var _a;
|
|
314
|
+
const batchId = (item === null || item === void 0 ? void 0 : item.batchId) && item.batchId !== '-' ? String(item.batchId).trim() : null;
|
|
315
|
+
if (!batchId)
|
|
316
|
+
return;
|
|
317
|
+
const warehouseName = (item === null || item === void 0 ? void 0 : item.warehouseCode) ? String(item.warehouseCode).trim() : null;
|
|
318
|
+
const rows = await tx.query(`
|
|
319
|
+
select
|
|
320
|
+
coalesce(sum(
|
|
321
|
+
case when (iv.qty - greatest(coalesce(iv.locked_qty,0),0) - greatest(coalesce(pds.unassigned_qty,0),0)) < 0
|
|
322
|
+
then 0
|
|
323
|
+
else (iv.qty - greatest(coalesce(iv.locked_qty,0),0) - greatest(coalesce(pds.unassigned_qty,0),0))
|
|
324
|
+
end
|
|
325
|
+
), 0) as total_available_qty
|
|
326
|
+
from inventories iv
|
|
327
|
+
left join product_detail_stocks pds on pds.product_detail_id = iv.product_detail_id
|
|
328
|
+
inner join locations loc on loc.id = iv.location_id
|
|
329
|
+
inner join warehouses w on w.id = loc.warehouse_id
|
|
330
|
+
inner join products p on p.id = iv.product_id
|
|
331
|
+
where iv.domain_id = $1
|
|
332
|
+
and iv.bizplace_id = $2
|
|
333
|
+
and iv.product_id = $3
|
|
334
|
+
and iv.packing_type = $4
|
|
335
|
+
and iv.packing_size = $5
|
|
336
|
+
and iv.uom = $6
|
|
337
|
+
and iv.status = 'STORED'
|
|
338
|
+
and loc.type not in ('QUARANTINE','RESERVE','DAMAGE','STORAGE')
|
|
339
|
+
and iv.obsolete = false
|
|
340
|
+
and (case when iv.expiration_date is not null and p.min_outbound_shelf_life is not null then CURRENT_DATE < iv.expiration_date - p.min_outbound_shelf_life else true end)
|
|
341
|
+
and iv.batch_id = $7
|
|
342
|
+
and ( $8::text is null or w.name = $8::text )
|
|
343
|
+
`, [
|
|
191
344
|
domain.id,
|
|
192
345
|
customerBizplace.id,
|
|
193
346
|
item.product.id,
|
|
194
347
|
item.packingType,
|
|
195
348
|
item.packingSize,
|
|
196
349
|
item.uom,
|
|
197
|
-
|
|
198
|
-
|
|
350
|
+
batchId,
|
|
351
|
+
warehouseName
|
|
199
352
|
]);
|
|
200
|
-
|
|
353
|
+
const totalQty = parseFloat(((_a = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _a === void 0 ? void 0 : _a.total_available_qty) || '0');
|
|
354
|
+
let reqQty = item.releaseQty;
|
|
355
|
+
// normalize comparison for decimal vs non-decimal products
|
|
356
|
+
if (!item.product.isInventoryDecimal) {
|
|
357
|
+
reqQty = Math.round(reqQty);
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
reqQty = Math.round(reqQty * 1000) / 1000;
|
|
361
|
+
}
|
|
362
|
+
if (totalQty + 1e-6 < reqQty) {
|
|
201
363
|
throw new error_util_1.ApiError('E01', 'INSUFFICIENT_STOCK');
|
|
202
364
|
}
|
|
203
|
-
console.log();
|
|
204
365
|
}));
|
|
205
366
|
}
|
|
206
367
|
// assignment
|
|
@@ -495,9 +656,14 @@ async function createReleaseGood(releaseGood, orderProducts, bizplace, context,
|
|
|
495
656
|
let resultReleaseGood = await tx.getRepository(sales_base_1.ReleaseGood).save(newReleaseGood);
|
|
496
657
|
let combinedOrderInventories = [];
|
|
497
658
|
let combinedOrderProducts = [];
|
|
498
|
-
|
|
659
|
+
await Promise.all(orderProducts.map(async (orderProduct) => {
|
|
660
|
+
var _a;
|
|
499
661
|
let orderInventories = orderProduct.orderInventories;
|
|
500
|
-
orderProduct = Object.assign(new sales_base_1.OrderProduct(), Object.assign(Object.assign({}, orderProduct), { name: (0, uuid_1.v4)(), domain: domain, bizplace: bizplace, releaseGood: resultReleaseGood, type: sales_base_1.ORDER_TYPES.RELEASE_OF_GOODS, status: sales_base_1.ORDER_PRODUCT_STATUS.ASSIGNED
|
|
662
|
+
orderProduct = Object.assign(new sales_base_1.OrderProduct(), Object.assign(Object.assign({}, orderProduct), { name: (0, uuid_1.v4)(), domain: domain, bizplace: bizplace, releaseGood: resultReleaseGood, type: sales_base_1.ORDER_TYPES.RELEASE_OF_GOODS, status: sales_base_1.ORDER_PRODUCT_STATUS.ASSIGNED,
|
|
663
|
+
// ensure batchId is persisted on order product even when assignment is enabled
|
|
664
|
+
batchId: (orderProduct === null || orderProduct === void 0 ? void 0 : orderProduct.batchId) !== undefined && (orderProduct === null || orderProduct === void 0 ? void 0 : orderProduct.batchId) !== null
|
|
665
|
+
? orderProduct.batchId
|
|
666
|
+
: ((_a = orderInventories === null || orderInventories === void 0 ? void 0 : orderInventories[0]) === null || _a === void 0 ? void 0 : _a.batchId) || '' }));
|
|
501
667
|
let newOrderProduct = await tx.getRepository(sales_base_1.OrderProduct).save(orderProduct);
|
|
502
668
|
combinedOrderProducts.push({
|
|
503
669
|
product: { name: orderProduct.product.name, sku: orderProduct.product.sku },
|
|
@@ -505,6 +671,7 @@ async function createReleaseGood(releaseGood, orderProducts, bizplace, context,
|
|
|
505
671
|
packingSize: orderProduct.packingSize,
|
|
506
672
|
releaseQty: orderProduct.releaseQty,
|
|
507
673
|
releaseUomValue: orderProduct.releaseUomValue,
|
|
674
|
+
warehouseCode: orderProduct.warehouseCode,
|
|
508
675
|
refItemId: orderProduct.refItemId
|
|
509
676
|
});
|
|
510
677
|
if ((worksheetPickingAssignment === null || worksheetPickingAssignment === void 0 ? void 0 : worksheetPickingAssignment.value) !== 'true') {
|
|
@@ -517,7 +684,8 @@ async function createReleaseGood(releaseGood, orderProducts, bizplace, context,
|
|
|
517
684
|
packingType: orderInventory.packingType,
|
|
518
685
|
packingSize: orderInventory.packingSize,
|
|
519
686
|
releaseQty: orderInventory.releaseQty,
|
|
520
|
-
releaseUomValue: orderInventory.releaseUomValue
|
|
687
|
+
releaseUomValue: orderInventory.releaseUomValue,
|
|
688
|
+
warehouseCode: orderInventory.warehouseCode
|
|
521
689
|
});
|
|
522
690
|
}
|
|
523
691
|
}
|
|
@@ -538,19 +706,21 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
538
706
|
inputOrderProducts = await inputOrderProducts.reduce(async (accPromise, itm, idx) => {
|
|
539
707
|
const acc = await accPromise;
|
|
540
708
|
let { sku, refCode } = itm.product;
|
|
541
|
-
let { packingType, packingSize, batchId, releaseQty, sellingPrice, paidAmount, uom, refItemId } = itm;
|
|
709
|
+
let { packingType, packingSize, batchId, releaseQty, sellingPrice, paidAmount, uom, refItemId, warehouseCode } = itm;
|
|
542
710
|
if (!sku && !refCode) {
|
|
543
711
|
throw new error_util_1.ApiError('E01', 'sku or refCode not found');
|
|
544
712
|
}
|
|
545
713
|
if (releaseQty <= 0) {
|
|
546
714
|
throw new error_util_1.ApiError('E01', 'negative stock request');
|
|
547
715
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
(
|
|
551
|
-
(
|
|
552
|
-
(
|
|
553
|
-
(
|
|
716
|
+
const normalizedWarehouseCode = warehouseCode ? String(warehouseCode).trim() : '';
|
|
717
|
+
let existingIndex = acc.findIndex(it => (it === null || it === void 0 ? void 0 : it.sku) == (sku === null || sku === void 0 ? void 0 : sku.trim()) &&
|
|
718
|
+
(it === null || it === void 0 ? void 0 : it.refCode) == (refCode === null || refCode === void 0 ? void 0 : refCode.trim()) &&
|
|
719
|
+
(it === null || it === void 0 ? void 0 : it.packingType) == (packingType === null || packingType === void 0 ? void 0 : packingType.trim()) &&
|
|
720
|
+
(it === null || it === void 0 ? void 0 : it.packingSize) == packingSize &&
|
|
721
|
+
(it === null || it === void 0 ? void 0 : it.uom) == uom &&
|
|
722
|
+
(it === null || it === void 0 ? void 0 : it.batchId) == ((batchId === null || batchId === void 0 ? void 0 : batchId.trim()) || '') &&
|
|
723
|
+
(it === null || it === void 0 ? void 0 : it.warehouseCode) == normalizedWarehouseCode);
|
|
554
724
|
if (existingIndex >= 0 && releaseQty > 0) {
|
|
555
725
|
acc[existingIndex].releaseQty = acc[existingIndex].releaseQty + releaseQty;
|
|
556
726
|
}
|
|
@@ -565,7 +735,8 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
565
735
|
paidAmount: paidAmount,
|
|
566
736
|
uom: uom,
|
|
567
737
|
batchId: (batchId === null || batchId === void 0 ? void 0 : batchId.trim()) || '',
|
|
568
|
-
refItemId: refItemId !== null && refItemId !== void 0 ? refItemId : ''
|
|
738
|
+
refItemId: refItemId !== null && refItemId !== void 0 ? refItemId : '',
|
|
739
|
+
warehouseCode: normalizedWarehouseCode
|
|
569
740
|
});
|
|
570
741
|
}
|
|
571
742
|
return acc;
|
|
@@ -573,7 +744,6 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
573
744
|
//find customer sku in system
|
|
574
745
|
await Promise.all(inputOrderProducts.map(async (inputOrderItem) => {
|
|
575
746
|
const sku = inputOrderItem.sku;
|
|
576
|
-
const uom = inputOrderItem === null || inputOrderItem === void 0 ? void 0 : inputOrderItem.uom;
|
|
577
747
|
const refCode = inputOrderItem.refCode;
|
|
578
748
|
const packingType = inputOrderItem.packingType;
|
|
579
749
|
const packingSize = inputOrderItem.packingSize;
|
|
@@ -608,10 +778,13 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
608
778
|
throw new error_util_1.ApiError('E01', `releaseQty must be an integer for product ${sku || refCode}`);
|
|
609
779
|
}
|
|
610
780
|
let newOrderProduct = Object.assign({}, inputOrderItem);
|
|
611
|
-
newOrderProduct = Object.assign(Object.assign({}, newOrderProduct), { product: productDetail.product, productDetail: productDetail, packingType: productDetail.packingType, packingSize: packingSize || productDetail.packingSize, uom: productDetail.uom, uomValue: productDetail.uomValue, refCode: inputOrderItem.refCode, releaseQty: Math.round(inputOrderItem.releaseQty * 1000) / 1000, releaseUomValue: inputOrderItem.releaseQty * (productDetail.uomValue || 1), packQty: 0, actualPackQty: 0, palletQty: 0, actualPalletQty: 0, type: 'RELEASE_OF_GOODS', status: sales_base_1.ORDER_PRODUCT_STATUS.ASSIGNED, batchId: (inputOrderItem === null || inputOrderItem === void 0 ? void 0 : inputOrderItem.batchId) || '' });
|
|
781
|
+
newOrderProduct = Object.assign(Object.assign({}, newOrderProduct), { product: productDetail.product, productDetail: productDetail, packingType: productDetail.packingType, packingSize: packingSize || productDetail.packingSize, uom: productDetail.uom, uomValue: productDetail.uomValue, refCode: inputOrderItem.refCode, releaseQty: Math.round(inputOrderItem.releaseQty * 1000) / 1000, releaseUomValue: inputOrderItem.releaseQty * (productDetail.uomValue || 1), packQty: 0, actualPackQty: 0, palletQty: 0, actualPalletQty: 0, type: 'RELEASE_OF_GOODS', warehouseCode: (inputOrderItem === null || inputOrderItem === void 0 ? void 0 : inputOrderItem.warehouseCode) || null, status: sales_base_1.ORDER_PRODUCT_STATUS.ASSIGNED, batchId: (inputOrderItem === null || inputOrderItem === void 0 ? void 0 : inputOrderItem.batchId) || '' });
|
|
612
782
|
newOrderProduct.orderInventories = [
|
|
613
|
-
Object.assign(Object.assign({}, newOrderProduct), { packQty: 0, actualPackQty: 0, palletQty: 0, actualPalletQty: 0, type: 'RELEASE_OF_GOODS', status: sales_base_1.ORDER_INVENTORY_STATUS.PENDING_WORKSHEET })
|
|
783
|
+
Object.assign(Object.assign({}, newOrderProduct), { packQty: 0, actualPackQty: 0, palletQty: 0, actualPalletQty: 0, type: 'RELEASE_OF_GOODS', warehouseCode: (inputOrderItem === null || inputOrderItem === void 0 ? void 0 : inputOrderItem.warehouseCode) || null, status: sales_base_1.ORDER_INVENTORY_STATUS.PENDING_WORKSHEET })
|
|
614
784
|
];
|
|
785
|
+
newOrderProduct.warehouseCode = (newOrderProduct === null || newOrderProduct === void 0 ? void 0 : newOrderProduct.warehouseCode)
|
|
786
|
+
? String(newOrderProduct.warehouseCode).trim()
|
|
787
|
+
: null;
|
|
615
788
|
orderProducts.push(newOrderProduct);
|
|
616
789
|
}
|
|
617
790
|
if (!productDetail) {
|
|
@@ -652,6 +825,7 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
652
825
|
actualPalletQty: 0,
|
|
653
826
|
orderInventories: [],
|
|
654
827
|
type: 'RELEASE_OF_GOODS',
|
|
828
|
+
warehouseCode: (inputOrderItem === null || inputOrderItem === void 0 ? void 0 : inputOrderItem.warehouseCode) || null,
|
|
655
829
|
status: sales_base_1.ORDER_PRODUCT_STATUS.ASSIGNED,
|
|
656
830
|
batchId: ''
|
|
657
831
|
};
|
|
@@ -674,6 +848,7 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
674
848
|
bundleProductSetting.bundleQty *
|
|
675
849
|
(productDetailBundle.uomValue <= 0 ? 1 : productDetailBundle.uomValue),
|
|
676
850
|
type: 'RELEASE_OF_GOODS',
|
|
851
|
+
warehouseCode: (inputOrderItem === null || inputOrderItem === void 0 ? void 0 : inputOrderItem.warehouseCode) || null,
|
|
677
852
|
status: sales_base_1.ORDER_INVENTORY_STATUS.PENDING_WORKSHEET
|
|
678
853
|
};
|
|
679
854
|
orderProduct.orderInventories.push(newOrderInventory);
|
|
@@ -698,7 +873,7 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
698
873
|
let oi = (op === null || op === void 0 ? void 0 : op.orderInventories) || [];
|
|
699
874
|
oi.forEach(itm => {
|
|
700
875
|
let { sku, refCode } = itm.product;
|
|
701
|
-
let { packingType, packingSize, batchId, releaseQty, product, productDetail, uom } = itm;
|
|
876
|
+
let { packingType, packingSize, batchId, releaseQty, product, productDetail, uom, warehouseCode } = itm;
|
|
702
877
|
if (!sku && !refCode) {
|
|
703
878
|
throw new error_util_1.ApiError('E04', t('error.sku or refCode not found'));
|
|
704
879
|
}
|
|
@@ -707,7 +882,8 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
707
882
|
(itm === null || itm === void 0 ? void 0 : itm.packingType) == (packingType === null || packingType === void 0 ? void 0 : packingType.trim()) &&
|
|
708
883
|
(itm === null || itm === void 0 ? void 0 : itm.packingSize) == packingSize &&
|
|
709
884
|
(itm === null || itm === void 0 ? void 0 : itm.batchId) == (batchId === null || batchId === void 0 ? void 0 : batchId.trim()) &&
|
|
710
|
-
(itm === null || itm === void 0 ? void 0 : itm.uom) == (uom === null || uom === void 0 ? void 0 : uom.trim())
|
|
885
|
+
(itm === null || itm === void 0 ? void 0 : itm.uom) == (uom === null || uom === void 0 ? void 0 : uom.trim()) &&
|
|
886
|
+
(itm === null || itm === void 0 ? void 0 : itm.warehouseCode) == (warehouseCode ? String(warehouseCode).trim() : warehouseCode));
|
|
711
887
|
if (existingIndex >= 0 && releaseQty > 0) {
|
|
712
888
|
acc[existingIndex].releaseQty = acc[existingIndex].releaseQty + releaseQty;
|
|
713
889
|
acc[existingIndex].releaseUomValue =
|
|
@@ -727,6 +903,8 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
727
903
|
if (refCode)
|
|
728
904
|
updateObj['refCode'] = refCode.trim();
|
|
729
905
|
updateObj['batchId'] = batchId ? batchId === null || batchId === void 0 ? void 0 : batchId.trim() : '-';
|
|
906
|
+
if (warehouseCode)
|
|
907
|
+
updateObj['warehouseCode'] = String(warehouseCode).trim();
|
|
730
908
|
acc.push(updateObj);
|
|
731
909
|
}
|
|
732
910
|
});
|
|
@@ -774,7 +952,8 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
774
952
|
return { orderProducts, combinedItems };
|
|
775
953
|
}
|
|
776
954
|
async function assignToInventory(orderProducts, customerBizplace, context, tx, worksheetPickingAssignment) {
|
|
777
|
-
|
|
955
|
+
var _a, _b;
|
|
956
|
+
const { domain, user } = context.state;
|
|
778
957
|
const pickingProductSetting = await tx.getRepository(setting_base_1.Setting).findOne({
|
|
779
958
|
where: { domain, name: 'rule-for-picking-product' }
|
|
780
959
|
});
|
|
@@ -884,8 +1063,12 @@ async function assignToInventory(orderProducts, customerBizplace, context, tx, w
|
|
|
884
1063
|
];
|
|
885
1064
|
let batchId = orderInventory[oiIdx].batchId;
|
|
886
1065
|
if (batchId)
|
|
887
|
-
params.push(batchId);
|
|
1066
|
+
params.push(String(batchId).trim());
|
|
888
1067
|
params = [...params, ...queryStrings.values];
|
|
1068
|
+
const warehouseNameFilter = ((_a = orderInventory[oiIdx]) === null || _a === void 0 ? void 0 : _a.warehouseCode) ? `AND w.name = $${params.length + 1}` : '';
|
|
1069
|
+
if ((_b = orderInventory[oiIdx]) === null || _b === void 0 ? void 0 : _b.warehouseCode) {
|
|
1070
|
+
params.push(String(orderInventory[oiIdx].warehouseCode).trim());
|
|
1071
|
+
}
|
|
889
1072
|
let query = `
|
|
890
1073
|
update inventories tgt set locked_qty = coalesce(locked_qty,0) + src.reserve_qty,
|
|
891
1074
|
locked_uom_value = coalesce(locked_uom_value,0) + src.reserve_uom_value,
|
|
@@ -920,11 +1103,13 @@ async function assignToInventory(orderProducts, customerBizplace, context, tx, w
|
|
|
920
1103
|
FROM "inventories" "iv"
|
|
921
1104
|
LEFT JOIN "product_detail_stocks" "pds" ON "pds"."product_detail_id" = "iv"."product_detail_id"
|
|
922
1105
|
INNER JOIN "locations" "loc" ON "loc"."id"="iv"."location_id"
|
|
1106
|
+
INNER JOIN "warehouses" "w" ON "w"."id" = "loc"."warehouse_id"
|
|
923
1107
|
INNER JOIN "products" "p" ON "p"."id"="iv"."product_id"
|
|
924
1108
|
INNER JOIN "warehouse_inventory_assignment_rankings" "wiar" ON "wiar"."location_type"="loc"."type"
|
|
925
1109
|
WHERE case when coalesce("iv"."locked_qty",0) < 0 then 0 else ("iv"."qty" - coalesce("iv"."locked_qty",0)) end > 0 AND
|
|
926
1110
|
"iv"."domain_id" = $2 AND "iv"."bizplace_id" = $3 AND "iv"."packing_type" = $4 AND "iv"."packing_size" = $5 AND "iv"."product_id" = $6 AND "iv"."status" = $7 AND "loc"."type" NOT IN ($8, $9, $10)
|
|
927
1111
|
AND ${batchId ? `"iv"."batch_id" = $11` : `1=1`}
|
|
1112
|
+
${warehouseNameFilter}
|
|
928
1113
|
AND "iv"."obsolete" = false AND case when "iv"."expiration_date" is not null and "p"."min_outbound_shelf_life" is not null then CURRENT_DATE < "iv"."expiration_date" - "p"."min_outbound_shelf_life" else true end
|
|
929
1114
|
${queryStrings.query.length > 0 ? `AND ${queryStrings.join(' AND ')}` : ''}
|
|
930
1115
|
ORDER BY wiar.rank ${sortQuery ? ', ' + sortQuery : ''}
|
|
@@ -948,7 +1133,7 @@ async function assignToInventory(orderProducts, customerBizplace, context, tx, w
|
|
|
948
1133
|
productId: orderInventory[oiIdx].product.id || ''
|
|
949
1134
|
},
|
|
950
1135
|
result: updatedInventories[0] || '',
|
|
951
|
-
location: 'add-release-order
|
|
1136
|
+
location: 'add-release-order v1 assignInventory',
|
|
952
1137
|
time: new Date()
|
|
953
1138
|
});
|
|
954
1139
|
let totalAssigned = updatedInventories[0].reduce((acc, inv) => {
|