@pisell/pisellos 2.2.193 → 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/modules/Order/index.d.ts +2 -1
- package/dist/modules/Order/index.js +45 -13
- package/dist/modules/Order/utils/manualProductDiscount.js +1 -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 +528 -159
- package/dist/server/index.js +2 -2
- package/dist/server/modules/products/index.js +4 -4
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/lib/model/strategy/adapter/promotion/index.js +0 -49
- package/lib/modules/Order/index.d.ts +2 -1
- package/lib/modules/Order/index.js +30 -2
- package/lib/modules/Order/utils/manualProductDiscount.js +1 -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 +419 -89
- package/lib/server/index.js +2 -2
- package/lib/server/modules/products/index.js +0 -4
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +1 -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),
|
package/lib/server/index.js
CHANGED
|
@@ -945,11 +945,11 @@ var Server = class {
|
|
|
945
945
|
async setupProductsQuotationPriceBridge() {
|
|
946
946
|
var _a;
|
|
947
947
|
if (!this.products) {
|
|
948
|
-
this.
|
|
948
|
+
this.logInfo("setupProductsQuotationPriceBridge: Products 模块未注册");
|
|
949
949
|
return;
|
|
950
950
|
}
|
|
951
951
|
if (!this.schedule) {
|
|
952
|
-
this.
|
|
952
|
+
this.logInfo("setupProductsQuotationPriceBridge: Schedule 模块未注册");
|
|
953
953
|
return;
|
|
954
954
|
}
|
|
955
955
|
try {
|
|
@@ -1170,10 +1170,6 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1170
1170
|
this.productDataSource.run({
|
|
1171
1171
|
pubsub: {
|
|
1172
1172
|
callback: (res) => {
|
|
1173
|
-
console.log("sse_products_callback", res);
|
|
1174
|
-
this.logInfo("sse_products_callback: 收到同步消息", {
|
|
1175
|
-
data: res == null ? void 0 : res.data
|
|
1176
|
-
});
|
|
1177
1173
|
if (!(res == null ? void 0 : res.data))
|
|
1178
1174
|
return;
|
|
1179
1175
|
const data = res.data;
|
|
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
311
311
|
date: string;
|
|
312
312
|
status: string;
|
|
313
313
|
week: string;
|
|
314
|
-
weekNum: 0 |
|
|
314
|
+
weekNum: 0 | 2 | 1 | 5 | 3 | 4 | 6;
|
|
315
315
|
}[]>;
|
|
316
316
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
317
317
|
private getScheduleDataByIds;
|
|
@@ -279,7 +279,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
279
279
|
* 获取当前的客户搜索条件
|
|
280
280
|
* @returns 当前搜索条件
|
|
281
281
|
*/
|
|
282
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
282
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
|
|
283
283
|
/**
|
|
284
284
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
285
285
|
* @returns 客户状态
|