@pisell/pisellos 2.3.142 → 2.3.144
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 +0 -9
- package/dist/modules/BookingContext/utils/resources.js +1 -1
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Order/utils.d.ts +5 -3
- package/dist/modules/Order/utils.js +32 -11
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/lib/model/strategy/adapter/promotion/index.js +1 -46
- package/lib/modules/BookingContext/utils/resources.js +1 -1
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Order/utils.d.ts +5 -3
- package/lib/modules/Order/utils.js +29 -10
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,9 +0,0 @@
|
|
|
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";
|
|
@@ -260,7 +260,7 @@ function getResourceMaxFreeTime(resource, isAutoAllocationOn) {
|
|
|
260
260
|
return d.usable && d.id !== 0;
|
|
261
261
|
});
|
|
262
262
|
var defaultResource = [];
|
|
263
|
-
var maxFreeTime =
|
|
263
|
+
var maxFreeTime = -1;
|
|
264
264
|
usableList.forEach(function (d) {
|
|
265
265
|
var _d$times = d.times,
|
|
266
266
|
times = _d$times === void 0 ? [] : _d$times;
|
|
@@ -592,7 +592,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
592
592
|
generateIdempotencyToken(): string;
|
|
593
593
|
syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
|
|
594
594
|
createOrder(params: CommitOrderParams['query']): {
|
|
595
|
-
type: "
|
|
595
|
+
type: "appointment_booking" | "virtual";
|
|
596
596
|
platform: string;
|
|
597
597
|
sales_channel: string;
|
|
598
598
|
order_sales_channel: string;
|
|
@@ -121,8 +121,9 @@ export declare function getBundleSellingMagnitude(bundle: Record<string, any> |
|
|
|
121
121
|
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
122
122
|
* - `metadata.source_product_price`:主商品/variant 基础价(已应用报价单),不含 option、
|
|
123
123
|
* 不含折扣。**权威源**。
|
|
124
|
-
* - `
|
|
125
|
-
* - `metadata.
|
|
124
|
+
* - `product_sku.option[].add_price` 保留单规格折前单价;Rules 的 option.price 只用于本次计算。
|
|
125
|
+
* - `metadata.main_product_original_price` = source + Σ(option.add_price × option.num)(含 option、不含折扣)。
|
|
126
|
+
* - `metadata.main_product_selling_price` = main_original − 行内 per-unit amount(含主商品及 option 优惠)。
|
|
126
127
|
* - `payment_price`:出站 payload 中为行 composite 已减整单折扣均摊价(无折扣时与 `selling_price` 同义)。
|
|
127
128
|
*
|
|
128
129
|
* Rules 钩子契约(hook_adapt 方案,Rules 内部保持不变):
|
|
@@ -131,8 +132,9 @@ export declare function getBundleSellingMagnitude(bundle: Record<string, any> |
|
|
|
131
132
|
* `getProductOriginTotalPrice` 会自行叠加 option + bundle,喂 source 可避免 option 双加。
|
|
132
133
|
* - `getProduct.total` = `selling_price × num`(行 composite × num),与 Rules 内部产出的
|
|
133
134
|
* total(source + option + bundle)对齐。
|
|
135
|
+
* - `getProduct.options` 用单规格原价参与重算;主商品折后价从 main_selling 减去 option 折后合计反推。
|
|
134
136
|
* - `setProduct` 反向流程:把 Rules 返回的 source-level `main_product_selling_price` / `price`
|
|
135
|
-
*
|
|
137
|
+
* 加回单规格原价合计,再减去 optionDiscountAmount;保留订单单规格原价供取消折扣及后续重算。
|
|
136
138
|
* 优先级:
|
|
137
139
|
* 1. `values.main_product_selling_price`(券应用分支,per-unit 券后 source-level 主价)
|
|
138
140
|
* 2. `values.price`(还原分支 `restoredPrice`、good_pass 归零)
|
|
@@ -588,8 +588,9 @@ export function getBundleSellingMagnitude(bundle) {
|
|
|
588
588
|
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
589
589
|
* - `metadata.source_product_price`:主商品/variant 基础价(已应用报价单),不含 option、
|
|
590
590
|
* 不含折扣。**权威源**。
|
|
591
|
-
* - `
|
|
592
|
-
* - `metadata.
|
|
591
|
+
* - `product_sku.option[].add_price` 保留单规格折前单价;Rules 的 option.price 只用于本次计算。
|
|
592
|
+
* - `metadata.main_product_original_price` = source + Σ(option.add_price × option.num)(含 option、不含折扣)。
|
|
593
|
+
* - `metadata.main_product_selling_price` = main_original − 行内 per-unit amount(含主商品及 option 优惠)。
|
|
593
594
|
* - `payment_price`:出站 payload 中为行 composite 已减整单折扣均摊价(无折扣时与 `selling_price` 同义)。
|
|
594
595
|
*
|
|
595
596
|
* Rules 钩子契约(hook_adapt 方案,Rules 内部保持不变):
|
|
@@ -598,8 +599,9 @@ export function getBundleSellingMagnitude(bundle) {
|
|
|
598
599
|
* `getProductOriginTotalPrice` 会自行叠加 option + bundle,喂 source 可避免 option 双加。
|
|
599
600
|
* - `getProduct.total` = `selling_price × num`(行 composite × num),与 Rules 内部产出的
|
|
600
601
|
* total(source + option + bundle)对齐。
|
|
602
|
+
* - `getProduct.options` 用单规格原价参与重算;主商品折后价从 main_selling 减去 option 折后合计反推。
|
|
601
603
|
* - `setProduct` 反向流程:把 Rules 返回的 source-level `main_product_selling_price` / `price`
|
|
602
|
-
*
|
|
604
|
+
* 加回单规格原价合计,再减去 optionDiscountAmount;保留订单单规格原价供取消折扣及后续重算。
|
|
603
605
|
* 优先级:
|
|
604
606
|
* 1. `values.main_product_selling_price`(券应用分支,per-unit 券后 source-level 主价)
|
|
605
607
|
* 2. `values.price`(还原分支 `restoredPrice`、good_pass 归零)
|
|
@@ -822,6 +824,15 @@ export function createDefaultOrderRulesHooks(getBookings) {
|
|
|
822
824
|
var effectiveNum = Number(num) > 0 ? Number(num) : 1;
|
|
823
825
|
return new Decimal(Number(totalLike) || 0).dividedBy(effectiveNum).toDecimalPlaces(2).toString();
|
|
824
826
|
};
|
|
827
|
+
|
|
828
|
+
// optionDiscountAmount 已是每件主商品内的单规格优惠合计,不再乘商品数量。
|
|
829
|
+
var getOptionDiscountAmount = function getOptionDiscountAmount(discountList) {
|
|
830
|
+
return (discountList || []).reduce(function (total, discount) {
|
|
831
|
+
var _discount$metadata, _discount$metadata2;
|
|
832
|
+
if (discount !== null && discount !== void 0 && (_discount$metadata = discount.metadata) !== null && _discount$metadata !== void 0 && _discount$metadata.custom_product_bundle_map_id) return total;
|
|
833
|
+
return total.plus(Number(discount === null || discount === void 0 || (_discount$metadata2 = discount.metadata) === null || _discount$metadata2 === void 0 ? void 0 : _discount$metadata2.optionDiscountAmount) || 0);
|
|
834
|
+
}, new Decimal(0));
|
|
835
|
+
};
|
|
825
836
|
var getBundleIdentity = function getBundleIdentity(bundle) {
|
|
826
837
|
var _ref21, _bundle$bundle_id, _ref22, _ref23, _bundle$bundle_produc, _ref24, _ref25, _bundle$bundle_varian, _ref26, _bundle$bundle_group_;
|
|
827
838
|
return [(_ref21 = (_bundle$bundle_id = bundle.bundle_id) !== null && _bundle$bundle_id !== void 0 ? _bundle$bundle_id : bundle.id) !== null && _ref21 !== void 0 ? _ref21 : '', (_ref22 = (_ref23 = (_bundle$bundle_produc = bundle.bundle_product_id) !== null && _bundle$bundle_produc !== void 0 ? _bundle$bundle_produc : bundle._bundle_product_id) !== null && _ref23 !== void 0 ? _ref23 : bundle.product_id) !== null && _ref22 !== void 0 ? _ref22 : '', (_ref24 = (_ref25 = (_bundle$bundle_varian = bundle.bundle_variant_id) !== null && _bundle$bundle_varian !== void 0 ? _bundle$bundle_varian : bundle.variant_id) !== null && _ref25 !== void 0 ? _ref25 : bundle.product_variant_id) !== null && _ref24 !== void 0 ? _ref24 : 0, (_ref26 = (_bundle$bundle_group_ = bundle.bundle_group_id) !== null && _bundle$bundle_group_ !== void 0 ? _bundle$bundle_group_ : bundle.group_id) !== null && _ref26 !== void 0 ? _ref26 : ''].join('|');
|
|
@@ -859,12 +870,14 @@ export function createDefaultOrderRulesHooks(getBookings) {
|
|
|
859
870
|
var _product$metadata7, _product$metadata8, _product$metadata9, _metadataAny$_promoti;
|
|
860
871
|
// source_product_price 是权威源;兜底链:source → mainSelling − options(反推)→ 行 selling_price
|
|
861
872
|
var metadataAny = product.metadata || {};
|
|
862
|
-
var
|
|
873
|
+
var productOptions = getProductSkuOptions(product);
|
|
874
|
+
var optionSum = sumOptionUnitPrice(productOptions);
|
|
875
|
+
var optionSellingSum = optionSum.minus(getOptionDiscountAmount(product.discount_list));
|
|
863
876
|
var sourcePrice;
|
|
864
877
|
if (metadataAny.source_product_price !== undefined) {
|
|
865
878
|
sourcePrice = String(metadataAny.source_product_price);
|
|
866
879
|
} else if (metadataAny.main_product_selling_price !== undefined) {
|
|
867
|
-
sourcePrice = new Decimal(Number(metadataAny.main_product_selling_price) || 0).minus(
|
|
880
|
+
sourcePrice = new Decimal(Number(metadataAny.main_product_selling_price) || 0).minus(optionSellingSum).toDecimalPlaces(2).toString();
|
|
868
881
|
} else {
|
|
869
882
|
var _product$selling_pric;
|
|
870
883
|
sourcePrice = String((_product$selling_pric = product.selling_price) !== null && _product$selling_pric !== void 0 ? _product$selling_pric : 0);
|
|
@@ -895,6 +908,12 @@ export function createDefaultOrderRulesHooks(getBookings) {
|
|
|
895
908
|
num: product.num || 1,
|
|
896
909
|
discount_list: product.discount_list || [],
|
|
897
910
|
bundle: product.product_bundle || [],
|
|
911
|
+
// 仅在 Rules 入参中映射 price,避免折后价污染订单的 add_price。
|
|
912
|
+
options: productOptions.map(function (option) {
|
|
913
|
+
return _objectSpread(_objectSpread({}, option), {}, {
|
|
914
|
+
price: option.add_price
|
|
915
|
+
});
|
|
916
|
+
}),
|
|
898
917
|
booking_id: ((_product$metadata8 = product.metadata) === null || _product$metadata8 === void 0 ? void 0 : _product$metadata8.booking_id) || null,
|
|
899
918
|
isClient: false,
|
|
900
919
|
// 勿写死 false:否则 Rules 不会走 total≠origin_total 的手动价推断,
|
|
@@ -902,20 +921,22 @@ export function createDefaultOrderRulesHooks(getBookings) {
|
|
|
902
921
|
isManualDiscount: resolveRulesManualDiscountFlag(metadataAny),
|
|
903
922
|
holder_id: (_product$metadata9 = product.metadata) === null || _product$metadata9 === void 0 ? void 0 : _product$metadata9.holder_id,
|
|
904
923
|
startDate: getProductStartDate(product),
|
|
905
|
-
main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new Decimal(Number(metadataAny.main_product_selling_price) || 0).minus(
|
|
924
|
+
main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new Decimal(Number(metadataAny.main_product_selling_price) || 0).minus(optionSellingSum).toDecimalPlaces(2).toString() : undefined,
|
|
906
925
|
inPromotion: ((_metadataAny$_promoti = metadataAny._promotion) === null || _metadataAny$_promoti === void 0 ? void 0 : _metadataAny$_promoti.inPromotion) === true,
|
|
907
926
|
_promotion: metadataAny._promotion
|
|
908
927
|
};
|
|
909
928
|
},
|
|
910
929
|
setProduct: function setProduct(product, values) {
|
|
911
|
-
var _ref32, _values$quantity, _ref33, _metadataAny$source_p,
|
|
930
|
+
var _ref32, _values$quantity, _ref33, _metadataAny$source_p, _values$discount_list, _product$product_sku, _values$quantity2;
|
|
912
931
|
var nextNum = Number((_ref32 = (_values$quantity = values.quantity) !== null && _values$quantity !== void 0 ? _values$quantity : product.num) !== null && _ref32 !== void 0 ? _ref32 : 1) || 1;
|
|
913
932
|
var metadataAny = product.metadata || {};
|
|
914
933
|
var existedSource = (_ref33 = (_metadataAny$source_p = metadataAny.source_product_price) !== null && _metadataAny$source_p !== void 0 ? _metadataAny$source_p : product.selling_price) !== null && _ref33 !== void 0 ? _ref33 : '0';
|
|
915
934
|
var nextOptions = getProductSkuOptions(product);
|
|
916
935
|
var optionSum = sumOptionUnitPrice(nextOptions);
|
|
936
|
+
var nextDiscountList = (_values$discount_list = values.discount_list) !== null && _values$discount_list !== void 0 ? _values$discount_list : product.discount_list;
|
|
937
|
+
var optionSellingSum = optionSum.minus(getOptionDiscountAmount(nextDiscountList));
|
|
917
938
|
|
|
918
|
-
// Rules 返回的 main_product_selling_price / price
|
|
939
|
+
// Rules 返回的 main_product_selling_price / price 为不含 option 的主商品价。
|
|
919
940
|
// 优先级:main_product_selling_price(per-unit 券后 source)> price(还原/good_pass 分支)>
|
|
920
941
|
// total/num(仅当 Rules 只给 total 时的兜底)> 保留当前 source。
|
|
921
942
|
var nextSourceSellingPrice = values.main_product_selling_price !== undefined ? String(values.main_product_selling_price) : values.price !== undefined ? String(values.price) : values.total !== undefined ? toUnitPriceString(values.total, nextNum) : String(existedSource);
|
|
@@ -924,8 +945,8 @@ export function createDefaultOrderRulesHooks(getBookings) {
|
|
|
924
945
|
// 缺省时保留现有 source(券前 = 当前 source)。
|
|
925
946
|
var nextSourceOriginalPrice = values.original_price !== undefined ? String(values.original_price) : String(existedSource);
|
|
926
947
|
|
|
927
|
-
//
|
|
928
|
-
var nextMainSellingPrice = new Decimal(Number(nextSourceSellingPrice) || 0).plus(
|
|
948
|
+
// 成交价只加回 option 折后合计;原价仍使用订单中保存的 option 原价。
|
|
949
|
+
var nextMainSellingPrice = new Decimal(Number(nextSourceSellingPrice) || 0).plus(optionSellingSum).toDecimalPlaces(2).toFixed(2);
|
|
929
950
|
var nextMainOriginalPrice = new Decimal(Number(nextSourceOriginalPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
930
951
|
var nextBundle = values.bundle !== undefined ? mergeRulesBundlePrices(product.product_bundle, values.bundle) : product.product_bundle;
|
|
931
952
|
var composedSellingPrice = composeLinePrice({
|
|
@@ -945,7 +966,7 @@ export function createDefaultOrderRulesHooks(getBookings) {
|
|
|
945
966
|
return _objectSpread(_objectSpread({}, product), {}, {
|
|
946
967
|
selling_price: composedSellingPrice,
|
|
947
968
|
original_price: finalOriginalPrice,
|
|
948
|
-
discount_list:
|
|
969
|
+
discount_list: nextDiscountList,
|
|
949
970
|
num: (_values$quantity2 = values.quantity) !== null && _values$quantity2 !== void 0 ? _values$quantity2 : product.num,
|
|
950
971
|
product_bundle: nextBundle,
|
|
951
972
|
metadata: _objectSpread(_objectSpread({}, metadataAny), {}, {
|
|
@@ -328,7 +328,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
328
328
|
date: string;
|
|
329
329
|
status: string;
|
|
330
330
|
week: string;
|
|
331
|
-
weekNum: 0 |
|
|
331
|
+
weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
|
|
332
332
|
}[]>;
|
|
333
333
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
334
334
|
private getScheduleDataByIds;
|
|
@@ -1,46 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "BUY_X_GET_Y_FREE_STRATEGY", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _examples.BUY_X_GET_Y_FREE_STRATEGY;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, "ITEM_REWARD_STRATEGY", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () {
|
|
15
|
-
return _examples.ITEM_REWARD_STRATEGY;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
Object.defineProperty(exports, "PromotionAdapter", {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get: function () {
|
|
21
|
-
return _adapter.PromotionAdapter;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(exports, "PromotionEvaluator", {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () {
|
|
27
|
-
return _evaluator.PromotionEvaluator;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
Object.defineProperty(exports, "X_ITEMS_FOR_Y_PRICE_STRATEGY", {
|
|
31
|
-
enumerable: true,
|
|
32
|
-
get: function () {
|
|
33
|
-
return _examples.X_ITEMS_FOR_Y_PRICE_STRATEGY;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
Object.defineProperty(exports, "default", {
|
|
37
|
-
enumerable: true,
|
|
38
|
-
get: function () {
|
|
39
|
-
return _adapter.default;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
var _evaluator = require("./evaluator");
|
|
43
|
-
var _adapter = _interopRequireWildcard(require("./adapter"));
|
|
44
|
-
var _examples = require("./examples");
|
|
45
|
-
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
46
|
-
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
1
|
+
"use strict";
|
|
@@ -241,7 +241,7 @@ function getResourceMaxFreeTime(resource, isAutoAllocationOn) {
|
|
|
241
241
|
if (!isAutoAllocationOn(form_id)) return [];
|
|
242
242
|
const usableList = (renderList || []).filter(d => d.usable && d.id !== 0);
|
|
243
243
|
let defaultResource = [];
|
|
244
|
-
let maxFreeTime =
|
|
244
|
+
let maxFreeTime = -1;
|
|
245
245
|
usableList.forEach(d => {
|
|
246
246
|
const {
|
|
247
247
|
times = []
|
|
@@ -592,7 +592,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
592
592
|
generateIdempotencyToken(): string;
|
|
593
593
|
syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
|
|
594
594
|
createOrder(params: CommitOrderParams['query']): {
|
|
595
|
-
type: "
|
|
595
|
+
type: "appointment_booking" | "virtual";
|
|
596
596
|
platform: string;
|
|
597
597
|
sales_channel: string;
|
|
598
598
|
order_sales_channel: string;
|
|
@@ -121,8 +121,9 @@ export declare function getBundleSellingMagnitude(bundle: Record<string, any> |
|
|
|
121
121
|
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
122
122
|
* - `metadata.source_product_price`:主商品/variant 基础价(已应用报价单),不含 option、
|
|
123
123
|
* 不含折扣。**权威源**。
|
|
124
|
-
* - `
|
|
125
|
-
* - `metadata.
|
|
124
|
+
* - `product_sku.option[].add_price` 保留单规格折前单价;Rules 的 option.price 只用于本次计算。
|
|
125
|
+
* - `metadata.main_product_original_price` = source + Σ(option.add_price × option.num)(含 option、不含折扣)。
|
|
126
|
+
* - `metadata.main_product_selling_price` = main_original − 行内 per-unit amount(含主商品及 option 优惠)。
|
|
126
127
|
* - `payment_price`:出站 payload 中为行 composite 已减整单折扣均摊价(无折扣时与 `selling_price` 同义)。
|
|
127
128
|
*
|
|
128
129
|
* Rules 钩子契约(hook_adapt 方案,Rules 内部保持不变):
|
|
@@ -131,8 +132,9 @@ export declare function getBundleSellingMagnitude(bundle: Record<string, any> |
|
|
|
131
132
|
* `getProductOriginTotalPrice` 会自行叠加 option + bundle,喂 source 可避免 option 双加。
|
|
132
133
|
* - `getProduct.total` = `selling_price × num`(行 composite × num),与 Rules 内部产出的
|
|
133
134
|
* total(source + option + bundle)对齐。
|
|
135
|
+
* - `getProduct.options` 用单规格原价参与重算;主商品折后价从 main_selling 减去 option 折后合计反推。
|
|
134
136
|
* - `setProduct` 反向流程:把 Rules 返回的 source-level `main_product_selling_price` / `price`
|
|
135
|
-
*
|
|
137
|
+
* 加回单规格原价合计,再减去 optionDiscountAmount;保留订单单规格原价供取消折扣及后续重算。
|
|
136
138
|
* 优先级:
|
|
137
139
|
* 1. `values.main_product_selling_price`(券应用分支,per-unit 券后 source-level 主价)
|
|
138
140
|
* 2. `values.price`(还原分支 `restoredPrice`、good_pass 归零)
|
|
@@ -641,8 +641,9 @@ function getBundleSellingMagnitude(bundle) {
|
|
|
641
641
|
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
642
642
|
* - `metadata.source_product_price`:主商品/variant 基础价(已应用报价单),不含 option、
|
|
643
643
|
* 不含折扣。**权威源**。
|
|
644
|
-
* - `
|
|
645
|
-
* - `metadata.
|
|
644
|
+
* - `product_sku.option[].add_price` 保留单规格折前单价;Rules 的 option.price 只用于本次计算。
|
|
645
|
+
* - `metadata.main_product_original_price` = source + Σ(option.add_price × option.num)(含 option、不含折扣)。
|
|
646
|
+
* - `metadata.main_product_selling_price` = main_original − 行内 per-unit amount(含主商品及 option 优惠)。
|
|
646
647
|
* - `payment_price`:出站 payload 中为行 composite 已减整单折扣均摊价(无折扣时与 `selling_price` 同义)。
|
|
647
648
|
*
|
|
648
649
|
* Rules 钩子契约(hook_adapt 方案,Rules 内部保持不变):
|
|
@@ -651,8 +652,9 @@ function getBundleSellingMagnitude(bundle) {
|
|
|
651
652
|
* `getProductOriginTotalPrice` 会自行叠加 option + bundle,喂 source 可避免 option 双加。
|
|
652
653
|
* - `getProduct.total` = `selling_price × num`(行 composite × num),与 Rules 内部产出的
|
|
653
654
|
* total(source + option + bundle)对齐。
|
|
655
|
+
* - `getProduct.options` 用单规格原价参与重算;主商品折后价从 main_selling 减去 option 折后合计反推。
|
|
654
656
|
* - `setProduct` 反向流程:把 Rules 返回的 source-level `main_product_selling_price` / `price`
|
|
655
|
-
*
|
|
657
|
+
* 加回单规格原价合计,再减去 optionDiscountAmount;保留订单单规格原价供取消折扣及后续重算。
|
|
656
658
|
* 优先级:
|
|
657
659
|
* 1. `values.main_product_selling_price`(券应用分支,per-unit 券后 source-level 主价)
|
|
658
660
|
* 2. `values.price`(还原分支 `restoredPrice`、good_pass 归零)
|
|
@@ -851,6 +853,14 @@ function createDefaultOrderRulesHooks(getBookings) {
|
|
|
851
853
|
const effectiveNum = Number(num) > 0 ? Number(num) : 1;
|
|
852
854
|
return new _decimal.default(Number(totalLike) || 0).dividedBy(effectiveNum).toDecimalPlaces(2).toString();
|
|
853
855
|
};
|
|
856
|
+
|
|
857
|
+
// optionDiscountAmount 已是每件主商品内的单规格优惠合计,不再乘商品数量。
|
|
858
|
+
const getOptionDiscountAmount = discountList => {
|
|
859
|
+
return (discountList || []).reduce((total, discount) => {
|
|
860
|
+
if (discount?.metadata?.custom_product_bundle_map_id) return total;
|
|
861
|
+
return total.plus(Number(discount?.metadata?.optionDiscountAmount) || 0);
|
|
862
|
+
}, new _decimal.default(0));
|
|
863
|
+
};
|
|
854
864
|
const getBundleIdentity = bundle => {
|
|
855
865
|
return [bundle.bundle_id ?? bundle.id ?? '', bundle.bundle_product_id ?? bundle._bundle_product_id ?? bundle.product_id ?? '', bundle.bundle_variant_id ?? bundle.variant_id ?? bundle.product_variant_id ?? 0, bundle.bundle_group_id ?? bundle.group_id ?? ''].join('|');
|
|
856
866
|
};
|
|
@@ -893,12 +903,14 @@ function createDefaultOrderRulesHooks(getBookings) {
|
|
|
893
903
|
getProduct: product => {
|
|
894
904
|
// source_product_price 是权威源;兜底链:source → mainSelling − options(反推)→ 行 selling_price
|
|
895
905
|
const metadataAny = product.metadata || {};
|
|
896
|
-
const
|
|
906
|
+
const productOptions = getProductSkuOptions(product);
|
|
907
|
+
const optionSum = sumOptionUnitPrice(productOptions);
|
|
908
|
+
const optionSellingSum = optionSum.minus(getOptionDiscountAmount(product.discount_list));
|
|
897
909
|
let sourcePrice;
|
|
898
910
|
if (metadataAny.source_product_price !== undefined) {
|
|
899
911
|
sourcePrice = String(metadataAny.source_product_price);
|
|
900
912
|
} else if (metadataAny.main_product_selling_price !== undefined) {
|
|
901
|
-
sourcePrice = new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(
|
|
913
|
+
sourcePrice = new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(optionSellingSum).toDecimalPlaces(2).toString();
|
|
902
914
|
} else {
|
|
903
915
|
sourcePrice = String(product.selling_price ?? 0);
|
|
904
916
|
}
|
|
@@ -928,6 +940,11 @@ function createDefaultOrderRulesHooks(getBookings) {
|
|
|
928
940
|
num: product.num || 1,
|
|
929
941
|
discount_list: product.discount_list || [],
|
|
930
942
|
bundle: product.product_bundle || [],
|
|
943
|
+
// 仅在 Rules 入参中映射 price,避免折后价污染订单的 add_price。
|
|
944
|
+
options: productOptions.map(option => ({
|
|
945
|
+
...option,
|
|
946
|
+
price: option.add_price
|
|
947
|
+
})),
|
|
931
948
|
booking_id: product.metadata?.booking_id || null,
|
|
932
949
|
isClient: false,
|
|
933
950
|
// 勿写死 false:否则 Rules 不会走 total≠origin_total 的手动价推断,
|
|
@@ -935,7 +952,7 @@ function createDefaultOrderRulesHooks(getBookings) {
|
|
|
935
952
|
isManualDiscount: resolveRulesManualDiscountFlag(metadataAny),
|
|
936
953
|
holder_id: product.metadata?.holder_id,
|
|
937
954
|
startDate: getProductStartDate(product),
|
|
938
|
-
main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(
|
|
955
|
+
main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(optionSellingSum).toDecimalPlaces(2).toString() : undefined,
|
|
939
956
|
inPromotion: metadataAny._promotion?.inPromotion === true,
|
|
940
957
|
_promotion: metadataAny._promotion
|
|
941
958
|
};
|
|
@@ -946,8 +963,10 @@ function createDefaultOrderRulesHooks(getBookings) {
|
|
|
946
963
|
const existedSource = metadataAny.source_product_price ?? product.selling_price ?? '0';
|
|
947
964
|
const nextOptions = getProductSkuOptions(product);
|
|
948
965
|
const optionSum = sumOptionUnitPrice(nextOptions);
|
|
966
|
+
const nextDiscountList = values.discount_list ?? product.discount_list;
|
|
967
|
+
const optionSellingSum = optionSum.minus(getOptionDiscountAmount(nextDiscountList));
|
|
949
968
|
|
|
950
|
-
// Rules 返回的 main_product_selling_price / price
|
|
969
|
+
// Rules 返回的 main_product_selling_price / price 为不含 option 的主商品价。
|
|
951
970
|
// 优先级:main_product_selling_price(per-unit 券后 source)> price(还原/good_pass 分支)>
|
|
952
971
|
// total/num(仅当 Rules 只给 total 时的兜底)> 保留当前 source。
|
|
953
972
|
const nextSourceSellingPrice = values.main_product_selling_price !== undefined ? String(values.main_product_selling_price) : values.price !== undefined ? String(values.price) : values.total !== undefined ? toUnitPriceString(values.total, nextNum) : String(existedSource);
|
|
@@ -956,8 +975,8 @@ function createDefaultOrderRulesHooks(getBookings) {
|
|
|
956
975
|
// 缺省时保留现有 source(券前 = 当前 source)。
|
|
957
976
|
const nextSourceOriginalPrice = values.original_price !== undefined ? String(values.original_price) : String(existedSource);
|
|
958
977
|
|
|
959
|
-
//
|
|
960
|
-
const nextMainSellingPrice = new _decimal.default(Number(nextSourceSellingPrice) || 0).plus(
|
|
978
|
+
// 成交价只加回 option 折后合计;原价仍使用订单中保存的 option 原价。
|
|
979
|
+
const nextMainSellingPrice = new _decimal.default(Number(nextSourceSellingPrice) || 0).plus(optionSellingSum).toDecimalPlaces(2).toFixed(2);
|
|
961
980
|
const nextMainOriginalPrice = new _decimal.default(Number(nextSourceOriginalPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
962
981
|
const nextBundle = values.bundle !== undefined ? mergeRulesBundlePrices(product.product_bundle, values.bundle) : product.product_bundle;
|
|
963
982
|
const composedSellingPrice = composeLinePrice({
|
|
@@ -978,7 +997,7 @@ function createDefaultOrderRulesHooks(getBookings) {
|
|
|
978
997
|
...product,
|
|
979
998
|
selling_price: composedSellingPrice,
|
|
980
999
|
original_price: finalOriginalPrice,
|
|
981
|
-
discount_list:
|
|
1000
|
+
discount_list: nextDiscountList,
|
|
982
1001
|
num: values.quantity ?? product.num,
|
|
983
1002
|
product_bundle: nextBundle,
|
|
984
1003
|
metadata: {
|
|
@@ -328,7 +328,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
328
328
|
date: string;
|
|
329
329
|
status: string;
|
|
330
330
|
week: string;
|
|
331
|
-
weekNum: 0 |
|
|
331
|
+
weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
|
|
332
332
|
}[]>;
|
|
333
333
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
334
334
|
private getScheduleDataByIds;
|