@pisell/pisellos 0.10.49 → 0.10.50
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/promotion/index.js +9 -0
- package/dist/modules/Discount/types.d.ts +2 -0
- package/dist/modules/Order/index.d.ts +1 -0
- package/dist/modules/Order/index.js +40 -22
- package/dist/modules/Rules/index.js +44 -26
- package/dist/modules/Rules/types.d.ts +4 -0
- package/dist/server/utils/small-ticket.js +10 -3
- package/dist/solution/BaseSales/index.js +2 -0
- package/lib/modules/Discount/types.d.ts +2 -0
- package/lib/modules/Order/index.d.ts +1 -0
- package/lib/modules/Order/index.js +19 -4
- package/lib/modules/Rules/index.js +23 -13
- package/lib/modules/Rules/types.d.ts +4 -0
- package/lib/server/utils/small-ticket.js +9 -2
- package/lib/solution/BaseSales/index.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// 导出评估器
|
|
2
|
+
export { PromotionEvaluator } from "./evaluator";
|
|
3
|
+
|
|
4
|
+
// 导出适配器
|
|
5
|
+
export { PromotionAdapter } from "./adapter";
|
|
6
|
+
export { default } from "./adapter";
|
|
7
|
+
|
|
8
|
+
// 导出策略配置示例常量
|
|
9
|
+
export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY, ITEM_REWARD_STRATEGY } from "./examples";
|
|
@@ -44,6 +44,7 @@ interface ApplicableProductDetails {
|
|
|
44
44
|
original_amount: string;
|
|
45
45
|
num: number;
|
|
46
46
|
metadata?: {
|
|
47
|
+
encoded?: string;
|
|
47
48
|
product_discount_difference?: number;
|
|
48
49
|
/** 月卡扣除本单新增使用后的剩余次数;不限次数时为 null。 */
|
|
49
50
|
balance?: number | null;
|
|
@@ -135,6 +136,7 @@ export interface Discount {
|
|
|
135
136
|
available_products_info?: any[];
|
|
136
137
|
format_title: Formattitle;
|
|
137
138
|
metadata?: {
|
|
139
|
+
encoded?: string;
|
|
138
140
|
discount_card_type?: 'fixed_amount' | 'percent';
|
|
139
141
|
custom_product_bundle_map_id?: string;
|
|
140
142
|
validity_type?: 'custom_schedule_validity' | 'fixed_validity';
|
|
@@ -210,7 +210,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
210
210
|
_step2;
|
|
211
211
|
try {
|
|
212
212
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
213
|
-
var _item$type2, _ref, _ref2, _item$discount$resour, _item$discount, _item$discount$title, _item$discount2, _item$discount3, _item$discount$fixed_, _item$
|
|
213
|
+
var _item$type2, _ref, _ref2, _item$discount$resour, _item$discount, _item$discount$title, _item$discount2, _item$metadata, _item$discount3, _item$discount4, _item$discount$fixed_, _item$discount5, _item$discount6, _item$amount, _ref3, _item$discount$origin, _item$discount7, _ref4, _ref5, _item$metadata$num, _item$metadata2, _item$discount$produc, _item$discount8, _ref6, _ref7, _item$metadata$num2, _item$metadata3, _item$discount9, _ref8, _item$discount$discou, _item$discount10, _item$amount2, _item$amount3, _product$product_id, _product$is_charge_ta, _ref9, _product$original_pri, _ref10, _item$discount$discou2, _item$discount11, _item$discount$discou3, _item$discount12;
|
|
214
214
|
var item = _step2.value;
|
|
215
215
|
var type = (_item$type2 = item === null || item === void 0 ? void 0 : item.type) !== null && _item$type2 !== void 0 ? _item$type2 : item === null || item === void 0 ? void 0 : item.tag;
|
|
216
216
|
if (!type || type === 'product') continue;
|
|
@@ -221,24 +221,31 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
221
221
|
var key = Number.isFinite(id) ? id : String(resourceId);
|
|
222
222
|
var title = (_item$discount$title = item === null || item === void 0 || (_item$discount2 = item.discount) === null || _item$discount2 === void 0 ? void 0 : _item$discount2.title) !== null && _item$discount$title !== void 0 ? _item$discount$title : {};
|
|
223
223
|
var amount = Number((item === null || item === void 0 ? void 0 : item.amount) || 0);
|
|
224
|
-
var
|
|
225
|
-
var
|
|
224
|
+
var encoded = (item === null || item === void 0 || (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata.encoded) || (item === null || item === void 0 ? void 0 : item.encoded) || (item === null || item === void 0 || (_item$discount3 = item.discount) === null || _item$discount3 === void 0 ? void 0 : _item$discount3.encoded) || '';
|
|
225
|
+
var discountCardType = item === null || item === void 0 || (_item$discount4 = item.discount) === null || _item$discount4 === void 0 ? void 0 : _item$discount4.discount_card_type;
|
|
226
|
+
var parValue = isDiscountCard ? discountCardType === 'fixed_amount' ? (_item$discount$fixed_ = item === null || item === void 0 || (_item$discount5 = item.discount) === null || _item$discount5 === void 0 ? void 0 : _item$discount5.fixed_amount) !== null && _item$discount$fixed_ !== void 0 ? _item$discount$fixed_ : item === null || item === void 0 ? void 0 : item.amount : item === null || item === void 0 || (_item$discount6 = item.discount) === null || _item$discount6 === void 0 ? void 0 : _item$discount6.percent : '0';
|
|
226
227
|
var detail = {
|
|
227
228
|
amount: String((_item$amount = item === null || item === void 0 ? void 0 : item.amount) !== null && _item$amount !== void 0 ? _item$amount : '0'),
|
|
228
229
|
type: type,
|
|
229
230
|
resource_id: key,
|
|
230
231
|
title: title,
|
|
231
|
-
original_amount: String((_ref3 = (_item$discount$origin = item === null || item === void 0 || (_item$
|
|
232
|
-
num: Number((_ref4 = (_ref5 = (_item$metadata$num = item === null || item === void 0 || (_item$
|
|
232
|
+
original_amount: String((_ref3 = (_item$discount$origin = item === null || item === void 0 || (_item$discount7 = item.discount) === null || _item$discount7 === void 0 ? void 0 : _item$discount7.original_amount) !== null && _item$discount$origin !== void 0 ? _item$discount$origin : item === null || item === void 0 ? void 0 : item.amount) !== null && _ref3 !== void 0 ? _ref3 : '0'),
|
|
233
|
+
num: Number((_ref4 = (_ref5 = (_item$metadata$num = item === null || item === void 0 || (_item$metadata2 = item.metadata) === null || _item$metadata2 === void 0 ? void 0 : _item$metadata2.num) !== null && _item$metadata$num !== void 0 ? _item$metadata$num : product === null || product === void 0 ? void 0 : product.num) !== null && _ref5 !== void 0 ? _ref5 : product === null || product === void 0 ? void 0 : product.product_quantity) !== null && _ref4 !== void 0 ? _ref4 : 1) || 1,
|
|
233
234
|
metadata: item === null || item === void 0 ? void 0 : item.metadata,
|
|
234
235
|
discount: _objectSpread(_objectSpread({}, (item === null || item === void 0 ? void 0 : item.discount) || {}), {}, {
|
|
235
|
-
product_id: (_item$discount$produc = item === null || item === void 0 || (_item$
|
|
236
|
+
product_id: (_item$discount$produc = item === null || item === void 0 || (_item$discount8 = item.discount) === null || _item$discount8 === void 0 ? void 0 : _item$discount8.product_id) !== null && _item$discount$produc !== void 0 ? _item$discount$produc : product === null || product === void 0 ? void 0 : product.product_id
|
|
236
237
|
}),
|
|
237
|
-
_num: Number((_ref6 = (_ref7 = (_item$metadata$num2 = item === null || item === void 0 || (_item$
|
|
238
|
+
_num: Number((_ref6 = (_ref7 = (_item$metadata$num2 = item === null || item === void 0 || (_item$metadata3 = item.metadata) === null || _item$metadata3 === void 0 ? void 0 : _item$metadata3.num) !== null && _item$metadata$num2 !== void 0 ? _item$metadata$num2 : product === null || product === void 0 ? void 0 : product.num) !== null && _ref7 !== void 0 ? _ref7 : product === null || product === void 0 ? void 0 : product.product_quantity) !== null && _ref6 !== void 0 ? _ref6 : 1) || 1
|
|
238
239
|
};
|
|
239
240
|
var existed = discountMap.get(key);
|
|
240
241
|
if (existed) {
|
|
241
242
|
var _existed$limited_rela;
|
|
243
|
+
if (!existed.encoded && encoded) {
|
|
244
|
+
existed.encoded = encoded;
|
|
245
|
+
existed.metadata = _objectSpread(_objectSpread({}, existed.metadata), {}, {
|
|
246
|
+
encoded: encoded
|
|
247
|
+
});
|
|
248
|
+
}
|
|
242
249
|
existed.amount = Number(existed.amount || 0) + amount;
|
|
243
250
|
existed.used_par_value = String(Number(existed.used_par_value || 0) + amount);
|
|
244
251
|
if (!isDiscountCard) {
|
|
@@ -257,10 +264,13 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
257
264
|
discountMap.set(key, {
|
|
258
265
|
id: key,
|
|
259
266
|
product_name: '',
|
|
260
|
-
encoded:
|
|
261
|
-
code: '',
|
|
267
|
+
encoded: encoded,
|
|
268
|
+
code: (item === null || item === void 0 ? void 0 : item.code) || (item === null || item === void 0 || (_item$discount9 = item.discount) === null || _item$discount9 === void 0 ? void 0 : _item$discount9.code) || '',
|
|
269
|
+
metadata: {
|
|
270
|
+
encoded: encoded
|
|
271
|
+
},
|
|
262
272
|
tag: type,
|
|
263
|
-
product_id: (_ref8 = (_item$discount$discou = item === null || item === void 0 || (_item$
|
|
273
|
+
product_id: (_ref8 = (_item$discount$discou = item === null || item === void 0 || (_item$discount10 = item.discount) === null || _item$discount10 === void 0 ? void 0 : _item$discount10.discount_product_id) !== null && _item$discount$discou !== void 0 ? _item$discount$discou : product === null || product === void 0 ? void 0 : product.product_id) !== null && _ref8 !== void 0 ? _ref8 : 0,
|
|
264
274
|
relation_type: '',
|
|
265
275
|
par_value: String(parValue !== null && parValue !== void 0 ? parValue : '0'),
|
|
266
276
|
used_par_value: String((_item$amount2 = item === null || item === void 0 ? void 0 : item.amount) !== null && _item$amount2 !== void 0 ? _item$amount2 : '0'),
|
|
@@ -293,8 +303,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
293
303
|
amount: amount,
|
|
294
304
|
discount: _objectSpread(_objectSpread({}, (item === null || item === void 0 ? void 0 : item.discount) || {}), {}, {
|
|
295
305
|
resource_id: key,
|
|
296
|
-
discount_product_id: (_ref10 = (_item$discount$discou2 = item === null || item === void 0 || (_item$
|
|
297
|
-
discount_calculation_mode: (_item$discount$discou3 = item === null || item === void 0 || (_item$
|
|
306
|
+
discount_product_id: (_ref10 = (_item$discount$discou2 = item === null || item === void 0 || (_item$discount11 = item.discount) === null || _item$discount11 === void 0 ? void 0 : _item$discount11.discount_product_id) !== null && _item$discount$discou2 !== void 0 ? _item$discount$discou2 : product === null || product === void 0 ? void 0 : product.product_id) !== null && _ref10 !== void 0 ? _ref10 : 0,
|
|
307
|
+
discount_calculation_mode: (_item$discount$discou3 = item === null || item === void 0 || (_item$discount12 = item.discount) === null || _item$discount12 === void 0 ? void 0 : _item$discount12.discount_calculation_mode) !== null && _item$discount$discou3 !== void 0 ? _item$discount$discou3 : 'item_level'
|
|
298
308
|
}),
|
|
299
309
|
applicableProductDetails: [detail],
|
|
300
310
|
appliedProductDetails: [detail]
|
|
@@ -1004,7 +1014,14 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1004
1014
|
_context6.next = 31;
|
|
1005
1015
|
return (_this$store$discount12 = this.store.discount) === null || _this$store$discount12 === void 0 ? void 0 : _this$store$discount12.setDiscountList(normalizedNewDiscountList);
|
|
1006
1016
|
case 31:
|
|
1007
|
-
|
|
1017
|
+
// 实际写回商品时沿用扫码试算的优先级,避免旧商品行的选卡覆盖本次扫码。
|
|
1018
|
+
this.applyDiscount({
|
|
1019
|
+
preferredEntitlementPassIds: withScanList.filter(function (discount) {
|
|
1020
|
+
return isEntitlementPass(discount);
|
|
1021
|
+
}).map(function (discount) {
|
|
1022
|
+
return discount.id;
|
|
1023
|
+
})
|
|
1024
|
+
});
|
|
1008
1025
|
_context6.next = 34;
|
|
1009
1026
|
return this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
|
|
1010
1027
|
case 34:
|
|
@@ -1093,7 +1110,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1093
1110
|
},
|
|
1094
1111
|
orderTotalAmount: Number(((_this$store$summary2 = this.store.summary) === null || _this$store$summary2 === void 0 ? void 0 : _this$store$summary2.total_amount) || 0)
|
|
1095
1112
|
}, {
|
|
1096
|
-
reapplyBookingDiscountProductUids: options === null || options === void 0 ? void 0 : options.reapplyBookingDiscountProductUids
|
|
1113
|
+
reapplyBookingDiscountProductUids: options === null || options === void 0 ? void 0 : options.reapplyBookingDiscountProductUids,
|
|
1114
|
+
preferredEntitlementPassIds: options === null || options === void 0 ? void 0 : options.preferredEntitlementPassIds
|
|
1097
1115
|
});
|
|
1098
1116
|
if (result !== null && result !== void 0 && result.productList) {
|
|
1099
1117
|
var previousProductsByUid = indexOrderProductsByUid(tempOrder.products);
|
|
@@ -5397,8 +5415,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
5397
5415
|
if (unique_identification_number !== undefined) {
|
|
5398
5416
|
var targetUid = String(unique_identification_number);
|
|
5399
5417
|
productIndex = tempOrder.products.findIndex(function (item) {
|
|
5400
|
-
var _item$
|
|
5401
|
-
return String(((_item$
|
|
5418
|
+
var _item$metadata4;
|
|
5419
|
+
return String(((_item$metadata4 = item.metadata) === null || _item$metadata4 === void 0 ? void 0 : _item$metadata4.unique_identification_number) || item.unique_identification_number || '') === targetUid;
|
|
5402
5420
|
});
|
|
5403
5421
|
}
|
|
5404
5422
|
if (productIndex === -1) {
|
|
@@ -5663,8 +5681,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
5663
5681
|
if (unique_identification_number !== undefined) {
|
|
5664
5682
|
targetUid = String(unique_identification_number);
|
|
5665
5683
|
productIndex = tempOrder.products.findIndex(function (item) {
|
|
5666
|
-
var _item$
|
|
5667
|
-
return String(((_item$
|
|
5684
|
+
var _item$metadata5;
|
|
5685
|
+
return String(((_item$metadata5 = item.metadata) === null || _item$metadata5 === void 0 ? void 0 : _item$metadata5.unique_identification_number) || item.unique_identification_number || '') === targetUid;
|
|
5668
5686
|
});
|
|
5669
5687
|
}
|
|
5670
5688
|
if (productIndex === -1) {
|
|
@@ -5853,8 +5871,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
5853
5871
|
bookingsBeforeRemove = tempOrder.bookings || [];
|
|
5854
5872
|
preserveDisplayPosition = options === null || options === void 0 ? void 0 : options.preserveDisplayPosition;
|
|
5855
5873
|
anchorIndex = preserveDisplayPosition ? productsBeforeRemove.findIndex(function (item) {
|
|
5856
|
-
var _item$
|
|
5857
|
-
var uid = ((_item$
|
|
5874
|
+
var _item$metadata6;
|
|
5875
|
+
var uid = ((_item$metadata6 = item.metadata) === null || _item$metadata6 === void 0 ? void 0 : _item$metadata6.unique_identification_number) || item.unique_identification_number;
|
|
5858
5876
|
return uid !== undefined && uid !== null && String(uid) === String(preserveDisplayPosition.anchorProductUid);
|
|
5859
5877
|
}) : -1;
|
|
5860
5878
|
productsAfterAnchor = anchorIndex >= 0 ? productsBeforeRemove.slice(anchorIndex + 1) : [];
|
|
@@ -5950,8 +5968,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
5950
5968
|
}
|
|
5951
5969
|
if (preserveDisplayPosition && anchorIndex >= 0) {
|
|
5952
5970
|
remainingProductIndex = tempOrder.products.findIndex(function (item) {
|
|
5953
|
-
var _item$
|
|
5954
|
-
var uid = ((_item$
|
|
5971
|
+
var _item$metadata7;
|
|
5972
|
+
var uid = ((_item$metadata7 = item.metadata) === null || _item$metadata7 === void 0 ? void 0 : _item$metadata7.unique_identification_number) || item.unique_identification_number;
|
|
5955
5973
|
return uid !== undefined && uid !== null && String(uid) === String(preserveDisplayPosition.remainingProductUid);
|
|
5956
5974
|
});
|
|
5957
5975
|
if (remainingProductIndex >= 0) {
|
|
@@ -191,11 +191,17 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
191
191
|
unavailableReason: UnavailableReason.AlreadyUsed
|
|
192
192
|
};
|
|
193
193
|
}
|
|
194
|
+
var scannedEntitlementPassIds = newDiscountList.filter(function (discount) {
|
|
195
|
+
return isEntitlementPass(discount);
|
|
196
|
+
}).map(function (discount) {
|
|
197
|
+
return discount.id;
|
|
198
|
+
});
|
|
199
|
+
var scannedEntitlementPassIdSet = new Set(scannedEntitlementPassIds.map(String));
|
|
194
200
|
|
|
195
|
-
//
|
|
196
|
-
//
|
|
201
|
+
// 客户次卡必须保留在完整列表中;同一实例以本次扫码数据更新。
|
|
202
|
+
// 历史折扣不参与试算,商品券继续沿用仅保留扫码来源的规则。
|
|
197
203
|
var filteredOldDiscountList = oldDiscountList.filter(function (discount) {
|
|
198
|
-
return !discount.isEditMode && (!isFullCoveragePass(discount) || discount.isScan);
|
|
204
|
+
return !discount.isEditMode && (!isFullCoveragePass(discount) || isEntitlementPass(discount) || discount.isScan) && !scannedEntitlementPassIdSet.has(String(discount.id));
|
|
199
205
|
});
|
|
200
206
|
var mergedDiscountList = uniqueById([].concat(_toConsumableArray(filteredOldDiscountList), _toConsumableArray(newDiscountList)));
|
|
201
207
|
var result = this.calcDiscount({
|
|
@@ -205,7 +211,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
205
211
|
holders: holders,
|
|
206
212
|
isFormSubject: isFormSubject
|
|
207
213
|
}, {
|
|
208
|
-
scan: true
|
|
214
|
+
scan: true,
|
|
215
|
+
preferredEntitlementPassIds: scannedEntitlementPassIds
|
|
209
216
|
});
|
|
210
217
|
|
|
211
218
|
// 检查是否有产品使用了新折扣
|
|
@@ -368,6 +375,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
368
375
|
holders = _ref8.holders,
|
|
369
376
|
isFormSubject = _ref8.isFormSubject,
|
|
370
377
|
orderTotalAmount = _ref8.orderTotalAmount;
|
|
378
|
+
var preferredEntitlementPassIds = new Set(((options === null || options === void 0 ? void 0 : options.preferredEntitlementPassIds) || []).map(String));
|
|
371
379
|
var resolveIsFormSubject = function resolveIsFormSubject(product) {
|
|
372
380
|
return typeof isFormSubject === 'function' ? Boolean(isFormSubject(product)) : Boolean(isFormSubject);
|
|
373
381
|
};
|
|
@@ -1179,7 +1187,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1179
1187
|
|
|
1180
1188
|
// 判断优惠券是否适用于该商品
|
|
1181
1189
|
if (isAvailableProduct && !isItemRewardProductDiscount && isLimitedProduct && timeLimit && isBundleAvailable && (_discount$config3 = discount.config) !== null && _discount$config3 !== void 0 && _discount$config3.isAvailable && (!isEntitlementPass(discount) || getRemainingEntitlementUses(discount, 0, 1) > 0)) {
|
|
1182
|
-
var _discountApplicabilit, _discount$metadata4, _discount$metadata5;
|
|
1190
|
+
var _discountApplicabilit, _discount$metadata4, _discount$metadata5, _discount$metadata6;
|
|
1183
1191
|
// 记录此优惠券适用的商品
|
|
1184
1192
|
(_discountApplicabilit = discountApplicability.get(discount.id)) === null || _discountApplicabilit === void 0 || _discountApplicabilit.push(product.id);
|
|
1185
1193
|
|
|
@@ -1206,6 +1214,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1206
1214
|
discount_product_id: discount.product_id
|
|
1207
1215
|
},
|
|
1208
1216
|
metadata: {
|
|
1217
|
+
encoded: ((_discount$metadata6 = discount.metadata) === null || _discount$metadata6 === void 0 ? void 0 : _discount$metadata6.encoded) || discount.encoded,
|
|
1209
1218
|
num: num,
|
|
1210
1219
|
discount_rule_uncheck_flag: discount === null || discount === void 0 ? void 0 : discount.discount_rule_uncheck_flag
|
|
1211
1220
|
}
|
|
@@ -1406,7 +1415,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1406
1415
|
return false;
|
|
1407
1416
|
});
|
|
1408
1417
|
|
|
1409
|
-
//
|
|
1418
|
+
// 识别用户本次显式选择的卡券,供次卡和折扣卡各自的优先级使用。
|
|
1410
1419
|
// 目标仍必须在当前商品的 applicableDiscounts 中,因此不会绕过 Holder、时间或商品范围校验。
|
|
1411
1420
|
var explicitlySelectedDiscount = (options === null || options === void 0 ? void 0 : options.isSelected) === true && options.discountId !== undefined ? applicableDiscounts.find(function (discount) {
|
|
1412
1421
|
var discountType = discount.tag || discount.type || '';
|
|
@@ -1415,10 +1424,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1415
1424
|
// 折扣卡会复用于整条商品行;商品券必须继续按单张拆分,不能复用该分支。
|
|
1416
1425
|
var explicitlySelectedDiscountCard = explicitlySelectedDiscount && !isFullCoveragePass(explicitlySelectedDiscount) ? explicitlySelectedDiscount : undefined;
|
|
1417
1426
|
|
|
1418
|
-
// 商品数量等变化会触发无 discountId
|
|
1427
|
+
// 商品数量等变化会触发无 discountId 的重算。只要当前行已应用的卡仍在
|
|
1419
1428
|
// applicableDiscounts 中,就应保留该行选择,避免被自动排序中力度更大的卡替换。
|
|
1420
|
-
var
|
|
1421
|
-
return ['discount_card', 'product_discount_card'].includes((item === null || item === void 0 ? void 0 : item.tag) || (item === null || item === void 0 ? void 0 : item.type));
|
|
1429
|
+
var appliedWalletDiscountIds = new Set((product.discount_list || []).filter(function (item) {
|
|
1430
|
+
return ['entitlement_pass', 'discount_card', 'product_discount_card'].includes((item === null || item === void 0 ? void 0 : item.tag) || (item === null || item === void 0 ? void 0 : item.type));
|
|
1422
1431
|
}).map(function (item) {
|
|
1423
1432
|
var _ref24, _item$discount$resour, _item$discount;
|
|
1424
1433
|
return (_ref24 = (_item$discount$resour = item === null || item === void 0 || (_item$discount = item.discount) === null || _item$discount === void 0 ? void 0 : _item$discount.resource_id) !== null && _item$discount$resour !== void 0 ? _item$discount$resour : item === null || item === void 0 ? void 0 : item.resource_id) !== null && _ref24 !== void 0 ? _ref24 : item === null || item === void 0 ? void 0 : item.id;
|
|
@@ -1427,20 +1436,26 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1427
1436
|
}).map(String));
|
|
1428
1437
|
var appliedDiscountCard = options !== null && options !== void 0 && options.scan ? undefined : applicableDiscounts.find(function (discount) {
|
|
1429
1438
|
var discountType = discount.tag || discount.type || '';
|
|
1430
|
-
return discount.isSelected === true && ['discount_card', 'product_discount_card'].includes(discountType) &&
|
|
1439
|
+
return discount.isSelected === true && ['discount_card', 'product_discount_card'].includes(discountType) && appliedWalletDiscountIds.has(String(discount.id));
|
|
1440
|
+
});
|
|
1441
|
+
var appliedEntitlementPass = options !== null && options !== void 0 && options.scan || (options === null || options === void 0 ? void 0 : options.preserveEntitlementSelection) === false ? undefined : applicableDiscounts.find(function (discount) {
|
|
1442
|
+
return isEntitlementPass(discount) && discount.isSelected === true && appliedWalletDiscountIds.has(String(discount.id));
|
|
1431
1443
|
});
|
|
1432
1444
|
|
|
1433
|
-
//
|
|
1445
|
+
// 次卡内部按本次手选/扫码、当前行已应用、默认排序选择;仍保留次卡相对其他券的优先级。
|
|
1434
1446
|
var scannedSelectedDiscountCard = applicableDiscounts.find(function (n) {
|
|
1435
1447
|
return n.isScan && n.isSelected && !isFullCoveragePass(n);
|
|
1436
1448
|
});
|
|
1437
1449
|
var selectedDiscountCard = explicitlySelectedDiscountCard || appliedDiscountCard || scannedSelectedDiscountCard;
|
|
1438
|
-
var
|
|
1450
|
+
var selectedEntitlementPass = (explicitlySelectedDiscount && isEntitlementPass(explicitlySelectedDiscount) ? explicitlySelectedDiscount : undefined) || applicableDiscounts.find(function (discount) {
|
|
1451
|
+
return isEntitlementPass(discount) && preferredEntitlementPassIds.has(String(discount.id));
|
|
1452
|
+
}) || appliedEntitlementPass || applicableDiscounts.find(function (discount) {
|
|
1439
1453
|
return isEntitlementPass(discount);
|
|
1440
1454
|
});
|
|
1441
|
-
var selectedDiscount =
|
|
1442
|
-
|
|
1443
|
-
|
|
1455
|
+
var selectedDiscount = selectedEntitlementPass || explicitlySelectedDiscount || selectedDiscountCard || applicableDiscounts[0];
|
|
1456
|
+
// 实际次数分配必须使用同一顺序,避免选中状态切换后仍将次数分配给默认卡。
|
|
1457
|
+
var prioritizedApplicableDiscounts = selectedDiscount && isFullCoveragePass(selectedDiscount) ? [selectedDiscount].concat(_toConsumableArray(applicableDiscounts.filter(function (discount) {
|
|
1458
|
+
return isFullCoveragePass(discount) && String(discount.id) !== String(selectedDiscount.id);
|
|
1444
1459
|
})), _toConsumableArray(applicableDiscounts.filter(function (discount) {
|
|
1445
1460
|
return !isFullCoveragePass(discount);
|
|
1446
1461
|
}))) : applicableDiscounts;
|
|
@@ -1683,7 +1698,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1683
1698
|
count: 1
|
|
1684
1699
|
}];
|
|
1685
1700
|
for (var i = 0; i < discountUsageGroups.length; i++) {
|
|
1686
|
-
var _originProduct4, _selectedDiscount$con, _product$options, _product$options2, _selectedDiscount$met, _selectedDiscount$met2, _reapplyDiscountPerce;
|
|
1701
|
+
var _originProduct4, _selectedDiscount$con, _product$options, _product$options2, _selectedDiscount$met, _selectedDiscount$met2, _reapplyDiscountPerce, _selectedDiscount$met3;
|
|
1687
1702
|
var _discountUsageGroups$ = discountUsageGroups[i],
|
|
1688
1703
|
_selectedDiscount = _discountUsageGroups$.discount,
|
|
1689
1704
|
appliedUseCount = _discountUsageGroups$.count;
|
|
@@ -1773,6 +1788,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1773
1788
|
_num: isFullCoverage ? appliedUseCount : product.num,
|
|
1774
1789
|
config: _selectedDiscount === null || _selectedDiscount === void 0 ? void 0 : _selectedDiscount.config,
|
|
1775
1790
|
metadata: _objectSpread(_objectSpread({
|
|
1791
|
+
encoded: ((_selectedDiscount$met3 = _selectedDiscount.metadata) === null || _selectedDiscount$met3 === void 0 ? void 0 : _selectedDiscount$met3.encoded) || _selectedDiscount.encoded,
|
|
1776
1792
|
num: isFullCoverage ? appliedUseCount : 1,
|
|
1777
1793
|
discount_rule_uncheck_flag: _selectedDiscount === null || _selectedDiscount === void 0 ? void 0 : _selectedDiscount.discount_rule_uncheck_flag
|
|
1778
1794
|
}, productDiscountDifference !== undefined && {
|
|
@@ -1830,7 +1846,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1830
1846
|
|
|
1831
1847
|
// 同一卡实例的本次新增使用合并为一条,metadata.num 记录实际次数。
|
|
1832
1848
|
for (var _i = 0; _i < fullCoveragePassUsageGroups.length; _i++) {
|
|
1833
|
-
var _selectedDiscount2$me;
|
|
1849
|
+
var _selectedDiscount2$me, _selectedDiscount2$me2;
|
|
1834
1850
|
var _fullCoveragePassUsag = fullCoveragePassUsageGroups[_i],
|
|
1835
1851
|
_selectedDiscount2 = _fullCoveragePassUsag.discount,
|
|
1836
1852
|
_appliedUseCount = _fullCoveragePassUsag.count;
|
|
@@ -1862,6 +1878,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1862
1878
|
discount_product_id: _selectedDiscount2.product_id
|
|
1863
1879
|
},
|
|
1864
1880
|
metadata: {
|
|
1881
|
+
encoded: ((_selectedDiscount2$me2 = _selectedDiscount2.metadata) === null || _selectedDiscount2$me2 === void 0 ? void 0 : _selectedDiscount2$me2.encoded) || _selectedDiscount2.encoded,
|
|
1865
1882
|
// 🔥 使用拆分后的唯一 _id
|
|
1866
1883
|
custom_product_bundle_map_id: uniqueId,
|
|
1867
1884
|
discount_rule_uncheck_flag: _selectedDiscount2 === null || _selectedDiscount2 === void 0 ? void 0 : _selectedDiscount2.discount_rule_uncheck_flag,
|
|
@@ -1901,7 +1918,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1901
1918
|
}));
|
|
1902
1919
|
}
|
|
1903
1920
|
} else {
|
|
1904
|
-
var _selectedDiscount3$me, _selectedDiscount3$me2, _reapplyDiscountPerce2, _flatItem$parentProdu9;
|
|
1921
|
+
var _selectedDiscount3$me, _selectedDiscount3$me2, _reapplyDiscountPerce2, _selectedDiscount3$me3, _flatItem$parentProdu9;
|
|
1905
1922
|
// 折扣卡:不拆分数量,直接应用
|
|
1906
1923
|
var _selectedDiscount3 = selectedDiscountCard || applicableDiscounts[0];
|
|
1907
1924
|
markDiscountUsed(_selectedDiscount3);
|
|
@@ -1956,6 +1973,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1956
1973
|
discount_product_id: _selectedDiscount3.product_id
|
|
1957
1974
|
},
|
|
1958
1975
|
metadata: _objectSpread({
|
|
1976
|
+
encoded: ((_selectedDiscount3$me3 = _selectedDiscount3.metadata) === null || _selectedDiscount3$me3 === void 0 ? void 0 : _selectedDiscount3$me3.encoded) || _selectedDiscount3.encoded,
|
|
1959
1977
|
// 🔥 使用唯一的 _id
|
|
1960
1978
|
custom_product_bundle_map_id: _uniqueId,
|
|
1961
1979
|
discount_rule_uncheck_flag: _selectedDiscount3 === null || _selectedDiscount3 === void 0 ? void 0 : _selectedDiscount3.discount_rule_uncheck_flag,
|
|
@@ -2133,8 +2151,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
2133
2151
|
|
|
2134
2152
|
// 🔥 更新主商品自己的 discount_list 中的 num(quantity=1)
|
|
2135
2153
|
var updatedMainDiscountList = mainProductData.discount_list.map(function (discount) {
|
|
2136
|
-
var _discount$
|
|
2137
|
-
if (discount !== null && discount !== void 0 && (_discount$
|
|
2154
|
+
var _discount$metadata7, _discount$metadata8;
|
|
2155
|
+
if (discount !== null && discount !== void 0 && (_discount$metadata7 = discount.metadata) !== null && _discount$metadata7 !== void 0 && _discount$metadata7.custom_product_bundle_map_id) {
|
|
2138
2156
|
// bundle的discount_list保持不变
|
|
2139
2157
|
return discount;
|
|
2140
2158
|
}
|
|
@@ -2142,7 +2160,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
2142
2160
|
return _objectSpread(_objectSpread({}, discount), {}, {
|
|
2143
2161
|
// num: 1,
|
|
2144
2162
|
metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
|
|
2145
|
-
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$
|
|
2163
|
+
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata8 = discount.metadata) === null || _discount$metadata8 === void 0 ? void 0 : _discount$metadata8.custom_product_bundle_map_id,
|
|
2146
2164
|
num: 1
|
|
2147
2165
|
})
|
|
2148
2166
|
});
|
|
@@ -2207,8 +2225,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
2207
2225
|
|
|
2208
2226
|
// 🔥 更新主商品自己的 discount_list 中的 num(quantity=原quantity-1)
|
|
2209
2227
|
var updatedMainDiscountListOriginal = mainProductData.discount_list.map(function (discount) {
|
|
2210
|
-
var _discount$
|
|
2211
|
-
if (discount !== null && discount !== void 0 && (_discount$
|
|
2228
|
+
var _discount$metadata9, _discount$metadata10;
|
|
2229
|
+
if (discount !== null && discount !== void 0 && (_discount$metadata9 = discount.metadata) !== null && _discount$metadata9 !== void 0 && _discount$metadata9.custom_product_bundle_map_id) {
|
|
2212
2230
|
// bundle的discount_list保持不变
|
|
2213
2231
|
return discount;
|
|
2214
2232
|
}
|
|
@@ -2216,7 +2234,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
2216
2234
|
return _objectSpread(_objectSpread({}, discount), {}, {
|
|
2217
2235
|
metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
|
|
2218
2236
|
num: mainProductQuantity - 1,
|
|
2219
|
-
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$
|
|
2237
|
+
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata10 = discount.metadata) === null || _discount$metadata10 === void 0 ? void 0 : _discount$metadata10.custom_product_bundle_map_id
|
|
2220
2238
|
})
|
|
2221
2239
|
// num: mainProductQuantity - 1,
|
|
2222
2240
|
});
|
|
@@ -2286,11 +2304,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
2286
2304
|
var nextBundleSellingPrice = (_ref28 = (_item$bundle_selling_ = item.bundle_selling_price) !== null && _item$bundle_selling_ !== void 0 ? _item$bundle_selling_ : item.price) !== null && _ref28 !== void 0 ? _ref28 : bundleItem.bundle_selling_price;
|
|
2287
2305
|
// 🔥 更新 discount_list 中的 num,使其与拆分后的 item.num 一致
|
|
2288
2306
|
var updatedDiscountList = (item.discount_list || []).map(function (discount) {
|
|
2289
|
-
var _discount$
|
|
2307
|
+
var _discount$metadata11;
|
|
2290
2308
|
return _objectSpread(_objectSpread({}, discount), {}, {
|
|
2291
2309
|
metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
|
|
2292
2310
|
num: item.num,
|
|
2293
|
-
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$
|
|
2311
|
+
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata11 = discount.metadata) === null || _discount$metadata11 === void 0 ? void 0 : _discount$metadata11.custom_product_bundle_map_id
|
|
2294
2312
|
})
|
|
2295
2313
|
// num: item.num, // 使用拆分后的 num
|
|
2296
2314
|
});
|
|
@@ -29,6 +29,10 @@ export interface RulesCalcDiscountOptions {
|
|
|
29
29
|
discountId?: number;
|
|
30
30
|
selectedList?: SetDiscountSelectedParams[];
|
|
31
31
|
scan?: boolean;
|
|
32
|
+
/** 本次扫码优先使用的次卡实例;普通重算不传,继续保留商品行当前选择。 */
|
|
33
|
+
preferredEntitlementPassIds?: number[];
|
|
34
|
+
/** 普通重算保留商品行已应用的次卡;最优选择传 false 恢复自动排序。 */
|
|
35
|
+
preserveEntitlementSelection?: boolean;
|
|
32
36
|
/** Change time 重报价目标行:允许已选编辑态折扣卡重新应用到这些 booking 商品。 */
|
|
33
37
|
reapplyBookingDiscountProductUids?: string[];
|
|
34
38
|
}
|
|
@@ -554,7 +554,8 @@ function normalizeProductDiscounts(params) {
|
|
|
554
554
|
var title = resolveDiscountTitleWithPercent(discount, locale);
|
|
555
555
|
var amount = (_ref15 = (_discount$amount2 = discount.amount) !== null && _discount$amount2 !== void 0 ? _discount$amount2 : discount.value) !== null && _ref15 !== void 0 ? _ref15 : discount.discount_amount;
|
|
556
556
|
var isMarkup = isManualMarkup(discount);
|
|
557
|
-
var
|
|
557
|
+
var isAggregatedBundleEntitlement = getProductWalletDiscountType(discount) === 'entitlement_pass' && Boolean(getReceiptDiscountBundleMapId(discount));
|
|
558
|
+
var totalAmount = new Decimal(toMoneyNumber(amount)).mul(isAggregatedBundleEntitlement ? 1 : quantity);
|
|
558
559
|
var formattedAmount = isMarkup ? formatMoney(totalAmount.abs(), currencySymbol) : formatNegativeMoney(totalAmount, currencySymbol);
|
|
559
560
|
return {
|
|
560
561
|
item: title,
|
|
@@ -654,6 +655,9 @@ function buildProductQuantityPriceText(params) {
|
|
|
654
655
|
function resolveDiscountTitleWithPercent(discount, locale) {
|
|
655
656
|
var _discount$discount2, _discount$discount$di, _discount$discount3;
|
|
656
657
|
var title = resolveDiscountTitle(discount, locale);
|
|
658
|
+
if (getProductWalletDiscountType(discount) === 'entitlement_pass') {
|
|
659
|
+
return title;
|
|
660
|
+
}
|
|
657
661
|
var percentRaw = (_discount$discount2 = discount.discount) === null || _discount$discount2 === void 0 ? void 0 : _discount$discount2.percent;
|
|
658
662
|
var cardType = (_discount$discount$di = (_discount$discount3 = discount.discount) === null || _discount$discount3 === void 0 ? void 0 : _discount$discount3.discount_card_type) !== null && _discount$discount$di !== void 0 ? _discount$discount$di : 'percent';
|
|
659
663
|
var percent = percentRaw !== undefined && percentRaw !== null ? Math.trunc(Number(percentRaw)) : NaN;
|
|
@@ -1738,9 +1742,8 @@ function getProductEntitlementBalance(asset) {
|
|
|
1738
1742
|
_step6;
|
|
1739
1743
|
try {
|
|
1740
1744
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
1741
|
-
var _record$metadata, _record$discount10, _record$discount11;
|
|
1742
1745
|
var record = _step6.value;
|
|
1743
|
-
var balance =
|
|
1746
|
+
var balance = getProductDiscountEntitlementBalance(record);
|
|
1744
1747
|
if (balance) return balance;
|
|
1745
1748
|
}
|
|
1746
1749
|
} catch (err) {
|
|
@@ -1750,6 +1753,10 @@ function getProductEntitlementBalance(asset) {
|
|
|
1750
1753
|
}
|
|
1751
1754
|
return null;
|
|
1752
1755
|
}
|
|
1756
|
+
function getProductDiscountEntitlementBalance(record) {
|
|
1757
|
+
var _record$metadata, _record$discount10, _record$discount11;
|
|
1758
|
+
return getEntitlementBalance((_record$metadata = record.metadata) === null || _record$metadata === void 0 ? void 0 : _record$metadata.balance, record.balance, (_record$discount10 = record.discount) === null || _record$discount10 === void 0 || (_record$discount10 = _record$discount10.metadata) === null || _record$discount10 === void 0 ? void 0 : _record$discount10.balance, (_record$discount11 = record.discount) === null || _record$discount11 === void 0 ? void 0 : _record$discount11.balance);
|
|
1759
|
+
}
|
|
1753
1760
|
function getEntitlementBalance() {
|
|
1754
1761
|
for (var _len3 = arguments.length, values = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
1755
1762
|
values[_key3] = arguments[_key3];
|
|
@@ -3302,6 +3302,8 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
3302
3302
|
return resolveIsFormSubject(tempOrder, product);
|
|
3303
3303
|
},
|
|
3304
3304
|
orderTotalAmount: orderTotalAmount
|
|
3305
|
+
}, {
|
|
3306
|
+
preserveEntitlementSelection: false
|
|
3305
3307
|
}) || result;
|
|
3306
3308
|
if (result.productList) {
|
|
3307
3309
|
tempOrder.products = preserveManualProductDiscountProducts(tempOrder.products, result.productList);
|
|
@@ -44,6 +44,7 @@ interface ApplicableProductDetails {
|
|
|
44
44
|
original_amount: string;
|
|
45
45
|
num: number;
|
|
46
46
|
metadata?: {
|
|
47
|
+
encoded?: string;
|
|
47
48
|
product_discount_difference?: number;
|
|
48
49
|
/** 月卡扣除本单新增使用后的剩余次数;不限次数时为 null。 */
|
|
49
50
|
balance?: number | null;
|
|
@@ -135,6 +136,7 @@ export interface Discount {
|
|
|
135
136
|
available_products_info?: any[];
|
|
136
137
|
format_title: Formattitle;
|
|
137
138
|
metadata?: {
|
|
139
|
+
encoded?: string;
|
|
138
140
|
discount_card_type?: 'fixed_amount' | 'percent';
|
|
139
141
|
custom_product_bundle_map_id?: string;
|
|
140
142
|
validity_type?: 'custom_schedule_validity' | 'fixed_validity';
|
|
@@ -168,6 +168,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
168
168
|
const key = Number.isFinite(id) ? id : String(resourceId);
|
|
169
169
|
const title = item?.discount?.title ?? {};
|
|
170
170
|
const amount = Number(item?.amount || 0);
|
|
171
|
+
const encoded = item?.metadata?.encoded || item?.encoded || item?.discount?.encoded || '';
|
|
171
172
|
const discountCardType = item?.discount?.discount_card_type;
|
|
172
173
|
const parValue = isDiscountCard ? discountCardType === 'fixed_amount' ? item?.discount?.fixed_amount ?? item?.amount : item?.discount?.percent : '0';
|
|
173
174
|
const detail = {
|
|
@@ -186,6 +187,13 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
186
187
|
};
|
|
187
188
|
const existed = discountMap.get(key);
|
|
188
189
|
if (existed) {
|
|
190
|
+
if (!existed.encoded && encoded) {
|
|
191
|
+
existed.encoded = encoded;
|
|
192
|
+
existed.metadata = {
|
|
193
|
+
...existed.metadata,
|
|
194
|
+
encoded
|
|
195
|
+
};
|
|
196
|
+
}
|
|
189
197
|
existed.amount = Number(existed.amount || 0) + amount;
|
|
190
198
|
existed.used_par_value = String(Number(existed.used_par_value || 0) + amount);
|
|
191
199
|
if (!isDiscountCard) {
|
|
@@ -205,8 +213,11 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
205
213
|
discountMap.set(key, {
|
|
206
214
|
id: key,
|
|
207
215
|
product_name: '',
|
|
208
|
-
encoded
|
|
209
|
-
code: '',
|
|
216
|
+
encoded,
|
|
217
|
+
code: item?.code || item?.discount?.code || '',
|
|
218
|
+
metadata: {
|
|
219
|
+
encoded
|
|
220
|
+
},
|
|
210
221
|
tag: type,
|
|
211
222
|
product_id: item?.discount?.discount_product_id ?? product?.product_id ?? 0,
|
|
212
223
|
relation_type: '',
|
|
@@ -728,7 +739,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
728
739
|
let resolvedDiscountList = normalizedNewDiscountList || this.getDiscountList();
|
|
729
740
|
if (isAvailable && normalizedNewDiscountList) {
|
|
730
741
|
await this.store.discount?.setDiscountList(normalizedNewDiscountList);
|
|
731
|
-
|
|
742
|
+
// 实际写回商品时沿用扫码试算的优先级,避免旧商品行的选卡覆盖本次扫码。
|
|
743
|
+
this.applyDiscount({
|
|
744
|
+
preferredEntitlementPassIds: withScanList.filter(discount => (0, _entitlementPass.isEntitlementPass)(discount)).map(discount => discount.id)
|
|
745
|
+
});
|
|
732
746
|
await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
|
|
733
747
|
resolvedDiscountList = this.getDiscountList();
|
|
734
748
|
} else if (shouldRetainForLater) {
|
|
@@ -786,7 +800,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
786
800
|
isFormSubject: product => (0, _utils.resolveIsFormSubject)(tempOrder, product),
|
|
787
801
|
orderTotalAmount: Number(this.store.summary?.total_amount || 0)
|
|
788
802
|
}, {
|
|
789
|
-
reapplyBookingDiscountProductUids: options?.reapplyBookingDiscountProductUids
|
|
803
|
+
reapplyBookingDiscountProductUids: options?.reapplyBookingDiscountProductUids,
|
|
804
|
+
preferredEntitlementPassIds: options?.preferredEntitlementPassIds
|
|
790
805
|
});
|
|
791
806
|
if (result?.productList) {
|
|
792
807
|
const previousProductsByUid = (0, _utils.indexOrderProductsByUid)(tempOrder.products);
|
|
@@ -104,10 +104,12 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
104
104
|
unavailableReason: _types.UnavailableReason.AlreadyUsed
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
|
+
const scannedEntitlementPassIds = newDiscountList.filter(discount => (0, _entitlementPass.isEntitlementPass)(discount)).map(discount => discount.id);
|
|
108
|
+
const scannedEntitlementPassIdSet = new Set(scannedEntitlementPassIds.map(String));
|
|
107
109
|
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
const filteredOldDiscountList = oldDiscountList.filter(discount => !discount.isEditMode && (!(0, _entitlementPass.isFullCoveragePass)(discount) || discount.isScan));
|
|
110
|
+
// 客户次卡必须保留在完整列表中;同一实例以本次扫码数据更新。
|
|
111
|
+
// 历史折扣不参与试算,商品券继续沿用仅保留扫码来源的规则。
|
|
112
|
+
const filteredOldDiscountList = oldDiscountList.filter(discount => !discount.isEditMode && (!(0, _entitlementPass.isFullCoveragePass)(discount) || (0, _entitlementPass.isEntitlementPass)(discount) || discount.isScan) && !scannedEntitlementPassIdSet.has(String(discount.id)));
|
|
111
113
|
const mergedDiscountList = (0, _utils.uniqueById)([...filteredOldDiscountList, ...newDiscountList]);
|
|
112
114
|
const result = this.calcDiscount({
|
|
113
115
|
discountList: mergedDiscountList,
|
|
@@ -116,7 +118,8 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
116
118
|
holders,
|
|
117
119
|
isFormSubject
|
|
118
120
|
}, {
|
|
119
|
-
scan: true
|
|
121
|
+
scan: true,
|
|
122
|
+
preferredEntitlementPassIds: scannedEntitlementPassIds
|
|
120
123
|
});
|
|
121
124
|
|
|
122
125
|
// 检查是否有产品使用了新折扣
|
|
@@ -216,6 +219,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
216
219
|
isFormSubject,
|
|
217
220
|
orderTotalAmount
|
|
218
221
|
}, options) {
|
|
222
|
+
const preferredEntitlementPassIds = new Set((options?.preferredEntitlementPassIds || []).map(String));
|
|
219
223
|
const resolveIsFormSubject = product => typeof isFormSubject === 'function' ? Boolean(isFormSubject(product)) : Boolean(isFormSubject);
|
|
220
224
|
|
|
221
225
|
// 识别出来是不是在编辑的界面里又新增了商品
|
|
@@ -969,6 +973,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
969
973
|
discount_product_id: discount.product_id
|
|
970
974
|
},
|
|
971
975
|
metadata: {
|
|
976
|
+
encoded: discount.metadata?.encoded || discount.encoded,
|
|
972
977
|
num: num,
|
|
973
978
|
discount_rule_uncheck_flag: discount?.discount_rule_uncheck_flag
|
|
974
979
|
}
|
|
@@ -1164,7 +1169,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1164
1169
|
return false;
|
|
1165
1170
|
});
|
|
1166
1171
|
|
|
1167
|
-
//
|
|
1172
|
+
// 识别用户本次显式选择的卡券,供次卡和折扣卡各自的优先级使用。
|
|
1168
1173
|
// 目标仍必须在当前商品的 applicableDiscounts 中,因此不会绕过 Holder、时间或商品范围校验。
|
|
1169
1174
|
const explicitlySelectedDiscount = options?.isSelected === true && options.discountId !== undefined ? applicableDiscounts.find(discount => {
|
|
1170
1175
|
const discountType = discount.tag || discount.type || '';
|
|
@@ -1173,21 +1178,23 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1173
1178
|
// 折扣卡会复用于整条商品行;商品券必须继续按单张拆分,不能复用该分支。
|
|
1174
1179
|
const explicitlySelectedDiscountCard = explicitlySelectedDiscount && !(0, _entitlementPass.isFullCoveragePass)(explicitlySelectedDiscount) ? explicitlySelectedDiscount : undefined;
|
|
1175
1180
|
|
|
1176
|
-
// 商品数量等变化会触发无 discountId
|
|
1181
|
+
// 商品数量等变化会触发无 discountId 的重算。只要当前行已应用的卡仍在
|
|
1177
1182
|
// applicableDiscounts 中,就应保留该行选择,避免被自动排序中力度更大的卡替换。
|
|
1178
|
-
const
|
|
1183
|
+
const appliedWalletDiscountIds = new Set((product.discount_list || []).filter(item => ['entitlement_pass', 'discount_card', 'product_discount_card'].includes(item?.tag || item?.type)).map(item => item?.discount?.resource_id ?? item?.resource_id ?? item?.id).filter(id => id !== undefined && id !== null).map(String));
|
|
1179
1184
|
const appliedDiscountCard = options?.scan ? undefined : applicableDiscounts.find(discount => {
|
|
1180
1185
|
const discountType = discount.tag || discount.type || '';
|
|
1181
|
-
return discount.isSelected === true && ['discount_card', 'product_discount_card'].includes(discountType) &&
|
|
1186
|
+
return discount.isSelected === true && ['discount_card', 'product_discount_card'].includes(discountType) && appliedWalletDiscountIds.has(String(discount.id));
|
|
1182
1187
|
});
|
|
1188
|
+
const appliedEntitlementPass = options?.scan || options?.preserveEntitlementSelection === false ? undefined : applicableDiscounts.find(discount => (0, _entitlementPass.isEntitlementPass)(discount) && discount.isSelected === true && appliedWalletDiscountIds.has(String(discount.id)));
|
|
1183
1189
|
|
|
1184
|
-
//
|
|
1190
|
+
// 次卡内部按本次手选/扫码、当前行已应用、默认排序选择;仍保留次卡相对其他券的优先级。
|
|
1185
1191
|
const scannedSelectedDiscountCard = applicableDiscounts.find(n => n.isScan && n.isSelected && !(0, _entitlementPass.isFullCoveragePass)(n));
|
|
1186
1192
|
const selectedDiscountCard = explicitlySelectedDiscountCard || appliedDiscountCard || scannedSelectedDiscountCard;
|
|
1187
|
-
const
|
|
1188
|
-
const selectedDiscount =
|
|
1189
|
-
|
|
1190
|
-
|
|
1193
|
+
const selectedEntitlementPass = (explicitlySelectedDiscount && (0, _entitlementPass.isEntitlementPass)(explicitlySelectedDiscount) ? explicitlySelectedDiscount : undefined) || applicableDiscounts.find(discount => (0, _entitlementPass.isEntitlementPass)(discount) && preferredEntitlementPassIds.has(String(discount.id))) || appliedEntitlementPass || applicableDiscounts.find(discount => (0, _entitlementPass.isEntitlementPass)(discount));
|
|
1194
|
+
const selectedDiscount = selectedEntitlementPass || explicitlySelectedDiscount || selectedDiscountCard || applicableDiscounts[0];
|
|
1195
|
+
// 实际次数分配必须使用同一顺序,避免选中状态切换后仍将次数分配给默认卡。
|
|
1196
|
+
const prioritizedApplicableDiscounts = selectedDiscount && (0, _entitlementPass.isFullCoveragePass)(selectedDiscount) ? [selectedDiscount, ...applicableDiscounts.filter(discount => {
|
|
1197
|
+
return (0, _entitlementPass.isFullCoveragePass)(discount) && String(discount.id) !== String(selectedDiscount.id);
|
|
1191
1198
|
}), ...applicableDiscounts.filter(discount => !(0, _entitlementPass.isFullCoveragePass)(discount))] : applicableDiscounts;
|
|
1192
1199
|
|
|
1193
1200
|
// 如果是手动折扣,则不适用优惠券
|
|
@@ -1461,6 +1468,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1461
1468
|
_num: isFullCoverage ? appliedUseCount : product.num,
|
|
1462
1469
|
config: selectedDiscount?.config,
|
|
1463
1470
|
metadata: {
|
|
1471
|
+
encoded: selectedDiscount.metadata?.encoded || selectedDiscount.encoded,
|
|
1464
1472
|
num: isFullCoverage ? appliedUseCount : 1,
|
|
1465
1473
|
discount_rule_uncheck_flag: selectedDiscount?.discount_rule_uncheck_flag,
|
|
1466
1474
|
// 🔥 order_level 分摊差值
|
|
@@ -1551,6 +1559,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1551
1559
|
discount_product_id: selectedDiscount.product_id
|
|
1552
1560
|
},
|
|
1553
1561
|
metadata: {
|
|
1562
|
+
encoded: selectedDiscount.metadata?.encoded || selectedDiscount.encoded,
|
|
1554
1563
|
// 🔥 使用拆分后的唯一 _id
|
|
1555
1564
|
custom_product_bundle_map_id: uniqueId,
|
|
1556
1565
|
discount_rule_uncheck_flag: selectedDiscount?.discount_rule_uncheck_flag,
|
|
@@ -1646,6 +1655,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1646
1655
|
discount_product_id: selectedDiscount.product_id
|
|
1647
1656
|
},
|
|
1648
1657
|
metadata: {
|
|
1658
|
+
encoded: selectedDiscount.metadata?.encoded || selectedDiscount.encoded,
|
|
1649
1659
|
// 🔥 使用唯一的 _id
|
|
1650
1660
|
custom_product_bundle_map_id: uniqueId,
|
|
1651
1661
|
discount_rule_uncheck_flag: selectedDiscount?.discount_rule_uncheck_flag,
|
|
@@ -29,6 +29,10 @@ export interface RulesCalcDiscountOptions {
|
|
|
29
29
|
discountId?: number;
|
|
30
30
|
selectedList?: SetDiscountSelectedParams[];
|
|
31
31
|
scan?: boolean;
|
|
32
|
+
/** 本次扫码优先使用的次卡实例;普通重算不传,继续保留商品行当前选择。 */
|
|
33
|
+
preferredEntitlementPassIds?: number[];
|
|
34
|
+
/** 普通重算保留商品行已应用的次卡;最优选择传 false 恢复自动排序。 */
|
|
35
|
+
preserveEntitlementSelection?: boolean;
|
|
32
36
|
/** Change time 重报价目标行:允许已选编辑态折扣卡重新应用到这些 booking 商品。 */
|
|
33
37
|
reapplyBookingDiscountProductUids?: string[];
|
|
34
38
|
}
|
|
@@ -527,7 +527,8 @@ function normalizeProductDiscounts(params) {
|
|
|
527
527
|
const title = resolveDiscountTitleWithPercent(discount, locale);
|
|
528
528
|
const amount = discount.amount ?? discount.value ?? discount.discount_amount;
|
|
529
529
|
const isMarkup = isManualMarkup(discount);
|
|
530
|
-
const
|
|
530
|
+
const isAggregatedBundleEntitlement = getProductWalletDiscountType(discount) === 'entitlement_pass' && Boolean(getReceiptDiscountBundleMapId(discount));
|
|
531
|
+
const totalAmount = new _decimal.default(toMoneyNumber(amount)).mul(isAggregatedBundleEntitlement ? 1 : quantity);
|
|
531
532
|
const formattedAmount = isMarkup ? formatMoney(totalAmount.abs(), currencySymbol) : formatNegativeMoney(totalAmount, currencySymbol);
|
|
532
533
|
return {
|
|
533
534
|
item: title,
|
|
@@ -620,6 +621,9 @@ function buildProductQuantityPriceText(params) {
|
|
|
620
621
|
}
|
|
621
622
|
function resolveDiscountTitleWithPercent(discount, locale) {
|
|
622
623
|
const title = resolveDiscountTitle(discount, locale);
|
|
624
|
+
if (getProductWalletDiscountType(discount) === 'entitlement_pass') {
|
|
625
|
+
return title;
|
|
626
|
+
}
|
|
623
627
|
const percentRaw = discount.discount?.percent;
|
|
624
628
|
const cardType = discount.discount?.discount_card_type ?? 'percent';
|
|
625
629
|
const percent = percentRaw !== undefined && percentRaw !== null ? Math.trunc(Number(percentRaw)) : NaN;
|
|
@@ -1591,11 +1595,14 @@ function getProductWalletDiscountTime(asset) {
|
|
|
1591
1595
|
}
|
|
1592
1596
|
function getProductEntitlementBalance(asset) {
|
|
1593
1597
|
for (const record of asset.records) {
|
|
1594
|
-
const balance =
|
|
1598
|
+
const balance = getProductDiscountEntitlementBalance(record);
|
|
1595
1599
|
if (balance) return balance;
|
|
1596
1600
|
}
|
|
1597
1601
|
return null;
|
|
1598
1602
|
}
|
|
1603
|
+
function getProductDiscountEntitlementBalance(record) {
|
|
1604
|
+
return getEntitlementBalance(record.metadata?.balance, record.balance, record.discount?.metadata?.balance, record.discount?.balance);
|
|
1605
|
+
}
|
|
1599
1606
|
function getEntitlementBalance(...values) {
|
|
1600
1607
|
for (const value of values) {
|
|
1601
1608
|
if (!isNumericAmount(value)) continue;
|
|
@@ -2111,6 +2111,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2111
2111
|
holders: [],
|
|
2112
2112
|
isFormSubject: product => (0, _utils.resolveIsFormSubject)(tempOrder, product),
|
|
2113
2113
|
orderTotalAmount
|
|
2114
|
+
}, {
|
|
2115
|
+
preserveEntitlementSelection: false
|
|
2114
2116
|
}) || result;
|
|
2115
2117
|
if (result.productList) {
|
|
2116
2118
|
tempOrder.products = preserveManualProductDiscountProducts(tempOrder.products, result.productList);
|