@pisell/pisellos 0.0.365 → 0.0.367
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/evaluator.js +1 -1
- package/dist/model/strategy/adapter/walletPass/utils.js +115 -77
- package/dist/modules/Rules/index.js +4 -3
- package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -2
- package/lib/model/strategy/adapter/walletPass/utils.js +55 -78
- package/lib/modules/Rules/index.js +2 -2
- package/package.json +1 -1
|
@@ -259,7 +259,7 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
|
|
|
259
259
|
allowCrossProduct: true,
|
|
260
260
|
applicableProductLimit: 0,
|
|
261
261
|
deductTaxAndFee: true
|
|
262
|
-
}, item === null || item === void 0 || (_item$strategyResult2 = item.strategyResult) === null || _item$strategyResult2 === void 0 ? void 0 : _item$strategyResult2.
|
|
262
|
+
}, (item === null || item === void 0 || (_item$strategyResult2 = item.strategyResult) === null || _item$strategyResult2 === void 0 || (_item$strategyResult2 = _item$strategyResult2.config) === null || _item$strategyResult2 === void 0 || (_item$strategyResult2 = _item$strategyResult2.metadata) === null || _item$strategyResult2 === void 0 ? void 0 : _item$strategyResult2.custom) || {})
|
|
263
263
|
}));
|
|
264
264
|
} else {
|
|
265
265
|
// 不可用的券,添加原因信息
|
|
@@ -51,12 +51,18 @@ export var getApplicableProductIds = function getApplicableProductIds(voucher) {
|
|
|
51
51
|
|
|
52
52
|
// 辅助函数:计算适用商品的总金额
|
|
53
53
|
var getApplicableProductsAmount = function getApplicableProductsAmount(voucher, productsData) {
|
|
54
|
+
var _config$deductTaxAndF2;
|
|
54
55
|
var applicableProductIds = getApplicableProductIds(voucher);
|
|
56
|
+
var config = voucher.config;
|
|
57
|
+
var deductTaxAndFee = (_config$deductTaxAndF2 = config === null || config === void 0 ? void 0 : config.deductTaxAndFee) !== null && _config$deductTaxAndF2 !== void 0 ? _config$deductTaxAndF2 : true;
|
|
58
|
+
|
|
59
|
+
// 根据券的配置选择使用哪个金额
|
|
60
|
+
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
|
|
55
61
|
|
|
56
62
|
// 如果为 null,适用于所有商品
|
|
57
63
|
if (applicableProductIds === null) {
|
|
58
64
|
return productsData.reduce(function (sum, p) {
|
|
59
|
-
return sum.plus(p
|
|
65
|
+
return sum.plus(p[amountField]);
|
|
60
66
|
}, new Decimal(0));
|
|
61
67
|
}
|
|
62
68
|
|
|
@@ -69,7 +75,7 @@ var getApplicableProductsAmount = function getApplicableProductsAmount(voucher,
|
|
|
69
75
|
return productsData.filter(function (p) {
|
|
70
76
|
return applicableProductIds.includes(p.product_id);
|
|
71
77
|
}).reduce(function (sum, p) {
|
|
72
|
-
return sum.plus(p
|
|
78
|
+
return sum.plus(p[amountField]);
|
|
73
79
|
}, new Decimal(0));
|
|
74
80
|
};
|
|
75
81
|
|
|
@@ -103,8 +109,10 @@ var getApplicableProducts = function getApplicableProducts(voucher, productsData
|
|
|
103
109
|
export function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
104
110
|
console.log(products, 'products123');
|
|
105
111
|
|
|
106
|
-
//
|
|
107
|
-
//
|
|
112
|
+
// 拆分商品数据,同时维护含税和不含税两个金额池
|
|
113
|
+
// remainingAmountWithTax: 含税费的剩余可抵扣金额
|
|
114
|
+
// remainingAmountPure: 纯商品金额(不含税费)的剩余可抵扣金额
|
|
115
|
+
// 在抵扣时,会根据券的 deductTaxAndFee 配置选择从哪个金额池扣除
|
|
108
116
|
var productsCopy = expandProductsWithBundleItems(products, true);
|
|
109
117
|
var remainingOrderAmount = new Decimal(orderTotalAmount); // 订单剩余应付金额
|
|
110
118
|
|
|
@@ -117,7 +125,9 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
117
125
|
_ref2$allowCrossProdu = _ref2.allowCrossProduct,
|
|
118
126
|
allowCrossProduct = _ref2$allowCrossProdu === void 0 ? true : _ref2$allowCrossProdu,
|
|
119
127
|
_ref2$applicableProdu = _ref2.applicableProductLimit,
|
|
120
|
-
applicableProductLimit = _ref2$applicableProdu === void 0 ? 0 : _ref2$applicableProdu
|
|
128
|
+
applicableProductLimit = _ref2$applicableProdu === void 0 ? 0 : _ref2$applicableProdu,
|
|
129
|
+
_ref2$deductTaxAndFee = _ref2.deductTaxAndFee,
|
|
130
|
+
deductTaxAndFee = _ref2$deductTaxAndFee === void 0 ? true : _ref2$deductTaxAndFee;
|
|
121
131
|
|
|
122
132
|
// 根据 deductTaxAndFee 配置获取推荐金额
|
|
123
133
|
var recommendedAmount = getRecommendedAmount(voucher);
|
|
@@ -131,6 +141,9 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
131
141
|
return new Decimal(0);
|
|
132
142
|
}
|
|
133
143
|
|
|
144
|
+
// 根据券的配置选择使用哪个金额字段
|
|
145
|
+
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
|
|
146
|
+
|
|
134
147
|
// 根据跨商品配置计算适用商品金额
|
|
135
148
|
var finalApplicableAmount = new Decimal(0);
|
|
136
149
|
if (allowCrossProduct) {
|
|
@@ -138,23 +151,23 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
138
151
|
if (applicableProductLimit > 0) {
|
|
139
152
|
// 有商品数量限制:按金额从高到低排序,取前 N 个商品
|
|
140
153
|
var sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
|
|
141
|
-
return a.
|
|
154
|
+
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
|
|
142
155
|
}).slice(0, applicableProductLimit);
|
|
143
156
|
finalApplicableAmount = sortedProducts.reduce(function (sum, p) {
|
|
144
|
-
return sum.plus(p
|
|
157
|
+
return sum.plus(p[amountField]);
|
|
145
158
|
}, new Decimal(0));
|
|
146
159
|
} else {
|
|
147
160
|
// 无商品数量限制:所有适用商品的总和
|
|
148
161
|
finalApplicableAmount = applicableProducts.reduce(function (sum, p) {
|
|
149
|
-
return sum.plus(p
|
|
162
|
+
return sum.plus(p[amountField]);
|
|
150
163
|
}, new Decimal(0));
|
|
151
164
|
}
|
|
152
165
|
} else {
|
|
153
166
|
// 非跨商品券:只能抵扣单个商品,取金额最高的商品
|
|
154
167
|
var maxProduct = applicableProducts.reduce(function (max, p) {
|
|
155
|
-
return p.
|
|
168
|
+
return p[amountField].greaterThan(max[amountField]) ? p : max;
|
|
156
169
|
});
|
|
157
|
-
finalApplicableAmount = maxProduct
|
|
170
|
+
finalApplicableAmount = maxProduct[amountField];
|
|
158
171
|
}
|
|
159
172
|
|
|
160
173
|
// 返回最小值
|
|
@@ -229,39 +242,35 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
229
242
|
var recommendedVouchers = [];
|
|
230
243
|
var usedVoucherCounts = new Map(); // 跟踪每个券 ID 的使用次数
|
|
231
244
|
|
|
232
|
-
//
|
|
245
|
+
// 重置商品余额追踪(同时维护含税和不含税两个金额池)
|
|
233
246
|
var productsForRecommendation = expandProductsWithBundleItems(products, true);
|
|
234
247
|
remainingOrderAmount = new Decimal(orderTotalAmount);
|
|
235
248
|
|
|
249
|
+
/**
|
|
236
250
|
// 分类券:未跨商品券 vs 跨商品券
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
var groups = new Map();
|
|
249
|
-
vouchers.forEach(function (v) {
|
|
250
|
-
var tag = v.tag;
|
|
251
|
+
const nonCrossProductVouchers = applicableVouchers.filter(
|
|
252
|
+
(v) => !v.config?.allowCrossProduct,
|
|
253
|
+
);
|
|
254
|
+
const crossProductVouchers = applicableVouchers.filter(
|
|
255
|
+
(v) => v.config?.allowCrossProduct,
|
|
256
|
+
);
|
|
257
|
+
// 按 tag 分组
|
|
258
|
+
const groupByType = (vouchers: any[]) => {
|
|
259
|
+
const groups = new Map<string, any[]>();
|
|
260
|
+
vouchers.forEach((v) => {
|
|
261
|
+
const tag = v.tag;
|
|
251
262
|
if (!groups.has(tag)) {
|
|
252
263
|
groups.set(tag, []);
|
|
253
264
|
}
|
|
254
|
-
groups.get(tag)
|
|
265
|
+
groups.get(tag)!.push(v);
|
|
255
266
|
});
|
|
256
267
|
return groups;
|
|
257
268
|
};
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return _toConsumableArray(vouchers).sort(function (a, b) {
|
|
262
|
-
return getRecommendedAmount(b) - getRecommendedAmount(a);
|
|
263
|
-
});
|
|
269
|
+
// 对每组券按金额(balance)从大到小排序
|
|
270
|
+
const sortVouchersByAmount = (vouchers: Voucher[]) => {
|
|
271
|
+
return [...vouchers].sort((a, b) => getRecommendedAmount(b) - getRecommendedAmount(a));
|
|
264
272
|
};
|
|
273
|
+
*/
|
|
265
274
|
|
|
266
275
|
// 处理单张券的抵扣
|
|
267
276
|
var applyVoucher = function applyVoucher(voucher) {
|
|
@@ -279,18 +288,23 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
279
288
|
_ref3$allowCrossProdu = _ref3.allowCrossProduct,
|
|
280
289
|
allowCrossProduct = _ref3$allowCrossProdu === void 0 ? true : _ref3$allowCrossProdu,
|
|
281
290
|
_ref3$applicableProdu = _ref3.applicableProductLimit,
|
|
282
|
-
applicableProductLimit = _ref3$applicableProdu === void 0 ? 0 : _ref3$applicableProdu
|
|
291
|
+
applicableProductLimit = _ref3$applicableProdu === void 0 ? 0 : _ref3$applicableProdu,
|
|
292
|
+
_ref3$deductTaxAndFee = _ref3.deductTaxAndFee,
|
|
293
|
+
deductTaxAndFee = _ref3$deductTaxAndFee === void 0 ? true : _ref3$deductTaxAndFee;
|
|
294
|
+
|
|
295
|
+
// 根据券的配置选择使用哪个金额字段
|
|
296
|
+
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
|
|
283
297
|
|
|
284
298
|
// 获取适用商品
|
|
285
299
|
var applicableProducts = getApplicableProducts(voucher, productsForRecommendation).filter(function (p) {
|
|
286
|
-
return p.
|
|
300
|
+
return p[amountField].greaterThan(0);
|
|
287
301
|
});
|
|
288
302
|
if (applicableProducts.length === 0) return false;
|
|
289
303
|
|
|
290
304
|
// 考虑 applicableProductLimit
|
|
291
305
|
if (allowCrossProduct && applicableProductLimit > 0) {
|
|
292
306
|
applicableProducts = applicableProducts.sort(function (a, b) {
|
|
293
|
-
return a.
|
|
307
|
+
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
|
|
294
308
|
}).slice(0, applicableProductLimit);
|
|
295
309
|
}
|
|
296
310
|
|
|
@@ -302,14 +316,14 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
302
316
|
if (allowCrossProduct) {
|
|
303
317
|
// 跨商品券:所有适用商品的剩余金额之和
|
|
304
318
|
calculatedAvailableMaxAmount = applicableProducts.reduce(function (sum, p) {
|
|
305
|
-
return sum.plus(p
|
|
319
|
+
return sum.plus(p[amountField]);
|
|
306
320
|
}, new Decimal(0));
|
|
307
321
|
} else {
|
|
308
322
|
// 非跨商品券:单个最高金额商品
|
|
309
323
|
var maxProduct = applicableProducts.reduce(function (max, p) {
|
|
310
|
-
return p.
|
|
324
|
+
return p[amountField].greaterThan(max[amountField]) ? p : max;
|
|
311
325
|
});
|
|
312
|
-
calculatedAvailableMaxAmount = maxProduct
|
|
326
|
+
calculatedAvailableMaxAmount = maxProduct[amountField];
|
|
313
327
|
}
|
|
314
328
|
|
|
315
329
|
// 取最小值:min(recommended_usage_amount, maxDeductionAmount, 适用商品金额, 订单剩余金额)
|
|
@@ -323,7 +337,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
323
337
|
if (allowCrossProduct) {
|
|
324
338
|
// 跨商品券:按剩余应付金额从高到低抵扣
|
|
325
339
|
var sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
|
|
326
|
-
return a.
|
|
340
|
+
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
|
|
327
341
|
});
|
|
328
342
|
var _iterator = _createForOfIteratorHelper(sortedProducts),
|
|
329
343
|
_step;
|
|
@@ -331,8 +345,8 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
331
345
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
332
346
|
var product = _step.value;
|
|
333
347
|
if (deductionLeft.lessThanOrEqualTo(0)) break;
|
|
334
|
-
var deductAmount = Decimal.min(deductionLeft, product
|
|
335
|
-
product
|
|
348
|
+
var deductAmount = Decimal.min(deductionLeft, product[amountField]);
|
|
349
|
+
product[amountField] = product[amountField].minus(deductAmount);
|
|
336
350
|
deductionLeft = deductionLeft.minus(deductAmount);
|
|
337
351
|
deductionDetails.push({
|
|
338
352
|
product_id: product.product_id,
|
|
@@ -349,10 +363,10 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
349
363
|
} else {
|
|
350
364
|
// 非跨商品券:只抵扣一个商品(金额最高的)
|
|
351
365
|
var targetProduct = applicableProducts.reduce(function (max, p) {
|
|
352
|
-
return p.
|
|
366
|
+
return p[amountField].greaterThan(max[amountField]) ? p : max;
|
|
353
367
|
});
|
|
354
|
-
var _deductAmount = Decimal.min(deductionLeft, targetProduct
|
|
355
|
-
targetProduct
|
|
368
|
+
var _deductAmount = Decimal.min(deductionLeft, targetProduct[amountField]);
|
|
369
|
+
targetProduct[amountField] = targetProduct[amountField].minus(_deductAmount);
|
|
356
370
|
deductionLeft = deductionLeft.minus(_deductAmount);
|
|
357
371
|
deductionDetails.push({
|
|
358
372
|
product_id: targetProduct.product_id,
|
|
@@ -383,23 +397,29 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
383
397
|
return false;
|
|
384
398
|
};
|
|
385
399
|
|
|
400
|
+
/**
|
|
386
401
|
// 第一轮:处理未跨商品券
|
|
387
|
-
|
|
388
|
-
nonCrossGroups.forEach(
|
|
389
|
-
|
|
390
|
-
sortedVouchers.forEach(
|
|
402
|
+
const nonCrossGroups = groupByType(nonCrossProductVouchers);
|
|
403
|
+
nonCrossGroups.forEach((vouchersInGroup) => {
|
|
404
|
+
const sortedVouchers = sortVouchersByAmount(vouchersInGroup);
|
|
405
|
+
sortedVouchers.forEach((voucher) => {
|
|
391
406
|
applyVoucher(voucher);
|
|
392
407
|
});
|
|
393
408
|
});
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
sortedVouchers.forEach(function (voucher) {
|
|
409
|
+
// 第二轮:处理跨商品券
|
|
410
|
+
const crossGroups = groupByType(crossProductVouchers);
|
|
411
|
+
crossGroups.forEach((vouchersInGroup) => {
|
|
412
|
+
const sortedVouchers = sortVouchersByAmount(vouchersInGroup);
|
|
413
|
+
sortedVouchers.forEach((voucher) => {
|
|
400
414
|
applyVoucher(voucher);
|
|
401
415
|
});
|
|
402
416
|
});
|
|
417
|
+
*/
|
|
418
|
+
|
|
419
|
+
// 直接按 applicableVouchers 的顺序处理所有券
|
|
420
|
+
applicableVouchers.forEach(function (voucher) {
|
|
421
|
+
applyVoucher(voucher);
|
|
422
|
+
});
|
|
403
423
|
|
|
404
424
|
// recommendedVouchers 已经包含了基于应用时计算的 _available_max_amount 和 _unified_available_status
|
|
405
425
|
|
|
@@ -439,7 +459,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
439
459
|
* @returns 返回更新后的所有券列表和已选券的详细抵扣信息
|
|
440
460
|
*/
|
|
441
461
|
export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, products) {
|
|
442
|
-
//
|
|
462
|
+
// 深拷贝并拆分商品列表(包含主商品和原价子商品,同时维护含税和不含税两个金额池),用于计算
|
|
443
463
|
var productsForCalc = expandProductsWithBundleItems(products, true);
|
|
444
464
|
var remainingOrderAmount = new Decimal(orderTotalAmount);
|
|
445
465
|
var selectedWithDetails = [];
|
|
@@ -450,11 +470,16 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
450
470
|
id = selectedVoucher.id;
|
|
451
471
|
var maxDeductionAmount = config.maxDeductionAmount,
|
|
452
472
|
allowCrossProduct = config.allowCrossProduct,
|
|
453
|
-
applicableProductLimit = config.applicableProductLimit
|
|
473
|
+
applicableProductLimit = config.applicableProductLimit,
|
|
474
|
+
_config$deductTaxAndF3 = config.deductTaxAndFee,
|
|
475
|
+
deductTaxAndFee = _config$deductTaxAndF3 === void 0 ? true : _config$deductTaxAndF3;
|
|
476
|
+
|
|
477
|
+
// 根据券的配置选择使用哪个金额字段
|
|
478
|
+
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
|
|
454
479
|
|
|
455
480
|
// 获取适用商品
|
|
456
481
|
var applicableProducts = getApplicableProducts(selectedVoucher, productsForCalc).filter(function (p) {
|
|
457
|
-
return p.
|
|
482
|
+
return p[amountField].greaterThan(0);
|
|
458
483
|
});
|
|
459
484
|
if (applicableProducts.length === 0) {
|
|
460
485
|
// 无适用商品,跳过
|
|
@@ -471,7 +496,7 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
471
496
|
// 考虑 applicableProductLimit
|
|
472
497
|
if (allowCrossProduct && applicableProductLimit > 0) {
|
|
473
498
|
applicableProducts = applicableProducts.sort(function (a, b) {
|
|
474
|
-
return a.
|
|
499
|
+
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
|
|
475
500
|
}).slice(0, applicableProductLimit);
|
|
476
501
|
}
|
|
477
502
|
|
|
@@ -484,7 +509,7 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
484
509
|
if (allowCrossProduct) {
|
|
485
510
|
// 跨商品券:按剩余应付金额从高到低抵扣
|
|
486
511
|
var sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
|
|
487
|
-
return a.
|
|
512
|
+
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
|
|
488
513
|
});
|
|
489
514
|
var _iterator2 = _createForOfIteratorHelper(sortedProducts),
|
|
490
515
|
_step2;
|
|
@@ -492,8 +517,8 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
492
517
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
493
518
|
var product = _step2.value;
|
|
494
519
|
if (deductionLeft.lessThanOrEqualTo(0)) break;
|
|
495
|
-
var deductAmount = Decimal.min(deductionLeft, product
|
|
496
|
-
product
|
|
520
|
+
var deductAmount = Decimal.min(deductionLeft, product[amountField]);
|
|
521
|
+
product[amountField] = product[amountField].minus(deductAmount);
|
|
497
522
|
deductionLeft = deductionLeft.minus(deductAmount);
|
|
498
523
|
deductionDetails.push({
|
|
499
524
|
product_id: product.product_id,
|
|
@@ -510,10 +535,10 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
510
535
|
} else {
|
|
511
536
|
// 非跨商品券:只抵扣一个商品(金额最高的)
|
|
512
537
|
var targetProduct = applicableProducts.reduce(function (max, p) {
|
|
513
|
-
return p.
|
|
538
|
+
return p[amountField].greaterThan(max[amountField]) ? p : max;
|
|
514
539
|
});
|
|
515
|
-
var _deductAmount2 = Decimal.min(deductionLeft, targetProduct
|
|
516
|
-
targetProduct
|
|
540
|
+
var _deductAmount2 = Decimal.min(deductionLeft, targetProduct[amountField]);
|
|
541
|
+
targetProduct[amountField] = targetProduct[amountField].minus(_deductAmount2);
|
|
517
542
|
deductionLeft = deductionLeft.minus(_deductAmount2);
|
|
518
543
|
deductionDetails.push({
|
|
519
544
|
product_id: targetProduct.product_id,
|
|
@@ -559,7 +584,12 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
559
584
|
product_id = voucher.product_id;
|
|
560
585
|
var maxDeductionAmount = config.maxDeductionAmount,
|
|
561
586
|
allowCrossProduct = config.allowCrossProduct,
|
|
562
|
-
applicableProductLimit = config.applicableProductLimit
|
|
587
|
+
applicableProductLimit = config.applicableProductLimit,
|
|
588
|
+
_config$deductTaxAndF4 = config.deductTaxAndFee,
|
|
589
|
+
deductTaxAndFee = _config$deductTaxAndF4 === void 0 ? true : _config$deductTaxAndF4;
|
|
590
|
+
|
|
591
|
+
// 根据券的配置选择使用哪个金额字段
|
|
592
|
+
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
|
|
563
593
|
|
|
564
594
|
// 根据 deductTaxAndFee 配置获取推荐金额
|
|
565
595
|
var recommendedAmount = getRecommendedAmount(voucher);
|
|
@@ -586,7 +616,7 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
586
616
|
if (isAvailable) {
|
|
587
617
|
// 获取适用商品
|
|
588
618
|
var applicableProducts = getApplicableProducts(voucher, productsForCalc).filter(function (p) {
|
|
589
|
-
return p.
|
|
619
|
+
return p[amountField].greaterThan(0);
|
|
590
620
|
});
|
|
591
621
|
if (applicableProducts.length === 0) {
|
|
592
622
|
isAvailable = false;
|
|
@@ -597,21 +627,21 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
597
627
|
if (allowCrossProduct) {
|
|
598
628
|
if (applicableProductLimit > 0) {
|
|
599
629
|
var sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
|
|
600
|
-
return a.
|
|
630
|
+
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
|
|
601
631
|
}).slice(0, applicableProductLimit);
|
|
602
632
|
calculatedMaxAmount = sortedProducts.reduce(function (sum, p) {
|
|
603
|
-
return sum.plus(p
|
|
633
|
+
return sum.plus(p[amountField]);
|
|
604
634
|
}, new Decimal(0));
|
|
605
635
|
} else {
|
|
606
636
|
calculatedMaxAmount = applicableProducts.reduce(function (sum, p) {
|
|
607
|
-
return sum.plus(p
|
|
637
|
+
return sum.plus(p[amountField]);
|
|
608
638
|
}, new Decimal(0));
|
|
609
639
|
}
|
|
610
640
|
} else {
|
|
611
641
|
var maxProduct = applicableProducts.reduce(function (max, p) {
|
|
612
|
-
return p.
|
|
642
|
+
return p[amountField].greaterThan(max[amountField]) ? p : max;
|
|
613
643
|
});
|
|
614
|
-
calculatedMaxAmount = maxProduct
|
|
644
|
+
calculatedMaxAmount = maxProduct[amountField];
|
|
615
645
|
}
|
|
616
646
|
calculatedMaxAmount = Decimal.min(baseAmount, calculatedMaxAmount, remainingOrderAmount);
|
|
617
647
|
if (calculatedMaxAmount.lessThanOrEqualTo(0)) {
|
|
@@ -701,17 +731,22 @@ export var getBundleItemPrice = function getBundleItemPrice(bundleItem, parentQu
|
|
|
701
731
|
/**
|
|
702
732
|
* 将商品数据拆分,包含主商品和原价子商品
|
|
703
733
|
* @param products 原始商品列表
|
|
704
|
-
* @param deductTaxAndFee
|
|
705
|
-
* @returns
|
|
734
|
+
* @param deductTaxAndFee 是否抵扣税费与附加费(已废弃,保留参数以兼容旧代码)
|
|
735
|
+
* @returns 拆分后的商品数据(包含主商品和子商品,同时维护含税和不含税两个金额池)
|
|
706
736
|
*/
|
|
707
737
|
var expandProductsWithBundleItems = function expandProductsWithBundleItems(products, deductTaxAndFee) {
|
|
708
738
|
var expandedProducts = [];
|
|
709
739
|
products.forEach(function (product) {
|
|
710
|
-
|
|
740
|
+
var productQuantity = getProductQuantity(product);
|
|
741
|
+
|
|
742
|
+
// 1. 添加主商品(同时计算含税和不含税两个金额)
|
|
711
743
|
expandedProducts.push(_objectSpread(_objectSpread({}, product), {}, {
|
|
712
744
|
is_bundle_item: false,
|
|
713
745
|
parent_product_id: null,
|
|
714
|
-
|
|
746
|
+
// 含税费的剩余金额
|
|
747
|
+
remainingAmountWithTax: new Decimal(getMainProductPrice(product, true)).times(productQuantity),
|
|
748
|
+
// 纯商品金额(不含税费)
|
|
749
|
+
remainingAmountPure: new Decimal(getMainProductPrice(product, false)).times(productQuantity)
|
|
715
750
|
}));
|
|
716
751
|
|
|
717
752
|
// 2. 添加原价子商品(作为独立商品项)
|
|
@@ -724,9 +759,12 @@ var expandProductsWithBundleItems = function expandProductsWithBundleItems(produ
|
|
|
724
759
|
// 使用 bundle_product_id 作为 product_id
|
|
725
760
|
is_bundle_item: true,
|
|
726
761
|
parent_product_id: product.product_id,
|
|
727
|
-
quantity: bundleItem.num *
|
|
762
|
+
quantity: bundleItem.num * productQuantity,
|
|
728
763
|
// 子商品数量 * 主商品数量
|
|
729
|
-
|
|
764
|
+
// 含税费的剩余金额
|
|
765
|
+
remainingAmountWithTax: new Decimal(getBundleItemPrice(bundleItem, productQuantity, true)),
|
|
766
|
+
// 纯商品金额(不含税费)
|
|
767
|
+
remainingAmountPure: new Decimal(getBundleItemPrice(bundleItem, productQuantity, false))
|
|
730
768
|
}));
|
|
731
769
|
}
|
|
732
770
|
});
|
|
@@ -107,12 +107,13 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
107
107
|
var _discount$holder;
|
|
108
108
|
// 非表单类型 holder 视为匹配
|
|
109
109
|
if (((_discount$holder = discount.holder) === null || _discount$holder === void 0 ? void 0 : _discount$holder.holder_type) !== 'form') return true;
|
|
110
|
-
// 卡券 holder 缺失视为不匹配
|
|
111
|
-
if (!discount.holder.holder_id) return false;
|
|
112
|
-
|
|
113
110
|
// 主预约holder, 目前(20251124)默认只考虑单个holder的情况
|
|
114
111
|
var orderHolderId = Array.isArray(holders) && holders.length > 0 ? holders[0].form_record_id : undefined;
|
|
115
112
|
var productHolderId = Array.isArray(product.holder_id) ? product.holder_id[0] : product.holder_id;
|
|
113
|
+
// 父预约及商品都无holder, 则略过检查
|
|
114
|
+
if (!orderHolderId && !productHolderId) return true;
|
|
115
|
+
|
|
116
|
+
// 最终直接匹配 holder 是否相同
|
|
116
117
|
return (productHolderId || orderHolderId) === discount.holder.holder_id;
|
|
117
118
|
}
|
|
118
119
|
|
|
@@ -210,7 +210,7 @@ var WalletPassEvaluator = class {
|
|
|
210
210
|
});
|
|
211
211
|
const newVouchers = [];
|
|
212
212
|
results.forEach((item) => {
|
|
213
|
-
var _a;
|
|
213
|
+
var _a, _b, _c;
|
|
214
214
|
if (item.isApplicable) {
|
|
215
215
|
newVouchers.push({
|
|
216
216
|
...item.voucher,
|
|
@@ -220,7 +220,7 @@ var WalletPassEvaluator = class {
|
|
|
220
220
|
allowCrossProduct: true,
|
|
221
221
|
applicableProductLimit: 0,
|
|
222
222
|
deductTaxAndFee: true,
|
|
223
|
-
...(_a = item == null ? void 0 : item.strategyResult) == null ? void 0 : _a.config.metadata.custom
|
|
223
|
+
...((_c = (_b = (_a = item == null ? void 0 : item.strategyResult) == null ? void 0 : _a.config) == null ? void 0 : _b.metadata) == null ? void 0 : _c.custom) || {}
|
|
224
224
|
}
|
|
225
225
|
});
|
|
226
226
|
} else {
|
|
@@ -61,13 +61,16 @@ var getApplicableProductIds = (voucher) => {
|
|
|
61
61
|
};
|
|
62
62
|
var getApplicableProductsAmount = (voucher, productsData) => {
|
|
63
63
|
const applicableProductIds = getApplicableProductIds(voucher);
|
|
64
|
+
const { config } = voucher;
|
|
65
|
+
const deductTaxAndFee = (config == null ? void 0 : config.deductTaxAndFee) ?? true;
|
|
66
|
+
const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
|
|
64
67
|
if (applicableProductIds === null) {
|
|
65
|
-
return productsData.reduce((sum, p) => sum.plus(p
|
|
68
|
+
return productsData.reduce((sum, p) => sum.plus(p[amountField]), new import_decimal.default(0));
|
|
66
69
|
}
|
|
67
70
|
if (applicableProductIds.length === 0) {
|
|
68
71
|
return new import_decimal.default(0);
|
|
69
72
|
}
|
|
70
|
-
return productsData.filter((p) => applicableProductIds.includes(p.product_id)).reduce((sum, p) => sum.plus(p
|
|
73
|
+
return productsData.filter((p) => applicableProductIds.includes(p.product_id)).reduce((sum, p) => sum.plus(p[amountField]), new import_decimal.default(0));
|
|
71
74
|
};
|
|
72
75
|
var getApplicableProducts = (voucher, productsData) => {
|
|
73
76
|
const applicableProductIds = getApplicableProductIds(voucher);
|
|
@@ -85,7 +88,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
|
85
88
|
let remainingOrderAmount = new import_decimal.default(orderTotalAmount);
|
|
86
89
|
const calculateAvailableMaxAmount = (voucher, productsData) => {
|
|
87
90
|
const { config } = voucher;
|
|
88
|
-
const { maxDeductionAmount = 0, allowCrossProduct = true, applicableProductLimit = 0 } = config ?? {};
|
|
91
|
+
const { maxDeductionAmount = 0, allowCrossProduct = true, applicableProductLimit = 0, deductTaxAndFee = true } = config ?? {};
|
|
89
92
|
const recommendedAmount = getRecommendedAmount(voucher);
|
|
90
93
|
const baseAmount = import_decimal.default.min(
|
|
91
94
|
new import_decimal.default(recommendedAmount),
|
|
@@ -95,25 +98,26 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
|
95
98
|
if (applicableProducts.length === 0) {
|
|
96
99
|
return new import_decimal.default(0);
|
|
97
100
|
}
|
|
101
|
+
const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
|
|
98
102
|
let finalApplicableAmount = new import_decimal.default(0);
|
|
99
103
|
if (allowCrossProduct) {
|
|
100
104
|
if (applicableProductLimit > 0) {
|
|
101
|
-
const sortedProducts = [...applicableProducts].sort((a, b) => a.
|
|
105
|
+
const sortedProducts = [...applicableProducts].sort((a, b) => a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1).slice(0, applicableProductLimit);
|
|
102
106
|
finalApplicableAmount = sortedProducts.reduce(
|
|
103
|
-
(sum, p) => sum.plus(p
|
|
107
|
+
(sum, p) => sum.plus(p[amountField]),
|
|
104
108
|
new import_decimal.default(0)
|
|
105
109
|
);
|
|
106
110
|
} else {
|
|
107
111
|
finalApplicableAmount = applicableProducts.reduce(
|
|
108
|
-
(sum, p) => sum.plus(p
|
|
112
|
+
(sum, p) => sum.plus(p[amountField]),
|
|
109
113
|
new import_decimal.default(0)
|
|
110
114
|
);
|
|
111
115
|
}
|
|
112
116
|
} else {
|
|
113
117
|
const maxProduct = applicableProducts.reduce(
|
|
114
|
-
(max, p) => p.
|
|
118
|
+
(max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
|
|
115
119
|
);
|
|
116
|
-
finalApplicableAmount = maxProduct
|
|
120
|
+
finalApplicableAmount = maxProduct[amountField];
|
|
117
121
|
}
|
|
118
122
|
return import_decimal.default.min(baseAmount, finalApplicableAmount, remainingOrderAmount);
|
|
119
123
|
};
|
|
@@ -162,32 +166,6 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
|
162
166
|
const usedVoucherCounts = /* @__PURE__ */ new Map();
|
|
163
167
|
const productsForRecommendation = expandProductsWithBundleItems(products, true);
|
|
164
168
|
remainingOrderAmount = new import_decimal.default(orderTotalAmount);
|
|
165
|
-
const nonCrossProductVouchers = applicableVouchers.filter(
|
|
166
|
-
(v) => {
|
|
167
|
-
var _a;
|
|
168
|
-
return !((_a = v.config) == null ? void 0 : _a.allowCrossProduct);
|
|
169
|
-
}
|
|
170
|
-
);
|
|
171
|
-
const crossProductVouchers = applicableVouchers.filter(
|
|
172
|
-
(v) => {
|
|
173
|
-
var _a;
|
|
174
|
-
return (_a = v.config) == null ? void 0 : _a.allowCrossProduct;
|
|
175
|
-
}
|
|
176
|
-
);
|
|
177
|
-
const groupByType = (vouchers) => {
|
|
178
|
-
const groups = /* @__PURE__ */ new Map();
|
|
179
|
-
vouchers.forEach((v) => {
|
|
180
|
-
const tag = v.tag;
|
|
181
|
-
if (!groups.has(tag)) {
|
|
182
|
-
groups.set(tag, []);
|
|
183
|
-
}
|
|
184
|
-
groups.get(tag).push(v);
|
|
185
|
-
});
|
|
186
|
-
return groups;
|
|
187
|
-
};
|
|
188
|
-
const sortVouchersByAmount = (vouchers) => {
|
|
189
|
-
return [...vouchers].sort((a, b) => getRecommendedAmount(b) - getRecommendedAmount(a));
|
|
190
|
-
};
|
|
191
169
|
const applyVoucher = (voucher) => {
|
|
192
170
|
const availabilityCheck = isVoucherAvailable(
|
|
193
171
|
voucher,
|
|
@@ -198,15 +176,16 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
|
198
176
|
return false;
|
|
199
177
|
}
|
|
200
178
|
const { config, id, product_id } = voucher;
|
|
201
|
-
const { maxDeductionAmount = 0, allowCrossProduct = true, applicableProductLimit = 0 } = config ?? {};
|
|
179
|
+
const { maxDeductionAmount = 0, allowCrossProduct = true, applicableProductLimit = 0, deductTaxAndFee = true } = config ?? {};
|
|
180
|
+
const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
|
|
202
181
|
let applicableProducts = getApplicableProducts(
|
|
203
182
|
voucher,
|
|
204
183
|
productsForRecommendation
|
|
205
|
-
).filter((p) => p.
|
|
184
|
+
).filter((p) => p[amountField].greaterThan(0));
|
|
206
185
|
if (applicableProducts.length === 0)
|
|
207
186
|
return false;
|
|
208
187
|
if (allowCrossProduct && applicableProductLimit > 0) {
|
|
209
|
-
applicableProducts = applicableProducts.sort((a, b) => a.
|
|
188
|
+
applicableProducts = applicableProducts.sort((a, b) => a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1).slice(0, applicableProductLimit);
|
|
210
189
|
}
|
|
211
190
|
const usageAmount = typeof voucher.edit_current_amount === "number" ? voucher.edit_current_amount : getRecommendedAmount(voucher);
|
|
212
191
|
const baseAmount = import_decimal.default.min(
|
|
@@ -216,14 +195,14 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
|
216
195
|
let calculatedAvailableMaxAmount = new import_decimal.default(0);
|
|
217
196
|
if (allowCrossProduct) {
|
|
218
197
|
calculatedAvailableMaxAmount = applicableProducts.reduce(
|
|
219
|
-
(sum, p) => sum.plus(p
|
|
198
|
+
(sum, p) => sum.plus(p[amountField]),
|
|
220
199
|
new import_decimal.default(0)
|
|
221
200
|
);
|
|
222
201
|
} else {
|
|
223
202
|
const maxProduct = applicableProducts.reduce(
|
|
224
|
-
(max, p) => p.
|
|
203
|
+
(max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
|
|
225
204
|
);
|
|
226
|
-
calculatedAvailableMaxAmount = maxProduct
|
|
205
|
+
calculatedAvailableMaxAmount = maxProduct[amountField];
|
|
227
206
|
}
|
|
228
207
|
const availableMaxAmount = import_decimal.default.min(
|
|
229
208
|
baseAmount,
|
|
@@ -238,13 +217,13 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
|
238
217
|
const deductionDetails = [];
|
|
239
218
|
if (allowCrossProduct) {
|
|
240
219
|
const sortedProducts = [...applicableProducts].sort(
|
|
241
|
-
(a, b) => a.
|
|
220
|
+
(a, b) => a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1
|
|
242
221
|
);
|
|
243
222
|
for (const product of sortedProducts) {
|
|
244
223
|
if (deductionLeft.lessThanOrEqualTo(0))
|
|
245
224
|
break;
|
|
246
|
-
const deductAmount = import_decimal.default.min(deductionLeft, product
|
|
247
|
-
product
|
|
225
|
+
const deductAmount = import_decimal.default.min(deductionLeft, product[amountField]);
|
|
226
|
+
product[amountField] = product[amountField].minus(deductAmount);
|
|
248
227
|
deductionLeft = deductionLeft.minus(deductAmount);
|
|
249
228
|
deductionDetails.push({
|
|
250
229
|
product_id: product.product_id,
|
|
@@ -256,13 +235,13 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
|
256
235
|
}
|
|
257
236
|
} else {
|
|
258
237
|
const targetProduct = applicableProducts.reduce(
|
|
259
|
-
(max, p) => p.
|
|
238
|
+
(max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
|
|
260
239
|
);
|
|
261
240
|
const deductAmount = import_decimal.default.min(
|
|
262
241
|
deductionLeft,
|
|
263
|
-
targetProduct
|
|
242
|
+
targetProduct[amountField]
|
|
264
243
|
);
|
|
265
|
-
targetProduct
|
|
244
|
+
targetProduct[amountField] = targetProduct[amountField].minus(deductAmount);
|
|
266
245
|
deductionLeft = deductionLeft.minus(deductAmount);
|
|
267
246
|
deductionDetails.push({
|
|
268
247
|
product_id: targetProduct.product_id,
|
|
@@ -289,19 +268,8 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
|
|
|
289
268
|
}
|
|
290
269
|
return false;
|
|
291
270
|
};
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const sortedVouchers = sortVouchersByAmount(vouchersInGroup);
|
|
295
|
-
sortedVouchers.forEach((voucher) => {
|
|
296
|
-
applyVoucher(voucher);
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
const crossGroups = groupByType(crossProductVouchers);
|
|
300
|
-
crossGroups.forEach((vouchersInGroup) => {
|
|
301
|
-
const sortedVouchers = sortVouchersByAmount(vouchersInGroup);
|
|
302
|
-
sortedVouchers.forEach((voucher) => {
|
|
303
|
-
applyVoucher(voucher);
|
|
304
|
-
});
|
|
271
|
+
applicableVouchers.forEach((voucher) => {
|
|
272
|
+
applyVoucher(voucher);
|
|
305
273
|
});
|
|
306
274
|
const recommendedMap = /* @__PURE__ */ new Map();
|
|
307
275
|
recommendedVouchers.forEach((v) => {
|
|
@@ -330,11 +298,12 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
|
|
|
330
298
|
const selectedWithDetails = [];
|
|
331
299
|
selectedVouchers.forEach((selectedVoucher) => {
|
|
332
300
|
const { config, id } = selectedVoucher;
|
|
333
|
-
const { maxDeductionAmount, allowCrossProduct, applicableProductLimit } = config;
|
|
301
|
+
const { maxDeductionAmount, allowCrossProduct, applicableProductLimit, deductTaxAndFee = true } = config;
|
|
302
|
+
const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
|
|
334
303
|
let applicableProducts = getApplicableProducts(
|
|
335
304
|
selectedVoucher,
|
|
336
305
|
productsForCalc
|
|
337
|
-
).filter((p) => p.
|
|
306
|
+
).filter((p) => p[amountField].greaterThan(0));
|
|
338
307
|
if (applicableProducts.length === 0) {
|
|
339
308
|
selectedWithDetails.push({
|
|
340
309
|
...selectedVoucher,
|
|
@@ -347,7 +316,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
|
|
|
347
316
|
return;
|
|
348
317
|
}
|
|
349
318
|
if (allowCrossProduct && applicableProductLimit > 0) {
|
|
350
|
-
applicableProducts = applicableProducts.sort((a, b) => a.
|
|
319
|
+
applicableProducts = applicableProducts.sort((a, b) => a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1).slice(0, applicableProductLimit);
|
|
351
320
|
}
|
|
352
321
|
const usageAmount = typeof selectedVoucher.edit_current_amount === "number" ? selectedVoucher.edit_current_amount : getRecommendedAmount(selectedVoucher);
|
|
353
322
|
const maxDeduction = import_decimal.default.min(
|
|
@@ -359,13 +328,13 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
|
|
|
359
328
|
const deductionDetails = [];
|
|
360
329
|
if (allowCrossProduct) {
|
|
361
330
|
const sortedProducts = [...applicableProducts].sort(
|
|
362
|
-
(a, b) => a.
|
|
331
|
+
(a, b) => a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1
|
|
363
332
|
);
|
|
364
333
|
for (const product of sortedProducts) {
|
|
365
334
|
if (deductionLeft.lessThanOrEqualTo(0))
|
|
366
335
|
break;
|
|
367
|
-
const deductAmount = import_decimal.default.min(deductionLeft, product
|
|
368
|
-
product
|
|
336
|
+
const deductAmount = import_decimal.default.min(deductionLeft, product[amountField]);
|
|
337
|
+
product[amountField] = product[amountField].minus(deductAmount);
|
|
369
338
|
deductionLeft = deductionLeft.minus(deductAmount);
|
|
370
339
|
deductionDetails.push({
|
|
371
340
|
product_id: product.product_id,
|
|
@@ -377,13 +346,13 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
|
|
|
377
346
|
}
|
|
378
347
|
} else {
|
|
379
348
|
const targetProduct = applicableProducts.reduce(
|
|
380
|
-
(max, p) => p.
|
|
349
|
+
(max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
|
|
381
350
|
);
|
|
382
351
|
const deductAmount = import_decimal.default.min(
|
|
383
352
|
deductionLeft,
|
|
384
|
-
targetProduct
|
|
353
|
+
targetProduct[amountField]
|
|
385
354
|
);
|
|
386
|
-
targetProduct
|
|
355
|
+
targetProduct[amountField] = targetProduct[amountField].minus(deductAmount);
|
|
387
356
|
deductionLeft = deductionLeft.minus(deductAmount);
|
|
388
357
|
deductionDetails.push({
|
|
389
358
|
product_id: targetProduct.product_id,
|
|
@@ -418,7 +387,8 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
|
|
|
418
387
|
return selectedDetail || voucher;
|
|
419
388
|
}
|
|
420
389
|
const { config, id, product_id } = voucher;
|
|
421
|
-
const { maxDeductionAmount, allowCrossProduct, applicableProductLimit } = config;
|
|
390
|
+
const { maxDeductionAmount, allowCrossProduct, applicableProductLimit, deductTaxAndFee = true } = config;
|
|
391
|
+
const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
|
|
422
392
|
const recommendedAmount = getRecommendedAmount(voucher);
|
|
423
393
|
let isAvailable = true;
|
|
424
394
|
let calculatedMaxAmount = new import_decimal.default(0);
|
|
@@ -441,7 +411,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
|
|
|
441
411
|
let applicableProducts = getApplicableProducts(
|
|
442
412
|
voucher,
|
|
443
413
|
productsForCalc
|
|
444
|
-
).filter((p) => p.
|
|
414
|
+
).filter((p) => p[amountField].greaterThan(0));
|
|
445
415
|
if (applicableProducts.length === 0) {
|
|
446
416
|
isAvailable = false;
|
|
447
417
|
reasonCode = "not_meet_the_required_conditions";
|
|
@@ -452,22 +422,22 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
|
|
|
452
422
|
);
|
|
453
423
|
if (allowCrossProduct) {
|
|
454
424
|
if (applicableProductLimit > 0) {
|
|
455
|
-
const sortedProducts = [...applicableProducts].sort((a, b) => a.
|
|
425
|
+
const sortedProducts = [...applicableProducts].sort((a, b) => a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1).slice(0, applicableProductLimit);
|
|
456
426
|
calculatedMaxAmount = sortedProducts.reduce(
|
|
457
|
-
(sum, p) => sum.plus(p
|
|
427
|
+
(sum, p) => sum.plus(p[amountField]),
|
|
458
428
|
new import_decimal.default(0)
|
|
459
429
|
);
|
|
460
430
|
} else {
|
|
461
431
|
calculatedMaxAmount = applicableProducts.reduce(
|
|
462
|
-
(sum, p) => sum.plus(p
|
|
432
|
+
(sum, p) => sum.plus(p[amountField]),
|
|
463
433
|
new import_decimal.default(0)
|
|
464
434
|
);
|
|
465
435
|
}
|
|
466
436
|
} else {
|
|
467
437
|
const maxProduct = applicableProducts.reduce(
|
|
468
|
-
(max, p) => p.
|
|
438
|
+
(max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
|
|
469
439
|
);
|
|
470
|
-
calculatedMaxAmount = maxProduct
|
|
440
|
+
calculatedMaxAmount = maxProduct[amountField];
|
|
471
441
|
}
|
|
472
442
|
calculatedMaxAmount = import_decimal.default.min(
|
|
473
443
|
baseAmount,
|
|
@@ -523,11 +493,15 @@ var getBundleItemPrice = (bundleItem, parentQuantity, isDeductTaxAndFee) => {
|
|
|
523
493
|
var expandProductsWithBundleItems = (products, deductTaxAndFee) => {
|
|
524
494
|
const expandedProducts = [];
|
|
525
495
|
products.forEach((product) => {
|
|
496
|
+
const productQuantity = getProductQuantity(product);
|
|
526
497
|
expandedProducts.push({
|
|
527
498
|
...product,
|
|
528
499
|
is_bundle_item: false,
|
|
529
500
|
parent_product_id: null,
|
|
530
|
-
|
|
501
|
+
// 含税费的剩余金额
|
|
502
|
+
remainingAmountWithTax: new import_decimal.default(getMainProductPrice(product, true)).times(productQuantity),
|
|
503
|
+
// 纯商品金额(不含税费)
|
|
504
|
+
remainingAmountPure: new import_decimal.default(getMainProductPrice(product, false)).times(productQuantity)
|
|
531
505
|
});
|
|
532
506
|
if (product.product_bundle && product.product_bundle.length > 0) {
|
|
533
507
|
product.product_bundle.forEach((bundleItem) => {
|
|
@@ -538,9 +512,12 @@ var expandProductsWithBundleItems = (products, deductTaxAndFee) => {
|
|
|
538
512
|
// 使用 bundle_product_id 作为 product_id
|
|
539
513
|
is_bundle_item: true,
|
|
540
514
|
parent_product_id: product.product_id,
|
|
541
|
-
quantity: bundleItem.num *
|
|
515
|
+
quantity: bundleItem.num * productQuantity,
|
|
542
516
|
// 子商品数量 * 主商品数量
|
|
543
|
-
|
|
517
|
+
// 含税费的剩余金额
|
|
518
|
+
remainingAmountWithTax: new import_decimal.default(getBundleItemPrice(bundleItem, productQuantity, true)),
|
|
519
|
+
// 纯商品金额(不含税费)
|
|
520
|
+
remainingAmountPure: new import_decimal.default(getBundleItemPrice(bundleItem, productQuantity, false))
|
|
544
521
|
});
|
|
545
522
|
}
|
|
546
523
|
});
|
|
@@ -67,10 +67,10 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
67
67
|
var _a;
|
|
68
68
|
if (((_a = discount.holder) == null ? void 0 : _a.holder_type) !== "form")
|
|
69
69
|
return true;
|
|
70
|
-
if (!discount.holder.holder_id)
|
|
71
|
-
return false;
|
|
72
70
|
const orderHolderId = Array.isArray(holders) && holders.length > 0 ? holders[0].form_record_id : void 0;
|
|
73
71
|
const productHolderId = Array.isArray(product.holder_id) ? product.holder_id[0] : product.holder_id;
|
|
72
|
+
if (!orderHolderId && !productHolderId)
|
|
73
|
+
return true;
|
|
74
74
|
return (productHolderId || orderHolderId) === discount.holder.holder_id;
|
|
75
75
|
}
|
|
76
76
|
// 判断discountList 是否可以对当前productList生效
|