@things-factory/sales-base 4.3.639 → 4.3.642
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/service/arrival-notice/arrival-notice-mutation.js +33 -2
- package/dist-server/service/arrival-notice/arrival-notice-mutation.js.map +1 -1
- package/dist-server/service/arrival-notice/arrival-notice-query.js +10 -3
- package/dist-server/service/arrival-notice/arrival-notice-query.js.map +1 -1
- package/dist-server/service/arrival-notice/arrival-notice-types.js +2 -2
- package/dist-server/service/arrival-notice/arrival-notice-types.js.map +1 -1
- package/dist-server/service/inventory-check-item/inventory-check-item-types.js +48 -12
- package/dist-server/service/inventory-check-item/inventory-check-item-types.js.map +1 -1
- package/dist-server/service/inventory-check-item/inventory-check-item.js +56 -4
- package/dist-server/service/inventory-check-item/inventory-check-item.js.map +1 -1
- package/dist-server/service/order-inventory/order-inventory-query.js +5 -1
- package/dist-server/service/order-inventory/order-inventory-query.js.map +1 -1
- package/dist-server/service/order-inventory/order-inventory-types.js +12 -12
- package/dist-server/service/order-inventory/order-inventory-types.js.map +1 -1
- package/dist-server/service/order-inventory/order-inventory.js +189 -13
- package/dist-server/service/order-inventory/order-inventory.js.map +1 -1
- package/dist-server/service/order-package-item/order-package-item-types.js +14 -2
- package/dist-server/service/order-package-item/order-package-item-types.js.map +1 -1
- package/dist-server/service/order-package-item/order-package-item.js +28 -2
- package/dist-server/service/order-package-item/order-package-item.js.map +1 -1
- package/dist-server/service/order-product/order-product-types.js +18 -18
- package/dist-server/service/order-product/order-product-types.js.map +1 -1
- package/dist-server/service/order-product/order-product.js +104 -13
- package/dist-server/service/order-product/order-product.js.map +1 -1
- package/dist-server/service/order-tote-item/order-tote-item-types.js +2 -2
- package/dist-server/service/order-tote-item/order-tote-item-types.js.map +1 -1
- package/dist-server/service/order-tote-item/order-tote-item.js +15 -1
- package/dist-server/service/order-tote-item/order-tote-item.js.map +1 -1
- package/dist-server/service/others/other-query.js +4 -4
- package/dist-server/service/others/other-query.js.map +1 -1
- package/dist-server/service/others/other-types.js +8 -4
- package/dist-server/service/others/other-types.js.map +1 -1
- package/dist-server/service/release-good/release-good-mutation.js +35 -6
- package/dist-server/service/release-good/release-good-mutation.js.map +1 -1
- package/dist-server/service/release-good/release-good-query.js +23 -11
- package/dist-server/service/release-good/release-good-query.js.map +1 -1
- package/dist-server/service/release-good/release-good-types.js +1 -1
- package/dist-server/service/release-good/release-good-types.js.map +1 -1
- package/dist-server/utils/inventory-util.js +18 -14
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +8 -8
- package/server/service/arrival-notice/arrival-notice-mutation.ts +39 -2
- package/server/service/arrival-notice/arrival-notice-query.ts +40 -68
- package/server/service/arrival-notice/arrival-notice-types.ts +4 -4
- package/server/service/inventory-check-item/inventory-check-item-types.ts +37 -10
- package/server/service/inventory-check-item/inventory-check-item.ts +52 -4
- package/server/service/order-inventory/order-inventory-query.ts +5 -0
- package/server/service/order-inventory/order-inventory-types.ts +12 -12
- package/server/service/order-inventory/order-inventory.ts +171 -13
- package/server/service/order-package-item/order-package-item-types.ts +12 -3
- package/server/service/order-package-item/order-package-item.ts +26 -2
- package/server/service/order-product/order-product-types.ts +18 -18
- package/server/service/order-product/order-product.ts +96 -12
- package/server/service/order-tote-item/order-tote-item-types.ts +3 -3
- package/server/service/order-tote-item/order-tote-item.ts +14 -1
- package/server/service/others/other-query.ts +8 -8
- package/server/service/others/other-types.ts +7 -4
- package/server/service/release-good/release-good-mutation.ts +51 -9
- package/server/service/release-good/release-good-query.ts +30 -14
- package/server/service/release-good/release-good-types.ts +1 -1
- package/server/utils/inventory-util.ts +50 -60
|
@@ -66,6 +66,40 @@ import { ReleaseGood } from './release-good'
|
|
|
66
66
|
import { bulkReleaseGoodsAvailableItemsFunction } from './release-good-query'
|
|
67
67
|
import { getTmsService } from '@things-factory/integration-lmd'
|
|
68
68
|
|
|
69
|
+
// Utility function for safe decimal arithmetic
|
|
70
|
+
function safeDecimalOperation(value1: number, value2: number, operation: 'add' | 'subtract' | 'multiply'): number {
|
|
71
|
+
// Convert to string with fixed precision to avoid floating point issues
|
|
72
|
+
const num1 = parseFloat(value1.toFixed(3))
|
|
73
|
+
const num2 = parseFloat(value2.toFixed(3))
|
|
74
|
+
|
|
75
|
+
let result: number
|
|
76
|
+
switch (operation) {
|
|
77
|
+
case 'add':
|
|
78
|
+
result = num1 + num2
|
|
79
|
+
break
|
|
80
|
+
case 'subtract':
|
|
81
|
+
result = num1 - num2
|
|
82
|
+
break
|
|
83
|
+
case 'multiply':
|
|
84
|
+
result = num1 * num2
|
|
85
|
+
break
|
|
86
|
+
default:
|
|
87
|
+
throw new Error('Invalid operation')
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Ensure result is within valid range and has correct precision
|
|
91
|
+
if (result < 0) {
|
|
92
|
+
throw new Error('Decimal value cannot be negative')
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Check if result exceeds maximum precision (10 digits total with 3 decimal places)
|
|
96
|
+
if (result > 9999999.999) {
|
|
97
|
+
throw new Error('Decimal value exceeds maximum allowed precision')
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return parseFloat(result.toFixed(3))
|
|
101
|
+
}
|
|
102
|
+
|
|
69
103
|
@Resolver(ReleaseGood)
|
|
70
104
|
export class ReleaseGoodMutation {
|
|
71
105
|
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
@@ -445,8 +479,8 @@ export async function deleteReleaseGood(tx: EntityManager, name: string, user: U
|
|
|
445
479
|
|
|
446
480
|
await tx.getRepository(Inventory).save({
|
|
447
481
|
...oi.inventory,
|
|
448
|
-
lockedQty: oi.inventory.lockedQty
|
|
449
|
-
lockedUomValue: oi.inventory.lockedUomValue
|
|
482
|
+
lockedQty: safeDecimalOperation(oi.inventory.lockedQty, oi.releaseQty, 'subtract'),
|
|
483
|
+
lockedUomValue: safeDecimalOperation(oi.inventory.lockedUomValue, oi.releaseUomValue, 'subtract'),
|
|
450
484
|
updater: user
|
|
451
485
|
})
|
|
452
486
|
}
|
|
@@ -813,8 +847,12 @@ export async function generateReleaseGoodFunction(
|
|
|
813
847
|
pbSettings.forEach(pbs => {
|
|
814
848
|
splitOI = {
|
|
815
849
|
...oi,
|
|
816
|
-
releaseQty: oi.releaseQty
|
|
817
|
-
releaseUomValue:
|
|
850
|
+
releaseQty: safeDecimalOperation(oi.releaseQty, pbs.bundleQty, 'multiply'),
|
|
851
|
+
releaseUomValue: safeDecimalOperation(
|
|
852
|
+
safeDecimalOperation(oi.releaseUomValue, pbs.bundleQty, 'multiply'),
|
|
853
|
+
pbs.product.primaryValue,
|
|
854
|
+
'multiply'
|
|
855
|
+
),
|
|
818
856
|
packingType: pbs.product.packingType,
|
|
819
857
|
batchId: '',
|
|
820
858
|
product: {
|
|
@@ -1414,8 +1452,8 @@ export async function rejectReleaseGood(
|
|
|
1414
1452
|
|
|
1415
1453
|
await tx.getRepository(Inventory).save({
|
|
1416
1454
|
...oi.inventory,
|
|
1417
|
-
lockedQty: oi.inventory.lockedQty
|
|
1418
|
-
lockedUomValue: oi.inventory.lockedUomValue
|
|
1455
|
+
lockedQty: safeDecimalOperation(oi.inventory.lockedQty, oi.releaseQty, 'subtract'),
|
|
1456
|
+
lockedUomValue: safeDecimalOperation(oi.inventory.lockedUomValue, oi.releaseUomValue, 'subtract'),
|
|
1419
1457
|
updater: user
|
|
1420
1458
|
})
|
|
1421
1459
|
}
|
|
@@ -1921,7 +1959,11 @@ function extractRawReleaseGoods(rawReleaseGoods): Partial<ReleaseGood[]> {
|
|
|
1921
1959
|
|
|
1922
1960
|
// if there is duplicated SKU, merge them and sum up the releaseQty
|
|
1923
1961
|
if (duplicateSkuIdx >= 0) {
|
|
1924
|
-
releaseGoods[idx].orderInventories[duplicateSkuIdx].releaseQty
|
|
1962
|
+
releaseGoods[idx].orderInventories[duplicateSkuIdx].releaseQty = safeDecimalOperation(
|
|
1963
|
+
releaseGoods[idx].orderInventories[duplicateSkuIdx].releaseQty,
|
|
1964
|
+
item.releaseQty,
|
|
1965
|
+
'add'
|
|
1966
|
+
)
|
|
1925
1967
|
} else {
|
|
1926
1968
|
releaseGoods[idx].orderInventories.push({
|
|
1927
1969
|
sku: item.sku,
|
|
@@ -1929,8 +1971,8 @@ function extractRawReleaseGoods(rawReleaseGoods): Partial<ReleaseGood[]> {
|
|
|
1929
1971
|
packingType: item.packingType,
|
|
1930
1972
|
packingSize: item.packingSize,
|
|
1931
1973
|
uom: item.uom,
|
|
1932
|
-
releaseQty: item.releaseQty,
|
|
1933
|
-
releaseUomValue: item.releaseUomValue
|
|
1974
|
+
releaseQty: Math.round(parseFloat(item.releaseQty) * 1000) / 1000,
|
|
1975
|
+
releaseUomValue: Math.round(parseFloat(item.releaseUomValue) * 1000) / 1000,
|
|
1934
1976
|
})
|
|
1935
1977
|
}
|
|
1936
1978
|
} else {
|
|
@@ -970,7 +970,7 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
970
970
|
packing_type VARCHAR(50),
|
|
971
971
|
packing_size FLOAT,
|
|
972
972
|
uom VARCHAR(10),
|
|
973
|
-
release_qty
|
|
973
|
+
release_qty NUMERIC(15,3)
|
|
974
974
|
);
|
|
975
975
|
`
|
|
976
976
|
)
|
|
@@ -1027,9 +1027,11 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
1027
1027
|
AND oi.uom = i.uom
|
|
1028
1028
|
AND oi.domain_id = $1
|
|
1029
1029
|
AND oi.bizplace_id = $2
|
|
1030
|
-
), 0) as "remain_uom_value"
|
|
1030
|
+
), 0) as "remain_uom_value",
|
|
1031
|
+
p.is_inventory_decimal
|
|
1031
1032
|
FROM inventories i
|
|
1032
|
-
|
|
1033
|
+
INNER JOIN locations l ON i.location_id = l.id
|
|
1034
|
+
LEFT JOIN products p ON i.product_id = p.id
|
|
1033
1035
|
INNER JOIN (
|
|
1034
1036
|
SELECT rrg.product_id, rrg.product_detail_id, rrg.sku, rrg.product_info, rrg.packing_type, rrg.packing_size, rrg.uom
|
|
1035
1037
|
FROM raw_release_goods rrg
|
|
@@ -1045,7 +1047,7 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
1045
1047
|
AND i.obsolete = false
|
|
1046
1048
|
AND i.transfer_qty <= 0
|
|
1047
1049
|
AND i.transfer_uom_value <= 0
|
|
1048
|
-
GROUP BY i.product_id, foo.product_detail_id, foo.sku, foo.product_info, i.packing_type, i.packing_size, i.uom
|
|
1050
|
+
GROUP BY i.product_id, foo.product_detail_id, foo.sku, foo.product_info, i.packing_type, i.packing_size, i.uom, p.is_inventory_decimal
|
|
1049
1051
|
${useDetailedQuery ? ', i.batch_id, i.carton_id, i.expiration_date' : ''}
|
|
1050
1052
|
ORDER BY foo.sku, remain_qty DESC
|
|
1051
1053
|
) SELECT * FROM inv WHERE remain_qty > 0
|
|
@@ -1056,7 +1058,7 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
1056
1058
|
await tx.query(`DROP TABLE raw_release_goods`)
|
|
1057
1059
|
|
|
1058
1060
|
availableItems = availableItems.map(item => {
|
|
1059
|
-
|
|
1061
|
+
const mappedItem = {
|
|
1060
1062
|
productId: item.product_id,
|
|
1061
1063
|
productDetailId: item.product_detail_id,
|
|
1062
1064
|
productInfo: item.product_info,
|
|
@@ -1068,8 +1070,10 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
1068
1070
|
remainUomValue: item.remain_uom_value,
|
|
1069
1071
|
batchId: item.batch_id ? item.batch_id : null,
|
|
1070
1072
|
cartonId: item.carton_id ? item.carton_id : null,
|
|
1071
|
-
expirationDate: item.expiration_date ? _getStdDateStr(new Date(item.expiration_date)) : null
|
|
1073
|
+
expirationDate: item.expiration_date ? _getStdDateStr(new Date(item.expiration_date)) : null,
|
|
1074
|
+
isInventoryDecimal: item.is_inventory_decimal === true
|
|
1072
1075
|
}
|
|
1076
|
+
return mappedItem
|
|
1073
1077
|
})
|
|
1074
1078
|
|
|
1075
1079
|
return _extractData(rawReleaseGoods, availableItems)
|
|
@@ -1120,17 +1124,25 @@ function _extractData(rawData, validatedData) {
|
|
|
1120
1124
|
// if sku is matched, assign qty and product id
|
|
1121
1125
|
if (idx >= 0) {
|
|
1122
1126
|
// assign qty to rawData as much as possible
|
|
1123
|
-
releaseUomValue = (Math.round((data[idx]?.remainUomValue / data[idx]?.remainQty) *
|
|
1127
|
+
releaseUomValue = (Math.round((data[idx]?.remainUomValue / data[idx]?.remainQty) * 1000) / 1000) * raw.releaseQty
|
|
1124
1128
|
|
|
1125
1129
|
raw.assignedQty =
|
|
1126
|
-
|
|
1130
|
+
Math.round(
|
|
1131
|
+
(data[idx].remainQty >= raw.releaseQty
|
|
1132
|
+
? raw.releaseQty > 0
|
|
1133
|
+
? raw.releaseQty
|
|
1134
|
+
: 0
|
|
1135
|
+
: data[idx].remainQty) * 1000
|
|
1136
|
+
) / 1000
|
|
1127
1137
|
|
|
1128
1138
|
raw.assignedUomValue =
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
:
|
|
1139
|
+
Math.round(
|
|
1140
|
+
(data[idx].remainUomValue >= releaseUomValue
|
|
1141
|
+
? releaseUomValue > 0
|
|
1142
|
+
? releaseUomValue
|
|
1143
|
+
: 0
|
|
1144
|
+
: data[idx].remainUomValue) * 1000
|
|
1145
|
+
) / 1000
|
|
1134
1146
|
|
|
1135
1147
|
// deduct qty & uomValue from validateData
|
|
1136
1148
|
data[idx].remainQty -= raw.assignedQty
|
|
@@ -1142,6 +1154,7 @@ function _extractData(rawData, validatedData) {
|
|
|
1142
1154
|
raw.packingType = data[idx].packingType
|
|
1143
1155
|
raw.packingSize = data[idx].packingSize
|
|
1144
1156
|
raw.uom = data[idx].uom
|
|
1157
|
+
raw.isInventoryDecimal = data[idx].isInventoryDecimal === true
|
|
1145
1158
|
} else {
|
|
1146
1159
|
raw.assignedQty = 0
|
|
1147
1160
|
raw.assignedUomValue = 0
|
|
@@ -1162,9 +1175,12 @@ function _extractData(rawData, validatedData) {
|
|
|
1162
1175
|
if (!raw.productId || !raw.productDetailId) {
|
|
1163
1176
|
errors.push('inventory or product not found')
|
|
1164
1177
|
}
|
|
1165
|
-
if (raw.releaseQty <= 0
|
|
1178
|
+
if (raw.releaseQty <= 0) {
|
|
1166
1179
|
errors.push('invalid release qty')
|
|
1167
1180
|
}
|
|
1181
|
+
if (raw.releaseQty % 1 !== 0 && raw.isInventoryDecimal !== true) {
|
|
1182
|
+
errors.push('decimal quantities are not allowed for this product')
|
|
1183
|
+
}
|
|
1168
1184
|
if (raw.assignedQty < raw.releaseQty) {
|
|
1169
1185
|
errors.push('insufficient stock')
|
|
1170
1186
|
}
|
|
@@ -99,7 +99,7 @@ export class InventoryInfos {
|
|
|
99
99
|
@Field(type => Float, { nullable: true })
|
|
100
100
|
packingSize?: number
|
|
101
101
|
|
|
102
|
-
@Field(type =>
|
|
102
|
+
@Field(type => Float, { nullable: false })
|
|
103
103
|
qty?: number
|
|
104
104
|
|
|
105
105
|
@Field(type => Float, { nullable: true })
|
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EntityManager,
|
|
3
|
-
Equal,
|
|
4
|
-
getRepository,
|
|
5
|
-
In,
|
|
6
|
-
Not,
|
|
7
|
-
Raw,
|
|
8
|
-
Repository,
|
|
9
|
-
SelectQueryBuilder
|
|
10
|
-
} from 'typeorm'
|
|
1
|
+
import { EntityManager, Equal, getRepository, In, Not, Raw, Repository, SelectQueryBuilder } from 'typeorm'
|
|
11
2
|
|
|
12
3
|
import { User } from '@things-factory/auth-base'
|
|
13
4
|
import { Bizplace } from '@things-factory/biz-base'
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
ProductDetail
|
|
18
|
-
} from '@things-factory/product-base'
|
|
19
|
-
import {
|
|
20
|
-
PartnerSetting,
|
|
21
|
-
Setting
|
|
22
|
-
} from '@things-factory/setting-base'
|
|
23
|
-
import {
|
|
24
|
-
Domain,
|
|
25
|
-
ListParam
|
|
26
|
-
} from '@things-factory/shell'
|
|
5
|
+
import { Product, ProductBundle, ProductDetail } from '@things-factory/product-base'
|
|
6
|
+
import { PartnerSetting, Setting } from '@things-factory/setting-base'
|
|
7
|
+
import { Domain, ListParam } from '@things-factory/shell'
|
|
27
8
|
import {
|
|
28
9
|
generateInventoryHistory,
|
|
29
10
|
Inventory,
|
|
@@ -303,6 +284,7 @@ export const InventoryUtil = {
|
|
|
303
284
|
COALESCE(p.sku, '') AS "productSKU",
|
|
304
285
|
COALESCE(p.brand, '') AS "productBrand",
|
|
305
286
|
p.id AS "productId",
|
|
287
|
+
p.is_inventory_decimal AS "isInventoryDecimal",
|
|
306
288
|
i.product_detail_id AS "productDetailId",
|
|
307
289
|
SUM(COALESCE(i.qty, 0)) - SUM(COALESCE(i.locked_qty, 0)) - MAX(COALESCE(bp.bundle_product_release_qty, 0)) - SUM(COALESCE(pds.unassigned_qty, 0)) AS "remainQty",
|
|
308
290
|
SUM(COALESCE(i.uom_value, 0)) - SUM(COALESCE(i.locked_uom_value, 0)) - MAX(COALESCE(bp.bundle_product_release_uom_value, 0)) - SUM(COALESCE(pds.unassigned_uom_value, 0)) AS "remainUomValue",
|
|
@@ -330,8 +312,9 @@ export const InventoryUtil = {
|
|
|
330
312
|
AND i.transfer_uom_value <= 0
|
|
331
313
|
AND i.lock_inventory is not true
|
|
332
314
|
AND CASE WHEN i.expiration_date IS NOT NULL AND p.min_outbound_shelf_life IS NOT NULL THEN CURRENT_DATE < i.expiration_date - p.min_outbound_shelf_life ELSE true END
|
|
333
|
-
${
|
|
334
|
-
|
|
315
|
+
${
|
|
316
|
+
cycleCountFilter
|
|
317
|
+
? `AND i.id NOT IN (
|
|
335
318
|
SELECT DISTINCT(ici.inventory_id) FROM worksheets w
|
|
336
319
|
INNER JOIN worksheet_details wd ON wd.worksheet_id = w.id
|
|
337
320
|
INNER JOIN inventory_check_items ici ON wd.target_inventory_check_item_id = ici.id
|
|
@@ -339,8 +322,9 @@ export const InventoryUtil = {
|
|
|
339
322
|
AND w.status != 'DONE'
|
|
340
323
|
AND w.bizplace_id IN (${bizplaceIds})
|
|
341
324
|
AND w.domain_id = '${domain.id}'
|
|
342
|
-
)`
|
|
343
|
-
|
|
325
|
+
)`
|
|
326
|
+
: `AND true`
|
|
327
|
+
}
|
|
344
328
|
${productWhereClause}
|
|
345
329
|
GROUP BY
|
|
346
330
|
i.product_detail_id,
|
|
@@ -361,6 +345,7 @@ export const InventoryUtil = {
|
|
|
361
345
|
pb.sku AS "productSKU",
|
|
362
346
|
'brand' AS "productBrand",
|
|
363
347
|
id AS "productId",
|
|
348
|
+
false AS "isInventoryDecimal",
|
|
364
349
|
pbs.product_detail_id AS "productDetailId",
|
|
365
350
|
MIN(FLOOR(pbs."availableQty")) AS "remainQty",
|
|
366
351
|
MIN(FLOOR(pbs."availableUomValue")) AS "remainUomValue",
|
|
@@ -430,7 +415,7 @@ export const InventoryUtil = {
|
|
|
430
415
|
} OFFSET $1 LIMIT $2`,
|
|
431
416
|
[(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]
|
|
432
417
|
)
|
|
433
|
-
}
|
|
418
|
+
}
|
|
434
419
|
|
|
435
420
|
await trxMgr.query(`drop table temp_inventory_product_group`)
|
|
436
421
|
|
|
@@ -440,7 +425,12 @@ export const InventoryUtil = {
|
|
|
440
425
|
}
|
|
441
426
|
},
|
|
442
427
|
|
|
443
|
-
async bizplaceInventoryProductGroupImport(
|
|
428
|
+
async bizplaceInventoryProductGroupImport(
|
|
429
|
+
bizplaces: Bizplace[],
|
|
430
|
+
params: ListParam,
|
|
431
|
+
context: any,
|
|
432
|
+
trxMgr: EntityManager
|
|
433
|
+
) {
|
|
444
434
|
try {
|
|
445
435
|
let filters = params.filters
|
|
446
436
|
const { domain }: { domain: Domain } = context.state
|
|
@@ -463,12 +453,13 @@ export const InventoryUtil = {
|
|
|
463
453
|
COALESCE(p.sku, '') AS "productSKU",
|
|
464
454
|
COALESCE(p.brand, '') AS "productBrand",
|
|
465
455
|
p.id AS "productId",
|
|
456
|
+
p.is_inventory_decimal AS "isInventoryDecimal",
|
|
466
457
|
i.product_detail_id AS "productDetailId",
|
|
467
458
|
p.picking_strategy AS "pickingStrategy",
|
|
468
459
|
i.created_at AS "createdAt",
|
|
469
460
|
i.expiration_date AS "expirationDate",
|
|
470
461
|
i.manufacture_date AS "manufactureDate",
|
|
471
|
-
l2.name AS "
|
|
462
|
+
l2.name AS "name",
|
|
472
463
|
l2.zone AS "zone",
|
|
473
464
|
l2.row AS "row",
|
|
474
465
|
l2.column AS "column",
|
|
@@ -526,12 +517,13 @@ export const InventoryUtil = {
|
|
|
526
517
|
pb.sku AS "productSKU",
|
|
527
518
|
'brand' AS "productBrand",
|
|
528
519
|
id AS "productId",
|
|
520
|
+
false AS "isInventoryDecimal",
|
|
529
521
|
pbs.product_detail_id AS "productDetailId",
|
|
530
522
|
NULL AS "pickingStrategy",
|
|
531
523
|
NULL AS "createdAt",
|
|
532
524
|
NULL AS "expirationDate",
|
|
533
525
|
NULL AS "manufactureDate",
|
|
534
|
-
NULL AS "
|
|
526
|
+
NULL AS "name",
|
|
535
527
|
NULL AS "zone",
|
|
536
528
|
NULL AS "row",
|
|
537
529
|
NULL AS "column",
|
|
@@ -570,36 +562,37 @@ export const InventoryUtil = {
|
|
|
570
562
|
})
|
|
571
563
|
|
|
572
564
|
const getLocationSortingClause = (inventoryAssignmentSetting: any) => {
|
|
573
|
-
|
|
565
|
+
let locationSortingRules: Array<{ name: string; desc: boolean }> = []
|
|
574
566
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
567
|
+
if (inventoryAssignmentSetting) {
|
|
568
|
+
try {
|
|
569
|
+
let locationSetting = JSON.parse(inventoryAssignmentSetting.value)
|
|
570
|
+
for (const key in locationSetting) {
|
|
571
|
+
locationSortingRules.push({ name: key, desc: locationSetting[key] !== 'ASC' })
|
|
572
|
+
}
|
|
573
|
+
} catch (error) {
|
|
574
|
+
console.error('Invalid JSON in inventoryAssignmentSetting:', error)
|
|
580
575
|
}
|
|
581
|
-
} catch (error) {
|
|
582
|
-
console.error("Invalid JSON in inventoryAssignmentSetting:", error)
|
|
583
576
|
}
|
|
584
|
-
}
|
|
585
577
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
578
|
+
if (locationSortingRules.length) {
|
|
579
|
+
return locationSortingRules
|
|
580
|
+
.map(
|
|
581
|
+
rule => `
|
|
589
582
|
CASE
|
|
590
583
|
WHEN "pickingStrategy" = 'LOCATION' THEN "${rule.name}"
|
|
591
584
|
END ${rule.desc ? 'DESC' : 'ASC'}
|
|
592
|
-
`
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
return `
|
|
597
|
-
CASE
|
|
598
|
-
WHEN "pickingStrategy" = 'LOCATION' THEN "locationName"
|
|
599
|
-
END ASC
|
|
600
|
-
`
|
|
601
|
-
}
|
|
585
|
+
`
|
|
586
|
+
)
|
|
587
|
+
.join(',\n')
|
|
588
|
+
}
|
|
602
589
|
|
|
590
|
+
return `
|
|
591
|
+
CASE
|
|
592
|
+
WHEN "pickingStrategy" = 'LOCATION' THEN "name"
|
|
593
|
+
END ASC
|
|
594
|
+
`
|
|
595
|
+
}
|
|
603
596
|
|
|
604
597
|
await trxMgr.query(queryStrings, [domain.id])
|
|
605
598
|
|
|
@@ -608,7 +601,6 @@ export const InventoryUtil = {
|
|
|
608
601
|
let items: any[] = []
|
|
609
602
|
|
|
610
603
|
if (!params?.pagination) {
|
|
611
|
-
|
|
612
604
|
const orderByClause = `
|
|
613
605
|
ORDER BY
|
|
614
606
|
${getLocationSortingClause(inventoryAssignmentSetting)},
|
|
@@ -629,9 +621,7 @@ export const InventoryUtil = {
|
|
|
629
621
|
ELSE NULL
|
|
630
622
|
END ASC
|
|
631
623
|
`
|
|
632
|
-
items = await trxMgr.query(
|
|
633
|
-
`select * from temp_inventory_product_group ${orderByClause}`
|
|
634
|
-
)
|
|
624
|
+
items = await trxMgr.query(`select * from temp_inventory_product_group ${orderByClause}`)
|
|
635
625
|
}
|
|
636
626
|
|
|
637
627
|
await trxMgr.query(`drop table temp_inventory_product_group`)
|
|
@@ -807,7 +797,7 @@ export const InventoryUtil = {
|
|
|
807
797
|
)
|
|
808
798
|
|
|
809
799
|
resultQb.forEach(itm => {
|
|
810
|
-
if (itm.releaseQty > itm.availableQty) {
|
|
800
|
+
if (parseFloat(itm.releaseQty) > parseFloat(itm.availableQty)) {
|
|
811
801
|
throw new ValidationError({
|
|
812
802
|
...ValidationError.ERROR_CODES.RELEASE_QTY_OVER_LIMIT,
|
|
813
803
|
detail: { data: JSON.stringify(resultQb) }
|
|
@@ -1336,7 +1326,7 @@ export function _composeTargetInventories(
|
|
|
1336
1326
|
let orderInventory: OrderInventory = new OrderInventory()
|
|
1337
1327
|
|
|
1338
1328
|
if (inventory.remainQty > leftReleaseQty) {
|
|
1339
|
-
const uomValuePerQty: number = Math.round((inventory.remainUomValue / inventory.remainQty) *
|
|
1329
|
+
const uomValuePerQty: number = Math.round((inventory.remainUomValue / inventory.remainQty) * 1000) / 1000
|
|
1340
1330
|
|
|
1341
1331
|
compReleaseQty += leftReleaseQty
|
|
1342
1332
|
compReleaseUomValue += leftReleaseUomValue
|
|
@@ -1344,7 +1334,7 @@ export function _composeTargetInventories(
|
|
|
1344
1334
|
orderInventory = {
|
|
1345
1335
|
...orderInventory,
|
|
1346
1336
|
releaseQty: leftReleaseQty,
|
|
1347
|
-
releaseUomValue: Math.round(leftReleaseQty * uomValuePerQty *
|
|
1337
|
+
releaseUomValue: Math.round(leftReleaseQty * uomValuePerQty * 1000) / 1000
|
|
1348
1338
|
}
|
|
1349
1339
|
} else {
|
|
1350
1340
|
compReleaseQty += inventory.remainQty
|