@pisell/pisellos 0.0.482 → 0.0.484
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 +2 -1
- package/dist/model/strategy/adapter/walletPass/type.d.ts +11 -0
- package/dist/modules/Discount/types.d.ts +2 -0
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Product/index.d.ts +1 -1
- package/dist/modules/Rules/index.js +128 -43
- package/dist/modules/Rules/types.d.ts +1 -0
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -1
- package/lib/model/strategy/adapter/walletPass/type.d.ts +11 -0
- package/lib/modules/Discount/types.d.ts +2 -0
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Product/index.d.ts +1 -1
- package/lib/modules/Rules/index.js +118 -46
- package/lib/modules/Rules/types.d.ts +1 -0
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -43,6 +43,8 @@ export interface Voucher {
|
|
|
43
43
|
applicableProductLimit: number;
|
|
44
44
|
/** 单订单行每单位可用同一 Wallet Pass 券次数;该行总券次上限 = maxPassesPerItem × 该行 quantity(按行唯一键区分)。0 表示不限制。 */
|
|
45
45
|
maxPassesPerItem: number;
|
|
46
|
+
/** 是否抵扣单规格价格 (Option Price),默认 false。开启后折扣范围包含 option 的 add_price */
|
|
47
|
+
deductOptionPrice: boolean;
|
|
46
48
|
};
|
|
47
49
|
}
|
|
48
50
|
/**
|
|
@@ -62,6 +64,13 @@ export interface Product {
|
|
|
62
64
|
main_product_original_price?: number;
|
|
63
65
|
/** 主商品折扣后金额,不包含套餐子商品 */
|
|
64
66
|
main_product_selling_price?: number;
|
|
67
|
+
/** 单规格(Option)列表 */
|
|
68
|
+
product_options?: {
|
|
69
|
+
id: number;
|
|
70
|
+
add_price: number | string;
|
|
71
|
+
num: number;
|
|
72
|
+
[key: string]: any;
|
|
73
|
+
}[];
|
|
65
74
|
/** 主商品税费 */
|
|
66
75
|
tax_fee: number;
|
|
67
76
|
metadata: {
|
|
@@ -141,6 +150,8 @@ export interface EvaluatorInput {
|
|
|
141
150
|
applicableProductLimit: number;
|
|
142
151
|
/** 单订单行每单位可用同一 Wallet Pass 券次数;行总上限 = maxPassesPerItem × 该行 quantity(按行唯一键计)。0 表示不限制。 */
|
|
143
152
|
maxPassesPerItem: number;
|
|
153
|
+
/** 是否抵扣单规格价格 (Option Price),默认 false */
|
|
154
|
+
deductOptionPrice: boolean;
|
|
144
155
|
}>[];
|
|
145
156
|
}
|
|
146
157
|
/**
|
|
@@ -120,6 +120,8 @@ export interface Discount {
|
|
|
120
120
|
allowCrossProduct?: boolean;
|
|
121
121
|
/** 可用商品数量上限 */
|
|
122
122
|
applicableProductLimit?: number;
|
|
123
|
+
/** 是否抵扣单规格价格 (Option Price) */
|
|
124
|
+
deductOptionPrice?: boolean;
|
|
123
125
|
};
|
|
124
126
|
applicableProductIds?: number[];
|
|
125
127
|
applicableProductDetails: ApplicableProductDetails[];
|
|
@@ -23,7 +23,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
23
23
|
*/
|
|
24
24
|
private logError;
|
|
25
25
|
createOrder(params: CommitOrderParams['query']): {
|
|
26
|
-
type: "
|
|
26
|
+
type: "virtual" | "appointment_booking";
|
|
27
27
|
platform: string;
|
|
28
28
|
sales_channel: string;
|
|
29
29
|
order_sales_channel: string;
|
|
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
|
|
|
49
49
|
getCategories(): ProductCategory[];
|
|
50
50
|
setOtherParams(key: string, value: any): void;
|
|
51
51
|
getOtherParams(): any;
|
|
52
|
-
getProductType(): "
|
|
52
|
+
getProductType(): "normal" | "duration" | "session";
|
|
53
53
|
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
var _excluded = ["_original_add_price"],
|
|
2
|
+
_excluded2 = ["_original_price", "_original_add_price"];
|
|
1
3
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
5
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
2
6
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
7
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
8
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
@@ -571,11 +575,13 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
571
575
|
|
|
572
576
|
// 转换 sortedFlattenedList 为 Product 格式
|
|
573
577
|
var productsForEvaluate = sortedFlattenedList.map(function (item) {
|
|
578
|
+
var _item$product;
|
|
574
579
|
return {
|
|
575
580
|
product_id: item.id,
|
|
576
581
|
price: item.price || 0,
|
|
577
582
|
quantity: item.quantity || item.num || 1,
|
|
578
|
-
selling_price: item.price || 0
|
|
583
|
+
selling_price: item.price || 0,
|
|
584
|
+
product_options: item.type === 'main' ? (_item$product = item.product) === null || _item$product === void 0 ? void 0 : _item$product.options : undefined
|
|
579
585
|
};
|
|
580
586
|
});
|
|
581
587
|
|
|
@@ -930,6 +936,61 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
930
936
|
// 🔥 用于存储扁平化商品处理结果的Map
|
|
931
937
|
var processedFlatItemsMap = new Map();
|
|
932
938
|
|
|
939
|
+
// 🔥 Option 折扣辅助函数
|
|
940
|
+
var applyDiscountToOptions = function applyDiscountToOptions(options, discount) {
|
|
941
|
+
if (!(options !== null && options !== void 0 && options.length)) return {
|
|
942
|
+
discountedOptions: options,
|
|
943
|
+
optionDiscountAmount: 0
|
|
944
|
+
};
|
|
945
|
+
var optionDiscountAmount = 0;
|
|
946
|
+
var discountedOptions = options.map(function (option) {
|
|
947
|
+
var _ref6, _ref7, _option$_original_pri, _ref8, _option$num, _rest$price, _option$_original_pri2;
|
|
948
|
+
// 折前单价:优先 price,缺失再 add_price;已写回折后价时用 _original_price(或旧字段 _original_add_price)
|
|
949
|
+
var rawUnit = (_ref6 = (_ref7 = (_option$_original_pri = option._original_price) !== null && _option$_original_pri !== void 0 ? _option$_original_pri : option._original_add_price) !== null && _ref7 !== void 0 ? _ref7 : option.price) !== null && _ref6 !== void 0 ? _ref6 : option.add_price;
|
|
950
|
+
var baseUnitNum = Number(rawUnit !== null && rawUnit !== void 0 ? rawUnit : 0);
|
|
951
|
+
if (baseUnitNum <= 0) return option;
|
|
952
|
+
var discountedPrice = getDiscountAmount(discount, baseUnitNum, baseUnitNum);
|
|
953
|
+
var optQty = Number((_ref8 = (_option$num = option.num) !== null && _option$num !== void 0 ? _option$num : option.quantity) !== null && _ref8 !== void 0 ? _ref8 : 1);
|
|
954
|
+
optionDiscountAmount = new Decimal(optionDiscountAmount).plus(new Decimal(baseUnitNum).minus(discountedPrice).mul(optQty)).toNumber();
|
|
955
|
+
var _original_add_price = option._original_add_price,
|
|
956
|
+
rest = _objectWithoutProperties(option, _excluded);
|
|
957
|
+
var tmpl = (_rest$price = rest.price) !== null && _rest$price !== void 0 ? _rest$price : rest.add_price;
|
|
958
|
+
var nextPrice = typeof tmpl === 'string' ? String(discountedPrice) : discountedPrice;
|
|
959
|
+
return _objectSpread(_objectSpread({}, rest), {}, {
|
|
960
|
+
_original_price: (_option$_original_pri2 = option._original_price) !== null && _option$_original_pri2 !== void 0 ? _option$_original_pri2 : _original_add_price !== undefined ? _original_add_price : rawUnit,
|
|
961
|
+
price: nextPrice
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
return {
|
|
965
|
+
discountedOptions: discountedOptions,
|
|
966
|
+
optionDiscountAmount: optionDiscountAmount
|
|
967
|
+
};
|
|
968
|
+
};
|
|
969
|
+
var restoreOptionPrices = function restoreOptionPrices(options) {
|
|
970
|
+
if (!(options !== null && options !== void 0 && options.length)) return options;
|
|
971
|
+
return options.map(function (option) {
|
|
972
|
+
var orig = option._original_price !== undefined ? option._original_price : option._original_add_price;
|
|
973
|
+
if (orig !== undefined) {
|
|
974
|
+
var _original_price = option._original_price,
|
|
975
|
+
_original_add_price = option._original_add_price,
|
|
976
|
+
rest = _objectWithoutProperties(option, _excluded2);
|
|
977
|
+
return _objectSpread(_objectSpread({}, rest), {}, {
|
|
978
|
+
price: orig
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
return option;
|
|
982
|
+
});
|
|
983
|
+
};
|
|
984
|
+
var getOptionTotal = function getOptionTotal(options) {
|
|
985
|
+
if (!(options !== null && options !== void 0 && options.length)) return 0;
|
|
986
|
+
return options.reduce(function (sum, opt) {
|
|
987
|
+
var _ref9, _opt$price, _ref10, _opt$num;
|
|
988
|
+
var unit = Number((_ref9 = (_opt$price = opt.price) !== null && _opt$price !== void 0 ? _opt$price : opt.add_price) !== null && _ref9 !== void 0 ? _ref9 : 0);
|
|
989
|
+
var n = Number((_ref10 = (_opt$num = opt.num) !== null && _opt$num !== void 0 ? _opt$num : opt.quantity) !== null && _ref10 !== void 0 ? _ref10 : 1);
|
|
990
|
+
return new Decimal(sum).plus(new Decimal(unit).mul(n)).toNumber();
|
|
991
|
+
}, 0);
|
|
992
|
+
};
|
|
993
|
+
|
|
933
994
|
// 然后再处理应用哪些优惠券,此时只考虑filteredDiscountList中的优惠券
|
|
934
995
|
// 🔥 使用扁平化后的列表进行处理
|
|
935
996
|
sortedFlattenedList.forEach(function (flatItem, index) {
|
|
@@ -1072,8 +1133,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1072
1133
|
var _product$discount_lis5, _product12, _product12$every;
|
|
1073
1134
|
// 主商品:判断自身是否手动折扣
|
|
1074
1135
|
isManualDiscount = typeof product.isManualDiscount === 'boolean' ? product.isManualDiscount : product.total != product.origin_total && (product.bundle || []).every(function (item) {
|
|
1075
|
-
var
|
|
1076
|
-
return !((
|
|
1136
|
+
var _ref11;
|
|
1137
|
+
return !((_ref11 = item.discount_list || []) !== null && _ref11 !== void 0 && _ref11.length);
|
|
1077
1138
|
}) && (!((_product$discount_lis5 = product.discount_list) !== null && _product$discount_lis5 !== void 0 && _product$discount_lis5.length) || ((_product12 = product) === null || _product12 === void 0 || (_product12 = _product12.discount_list) === null || _product12 === void 0 || (_product12$every = _product12.every) === null || _product12$every === void 0 ? void 0 : _product12$every.call(_product12, function (item) {
|
|
1078
1139
|
return item.type === 'product';
|
|
1079
1140
|
})));
|
|
@@ -1086,8 +1147,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1086
1147
|
if (parentProduct) {
|
|
1087
1148
|
var _parentProduct$discou, _parentProduct$discou2, _parentProduct$discou3;
|
|
1088
1149
|
isManualDiscount = typeof parentProduct.isManualDiscount === 'boolean' ? parentProduct.isManualDiscount : parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every(function (item) {
|
|
1089
|
-
var
|
|
1090
|
-
return !((
|
|
1150
|
+
var _ref12;
|
|
1151
|
+
return !((_ref12 = item.discount_list || []) !== null && _ref12 !== void 0 && _ref12.length);
|
|
1091
1152
|
}) && (!((_parentProduct$discou = parentProduct.discount_list) !== null && _parentProduct$discou !== void 0 && _parentProduct$discou.length) || (parentProduct === null || parentProduct === void 0 || (_parentProduct$discou2 = parentProduct.discount_list) === null || _parentProduct$discou2 === void 0 || (_parentProduct$discou3 = _parentProduct$discou2.every) === null || _parentProduct$discou3 === void 0 ? void 0 : _parentProduct$discou3.call(_parentProduct$discou2, function (item) {
|
|
1092
1153
|
return item.type === 'product';
|
|
1093
1154
|
})));
|
|
@@ -1154,7 +1215,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1154
1215
|
// 如果没有适用的优惠券,或者手动折扣,则不适用优惠券
|
|
1155
1216
|
if (applicableDiscounts.length === 0 || isManualDiscount || isBoolean(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
1156
1217
|
if (flatItem.type === 'main') {
|
|
1157
|
-
//
|
|
1218
|
+
// 主商品:保持原有逻辑,还原 option 价格
|
|
1219
|
+
var restoredOptions = restoreOptionPrices(product.options);
|
|
1158
1220
|
if (product.isClient) {
|
|
1159
1221
|
processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {} : {
|
|
1160
1222
|
origin_total: getProductOriginTotalPrice({
|
|
@@ -1162,7 +1224,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1162
1224
|
original_price: product.original_price
|
|
1163
1225
|
},
|
|
1164
1226
|
bundle: product.bundle,
|
|
1165
|
-
options:
|
|
1227
|
+
options: restoredOptions
|
|
1166
1228
|
}),
|
|
1167
1229
|
variant: originProduct._productInit.variant,
|
|
1168
1230
|
original_price: originProduct._productInit.original_price,
|
|
@@ -1171,15 +1233,16 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1171
1233
|
price: product.price
|
|
1172
1234
|
},
|
|
1173
1235
|
bundle: product.bundle,
|
|
1174
|
-
options:
|
|
1236
|
+
options: restoredOptions
|
|
1175
1237
|
}),
|
|
1176
|
-
price: product.price
|
|
1238
|
+
price: product.price,
|
|
1239
|
+
options: restoredOptions
|
|
1177
1240
|
}), {}, {
|
|
1178
1241
|
discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion')
|
|
1179
1242
|
}))]);
|
|
1180
1243
|
} else {
|
|
1181
|
-
var
|
|
1182
|
-
var total = product.inPromotion ? (
|
|
1244
|
+
var _ref13, _product$_promotion$f, _product13, _product$origin_total, _product$price2;
|
|
1245
|
+
var total = product.inPromotion ? (_ref13 = (_product$_promotion$f = (_product13 = product) === null || _product13 === void 0 || (_product13 = _product13._promotion) === null || _product13 === void 0 ? void 0 : _product13.finalPrice) !== null && _product$_promotion$f !== void 0 ? _product$_promotion$f : product.origin_total) !== null && _ref13 !== void 0 ? _ref13 : product.total : (_product$origin_total = product.origin_total) !== null && _product$origin_total !== void 0 ? _product$origin_total : product.total;
|
|
1183
1246
|
var main_product_selling_price = (_product$price2 = product.price) !== null && _product$price2 !== void 0 ? _product$price2 : product.main_product_selling_price;
|
|
1184
1247
|
if ((product.discount_list || []).some(function (item) {
|
|
1185
1248
|
return item.type === 'promotion';
|
|
@@ -1194,7 +1257,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1194
1257
|
_id: product._id.split('___')[0] + '___' + index,
|
|
1195
1258
|
total: total,
|
|
1196
1259
|
price: product.price,
|
|
1197
|
-
main_product_selling_price: main_product_selling_price
|
|
1260
|
+
main_product_selling_price: main_product_selling_price,
|
|
1261
|
+
options: restoredOptions
|
|
1198
1262
|
}), {}, {
|
|
1199
1263
|
discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion')
|
|
1200
1264
|
}))]);
|
|
@@ -1269,7 +1333,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1269
1333
|
}));
|
|
1270
1334
|
}
|
|
1271
1335
|
for (var i = 0; i < splitCount; i++) {
|
|
1272
|
-
var _originProduct, _selectedDiscount$met, _selectedDiscount$met2;
|
|
1336
|
+
var _originProduct, _selectedDiscount$con2, _product$options, _product$options2, _selectedDiscount$met, _selectedDiscount$met2;
|
|
1273
1337
|
// 商品券:每个拆分商品使用不同的商品券(从 applicableDiscounts 按索引取)
|
|
1274
1338
|
// 折扣卡:所有拆分商品使用同一张折扣卡(selectedDiscountCard 或 applicableDiscounts[0])
|
|
1275
1339
|
var currentSelectedDiscount = isGoodPass ? selectedDiscountCard || applicableDiscounts[i] : selectedDiscountCard || applicableDiscounts[0];
|
|
@@ -1306,28 +1370,47 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1306
1370
|
var isOrderLevel = isOrderLevelFixedAmountDiscount(selectedDiscount);
|
|
1307
1371
|
var orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
|
|
1308
1372
|
var productAllocation = orderLevelAllocation === null || orderLevelAllocation === void 0 ? void 0 : orderLevelAllocation.get(flatItem._id);
|
|
1309
|
-
var
|
|
1373
|
+
var isDeductOptionPrice = !!((_selectedDiscount$con2 = selectedDiscount.config) !== null && _selectedDiscount$con2 !== void 0 && _selectedDiscount$con2.deductOptionPrice);
|
|
1374
|
+
|
|
1375
|
+
// 主商品折后价(不含 option);勿与 option 合计混在同一变量,否则 main_product_selling_price 错误
|
|
1376
|
+
var mainProductSellingPrice = void 0;
|
|
1310
1377
|
var amount = void 0;
|
|
1311
1378
|
var productDiscountDifference = void 0;
|
|
1379
|
+
var discountedOptions = product.options;
|
|
1380
|
+
var optionDiscountAmount = 0;
|
|
1312
1381
|
if (isOrderLevel && productAllocation) {
|
|
1313
1382
|
// order_level:使用预计算的分摊金额
|
|
1314
1383
|
amount = productAllocation.discountAmount;
|
|
1315
1384
|
productDiscountDifference = productAllocation.difference;
|
|
1316
|
-
|
|
1385
|
+
mainProductSellingPrice = Math.max(new Decimal(product.price).minus(amount).toNumber(), 0);
|
|
1317
1386
|
} else {
|
|
1318
1387
|
// item_level 或其他类型:使用原有逻辑
|
|
1319
|
-
|
|
1320
|
-
amount = new Decimal(product.price).minus(new Decimal(
|
|
1388
|
+
mainProductSellingPrice = getDiscountAmount(currentSelectedDiscount, product.price, product.price);
|
|
1389
|
+
amount = new Decimal(product.price).minus(new Decimal(mainProductSellingPrice)).toNumber();
|
|
1390
|
+
}
|
|
1391
|
+
if (isDeductOptionPrice && (_product$options = product.options) !== null && _product$options !== void 0 && _product$options.length) {
|
|
1392
|
+
var optionResult = applyDiscountToOptions(product.options, currentSelectedDiscount);
|
|
1393
|
+
discountedOptions = optionResult.discountedOptions;
|
|
1394
|
+
optionDiscountAmount = optionResult.optionDiscountAmount;
|
|
1321
1395
|
}
|
|
1396
|
+
|
|
1397
|
+
// total = 主商品折后 + option 行合计;开启 option 抵扣时必须用 discountedOptions,不能用未折扣的 product.options 再算一遍
|
|
1398
|
+
var optionsForLineTotal = isDeductOptionPrice && (_product$options2 = product.options) !== null && _product$options2 !== void 0 && _product$options2.length ? discountedOptions : product.options;
|
|
1399
|
+
var optionsLineTotal = getOptionTotal(optionsForLineTotal || []);
|
|
1400
|
+
var _total2 = new Decimal(mainProductSellingPrice).plus(optionsLineTotal).toNumber();
|
|
1401
|
+
|
|
1402
|
+
// discount_list.amount / fixed_amount:行级总优惠 = 主商品优惠 + option 优惠(与 total 变化一致)
|
|
1403
|
+
var mainProductDiscountAmount = amount;
|
|
1404
|
+
var lineDiscountAmount = new Decimal(mainProductDiscountAmount).plus(optionDiscountAmount).toNumber();
|
|
1322
1405
|
var currentDiscountType = currentSelectedDiscount.tag === 'product_discount_card' ? 'discount_card' : currentSelectedDiscount.tag;
|
|
1323
1406
|
var _discountType = selectedDiscount.tag || selectedDiscount.type;
|
|
1324
1407
|
var currentIsGoodPass = currentDiscountType === 'good_pass';
|
|
1325
1408
|
var discountDetail = {
|
|
1326
|
-
amount:
|
|
1409
|
+
amount: lineDiscountAmount,
|
|
1327
1410
|
type: selectedDiscount.tag === 'product_discount_card' ? 'discount_card' : _discountType,
|
|
1328
1411
|
discount: {
|
|
1329
1412
|
discount_card_type: selectedDiscount === null || selectedDiscount === void 0 || (_selectedDiscount$met = selectedDiscount.metadata) === null || _selectedDiscount$met === void 0 ? void 0 : _selectedDiscount$met.discount_card_type,
|
|
1330
|
-
fixed_amount:
|
|
1413
|
+
fixed_amount: lineDiscountAmount,
|
|
1331
1414
|
discount_calculation_mode: selectedDiscount === null || selectedDiscount === void 0 || (_selectedDiscount$met2 = selectedDiscount.metadata) === null || _selectedDiscount$met2 === void 0 ? void 0 : _selectedDiscount$met2.discount_calculation_mode,
|
|
1332
1415
|
resource_id: selectedDiscount.id,
|
|
1333
1416
|
title: selectedDiscount.format_title,
|
|
@@ -1339,41 +1422,39 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1339
1422
|
// 前端使用的num数量,为了计算优惠金额(拆分时为1)
|
|
1340
1423
|
_num: isNeedSplit ? 1 : product.num,
|
|
1341
1424
|
config: currentSelectedDiscount === null || currentSelectedDiscount === void 0 ? void 0 : currentSelectedDiscount.config,
|
|
1342
|
-
metadata: _objectSpread({
|
|
1425
|
+
metadata: _objectSpread(_objectSpread({
|
|
1343
1426
|
num: 1,
|
|
1344
1427
|
discount_rule_uncheck_flag: selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.discount_rule_uncheck_flag
|
|
1345
1428
|
}, productDiscountDifference !== undefined && {
|
|
1346
1429
|
product_discount_difference: productDiscountDifference
|
|
1430
|
+
}), {}, {
|
|
1431
|
+
/** 仅主商品上的优惠金额(不含 option) */
|
|
1432
|
+
mainProductDiscountAmount: mainProductDiscountAmount,
|
|
1433
|
+
optionDiscountAmount: optionDiscountAmount
|
|
1347
1434
|
})
|
|
1348
1435
|
};
|
|
1349
1436
|
appliedProducts.push(discountDetail);
|
|
1350
1437
|
appliedDiscountProducts.set(currentSelectedDiscount.id, appliedProducts);
|
|
1351
|
-
var _total2 = targetProductTotal;
|
|
1352
|
-
if (product.options) {
|
|
1353
|
-
_total2 = product.options.reduce(function (accumulator, currentValue) {
|
|
1354
|
-
var currentPrice = new Decimal(currentValue.price || 0);
|
|
1355
|
-
var currentNum = new Decimal(currentValue.num || 0);
|
|
1356
|
-
return accumulator.add(currentPrice.mul(currentNum));
|
|
1357
|
-
}, new Decimal(_total2)).toNumber();
|
|
1358
|
-
}
|
|
1359
1438
|
|
|
1360
1439
|
// 记录应用了优惠券的商品
|
|
1361
1440
|
// 后续更新价格改为 getProductTotalPrice getProductOriginTotalPrice逻辑
|
|
1362
1441
|
if (product.isClient) {
|
|
1363
1442
|
arr.push(_this3.hooks.setProduct(originProduct, {
|
|
1364
1443
|
discount_list: [discountDetail],
|
|
1365
|
-
|
|
1444
|
+
// good_pass:主商品价以折后价为准;勿用 product.price - amount(amount 含 option 优惠时会算错)
|
|
1445
|
+
price: currentIsGoodPass ? mainProductSellingPrice : product.price,
|
|
1366
1446
|
quantity: isNeedSplit ? 1 : product.quantity,
|
|
1367
1447
|
origin_total: getProductOriginTotalPrice({
|
|
1368
1448
|
product: {
|
|
1369
1449
|
original_price: product.original_price
|
|
1370
1450
|
},
|
|
1371
1451
|
bundle: product.bundle,
|
|
1372
|
-
options: product.options
|
|
1452
|
+
options: restoreOptionPrices(product.options)
|
|
1373
1453
|
}),
|
|
1374
1454
|
variant: originProduct._productInit.variant,
|
|
1375
1455
|
original_price: new Decimal(product.price || 0).toNumber(),
|
|
1376
|
-
total: _total2
|
|
1456
|
+
total: _total2,
|
|
1457
|
+
options: discountedOptions
|
|
1377
1458
|
}));
|
|
1378
1459
|
} else {
|
|
1379
1460
|
arr.push(_this3.hooks.setProduct(originProduct, {
|
|
@@ -1383,7 +1464,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1383
1464
|
quantity: isNeedSplit ? 1 : product.quantity,
|
|
1384
1465
|
total: _total2,
|
|
1385
1466
|
origin_total: productOriginTotal,
|
|
1386
|
-
main_product_selling_price:
|
|
1467
|
+
main_product_selling_price: mainProductSellingPrice,
|
|
1468
|
+
options: discountedOptions
|
|
1387
1469
|
}));
|
|
1388
1470
|
}
|
|
1389
1471
|
}
|
|
@@ -1720,22 +1802,22 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1720
1802
|
var _isOrderLevel = isOrderLevelFixedAmountDiscount(selectedDiscount);
|
|
1721
1803
|
var _orderLevelAllocation = _isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
|
|
1722
1804
|
var _productAllocation = _orderLevelAllocation === null || _orderLevelAllocation === void 0 ? void 0 : _orderLevelAllocation.get(flatItem._id);
|
|
1723
|
-
var
|
|
1805
|
+
var targetProductTotal;
|
|
1724
1806
|
var fixedAmountPerItem;
|
|
1725
1807
|
var _productDiscountDifference;
|
|
1726
1808
|
if (_isOrderLevel && _productAllocation) {
|
|
1727
1809
|
// order_level:使用预计算的单价折扣金额(已经是单价,无需再除以数量)
|
|
1728
1810
|
fixedAmountPerItem = _productAllocation.discountAmount;
|
|
1729
1811
|
_productDiscountDifference = _productAllocation.difference;
|
|
1730
|
-
|
|
1812
|
+
targetProductTotal = Math.max(new Decimal(_productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
|
|
1731
1813
|
} else {
|
|
1732
1814
|
// item_level 或其他类型:使用原有逻辑
|
|
1733
|
-
|
|
1734
|
-
fixedAmountPerItem = new Decimal(_productOriginTotal).minus(
|
|
1815
|
+
targetProductTotal = getDiscountAmount(_currentBundleDiscount, _productOriginTotal, _productOriginTotal);
|
|
1816
|
+
fixedAmountPerItem = new Decimal(_productOriginTotal).minus(targetProductTotal).toNumber();
|
|
1735
1817
|
}
|
|
1736
1818
|
|
|
1737
1819
|
// 计算实际折扣金额
|
|
1738
|
-
var bundleActualDiscountAmount = new Decimal(_productOriginTotal).minus(
|
|
1820
|
+
var bundleActualDiscountAmount = new Decimal(_productOriginTotal).minus(targetProductTotal).toNumber();
|
|
1739
1821
|
|
|
1740
1822
|
// 🔥 使用当前的 _id 作为唯一标识
|
|
1741
1823
|
var _uniqueId = flatItem._id;
|
|
@@ -1770,7 +1852,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1770
1852
|
_appliedProducts2.push(_discountDetail2);
|
|
1771
1853
|
appliedDiscountProducts.set(_currentBundleDiscount.id, _appliedProducts2);
|
|
1772
1854
|
processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
|
|
1773
|
-
total:
|
|
1855
|
+
total: targetProductTotal,
|
|
1774
1856
|
price: new Decimal(_productOriginTotal || 0).minus(fixedAmountPerItem).toNumber(),
|
|
1775
1857
|
discount_list: _this3.filterDiscountListByType(flatItem.discount_list, 'promotion').concat([_discountDetail2]),
|
|
1776
1858
|
processed: true
|
|
@@ -1789,8 +1871,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1789
1871
|
// 获取主商品处理结果
|
|
1790
1872
|
var mainProductArr = processedProductsMap.get(product._id);
|
|
1791
1873
|
if (!mainProductArr || mainProductArr.length === 0) {
|
|
1792
|
-
//
|
|
1874
|
+
// 如果没有处理结果,返回默认商品(还原 option 价格)
|
|
1793
1875
|
var getDefaultProduct = function getDefaultProduct() {
|
|
1876
|
+
var restoredOptions = restoreOptionPrices(product.options);
|
|
1794
1877
|
if (product.isClient) {
|
|
1795
1878
|
return _this3.hooks.setProduct(originProduct, {
|
|
1796
1879
|
discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
|
|
@@ -1800,7 +1883,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1800
1883
|
original_price: product.original_price
|
|
1801
1884
|
},
|
|
1802
1885
|
bundle: product.bundle,
|
|
1803
|
-
options:
|
|
1886
|
+
options: restoredOptions
|
|
1804
1887
|
}),
|
|
1805
1888
|
variant: originProduct._productInit.variant,
|
|
1806
1889
|
original_price: originProduct._productInit.original_price,
|
|
@@ -1809,15 +1892,17 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1809
1892
|
price: product.price
|
|
1810
1893
|
},
|
|
1811
1894
|
bundle: product.bundle,
|
|
1812
|
-
options:
|
|
1813
|
-
})
|
|
1895
|
+
options: restoredOptions
|
|
1896
|
+
}),
|
|
1897
|
+
options: restoredOptions
|
|
1814
1898
|
});
|
|
1815
1899
|
} else {
|
|
1816
1900
|
return _this3.hooks.setProduct(originProduct, {
|
|
1817
1901
|
discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
|
|
1818
1902
|
total: product.total,
|
|
1819
1903
|
origin_total: product.origin_total,
|
|
1820
|
-
price: product.price
|
|
1904
|
+
price: product.price,
|
|
1905
|
+
options: restoreOptionPrices(product.options)
|
|
1821
1906
|
});
|
|
1822
1907
|
}
|
|
1823
1908
|
};
|
|
@@ -131,7 +131,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
|
|
|
131
131
|
* 获取当前的客户搜索条件
|
|
132
132
|
* @returns 当前搜索条件
|
|
133
133
|
*/
|
|
134
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
134
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
|
|
135
135
|
/**
|
|
136
136
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
137
137
|
* @returns 客户状态
|
|
@@ -42,7 +42,8 @@ var defaultStrategyMetadataCustom = {
|
|
|
42
42
|
allowCrossProduct: true,
|
|
43
43
|
applicableProductLimit: 0,
|
|
44
44
|
deductTaxAndFee: true,
|
|
45
|
-
maxPassesPerItem: 0
|
|
45
|
+
maxPassesPerItem: 0,
|
|
46
|
+
deductOptionPrice: false
|
|
46
47
|
};
|
|
47
48
|
var WalletPassEvaluator = class {
|
|
48
49
|
constructor() {
|
|
@@ -43,6 +43,8 @@ export interface Voucher {
|
|
|
43
43
|
applicableProductLimit: number;
|
|
44
44
|
/** 单订单行每单位可用同一 Wallet Pass 券次数;该行总券次上限 = maxPassesPerItem × 该行 quantity(按行唯一键区分)。0 表示不限制。 */
|
|
45
45
|
maxPassesPerItem: number;
|
|
46
|
+
/** 是否抵扣单规格价格 (Option Price),默认 false。开启后折扣范围包含 option 的 add_price */
|
|
47
|
+
deductOptionPrice: boolean;
|
|
46
48
|
};
|
|
47
49
|
}
|
|
48
50
|
/**
|
|
@@ -62,6 +64,13 @@ export interface Product {
|
|
|
62
64
|
main_product_original_price?: number;
|
|
63
65
|
/** 主商品折扣后金额,不包含套餐子商品 */
|
|
64
66
|
main_product_selling_price?: number;
|
|
67
|
+
/** 单规格(Option)列表 */
|
|
68
|
+
product_options?: {
|
|
69
|
+
id: number;
|
|
70
|
+
add_price: number | string;
|
|
71
|
+
num: number;
|
|
72
|
+
[key: string]: any;
|
|
73
|
+
}[];
|
|
65
74
|
/** 主商品税费 */
|
|
66
75
|
tax_fee: number;
|
|
67
76
|
metadata: {
|
|
@@ -141,6 +150,8 @@ export interface EvaluatorInput {
|
|
|
141
150
|
applicableProductLimit: number;
|
|
142
151
|
/** 单订单行每单位可用同一 Wallet Pass 券次数;行总上限 = maxPassesPerItem × 该行 quantity(按行唯一键计)。0 表示不限制。 */
|
|
143
152
|
maxPassesPerItem: number;
|
|
153
|
+
/** 是否抵扣单规格价格 (Option Price),默认 false */
|
|
154
|
+
deductOptionPrice: boolean;
|
|
144
155
|
}>[];
|
|
145
156
|
}
|
|
146
157
|
/**
|
|
@@ -120,6 +120,8 @@ export interface Discount {
|
|
|
120
120
|
allowCrossProduct?: boolean;
|
|
121
121
|
/** 可用商品数量上限 */
|
|
122
122
|
applicableProductLimit?: number;
|
|
123
|
+
/** 是否抵扣单规格价格 (Option Price) */
|
|
124
|
+
deductOptionPrice?: boolean;
|
|
123
125
|
};
|
|
124
126
|
applicableProductIds?: number[];
|
|
125
127
|
applicableProductDetails: ApplicableProductDetails[];
|
|
@@ -23,7 +23,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
23
23
|
*/
|
|
24
24
|
private logError;
|
|
25
25
|
createOrder(params: CommitOrderParams['query']): {
|
|
26
|
-
type: "
|
|
26
|
+
type: "virtual" | "appointment_booking";
|
|
27
27
|
platform: string;
|
|
28
28
|
sales_channel: string;
|
|
29
29
|
order_sales_channel: string;
|
|
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
|
|
|
49
49
|
getCategories(): ProductCategory[];
|
|
50
50
|
setOtherParams(key: string, value: any): void;
|
|
51
51
|
getOtherParams(): any;
|
|
52
|
-
getProductType(): "
|
|
52
|
+
getProductType(): "normal" | "duration" | "session";
|
|
53
53
|
}
|
|
@@ -390,12 +390,16 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
390
390
|
available_product_type: (_a = discount.limited_relation_product_data) == null ? void 0 : _a.type,
|
|
391
391
|
available_product_ids: (_b = discount.limited_relation_product_data) == null ? void 0 : _b.product_ids
|
|
392
392
|
};
|
|
393
|
-
const productsForEvaluate = sortedFlattenedList.map((item) =>
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
393
|
+
const productsForEvaluate = sortedFlattenedList.map((item) => {
|
|
394
|
+
var _a2;
|
|
395
|
+
return {
|
|
396
|
+
product_id: item.id,
|
|
397
|
+
price: item.price || 0,
|
|
398
|
+
quantity: item.quantity || item.num || 1,
|
|
399
|
+
selling_price: item.price || 0,
|
|
400
|
+
product_options: item.type === "main" ? (_a2 = item.product) == null ? void 0 : _a2.options : void 0
|
|
401
|
+
};
|
|
402
|
+
});
|
|
399
403
|
const result = evaluator.checkVoucherAvailability({
|
|
400
404
|
orderTotalAmount,
|
|
401
405
|
products: productsForEvaluate,
|
|
@@ -632,8 +636,52 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
632
636
|
});
|
|
633
637
|
});
|
|
634
638
|
const processedFlatItemsMap = /* @__PURE__ */ new Map();
|
|
639
|
+
const applyDiscountToOptions = (options2, discount) => {
|
|
640
|
+
if (!(options2 == null ? void 0 : options2.length))
|
|
641
|
+
return { discountedOptions: options2, optionDiscountAmount: 0 };
|
|
642
|
+
let optionDiscountAmount = 0;
|
|
643
|
+
const discountedOptions = options2.map((option) => {
|
|
644
|
+
const rawUnit = option._original_price ?? option._original_add_price ?? option.price ?? option.add_price;
|
|
645
|
+
const baseUnitNum = Number(rawUnit ?? 0);
|
|
646
|
+
if (baseUnitNum <= 0)
|
|
647
|
+
return option;
|
|
648
|
+
const discountedPrice = (0, import_utils.getDiscountAmount)(discount, baseUnitNum, baseUnitNum);
|
|
649
|
+
const optQty = Number(option.num ?? option.quantity ?? 1);
|
|
650
|
+
optionDiscountAmount = new import_decimal.default(optionDiscountAmount).plus(new import_decimal.default(baseUnitNum).minus(discountedPrice).mul(optQty)).toNumber();
|
|
651
|
+
const { _original_add_price, ...rest } = option;
|
|
652
|
+
const tmpl = rest.price ?? rest.add_price;
|
|
653
|
+
const nextPrice = typeof tmpl === "string" ? String(discountedPrice) : discountedPrice;
|
|
654
|
+
return {
|
|
655
|
+
...rest,
|
|
656
|
+
_original_price: option._original_price ?? (_original_add_price !== void 0 ? _original_add_price : rawUnit),
|
|
657
|
+
price: nextPrice
|
|
658
|
+
};
|
|
659
|
+
});
|
|
660
|
+
return { discountedOptions, optionDiscountAmount };
|
|
661
|
+
};
|
|
662
|
+
const restoreOptionPrices = (options2) => {
|
|
663
|
+
if (!(options2 == null ? void 0 : options2.length))
|
|
664
|
+
return options2;
|
|
665
|
+
return options2.map((option) => {
|
|
666
|
+
const orig = option._original_price !== void 0 ? option._original_price : option._original_add_price;
|
|
667
|
+
if (orig !== void 0) {
|
|
668
|
+
const { _original_price, _original_add_price, ...rest } = option;
|
|
669
|
+
return { ...rest, price: orig };
|
|
670
|
+
}
|
|
671
|
+
return option;
|
|
672
|
+
});
|
|
673
|
+
};
|
|
674
|
+
const getOptionTotal = (options2) => {
|
|
675
|
+
if (!(options2 == null ? void 0 : options2.length))
|
|
676
|
+
return 0;
|
|
677
|
+
return options2.reduce((sum, opt) => {
|
|
678
|
+
const unit = Number(opt.price ?? opt.add_price ?? 0);
|
|
679
|
+
const n = Number(opt.num ?? opt.quantity ?? 1);
|
|
680
|
+
return new import_decimal.default(sum).plus(new import_decimal.default(unit).mul(n)).toNumber();
|
|
681
|
+
}, 0);
|
|
682
|
+
};
|
|
635
683
|
sortedFlattenedList.forEach((flatItem, index) => {
|
|
636
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J;
|
|
684
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M;
|
|
637
685
|
let product, originProduct;
|
|
638
686
|
if (flatItem.type === "main") {
|
|
639
687
|
product = flatItem.product;
|
|
@@ -842,6 +890,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
842
890
|
}
|
|
843
891
|
if (applicableDiscounts.length === 0 || isManualDiscount || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
844
892
|
if (flatItem.type === "main") {
|
|
893
|
+
const restoredOptions = restoreOptionPrices(product.options);
|
|
845
894
|
if (product.isClient) {
|
|
846
895
|
processedProductsMap.set(product._id, [
|
|
847
896
|
this.hooks.setProduct(originProduct, {
|
|
@@ -851,7 +900,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
851
900
|
original_price: product.original_price
|
|
852
901
|
},
|
|
853
902
|
bundle: product.bundle,
|
|
854
|
-
options:
|
|
903
|
+
options: restoredOptions
|
|
855
904
|
}),
|
|
856
905
|
variant: originProduct._productInit.variant,
|
|
857
906
|
original_price: originProduct._productInit.original_price,
|
|
@@ -860,9 +909,10 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
860
909
|
price: product.price
|
|
861
910
|
},
|
|
862
911
|
bundle: product.bundle,
|
|
863
|
-
options:
|
|
912
|
+
options: restoredOptions
|
|
864
913
|
}),
|
|
865
|
-
price: product.price
|
|
914
|
+
price: product.price,
|
|
915
|
+
options: restoredOptions
|
|
866
916
|
},
|
|
867
917
|
discount_list: this.filterDiscountListByType(product.discount_list, "promotion")
|
|
868
918
|
})
|
|
@@ -882,7 +932,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
882
932
|
_id: product._id.split("___")[0] + "___" + index,
|
|
883
933
|
total,
|
|
884
934
|
price: product.price,
|
|
885
|
-
main_product_selling_price
|
|
935
|
+
main_product_selling_price,
|
|
936
|
+
options: restoredOptions
|
|
886
937
|
},
|
|
887
938
|
discount_list: this.filterDiscountListByType(product.discount_list, "promotion")
|
|
888
939
|
})
|
|
@@ -965,27 +1016,47 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
965
1016
|
const isOrderLevel = (0, import_utils3.isOrderLevelFixedAmountDiscount)(selectedDiscount);
|
|
966
1017
|
const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
|
|
967
1018
|
const productAllocation = orderLevelAllocation == null ? void 0 : orderLevelAllocation.get(flatItem._id);
|
|
968
|
-
|
|
1019
|
+
const isDeductOptionPrice = !!((_y = selectedDiscount.config) == null ? void 0 : _y.deductOptionPrice);
|
|
1020
|
+
let mainProductSellingPrice;
|
|
969
1021
|
let amount;
|
|
970
1022
|
let productDiscountDifference;
|
|
1023
|
+
let discountedOptions = product.options;
|
|
1024
|
+
let optionDiscountAmount = 0;
|
|
971
1025
|
if (isOrderLevel && productAllocation) {
|
|
972
1026
|
amount = productAllocation.discountAmount;
|
|
973
1027
|
productDiscountDifference = productAllocation.difference;
|
|
974
|
-
|
|
1028
|
+
mainProductSellingPrice = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
|
|
975
1029
|
} else {
|
|
976
|
-
|
|
977
|
-
|
|
1030
|
+
mainProductSellingPrice = (0, import_utils.getDiscountAmount)(
|
|
1031
|
+
currentSelectedDiscount,
|
|
1032
|
+
product.price,
|
|
1033
|
+
product.price
|
|
1034
|
+
);
|
|
1035
|
+
amount = new import_decimal.default(product.price).minus(new import_decimal.default(mainProductSellingPrice)).toNumber();
|
|
978
1036
|
}
|
|
1037
|
+
if (isDeductOptionPrice && ((_z = product.options) == null ? void 0 : _z.length)) {
|
|
1038
|
+
const optionResult = applyDiscountToOptions(
|
|
1039
|
+
product.options,
|
|
1040
|
+
currentSelectedDiscount
|
|
1041
|
+
);
|
|
1042
|
+
discountedOptions = optionResult.discountedOptions;
|
|
1043
|
+
optionDiscountAmount = optionResult.optionDiscountAmount;
|
|
1044
|
+
}
|
|
1045
|
+
const optionsForLineTotal = isDeductOptionPrice && ((_A = product.options) == null ? void 0 : _A.length) ? discountedOptions : product.options;
|
|
1046
|
+
const optionsLineTotal = getOptionTotal(optionsForLineTotal || []);
|
|
1047
|
+
const total = new import_decimal.default(mainProductSellingPrice).plus(optionsLineTotal).toNumber();
|
|
1048
|
+
const mainProductDiscountAmount = amount;
|
|
1049
|
+
const lineDiscountAmount = new import_decimal.default(mainProductDiscountAmount).plus(optionDiscountAmount).toNumber();
|
|
979
1050
|
const currentDiscountType = currentSelectedDiscount.tag === "product_discount_card" ? "discount_card" : currentSelectedDiscount.tag;
|
|
980
1051
|
const discountType2 = selectedDiscount.tag || selectedDiscount.type;
|
|
981
1052
|
const currentIsGoodPass = currentDiscountType === "good_pass";
|
|
982
1053
|
const discountDetail = {
|
|
983
|
-
amount,
|
|
1054
|
+
amount: lineDiscountAmount,
|
|
984
1055
|
type: selectedDiscount.tag === "product_discount_card" ? "discount_card" : discountType2,
|
|
985
1056
|
discount: {
|
|
986
|
-
discount_card_type: (
|
|
987
|
-
fixed_amount:
|
|
988
|
-
discount_calculation_mode: (
|
|
1057
|
+
discount_card_type: (_B = selectedDiscount == null ? void 0 : selectedDiscount.metadata) == null ? void 0 : _B.discount_card_type,
|
|
1058
|
+
fixed_amount: lineDiscountAmount,
|
|
1059
|
+
discount_calculation_mode: (_C = selectedDiscount == null ? void 0 : selectedDiscount.metadata) == null ? void 0 : _C.discount_calculation_mode,
|
|
989
1060
|
resource_id: selectedDiscount.id,
|
|
990
1061
|
title: selectedDiscount.format_title,
|
|
991
1062
|
original_amount: product.price,
|
|
@@ -1000,35 +1071,32 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1000
1071
|
num: 1,
|
|
1001
1072
|
discount_rule_uncheck_flag: selectedDiscount == null ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
|
|
1002
1073
|
// 🔥 order_level 分摊差值
|
|
1003
|
-
...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
|
|
1074
|
+
...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference },
|
|
1075
|
+
/** 仅主商品上的优惠金额(不含 option) */
|
|
1076
|
+
mainProductDiscountAmount,
|
|
1077
|
+
optionDiscountAmount
|
|
1004
1078
|
}
|
|
1005
1079
|
};
|
|
1006
1080
|
appliedProducts.push(discountDetail);
|
|
1007
1081
|
appliedDiscountProducts.set(currentSelectedDiscount.id, appliedProducts);
|
|
1008
|
-
let total = targetProductTotal;
|
|
1009
|
-
if (product.options) {
|
|
1010
|
-
total = product.options.reduce((accumulator, currentValue) => {
|
|
1011
|
-
const currentPrice = new import_decimal.default(currentValue.price || 0);
|
|
1012
|
-
const currentNum = new import_decimal.default(currentValue.num || 0);
|
|
1013
|
-
return accumulator.add(currentPrice.mul(currentNum));
|
|
1014
|
-
}, new import_decimal.default(total)).toNumber();
|
|
1015
|
-
}
|
|
1016
1082
|
if (product.isClient) {
|
|
1017
1083
|
arr.push(
|
|
1018
1084
|
this.hooks.setProduct(originProduct, {
|
|
1019
1085
|
discount_list: [discountDetail],
|
|
1020
|
-
|
|
1086
|
+
// good_pass:主商品价以折后价为准;勿用 product.price - amount(amount 含 option 优惠时会算错)
|
|
1087
|
+
price: currentIsGoodPass ? mainProductSellingPrice : product.price,
|
|
1021
1088
|
quantity: isNeedSplit ? 1 : product.quantity,
|
|
1022
1089
|
origin_total: (0, import_utils2.getProductOriginTotalPrice)({
|
|
1023
1090
|
product: {
|
|
1024
1091
|
original_price: product.original_price
|
|
1025
1092
|
},
|
|
1026
1093
|
bundle: product.bundle,
|
|
1027
|
-
options: product.options
|
|
1094
|
+
options: restoreOptionPrices(product.options)
|
|
1028
1095
|
}),
|
|
1029
1096
|
variant: originProduct._productInit.variant,
|
|
1030
1097
|
original_price: new import_decimal.default(product.price || 0).toNumber(),
|
|
1031
|
-
total
|
|
1098
|
+
total,
|
|
1099
|
+
options: discountedOptions
|
|
1032
1100
|
})
|
|
1033
1101
|
);
|
|
1034
1102
|
} else {
|
|
@@ -1040,7 +1108,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1040
1108
|
quantity: isNeedSplit ? 1 : product.quantity,
|
|
1041
1109
|
total,
|
|
1042
1110
|
origin_total: productOriginTotal,
|
|
1043
|
-
main_product_selling_price:
|
|
1111
|
+
main_product_selling_price: mainProductSellingPrice,
|
|
1112
|
+
options: discountedOptions
|
|
1044
1113
|
})
|
|
1045
1114
|
);
|
|
1046
1115
|
}
|
|
@@ -1075,8 +1144,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1075
1144
|
amount: bundleDiscountAmount,
|
|
1076
1145
|
type: bundleDiscountType,
|
|
1077
1146
|
discount: {
|
|
1078
|
-
discount_card_type: (
|
|
1079
|
-
discount_calculation_mode: (
|
|
1147
|
+
discount_card_type: (_D = currentBundleDiscount == null ? void 0 : currentBundleDiscount.metadata) == null ? void 0 : _D.discount_card_type,
|
|
1148
|
+
discount_calculation_mode: (_E = currentBundleDiscount == null ? void 0 : currentBundleDiscount.metadata) == null ? void 0 : _E.discount_calculation_mode,
|
|
1080
1149
|
fixed_amount: bundleDiscountAmount,
|
|
1081
1150
|
resource_id: currentBundleDiscount.id,
|
|
1082
1151
|
title: currentBundleDiscount.format_title,
|
|
@@ -1184,7 +1253,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1184
1253
|
const nextDiscType = nextSelectedDiscount.tag || nextSelectedDiscount.type;
|
|
1185
1254
|
const nextIsGoodPass = nextDiscType === "good_pass";
|
|
1186
1255
|
const nextIsDiscountCard = ["discount_card", "product_discount_card"].includes(nextDiscType);
|
|
1187
|
-
const nextApplicableProductLimit = ((
|
|
1256
|
+
const nextApplicableProductLimit = ((_F = nextSelectedDiscount.config) == null ? void 0 : _F.applicableProductLimit) || 0;
|
|
1188
1257
|
const nextIsNeedSplit = nextIsGoodPass || nextIsDiscountCard && nextApplicableProductLimit > 0;
|
|
1189
1258
|
if (!nextIsNeedSplit) {
|
|
1190
1259
|
const nextBundleDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
|
|
@@ -1207,7 +1276,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1207
1276
|
amount: nextDiscountAmount * remainingNum,
|
|
1208
1277
|
type: nextBundleDiscType,
|
|
1209
1278
|
discount: {
|
|
1210
|
-
discount_card_type: (
|
|
1279
|
+
discount_card_type: (_G = nextBundleDiscount == null ? void 0 : nextBundleDiscount.metadata) == null ? void 0 : _G.discount_card_type,
|
|
1211
1280
|
fixed_amount: nextDiscountAmount,
|
|
1212
1281
|
resource_id: nextBundleDiscount.id,
|
|
1213
1282
|
title: nextBundleDiscount.format_title,
|
|
@@ -1221,7 +1290,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1221
1290
|
num: remainingNum
|
|
1222
1291
|
},
|
|
1223
1292
|
config: nextBundleDiscount == null ? void 0 : nextBundleDiscount.config,
|
|
1224
|
-
_num: remainingNum * (((
|
|
1293
|
+
_num: remainingNum * (((_H = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _H.num) || 1)
|
|
1225
1294
|
};
|
|
1226
1295
|
const nextAppliedProducts = appliedDiscountProducts.get(nextBundleDiscount.id) || [];
|
|
1227
1296
|
nextAppliedProducts.push(nextDiscountDetail);
|
|
@@ -1245,7 +1314,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1245
1314
|
(item) => (item.tag || item.type) === "good_pass"
|
|
1246
1315
|
).length;
|
|
1247
1316
|
nextMaxUsageLimit = nextGoodPassCount;
|
|
1248
|
-
if ((
|
|
1317
|
+
if ((_I = nextSelectedDiscount.config) == null ? void 0 : _I.maxUsagePerOrder) {
|
|
1249
1318
|
const usedCount = usedProductIdCounts.get(nextSelectedDiscount.product_id) || 0;
|
|
1250
1319
|
nextMaxUsageLimit = Math.min(
|
|
1251
1320
|
nextGoodPassCount,
|
|
@@ -1294,7 +1363,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1294
1363
|
amount: nextBundleDiscAmount,
|
|
1295
1364
|
type: nextBundleDiscTypeStr,
|
|
1296
1365
|
discount: {
|
|
1297
|
-
discount_card_type: (
|
|
1366
|
+
discount_card_type: (_J = nextBundleDiscount == null ? void 0 : nextBundleDiscount.metadata) == null ? void 0 : _J.discount_card_type,
|
|
1298
1367
|
fixed_amount: nextBundleDiscAmount,
|
|
1299
1368
|
resource_id: nextBundleDiscount.id,
|
|
1300
1369
|
title: nextBundleDiscount.format_title,
|
|
@@ -1366,9 +1435,9 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1366
1435
|
amount: bundleActualDiscountAmount * (product.num || 1),
|
|
1367
1436
|
type: currentBundleDiscount.tag === "product_discount_card" ? "discount_card" : currentBundleDiscount.tag,
|
|
1368
1437
|
discount: {
|
|
1369
|
-
discount_card_type: (
|
|
1438
|
+
discount_card_type: (_K = currentBundleDiscount == null ? void 0 : currentBundleDiscount.metadata) == null ? void 0 : _K.discount_card_type,
|
|
1370
1439
|
fixed_amount: bundleActualDiscountAmount,
|
|
1371
|
-
discount_calculation_mode: (
|
|
1440
|
+
discount_calculation_mode: (_L = currentBundleDiscount == null ? void 0 : currentBundleDiscount.metadata) == null ? void 0 : _L.discount_calculation_mode,
|
|
1372
1441
|
resource_id: currentBundleDiscount.id,
|
|
1373
1442
|
title: currentBundleDiscount.format_title,
|
|
1374
1443
|
original_amount: product.original_price,
|
|
@@ -1385,7 +1454,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1385
1454
|
...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
|
|
1386
1455
|
},
|
|
1387
1456
|
config: currentBundleDiscount == null ? void 0 : currentBundleDiscount.config,
|
|
1388
|
-
_num: (product.num || 1) * (((
|
|
1457
|
+
_num: (product.num || 1) * (((_M = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _M.num) || 1)
|
|
1389
1458
|
};
|
|
1390
1459
|
const appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
|
|
1391
1460
|
appliedProducts.push(discountDetail);
|
|
@@ -1408,6 +1477,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1408
1477
|
const mainProductArr = processedProductsMap2.get(product._id);
|
|
1409
1478
|
if (!mainProductArr || mainProductArr.length === 0) {
|
|
1410
1479
|
const getDefaultProduct = () => {
|
|
1480
|
+
const restoredOptions = restoreOptionPrices(product.options);
|
|
1411
1481
|
if (product.isClient) {
|
|
1412
1482
|
return this.hooks.setProduct(originProduct, {
|
|
1413
1483
|
discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
|
|
@@ -1417,7 +1487,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1417
1487
|
original_price: product.original_price
|
|
1418
1488
|
},
|
|
1419
1489
|
bundle: product.bundle,
|
|
1420
|
-
options:
|
|
1490
|
+
options: restoredOptions
|
|
1421
1491
|
}),
|
|
1422
1492
|
variant: originProduct._productInit.variant,
|
|
1423
1493
|
original_price: originProduct._productInit.original_price,
|
|
@@ -1426,15 +1496,17 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1426
1496
|
price: product.price
|
|
1427
1497
|
},
|
|
1428
1498
|
bundle: product.bundle,
|
|
1429
|
-
options:
|
|
1430
|
-
})
|
|
1499
|
+
options: restoredOptions
|
|
1500
|
+
}),
|
|
1501
|
+
options: restoredOptions
|
|
1431
1502
|
});
|
|
1432
1503
|
} else {
|
|
1433
1504
|
return this.hooks.setProduct(originProduct, {
|
|
1434
1505
|
discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
|
|
1435
1506
|
total: product.total,
|
|
1436
1507
|
origin_total: product.origin_total,
|
|
1437
|
-
price: product.price
|
|
1508
|
+
price: product.price,
|
|
1509
|
+
options: restoreOptionPrices(product.options)
|
|
1438
1510
|
});
|
|
1439
1511
|
}
|
|
1440
1512
|
};
|
|
@@ -131,7 +131,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
|
|
|
131
131
|
* 获取当前的客户搜索条件
|
|
132
132
|
* @returns 当前搜索条件
|
|
133
133
|
*/
|
|
134
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
134
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
|
|
135
135
|
/**
|
|
136
136
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
137
137
|
* @returns 客户状态
|