@things-factory/operato-hub 4.3.248 → 4.3.249
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/config.development.js +105 -77
- package/dist-server/routers/api/restful-apis/unstable/add-release-order.js +156 -133
- package/dist-server/routers/api/restful-apis/unstable/add-release-order.js.map +1 -1
- package/dist-server/routers/api/restful-apis/v1/warehouse/add-release-order.js +146 -123
- package/dist-server/routers/api/restful-apis/v1/warehouse/add-release-order.js.map +1 -1
- package/package.json +5 -5
- package/server/routers/api/restful-apis/unstable/add-release-order.ts +218 -172
- package/server/routers/api/restful-apis/v1/warehouse/add-release-order.ts +207 -161
|
@@ -35,11 +35,12 @@ import {
|
|
|
35
35
|
OrderNoGenerator,
|
|
36
36
|
OrderProduct,
|
|
37
37
|
ReleaseGood,
|
|
38
|
-
SellercraftController
|
|
38
|
+
SellercraftController,
|
|
39
|
+
ORDER_METHOD
|
|
39
40
|
} from '@things-factory/sales-base'
|
|
40
41
|
import { Setting } from '@things-factory/setting-base'
|
|
41
42
|
import { Domain } from '@things-factory/shell'
|
|
42
|
-
import { Inventory, INVENTORY_STATUS, LOCATION_TYPE } from '@things-factory/warehouse-base'
|
|
43
|
+
import { Inventory, INVENTORY_STATUS, LOCATION_TYPE, ProductDetailStock } from '@things-factory/warehouse-base'
|
|
43
44
|
import { LastMileDelivery } from '@things-factory/integration-lmd'
|
|
44
45
|
|
|
45
46
|
import { ValidationError } from '../../../../errors/index'
|
|
@@ -80,6 +81,10 @@ router.post(
|
|
|
80
81
|
relations: ['domain']
|
|
81
82
|
})
|
|
82
83
|
|
|
84
|
+
const worksheetPickingAssignment: Setting = await tx.getRepository(Setting).findOne({
|
|
85
|
+
where: { domain, category: 'id-rule', name: 'enable-worksheet-picking-activation-assignment' }
|
|
86
|
+
})
|
|
87
|
+
|
|
83
88
|
releaseGood = {
|
|
84
89
|
domain,
|
|
85
90
|
bizplace: customerBizplace,
|
|
@@ -128,7 +133,8 @@ router.post(
|
|
|
128
133
|
discountAmount: bodyReq?.discountAmount,
|
|
129
134
|
taxAmount: bodyReq?.taxAmount,
|
|
130
135
|
shippingFee: bodyReq?.shippingFee,
|
|
131
|
-
lmdOption: bodyReq?.lmdOption
|
|
136
|
+
lmdOption: bodyReq?.lmdOption,
|
|
137
|
+
assignedInventory: worksheetPickingAssignment?.value == 'true' ? false : true
|
|
132
138
|
}
|
|
133
139
|
|
|
134
140
|
// check existing order
|
|
@@ -199,12 +205,25 @@ router.post(
|
|
|
199
205
|
}
|
|
200
206
|
// assignment
|
|
201
207
|
// console.time('assign')
|
|
202
|
-
let assignedOrderProducts = await assignToInventory(
|
|
208
|
+
let assignedOrderProducts = await assignToInventory(
|
|
209
|
+
massagedData.orderProducts,
|
|
210
|
+
customerBizplace,
|
|
211
|
+
context,
|
|
212
|
+
tx,
|
|
213
|
+
worksheetPickingAssignment
|
|
214
|
+
)
|
|
203
215
|
// console.timeEnd('assign')
|
|
204
216
|
|
|
205
217
|
// create order
|
|
206
218
|
// console.time('save')
|
|
207
|
-
let result = await createReleaseGood(
|
|
219
|
+
let result = await createReleaseGood(
|
|
220
|
+
releaseGood,
|
|
221
|
+
assignedOrderProducts,
|
|
222
|
+
customerBizplace,
|
|
223
|
+
context,
|
|
224
|
+
tx,
|
|
225
|
+
worksheetPickingAssignment
|
|
226
|
+
)
|
|
208
227
|
// console.timeEnd('save')
|
|
209
228
|
|
|
210
229
|
let addReleaseGood = {
|
|
@@ -474,7 +493,8 @@ async function createReleaseGood(
|
|
|
474
493
|
orderProducts: OrderProduct[],
|
|
475
494
|
bizplace: Bizplace,
|
|
476
495
|
context: any,
|
|
477
|
-
tx?: EntityManager
|
|
496
|
+
tx?: EntityManager,
|
|
497
|
+
worksheetPickingAssignment?: any
|
|
478
498
|
): Promise<ReleaseGood> {
|
|
479
499
|
try {
|
|
480
500
|
const { domain, user }: { domain: Domain; user: User } = context.state
|
|
@@ -576,7 +596,9 @@ async function createReleaseGood(
|
|
|
576
596
|
creator: user,
|
|
577
597
|
updater: user,
|
|
578
598
|
acceptedBy: user,
|
|
579
|
-
acceptedAt: new Date()
|
|
599
|
+
acceptedAt: new Date(),
|
|
600
|
+
assignedInventory: worksheetPickingAssignment?.value == 'true' ? false : true,
|
|
601
|
+
orderMethod: ORDER_METHOD.SELECT_BY_PRODUCT
|
|
580
602
|
}
|
|
581
603
|
|
|
582
604
|
let resultReleaseGood = await tx.getRepository(ReleaseGood).save(newReleaseGood)
|
|
@@ -595,27 +617,29 @@ async function createReleaseGood(
|
|
|
595
617
|
})
|
|
596
618
|
let result = await tx.getRepository(OrderProduct).save(orderProduct)
|
|
597
619
|
|
|
598
|
-
|
|
599
|
-
let
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
620
|
+
if (worksheetPickingAssignment.value !== 'true') {
|
|
621
|
+
for (let oiIdx = 0; oiIdx < orderInventories.length; oiIdx++) {
|
|
622
|
+
let orderInventory = Object.assign(new OrderInventory(), {
|
|
623
|
+
...orderInventories[oiIdx],
|
|
624
|
+
name: uuidv4(),
|
|
625
|
+
domain: domain,
|
|
626
|
+
bizplace: bizplace,
|
|
627
|
+
releaseGood: resultReleaseGood,
|
|
628
|
+
type: ORDER_TYPES.RELEASE_OF_GOODS,
|
|
629
|
+
status: ORDER_INVENTORY_STATUS.PENDING_WORKSHEET,
|
|
630
|
+
orderProduct: result
|
|
631
|
+
})
|
|
632
|
+
await tx.getRepository(OrderInventory).save(orderInventory)
|
|
633
|
+
|
|
634
|
+
combinedOrderInventories.push({
|
|
635
|
+
product: { name: orderInventory.product.name, sku: orderInventory.product.sku },
|
|
636
|
+
batchId: orderInventory.batchId,
|
|
637
|
+
packingType: orderInventory.packingType,
|
|
638
|
+
packingSize: orderInventory.packingSize,
|
|
639
|
+
releaseQty: orderInventory.releaseQty,
|
|
640
|
+
releaseUomValue: orderInventory.releaseUomValue
|
|
641
|
+
})
|
|
642
|
+
}
|
|
619
643
|
}
|
|
620
644
|
|
|
621
645
|
return result
|
|
@@ -951,116 +975,125 @@ async function massageOrderItems(
|
|
|
951
975
|
}
|
|
952
976
|
}
|
|
953
977
|
|
|
954
|
-
async function assignToInventory(
|
|
978
|
+
async function assignToInventory(
|
|
979
|
+
orderProducts: OrderProduct[],
|
|
980
|
+
customerBizplace,
|
|
981
|
+
context,
|
|
982
|
+
tx,
|
|
983
|
+
worksheetPickingAssignment
|
|
984
|
+
) {
|
|
955
985
|
const { client, domain, user } = context.state
|
|
986
|
+
|
|
987
|
+
const pickingProductSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
988
|
+
where: { domain, name: 'rule-for-picking-product' }
|
|
989
|
+
})
|
|
990
|
+
|
|
956
991
|
for (let opIdx = 0; opIdx < orderProducts.length; opIdx++) {
|
|
957
992
|
let orderProduct = orderProducts[opIdx]
|
|
958
993
|
|
|
959
994
|
let assignedOrderInventories = []
|
|
960
|
-
const pickingProductSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
961
|
-
where: { domain, name: 'rule-for-picking-product' }
|
|
962
|
-
})
|
|
963
995
|
|
|
964
996
|
for (let oiIdx = 0; oiIdx < orderProducts[opIdx].orderInventories.length; oiIdx++) {
|
|
965
997
|
const orderInventory = orderProduct.orderInventories[oiIdx]
|
|
966
998
|
let sortings: any = []
|
|
967
999
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1000
|
+
if (worksheetPickingAssignment?.value !== 'true') {
|
|
1001
|
+
switch (orderInventory.product.pickingStrategy) {
|
|
1002
|
+
case 'LIFO':
|
|
1003
|
+
sortings.push({ name: 'iv.created_at', desc: true })
|
|
1004
|
+
if (pickingProductSetting?.value) {
|
|
1005
|
+
for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
|
|
1006
|
+
sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
|
|
1007
|
+
}
|
|
1008
|
+
} else {
|
|
1009
|
+
sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
|
|
974
1010
|
}
|
|
975
|
-
} else {
|
|
976
|
-
sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
|
|
977
|
-
}
|
|
978
1011
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1012
|
+
break
|
|
1013
|
+
case 'FEFO':
|
|
1014
|
+
sortings.push({ name: 'iv.expiration_date', desc: false }, { name: 'iv.created_at', desc: false })
|
|
1015
|
+
if (pickingProductSetting?.value) {
|
|
1016
|
+
for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
|
|
1017
|
+
sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
|
|
1018
|
+
}
|
|
1019
|
+
} else {
|
|
1020
|
+
sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
|
|
985
1021
|
}
|
|
986
|
-
} else {
|
|
987
|
-
sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
|
|
988
|
-
}
|
|
989
1022
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1023
|
+
break
|
|
1024
|
+
case 'FMFO':
|
|
1025
|
+
sortings.push({ name: 'iv.manufacture_date', desc: false }, { name: 'iv.created_at', desc: false })
|
|
1026
|
+
if (pickingProductSetting?.value) {
|
|
1027
|
+
for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
|
|
1028
|
+
sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
|
|
1029
|
+
}
|
|
1030
|
+
} else {
|
|
1031
|
+
sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
|
|
996
1032
|
}
|
|
997
|
-
} else {
|
|
998
|
-
sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
|
|
999
|
-
}
|
|
1000
1033
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1034
|
+
break
|
|
1035
|
+
case 'LOCATION':
|
|
1036
|
+
if (pickingProductSetting?.value) {
|
|
1037
|
+
for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
|
|
1038
|
+
sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
|
|
1039
|
+
}
|
|
1040
|
+
} else {
|
|
1041
|
+
sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
|
|
1006
1042
|
}
|
|
1007
|
-
} else {
|
|
1008
|
-
sortings.push({ name: 'loc.name', desc: false }, { name: 'iv.created_at', desc: false })
|
|
1009
|
-
}
|
|
1010
1043
|
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1044
|
+
break
|
|
1045
|
+
//Every other case includes 'FIFO' will be applicable for this case
|
|
1046
|
+
default:
|
|
1047
|
+
sortings.push({ name: 'iv.created_at', desc: false })
|
|
1048
|
+
if (pickingProductSetting?.value) {
|
|
1049
|
+
for (const [key, value] of Object.entries(JSON.parse(pickingProductSetting.value))) {
|
|
1050
|
+
sortings.push({ name: `loc.${key}`, desc: value == 'DESC' ? true : false })
|
|
1051
|
+
}
|
|
1052
|
+
} else {
|
|
1053
|
+
sortings.push({ name: 'loc.name', desc: false })
|
|
1054
|
+
sortings.push({ name: 'iv.pallet_id', desc: false })
|
|
1018
1055
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
sortings.push({ name: 'iv.pallet_id', desc: false })
|
|
1022
|
-
}
|
|
1023
|
-
break
|
|
1024
|
-
}
|
|
1056
|
+
break
|
|
1057
|
+
}
|
|
1025
1058
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1059
|
+
let queryFilters = []
|
|
1060
|
+
|
|
1061
|
+
let queryStrings = queryFilters.reduce(
|
|
1062
|
+
(acc, itm, idx, arr) => {
|
|
1063
|
+
acc.values.push(itm.filters)
|
|
1064
|
+
|
|
1065
|
+
switch (itm?.operator) {
|
|
1066
|
+
case 'notin':
|
|
1067
|
+
case 'in':
|
|
1068
|
+
acc.query.push(
|
|
1069
|
+
`${itm.query} ${itm.operator == 'notin' ? 'NOT IN' : 'IN'} (${itm.filtes
|
|
1070
|
+
.map((itm, idx) => {
|
|
1071
|
+
return `$${acc.values.length + 1}`
|
|
1072
|
+
})
|
|
1073
|
+
.join(',')})`
|
|
1074
|
+
)
|
|
1075
|
+
break
|
|
1043
1076
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1077
|
+
default:
|
|
1078
|
+
acc.query.push(`${itm.query} ${itm?.operator ? itm.operator : '='} $${acc.values.length + 1}`)
|
|
1079
|
+
break
|
|
1080
|
+
}
|
|
1081
|
+
acc.query.push(`${itm.query} ${itm?.operator ? itm.operator : '='} $${acc.values.length + 1}`)
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
query: [],
|
|
1085
|
+
values: []
|
|
1047
1086
|
}
|
|
1048
|
-
|
|
1049
|
-
},
|
|
1050
|
-
{
|
|
1051
|
-
query: [],
|
|
1052
|
-
values: []
|
|
1053
|
-
}
|
|
1054
|
-
)
|
|
1087
|
+
)
|
|
1055
1088
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1089
|
+
let sortQuery = sortings
|
|
1090
|
+
.map(itm => {
|
|
1091
|
+
return `${itm.name} ${itm.desc ? 'DESC' : 'ASC'}`
|
|
1092
|
+
})
|
|
1093
|
+
.join(`,`)
|
|
1061
1094
|
|
|
1062
|
-
|
|
1063
|
-
|
|
1095
|
+
let updatedInventories = await tx.getRepository(Inventory).query(
|
|
1096
|
+
`
|
|
1064
1097
|
update inventories tgt set locked_qty = coalesce(locked_qty,0) + src.reserve_qty,
|
|
1065
1098
|
locked_uom_value = coalesce(locked_uom_value,0) + src.reserve_uom_value,
|
|
1066
1099
|
updated_at = NOW(),
|
|
@@ -1073,14 +1106,14 @@ async function assignToInventory(orderProducts: OrderProduct[], customerBizplace
|
|
|
1073
1106
|
case when "lock_amount" < 0 then "available_qty" else "available_qty" - "lock_amount" end as "reserve_qty"
|
|
1074
1107
|
from (
|
|
1075
1108
|
select *,
|
|
1076
|
-
qty - locked_qty as available_qty,
|
|
1077
|
-
sum(qty - locked_qty - release_qty) over (order by sort_seq asc rows between unbounded preceding and current row) as lock_amount
|
|
1109
|
+
qty - locked_qty - unassigned_qty as available_qty,
|
|
1110
|
+
sum(qty - locked_qty - release_qty - unassigned_qty) over (order by sort_seq asc rows between unbounded preceding and current row) as lock_amount
|
|
1078
1111
|
from (
|
|
1079
1112
|
SELECT 0 as sort_seq, null as id, null as pallet_id, null as batch_id, null as batch_id_ref,
|
|
1080
1113
|
null as unit, '${orderInventory.uom}' as uom, '${orderInventory.packingType}' as packing_type, '${
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
null as manufacture_year, null as carton_id, 0 as uom_value, 0 as locked_uom_value, 0 as qty, 0 as locked_qty, null as created_at,
|
|
1114
|
+
orderInventory.packingSize
|
|
1115
|
+
}' as packing_size,
|
|
1116
|
+
null as manufacture_year, null as carton_id, 0 as uom_value, 0 as locked_uom_value, 0 as qty, 0 as locked_qty, 0 as unassigned_uom_value, 0 as unassigned_qty, null as created_at,
|
|
1084
1117
|
'${orderInventory.releaseQty}' as release_qty, '${orderInventory.releaseUomValue}' as release_uom_value
|
|
1085
1118
|
UNION
|
|
1086
1119
|
(
|
|
@@ -1090,9 +1123,10 @@ async function assignToInventory(orderProducts: OrderProduct[], customerBizplace
|
|
|
1090
1123
|
iv.id, iv.pallet_id, iv.batch_id, iv.batch_id_ref,
|
|
1091
1124
|
iv.unit, iv.uom, iv.packing_type, iv.packing_size,
|
|
1092
1125
|
iv.manufacture_year, iv.carton_id, iv.uom_value,
|
|
1093
|
-
coalesce(iv.locked_uom_value,0) as locked_uom_value, iv.qty, coalesce(iv.locked_qty,0) as locked_qty, iv.created_at,
|
|
1126
|
+
coalesce(iv.locked_uom_value,0) as locked_uom_value, iv.qty, coalesce(iv.locked_qty,0) as locked_qty, coalesce(pds.unassigned_uom_value,0) as unassigned_uom_value, coalesce(pds.unassigned_qty,0) as unassigned_qty, iv.created_at,
|
|
1094
1127
|
0 as release_qty, 0 as release_uom_value
|
|
1095
1128
|
FROM "inventories" "iv"
|
|
1129
|
+
LEFT JOIN "product_detail_stocks" "pds" ON "pds"."product_detail_id" = "iv"."product_detail_id"
|
|
1096
1130
|
INNER JOIN "locations" "loc" ON "loc"."id"="iv"."location_id"
|
|
1097
1131
|
INNER JOIN "products" "p" ON "p"."id"="iv"."product_id"
|
|
1098
1132
|
INNER JOIN "warehouse_inventory_assignment_rankings" "wiar" ON "wiar"."location_type"="loc"."type"
|
|
@@ -1110,63 +1144,75 @@ async function assignToInventory(orderProducts: OrderProduct[], customerBizplace
|
|
|
1110
1144
|
tgt."id", tgt."qty", tgt."pallet_id", tgt."carton_id", tgt."batch_id", tgt."batch_id_ref", tgt."unit",
|
|
1111
1145
|
tgt."uom", tgt."packing_type", tgt."packing_size", tgt."manufacture_year",
|
|
1112
1146
|
tgt."locked_qty", tgt."uom_value", tgt."locked_uom_value", src."reserve_qty", src."reserve_uom_value";`,
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1147
|
+
[
|
|
1148
|
+
user.id,
|
|
1149
|
+
domain.id,
|
|
1150
|
+
customerBizplace.id,
|
|
1151
|
+
orderInventory.packingType,
|
|
1152
|
+
orderInventory.packingSize,
|
|
1153
|
+
orderInventory.product.id,
|
|
1154
|
+
INVENTORY_STATUS.STORED,
|
|
1155
|
+
LOCATION_TYPE.QUARANTINE,
|
|
1156
|
+
LOCATION_TYPE.RESERVE,
|
|
1157
|
+
LOCATION_TYPE.STORAGE,
|
|
1158
|
+
...queryStrings.values
|
|
1159
|
+
]
|
|
1160
|
+
)
|
|
1127
1161
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
if (orderInventory.releaseQty != totalAssigned) {
|
|
1133
|
-
throw new ValidationError({
|
|
1134
|
-
errorCode: 'INSUFFICIENT_STOCK',
|
|
1135
|
-
message: 'insufficient stock',
|
|
1136
|
-
detail: JSON.stringify({
|
|
1137
|
-
code: 'insufficient stock',
|
|
1138
|
-
sku: orderInventory.product.sku,
|
|
1139
|
-
packingType: orderInventory.packingType,
|
|
1140
|
-
packingSize: orderInventory.packingSize,
|
|
1141
|
-
uom: orderInventory.uom,
|
|
1142
|
-
qty: orderInventory.releaseQty,
|
|
1143
|
-
uom_value: orderInventory.releaseUomValue
|
|
1144
|
-
})
|
|
1145
|
-
})
|
|
1146
|
-
}
|
|
1162
|
+
let totalAssigned = updatedInventories[0].reduce((acc, inv) => {
|
|
1163
|
+
return acc + inv.reserve_qty
|
|
1164
|
+
}, 0)
|
|
1147
1165
|
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
bizplace: { id: customerBizplace.id }
|
|
1166
|
+
if (orderInventory.releaseQty != totalAssigned) {
|
|
1167
|
+
throw new ValidationError({
|
|
1168
|
+
errorCode: 'INSUFFICIENT_STOCK',
|
|
1169
|
+
message: 'insufficient stock',
|
|
1170
|
+
detail: JSON.stringify({
|
|
1171
|
+
code: 'insufficient stock',
|
|
1172
|
+
sku: orderInventory.product.sku,
|
|
1173
|
+
packingType: orderInventory.packingType,
|
|
1174
|
+
packingSize: orderInventory.packingSize,
|
|
1175
|
+
uom: orderInventory.uom,
|
|
1176
|
+
qty: orderInventory.releaseQty,
|
|
1177
|
+
uom_value: orderInventory.releaseUomValue
|
|
1178
|
+
})
|
|
1179
|
+
})
|
|
1163
1180
|
}
|
|
1164
1181
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1182
|
+
updatedInventories[0].forEach(inv => {
|
|
1183
|
+
let oi = {
|
|
1184
|
+
...orderInventory,
|
|
1185
|
+
inventory: { id: inv.id },
|
|
1186
|
+
uom: inv.uom,
|
|
1187
|
+
packingType: inv.packing_type,
|
|
1188
|
+
batchId: inv.batch_id,
|
|
1189
|
+
releaseQty: inv.reserve_qty,
|
|
1190
|
+
releaseUomValue: inv.reserve_uom_value,
|
|
1191
|
+
pickedQty: 0,
|
|
1192
|
+
packedQty: 0,
|
|
1193
|
+
type: ORDER_TYPES.RELEASE_OF_GOODS,
|
|
1194
|
+
status: ORDER_INVENTORY_STATUS.PENDING_WORKSHEET,
|
|
1195
|
+
domain: { id: domain.id },
|
|
1196
|
+
bizplace: { id: customerBizplace.id }
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
assignedOrderInventories.push(oi)
|
|
1200
|
+
})
|
|
1168
1201
|
|
|
1169
|
-
|
|
1202
|
+
orderProducts[opIdx].orderInventories = assignedOrderInventories
|
|
1203
|
+
} else {
|
|
1204
|
+
await tx
|
|
1205
|
+
.getRepository(ProductDetailStock)
|
|
1206
|
+
.createQueryBuilder()
|
|
1207
|
+
.update(ProductDetailStock)
|
|
1208
|
+
.set({
|
|
1209
|
+
unassignedQty: () => `"unassigned_qty" + ${orderInventory.releaseQty}`,
|
|
1210
|
+
unassignedUomValue: () => `"unassigned_uom_value" + ${orderInventory.releaseUomValue}`
|
|
1211
|
+
})
|
|
1212
|
+
.where({ productDetail: orderInventory.productDetail.id })
|
|
1213
|
+
.execute()
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1170
1216
|
}
|
|
1171
1217
|
|
|
1172
1218
|
return orderProducts
|