@pisell/pisellos 2.2.192 → 2.2.194
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/model/strategy/adapter/walletPass/utils.js +7 -4
- package/dist/modules/Order/index.d.ts +12 -9
- package/dist/modules/Order/index.js +503 -580
- package/dist/modules/Order/types.d.ts +5 -5
- package/dist/modules/Order/utils/manualProductDiscount.js +1 -1
- package/dist/modules/Order/utils.js +3 -3
- package/dist/modules/Payment/utils.js +2 -1
- package/dist/modules/SalesSummary/index.d.ts +0 -25
- package/dist/modules/SalesSummary/types.d.ts +1 -0
- package/dist/modules/SalesSummary/utils.d.ts +2 -25
- package/dist/modules/SalesSummary/utils.js +529 -160
- package/dist/server/index.d.ts +8 -1
- package/dist/server/index.js +653 -466
- package/dist/server/modules/order/index.d.ts +3 -2
- package/dist/server/modules/order/index.js +68 -52
- package/dist/server/modules/products/index.js +4 -4
- package/dist/solution/BaseSales/index.d.ts +2 -1
- package/dist/solution/BaseSales/index.js +116 -122
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +0 -1
- package/dist/solution/ScanOrder/index.js +3 -1
- package/lib/model/strategy/adapter/walletPass/utils.js +3 -2
- package/lib/modules/Order/index.d.ts +12 -9
- package/lib/modules/Order/index.js +124 -120
- package/lib/modules/Order/types.d.ts +5 -5
- package/lib/modules/Order/utils/manualProductDiscount.js +1 -1
- package/lib/modules/Order/utils.js +4 -4
- package/lib/modules/Payment/utils.js +2 -1
- package/lib/modules/SalesSummary/index.d.ts +0 -25
- package/lib/modules/SalesSummary/types.d.ts +1 -0
- package/lib/modules/SalesSummary/utils.d.ts +2 -25
- package/lib/modules/SalesSummary/utils.js +420 -92
- package/lib/server/index.d.ts +8 -1
- package/lib/server/index.js +145 -26
- package/lib/server/modules/order/index.d.ts +3 -2
- package/lib/server/modules/order/index.js +25 -15
- package/lib/server/modules/products/index.js +0 -4
- package/lib/solution/BaseSales/index.d.ts +2 -1
- package/lib/solution/BaseSales/index.js +53 -16
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +0 -1
- package/lib/solution/ScanOrder/index.js +3 -1
- package/package.json +1 -1
|
@@ -42,6 +42,31 @@ function toDecimal(value) {
|
|
|
42
42
|
function toFixed2(value) {
|
|
43
43
|
return new import_decimal.default(value || 0).toFixed(2);
|
|
44
44
|
}
|
|
45
|
+
function toAmountFormat(value) {
|
|
46
|
+
return new import_decimal.default(value || 0).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
47
|
+
}
|
|
48
|
+
function toBackendTaxFee(value) {
|
|
49
|
+
return toBcScale(value, 2);
|
|
50
|
+
}
|
|
51
|
+
function toBcScale(value, scale) {
|
|
52
|
+
const factor = new import_decimal.default(10).pow(scale);
|
|
53
|
+
return new import_decimal.default(value || 0).times(factor).toDecimalPlaces(0, import_decimal.default.ROUND_DOWN).div(factor);
|
|
54
|
+
}
|
|
55
|
+
function bcAdd(left, right, scale) {
|
|
56
|
+
return toBcScale(new import_decimal.default(left || 0).plus(right || 0), scale);
|
|
57
|
+
}
|
|
58
|
+
function bcSub(left, right, scale) {
|
|
59
|
+
return toBcScale(new import_decimal.default(left || 0).minus(right || 0), scale);
|
|
60
|
+
}
|
|
61
|
+
function bcMul(left, right, scale) {
|
|
62
|
+
return toBcScale(new import_decimal.default(left || 0).times(right || 0), scale);
|
|
63
|
+
}
|
|
64
|
+
function bcDiv(left, right, scale) {
|
|
65
|
+
const divisor = new import_decimal.default(right || 0);
|
|
66
|
+
if (divisor.eq(0))
|
|
67
|
+
return new import_decimal.default(0);
|
|
68
|
+
return toBcScale(new import_decimal.default(left || 0).div(divisor), scale);
|
|
69
|
+
}
|
|
45
70
|
function getSafeNum(num) {
|
|
46
71
|
if (!num || Number.isNaN(num))
|
|
47
72
|
return 1;
|
|
@@ -71,6 +96,11 @@ function getUnitOriginalTotal(product) {
|
|
|
71
96
|
const basePrice = mainOriginal !== void 0 ? toDecimal(mainOriginal) : mainSelling !== void 0 ? toDecimal(mainSelling) : toDecimal(product.original_price || product.selling_price);
|
|
72
97
|
return basePrice.plus(getBundleUnitPrice(product, true));
|
|
73
98
|
}
|
|
99
|
+
function isGeneratedVoucherProduct(product) {
|
|
100
|
+
const record = product;
|
|
101
|
+
const metadata = (record == null ? void 0 : record.metadata) || {};
|
|
102
|
+
return (record == null ? void 0 : record.extension_type) === "product_voucher" || metadata.parent_order_detail_id !== void 0 || metadata.gift_card_type !== void 0;
|
|
103
|
+
}
|
|
74
104
|
function buildSurchargeServiceItems(products) {
|
|
75
105
|
return products.map((product) => {
|
|
76
106
|
var _a, _b;
|
|
@@ -101,6 +131,252 @@ function buildSurchargeServiceItems(products) {
|
|
|
101
131
|
};
|
|
102
132
|
});
|
|
103
133
|
}
|
|
134
|
+
function getRelationSurchargeIds(item) {
|
|
135
|
+
var _a;
|
|
136
|
+
const ids = (item == null ? void 0 : item.relation_surcharge_ids) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.relation_surcharge_ids);
|
|
137
|
+
if (!Array.isArray(ids))
|
|
138
|
+
return [];
|
|
139
|
+
return ids.filter((id) => id !== void 0 && id !== null && id !== "");
|
|
140
|
+
}
|
|
141
|
+
function getSurchargeConfigId(config) {
|
|
142
|
+
return (config == null ? void 0 : config.id) ?? (config == null ? void 0 : config.surcharge_id);
|
|
143
|
+
}
|
|
144
|
+
function getSurchargeConfigById(surchargeList) {
|
|
145
|
+
const map = /* @__PURE__ */ new Map();
|
|
146
|
+
for (const config of surchargeList || []) {
|
|
147
|
+
const id = getSurchargeConfigId(config);
|
|
148
|
+
if (id !== void 0)
|
|
149
|
+
map.set(id, config);
|
|
150
|
+
}
|
|
151
|
+
return map;
|
|
152
|
+
}
|
|
153
|
+
function getMainSurchargeUnitAmount(product) {
|
|
154
|
+
var _a, _b;
|
|
155
|
+
const record = product;
|
|
156
|
+
return toDecimal(
|
|
157
|
+
((_a = record.metadata) == null ? void 0 : _a.main_product_attached_bundle_selling_price) ?? ((_b = record.metadata) == null ? void 0 : _b.main_product_selling_price) ?? record.selling_price ?? 0
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
function getBundleSurchargeUnitAmount(bundle) {
|
|
161
|
+
return toDecimal((bundle == null ? void 0 : bundle.bundle_selling_price) ?? (bundle == null ? void 0 : bundle.bundle_sum_price) ?? (bundle == null ? void 0 : bundle.price) ?? 0);
|
|
162
|
+
}
|
|
163
|
+
function getBundleProductId(bundle) {
|
|
164
|
+
const id = (bundle == null ? void 0 : bundle.bundle_product_id) ?? (bundle == null ? void 0 : bundle._bundle_product_id) ?? (bundle == null ? void 0 : bundle.product_id);
|
|
165
|
+
if (id === void 0 || id === null || id === "")
|
|
166
|
+
return null;
|
|
167
|
+
const parsed = Number(id);
|
|
168
|
+
if (!Number.isFinite(parsed))
|
|
169
|
+
return null;
|
|
170
|
+
return parsed;
|
|
171
|
+
}
|
|
172
|
+
function createSurchargeAllocationNodes(products, sourceItems) {
|
|
173
|
+
var _a;
|
|
174
|
+
const nodes = [];
|
|
175
|
+
for (let productIndex = 0; productIndex < products.length; productIndex++) {
|
|
176
|
+
const product = products[productIndex];
|
|
177
|
+
const sourceItem = sourceItems[productIndex] || {};
|
|
178
|
+
const productQuantity = new import_decimal.default(getSafeNum(product.num));
|
|
179
|
+
for (let bundleIndex = 0; bundleIndex < (product.product_bundle || []).length; bundleIndex++) {
|
|
180
|
+
const bundle = product.product_bundle[bundleIndex];
|
|
181
|
+
if (!isBundleOriginalPrice(bundle))
|
|
182
|
+
continue;
|
|
183
|
+
const sourceBundle = ((_a = sourceItem == null ? void 0 : sourceItem.bundle) == null ? void 0 : _a[bundleIndex]) || {};
|
|
184
|
+
nodes.push({
|
|
185
|
+
kind: "bundle",
|
|
186
|
+
target: bundle,
|
|
187
|
+
source: sourceBundle,
|
|
188
|
+
productId: getBundleProductId(bundle),
|
|
189
|
+
unitAmount: getBundleSurchargeUnitAmount(bundle),
|
|
190
|
+
quantity: new import_decimal.default(getSafeNum((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity))).times(productQuantity),
|
|
191
|
+
relationSurchargeIds: getRelationSurchargeIds(sourceBundle)
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
nodes.push({
|
|
195
|
+
kind: "main",
|
|
196
|
+
target: product,
|
|
197
|
+
source: sourceItem,
|
|
198
|
+
productId: product.product_id ?? null,
|
|
199
|
+
unitAmount: getMainSurchargeUnitAmount(product),
|
|
200
|
+
quantity: productQuantity,
|
|
201
|
+
relationSurchargeIds: getRelationSurchargeIds(sourceItem)
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return nodes;
|
|
205
|
+
}
|
|
206
|
+
function resetProductSurchargeFields(products) {
|
|
207
|
+
for (const product of products) {
|
|
208
|
+
product.surcharge_fee = 0;
|
|
209
|
+
product.main_product_attached_bundle_surcharge_fee = "0.00";
|
|
210
|
+
product.surcharge_rounding_remainder = 0;
|
|
211
|
+
product.relation_surcharge_ids = [];
|
|
212
|
+
for (const bundle of product.product_bundle || []) {
|
|
213
|
+
bundle.surcharge_fee = 0;
|
|
214
|
+
bundle.relation_surcharge_ids = [];
|
|
215
|
+
bundle.metadata = {
|
|
216
|
+
...bundle.metadata || {},
|
|
217
|
+
surcharge_fee: "0.00",
|
|
218
|
+
surcharge_rounding_remainder: "0.00",
|
|
219
|
+
relation_surcharge_ids: []
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function buildSurchargeQuantityTotals(nodes) {
|
|
225
|
+
const totals = /* @__PURE__ */ new Map();
|
|
226
|
+
for (const node of nodes) {
|
|
227
|
+
for (const surchargeId of node.relationSurchargeIds) {
|
|
228
|
+
totals.set(
|
|
229
|
+
surchargeId,
|
|
230
|
+
(totals.get(surchargeId) || new import_decimal.default(0)).plus(node.quantity)
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return totals;
|
|
235
|
+
}
|
|
236
|
+
function getFallbackAllProductSurchargeIds(surchargeList) {
|
|
237
|
+
return (surchargeList || []).reduce((ids, config) => {
|
|
238
|
+
const id = getSurchargeConfigId(config);
|
|
239
|
+
if (id === void 0)
|
|
240
|
+
return ids;
|
|
241
|
+
if (Number(config.open_product ?? 0) === 0)
|
|
242
|
+
return ids;
|
|
243
|
+
if (Number(config.is_all ?? 0) !== 1)
|
|
244
|
+
return ids;
|
|
245
|
+
ids.push(id);
|
|
246
|
+
return ids;
|
|
247
|
+
}, []);
|
|
248
|
+
}
|
|
249
|
+
function getBackendSurchargeState(stateMap, surchargeId, config) {
|
|
250
|
+
let state = stateMap.get(surchargeId);
|
|
251
|
+
if (!state) {
|
|
252
|
+
state = {
|
|
253
|
+
config,
|
|
254
|
+
amount: new import_decimal.default(0),
|
|
255
|
+
totalOffsetFee: new import_decimal.default(0),
|
|
256
|
+
calculatedQuantity: new import_decimal.default(0),
|
|
257
|
+
fixedIncluded: false,
|
|
258
|
+
fixedRemainderAssigned: false
|
|
259
|
+
};
|
|
260
|
+
stateMap.set(surchargeId, state);
|
|
261
|
+
}
|
|
262
|
+
return state;
|
|
263
|
+
}
|
|
264
|
+
function applySurchargeNodeResult(node, params) {
|
|
265
|
+
const { unitSurchargeFee, roundingRemainder, surchargeIds } = params;
|
|
266
|
+
if (node.kind === "main") {
|
|
267
|
+
node.target.surcharge_fee = unitSurchargeFee.toNumber();
|
|
268
|
+
node.target.main_product_attached_bundle_surcharge_fee = toFixed2(unitSurchargeFee);
|
|
269
|
+
node.target.surcharge_rounding_remainder = roundingRemainder.toNumber();
|
|
270
|
+
node.target.relation_surcharge_ids = surchargeIds;
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
node.target.surcharge_fee = unitSurchargeFee.toNumber();
|
|
274
|
+
node.target.relation_surcharge_ids = surchargeIds;
|
|
275
|
+
node.target.metadata = {
|
|
276
|
+
...node.target.metadata || {},
|
|
277
|
+
surcharge_fee: toFixed2(unitSurchargeFee),
|
|
278
|
+
surcharge_rounding_remainder: toFixed2(roundingRemainder),
|
|
279
|
+
relation_surcharge_ids: surchargeIds
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function calculateBackendProductSurcharges(params) {
|
|
283
|
+
const { products, sourceItems, surchargeList } = params;
|
|
284
|
+
resetProductSurchargeFields(products);
|
|
285
|
+
const configById = getSurchargeConfigById(surchargeList);
|
|
286
|
+
const nodes = createSurchargeAllocationNodes(products, sourceItems);
|
|
287
|
+
const fallbackAllProductSurchargeIds = getFallbackAllProductSurchargeIds(surchargeList);
|
|
288
|
+
for (const node of nodes) {
|
|
289
|
+
if (node.relationSurchargeIds.length === 0) {
|
|
290
|
+
node.relationSurchargeIds = fallbackAllProductSurchargeIds;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const quantityTotals = buildSurchargeQuantityTotals(nodes);
|
|
294
|
+
const stateMap = /* @__PURE__ */ new Map();
|
|
295
|
+
for (const node of nodes) {
|
|
296
|
+
let unitSurchargeFee = new import_decimal.default(0);
|
|
297
|
+
let roundingRemainder = new import_decimal.default(0);
|
|
298
|
+
const appliedSurchargeIds = [];
|
|
299
|
+
for (const surchargeId of node.relationSurchargeIds) {
|
|
300
|
+
const config = configById.get(surchargeId);
|
|
301
|
+
const totalQuantity = quantityTotals.get(surchargeId) || new import_decimal.default(0);
|
|
302
|
+
if (!config || totalQuantity.lte(0))
|
|
303
|
+
continue;
|
|
304
|
+
const percentage = new import_decimal.default(config.percentage || 0);
|
|
305
|
+
const fixed = new import_decimal.default(config.fixed || 0);
|
|
306
|
+
const unitPercentageFee = import_decimal.default.max(0, bcMul(node.unitAmount, percentage, 2));
|
|
307
|
+
const percentageTotalFee = bcMul(node.quantity, unitPercentageFee, 2);
|
|
308
|
+
let unitFixedFee = new import_decimal.default(0);
|
|
309
|
+
let fixedRemainder = new import_decimal.default(0);
|
|
310
|
+
if (fixed.gt(0)) {
|
|
311
|
+
unitFixedFee = bcDiv(fixed, totalQuantity, 2);
|
|
312
|
+
const distributedFixed = bcMul(unitFixedFee, totalQuantity, 2);
|
|
313
|
+
fixedRemainder = bcSub(fixed, distributedFixed, 2);
|
|
314
|
+
}
|
|
315
|
+
const currentUnitSurcharge = import_decimal.default.max(
|
|
316
|
+
0,
|
|
317
|
+
bcAdd(unitPercentageFee, unitFixedFee, 2)
|
|
318
|
+
);
|
|
319
|
+
if (currentUnitSurcharge.lte(0))
|
|
320
|
+
continue;
|
|
321
|
+
const state = getBackendSurchargeState(stateMap, surchargeId, config);
|
|
322
|
+
state.amount = bcAdd(state.amount, percentageTotalFee, 2);
|
|
323
|
+
const precisePercentage = import_decimal.default.max(0, bcMul(node.unitAmount, percentage, 6));
|
|
324
|
+
const offsetBaseFee = import_decimal.default.max(0, bcSub(precisePercentage, unitPercentageFee, 6));
|
|
325
|
+
state.totalOffsetFee = bcAdd(
|
|
326
|
+
state.totalOffsetFee,
|
|
327
|
+
bcMul(offsetBaseFee, node.quantity, 6),
|
|
328
|
+
6
|
|
329
|
+
);
|
|
330
|
+
state.calculatedQuantity = bcAdd(state.calculatedQuantity, node.quantity, 6);
|
|
331
|
+
if (!state.fixedIncluded && fixed.gt(0)) {
|
|
332
|
+
state.amount = bcAdd(state.amount, fixed, 2);
|
|
333
|
+
state.fixedIncluded = true;
|
|
334
|
+
}
|
|
335
|
+
if (!state.fixedRemainderAssigned && !fixedRemainder.eq(0)) {
|
|
336
|
+
state.fixedRemainderAssigned = true;
|
|
337
|
+
roundingRemainder = bcAdd(roundingRemainder, fixedRemainder, 2);
|
|
338
|
+
}
|
|
339
|
+
if (state.calculatedQuantity.gte(totalQuantity) && state.totalOffsetFee.gt(0)) {
|
|
340
|
+
const totalOffsetFee = toAmountFormat(state.totalOffsetFee);
|
|
341
|
+
state.amount = bcAdd(state.amount, totalOffsetFee, 2);
|
|
342
|
+
roundingRemainder = bcAdd(roundingRemainder, totalOffsetFee, 2);
|
|
343
|
+
state.totalOffsetFee = new import_decimal.default(0);
|
|
344
|
+
}
|
|
345
|
+
unitSurchargeFee = bcAdd(unitSurchargeFee, currentUnitSurcharge, 2);
|
|
346
|
+
appliedSurchargeIds.push(surchargeId);
|
|
347
|
+
}
|
|
348
|
+
applySurchargeNodeResult(node, {
|
|
349
|
+
unitSurchargeFee,
|
|
350
|
+
roundingRemainder,
|
|
351
|
+
surchargeIds: appliedSurchargeIds
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
return (surchargeList || []).reduce((result, config, index) => {
|
|
355
|
+
const surchargeId = getSurchargeConfigId(config);
|
|
356
|
+
if (surchargeId === void 0)
|
|
357
|
+
return result;
|
|
358
|
+
const state = stateMap.get(surchargeId);
|
|
359
|
+
if (!state || state.amount.lte(0))
|
|
360
|
+
return result;
|
|
361
|
+
const name = config.name || config.label || {};
|
|
362
|
+
result.push({
|
|
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;
|
|
378
|
+
}, []);
|
|
379
|
+
}
|
|
104
380
|
function getProductDepositData(product) {
|
|
105
381
|
var _a, _b, _c;
|
|
106
382
|
const rootDepositData = (_a = product._origin) == null ? void 0 : _a.custom_deposit_data;
|
|
@@ -219,47 +495,85 @@ function getMainProductPaymentTotal(product) {
|
|
|
219
495
|
}
|
|
220
496
|
return import_decimal.default.max(total, 0);
|
|
221
497
|
}
|
|
498
|
+
function getExplicitTaxRemainder(item) {
|
|
499
|
+
var _a;
|
|
500
|
+
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);
|
|
501
|
+
if (value === void 0 || value === null || value === "")
|
|
502
|
+
return null;
|
|
503
|
+
return new import_decimal.default(value || 0);
|
|
504
|
+
}
|
|
505
|
+
function getPersistedTaxRemainder(item, parentProduct) {
|
|
506
|
+
const isPersistedLine = (item == null ? void 0 : item.order_detail_id) !== void 0 && (item == null ? void 0 : item.order_detail_id) !== null || (parentProduct == null ? void 0 : parentProduct.order_detail_id) !== void 0 && (parentProduct == null ? void 0 : parentProduct.order_detail_id) !== null;
|
|
507
|
+
if (!isPersistedLine)
|
|
508
|
+
return null;
|
|
509
|
+
return getExplicitTaxRemainder(item);
|
|
510
|
+
}
|
|
511
|
+
function writeTaxRemainder(item, roundingRemainder) {
|
|
512
|
+
item.tax_fee_rounding_remainder = roundingRemainder.toNumber();
|
|
513
|
+
if (item.metadata && typeof item.metadata === "object") {
|
|
514
|
+
item.metadata.tax_fee_rounding_remainder = roundingRemainder.toFixed(2);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
function resetTaxRemainderFields(products) {
|
|
518
|
+
for (const product of products) {
|
|
519
|
+
const productRemainder = getPersistedTaxRemainder(product);
|
|
520
|
+
product.tax_fee_rounding_remainder = (productRemainder == null ? void 0 : productRemainder.toNumber()) ?? 0;
|
|
521
|
+
product.original_tax_fee_rounding_remainder = 0;
|
|
522
|
+
for (const bundle of product.product_bundle || []) {
|
|
523
|
+
const bundleRemainder = getPersistedTaxRemainder(bundle, product);
|
|
524
|
+
bundle.metadata = {
|
|
525
|
+
...bundle.metadata || {},
|
|
526
|
+
tax_fee_rounding_remainder: (bundleRemainder == null ? void 0 : bundleRemainder.toFixed(2)) ?? "0.00"
|
|
527
|
+
};
|
|
528
|
+
bundle.tax_fee_rounding_remainder = (bundleRemainder == null ? void 0 : bundleRemainder.toNumber()) ?? 0;
|
|
529
|
+
bundle.original_tax_fee_rounding_remainder = 0;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
function getBundlePaymentPrice(bundle, product) {
|
|
534
|
+
var _a;
|
|
535
|
+
if ((bundle == null ? void 0 : bundle.bundle_payment_price) !== void 0)
|
|
536
|
+
return toDecimal(bundle.bundle_payment_price);
|
|
537
|
+
const basePrice = toDecimal((bundle == null ? void 0 : bundle.bundle_selling_price) ?? (bundle == null ? void 0 : bundle.bundle_sum_price) ?? (bundle == null ? void 0 : bundle.price) ?? 0);
|
|
538
|
+
if (!isBundleOriginalPrice(bundle))
|
|
539
|
+
return basePrice;
|
|
540
|
+
const averageDiscountRate = toDecimal(
|
|
541
|
+
((_a = product.metadata) == null ? void 0 : _a.average_discount_amount_rate) ?? 1
|
|
542
|
+
);
|
|
543
|
+
return toAmountFormat(bcMul(basePrice, averageDiscountRate, 6));
|
|
544
|
+
}
|
|
545
|
+
function applyBackendTaxRemainder(params) {
|
|
546
|
+
const { target, rawTax, formattedTax, quantity, state } = params;
|
|
547
|
+
const taxFeeDifference = bcMul(
|
|
548
|
+
bcSub(rawTax, formattedTax, 6),
|
|
549
|
+
quantity,
|
|
550
|
+
6
|
|
551
|
+
);
|
|
552
|
+
state.difference = bcAdd(state.difference, taxFeeDifference, 6);
|
|
553
|
+
if (state.difference.lt(5e-3))
|
|
554
|
+
return new import_decimal.default(0);
|
|
555
|
+
const roundingRemainder = toAmountFormat(state.difference);
|
|
556
|
+
writeTaxRemainder(target, roundingRemainder);
|
|
557
|
+
state.difference = bcSub(state.difference, roundingRemainder, 6);
|
|
558
|
+
return roundingRemainder;
|
|
559
|
+
}
|
|
222
560
|
function calculateProductsTax(products, taxRate, isPriceIncludeTax) {
|
|
223
561
|
const rate = new import_decimal.default(taxRate);
|
|
224
|
-
|
|
225
|
-
let
|
|
226
|
-
let
|
|
227
|
-
|
|
228
|
-
let lastTaxableItem = null;
|
|
562
|
+
const taxRemainderState = { difference: new import_decimal.default(0) };
|
|
563
|
+
let totalTax = new import_decimal.default(0);
|
|
564
|
+
let totalOriginTax = new import_decimal.default(0);
|
|
565
|
+
resetTaxRemainderFields(products);
|
|
229
566
|
for (const product of products) {
|
|
230
567
|
const quantity = new import_decimal.default(getSafeNum(product.num));
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const mainTaxableBase = mainTotal.lte(0) ? surchargeFee : mainTotal.plus(surchargeFee);
|
|
234
|
-
const mainTaxPrecise = calculateSingleItemTax({
|
|
235
|
-
price: mainTaxableBase,
|
|
236
|
-
taxRate: rate,
|
|
237
|
-
isPriceIncludeTax,
|
|
238
|
-
isChargeTax: product.is_charge_tax ?? 0
|
|
239
|
-
});
|
|
240
|
-
const mainTaxRounded = mainTaxPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
241
|
-
product.main_product_attached_bundle_tax_fee = mainTaxRounded.toFixed(2);
|
|
242
|
-
if (mainTaxPrecise.gt(0)) {
|
|
243
|
-
lastTaxableItem = { type: "main", item: product };
|
|
244
|
-
}
|
|
245
|
-
const originalTotal = getUnitOriginalTotal(product);
|
|
246
|
-
const originalTaxableBase = originalTotal.lte(0) ? surchargeFee : originalTotal.plus(surchargeFee);
|
|
247
|
-
const originalTaxPrecise = calculateSingleItemTax({
|
|
248
|
-
price: originalTaxableBase,
|
|
249
|
-
taxRate: rate,
|
|
250
|
-
isPriceIncludeTax,
|
|
251
|
-
isChargeTax: product.is_charge_tax ?? 0
|
|
252
|
-
});
|
|
253
|
-
let bundlePreciseTax = new import_decimal.default(0);
|
|
254
|
-
let bundleRoundedTax = new import_decimal.default(0);
|
|
255
|
-
let bundlePreciseOriginTax = new import_decimal.default(0);
|
|
256
|
-
let bundleRoundedOriginTax = new import_decimal.default(0);
|
|
568
|
+
let productUnitTax = new import_decimal.default(0);
|
|
569
|
+
let productUnitOriginTax = new import_decimal.default(0);
|
|
257
570
|
const bundleItems = product.product_bundle || [];
|
|
258
571
|
for (const bundleItem of bundleItems) {
|
|
259
572
|
if (!isBundleOriginalPrice(bundleItem))
|
|
260
573
|
continue;
|
|
261
574
|
const bundleQuantity = new import_decimal.default(getSafeNum(bundleItem.num ?? bundleItem.quantity));
|
|
262
|
-
const
|
|
575
|
+
const totalBundleQuantity = bundleQuantity.times(quantity);
|
|
576
|
+
const bundlePrice = getBundlePaymentPrice(bundleItem, product);
|
|
263
577
|
const bundleOriginalPrice = toDecimal(bundleItem.original_price ?? bundleItem.product_price ?? bundleItem.price ?? 0);
|
|
264
578
|
const bundleSurchargeFee = toDecimal(bundleItem.surcharge_fee);
|
|
265
579
|
const bundleTaxPrecise = calculateSingleItemTax({
|
|
@@ -268,48 +582,72 @@ function calculateProductsTax(products, taxRate, isPriceIncludeTax) {
|
|
|
268
582
|
isPriceIncludeTax,
|
|
269
583
|
isChargeTax: bundleItem.is_charge_tax ?? product.is_charge_tax ?? 0
|
|
270
584
|
});
|
|
271
|
-
const bundleTaxRounded = bundleTaxPrecise
|
|
585
|
+
const bundleTaxRounded = toBackendTaxFee(bundleTaxPrecise);
|
|
586
|
+
bundleItem.tax_fee = bundleTaxRounded.toNumber();
|
|
587
|
+
const persistedBundleRemainder = getPersistedTaxRemainder(bundleItem, product);
|
|
588
|
+
const bundleRemainder = persistedBundleRemainder ?? applyBackendTaxRemainder({
|
|
589
|
+
target: bundleItem,
|
|
590
|
+
rawTax: bundleTaxPrecise,
|
|
591
|
+
formattedTax: bundleTaxRounded,
|
|
592
|
+
quantity: totalBundleQuantity,
|
|
593
|
+
state: taxRemainderState
|
|
594
|
+
});
|
|
595
|
+
if (persistedBundleRemainder)
|
|
596
|
+
writeTaxRemainder(bundleItem, persistedBundleRemainder);
|
|
272
597
|
const bundleOrigTaxPrecise = calculateSingleItemTax({
|
|
273
598
|
price: bundleOriginalPrice.plus(bundleSurchargeFee),
|
|
274
599
|
taxRate: rate,
|
|
275
600
|
isPriceIncludeTax,
|
|
276
601
|
isChargeTax: bundleItem.is_charge_tax ?? product.is_charge_tax ?? 0
|
|
277
602
|
});
|
|
278
|
-
const bundleOrigTaxRounded = bundleOrigTaxPrecise
|
|
279
|
-
bundleItem.tax_fee = bundleTaxRounded.toNumber();
|
|
603
|
+
const bundleOrigTaxRounded = toAmountFormat(bundleOrigTaxPrecise);
|
|
280
604
|
bundleItem.original_tax_fee = bundleOrigTaxRounded.toNumber();
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (bundleTaxPrecise.gt(0)) {
|
|
286
|
-
lastTaxableItem = { type: "bundle", item: bundleItem };
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
const itemTaxPrecise = mainTaxPrecise.plus(bundlePreciseTax);
|
|
290
|
-
const itemTaxRounded = mainTaxRounded.plus(bundleRoundedTax);
|
|
291
|
-
const itemOriginTaxPrecise = originalTaxPrecise.plus(bundlePreciseOriginTax);
|
|
292
|
-
const itemOriginTaxRounded = originalTaxPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).plus(bundleRoundedOriginTax);
|
|
293
|
-
product.tax_fee = itemTaxRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toFixed(2);
|
|
294
|
-
product.original_tax_fee = itemOriginTaxRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
295
|
-
preciseTax = preciseTax.plus(itemTaxPrecise.times(quantity));
|
|
296
|
-
roundedTax = roundedTax.plus(itemTaxRounded.times(quantity));
|
|
297
|
-
preciseOriginTax = preciseOriginTax.plus(itemOriginTaxPrecise.times(quantity));
|
|
298
|
-
roundedOriginTax = roundedOriginTax.plus(itemOriginTaxRounded.times(quantity));
|
|
299
|
-
}
|
|
300
|
-
const expectedTax = preciseTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
301
|
-
const expectedOriginTax = preciseOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
302
|
-
const taxRemainder = expectedTax.minus(roundedTax).toNumber();
|
|
303
|
-
const originTaxRemainder = expectedOriginTax.minus(roundedOriginTax).toNumber();
|
|
304
|
-
if (lastTaxableItem) {
|
|
305
|
-
if (taxRemainder !== 0) {
|
|
306
|
-
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
|
|
307
|
-
}
|
|
308
|
-
if (originTaxRemainder !== 0) {
|
|
309
|
-
lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
|
|
605
|
+
productUnitTax = productUnitTax.plus(bundleTaxRounded.times(bundleQuantity));
|
|
606
|
+
productUnitOriginTax = productUnitOriginTax.plus(bundleOrigTaxRounded.times(bundleQuantity));
|
|
607
|
+
totalTax = totalTax.plus(bundleTaxRounded.times(totalBundleQuantity)).plus(bundleRemainder);
|
|
608
|
+
totalOriginTax = totalOriginTax.plus(bundleOrigTaxRounded.times(totalBundleQuantity));
|
|
310
609
|
}
|
|
610
|
+
const mainTotal = getMainProductPaymentTotal(product);
|
|
611
|
+
const surchargeFee = toDecimal(product.surcharge_fee);
|
|
612
|
+
const mainTaxableBase = mainTotal.lte(0) ? surchargeFee : mainTotal.plus(surchargeFee);
|
|
613
|
+
const mainTaxPrecise = calculateSingleItemTax({
|
|
614
|
+
price: mainTaxableBase,
|
|
615
|
+
taxRate: rate,
|
|
616
|
+
isPriceIncludeTax,
|
|
617
|
+
isChargeTax: product.is_charge_tax ?? 0
|
|
618
|
+
});
|
|
619
|
+
const mainTaxRounded = toBackendTaxFee(mainTaxPrecise);
|
|
620
|
+
product.main_product_attached_bundle_tax_fee = mainTaxRounded.toFixed(2);
|
|
621
|
+
const persistedMainRemainder = getPersistedTaxRemainder(product);
|
|
622
|
+
const mainRemainder = persistedMainRemainder ?? applyBackendTaxRemainder({
|
|
623
|
+
target: product,
|
|
624
|
+
rawTax: mainTaxPrecise,
|
|
625
|
+
formattedTax: mainTaxRounded,
|
|
626
|
+
quantity,
|
|
627
|
+
state: taxRemainderState
|
|
628
|
+
});
|
|
629
|
+
if (persistedMainRemainder)
|
|
630
|
+
writeTaxRemainder(product, persistedMainRemainder);
|
|
631
|
+
const originalTotal = getUnitOriginalTotal(product);
|
|
632
|
+
const originalTaxableBase = originalTotal.lte(0) ? surchargeFee : originalTotal.plus(surchargeFee);
|
|
633
|
+
const originalTaxPrecise = calculateSingleItemTax({
|
|
634
|
+
price: originalTaxableBase,
|
|
635
|
+
taxRate: rate,
|
|
636
|
+
isPriceIncludeTax,
|
|
637
|
+
isChargeTax: product.is_charge_tax ?? 0
|
|
638
|
+
});
|
|
639
|
+
const originalTaxRounded = toAmountFormat(originalTaxPrecise);
|
|
640
|
+
productUnitTax = productUnitTax.plus(mainTaxRounded);
|
|
641
|
+
productUnitOriginTax = productUnitOriginTax.plus(originalTaxRounded);
|
|
642
|
+
product.tax_fee = productUnitTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toFixed(2);
|
|
643
|
+
product.original_tax_fee = productUnitOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
644
|
+
totalTax = totalTax.plus(mainTaxRounded.times(quantity)).plus(mainRemainder);
|
|
645
|
+
totalOriginTax = totalOriginTax.plus(originalTaxRounded.times(quantity));
|
|
311
646
|
}
|
|
312
|
-
return {
|
|
647
|
+
return {
|
|
648
|
+
tax: totalTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP),
|
|
649
|
+
originTax: totalOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP)
|
|
650
|
+
};
|
|
313
651
|
}
|
|
314
652
|
function createEmptySalesSummary() {
|
|
315
653
|
return {
|
|
@@ -347,20 +685,23 @@ function calculateSalesSummary(params) {
|
|
|
347
685
|
} = params;
|
|
348
686
|
if (!(products == null ? void 0 : products.length))
|
|
349
687
|
return createEmptySalesSummary();
|
|
350
|
-
const
|
|
688
|
+
const summaryProducts = products.filter((product) => !isGeneratedVoucherProduct(product));
|
|
689
|
+
if (!summaryProducts.length)
|
|
690
|
+
return createEmptySalesSummary();
|
|
691
|
+
const productQuantity = summaryProducts.reduce(
|
|
351
692
|
(sum, item) => sum + getSafeNum(item.num),
|
|
352
693
|
0
|
|
353
694
|
);
|
|
354
|
-
const productOriginalAmount =
|
|
695
|
+
const productOriginalAmount = summaryProducts.reduce(
|
|
355
696
|
(sum, item) => sum.plus(getUnitOriginalTotal(item).times(getSafeNum(item.num))),
|
|
356
697
|
new import_decimal.default(0)
|
|
357
698
|
);
|
|
358
|
-
const productAmount =
|
|
699
|
+
const productAmount = summaryProducts.reduce(
|
|
359
700
|
(sum, item) => sum.plus(getUnitPaymentTotal(item).times(getSafeNum(item.num))),
|
|
360
701
|
new import_decimal.default(0)
|
|
361
702
|
);
|
|
362
|
-
const surchargeServiceItems = buildSurchargeServiceItems(
|
|
363
|
-
|
|
703
|
+
const surchargeServiceItems = buildSurchargeServiceItems(summaryProducts);
|
|
704
|
+
(0, import_utils.getSurcharge)(
|
|
364
705
|
{
|
|
365
706
|
service: surchargeServiceItems,
|
|
366
707
|
addons: [],
|
|
@@ -374,6 +715,11 @@ function calculateSalesSummary(params) {
|
|
|
374
715
|
scheduleById
|
|
375
716
|
}
|
|
376
717
|
);
|
|
718
|
+
const surcharge = calculateBackendProductSurcharges({
|
|
719
|
+
products: summaryProducts,
|
|
720
|
+
sourceItems: surchargeServiceItems,
|
|
721
|
+
surchargeList
|
|
722
|
+
});
|
|
377
723
|
const surchargeAmount = new import_decimal.default(
|
|
378
724
|
(0, import_utils.getSurchargeAmount)(
|
|
379
725
|
{ bookingDetail: null, bookingId: void 0 },
|
|
@@ -381,29 +727,13 @@ function calculateSalesSummary(params) {
|
|
|
381
727
|
{ isEdit: false }
|
|
382
728
|
) || 0
|
|
383
729
|
);
|
|
384
|
-
for (let i = 0; i < products.length; i++) {
|
|
385
|
-
const sourceItem = surchargeServiceItems[i] || {};
|
|
386
|
-
const product = products[i];
|
|
387
|
-
product.surcharge_fee = sourceItem.surcharge_fee || 0;
|
|
388
|
-
const relationSurchargeIds = Array.isArray(sourceItem.relation_surcharge_ids) ? sourceItem.relation_surcharge_ids : [];
|
|
389
|
-
const hasSurcharge = new import_decimal.default(product.surcharge_fee || 0).gt(0) || relationSurchargeIds.length > 0;
|
|
390
|
-
if (hasSurcharge) {
|
|
391
|
-
product.main_product_attached_bundle_surcharge_fee = toFixed2(product.surcharge_fee);
|
|
392
|
-
}
|
|
393
|
-
if (relationSurchargeIds.length > 0) {
|
|
394
|
-
product.relation_surcharge_ids = sourceItem.relation_surcharge_ids;
|
|
395
|
-
}
|
|
396
|
-
if (hasSurcharge && sourceItem.surcharge_rounding_remainder !== void 0) {
|
|
397
|
-
product.surcharge_rounding_remainder = sourceItem.surcharge_rounding_remainder;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
730
|
const hasTaxRate = taxRate !== void 0 && taxRate !== null && taxRate > 0;
|
|
401
731
|
let productTaxFee;
|
|
402
732
|
if (hasTaxRate) {
|
|
403
|
-
const taxResult = calculateProductsTax(
|
|
733
|
+
const taxResult = calculateProductsTax(summaryProducts, taxRate, isPriceIncludeTax);
|
|
404
734
|
productTaxFee = taxResult.tax;
|
|
405
735
|
} else {
|
|
406
|
-
productTaxFee =
|
|
736
|
+
productTaxFee = summaryProducts.reduce(
|
|
407
737
|
(sum, item) => sum.plus(toDecimal(item.tax_fee).times(getSafeNum(item.num))),
|
|
408
738
|
new import_decimal.default(0)
|
|
409
739
|
);
|
|
@@ -411,7 +741,7 @@ function calculateSalesSummary(params) {
|
|
|
411
741
|
const shopDiscountAmount = import_decimal.default.max(new import_decimal.default(Number(shopDiscount) || 0), 0);
|
|
412
742
|
const preTaxExpectAmount = import_decimal.default.max(0, productAmount.plus(surchargeAmount).minus(shopDiscountAmount));
|
|
413
743
|
const totalAmount = isPriceIncludeTax === 1 ? preTaxExpectAmount : preTaxExpectAmount.plus(productTaxFee);
|
|
414
|
-
const deposit = calculateProductsDeposit(
|
|
744
|
+
const deposit = calculateProductsDeposit(summaryProducts);
|
|
415
745
|
return {
|
|
416
746
|
product_quantity: productQuantity,
|
|
417
747
|
product_original_amount: toFixed2(productOriginalAmount),
|
|
@@ -423,9 +753,7 @@ function calculateSalesSummary(params) {
|
|
|
423
753
|
tax_fee: toFixed2(productTaxFee),
|
|
424
754
|
surcharge_fee: toFixed2(surchargeAmount),
|
|
425
755
|
surcharges: surcharge,
|
|
426
|
-
discount_amount: toFixed2(
|
|
427
|
-
import_decimal.default.max(productOriginalAmount.minus(productAmount), 0).plus(shopDiscountAmount)
|
|
428
|
-
),
|
|
756
|
+
discount_amount: toFixed2(shopDiscountAmount),
|
|
429
757
|
deposit_amount: deposit ? deposit.total : "0.00",
|
|
430
758
|
deposit,
|
|
431
759
|
expect_amount: toFixed2(totalAmount),
|
package/lib/server/index.d.ts
CHANGED
|
@@ -284,6 +284,9 @@ declare class Server {
|
|
|
284
284
|
* @example 批量:GET /update/localOrder?order_ids=96971,96972,96973
|
|
285
285
|
*/
|
|
286
286
|
private handleUpdateLocalOrder;
|
|
287
|
+
private handleOrderSalesCheckout;
|
|
288
|
+
private handleOrderCheckout;
|
|
289
|
+
private handleOrderCheckoutSubmit;
|
|
287
290
|
private handleOrderSalesDetail;
|
|
288
291
|
/**
|
|
289
292
|
* 解析 order_ids 入参,兼容 url query / data 字段、字符串(csv) / 数组两种形态。
|
|
@@ -311,8 +314,12 @@ declare class Server {
|
|
|
311
314
|
* 从 url 中解析指定 query 参数,兼容相对路径与绝对路径
|
|
312
315
|
*/
|
|
313
316
|
private extractQueryParam;
|
|
314
|
-
private
|
|
317
|
+
private extractOrderSalesDetailLookup;
|
|
318
|
+
private shouldForceRemoteSalesDetail;
|
|
315
319
|
private buildOrderSalesDetailBackendPath;
|
|
320
|
+
private extractOrderDataFromCheckoutResponse;
|
|
321
|
+
private normalizeCheckoutResponse;
|
|
322
|
+
private extractBackendErrorResponse;
|
|
316
323
|
/**
|
|
317
324
|
* 从 url 或路由 path 解析 pathname(不含 query,去掉末尾 /)
|
|
318
325
|
*/
|