@things-factory/operato-hub 4.3.770 → 4.3.771
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 +107 -52
- package/dist-server/routers/api/restful-apis/unstable/add-release-order.js +81 -45
- 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 +55 -44
- package/dist-server/routers/api/restful-apis/v1/warehouse/add-release-order.js.map +1 -1
- package/dist-server/routers/api/restful-apis/v1/warehouse/update-release-order-details.js +65 -36
- package/dist-server/routers/api/restful-apis/v1/warehouse/update-release-order-details.js.map +1 -1
- package/dist-server/routers/xilnex-router.js +7 -2
- package/dist-server/routers/xilnex-router.js.map +1 -1
- package/package.json +5 -5
- package/server/routers/api/restful-apis/unstable/add-release-order.ts +90 -50
- package/server/routers/api/restful-apis/v1/warehouse/add-release-order.ts +63 -48
- package/server/routers/api/restful-apis/v1/warehouse/update-release-order-details.ts +69 -38
- package/server/routers/xilnex-router.ts +7 -2
package/config.development.js
CHANGED
|
@@ -4,15 +4,46 @@ module.exports = {
|
|
|
4
4
|
useVirtualHostBasedDomain: false,
|
|
5
5
|
fallbackRoute: '/',
|
|
6
6
|
subdomainOffset: 2,
|
|
7
|
-
port:
|
|
7
|
+
port: 3000,
|
|
8
8
|
inspect: '9260',
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
//postgres
|
|
10
|
+
ormconfig: {
|
|
11
|
+
name: 'default',
|
|
12
|
+
type: 'postgres',
|
|
13
|
+
database: 'postgres',
|
|
14
|
+
username: 'postgres',
|
|
15
|
+
password: 't62dgT#Ns*GerhuZ9wnzm^',
|
|
16
|
+
host: 'my-operato-pg.cjcso4qmeuq0.ap-southeast-5.rds.amazonaws.com',
|
|
17
|
+
port: 55432,
|
|
18
|
+
synchronize: false,
|
|
19
|
+
logging: ['query', 'error'],
|
|
20
|
+
logger: 'advanced-console'
|
|
15
21
|
},
|
|
22
|
+
//operato
|
|
23
|
+
// ormconfig: {
|
|
24
|
+
// name: 'default',
|
|
25
|
+
// type: 'postgres',
|
|
26
|
+
// database: 'operato',
|
|
27
|
+
// username: 'postgres',
|
|
28
|
+
// password: 'hatio',
|
|
29
|
+
// host: '192.168.0.151',
|
|
30
|
+
// port: 15432,
|
|
31
|
+
// synchronize: false,
|
|
32
|
+
// logging: true
|
|
33
|
+
// },
|
|
34
|
+
//eric2
|
|
35
|
+
// ormconfig: {
|
|
36
|
+
// name: 'default',
|
|
37
|
+
// type: 'postgres',
|
|
38
|
+
// database: 'eric2',
|
|
39
|
+
// username: 'postgres',
|
|
40
|
+
// password: 'hatio',
|
|
41
|
+
// host: '192.168.0.153',
|
|
42
|
+
// port: 15432,
|
|
43
|
+
// synchronize: false,
|
|
44
|
+
// logging: true
|
|
45
|
+
// },
|
|
46
|
+
// arif's
|
|
16
47
|
// ormconfig: {
|
|
17
48
|
// name: 'default',
|
|
18
49
|
// type: 'postgres',
|
|
@@ -24,47 +55,30 @@ module.exports = {
|
|
|
24
55
|
// synchronize: false,
|
|
25
56
|
// logging: true
|
|
26
57
|
// },
|
|
27
|
-
|
|
28
|
-
// STAGING DATABASE
|
|
29
|
-
ormconfig: {
|
|
30
|
-
name: 'default',
|
|
31
|
-
type: 'postgres',
|
|
32
|
-
database: 'staging',
|
|
33
|
-
username: 'postgres',
|
|
34
|
-
password: 't62dgT#Ns*GerhuZ9wnzm^',
|
|
35
|
-
host: 'my-operato-pg.cjcso4qmeuq0.ap-southeast-5.rds.amazonaws.com',
|
|
36
|
-
port: 55432,
|
|
37
|
-
synchronize: false,
|
|
38
|
-
logging: true
|
|
39
|
-
},
|
|
40
|
-
|
|
58
|
+
//EMS
|
|
41
59
|
// ormconfig: {
|
|
42
60
|
// name: 'default',
|
|
43
61
|
// type: 'postgres',
|
|
44
|
-
// database: '
|
|
62
|
+
// database: 'EMS',
|
|
45
63
|
// username: 'postgres',
|
|
46
64
|
// password: 'hatio',
|
|
47
|
-
// host: '192.168.0.
|
|
65
|
+
// host: '192.168.0.161',
|
|
48
66
|
// port: 15432,
|
|
49
67
|
// synchronize: false,
|
|
50
68
|
// logging: true
|
|
51
69
|
// },
|
|
52
|
-
|
|
53
|
-
//db izzah
|
|
70
|
+
//db nora
|
|
54
71
|
// ormconfig: {
|
|
55
72
|
// name: 'default',
|
|
56
73
|
// type: 'postgres',
|
|
57
|
-
// database: '
|
|
74
|
+
// database: 'postgres',
|
|
58
75
|
// username: 'postgres',
|
|
59
76
|
// password: 'hatio',
|
|
60
|
-
// host: '192.168.0.
|
|
77
|
+
// host: '192.168.0.36',
|
|
61
78
|
// port: 15432,
|
|
62
79
|
// synchronize: true,
|
|
63
80
|
// logging: true
|
|
64
81
|
// },
|
|
65
|
-
//postgres
|
|
66
|
-
|
|
67
|
-
// //ERIC
|
|
68
82
|
// ormconfig: {
|
|
69
83
|
// name: 'default',
|
|
70
84
|
// type: 'postgres',
|
|
@@ -76,20 +90,18 @@ module.exports = {
|
|
|
76
90
|
// synchronize: true,
|
|
77
91
|
// logging: true
|
|
78
92
|
// },
|
|
79
|
-
|
|
80
|
-
//eric2
|
|
93
|
+
//db izzah
|
|
81
94
|
// ormconfig: {
|
|
82
95
|
// name: 'default',
|
|
83
96
|
// type: 'postgres',
|
|
84
|
-
// database: '
|
|
97
|
+
// database: '06072023',
|
|
85
98
|
// username: 'postgres',
|
|
86
99
|
// password: 'hatio',
|
|
87
100
|
// host: '192.168.0.153',
|
|
88
101
|
// port: 15432,
|
|
89
|
-
// synchronize:
|
|
102
|
+
// synchronize: true,
|
|
90
103
|
// logging: true
|
|
91
104
|
// },
|
|
92
|
-
|
|
93
105
|
// ormconfig: {
|
|
94
106
|
// name: 'default',
|
|
95
107
|
// type: 'postgres',
|
|
@@ -103,6 +115,7 @@ module.exports = {
|
|
|
103
115
|
// connectTimeoutMS: 30000,
|
|
104
116
|
// extra: { poolSize: 30 }
|
|
105
117
|
// },
|
|
118
|
+
|
|
106
119
|
// ormconfig: {
|
|
107
120
|
// name: 'default',
|
|
108
121
|
// type: 'postgres',
|
|
@@ -116,6 +129,7 @@ module.exports = {
|
|
|
116
129
|
// connectTimeoutMS: 30000,
|
|
117
130
|
// extra: { poolSize: 30 }
|
|
118
131
|
// },
|
|
132
|
+
|
|
119
133
|
password: {
|
|
120
134
|
lowerCase: true,
|
|
121
135
|
upperCase: false,
|
|
@@ -130,10 +144,23 @@ module.exports = {
|
|
|
130
144
|
},
|
|
131
145
|
sftpFileStorage: {
|
|
132
146
|
type: 's3',
|
|
133
|
-
accessKeyId: '
|
|
134
|
-
secretAccessKey: '
|
|
135
|
-
bucketName: 'operato-sftp'
|
|
147
|
+
accessKeyId: 'AKIAUQEOPWEJAMXCXGB4',
|
|
148
|
+
secretAccessKey: 'NUHZocUnWoRtOD5LI06OX6l+TCFq7Xs4FnzPGSkX',
|
|
149
|
+
bucketName: 'operato-sftp',
|
|
150
|
+
region: 'ap-southeast-1'
|
|
136
151
|
},
|
|
152
|
+
|
|
153
|
+
// SFTP Configuration for external server
|
|
154
|
+
// sftpExternal: {
|
|
155
|
+
// type: 'sftp',
|
|
156
|
+
// host: '103.4.6.168',
|
|
157
|
+
// port: 2211,
|
|
158
|
+
// username: 'hatio_admin',
|
|
159
|
+
// password: 'Yltc@2025!',
|
|
160
|
+
// basePath: '/Staging',
|
|
161
|
+
// timeout: 30000,
|
|
162
|
+
// retries: 3
|
|
163
|
+
// },
|
|
137
164
|
// storage: {
|
|
138
165
|
// type: 's3',
|
|
139
166
|
// accessKeyId: 'AKIAUQEOPWEJCDH6AR5H',
|
|
@@ -167,11 +194,6 @@ module.exports = {
|
|
|
167
194
|
ciphers: 'SSLv3'
|
|
168
195
|
}
|
|
169
196
|
},
|
|
170
|
-
jobQueue: {
|
|
171
|
-
// For JobQueueService/JobWorker (FIFO queue is supported)
|
|
172
|
-
queueUrl: 'https://sqs.ap-southeast-5.amazonaws.com/309536469266/operato-job-queue.fifo',
|
|
173
|
-
sqsRegion: 'ap-southeast-5'
|
|
174
|
-
},
|
|
175
197
|
sender: 'noreply@hatiolab.com',
|
|
176
198
|
notification: {
|
|
177
199
|
// fcm: {
|
|
@@ -205,12 +227,20 @@ module.exports = {
|
|
|
205
227
|
appSecret: '1c385935dc131c4b902b9bbf6a4798af',
|
|
206
228
|
callback: 'http://192.168.0.161:5000/callback-operato'
|
|
207
229
|
},
|
|
230
|
+
|
|
231
|
+
// Job queue (AWS SQS)
|
|
232
|
+
jobQueue: {
|
|
233
|
+
// For JobQueueService/JobWorker (FIFO queue is supported)
|
|
234
|
+
queueUrl: 'https://sqs.ap-southeast-5.amazonaws.com/309536469266/operato-job-queue.fifo',
|
|
235
|
+
sqsRegion: 'ap-southeast-5'
|
|
236
|
+
},
|
|
208
237
|
marketplaceIntegrationShopee: {
|
|
209
238
|
platform: 'shopee',
|
|
210
239
|
isUAT: false,
|
|
211
240
|
application: 'Operato MMS',
|
|
212
241
|
partnerId: 846025,
|
|
213
|
-
partnerKey: 'd34cfd85a603f196a0d74ebe08043280c1a27788bb36bdffd61e7e0bb1c90b64'
|
|
242
|
+
partnerKey: 'd34cfd85a603f196a0d74ebe08043280c1a27788bb36bdffd61e7e0bb1c90b64',
|
|
243
|
+
v2: true
|
|
214
244
|
},
|
|
215
245
|
marketplaceIntegrationLazada: {
|
|
216
246
|
platform: 'lazada',
|
|
@@ -219,6 +249,16 @@ module.exports = {
|
|
|
219
249
|
appSecret: 'HB3RTNEXHlVSlBr9SmWF8AjbSUT7a825',
|
|
220
250
|
callback: 'https://maybank.operato-m.com/lazada-callback'
|
|
221
251
|
},
|
|
252
|
+
|
|
253
|
+
//testinglazada
|
|
254
|
+
// marketplaceIntegrationLazada: {
|
|
255
|
+
// platform: 'lazada',
|
|
256
|
+
// application: 'powrup_bi',
|
|
257
|
+
// appKey: '117890',
|
|
258
|
+
// appSecret: 'tQVllnUa7irAHoNxAwXEVxoP1we1bUjE',
|
|
259
|
+
// callback: 'https://73c5-175-141-30-142.ngrok-free.app/lazada-callback'
|
|
260
|
+
// },
|
|
261
|
+
|
|
222
262
|
accountingIntegrationXero: {
|
|
223
263
|
platform: 'xero',
|
|
224
264
|
application: 'Operato WMS',
|
|
@@ -227,21 +267,36 @@ module.exports = {
|
|
|
227
267
|
callback: 'http://operato-h.com:3000/callback-xero',
|
|
228
268
|
hostname: 'http://operato-h.com:3000/'
|
|
229
269
|
},
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
270
|
+
lmdIntegrationNinjavan: {
|
|
271
|
+
clientId: 'P8WCEwMo0FHNlPECwTLetwN3diAmt5KF',
|
|
272
|
+
secretKey: '1D0yNZGseOjhxnwri29xmuZiiuRp131L',
|
|
273
|
+
refreshThreshold: 43200
|
|
234
274
|
},
|
|
275
|
+
|
|
276
|
+
lmdIntegrationEms: { refreshThreshold: 43200 },
|
|
277
|
+
|
|
278
|
+
lmdIntegrationCitylink: { refreshThreshold: 172800000 },
|
|
235
279
|
awbFileStorage: {
|
|
236
280
|
type: 's3',
|
|
237
|
-
accessKeyId: '
|
|
238
|
-
secretAccessKey: '
|
|
281
|
+
accessKeyId: 'AKIAUQEOPWEJPXIVER74',
|
|
282
|
+
secretAccessKey: 'I6uuS+6CMzIQlqBS9i+G8AYIeYj5RR7wb4fxjbLq',
|
|
239
283
|
bucketName: 'operato-awb',
|
|
240
284
|
region: 'ap-southeast-1'
|
|
241
285
|
},
|
|
286
|
+
lambda: {
|
|
287
|
+
region: 'ap-southeast-1',
|
|
288
|
+
accessKeyId: 'AKIAUQEOPWEJPXIVER74',
|
|
289
|
+
secretAccessKey: 'I6uuS+6CMzIQlqBS9i+G8AYIeYj5RR7wb4fxjbLq'
|
|
290
|
+
},
|
|
291
|
+
lmdIntegrationConfig: {
|
|
292
|
+
version: {
|
|
293
|
+
v1: 'lmdMiddleware',
|
|
294
|
+
v2: 'lmdMiddlewareV2'
|
|
295
|
+
}
|
|
296
|
+
},
|
|
242
297
|
awsSesEmail: {
|
|
243
|
-
accessKeyId: '
|
|
244
|
-
secretAccessKey: '
|
|
298
|
+
accessKeyId: 'AKIAUQEOPWEJPXIVER74',
|
|
299
|
+
secretAccessKey: 'I6uuS+6CMzIQlqBS9i+G8AYIeYj5RR7wb4fxjbLq',
|
|
245
300
|
email: 'support@hatio.asia'
|
|
246
301
|
},
|
|
247
302
|
reportApiUrl:
|
|
@@ -816,6 +816,7 @@ async function massageOrderItems(releaseGood, inputOrderProducts, context) {
|
|
|
816
816
|
}
|
|
817
817
|
}
|
|
818
818
|
async function assignToInventory(releaseGood, orderProducts, customerBizplace, context, tx, worksheetPickingAssignment) {
|
|
819
|
+
var _a;
|
|
819
820
|
const { client, domain, user } = context.state;
|
|
820
821
|
const pickingProductSetting = await tx.getRepository(setting_base_1.Setting).findOne({
|
|
821
822
|
where: { domain, name: 'rule-for-picking-product' }
|
|
@@ -890,7 +891,7 @@ async function assignToInventory(releaseGood, orderProducts, customerBizplace, c
|
|
|
890
891
|
switch (itm === null || itm === void 0 ? void 0 : itm.operator) {
|
|
891
892
|
case 'notin':
|
|
892
893
|
case 'in':
|
|
893
|
-
acc.query.push(`${itm.query} ${itm.operator == 'notin' ? 'NOT IN' : 'IN'} (${itm.
|
|
894
|
+
acc.query.push(`${itm.query} ${itm.operator == 'notin' ? 'NOT IN' : 'IN'} (${itm.filters
|
|
894
895
|
.map((itm, idx) => {
|
|
895
896
|
return `$${acc.values.length + 1}`;
|
|
896
897
|
})
|
|
@@ -900,7 +901,7 @@ async function assignToInventory(releaseGood, orderProducts, customerBizplace, c
|
|
|
900
901
|
acc.query.push(`${itm.query} ${(itm === null || itm === void 0 ? void 0 : itm.operator) ? itm.operator : '='} $${acc.values.length + 1}`);
|
|
901
902
|
break;
|
|
902
903
|
}
|
|
903
|
-
|
|
904
|
+
return acc;
|
|
904
905
|
}, {
|
|
905
906
|
query: [],
|
|
906
907
|
values: []
|
|
@@ -926,16 +927,25 @@ async function assignToInventory(releaseGood, orderProducts, customerBizplace, c
|
|
|
926
927
|
params.push(orderInventory.batchId);
|
|
927
928
|
}
|
|
928
929
|
params = [...params, ...queryStrings.values];
|
|
929
|
-
|
|
930
|
-
|
|
930
|
+
// Add seed row parameters to avoid SQL injection
|
|
931
|
+
const seedUomIdx = params.length + 1;
|
|
932
|
+
const seedPackingTypeIdx = params.length + 2;
|
|
933
|
+
const seedPackingSizeIdx = params.length + 3;
|
|
934
|
+
const seedReleaseQtyIdx = params.length + 4;
|
|
935
|
+
const seedReleaseUomValueIdx = params.length + 5;
|
|
936
|
+
params.push(orderInventory.uom, orderInventory.packingType, orderInventory.packingSize, orderInventory.releaseQty, orderInventory.releaseUomValue);
|
|
937
|
+
const MAX_ASSIGN_RETRIES = 3;
|
|
938
|
+
const RETRY_DELAY_MS = 10;
|
|
939
|
+
const assignQuery = `
|
|
940
|
+
update inventories tgt set locked_qty = coalesce(locked_qty,0) + src.reserve_qty,
|
|
931
941
|
locked_uom_value = coalesce(locked_uom_value,0) + src.reserve_uom_value,
|
|
932
942
|
updated_at = NOW(),
|
|
933
943
|
updater_id = $1
|
|
934
944
|
from (
|
|
935
945
|
select "id", "pallet_id","carton_id", "batch_id", "batch_id_ref", "unit", "uom", "packing_type", "packing_size", "manufacture_year",
|
|
936
|
-
"reserve_qty", (("uom_value"/"qty") * "reserve_qty") as "reserve_uom_value" from (
|
|
937
|
-
select "sort_seq", "id", "pallet_id", "batch_id", "batch_id_ref", "unit", "uom", "packing_type", "packing_size", "manufacture_year", "carton_id", "uom_value", "locked_uom_value", "qty", "locked_qty", "created_at",
|
|
938
|
-
"release_qty", "release_uom_value", lock_amount,
|
|
946
|
+
"reserve_qty", (("uom_value"/"qty") * "reserve_qty") as "reserve_uom_value" from (
|
|
947
|
+
select "sort_seq", "id", "pallet_id", "batch_id", "batch_id_ref", "unit", "uom", "packing_type", "packing_size", "manufacture_year", "carton_id", "uom_value", "locked_uom_value", "qty", "locked_qty", "created_at",
|
|
948
|
+
"release_qty", "release_uom_value", lock_amount,
|
|
939
949
|
case when "lock_amount" < 0 then "available_qty" else "available_qty" - "lock_amount" end as "reserve_qty"
|
|
940
950
|
from (
|
|
941
951
|
select *,
|
|
@@ -945,57 +955,81 @@ async function assignToInventory(releaseGood, orderProducts, customerBizplace, c
|
|
|
945
955
|
) as available_qty,
|
|
946
956
|
sum(qty - locked_qty - release_qty - unassigned_qty) over (order by sort_seq asc rows between unbounded preceding and current row) as lock_amount
|
|
947
957
|
from (
|
|
948
|
-
SELECT 0 as sort_seq, null as id, null as pallet_id, null as batch_id, null as batch_id_ref,
|
|
949
|
-
null as unit,
|
|
958
|
+
SELECT 0 as sort_seq, null as id, null as pallet_id, null as batch_id, null as batch_id_ref,
|
|
959
|
+
null as unit, $${seedUomIdx} as uom, $${seedPackingTypeIdx} as packing_type, $${seedPackingSizeIdx} as packing_size,
|
|
950
960
|
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,
|
|
951
|
-
|
|
961
|
+
$${seedReleaseQtyIdx}::numeric as release_qty, $${seedReleaseUomValueIdx}::numeric as release_uom_value
|
|
952
962
|
UNION
|
|
953
963
|
(
|
|
954
|
-
SELECT ROW_NUMBER() OVER(PARTITION BY iv.domain_id ORDER BY wiar.rank ${sortQuery ? ', ' + sortQuery : ''}) as sort_seq,
|
|
955
|
-
iv.id, iv.pallet_id, iv.batch_id, iv.batch_id_ref,
|
|
956
|
-
iv.unit, iv.uom, iv.packing_type, iv.packing_size,
|
|
957
|
-
iv.manufacture_year, iv.carton_id, iv.uom_value,
|
|
964
|
+
SELECT ROW_NUMBER() OVER(PARTITION BY iv.domain_id ORDER BY wiar.rank ${sortQuery ? ', ' + sortQuery : ''}) as sort_seq,
|
|
965
|
+
iv.id, iv.pallet_id, iv.batch_id, iv.batch_id_ref,
|
|
966
|
+
iv.unit, iv.uom, iv.packing_type, iv.packing_size,
|
|
967
|
+
iv.manufacture_year, iv.carton_id, iv.uom_value,
|
|
958
968
|
coalesce(iv.locked_uom_value,0) as locked_uom_value, iv.qty, greatest(coalesce(iv.locked_qty,0),0) as locked_qty, coalesce(pds.unassigned_uom_value,0) as unassigned_uom_value, greatest(coalesce(pds.unassigned_qty,0),0) as unassigned_qty, iv.created_at,
|
|
959
969
|
0 as release_qty, 0 as release_uom_value
|
|
960
|
-
FROM "inventories" "iv"
|
|
970
|
+
FROM "inventories" "iv"
|
|
961
971
|
LEFT JOIN "product_detail_stocks" "pds" ON "pds"."product_detail_id" = "iv"."product_detail_id"
|
|
962
|
-
INNER JOIN "locations" "loc" ON "loc"."id"="iv"."location_id"
|
|
963
|
-
INNER JOIN "products" "p" ON "p"."id"="iv"."product_id"
|
|
972
|
+
INNER JOIN "locations" "loc" ON "loc"."id"="iv"."location_id"
|
|
973
|
+
INNER JOIN "products" "p" ON "p"."id"="iv"."product_id"
|
|
964
974
|
INNER JOIN "warehouse_inventory_assignment_rankings" "wiar" ON "wiar"."location_type"="loc"."type"
|
|
965
|
-
WHERE case when coalesce("iv"."locked_qty",0) < 0 then 0 else ("iv"."qty" - coalesce("iv"."locked_qty",0)) end > 0 AND
|
|
975
|
+
WHERE case when coalesce("iv"."locked_qty",0) < 0 then 0 else ("iv"."qty" - coalesce("iv"."locked_qty",0)) end > 0 AND
|
|
966
976
|
"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)
|
|
967
977
|
AND ${orderInventory.batchId ? `"iv"."batch_id" = $11` : `1=1`}
|
|
968
978
|
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
|
|
969
|
-
${queryStrings.query.length > 0 ? `AND ${queryStrings.join(' AND ')}` : ''}
|
|
979
|
+
${queryStrings.query.length > 0 ? `AND ${queryStrings.query.join(' AND ')}` : ''}
|
|
970
980
|
ORDER BY wiar.rank ${sortQuery ? ', ' + sortQuery : ''}
|
|
971
981
|
)
|
|
972
982
|
) dt1
|
|
973
|
-
) dt2 where case when "lock_amount" < 0 then "available_qty" else "available_qty" - "lock_amount" end > 0
|
|
983
|
+
) dt2 where case when "lock_amount" < 0 then "available_qty" else "available_qty" - "lock_amount" end > 0
|
|
974
984
|
) dt3 where sort_seq > 0
|
|
975
|
-
) src where src.id = tgt.id
|
|
976
|
-
returning
|
|
977
|
-
tgt."id", tgt."qty", tgt."pallet_id", tgt."carton_id", tgt."batch_id", tgt."batch_id_ref", tgt."unit",
|
|
978
|
-
tgt."uom", tgt."packing_type", tgt."packing_size", tgt."manufacture_year",
|
|
979
|
-
tgt."locked_qty", tgt."uom_value", tgt."locked_uom_value", src."reserve_qty", src."reserve_uom_value"
|
|
980
|
-
let
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
985
|
+
) src where src.id = tgt.id AND tgt.qty >= coalesce(tgt.locked_qty, 0) + src.reserve_qty
|
|
986
|
+
returning
|
|
987
|
+
tgt."id", tgt."qty", tgt."pallet_id", tgt."carton_id", tgt."batch_id", tgt."batch_id_ref", tgt."unit",
|
|
988
|
+
tgt."uom", tgt."packing_type", tgt."packing_size", tgt."manufacture_year",
|
|
989
|
+
tgt."locked_qty", tgt."uom_value", tgt."locked_uom_value", src."reserve_qty", src."reserve_uom_value";`;
|
|
990
|
+
let updatedInventories;
|
|
991
|
+
for (let attempt = 1; attempt <= MAX_ASSIGN_RETRIES; attempt++) {
|
|
992
|
+
await tx.query('SAVEPOINT assign_retry');
|
|
993
|
+
updatedInventories = await tx.getRepository(warehouse_base_1.Inventory).query(assignQuery, params);
|
|
994
|
+
const assignedRows = (updatedInventories === null || updatedInventories === void 0 ? void 0 : updatedInventories[0]) || [];
|
|
995
|
+
let totalAssigned = assignedRows.reduce((acc, inv) => {
|
|
996
|
+
return acc + Number(inv.reserve_qty);
|
|
997
|
+
}, 0);
|
|
998
|
+
// Use epsilon comparison for floating-point tolerance
|
|
999
|
+
let opReleaseQty = orderProduct.releaseQty;
|
|
1000
|
+
if (!((_a = orderInventory.product) === null || _a === void 0 ? void 0 : _a.isInventoryDecimal)) {
|
|
1001
|
+
opReleaseQty = Math.round(opReleaseQty);
|
|
1002
|
+
totalAssigned = Math.round(totalAssigned);
|
|
1003
|
+
}
|
|
1004
|
+
else {
|
|
1005
|
+
opReleaseQty = Math.round(opReleaseQty * 1000) / 1000;
|
|
1006
|
+
totalAssigned = Math.round(totalAssigned * 1000) / 1000;
|
|
1007
|
+
}
|
|
1008
|
+
if (Math.abs(opReleaseQty - totalAssigned) > 0.001) {
|
|
1009
|
+
await tx.query('ROLLBACK TO SAVEPOINT assign_retry');
|
|
1010
|
+
if (attempt < MAX_ASSIGN_RETRIES) {
|
|
1011
|
+
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS));
|
|
1012
|
+
continue;
|
|
1013
|
+
}
|
|
1014
|
+
throw new index_1.ValidationError({
|
|
1015
|
+
errorCode: 'INSUFFICIENT_STOCK',
|
|
1016
|
+
message: 'insufficient stock',
|
|
1017
|
+
detail: JSON.stringify({
|
|
1018
|
+
code: 'insufficient stock',
|
|
1019
|
+
sku: orderProduct.product.sku,
|
|
1020
|
+
packingType: orderProduct.packingType,
|
|
1021
|
+
packingSize: orderProduct.packingSize,
|
|
1022
|
+
uom: orderProduct.uom,
|
|
1023
|
+
qty: orderProduct.releaseQty,
|
|
1024
|
+
uom_value: orderProduct.releaseUomValue
|
|
1025
|
+
})
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
await tx.query('RELEASE SAVEPOINT assign_retry');
|
|
1029
|
+
break;
|
|
997
1030
|
}
|
|
998
|
-
|
|
1031
|
+
;
|
|
1032
|
+
((updatedInventories === null || updatedInventories === void 0 ? void 0 : updatedInventories[0]) || []).forEach(inv => {
|
|
999
1033
|
let oi = Object.assign(Object.assign({}, orderInventory), { inventory: { id: inv.id }, uom: inv.uom, packingType: inv.packing_type, batchId: inv.batch_id, releaseQty: inv.reserve_qty, releaseUomValue: inv.reserve_uom_value, pickedQty: 0, packedQty: 0, type: sales_base_1.ORDER_TYPES.RELEASE_OF_GOODS, status: sales_base_1.ORDER_INVENTORY_STATUS.PENDING_WORKSHEET, domain: { id: domain.id }, bizplace: { id: customerBizplace.id } });
|
|
1000
1034
|
assignedOrderInventories.push(oi);
|
|
1001
1035
|
});
|
|
@@ -1007,9 +1041,11 @@ async function assignToInventory(releaseGood, orderProducts, customerBizplace, c
|
|
|
1007
1041
|
.createQueryBuilder()
|
|
1008
1042
|
.update(warehouse_base_1.ProductDetailStock)
|
|
1009
1043
|
.set({
|
|
1010
|
-
unassignedQty: () => `"unassigned_qty" +
|
|
1011
|
-
unassignedUomValue: () => `"unassigned_uom_value" +
|
|
1044
|
+
unassignedQty: () => `"unassigned_qty" + :releaseQty::numeric`,
|
|
1045
|
+
unassignedUomValue: () => `"unassigned_uom_value" + :releaseUomValue::numeric`
|
|
1012
1046
|
})
|
|
1047
|
+
.setParameter('releaseQty', orderInventory.releaseQty)
|
|
1048
|
+
.setParameter('releaseUomValue', orderInventory.releaseUomValue)
|
|
1013
1049
|
.where({ productDetail: orderInventory.productDetail.id })
|
|
1014
1050
|
.execute();
|
|
1015
1051
|
}
|