@pisell/pisellos 2.2.197 → 2.2.199
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/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +7 -3
- package/dist/modules/Cart/utils/cartProduct.js +11 -1
- package/dist/modules/Cart/utils/changePrice.js +11 -11
- package/dist/modules/Order/index.d.ts +16 -0
- package/dist/modules/Order/index.js +1232 -568
- package/dist/modules/Order/types.d.ts +1 -0
- package/dist/modules/Order/utils.d.ts +33 -2
- package/dist/modules/Order/utils.js +112 -55
- package/dist/modules/Payment/walletpass.js +14 -7
- package/dist/modules/SalesSummary/utils.js +394 -149
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +294 -190
- package/dist/server/modules/order/index.d.ts +8 -0
- package/dist/server/modules/order/index.js +536 -317
- package/dist/server/modules/order/types.d.ts +2 -0
- package/dist/solution/BaseSales/index.js +2 -1
- package/dist/solution/BaseSales/types.d.ts +1 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +19 -4
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/ScanOrder/types.d.ts +1 -0
- package/dist/solution/ScanOrder/utils.js +26 -9
- package/dist/solution/VenueBooking/index.js +2 -1
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +4 -1
- package/lib/modules/Cart/utils/cartProduct.js +11 -1
- package/lib/modules/Cart/utils/changePrice.js +12 -20
- package/lib/modules/Order/index.d.ts +16 -0
- package/lib/modules/Order/index.js +525 -18
- package/lib/modules/Order/types.d.ts +1 -0
- package/lib/modules/Order/utils.d.ts +33 -2
- package/lib/modules/Order/utils.js +44 -9
- package/lib/modules/Payment/walletpass.js +7 -3
- package/lib/modules/SalesSummary/utils.js +256 -46
- package/lib/server/index.d.ts +3 -0
- package/lib/server/index.js +82 -3
- package/lib/server/modules/order/index.d.ts +8 -0
- package/lib/server/modules/order/index.js +106 -4
- package/lib/server/modules/order/types.d.ts +2 -0
- package/lib/solution/BaseSales/index.js +2 -1
- package/lib/solution/BaseSales/types.d.ts +1 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +15 -1
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/ScanOrder/types.d.ts +1 -0
- package/lib/solution/ScanOrder/utils.js +28 -10
- package/lib/solution/VenueBooking/index.js +2 -1
- package/package.json +1 -1
|
@@ -78,8 +78,8 @@ function getBundleUnitPrice(product, useOriginal = false) {
|
|
|
78
78
|
const bundleItems = product.product_bundle || [];
|
|
79
79
|
return bundleItems.reduce((sum, item) => {
|
|
80
80
|
const quantity = getSafeNum(item == null ? void 0 : item.num);
|
|
81
|
-
const
|
|
82
|
-
return sum.plus(
|
|
81
|
+
const signedUnit = (0, import_utils2.getBundleSignedUnit)(item, { useOriginal });
|
|
82
|
+
return sum.plus(signedUnit.times(quantity));
|
|
83
83
|
}, new import_decimal.default(0));
|
|
84
84
|
}
|
|
85
85
|
function getUnitPaymentTotal(product) {
|
|
@@ -107,6 +107,7 @@ function buildSurchargeServiceItems(products) {
|
|
|
107
107
|
const quantity = getSafeNum(product.num);
|
|
108
108
|
const unitTotal = getUnitPaymentTotal(product);
|
|
109
109
|
const options = (0, import_utils2.getProductSkuOptions)(product);
|
|
110
|
+
const persistedSurchargeFee = getPersistedMainSurchargeFee(product);
|
|
110
111
|
return {
|
|
111
112
|
id: product.product_id,
|
|
112
113
|
num: quantity,
|
|
@@ -125,7 +126,10 @@ function buildSurchargeServiceItems(products) {
|
|
|
125
126
|
option: options,
|
|
126
127
|
options,
|
|
127
128
|
relation_details: [],
|
|
128
|
-
metadata:
|
|
129
|
+
metadata: {
|
|
130
|
+
...product.metadata || {},
|
|
131
|
+
__persisted_surcharge_fee: persistedSurchargeFee == null ? void 0 : persistedSurchargeFee.toFixed(2)
|
|
132
|
+
},
|
|
129
133
|
start_date: ((_a = product.metadata) == null ? void 0 : _a.start_date) || "",
|
|
130
134
|
start_time: ((_b = product.metadata) == null ? void 0 : _b.start_time) || ""
|
|
131
135
|
};
|
|
@@ -133,10 +137,11 @@ function buildSurchargeServiceItems(products) {
|
|
|
133
137
|
}
|
|
134
138
|
function getRelationSurchargeIds(item) {
|
|
135
139
|
var _a;
|
|
136
|
-
const ids =
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
+
const ids = [
|
|
141
|
+
...Array.isArray(item == null ? void 0 : item.relation_surcharge_ids) ? item.relation_surcharge_ids : [],
|
|
142
|
+
...Array.isArray((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.relation_surcharge_ids) ? item.metadata.relation_surcharge_ids : []
|
|
143
|
+
];
|
|
144
|
+
return [...new Set(ids.filter((id) => id !== void 0 && id !== null && id !== ""))];
|
|
140
145
|
}
|
|
141
146
|
function getSurchargeConfigId(config) {
|
|
142
147
|
return (config == null ? void 0 : config.id) ?? (config == null ? void 0 : config.surcharge_id);
|
|
@@ -169,6 +174,50 @@ function getBundleProductId(bundle) {
|
|
|
169
174
|
return null;
|
|
170
175
|
return parsed;
|
|
171
176
|
}
|
|
177
|
+
function getPersistedMainSurchargeFee(product) {
|
|
178
|
+
var _a;
|
|
179
|
+
if ((product == null ? void 0 : product.order_detail_id) === void 0 || (product == null ? void 0 : product.order_detail_id) === null)
|
|
180
|
+
return null;
|
|
181
|
+
const value = (product == null ? void 0 : product.surcharge_fee) ?? (product == null ? void 0 : product.main_product_attached_bundle_surcharge_fee) ?? ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.main_product_attached_bundle_surcharge_fee);
|
|
182
|
+
if (value === void 0 || value === null || value === "")
|
|
183
|
+
return null;
|
|
184
|
+
return toDecimal(value);
|
|
185
|
+
}
|
|
186
|
+
function getPersistedSourceSurchargeFee(sourceItem) {
|
|
187
|
+
var _a;
|
|
188
|
+
const value = (_a = sourceItem == null ? void 0 : sourceItem.metadata) == null ? void 0 : _a.__persisted_surcharge_fee;
|
|
189
|
+
if (value === void 0 || value === null || value === "")
|
|
190
|
+
return null;
|
|
191
|
+
return toDecimal(value);
|
|
192
|
+
}
|
|
193
|
+
function getPersistedSurchargeRemainder(item, sourceItem) {
|
|
194
|
+
var _a, _b;
|
|
195
|
+
const value = ((_a = sourceItem == null ? void 0 : sourceItem.metadata) == null ? void 0 : _a.surcharge_rounding_remainder) ?? (item == null ? void 0 : item.surcharge_rounding_remainder) ?? ((_b = item == null ? void 0 : item.metadata) == null ? void 0 : _b.surcharge_rounding_remainder);
|
|
196
|
+
if (value === void 0 || value === null || value === "")
|
|
197
|
+
return null;
|
|
198
|
+
return toDecimal(value);
|
|
199
|
+
}
|
|
200
|
+
function getPersistedQuantity(item, fallbackQuantity) {
|
|
201
|
+
const isPersistedLine = (item == null ? void 0 : item.order_detail_id) !== void 0 && (item == null ? void 0 : item.order_detail_id) !== null;
|
|
202
|
+
if (!isPersistedLine)
|
|
203
|
+
return new import_decimal.default(0);
|
|
204
|
+
const value = (item == null ? void 0 : item.product_quantity) ?? (item == null ? void 0 : item.quantity);
|
|
205
|
+
const parsed = new import_decimal.default(value || 0);
|
|
206
|
+
if (parsed.lte(0))
|
|
207
|
+
return import_decimal.default.min(fallbackQuantity, 1);
|
|
208
|
+
return import_decimal.default.min(fallbackQuantity, parsed);
|
|
209
|
+
}
|
|
210
|
+
function getPersistedBundleSurchargeFee(bundle, product) {
|
|
211
|
+
var _a;
|
|
212
|
+
if ((bundle == null ? void 0 : bundle.order_detail_id) === void 0 && (product == null ? void 0 : product.order_detail_id) === void 0)
|
|
213
|
+
return null;
|
|
214
|
+
if ((bundle == null ? void 0 : bundle.order_detail_id) === null && (product == null ? void 0 : product.order_detail_id) === null)
|
|
215
|
+
return null;
|
|
216
|
+
const value = (bundle == null ? void 0 : bundle.surcharge_fee) ?? ((_a = bundle == null ? void 0 : bundle.metadata) == null ? void 0 : _a.surcharge_fee);
|
|
217
|
+
if (value === void 0 || value === null || value === "")
|
|
218
|
+
return null;
|
|
219
|
+
return toDecimal(value);
|
|
220
|
+
}
|
|
172
221
|
function createSurchargeAllocationNodes(products, sourceItems) {
|
|
173
222
|
var _a;
|
|
174
223
|
const nodes = [];
|
|
@@ -188,7 +237,10 @@ function createSurchargeAllocationNodes(products, sourceItems) {
|
|
|
188
237
|
productId: getBundleProductId(bundle),
|
|
189
238
|
unitAmount: getBundleSurchargeUnitAmount(bundle),
|
|
190
239
|
quantity: new import_decimal.default(getSafeNum((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity))).times(productQuantity),
|
|
191
|
-
|
|
240
|
+
persistedQuantity: getPersistedQuantity(bundle, new import_decimal.default(getSafeNum((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity))).times(productQuantity)),
|
|
241
|
+
relationSurchargeIds: getRelationSurchargeIds(sourceBundle).length ? getRelationSurchargeIds(sourceBundle) : getRelationSurchargeIds(bundle),
|
|
242
|
+
persistedUnitSurchargeFee: getPersistedBundleSurchargeFee(bundle, product),
|
|
243
|
+
persistedSurchargeRemainder: getPersistedSurchargeRemainder(bundle, sourceBundle)
|
|
192
244
|
});
|
|
193
245
|
}
|
|
194
246
|
nodes.push({
|
|
@@ -198,7 +250,10 @@ function createSurchargeAllocationNodes(products, sourceItems) {
|
|
|
198
250
|
productId: product.product_id ?? null,
|
|
199
251
|
unitAmount: getMainSurchargeUnitAmount(product),
|
|
200
252
|
quantity: productQuantity,
|
|
201
|
-
|
|
253
|
+
persistedQuantity: getPersistedQuantity(product, productQuantity),
|
|
254
|
+
relationSurchargeIds: getRelationSurchargeIds(sourceItem).length ? getRelationSurchargeIds(sourceItem) : getRelationSurchargeIds(product),
|
|
255
|
+
persistedUnitSurchargeFee: getPersistedSourceSurchargeFee(sourceItem) ?? getPersistedMainSurchargeFee(product),
|
|
256
|
+
persistedSurchargeRemainder: getPersistedSurchargeRemainder(product, sourceItem)
|
|
202
257
|
});
|
|
203
258
|
}
|
|
204
259
|
return nodes;
|
|
@@ -221,6 +276,17 @@ function resetProductSurchargeFields(products) {
|
|
|
221
276
|
}
|
|
222
277
|
}
|
|
223
278
|
}
|
|
279
|
+
function getPersistedSurchargeIds(nodes) {
|
|
280
|
+
const ids = /* @__PURE__ */ new Set();
|
|
281
|
+
for (const node of nodes) {
|
|
282
|
+
if (!node.persistedUnitSurchargeFee || node.persistedUnitSurchargeFee.lte(0))
|
|
283
|
+
continue;
|
|
284
|
+
for (const surchargeId of node.relationSurchargeIds) {
|
|
285
|
+
ids.add(surchargeId);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return ids;
|
|
289
|
+
}
|
|
224
290
|
function buildSurchargeQuantityTotals(nodes) {
|
|
225
291
|
const totals = /* @__PURE__ */ new Map();
|
|
226
292
|
for (const node of nodes) {
|
|
@@ -261,6 +327,24 @@ function getBackendSurchargeState(stateMap, surchargeId, config) {
|
|
|
261
327
|
}
|
|
262
328
|
return state;
|
|
263
329
|
}
|
|
330
|
+
function buildSurchargeResultItem(config, surchargeId, amount, index) {
|
|
331
|
+
const name = (config == null ? void 0 : config.name) || (config == null ? void 0 : config.label) || {};
|
|
332
|
+
return {
|
|
333
|
+
key: `custom_surcharge_${index}`,
|
|
334
|
+
label: name,
|
|
335
|
+
name,
|
|
336
|
+
value: amount.toNumber(),
|
|
337
|
+
surcharge_id: surchargeId,
|
|
338
|
+
description: config == null ? void 0 : config.description,
|
|
339
|
+
type: "default",
|
|
340
|
+
fixed: config == null ? void 0 : config.fixed,
|
|
341
|
+
amount: amount.toNumber(),
|
|
342
|
+
percentage: config == null ? void 0 : config.percentage,
|
|
343
|
+
metadata: {
|
|
344
|
+
open_product: config == null ? void 0 : config.open_product
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
264
348
|
function applySurchargeNodeResult(node, params) {
|
|
265
349
|
const { unitSurchargeFee, roundingRemainder, surchargeIds } = params;
|
|
266
350
|
if (node.kind === "main") {
|
|
@@ -290,16 +374,64 @@ function calculateBackendProductSurcharges(params) {
|
|
|
290
374
|
node.relationSurchargeIds = fallbackAllProductSurchargeIds;
|
|
291
375
|
}
|
|
292
376
|
}
|
|
377
|
+
const persistedSurchargeIds = getPersistedSurchargeIds(nodes);
|
|
293
378
|
const quantityTotals = buildSurchargeQuantityTotals(nodes);
|
|
294
379
|
const stateMap = /* @__PURE__ */ new Map();
|
|
295
380
|
for (const node of nodes) {
|
|
296
381
|
let unitSurchargeFee = new import_decimal.default(0);
|
|
297
382
|
let roundingRemainder = new import_decimal.default(0);
|
|
298
383
|
const appliedSurchargeIds = [];
|
|
384
|
+
let persistedRemainderApplied = false;
|
|
299
385
|
for (const surchargeId of node.relationSurchargeIds) {
|
|
300
386
|
const config = configById.get(surchargeId);
|
|
301
387
|
const totalQuantity = quantityTotals.get(surchargeId) || new import_decimal.default(0);
|
|
302
|
-
if (
|
|
388
|
+
if (totalQuantity.lte(0))
|
|
389
|
+
continue;
|
|
390
|
+
const persistedUnitSurchargeFee = node.persistedUnitSurchargeFee;
|
|
391
|
+
if (persistedUnitSurchargeFee && persistedUnitSurchargeFee.gt(0)) {
|
|
392
|
+
const persistedQuantity = import_decimal.default.min(node.persistedQuantity, node.quantity);
|
|
393
|
+
const deltaQuantity = import_decimal.default.max(node.quantity.minus(persistedQuantity), 0);
|
|
394
|
+
const state2 = getBackendSurchargeState(
|
|
395
|
+
stateMap,
|
|
396
|
+
surchargeId,
|
|
397
|
+
config || { surcharge_id: surchargeId }
|
|
398
|
+
);
|
|
399
|
+
const persistedSurchargeRemainder = !persistedRemainderApplied && node.persistedSurchargeRemainder ? node.persistedSurchargeRemainder : new import_decimal.default(0);
|
|
400
|
+
state2.amount = bcAdd(
|
|
401
|
+
bcAdd(
|
|
402
|
+
state2.amount,
|
|
403
|
+
bcMul(persistedUnitSurchargeFee, persistedQuantity, 2),
|
|
404
|
+
2
|
|
405
|
+
),
|
|
406
|
+
persistedSurchargeRemainder,
|
|
407
|
+
2
|
|
408
|
+
);
|
|
409
|
+
const fixed2 = new import_decimal.default((config == null ? void 0 : config.fixed) || 0);
|
|
410
|
+
if (fixed2.gt(0))
|
|
411
|
+
state2.fixedIncluded = true;
|
|
412
|
+
let nodeTotalSurcharge = bcAdd(
|
|
413
|
+
bcMul(persistedUnitSurchargeFee, persistedQuantity, 2),
|
|
414
|
+
persistedSurchargeRemainder,
|
|
415
|
+
2
|
|
416
|
+
);
|
|
417
|
+
if (config && deltaQuantity.gt(0)) {
|
|
418
|
+
const percentage2 = new import_decimal.default(config.percentage || 0);
|
|
419
|
+
const deltaUnitPercentageFee = import_decimal.default.max(0, bcMul(node.unitAmount, percentage2, 2));
|
|
420
|
+
const deltaSurcharge = bcMul(deltaQuantity, deltaUnitPercentageFee, 2);
|
|
421
|
+
state2.amount = bcAdd(state2.amount, deltaSurcharge, 2);
|
|
422
|
+
nodeTotalSurcharge = bcAdd(nodeTotalSurcharge, deltaSurcharge, 2);
|
|
423
|
+
}
|
|
424
|
+
if (node.quantity.gt(0)) {
|
|
425
|
+
unitSurchargeFee = bcAdd(unitSurchargeFee, bcDiv(nodeTotalSurcharge, node.quantity, 2), 2);
|
|
426
|
+
}
|
|
427
|
+
if (!persistedSurchargeRemainder.eq(0)) {
|
|
428
|
+
roundingRemainder = bcAdd(roundingRemainder, persistedSurchargeRemainder, 2);
|
|
429
|
+
persistedRemainderApplied = true;
|
|
430
|
+
}
|
|
431
|
+
appliedSurchargeIds.push(surchargeId);
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (!config)
|
|
303
435
|
continue;
|
|
304
436
|
const percentage = new import_decimal.default(config.percentage || 0);
|
|
305
437
|
const fixed = new import_decimal.default(config.fixed || 0);
|
|
@@ -307,7 +439,7 @@ function calculateBackendProductSurcharges(params) {
|
|
|
307
439
|
const percentageTotalFee = bcMul(node.quantity, unitPercentageFee, 2);
|
|
308
440
|
let unitFixedFee = new import_decimal.default(0);
|
|
309
441
|
let fixedRemainder = new import_decimal.default(0);
|
|
310
|
-
if (fixed.gt(0)) {
|
|
442
|
+
if (fixed.gt(0) && !persistedSurchargeIds.has(surchargeId)) {
|
|
311
443
|
unitFixedFee = bcDiv(fixed, totalQuantity, 2);
|
|
312
444
|
const distributedFixed = bcMul(unitFixedFee, totalQuantity, 2);
|
|
313
445
|
fixedRemainder = bcSub(fixed, distributedFixed, 2);
|
|
@@ -328,7 +460,7 @@ function calculateBackendProductSurcharges(params) {
|
|
|
328
460
|
6
|
|
329
461
|
);
|
|
330
462
|
state.calculatedQuantity = bcAdd(state.calculatedQuantity, node.quantity, 6);
|
|
331
|
-
if (!state.fixedIncluded && fixed.gt(0)) {
|
|
463
|
+
if (!state.fixedIncluded && fixed.gt(0) && !persistedSurchargeIds.has(surchargeId)) {
|
|
332
464
|
state.amount = bcAdd(state.amount, fixed, 2);
|
|
333
465
|
state.fixedIncluded = true;
|
|
334
466
|
}
|
|
@@ -351,31 +483,25 @@ function calculateBackendProductSurcharges(params) {
|
|
|
351
483
|
surchargeIds: appliedSurchargeIds
|
|
352
484
|
});
|
|
353
485
|
}
|
|
354
|
-
|
|
486
|
+
const result = (surchargeList || []).reduce((items, config, index) => {
|
|
355
487
|
const surchargeId = getSurchargeConfigId(config);
|
|
356
488
|
if (surchargeId === void 0)
|
|
357
|
-
return
|
|
489
|
+
return items;
|
|
358
490
|
const state = stateMap.get(surchargeId);
|
|
359
491
|
if (!state || state.amount.lte(0))
|
|
360
|
-
return
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
key: `custom_surcharge_${index}`,
|
|
364
|
-
label: name,
|
|
365
|
-
name,
|
|
366
|
-
value: state.amount.toNumber(),
|
|
367
|
-
surcharge_id: surchargeId,
|
|
368
|
-
description: config.description,
|
|
369
|
-
type: "default",
|
|
370
|
-
fixed: config.fixed,
|
|
371
|
-
amount: state.amount.toNumber(),
|
|
372
|
-
percentage: config.percentage,
|
|
373
|
-
metadata: {
|
|
374
|
-
open_product: config.open_product
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
return result;
|
|
492
|
+
return items;
|
|
493
|
+
items.push(buildSurchargeResultItem(config, surchargeId, state.amount, index));
|
|
494
|
+
return items;
|
|
378
495
|
}, []);
|
|
496
|
+
const includedIds = new Set(
|
|
497
|
+
result.map((item) => item == null ? void 0 : item.surcharge_id).filter((id) => id !== void 0)
|
|
498
|
+
);
|
|
499
|
+
for (const [surchargeId, state] of stateMap.entries()) {
|
|
500
|
+
if (includedIds.has(surchargeId) || state.amount.lte(0))
|
|
501
|
+
continue;
|
|
502
|
+
result.push(buildSurchargeResultItem(state.config, surchargeId, state.amount, result.length));
|
|
503
|
+
}
|
|
504
|
+
return result;
|
|
379
505
|
}
|
|
380
506
|
function getProductDepositData(product) {
|
|
381
507
|
var _a, _b, _c;
|
|
@@ -481,20 +607,28 @@ function calculateSingleItemTax(params) {
|
|
|
481
607
|
return new import_decimal.default(0);
|
|
482
608
|
return price.dividedBy(divisor).times(rate);
|
|
483
609
|
}
|
|
484
|
-
function
|
|
610
|
+
function getMainAttachedBundleSellingTotal(product) {
|
|
485
611
|
var _a, _b;
|
|
486
612
|
const mainSelling = ((_a = product.metadata) == null ? void 0 : _a.main_product_selling_price) ?? ((_b = product.metadata) == null ? void 0 : _b.main_product_original_price) ?? 0;
|
|
487
613
|
let total = toDecimal(mainSelling);
|
|
488
614
|
const bundleItems = product.product_bundle || [];
|
|
489
615
|
for (const bundleItem of bundleItems) {
|
|
490
616
|
if (isBundleMarkupOrDiscount(bundleItem)) {
|
|
491
|
-
const unit =
|
|
617
|
+
const unit = (0, import_utils2.getBundleSignedUnit)(bundleItem);
|
|
492
618
|
const qty = getSafeNum(bundleItem.num ?? bundleItem.quantity);
|
|
493
619
|
total = total.plus(unit.times(qty));
|
|
494
620
|
}
|
|
495
621
|
}
|
|
496
622
|
return import_decimal.default.max(total, 0);
|
|
497
623
|
}
|
|
624
|
+
function getMainProductPaymentTotal(product) {
|
|
625
|
+
var _a;
|
|
626
|
+
const attachedPayment = (_a = product.metadata) == null ? void 0 : _a.main_product_attached_bundle_payment_price;
|
|
627
|
+
if (attachedPayment !== void 0 && attachedPayment !== null && attachedPayment !== "") {
|
|
628
|
+
return import_decimal.default.max(toDecimal(attachedPayment), 0);
|
|
629
|
+
}
|
|
630
|
+
return getMainAttachedBundleSellingTotal(product);
|
|
631
|
+
}
|
|
498
632
|
function getExplicitTaxRemainder(item) {
|
|
499
633
|
var _a;
|
|
500
634
|
const value = (item == null ? void 0 : item.tax_fee_rounding_remainder) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.tax_fee_rounding_remainder);
|
|
@@ -508,6 +642,15 @@ function getPersistedTaxRemainder(item, parentProduct) {
|
|
|
508
642
|
return null;
|
|
509
643
|
return getExplicitTaxRemainder(item);
|
|
510
644
|
}
|
|
645
|
+
function getPersistedMainTaxFee(product) {
|
|
646
|
+
var _a;
|
|
647
|
+
if ((product == null ? void 0 : product.order_detail_id) === void 0 || (product == null ? void 0 : product.order_detail_id) === null)
|
|
648
|
+
return null;
|
|
649
|
+
const value = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.main_product_attached_bundle_tax_fee) ?? (product == null ? void 0 : product.main_product_attached_bundle_tax_fee) ?? (product == null ? void 0 : product.tax_fee);
|
|
650
|
+
if (value === void 0 || value === null || value === "")
|
|
651
|
+
return null;
|
|
652
|
+
return toDecimal(value);
|
|
653
|
+
}
|
|
511
654
|
function writeTaxRemainder(item, roundingRemainder) {
|
|
512
655
|
item.tax_fee_rounding_remainder = roundingRemainder.toNumber();
|
|
513
656
|
if (item.metadata && typeof item.metadata === "object") {
|
|
@@ -517,15 +660,24 @@ function writeTaxRemainder(item, roundingRemainder) {
|
|
|
517
660
|
function resetTaxRemainderFields(products) {
|
|
518
661
|
for (const product of products) {
|
|
519
662
|
const productRemainder = getPersistedTaxRemainder(product);
|
|
520
|
-
|
|
663
|
+
if (productRemainder !== null) {
|
|
664
|
+
product.tax_fee_rounding_remainder = productRemainder.toNumber();
|
|
665
|
+
} else {
|
|
666
|
+
delete product.tax_fee_rounding_remainder;
|
|
667
|
+
}
|
|
521
668
|
product.original_tax_fee_rounding_remainder = 0;
|
|
522
669
|
for (const bundle of product.product_bundle || []) {
|
|
523
670
|
const bundleRemainder = getPersistedTaxRemainder(bundle, product);
|
|
524
671
|
bundle.metadata = {
|
|
525
|
-
...bundle.metadata || {}
|
|
526
|
-
tax_fee_rounding_remainder: (bundleRemainder == null ? void 0 : bundleRemainder.toFixed(2)) ?? "0.00"
|
|
672
|
+
...bundle.metadata || {}
|
|
527
673
|
};
|
|
528
|
-
|
|
674
|
+
if (bundleRemainder !== null) {
|
|
675
|
+
bundle.metadata.tax_fee_rounding_remainder = bundleRemainder.toFixed(2);
|
|
676
|
+
bundle.tax_fee_rounding_remainder = bundleRemainder.toNumber();
|
|
677
|
+
} else {
|
|
678
|
+
delete bundle.metadata.tax_fee_rounding_remainder;
|
|
679
|
+
delete bundle.tax_fee_rounding_remainder;
|
|
680
|
+
}
|
|
529
681
|
bundle.original_tax_fee_rounding_remainder = 0;
|
|
530
682
|
}
|
|
531
683
|
}
|
|
@@ -617,17 +769,22 @@ function calculateProductsTax(products, taxRate, isPriceIncludeTax) {
|
|
|
617
769
|
isChargeTax: product.is_charge_tax ?? 0
|
|
618
770
|
});
|
|
619
771
|
const mainTaxRounded = toBackendTaxFee(mainTaxPrecise);
|
|
620
|
-
product.main_product_attached_bundle_tax_fee = mainTaxRounded.toFixed(2);
|
|
621
772
|
const persistedMainRemainder = getPersistedTaxRemainder(product);
|
|
622
|
-
const
|
|
773
|
+
const persistedMainTaxFee = getPersistedMainTaxFee(product);
|
|
774
|
+
const persistedQuantity = getPersistedQuantity(product, quantity);
|
|
775
|
+
const deltaQuantity = import_decimal.default.max(quantity.minus(persistedQuantity), 0);
|
|
776
|
+
const shouldUsePersistedMainTax = persistedMainTaxFee && persistedMainTaxFee.gt(0) && persistedQuantity.gte(quantity);
|
|
777
|
+
const shouldSplitPersistedMainTax = persistedMainTaxFee && persistedMainTaxFee.gt(0) && persistedQuantity.gt(0) && deltaQuantity.gt(0);
|
|
778
|
+
const mainRemainder = shouldUsePersistedMainTax || shouldSplitPersistedMainTax ? new import_decimal.default(0) : persistedMainRemainder ?? applyBackendTaxRemainder({
|
|
623
779
|
target: product,
|
|
624
780
|
rawTax: mainTaxPrecise,
|
|
625
781
|
formattedTax: mainTaxRounded,
|
|
626
782
|
quantity,
|
|
627
783
|
state: taxRemainderState
|
|
628
784
|
});
|
|
629
|
-
if (persistedMainRemainder)
|
|
785
|
+
if (persistedMainRemainder && !shouldSplitPersistedMainTax) {
|
|
630
786
|
writeTaxRemainder(product, persistedMainRemainder);
|
|
787
|
+
}
|
|
631
788
|
const originalTotal = getUnitOriginalTotal(product);
|
|
632
789
|
const originalTaxableBase = originalTotal.lte(0) ? surchargeFee : originalTotal.plus(surchargeFee);
|
|
633
790
|
const originalTaxPrecise = calculateSingleItemTax({
|
|
@@ -637,18 +794,64 @@ function calculateProductsTax(products, taxRate, isPriceIncludeTax) {
|
|
|
637
794
|
isChargeTax: product.is_charge_tax ?? 0
|
|
638
795
|
});
|
|
639
796
|
const originalTaxRounded = toAmountFormat(originalTaxPrecise);
|
|
640
|
-
|
|
797
|
+
const effectiveMainUnitTax = shouldUsePersistedMainTax ? persistedMainTaxFee : shouldSplitPersistedMainTax ? persistedMainTaxFee.times(persistedQuantity).plus(mainTaxRounded.times(deltaQuantity)).div(quantity).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP) : mainTaxRounded;
|
|
798
|
+
productUnitTax = productUnitTax.plus(effectiveMainUnitTax);
|
|
641
799
|
productUnitOriginTax = productUnitOriginTax.plus(originalTaxRounded);
|
|
800
|
+
product.main_product_attached_bundle_tax_fee = effectiveMainUnitTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toFixed(2);
|
|
642
801
|
product.tax_fee = productUnitTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toFixed(2);
|
|
643
802
|
product.original_tax_fee = productUnitOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
644
|
-
totalTax = totalTax.plus(
|
|
803
|
+
totalTax = totalTax.plus(
|
|
804
|
+
shouldUsePersistedMainTax ? persistedMainTaxFee.times(quantity).plus(persistedMainRemainder || 0) : shouldSplitPersistedMainTax ? persistedMainTaxFee.times(persistedQuantity).plus(mainTaxRounded.times(deltaQuantity)) : mainTaxRounded.times(quantity).plus(mainRemainder)
|
|
805
|
+
);
|
|
645
806
|
totalOriginTax = totalOriginTax.plus(originalTaxRounded.times(quantity));
|
|
807
|
+
if (product.tax_fee_rounding_remainder === void 0) {
|
|
808
|
+
product.tax_fee_rounding_remainder = 0;
|
|
809
|
+
}
|
|
646
810
|
}
|
|
647
811
|
return {
|
|
648
812
|
tax: totalTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP),
|
|
649
813
|
originTax: totalOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP)
|
|
650
814
|
};
|
|
651
815
|
}
|
|
816
|
+
function allocateShopDiscountToPayment(products, productAmount, shopDiscountAmount) {
|
|
817
|
+
const effectiveDiscount = productAmount.lte(0) ? new import_decimal.default(0) : import_decimal.default.max(import_decimal.default.min(productAmount, shopDiscountAmount), 0);
|
|
818
|
+
let allocatedDiscount = new import_decimal.default(0);
|
|
819
|
+
products.forEach((product, index) => {
|
|
820
|
+
const quantity = new import_decimal.default(getSafeNum(product.num));
|
|
821
|
+
const sellingUnit = getUnitPaymentTotal(product);
|
|
822
|
+
const lineSellingTotal = sellingUnit.times(quantity);
|
|
823
|
+
const lineDiscount = effectiveDiscount.lte(0) ? new import_decimal.default(0) : index === products.length - 1 ? import_decimal.default.max(effectiveDiscount.minus(allocatedDiscount), 0) : toAmountFormat(lineSellingTotal.div(productAmount).times(effectiveDiscount));
|
|
824
|
+
allocatedDiscount = allocatedDiscount.plus(lineDiscount);
|
|
825
|
+
const unitDiscount = quantity.lte(0) ? new import_decimal.default(0) : lineDiscount.div(quantity);
|
|
826
|
+
const paymentUnit = import_decimal.default.max(sellingUnit.minus(unitDiscount), 0);
|
|
827
|
+
const rate = sellingUnit.lte(0) ? new import_decimal.default(1) : toBcScale(paymentUnit.div(sellingUnit), 6);
|
|
828
|
+
const mainSellingTotal = getMainAttachedBundleSellingTotal(product);
|
|
829
|
+
const mainPaymentTotal = toAmountFormat(bcMul(mainSellingTotal, rate, 6));
|
|
830
|
+
product.metadata = {
|
|
831
|
+
...product.metadata || {},
|
|
832
|
+
average_discount_amount_rate: rate.toString(),
|
|
833
|
+
main_product_attached_bundle_selling_price: mainSellingTotal.toFixed(2),
|
|
834
|
+
main_product_attached_bundle_payment_price: mainPaymentTotal.toFixed(2)
|
|
835
|
+
};
|
|
836
|
+
for (const bundle of product.product_bundle || []) {
|
|
837
|
+
if (isBundleOriginalPrice(bundle)) {
|
|
838
|
+
const bundleSelling = toDecimal(
|
|
839
|
+
bundle.bundle_selling_price ?? bundle.bundle_sum_price ?? bundle.price ?? 0
|
|
840
|
+
);
|
|
841
|
+
bundle.bundle_payment_price = toAmountFormat(bcMul(bundleSelling, rate, 6)).toFixed(2);
|
|
842
|
+
continue;
|
|
843
|
+
}
|
|
844
|
+
if ((0, import_utils2.isMarkdownBundle)(bundle)) {
|
|
845
|
+
const magnitude = (0, import_utils2.getBundleSellingMagnitude)(bundle);
|
|
846
|
+
bundle.custom_price = bundle.custom_price ?? bundle.price;
|
|
847
|
+
bundle.price = magnitude.toFixed(2);
|
|
848
|
+
bundle.bundle_selling_price = magnitude.toFixed(2);
|
|
849
|
+
bundle.bundle_payment_price = toAmountFormat(bcMul(magnitude, rate, 6)).toFixed(2);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
product.payment_price = paymentUnit.toFixed(2);
|
|
853
|
+
});
|
|
854
|
+
}
|
|
652
855
|
function createEmptySalesSummary() {
|
|
653
856
|
return {
|
|
654
857
|
product_quantity: 0,
|
|
@@ -700,6 +903,14 @@ function calculateSalesSummary(params) {
|
|
|
700
903
|
(sum, item) => sum.plus(getUnitPaymentTotal(item).times(getSafeNum(item.num))),
|
|
701
904
|
new import_decimal.default(0)
|
|
702
905
|
);
|
|
906
|
+
const shopDiscountAmount = import_decimal.default.max(new import_decimal.default(Number(shopDiscount) || 0), 0);
|
|
907
|
+
const hasPersistedSurchargeSnapshot = summaryProducts.some((product) => {
|
|
908
|
+
var _a;
|
|
909
|
+
return (_a = getPersistedMainSurchargeFee(product)) == null ? void 0 : _a.gt(0);
|
|
910
|
+
});
|
|
911
|
+
if (!hasPersistedSurchargeSnapshot) {
|
|
912
|
+
allocateShopDiscountToPayment(summaryProducts, productAmount, shopDiscountAmount);
|
|
913
|
+
}
|
|
703
914
|
const surchargeServiceItems = buildSurchargeServiceItems(summaryProducts);
|
|
704
915
|
(0, import_utils.getSurcharge)(
|
|
705
916
|
{
|
|
@@ -738,9 +949,8 @@ function calculateSalesSummary(params) {
|
|
|
738
949
|
new import_decimal.default(0)
|
|
739
950
|
);
|
|
740
951
|
}
|
|
741
|
-
const
|
|
742
|
-
const
|
|
743
|
-
const totalAmount = isPriceIncludeTax === 1 ? preTaxExpectAmount : preTaxExpectAmount.plus(productTaxFee);
|
|
952
|
+
const orderAmountBeforeDiscount = productAmount.plus(surchargeAmount).plus(isPriceIncludeTax === 1 ? 0 : productTaxFee);
|
|
953
|
+
const totalAmount = import_decimal.default.max(0, orderAmountBeforeDiscount.minus(shopDiscountAmount));
|
|
744
954
|
const deposit = calculateProductsDeposit(summaryProducts);
|
|
745
955
|
return {
|
|
746
956
|
product_quantity: productQuantity,
|
package/lib/server/index.d.ts
CHANGED
|
@@ -287,6 +287,8 @@ declare class Server {
|
|
|
287
287
|
private handleOrderSalesCheckout;
|
|
288
288
|
private handleOrderCheckout;
|
|
289
289
|
private handleOrderCheckoutSubmit;
|
|
290
|
+
private handlePendingSyncCheckoutOrder;
|
|
291
|
+
private buildPendingSyncCheckoutOrder;
|
|
290
292
|
private handleOrderSalesDetail;
|
|
291
293
|
/**
|
|
292
294
|
* 解析 order_ids 入参,兼容 url query / data 字段、字符串(csv) / 数组两种形态。
|
|
@@ -320,6 +322,7 @@ declare class Server {
|
|
|
320
322
|
private extractOrderDataFromCheckoutResponse;
|
|
321
323
|
private normalizeCheckoutResponse;
|
|
322
324
|
private extractBackendErrorResponse;
|
|
325
|
+
private isExplicitBackendErrorResponse;
|
|
323
326
|
/**
|
|
324
327
|
* 从 url 或路由 path 解析 pathname(不含 query,去掉末尾 /)
|
|
325
328
|
*/
|
package/lib/server/index.js
CHANGED
|
@@ -1749,7 +1749,12 @@ var Server = class {
|
|
|
1749
1749
|
});
|
|
1750
1750
|
if (!((_a = this.app) == null ? void 0 : _a.request)) {
|
|
1751
1751
|
this.logError(`${title}: app.request 不可用`);
|
|
1752
|
-
return {
|
|
1752
|
+
return this.handlePendingSyncCheckoutOrder({
|
|
1753
|
+
backendPath,
|
|
1754
|
+
data,
|
|
1755
|
+
title,
|
|
1756
|
+
reason: "app.request 不可用"
|
|
1757
|
+
});
|
|
1753
1758
|
}
|
|
1754
1759
|
try {
|
|
1755
1760
|
const response = await this.app.request.post(backendPath, data, {
|
|
@@ -1759,7 +1764,8 @@ var Server = class {
|
|
|
1759
1764
|
});
|
|
1760
1765
|
const fresh = this.extractOrderDataFromCheckoutResponse(response);
|
|
1761
1766
|
if (fresh && this.order) {
|
|
1762
|
-
|
|
1767
|
+
const syncedOrder = { ...fresh, need_sync: 0 };
|
|
1768
|
+
await this.order.upsertOrdersFromRemote([syncedOrder]);
|
|
1763
1769
|
this.logInfo(`${title}: 订单已同步到本地`, {
|
|
1764
1770
|
order_id: fresh.order_id,
|
|
1765
1771
|
external_sale_number: fresh.external_sale_number,
|
|
@@ -1778,9 +1784,77 @@ var Server = class {
|
|
|
1778
1784
|
const backendError = this.extractBackendErrorResponse(error);
|
|
1779
1785
|
if (backendError)
|
|
1780
1786
|
return backendError;
|
|
1787
|
+
return this.handlePendingSyncCheckoutOrder({
|
|
1788
|
+
backendPath,
|
|
1789
|
+
data,
|
|
1790
|
+
title,
|
|
1791
|
+
reason: errorMessage
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
async handlePendingSyncCheckoutOrder(params) {
|
|
1796
|
+
const { backendPath, data, title, reason } = params;
|
|
1797
|
+
const pendingOrder = this.buildPendingSyncCheckoutOrder(data);
|
|
1798
|
+
if (!pendingOrder) {
|
|
1799
|
+
this.logError(`${title}: checkout 失败且订单缺少本地存储标识`, {
|
|
1800
|
+
backendPath,
|
|
1801
|
+
reason
|
|
1802
|
+
});
|
|
1803
|
+
return {
|
|
1804
|
+
code: 500,
|
|
1805
|
+
status: false,
|
|
1806
|
+
message: "订单缺少本地存储标识,无法写入待同步队列",
|
|
1807
|
+
data: null
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1810
|
+
if (!this.order || typeof this.order.upsertPendingSyncOrders !== "function") {
|
|
1811
|
+
this.logError(`${title}: Order 模块不支持本地待同步写入`, {
|
|
1812
|
+
backendPath,
|
|
1813
|
+
reason
|
|
1814
|
+
});
|
|
1815
|
+
return {
|
|
1816
|
+
code: 500,
|
|
1817
|
+
status: false,
|
|
1818
|
+
message: "Order 模块不支持本地待同步写入",
|
|
1819
|
+
data: null
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
try {
|
|
1823
|
+
await this.order.upsertPendingSyncOrders([pendingOrder]);
|
|
1824
|
+
this.logWarning(`${title}: 后端未明确报错,订单已写入本地待同步`, {
|
|
1825
|
+
backendPath,
|
|
1826
|
+
reason,
|
|
1827
|
+
order_id: pendingOrder.order_id,
|
|
1828
|
+
external_sale_number: pendingOrder.external_sale_number,
|
|
1829
|
+
order_number: pendingOrder.order_number
|
|
1830
|
+
});
|
|
1831
|
+
return {
|
|
1832
|
+
code: 200,
|
|
1833
|
+
status: true,
|
|
1834
|
+
message: "",
|
|
1835
|
+
data: pendingOrder
|
|
1836
|
+
};
|
|
1837
|
+
} catch (error) {
|
|
1838
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1839
|
+
this.logError(`${title}: 写入本地待同步订单失败`, {
|
|
1840
|
+
backendPath,
|
|
1841
|
+
reason,
|
|
1842
|
+
error: errorMessage
|
|
1843
|
+
});
|
|
1781
1844
|
return { code: 500, status: false, message: errorMessage, data: null };
|
|
1782
1845
|
}
|
|
1783
1846
|
}
|
|
1847
|
+
buildPendingSyncCheckoutOrder(data) {
|
|
1848
|
+
if (!data || typeof data !== "object")
|
|
1849
|
+
return null;
|
|
1850
|
+
const hasStorageKey = data.external_sale_number !== void 0 && data.external_sale_number !== null && data.external_sale_number !== "" ? true : data.order_id !== void 0 && data.order_id !== null && data.order_id !== "";
|
|
1851
|
+
if (!hasStorageKey)
|
|
1852
|
+
return null;
|
|
1853
|
+
return {
|
|
1854
|
+
...data,
|
|
1855
|
+
need_sync: 1
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1784
1858
|
/**
|
|
1785
1859
|
* 解析 order_ids 入参,兼容 url query / data 字段、字符串(csv) / 数组两种形态。
|
|
1786
1860
|
* 自动 trim、去空、按字符串去重,输出归一化后的字符串数组。
|
|
@@ -1993,9 +2067,14 @@ var Server = class {
|
|
|
1993
2067
|
error == null ? void 0 : error.body
|
|
1994
2068
|
];
|
|
1995
2069
|
return candidates.find(
|
|
1996
|
-
(candidate) => candidate
|
|
2070
|
+
(candidate) => this.isExplicitBackendErrorResponse(candidate)
|
|
1997
2071
|
) || null;
|
|
1998
2072
|
}
|
|
2073
|
+
isExplicitBackendErrorResponse(candidate) {
|
|
2074
|
+
if (!candidate || typeof candidate !== "object")
|
|
2075
|
+
return false;
|
|
2076
|
+
return candidate.code !== void 0 || candidate.status !== void 0 || typeof candidate.message === "string";
|
|
2077
|
+
}
|
|
1999
2078
|
/**
|
|
2000
2079
|
* 从 url 或路由 path 解析 pathname(不含 query,去掉末尾 /)
|
|
2001
2080
|
*/
|
|
@@ -92,6 +92,11 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
92
92
|
* 供 /update/localOrder 等在「本地尚无该单」时写入新建单。
|
|
93
93
|
*/
|
|
94
94
|
upsertOrdersFromRemote(freshOrders: OrderData[]): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* 将本地待同步订单按 SQLite storage key 合并进 store 并落库。
|
|
97
|
+
* checkout 离线兜底可能没有 order_id,但通常会有 external_sale_number。
|
|
98
|
+
*/
|
|
99
|
+
upsertPendingSyncOrders(pendingOrders: OrderData[]): Promise<void>;
|
|
95
100
|
/**
|
|
96
101
|
* 通过 SSE 按自定义 query 拉取订单(支持 select/with 精简字段)
|
|
97
102
|
*/
|
|
@@ -172,6 +177,9 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
172
177
|
private getStorageItem;
|
|
173
178
|
private setStorageItem;
|
|
174
179
|
private loadOrdersFromSQLite;
|
|
180
|
+
private isPendingSyncOrder;
|
|
181
|
+
private normalizeRemoteSyncedOrder;
|
|
182
|
+
private mergeRemoteSnapshotWithPendingOrders;
|
|
175
183
|
/**
|
|
176
184
|
* 串行执行订单 SQLite 写入任务,避免快照替换与增量 upsert 并发交错。
|
|
177
185
|
*
|