@pisell/pisellos 3.0.77 → 3.0.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/Cart/types.d.ts +2 -0
- package/dist/modules/Cart/utils/cartProduct.js +21 -1
- package/dist/modules/Cart/utils/changePrice.js +6 -0
- package/dist/modules/Date/index.d.ts +1 -1
- package/dist/modules/Date/index.js +16 -8
- package/dist/modules/Date/types.d.ts +3 -1
- package/dist/modules/Discount/index.d.ts +1 -0
- package/dist/modules/Discount/index.js +2 -1
- package/dist/modules/ProductList/index.js +8 -9
- package/dist/modules/Rules/index.d.ts +3 -1
- package/dist/modules/Rules/index.js +110 -27
- package/dist/modules/Rules/types.d.ts +6 -0
- package/dist/modules/Rules/types.js +8 -0
- package/dist/modules/Schedule/index.d.ts +9 -0
- package/dist/modules/Schedule/index.js +76 -0
- package/dist/modules/Summary/index.d.ts +3 -0
- package/dist/modules/Summary/index.js +134 -15
- package/dist/modules/Summary/types.d.ts +7 -0
- package/dist/modules/Summary/utils.d.ts +104 -1
- package/dist/modules/Summary/utils.js +1131 -13
- package/dist/solution/BookingByStep/index.d.ts +14 -0
- package/dist/solution/BookingByStep/index.js +688 -210
- package/dist/solution/BookingByStep/utils/capacity.js +1 -1
- package/dist/solution/BookingByStep/utils/resources.js +4 -0
- package/dist/solution/ShopDiscount/index.d.ts +2 -0
- package/dist/solution/ShopDiscount/index.js +11 -6
- package/lib/modules/Cart/types.d.ts +2 -0
- package/lib/modules/Cart/utils/cartProduct.js +16 -1
- package/lib/modules/Cart/utils/changePrice.js +5 -0
- package/lib/modules/Date/index.d.ts +1 -1
- package/lib/modules/Date/index.js +7 -1
- package/lib/modules/Date/types.d.ts +3 -1
- package/lib/modules/Discount/index.d.ts +1 -0
- package/lib/modules/Discount/index.js +2 -1
- package/lib/modules/ProductList/index.js +0 -7
- package/lib/modules/Rules/index.d.ts +3 -1
- package/lib/modules/Rules/index.js +43 -5
- package/lib/modules/Rules/types.d.ts +6 -0
- package/lib/modules/Rules/types.js +11 -2
- package/lib/modules/Schedule/index.d.ts +9 -0
- package/lib/modules/Schedule/index.js +60 -0
- package/lib/modules/Summary/index.d.ts +3 -0
- package/lib/modules/Summary/index.js +61 -2
- package/lib/modules/Summary/types.d.ts +7 -0
- package/lib/modules/Summary/utils.d.ts +104 -1
- package/lib/modules/Summary/utils.js +673 -8
- package/lib/solution/BookingByStep/index.d.ts +14 -0
- package/lib/solution/BookingByStep/index.js +465 -89
- package/lib/solution/BookingByStep/utils/capacity.js +1 -1
- package/lib/solution/BookingByStep/utils/resources.js +4 -1
- package/lib/solution/ShopDiscount/index.d.ts +2 -0
- package/lib/solution/ShopDiscount/index.js +11 -5
- package/package.json +1 -1
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
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); }
|
|
2
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
3
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
5
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
6
|
+
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; } } }; }
|
|
7
|
+
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; }
|
|
8
|
+
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; }
|
|
9
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
10
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
11
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
1
12
|
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
2
13
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
14
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -5,12 +16,47 @@ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symb
|
|
|
5
16
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
6
17
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
7
18
|
import Decimal from 'decimal.js';
|
|
8
|
-
|
|
19
|
+
import { isNormalProduct } from "../Product/utils";
|
|
20
|
+
import dayjs from 'dayjs';
|
|
21
|
+
export var calculatePriceDetails = function calculatePriceDetails(shopInfo, items, isInScheduleByDate, surchargeList, scheduleById) {
|
|
9
22
|
var subtotal = new Decimal(calculateSubtotal(items));
|
|
10
23
|
var totalTaxFee = new Decimal(calculateTaxFee(shopInfo, items));
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
24
|
+
// 订单附加费列表
|
|
25
|
+
var surcharge = getSurcharge({
|
|
26
|
+
service: items,
|
|
27
|
+
addons: [],
|
|
28
|
+
bookingDetail: null,
|
|
29
|
+
bookingId: undefined
|
|
30
|
+
}, {
|
|
31
|
+
isEdit: false,
|
|
32
|
+
isInScheduleByDate: isInScheduleByDate,
|
|
33
|
+
surcharge_list: surchargeList,
|
|
34
|
+
scheduleById: scheduleById
|
|
35
|
+
});
|
|
36
|
+
// 订单附加费金额
|
|
37
|
+
var surchargeAmount = new Decimal(getSurchargeAmount({
|
|
38
|
+
bookingDetail: null,
|
|
39
|
+
bookingId: undefined
|
|
40
|
+
}, surcharge, {
|
|
41
|
+
isEdit: false
|
|
42
|
+
}));
|
|
43
|
+
// 税费
|
|
44
|
+
var _getTax = getTax({
|
|
45
|
+
service: items,
|
|
46
|
+
bookingDetail: null,
|
|
47
|
+
bookingId: undefined
|
|
48
|
+
}, {
|
|
49
|
+
computed: {
|
|
50
|
+
productExpectAmount: subtotal.toNumber(),
|
|
51
|
+
shopDiscount: 0
|
|
52
|
+
},
|
|
53
|
+
isEdit: false,
|
|
54
|
+
tax_rate: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.tax_rate,
|
|
55
|
+
is_price_include_tax: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.is_price_include_tax
|
|
56
|
+
}),
|
|
57
|
+
tax = _getTax.tax,
|
|
58
|
+
originTax = _getTax.originTax;
|
|
59
|
+
var total = shopInfo !== null && shopInfo !== void 0 && shopInfo.is_price_include_tax ? subtotal.plus(surchargeAmount) : subtotal.plus(tax).plus(surchargeAmount);
|
|
14
60
|
|
|
15
61
|
// 计算定金
|
|
16
62
|
var deposit = calculateDeposit(items);
|
|
@@ -18,8 +64,11 @@ export var calculatePriceDetails = function calculatePriceDetails(shopInfo, item
|
|
|
18
64
|
subtotal: subtotal.toFixed(2),
|
|
19
65
|
total: total.toFixed(2),
|
|
20
66
|
taxTitle: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.tax_title,
|
|
21
|
-
|
|
67
|
+
taxRate: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.tax_rate,
|
|
68
|
+
totalTaxFee: tax,
|
|
22
69
|
isPriceIncludeTax: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.is_price_include_tax,
|
|
70
|
+
surcharge: surcharge,
|
|
71
|
+
surchargeAmount: surchargeAmount.toFixed(2),
|
|
23
72
|
deposit: deposit
|
|
24
73
|
};
|
|
25
74
|
};
|
|
@@ -42,14 +91,468 @@ export var getBundleDiscountList = function getBundleDiscountList(bundle) {
|
|
|
42
91
|
});
|
|
43
92
|
return discountList;
|
|
44
93
|
};
|
|
45
|
-
var
|
|
94
|
+
export var calcDiscountListDifference = function calcDiscountListDifference(discountList) {
|
|
95
|
+
return discountList.reduce(function (pre, cur) {
|
|
96
|
+
var _cur$metadata;
|
|
97
|
+
return pre + ((cur === null || cur === void 0 || (_cur$metadata = cur.metadata) === null || _cur$metadata === void 0 ? void 0 : _cur$metadata.product_discount_difference) || 0);
|
|
98
|
+
}, 0);
|
|
99
|
+
};
|
|
100
|
+
export var getProductDiscountProductDiscountDifference = function getProductDiscountProductDiscountDifference(item) {
|
|
46
101
|
var _item$_origin, _item$_origin2;
|
|
47
102
|
var mainDiscountList = ((_item$_origin = item._origin) === null || _item$_origin === void 0 || (_item$_origin = _item$_origin.product) === null || _item$_origin === void 0 ? void 0 : _item$_origin.discount_list) || [];
|
|
48
103
|
var bundleDiscountList = getBundleDiscountList(((_item$_origin2 = item._origin) === null || _item$_origin2 === void 0 || (_item$_origin2 = _item$_origin2.product) === null || _item$_origin2 === void 0 ? void 0 : _item$_origin2.product_bundle) || []);
|
|
49
104
|
var discountList = [].concat(_toConsumableArray(mainDiscountList), _toConsumableArray(bundleDiscountList));
|
|
50
|
-
return discountList
|
|
51
|
-
|
|
52
|
-
|
|
105
|
+
return calcDiscountListDifference(discountList);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 计算订单税费(折扣前/折扣后),并把单品税费信息回写到商品数据上(用于明细展示/后续计算)。
|
|
110
|
+
*
|
|
111
|
+
* - **折扣前税费**:`originTax`
|
|
112
|
+
* - **折扣后税费**:`tax`(会考虑 `computed.shopDiscount` 对每个商品的分摊影响)
|
|
113
|
+
* - **税率/是否含税**:优先取 `bookingDetail.tax_rate` / `bookingDetail.is_price_include_tax`,取不到再回退到 `options.tax_rate` / `options.is_price_include_tax`
|
|
114
|
+
*
|
|
115
|
+
* **副作用(会修改入参商品对象)**:
|
|
116
|
+
* - 主商品:写入 `item.original_tax_fee` / `item.tax_fee`(四舍五入保留两位)
|
|
117
|
+
* - bundle 原价子商品:写入 `bundleItem.original_tax_fee` / `bundleItem.tax_fee`
|
|
118
|
+
* - 加时商品(`relation_details`):写入 `atItem.tax_fee`
|
|
119
|
+
* - 税费舍入差值:追加到最后一个“含税商品”的 `tax_fee_rounding_remainder` / `original_tax_fee_rounding_remainder`
|
|
120
|
+
*
|
|
121
|
+
* @param params 入参集合(RORO)
|
|
122
|
+
* @param params.service 服务商品数组(主商品)。通常是购物车商品结构(可能包含 `bundle` / `relation_details`)
|
|
123
|
+
* @param params.addons 附加商品数组(可选)。结构同商品数组
|
|
124
|
+
* @param params.bookingDetail 订单详情(编辑/详情场景用于读取后端税率配置),可选
|
|
125
|
+
* @param params.bookingId 订单/预约 ID(编辑/详情场景识别用),可选
|
|
126
|
+
* @param options 计算选项
|
|
127
|
+
* @param options.isEdit 是否处于“编辑中”。当前实现不强依赖该值(历史逻辑保留),但建议按真实状态传入
|
|
128
|
+
* @param options.computed 预计算结果(用于折扣分摊)
|
|
129
|
+
* @param options.computed.productExpectAmount 商品期望总金额(用于按比例分摊折扣)
|
|
130
|
+
* @param options.computed.shopDiscount 店铺折扣总额(用于按比例分摊到商品)
|
|
131
|
+
* @param options.tax_rate 管理端税率(百分比,如 5 表示 5%)。仅当 `bookingDetail.tax_rate` 不存在时生效
|
|
132
|
+
* @param options.is_price_include_tax 是否含税:`0` 不含税、`1` 含税。仅当 `bookingDetail.is_price_include_tax` 不存在时生效
|
|
133
|
+
* @returns 税费汇总(number,金额单位与商品价格一致,四舍五入保留两位)
|
|
134
|
+
* @returns.originTax 折扣前税费合计
|
|
135
|
+
* @returns.tax 折扣后税费合计
|
|
136
|
+
*/
|
|
137
|
+
export var getTax = function getTax(_ref, options) {
|
|
138
|
+
var service = _ref.service,
|
|
139
|
+
addons = _ref.addons,
|
|
140
|
+
bookingDetail = _ref.bookingDetail,
|
|
141
|
+
bookingId = _ref.bookingId;
|
|
142
|
+
var isEdit = options.isEdit,
|
|
143
|
+
computed = options.computed,
|
|
144
|
+
tax_rate = options.tax_rate,
|
|
145
|
+
is_price_include_tax = options.is_price_include_tax;
|
|
146
|
+
|
|
147
|
+
// 详情时未编辑的状态下, 取后端的值
|
|
148
|
+
// if (!isEdit) {
|
|
149
|
+
// return { tax: Number(bookingDetail?.tax_fee) || 0 };
|
|
150
|
+
// }
|
|
151
|
+
|
|
152
|
+
var totalOriginTax = new Decimal(0);
|
|
153
|
+
var totalTax = new Decimal(0);
|
|
154
|
+
if (service || addons) {
|
|
155
|
+
// 处理服务商品
|
|
156
|
+
if (service !== null && service !== void 0 && service.length) {
|
|
157
|
+
var serviceResult = processItemsTax(service.map(function (item) {
|
|
158
|
+
return _objectSpread(_objectSpread({}, item), {}, {
|
|
159
|
+
option: (item === null || item === void 0 ? void 0 : item.option) || (item === null || item === void 0 ? void 0 : item.options) || [],
|
|
160
|
+
bundle: (item === null || item === void 0 ? void 0 : item.bundle) || (item === null || item === void 0 ? void 0 : item.bundles) || []
|
|
161
|
+
});
|
|
162
|
+
}), {
|
|
163
|
+
bookingDetail: bookingDetail,
|
|
164
|
+
bookingId: bookingId
|
|
165
|
+
}, {
|
|
166
|
+
tax_rate: tax_rate,
|
|
167
|
+
is_price_include_tax: is_price_include_tax,
|
|
168
|
+
computed: computed
|
|
169
|
+
});
|
|
170
|
+
totalOriginTax = totalOriginTax.plus(serviceResult.originTax);
|
|
171
|
+
totalTax = totalTax.plus(serviceResult.tax);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 处理附加商品
|
|
175
|
+
if (addons !== null && addons !== void 0 && addons.length) {
|
|
176
|
+
var addonsResult = processItemsTax(addons, {
|
|
177
|
+
bookingDetail: bookingDetail,
|
|
178
|
+
bookingId: bookingId
|
|
179
|
+
}, {
|
|
180
|
+
tax_rate: tax_rate,
|
|
181
|
+
is_price_include_tax: is_price_include_tax,
|
|
182
|
+
computed: computed
|
|
183
|
+
});
|
|
184
|
+
totalOriginTax = totalOriginTax.plus(addonsResult.originTax);
|
|
185
|
+
totalTax = totalTax.plus(addonsResult.tax);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
originTax: totalOriginTax.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber(),
|
|
190
|
+
tax: totalTax.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber()
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
function getDiscountedTaxableBase(input) {
|
|
194
|
+
var basePrice = input.basePrice,
|
|
195
|
+
discount = input.discount,
|
|
196
|
+
surchargeFee = input.surchargeFee;
|
|
197
|
+
if (surchargeFee.lte(0) && basePrice.lte(0)) return new Decimal(0);
|
|
198
|
+
var discountedBase = basePrice.minus(discount);
|
|
199
|
+
if (discountedBase.lte(0)) return surchargeFee;
|
|
200
|
+
return discountedBase.plus(surchargeFee);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* 处理商品税费计算(折扣前后)
|
|
205
|
+
* 支持税费舍入差值追加到最后一个含税商品的 tax_fee_rounding_remainder / original_tax_fee_rounding_remainder 字段
|
|
206
|
+
* @param items 商品数组
|
|
207
|
+
* @param state 状态
|
|
208
|
+
* @param options 选项
|
|
209
|
+
* @param computed 计算结果
|
|
210
|
+
* @returns 累积的税费信息
|
|
211
|
+
*/
|
|
212
|
+
var processItemsTax = function processItemsTax(items, _ref2, options) {
|
|
213
|
+
var bookingDetail = _ref2.bookingDetail,
|
|
214
|
+
bookingId = _ref2.bookingId;
|
|
215
|
+
var tax_rate = options.tax_rate,
|
|
216
|
+
is_price_include_tax = options.is_price_include_tax,
|
|
217
|
+
computed = options.computed;
|
|
218
|
+
var shopDiscount = computed.shopDiscount,
|
|
219
|
+
productExpectAmount = computed.productExpectAmount;
|
|
220
|
+
|
|
221
|
+
// 精确税费累加(不四舍五入)
|
|
222
|
+
var preciseOriginTax = new Decimal(0);
|
|
223
|
+
var preciseTax = new Decimal(0);
|
|
224
|
+
// 四舍五入后的税费累加
|
|
225
|
+
var roundedOriginTax = new Decimal(0);
|
|
226
|
+
var roundedTax = new Decimal(0);
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 最后一个含税商品的引用(按物理位置)
|
|
230
|
+
* 用于追加税费舍入差值
|
|
231
|
+
*/
|
|
232
|
+
var lastTaxableItem = null;
|
|
233
|
+
var _iterator = _createForOfIteratorHelper(items),
|
|
234
|
+
_step;
|
|
235
|
+
try {
|
|
236
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
237
|
+
var item = _step.value;
|
|
238
|
+
var quantity = new Decimal(item.num || 1);
|
|
239
|
+
var unitPrice = new Decimal(item.total || 0);
|
|
240
|
+
var mainProductPrice = new Decimal(getMainProductTotal(_objectSpread(_objectSpread({}, item), {}, {
|
|
241
|
+
option: (item === null || item === void 0 ? void 0 : item.option) || (item === null || item === void 0 ? void 0 : item.options) || [],
|
|
242
|
+
bundle: (item === null || item === void 0 ? void 0 : item.bundle) || (item === null || item === void 0 ? void 0 : item.bundles) || []
|
|
243
|
+
})) || 0);
|
|
244
|
+
|
|
245
|
+
// 计算原始税费(折扣前)- 单个商品(精确值)
|
|
246
|
+
var originalTaxableBase = getDiscountedTaxableBase({
|
|
247
|
+
basePrice: mainProductPrice,
|
|
248
|
+
discount: new Decimal(0),
|
|
249
|
+
surchargeFee: new Decimal((item === null || item === void 0 ? void 0 : item.surcharge_fee) || 0)
|
|
250
|
+
});
|
|
251
|
+
var originalTaxPerItemPrecise = getProductItemTax(_objectSpread(_objectSpread({}, item), {}, {
|
|
252
|
+
total: originalTaxableBase.toNumber(),
|
|
253
|
+
quantity: 1
|
|
254
|
+
}), {
|
|
255
|
+
bookingDetail: bookingDetail,
|
|
256
|
+
bookingId: bookingId
|
|
257
|
+
}, {
|
|
258
|
+
tax_rate: tax_rate,
|
|
259
|
+
is_price_include_tax: is_price_include_tax
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// 计算平摊到该商品的折扣
|
|
263
|
+
var itemDiscount = new Decimal(0);
|
|
264
|
+
if (productExpectAmount > 0) {
|
|
265
|
+
itemDiscount = unitPrice.dividedBy(productExpectAmount).times(shopDiscount);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// 按比例计算主商品应分摊的折扣
|
|
269
|
+
var mainItemDiscount = new Decimal(0);
|
|
270
|
+
if (unitPrice.greaterThan(0)) {
|
|
271
|
+
mainItemDiscount = mainProductPrice.dividedBy(productExpectAmount).times(shopDiscount);
|
|
272
|
+
}
|
|
273
|
+
var mainItemDiscountedUnitPrice = getDiscountedTaxableBase({
|
|
274
|
+
basePrice: mainProductPrice,
|
|
275
|
+
discount: mainItemDiscount,
|
|
276
|
+
surchargeFee: new Decimal((item === null || item === void 0 ? void 0 : item.surcharge_fee) || 0)
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// 计算折后税费(折扣后)- 主商品的税费(精确值)
|
|
280
|
+
var maxDiscountedTaxPerItemPrecise = getProductItemTax(_objectSpread(_objectSpread({}, item), {}, {
|
|
281
|
+
total: mainItemDiscountedUnitPrice.toNumber(),
|
|
282
|
+
price: item.total,
|
|
283
|
+
quantity: 1
|
|
284
|
+
}), {
|
|
285
|
+
bookingDetail: bookingDetail,
|
|
286
|
+
bookingId: bookingId
|
|
287
|
+
}, {
|
|
288
|
+
tax_rate: tax_rate,
|
|
289
|
+
is_price_include_tax: is_price_include_tax
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// 四舍五入后的值
|
|
293
|
+
var maxDiscountedTaxPerItemRounded = maxDiscountedTaxPerItemPrecise.toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
|
|
294
|
+
|
|
295
|
+
// 保存到商品扩展信息中(保留两位小数)
|
|
296
|
+
item.main_product_attached_bundle_tax_fee = maxDiscountedTaxPerItemRounded.toNumber();
|
|
297
|
+
|
|
298
|
+
// 如果主商品有税费,记录为最后一个含税商品
|
|
299
|
+
if (maxDiscountedTaxPerItemPrecise.gt(0)) {
|
|
300
|
+
lastTaxableItem = {
|
|
301
|
+
type: 'main',
|
|
302
|
+
item: item
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// 注意:加时商品独立计算,不考虑主商品数量
|
|
307
|
+
var addTimePreciseTax = new Decimal(0);
|
|
308
|
+
var addTimeRoundedTax = new Decimal(0);
|
|
309
|
+
if (Array.isArray(item.relation_details)) {
|
|
310
|
+
var _iterator2 = _createForOfIteratorHelper(item.relation_details),
|
|
311
|
+
_step2;
|
|
312
|
+
try {
|
|
313
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
314
|
+
var atItem = _step2.value;
|
|
315
|
+
// 计算单件加时商品折扣后价格
|
|
316
|
+
var _originTotal = new Decimal(atItem.selling_price || atItem.price || 0);
|
|
317
|
+
var addTimeDiscount = productExpectAmount > 0 ? _originTotal.dividedBy(productExpectAmount).times(shopDiscount) : new Decimal(0);
|
|
318
|
+
var _discountedTotal = getDiscountedTaxableBase({
|
|
319
|
+
basePrice: _originTotal,
|
|
320
|
+
discount: addTimeDiscount,
|
|
321
|
+
surchargeFee: new Decimal((atItem === null || atItem === void 0 ? void 0 : atItem.surcharge_fee) || 0)
|
|
322
|
+
});
|
|
323
|
+
var addTimeTaxPerItemPrecise = getProductItemTax(_objectSpread(_objectSpread({}, atItem), {}, {
|
|
324
|
+
total: _discountedTotal.toNumber(),
|
|
325
|
+
quantity: atItem.product_quantity || atItem.num || 1
|
|
326
|
+
}), {
|
|
327
|
+
bookingDetail: bookingDetail,
|
|
328
|
+
bookingId: bookingId
|
|
329
|
+
}, {
|
|
330
|
+
tax_rate: tax_rate,
|
|
331
|
+
is_price_include_tax: is_price_include_tax
|
|
332
|
+
});
|
|
333
|
+
var addTimeTaxPerItemRounded = addTimeTaxPerItemPrecise.toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
|
|
334
|
+
|
|
335
|
+
// 保存到加时商品上(四舍五入后的值)
|
|
336
|
+
atItem.tax_fee = addTimeTaxPerItemRounded.toNumber();
|
|
337
|
+
addTimePreciseTax = addTimePreciseTax.plus(addTimeTaxPerItemPrecise);
|
|
338
|
+
addTimeRoundedTax = addTimeRoundedTax.plus(addTimeTaxPerItemRounded);
|
|
339
|
+
|
|
340
|
+
// 如果加时商品有税费,记录为最后一个含税商品
|
|
341
|
+
if (addTimeTaxPerItemPrecise.gt(0)) {
|
|
342
|
+
lastTaxableItem = {
|
|
343
|
+
type: 'addTime',
|
|
344
|
+
item: atItem
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
} catch (err) {
|
|
349
|
+
_iterator2.e(err);
|
|
350
|
+
} finally {
|
|
351
|
+
_iterator2.f();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// 处理 bundle 子商品(仅原价子商品)
|
|
356
|
+
var bundlePreciseOriginTax = new Decimal(0);
|
|
357
|
+
var bundlePreciseTax = new Decimal(0);
|
|
358
|
+
var bundleRoundedOriginTax = new Decimal(0);
|
|
359
|
+
var bundleRoundedTax = new Decimal(0);
|
|
360
|
+
if (Array.isArray(item === null || item === void 0 ? void 0 : item.bundle)) {
|
|
361
|
+
var _iterator3 = _createForOfIteratorHelper(item === null || item === void 0 ? void 0 : item.bundle),
|
|
362
|
+
_step3;
|
|
363
|
+
try {
|
|
364
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
365
|
+
var bundleItem = _step3.value;
|
|
366
|
+
// 只处理原价的子商品
|
|
367
|
+
if (getBundleItemIsOriginalPrice(bundleItem)) {
|
|
368
|
+
var _ref3, _bundleItem$bundle_se;
|
|
369
|
+
var bundleQuantity = new Decimal(bundleItem.num || bundleItem.quantity || 1);
|
|
370
|
+
var bundleUnitPrice = new Decimal((_ref3 = (_bundleItem$bundle_se = bundleItem.bundle_selling_price) !== null && _bundleItem$bundle_se !== void 0 ? _bundleItem$bundle_se : bundleItem.price) !== null && _ref3 !== void 0 ? _ref3 : 0);
|
|
371
|
+
|
|
372
|
+
// 计算原始税费(折扣前)- 单个商品(精确值)
|
|
373
|
+
var bundleOriginalTaxableBase = getDiscountedTaxableBase({
|
|
374
|
+
basePrice: bundleUnitPrice,
|
|
375
|
+
discount: new Decimal(0),
|
|
376
|
+
surchargeFee: new Decimal((bundleItem === null || bundleItem === void 0 ? void 0 : bundleItem.surcharge_fee) || 0)
|
|
377
|
+
});
|
|
378
|
+
var bundleOriginalTaxPerItemPrecise = getProductItemTax(_objectSpread(_objectSpread({}, bundleItem), {}, {
|
|
379
|
+
total: bundleOriginalTaxableBase.toNumber(),
|
|
380
|
+
quantity: 1
|
|
381
|
+
}), {
|
|
382
|
+
bookingDetail: bookingDetail,
|
|
383
|
+
bookingId: bookingId
|
|
384
|
+
}, {
|
|
385
|
+
tax_rate: tax_rate,
|
|
386
|
+
is_price_include_tax: is_price_include_tax
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// 计算平摊到该bundle商品的折扣
|
|
390
|
+
var bundleItemDiscount = new Decimal(0);
|
|
391
|
+
if (productExpectAmount > 0) {
|
|
392
|
+
bundleItemDiscount = bundleUnitPrice.dividedBy(productExpectAmount).times(shopDiscount);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// bundle商品折后单价
|
|
396
|
+
var bundleDiscountedUnitPrice = getDiscountedTaxableBase({
|
|
397
|
+
basePrice: bundleUnitPrice,
|
|
398
|
+
discount: bundleItemDiscount,
|
|
399
|
+
surchargeFee: new Decimal((bundleItem === null || bundleItem === void 0 ? void 0 : bundleItem.surcharge_fee) || 0)
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// 计算折后税费(折扣后)- 单个商品(精确值)
|
|
403
|
+
var bundleDiscountedTaxPerItemPrecise = getProductItemTax(_objectSpread(_objectSpread({}, bundleItem), {}, {
|
|
404
|
+
total: bundleDiscountedUnitPrice.toNumber(),
|
|
405
|
+
quantity: 1
|
|
406
|
+
}), {
|
|
407
|
+
bookingDetail: bookingDetail,
|
|
408
|
+
bookingId: bookingId
|
|
409
|
+
}, {
|
|
410
|
+
tax_rate: tax_rate,
|
|
411
|
+
is_price_include_tax: is_price_include_tax
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
// 四舍五入后的值
|
|
415
|
+
var bundleOriginalTaxPerItemRounded = bundleOriginalTaxPerItemPrecise.toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
|
|
416
|
+
var bundleDiscountedTaxPerItemRounded = bundleDiscountedTaxPerItemPrecise.toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
|
|
417
|
+
|
|
418
|
+
// 保存到bundle商品上(单个商品的税费,四舍五入后)
|
|
419
|
+
bundleItem.original_tax_fee = bundleOriginalTaxPerItemRounded.toNumber();
|
|
420
|
+
bundleItem.tax_fee = bundleDiscountedTaxPerItemRounded.toNumber();
|
|
421
|
+
|
|
422
|
+
// 累加bundle税费(需要乘以bundle数量)
|
|
423
|
+
bundlePreciseOriginTax = bundlePreciseOriginTax.plus(bundleOriginalTaxPerItemPrecise.times(bundleQuantity));
|
|
424
|
+
bundlePreciseTax = bundlePreciseTax.plus(bundleDiscountedTaxPerItemPrecise.times(bundleQuantity));
|
|
425
|
+
bundleRoundedOriginTax = bundleRoundedOriginTax.plus(bundleOriginalTaxPerItemRounded.times(bundleQuantity));
|
|
426
|
+
bundleRoundedTax = bundleRoundedTax.plus(bundleDiscountedTaxPerItemRounded.times(bundleQuantity));
|
|
427
|
+
|
|
428
|
+
// 如果bundle商品有税费,记录为最后一个含税商品
|
|
429
|
+
if (bundleDiscountedTaxPerItemPrecise.gt(0)) {
|
|
430
|
+
lastTaxableItem = {
|
|
431
|
+
type: 'bundle',
|
|
432
|
+
item: bundleItem
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
} catch (err) {
|
|
438
|
+
_iterator3.e(err);
|
|
439
|
+
} finally {
|
|
440
|
+
_iterator3.f();
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
// 主商品的原始税费和折后税费(精确值)
|
|
444
|
+
var originalTaxFeePrecise = originalTaxPerItemPrecise.plus(bundlePreciseOriginTax);
|
|
445
|
+
var taxFeePrecise = maxDiscountedTaxPerItemPrecise.plus(bundlePreciseTax);
|
|
446
|
+
|
|
447
|
+
// 主商品的原始税费和折后税费(四舍五入后)
|
|
448
|
+
var originalTaxFeeRounded = originalTaxPerItemPrecise.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).plus(bundleRoundedOriginTax);
|
|
449
|
+
var taxFeeRounded = maxDiscountedTaxPerItemRounded.plus(bundleRoundedTax);
|
|
450
|
+
|
|
451
|
+
// 保存到商品扩展信息中(四舍五入后的值)
|
|
452
|
+
item.original_tax_fee = originalTaxFeeRounded.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
|
|
453
|
+
item.tax_fee = taxFeeRounded.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
|
|
454
|
+
|
|
455
|
+
// 累加到总税费(乘以数量)
|
|
456
|
+
preciseOriginTax = preciseOriginTax.plus(originalTaxFeePrecise.times(quantity)).plus(addTimePreciseTax);
|
|
457
|
+
preciseTax = preciseTax.plus(taxFeePrecise.times(quantity)).plus(addTimePreciseTax);
|
|
458
|
+
roundedOriginTax = roundedOriginTax.plus(originalTaxFeeRounded.times(quantity)).plus(addTimeRoundedTax);
|
|
459
|
+
roundedTax = roundedTax.plus(taxFeeRounded.times(quantity)).plus(addTimeRoundedTax);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// 计算期望的总税费(精确累加后四舍五入)
|
|
463
|
+
} catch (err) {
|
|
464
|
+
_iterator.e(err);
|
|
465
|
+
} finally {
|
|
466
|
+
_iterator.f();
|
|
467
|
+
}
|
|
468
|
+
var expectedOriginTax = preciseOriginTax.toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
|
|
469
|
+
var expectedTax = preciseTax.toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
|
|
470
|
+
|
|
471
|
+
// 计算舍入差值
|
|
472
|
+
var originTaxRemainder = expectedOriginTax.minus(roundedOriginTax).toNumber();
|
|
473
|
+
var taxRemainder = expectedTax.minus(roundedTax).toNumber();
|
|
474
|
+
|
|
475
|
+
// 将差值追加到最后一个含税商品
|
|
476
|
+
if (lastTaxableItem) {
|
|
477
|
+
if (originTaxRemainder !== 0) {
|
|
478
|
+
if (lastTaxableItem.type === 'main') {
|
|
479
|
+
lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
|
|
480
|
+
} else {
|
|
481
|
+
lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (taxRemainder !== 0) {
|
|
485
|
+
if (lastTaxableItem.type === 'main') {
|
|
486
|
+
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
|
|
487
|
+
} else {
|
|
488
|
+
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return {
|
|
493
|
+
originTax: expectedOriginTax,
|
|
494
|
+
tax: expectedTax
|
|
495
|
+
};
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* 计算单个商品的税费(返回精确值,不四舍五入)
|
|
500
|
+
* @param item 商品信息
|
|
501
|
+
* @param state 状态
|
|
502
|
+
* @param options 选项
|
|
503
|
+
* @returns 精确的税费值(Decimal类型)
|
|
504
|
+
*/
|
|
505
|
+
var getProductItemTax = function getProductItemTax(item, state, options) {
|
|
506
|
+
var _ref4, _item$quantity, _bookingDetail$tax_ra, _ref5, _bookingDetail$is_pri;
|
|
507
|
+
var bookingDetail = state.bookingDetail;
|
|
508
|
+
var tax_rate = options.tax_rate,
|
|
509
|
+
is_price_include_tax = options.is_price_include_tax;
|
|
510
|
+
|
|
511
|
+
// 折扣后的金额 = 商品金额 - 商品折扣
|
|
512
|
+
var productDiscountPrice = new Decimal(item.total || 0);
|
|
513
|
+
/**
|
|
514
|
+
* 注意:该函数被多处以“单件税费”方式调用(调用方会显式传入 quantity: 1),
|
|
515
|
+
* 因此这里必须优先使用 `item.quantity`,否则会出现数量被重复相乘(外层再乘一次 num)的情况。
|
|
516
|
+
*/
|
|
517
|
+
var quantity = new Decimal((_ref4 = (_item$quantity = item.quantity) !== null && _item$quantity !== void 0 ? _item$quantity : item.num) !== null && _ref4 !== void 0 ? _ref4 : 1);
|
|
518
|
+
|
|
519
|
+
// 如果商品金额小于或等于0,不计算税费
|
|
520
|
+
if (productDiscountPrice.lte(0)) {
|
|
521
|
+
return new Decimal(0);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// 优先从 bookingDetail 取税率和是否含税设置,取不到则从 options 中取(兼容新增模式)
|
|
525
|
+
// 注意:bookingDetail中的tax_rate不需要除以100,options 中的tax_rate需要除以100
|
|
526
|
+
var currentTaxRate = new Decimal((_bookingDetail$tax_ra = bookingDetail === null || bookingDetail === void 0 ? void 0 : bookingDetail.tax_rate) !== null && _bookingDetail$tax_ra !== void 0 ? _bookingDetail$tax_ra : tax_rate ? tax_rate / 100 : 0);
|
|
527
|
+
var currentIsPriceIncludeTax = (_ref5 = (_bookingDetail$is_pri = bookingDetail === null || bookingDetail === void 0 ? void 0 : bookingDetail.is_price_include_tax) !== null && _bookingDetail$is_pri !== void 0 ? _bookingDetail$is_pri : is_price_include_tax) !== null && _ref5 !== void 0 ? _ref5 : 0;
|
|
528
|
+
var singleItemTax = new Decimal(0);
|
|
529
|
+
|
|
530
|
+
// 计算单个商品税费, 一次性商品 is_charge_tax 可能为空
|
|
531
|
+
if (item.is_charge_tax === 0 || !item.is_charge_tax) {
|
|
532
|
+
// 该商品不需要收税
|
|
533
|
+
singleItemTax = new Decimal(0);
|
|
534
|
+
} else {
|
|
535
|
+
// 该商品需要收税
|
|
536
|
+
if (currentIsPriceIncludeTax === 0) {
|
|
537
|
+
// 价格不含税:管理端填写的单价是不含税的价格
|
|
538
|
+
singleItemTax = productDiscountPrice.times(currentTaxRate);
|
|
539
|
+
} else {
|
|
540
|
+
// 价格含税:管理端填写的单价是含税的价格
|
|
541
|
+
// 含税总价 = 不含税价 + (不含税价 * 税率) = 不含税价 * (1 + 税率)
|
|
542
|
+
// 商品不含税价 = 含税总价 / (1 + 税率)
|
|
543
|
+
// 税 = 不含税价 * 税率
|
|
544
|
+
var divisor = new Decimal(1).plus(currentTaxRate);
|
|
545
|
+
if (divisor.lte(0)) {
|
|
546
|
+
// 如果 (1 + 税率) <= 0,说明税率异常,不计算税费
|
|
547
|
+
singleItemTax = new Decimal(0);
|
|
548
|
+
} else {
|
|
549
|
+
singleItemTax = productDiscountPrice.dividedBy(divisor).times(currentTaxRate);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// 结果 = 单个商品税费 × 数量(返回精确值,不四舍五入)
|
|
555
|
+
return singleItemTax.times(quantity);
|
|
53
556
|
};
|
|
54
557
|
|
|
55
558
|
/**
|
|
@@ -81,9 +584,9 @@ export var calculateTaxFee = function calculateTaxFee(shopInfo, items) {
|
|
|
81
584
|
if (!(items !== null && items !== void 0 && items.length)) {
|
|
82
585
|
return '0.00';
|
|
83
586
|
}
|
|
84
|
-
var
|
|
85
|
-
is_price_include_tax =
|
|
86
|
-
tax_rate =
|
|
587
|
+
var _ref6 = shopInfo || {},
|
|
588
|
+
is_price_include_tax = _ref6.is_price_include_tax,
|
|
589
|
+
tax_rate = _ref6.tax_rate;
|
|
87
590
|
var totalTaxFee = items.reduce(function (sum, item) {
|
|
88
591
|
var cartItemTotalPrice = new Decimal(item.summaryTotal || 0);
|
|
89
592
|
var taxRate = new Decimal(tax_rate || 0).div(100);
|
|
@@ -129,4 +632,619 @@ export var calculateDeposit = function calculateDeposit(items) {
|
|
|
129
632
|
};
|
|
130
633
|
}
|
|
131
634
|
return undefined;
|
|
132
|
-
};
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* 计算订单附加费金额(订单级别合计)。
|
|
639
|
+
*
|
|
640
|
+
* - **详情未编辑**(`!options.isEdit && bookingId`)且存在后端详情时:直接返回 `bookingDetail.surcharge_fee`
|
|
641
|
+
* - **新增/编辑**时:对 `surcharge`(通常为 `getSurcharge` 的返回值)按 `item.value` 求和
|
|
642
|
+
*
|
|
643
|
+
* @param params 入参集合(RORO)
|
|
644
|
+
* @param params.bookingDetail 订单详情(详情未编辑时用于读取后端的 `surcharge_fee`),可选
|
|
645
|
+
* @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
|
|
646
|
+
* @param surcharge 附加费列表(通常来自 `getSurcharge`),元素结构至少包含 `value: number`
|
|
647
|
+
* @param options 计算选项
|
|
648
|
+
* @param options.isEdit 是否处于“编辑中”。`false` 时会优先走后端金额直取逻辑(若存在)
|
|
649
|
+
* @returns 订单附加费金额(number,金额单位与商品价格一致)
|
|
650
|
+
*/
|
|
651
|
+
export var getSurchargeAmount = function getSurchargeAmount(_ref7, surcharge, options) {
|
|
652
|
+
var bookingDetail = _ref7.bookingDetail,
|
|
653
|
+
bookingId = _ref7.bookingId;
|
|
654
|
+
var isEdit = options.isEdit;
|
|
655
|
+
// 订单未变更过
|
|
656
|
+
if (!isEdit) {
|
|
657
|
+
// 有后端数据则直接使用后端的数据
|
|
658
|
+
if (bookingDetail && bookingId) {
|
|
659
|
+
return Number(bookingDetail.surcharge_fee);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (!Array.isArray(surcharge)) return 0;
|
|
663
|
+
// 新增状态使用 getSurcharge 的返回值进行求和
|
|
664
|
+
return surcharge.reduce(function (total, item) {
|
|
665
|
+
return total + (item.value || 0);
|
|
666
|
+
}, 0);
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
// bundle商品是否是原价
|
|
670
|
+
var getBundleItemIsOriginalPrice = function getBundleItemIsOriginalPrice(item) {
|
|
671
|
+
return (item === null || item === void 0 ? void 0 : item.price_type) === 'markup' && (item === null || item === void 0 ? void 0 : item.price_type_ext) === 'product_price';
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
// bundle商品是否是加价
|
|
675
|
+
var getBundleItemIsMarkupPrice = function getBundleItemIsMarkupPrice(item) {
|
|
676
|
+
return (item === null || item === void 0 ? void 0 : item.price_type) === 'markup' && ((item === null || item === void 0 ? void 0 : item.price_type_ext) === '' || !(item !== null && item !== void 0 && item.price_type_ext));
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
// bundle商品是否是减价
|
|
680
|
+
var getBundleItemIsDiscountPrice = function getBundleItemIsDiscountPrice(item) {
|
|
681
|
+
return (item === null || item === void 0 ? void 0 : item.price_type) === 'markdown' && ((item === null || item === void 0 ? void 0 : item.price_type_ext) === '' || !(item !== null && item !== void 0 && item.price_type_ext));
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
// bundle商品是否是加价或减价
|
|
685
|
+
var getBundleItemIsMarkupOrDiscountPrice = function getBundleItemIsMarkupOrDiscountPrice(item) {
|
|
686
|
+
return getBundleItemIsMarkupPrice(item) || getBundleItemIsDiscountPrice(item);
|
|
687
|
+
};
|
|
688
|
+
var getDiscountAmount = function getDiscountAmount(discounts) {
|
|
689
|
+
return (discounts || []).reduce(function (total, discount) {
|
|
690
|
+
return total.add(new Decimal(discount.amount || 0));
|
|
691
|
+
}, new Decimal(0)).toNumber();
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* 获取主商品加价减价后的总价 (主商品价格 + 子商品加价减价)
|
|
696
|
+
*/
|
|
697
|
+
var getMainProductTotal = function getMainProductTotal(item) {
|
|
698
|
+
var _ref8, _ref9, _item$main_product_se, _item$metadata, _item$_origin3, _item$_originData;
|
|
699
|
+
var total = new Decimal((_ref8 = (_ref9 = (_item$main_product_se = item === null || item === void 0 ? void 0 : item.main_product_selling_price) !== null && _item$main_product_se !== void 0 ? _item$main_product_se : item === null || item === void 0 || (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata.main_product_selling_price) !== null && _ref9 !== void 0 ? _ref9 : item.price) !== null && _ref8 !== void 0 ? _ref8 : 0);
|
|
700
|
+
var discount = (item === null || item === void 0 || (_item$_origin3 = item._origin) === null || _item$_origin3 === void 0 || (_item$_origin3 = _item$_origin3.product) === null || _item$_origin3 === void 0 ? void 0 : _item$_origin3.discount_list) || (item === null || item === void 0 || (_item$_originData = item._originData) === null || _item$_originData === void 0 || (_item$_originData = _item$_originData.product) === null || _item$_originData === void 0 || (_item$_originData = _item$_originData.discount_list) === null || _item$_originData === void 0 ? void 0 : _item$_originData.filter(function (item) {
|
|
701
|
+
var _item$metadata2;
|
|
702
|
+
return !(item !== null && item !== void 0 && (_item$metadata2 = item.metadata) !== null && _item$metadata2 !== void 0 && _item$metadata2.custom_product_bundle_map_id);
|
|
703
|
+
})) || [];
|
|
704
|
+
var mainProductDiscountAmount = getDiscountAmount(discount);
|
|
705
|
+
total = total.minus(mainProductDiscountAmount);
|
|
706
|
+
|
|
707
|
+
// 单规格
|
|
708
|
+
if (item !== null && item !== void 0 && item.option && Array.isArray(item === null || item === void 0 ? void 0 : item.option)) {
|
|
709
|
+
total = total.add(item === null || item === void 0 ? void 0 : item.option.reduce(function (t, option) {
|
|
710
|
+
return t.add(new Decimal(option.price || 0).mul(option.num || 1));
|
|
711
|
+
}, new Decimal(0)));
|
|
712
|
+
}
|
|
713
|
+
var _iterator4 = _createForOfIteratorHelper((item === null || item === void 0 ? void 0 : item.bundle) || []),
|
|
714
|
+
_step4;
|
|
715
|
+
try {
|
|
716
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
717
|
+
var bundleItem = _step4.value;
|
|
718
|
+
if (getBundleItemIsMarkupOrDiscountPrice(bundleItem)) {
|
|
719
|
+
var _ref10, _bundleItem$bundle_se2;
|
|
720
|
+
// IMPORTANT: 套餐子商品如果应用了 discount,bundle_selling_price和 price 其实都已经是折后价格了,不需要单独再减一次
|
|
721
|
+
var bundleItemTotal = new Decimal((_ref10 = (_bundleItem$bundle_se2 = bundleItem.bundle_selling_price) !== null && _bundleItem$bundle_se2 !== void 0 ? _bundleItem$bundle_se2 : bundleItem.price) !== null && _ref10 !== void 0 ? _ref10 : 0);
|
|
722
|
+
total = total.add(bundleItemTotal);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
} catch (err) {
|
|
726
|
+
_iterator4.e(err);
|
|
727
|
+
} finally {
|
|
728
|
+
_iterator4.f();
|
|
729
|
+
}
|
|
730
|
+
return total.toNumber();
|
|
731
|
+
};
|
|
732
|
+
/**
|
|
733
|
+
* 判断商品是否符合附加费条件
|
|
734
|
+
*/
|
|
735
|
+
var isProductMatchSurchargeCondition = function isProductMatchSurchargeCondition(item, options) {
|
|
736
|
+
var isInScheduleByDate = options === null || options === void 0 ? void 0 : options.isInScheduleByDate;
|
|
737
|
+
var surchargeConfig = options.surchargeConfig,
|
|
738
|
+
_options$scheduleById = options.scheduleById,
|
|
739
|
+
scheduleById = _options$scheduleById === void 0 ? {} : _options$scheduleById;
|
|
740
|
+
var startDate = item.startDate,
|
|
741
|
+
product_id = item.product_id,
|
|
742
|
+
isCustomItem = item.isCustomItem;
|
|
743
|
+
var _surchargeConfig$open = surchargeConfig.open_product,
|
|
744
|
+
open_product = _surchargeConfig$open === void 0 ? 0 : _surchargeConfig$open,
|
|
745
|
+
_surchargeConfig$is_a = surchargeConfig.is_all,
|
|
746
|
+
is_all = _surchargeConfig$is_a === void 0 ? 0 : _surchargeConfig$is_a,
|
|
747
|
+
_surchargeConfig$avai = surchargeConfig.available_product_ids,
|
|
748
|
+
available_product_ids = _surchargeConfig$avai === void 0 ? [] : _surchargeConfig$avai,
|
|
749
|
+
_surchargeConfig$open2 = surchargeConfig.open_schedule,
|
|
750
|
+
open_schedule = _surchargeConfig$open2 === void 0 ? 0 : _surchargeConfig$open2,
|
|
751
|
+
schedule_type = surchargeConfig.schedule_type,
|
|
752
|
+
_surchargeConfig$avai2 = surchargeConfig.available_schedule_ids,
|
|
753
|
+
available_schedule_ids = _surchargeConfig$avai2 === void 0 ? [] : _surchargeConfig$avai2;
|
|
754
|
+
|
|
755
|
+
// 判断商品是否符合条件
|
|
756
|
+
var isProductMatch = false;
|
|
757
|
+
if (open_product === 0) {
|
|
758
|
+
// 未开启商品限制,所有商品都符合
|
|
759
|
+
isProductMatch = true;
|
|
760
|
+
} else {
|
|
761
|
+
// 开启了商品限制
|
|
762
|
+
if (is_all === 1) {
|
|
763
|
+
// 所有商品都收取附加费
|
|
764
|
+
isProductMatch = true;
|
|
765
|
+
} else {
|
|
766
|
+
// 指定商品收取附加费
|
|
767
|
+
if (isCustomItem) {
|
|
768
|
+
// 自定义商品:如果是指定商品模式,自定义商品不符合条件
|
|
769
|
+
// 因为自定义商品没有 product_id,无法匹配到指定商品列表
|
|
770
|
+
isProductMatch = false;
|
|
771
|
+
} else {
|
|
772
|
+
// 普通商品:检查是否在指定商品列表中
|
|
773
|
+
isProductMatch = available_product_ids.includes(product_id);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// 判断日程是否符合条件
|
|
779
|
+
var isScheduleMatch = false;
|
|
780
|
+
if (open_schedule === 0) {
|
|
781
|
+
// 未开启日程限制,所有日程都符合
|
|
782
|
+
isScheduleMatch = true;
|
|
783
|
+
} else {
|
|
784
|
+
// 开启了日程限制
|
|
785
|
+
if (schedule_type === 'all') {
|
|
786
|
+
// 所有日程都收取附加费
|
|
787
|
+
isScheduleMatch = true;
|
|
788
|
+
} else {
|
|
789
|
+
// 指定日程收取附加费
|
|
790
|
+
for (var j = 0; j < available_schedule_ids.length; j++) {
|
|
791
|
+
var scheduleId = available_schedule_ids[j];
|
|
792
|
+
var schedule = scheduleById[scheduleId];
|
|
793
|
+
if (schedule) {
|
|
794
|
+
var isInSchedule = isInScheduleByDate({
|
|
795
|
+
// date: startDate?.format('YYYY-MM-DD HH:mm:ss') || '',
|
|
796
|
+
date: startDate || '',
|
|
797
|
+
schedule: schedule
|
|
798
|
+
});
|
|
799
|
+
if (isInSchedule) {
|
|
800
|
+
isScheduleMatch = true;
|
|
801
|
+
break;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// 商品和日程条件都要满足(取交集)
|
|
809
|
+
return isProductMatch && isScheduleMatch;
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* 订单附加费各项信息
|
|
814
|
+
*
|
|
815
|
+
* - **详情未编辑**(`!options.isEdit && bookingId`)时:直接返回 `bookingDetail.surcharge`(后端计算结果)
|
|
816
|
+
* - **新增/编辑**时:按 `options.surcharge_list` 逐条配置计算本次订单的附加费
|
|
817
|
+
*
|
|
818
|
+
* 规则要点:
|
|
819
|
+
* - 匹配范围包含:主商品(`service`)、原价 bundle 子商品(`item.bundle`)、加时商品(`item.relation_details`)、以及 addons(`addons.value`)
|
|
820
|
+
* - 固定附加费 `fixed`:只加一次,再按商品数量分摊(向下取整保留两位),剩余小数会以 `surcharge_rounding_remainder` 形式抹平到最后一个商品
|
|
821
|
+
* - 百分比附加费 `percentage`:按每个商品(价格 * 数量)分别计算再累加
|
|
822
|
+
* - 当 `open_product === 0`:不回写到商品,只在订单级别累加;否则会把单品附加费回写到商品
|
|
823
|
+
*
|
|
824
|
+
* **副作用(可能修改入参商品对象)**:
|
|
825
|
+
* - 当 `open_product !== 0` 时:写入 `item.surcharge_fee`(单品单数量附加费,保留两位、向下取整)
|
|
826
|
+
* - 写入 `item.relation_surcharge_ids`(关联到的 surcharge 配置 id 列表)
|
|
827
|
+
* - 写入 `item.surcharge_rounding_remainder`(用于抹平固定附加费/总额舍入差)
|
|
828
|
+
*
|
|
829
|
+
* @param params 入参集合(RORO)
|
|
830
|
+
* @param params.service 服务商品数组(主商品)。元素可能包含 `bundle` / `relation_details`
|
|
831
|
+
* @param params.addons 附加商品容器。当前实现读取 `addons.value` 作为商品数组(所以通常传 `{ value: CartItem[] }`)
|
|
832
|
+
* @param params.bookingDetail 订单详情(详情未编辑时用于直接取后端的 surcharge 列表),可选
|
|
833
|
+
* @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
|
|
834
|
+
* @param options 计算选项
|
|
835
|
+
* @param options.isEdit 是否处于“编辑中”。`false` 且存在 `bookingId` 时会走详情直取逻辑
|
|
836
|
+
* @param options.surcharge_list 附加费配置列表(后端下发)。缺失/为空则返回空数组
|
|
837
|
+
* @param options.isInScheduleByDate 判断日期是否落在某个 schedule 内的方法(通常来自 ScheduleModule)
|
|
838
|
+
* @param options.scheduleById schedule 映射表:`{ [scheduleId]: schedule }`(用于根据配置的 `available_schedule_ids` 做日程匹配)
|
|
839
|
+
* @returns 附加费列表(仅返回金额 > 0 的项)
|
|
840
|
+
*/
|
|
841
|
+
export var getSurcharge = function getSurcharge(_ref11, options) {
|
|
842
|
+
var _service$filter;
|
|
843
|
+
var service = _ref11.service,
|
|
844
|
+
addons = _ref11.addons,
|
|
845
|
+
bookingDetail = _ref11.bookingDetail,
|
|
846
|
+
bookingId = _ref11.bookingId;
|
|
847
|
+
var isEdit = options.isEdit,
|
|
848
|
+
isInScheduleByDate = options.isInScheduleByDate,
|
|
849
|
+
surcharge_list = options.surcharge_list,
|
|
850
|
+
scheduleById = options.scheduleById;
|
|
851
|
+
// 在所有商品里试着找 start_date,如果没有则用当前时间
|
|
852
|
+
var firstAppointmentCartItem = (_service$filter = service.filter(function (n) {
|
|
853
|
+
return !isNormalProduct(n._productOrigin);
|
|
854
|
+
})) === null || _service$filter === void 0 ? void 0 : _service$filter[0];
|
|
855
|
+
var startDate = '';
|
|
856
|
+
if (firstAppointmentCartItem) {
|
|
857
|
+
startDate = firstAppointmentCartItem.start_date + ' ' + firstAppointmentCartItem.start_time + ':00';
|
|
858
|
+
} else {
|
|
859
|
+
startDate = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|
860
|
+
}
|
|
861
|
+
// 编辑状态, 且未修改商品时直接从详情取出
|
|
862
|
+
if (!isEdit && bookingId) {
|
|
863
|
+
if (Array.isArray(bookingDetail === null || bookingDetail === void 0 ? void 0 : bookingDetail.surcharge)) {
|
|
864
|
+
return ((bookingDetail === null || bookingDetail === void 0 ? void 0 : bookingDetail.surcharge) || []).filter(function (d) {
|
|
865
|
+
return Number(d.amount) > 0;
|
|
866
|
+
}).map(function (d, index) {
|
|
867
|
+
return {
|
|
868
|
+
key: "custom_surcharge_".concat(index),
|
|
869
|
+
// label:
|
|
870
|
+
// d.name[state.locale || 'en'] ||
|
|
871
|
+
// d.name['en'] ||
|
|
872
|
+
// d.name['original'],
|
|
873
|
+
label: d.name,
|
|
874
|
+
value: d.amount,
|
|
875
|
+
name: d.name,
|
|
876
|
+
surcharge_id: d.id,
|
|
877
|
+
description: d.description,
|
|
878
|
+
// 后端说这个固定传 default
|
|
879
|
+
type: 'default',
|
|
880
|
+
fixed: d.fixed,
|
|
881
|
+
amount: d.amount,
|
|
882
|
+
percentage: d.percentage
|
|
883
|
+
};
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
return [];
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
// 用于“计算总价”的场景:每次调用都应重新计算(避免重复调用导致 surcharge_fee 累加)
|
|
890
|
+
// 注意:同一次调用内仍会在多条 surcharge 配置之间累加
|
|
891
|
+
resetItemsSurchargeSideEffects({
|
|
892
|
+
service: service,
|
|
893
|
+
addons: addons
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
// 无附加费规则
|
|
897
|
+
if (!Array.isArray(surcharge_list) || !(surcharge_list !== null && surcharge_list !== void 0 && surcharge_list.length)) return [];
|
|
898
|
+
|
|
899
|
+
// 分别计算每种附加费总和
|
|
900
|
+
var surchargeWithAmount = [];
|
|
901
|
+
|
|
902
|
+
// 遍历每种附加费配置
|
|
903
|
+
for (var i = 0; i < surcharge_list.length; i++) {
|
|
904
|
+
var surchargeConfig = surcharge_list[i];
|
|
905
|
+
var _surchargeConfig$perc = surchargeConfig.percentage,
|
|
906
|
+
percentage = _surchargeConfig$perc === void 0 ? '0' : _surchargeConfig$perc,
|
|
907
|
+
_surchargeConfig$fixe = surchargeConfig.fixed,
|
|
908
|
+
fixed = _surchargeConfig$fixe === void 0 ? '0' : _surchargeConfig$fixe,
|
|
909
|
+
id = surchargeConfig.id,
|
|
910
|
+
type = surchargeConfig.type,
|
|
911
|
+
description = surchargeConfig.description,
|
|
912
|
+
open_product = surchargeConfig.open_product;
|
|
913
|
+
|
|
914
|
+
// 收集所有符合条件的商品
|
|
915
|
+
var matchedItems = [];
|
|
916
|
+
|
|
917
|
+
// 检查service中符合条件的商品
|
|
918
|
+
if (Array.isArray(service)) {
|
|
919
|
+
var _iterator5 = _createForOfIteratorHelper(service),
|
|
920
|
+
_step5;
|
|
921
|
+
try {
|
|
922
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
923
|
+
var item = _step5.value;
|
|
924
|
+
// 主商品符合附加费条件
|
|
925
|
+
if (isProductMatchSurchargeCondition({
|
|
926
|
+
isCustomItem: item.isCustomItem,
|
|
927
|
+
startDate: startDate,
|
|
928
|
+
product_id: item.id
|
|
929
|
+
}, {
|
|
930
|
+
surchargeConfig: surchargeConfig,
|
|
931
|
+
scheduleById: scheduleById || {},
|
|
932
|
+
isInScheduleByDate: isInScheduleByDate
|
|
933
|
+
})) {
|
|
934
|
+
// 主商品加价减价后的总价
|
|
935
|
+
var total = getMainProductTotal(_objectSpread(_objectSpread({}, item), {}, {
|
|
936
|
+
option: (item === null || item === void 0 ? void 0 : item.option) || (item === null || item === void 0 ? void 0 : item.options) || [],
|
|
937
|
+
bundle: (item === null || item === void 0 ? void 0 : item.bundle) || (item === null || item === void 0 ? void 0 : item.bundles) || []
|
|
938
|
+
}));
|
|
939
|
+
var mainQuantity = item.num || 1;
|
|
940
|
+
matchedItems.push({
|
|
941
|
+
total: total,
|
|
942
|
+
// addTimeTotal: getRelationDetailsTotal(
|
|
943
|
+
// item._extend.relation_details || []
|
|
944
|
+
// ),
|
|
945
|
+
isMain: true,
|
|
946
|
+
quantity: mainQuantity,
|
|
947
|
+
item: item,
|
|
948
|
+
mainQuantity: mainQuantity // 主商品的mainQuantity等于自己的quantity
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
var arr = (item === null || item === void 0 ? void 0 : item.bundle) || (item === null || item === void 0 ? void 0 : item.bundles) || [];
|
|
952
|
+
// 遍历子商品 原价商品符合附加费条件
|
|
953
|
+
var _iterator6 = _createForOfIteratorHelper(arr),
|
|
954
|
+
_step6;
|
|
955
|
+
try {
|
|
956
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
957
|
+
var bundleItem = _step6.value;
|
|
958
|
+
// bundle商品是原价且符合附加费条件
|
|
959
|
+
if (getBundleItemIsOriginalPrice(bundleItem) && isProductMatchSurchargeCondition({
|
|
960
|
+
isCustomItem: false,
|
|
961
|
+
startDate: startDate,
|
|
962
|
+
product_id: bundleItem._bundle_product_id
|
|
963
|
+
}, {
|
|
964
|
+
surchargeConfig: surchargeConfig,
|
|
965
|
+
scheduleById: scheduleById || {},
|
|
966
|
+
isInScheduleByDate: isInScheduleByDate
|
|
967
|
+
})) {
|
|
968
|
+
var _ref12, _bundleItem$bundle_se3;
|
|
969
|
+
var _mainQuantity = item.num || 1;
|
|
970
|
+
matchedItems.push({
|
|
971
|
+
isMain: false,
|
|
972
|
+
total: Number((_ref12 = (_bundleItem$bundle_se3 = bundleItem.bundle_selling_price) !== null && _bundleItem$bundle_se3 !== void 0 ? _bundleItem$bundle_se3 : bundleItem.price) !== null && _ref12 !== void 0 ? _ref12 : 0),
|
|
973
|
+
quantity: bundleItem.num || bundleItem.quantity || 1,
|
|
974
|
+
item: bundleItem,
|
|
975
|
+
mainQuantity: _mainQuantity // 子商品的mainQuantity是所属主商品的quantity
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// 加时商品符合附加费条件
|
|
981
|
+
} catch (err) {
|
|
982
|
+
_iterator6.e(err);
|
|
983
|
+
} finally {
|
|
984
|
+
_iterator6.f();
|
|
985
|
+
}
|
|
986
|
+
var _iterator7 = _createForOfIteratorHelper(item.relation_details || []),
|
|
987
|
+
_step7;
|
|
988
|
+
try {
|
|
989
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
990
|
+
var relationDetail = _step7.value;
|
|
991
|
+
if (isProductMatchSurchargeCondition({
|
|
992
|
+
isCustomItem: false,
|
|
993
|
+
startDate: startDate,
|
|
994
|
+
product_id: relationDetail.product_id
|
|
995
|
+
}, {
|
|
996
|
+
surchargeConfig: surchargeConfig,
|
|
997
|
+
scheduleById: scheduleById || {},
|
|
998
|
+
isInScheduleByDate: isInScheduleByDate
|
|
999
|
+
})) {
|
|
1000
|
+
var _relationDetail$metad;
|
|
1001
|
+
matchedItems.push({
|
|
1002
|
+
isMain: false,
|
|
1003
|
+
total: Number((relationDetail === null || relationDetail === void 0 ? void 0 : relationDetail.price) || (relationDetail === null || relationDetail === void 0 || (_relationDetail$metad = relationDetail.metadata) === null || _relationDetail$metad === void 0 ? void 0 : _relationDetail$metad.main_product_attached_bundle_selling_price)),
|
|
1004
|
+
quantity: relationDetail.num || relationDetail.quantity || 1,
|
|
1005
|
+
item: relationDetail,
|
|
1006
|
+
mainQuantity: 1 // 加时商品不受主商品数量影响
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
} catch (err) {
|
|
1011
|
+
_iterator7.e(err);
|
|
1012
|
+
} finally {
|
|
1013
|
+
_iterator7.f();
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
} catch (err) {
|
|
1017
|
+
_iterator5.e(err);
|
|
1018
|
+
} finally {
|
|
1019
|
+
_iterator5.f();
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// 检查addons中符合条件的商品
|
|
1024
|
+
if (Array.isArray(addons === null || addons === void 0 ? void 0 : addons.value)) {
|
|
1025
|
+
var _iterator8 = _createForOfIteratorHelper(addons.value),
|
|
1026
|
+
_step8;
|
|
1027
|
+
try {
|
|
1028
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
1029
|
+
var _item = _step8.value;
|
|
1030
|
+
if (isProductMatchSurchargeCondition(_objectSpread(_objectSpread({}, _item), {}, {
|
|
1031
|
+
startDate: startDate
|
|
1032
|
+
}), {
|
|
1033
|
+
surchargeConfig: surchargeConfig,
|
|
1034
|
+
scheduleById: scheduleById || {},
|
|
1035
|
+
isInScheduleByDate: isInScheduleByDate
|
|
1036
|
+
})) {
|
|
1037
|
+
matchedItems.push({
|
|
1038
|
+
isMain: true,
|
|
1039
|
+
total: Number(_item.total),
|
|
1040
|
+
quantity: _item.num || 1,
|
|
1041
|
+
item: _item,
|
|
1042
|
+
mainQuantity: 1 // addons独立商品,mainQuantity为1
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
} catch (err) {
|
|
1047
|
+
_iterator8.e(err);
|
|
1048
|
+
} finally {
|
|
1049
|
+
_iterator8.f();
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
var finalAmount = 0;
|
|
1053
|
+
|
|
1054
|
+
// 计算商品总数:主商品和addons按quantity计算,子商品(bundle item)需要乘以主商品数量
|
|
1055
|
+
var productCount = matchedItems.reduce(function (total, item) {
|
|
1056
|
+
if (item.isMain) {
|
|
1057
|
+
// 主商品和addons商品
|
|
1058
|
+
return total + (item.num || item.quantity || 1);
|
|
1059
|
+
} else {
|
|
1060
|
+
// 子商品(bundle item)和加时商品
|
|
1061
|
+
// 加时商品的 mainQuantity = 1,所以不受影响
|
|
1062
|
+
// bundle item 的 mainQuantity = 主商品数量,需要乘以实际数量
|
|
1063
|
+
return total + (item.num || item.quantity || 1) * (item.mainQuantity || 1);
|
|
1064
|
+
}
|
|
1065
|
+
}, 0);
|
|
1066
|
+
|
|
1067
|
+
// 追加进入的固定附加费总值
|
|
1068
|
+
var fixedTotal = new Decimal(0);
|
|
1069
|
+
// 追加到商品的附加费总值 用于追加抹平字段
|
|
1070
|
+
var productTotalSurcharge = new Decimal(0);
|
|
1071
|
+
if (matchedItems.length > 0) {
|
|
1072
|
+
// 基于每个商品计算附加费:max(0, 商品价格) * rate + fixed
|
|
1073
|
+
var configTotal = new Decimal(0);
|
|
1074
|
+
|
|
1075
|
+
// 计算固定附加费 - 只加一次
|
|
1076
|
+
if (fixed && new Decimal(fixed).gt(0)) {
|
|
1077
|
+
configTotal = configTotal.plus(fixed);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
// 计算百分比附加费 - 对每个商品单独计算
|
|
1081
|
+
if (percentage && new Decimal(percentage).gt(0) || fixed) {
|
|
1082
|
+
var percentageRate = new Decimal(percentage);
|
|
1083
|
+
var _iterator9 = _createForOfIteratorHelper(matchedItems.entries()),
|
|
1084
|
+
_step9;
|
|
1085
|
+
try {
|
|
1086
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
1087
|
+
var _step9$value = _slicedToArray(_step9.value, 2),
|
|
1088
|
+
index = _step9$value[0],
|
|
1089
|
+
_item2 = _step9$value[1];
|
|
1090
|
+
var isLast = index === matchedItems.length - 1;
|
|
1091
|
+
// 对每个商品:max(0, 价格) * 数量 * 费率
|
|
1092
|
+
var itemPrice = new Decimal(Math.max(0, _item2.total || 0));
|
|
1093
|
+
var itemQuantity = new Decimal(_item2.isMain ? _item2.quantity || 1 : _item2.quantity * _item2.mainQuantity || 1);
|
|
1094
|
+
var addTimeTotal = new Decimal(_item2.addTimeTotal || 0);
|
|
1095
|
+
// 单个商品总附加费
|
|
1096
|
+
var itemTotalSurcharge = itemPrice.times(itemQuantity).plus(addTimeTotal).times(percentageRate);
|
|
1097
|
+
configTotal = configTotal.plus(itemTotalSurcharge);
|
|
1098
|
+
|
|
1099
|
+
// 单个商品单数量附加费
|
|
1100
|
+
var itemSurcharge = itemPrice.times(percentageRate);
|
|
1101
|
+
|
|
1102
|
+
// 固定附加费 = 1 / 商品数量 * 固定附加费(向下取整保留两位小数)
|
|
1103
|
+
var fixedSurcharge = new Decimal(1).div(productCount).times(fixed).times(100).floor().div(100).toFixed(2);
|
|
1104
|
+
var quantity = _item2.isMain ? _item2.quantity : _item2.quantity * _item2.mainQuantity;
|
|
1105
|
+
fixedTotal = fixedTotal.plus(new Decimal(fixedSurcharge).times(quantity).toNumber());
|
|
1106
|
+
// 如果是最后一个商品 判断fixed - fixedTotal 是否有剩余小数 如果有的话,追加抹平字段
|
|
1107
|
+
if (isLast && fixedTotal.gt(0)) {
|
|
1108
|
+
var remaining = new Decimal(fixed).minus(fixedTotal).toNumber();
|
|
1109
|
+
if (remaining > 0) {
|
|
1110
|
+
productTotalSurcharge = productTotalSurcharge.plus(remaining);
|
|
1111
|
+
if (_item2.isMain) {
|
|
1112
|
+
_item2.item.surcharge_rounding_remainder = remaining;
|
|
1113
|
+
} else {
|
|
1114
|
+
_item2.item.surcharge_rounding_remainder = remaining;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
// 只有当 open_product !== 0 时,才将附加费追加到商品身上
|
|
1119
|
+
// open_product === 0 表示商品未开启该附加费,只在订单级别累加
|
|
1120
|
+
if (open_product !== 0) {
|
|
1121
|
+
if (_item2.isMain) {
|
|
1122
|
+
var _item2$item;
|
|
1123
|
+
var originSurchargeFee = new Decimal(_item2.item.surcharge_fee || 0);
|
|
1124
|
+
// 保留两位小数
|
|
1125
|
+
var surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, Decimal.ROUND_DOWN).toNumber();
|
|
1126
|
+
productTotalSurcharge = productTotalSurcharge.plus(new Decimal(surchargeFee).times(itemQuantity).toNumber());
|
|
1127
|
+
_item2.item.surcharge_fee = surchargeFee;
|
|
1128
|
+
_item2.item.relation_surcharge_ids = [].concat(_toConsumableArray(((_item2$item = _item2.item) === null || _item2$item === void 0 ? void 0 : _item2$item.relation_surcharge_ids) || []), [id]);
|
|
1129
|
+
} else {
|
|
1130
|
+
var _item2$item2;
|
|
1131
|
+
var _originSurchargeFee = new Decimal(_item2.item.surcharge_fee || 0);
|
|
1132
|
+
// 保留两位小数
|
|
1133
|
+
var _surchargeFee = _originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, Decimal.ROUND_DOWN).toNumber();
|
|
1134
|
+
productTotalSurcharge = productTotalSurcharge.plus(new Decimal(_surchargeFee).times(itemQuantity).toNumber());
|
|
1135
|
+
_item2.item.surcharge_fee = _surchargeFee;
|
|
1136
|
+
_item2.item.relation_surcharge_ids = [].concat(_toConsumableArray(((_item2$item2 = _item2.item) === null || _item2$item2 === void 0 ? void 0 : _item2$item2.relation_surcharge_ids) || []), [id]);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
// 最后一个商品 判断configTotal - productTotalSurcharge 是否有剩余小数 如果有的话,追加抹平字段
|
|
1140
|
+
if (isLast && configTotal.minus(productTotalSurcharge).gt(0)) {
|
|
1141
|
+
// 四舍五入configTotal
|
|
1142
|
+
var configTotalRounded = configTotal.toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
|
|
1143
|
+
if (_item2.isMain) {
|
|
1144
|
+
var newRoundingRemainder = new Decimal(_item2.item.surcharge_rounding_remainder || 0);
|
|
1145
|
+
newRoundingRemainder = newRoundingRemainder.plus(configTotalRounded.minus(productTotalSurcharge));
|
|
1146
|
+
_item2.item.surcharge_rounding_remainder = newRoundingRemainder.toNumber();
|
|
1147
|
+
} else {
|
|
1148
|
+
var _newRoundingRemainder = new Decimal(_item2.item.surcharge_rounding_remainder || 0);
|
|
1149
|
+
_newRoundingRemainder = _newRoundingRemainder.plus(configTotalRounded.minus(productTotalSurcharge));
|
|
1150
|
+
_item2.item.surcharge_rounding_remainder = _newRoundingRemainder.toNumber();
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
} catch (err) {
|
|
1155
|
+
_iterator9.e(err);
|
|
1156
|
+
} finally {
|
|
1157
|
+
_iterator9.f();
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
// 如果该配置有金额,则添加到结果中
|
|
1162
|
+
finalAmount = configTotal.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
|
|
1163
|
+
}
|
|
1164
|
+
var name = surchargeConfig.name || {};
|
|
1165
|
+
if (Number(finalAmount) <= 0) {
|
|
1166
|
+
continue;
|
|
1167
|
+
}
|
|
1168
|
+
surchargeWithAmount.push({
|
|
1169
|
+
key: "custom_surcharge_".concat(i),
|
|
1170
|
+
// label: name[state.locale || 'en'] || name['en'] || name['original'],
|
|
1171
|
+
label: name,
|
|
1172
|
+
name: name,
|
|
1173
|
+
value: finalAmount,
|
|
1174
|
+
surcharge_id: id,
|
|
1175
|
+
description: description,
|
|
1176
|
+
// 后端说固定传 default
|
|
1177
|
+
type: 'default',
|
|
1178
|
+
fixed: fixed,
|
|
1179
|
+
amount: finalAmount,
|
|
1180
|
+
percentage: percentage,
|
|
1181
|
+
metadata: {
|
|
1182
|
+
open_product: open_product
|
|
1183
|
+
}
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
return surchargeWithAmount;
|
|
1187
|
+
};
|
|
1188
|
+
function resetItemsSurchargeSideEffects(_ref13) {
|
|
1189
|
+
var service = _ref13.service,
|
|
1190
|
+
addons = _ref13.addons;
|
|
1191
|
+
var resetItem = function resetItem(item) {
|
|
1192
|
+
if (!item) return;
|
|
1193
|
+
item.surcharge_fee = 0;
|
|
1194
|
+
item.surcharge_rounding_remainder = 0;
|
|
1195
|
+
item.relation_surcharge_ids = [];
|
|
1196
|
+
};
|
|
1197
|
+
if (Array.isArray(service)) {
|
|
1198
|
+
var _iterator10 = _createForOfIteratorHelper(service),
|
|
1199
|
+
_step10;
|
|
1200
|
+
try {
|
|
1201
|
+
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
|
1202
|
+
var item = _step10.value;
|
|
1203
|
+
resetItem(item);
|
|
1204
|
+
var arr = (item === null || item === void 0 ? void 0 : item.bundle) || (item === null || item === void 0 ? void 0 : item.bundles) || [];
|
|
1205
|
+
var _iterator11 = _createForOfIteratorHelper(arr),
|
|
1206
|
+
_step11;
|
|
1207
|
+
try {
|
|
1208
|
+
for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
|
|
1209
|
+
var bundleItem = _step11.value;
|
|
1210
|
+
resetItem(bundleItem);
|
|
1211
|
+
}
|
|
1212
|
+
} catch (err) {
|
|
1213
|
+
_iterator11.e(err);
|
|
1214
|
+
} finally {
|
|
1215
|
+
_iterator11.f();
|
|
1216
|
+
}
|
|
1217
|
+
var _iterator12 = _createForOfIteratorHelper((item === null || item === void 0 ? void 0 : item.relation_details) || []),
|
|
1218
|
+
_step12;
|
|
1219
|
+
try {
|
|
1220
|
+
for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
|
|
1221
|
+
var relationDetail = _step12.value;
|
|
1222
|
+
resetItem(relationDetail);
|
|
1223
|
+
}
|
|
1224
|
+
} catch (err) {
|
|
1225
|
+
_iterator12.e(err);
|
|
1226
|
+
} finally {
|
|
1227
|
+
_iterator12.f();
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
} catch (err) {
|
|
1231
|
+
_iterator10.e(err);
|
|
1232
|
+
} finally {
|
|
1233
|
+
_iterator10.f();
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
if (Array.isArray(addons === null || addons === void 0 ? void 0 : addons.value)) {
|
|
1237
|
+
var _iterator13 = _createForOfIteratorHelper(addons.value),
|
|
1238
|
+
_step13;
|
|
1239
|
+
try {
|
|
1240
|
+
for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
|
|
1241
|
+
var _item3 = _step13.value;
|
|
1242
|
+
resetItem(_item3);
|
|
1243
|
+
}
|
|
1244
|
+
} catch (err) {
|
|
1245
|
+
_iterator13.e(err);
|
|
1246
|
+
} finally {
|
|
1247
|
+
_iterator13.f();
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
}
|