@pisell/pisellos 0.0.401 → 0.0.403
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/Product/index.d.ts +1 -1
- package/dist/modules/Summary/index.d.ts +2 -0
- package/dist/modules/Summary/index.js +39 -1
- package/dist/modules/Summary/utils.d.ts +83 -2
- package/dist/modules/Summary/utils.js +93 -31
- package/lib/modules/Product/index.d.ts +1 -1
- package/lib/modules/Summary/index.d.ts +2 -0
- package/lib/modules/Summary/index.js +20 -0
- package/lib/modules/Summary/utils.d.ts +83 -2
- package/lib/modules/Summary/utils.js +230 -4
- package/package.json +1 -1
|
@@ -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
|
}
|
|
@@ -16,7 +16,8 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
|
|
|
16
16
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
17
17
|
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); }
|
|
18
18
|
import { BaseModule } from "../BaseModule";
|
|
19
|
-
import {
|
|
19
|
+
import { ScheduleModule } from "../Schedule";
|
|
20
|
+
import { calculatePriceDetails, getSurcharge, getTax } from "./utils";
|
|
20
21
|
export var SummaryModule = /*#__PURE__*/function (_BaseModule) {
|
|
21
22
|
_inherits(SummaryModule, _BaseModule);
|
|
22
23
|
var _super = _createSuper(SummaryModule);
|
|
@@ -165,6 +166,43 @@ export var SummaryModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
165
166
|
});
|
|
166
167
|
}
|
|
167
168
|
}
|
|
169
|
+
}, {
|
|
170
|
+
key: "getTaxforUtils",
|
|
171
|
+
value: function getTaxforUtils(items, shopInfo, subtotal) {
|
|
172
|
+
return getTax({
|
|
173
|
+
service: items,
|
|
174
|
+
bookingDetail: null,
|
|
175
|
+
bookingId: undefined
|
|
176
|
+
}, {
|
|
177
|
+
computed: {
|
|
178
|
+
productExpectAmount: subtotal.toNumber(),
|
|
179
|
+
shopDiscount: 0
|
|
180
|
+
},
|
|
181
|
+
isEdit: false,
|
|
182
|
+
tax_rate: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.tax_rate,
|
|
183
|
+
is_price_include_tax: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.is_price_include_tax
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}, {
|
|
187
|
+
key: "getSurchargeforUtils",
|
|
188
|
+
value: function getSurchargeforUtils(items) {
|
|
189
|
+
var surchargeList = this.store.surchargeList;
|
|
190
|
+
var surchargeAmount = getSurcharge({
|
|
191
|
+
service: items,
|
|
192
|
+
addons: [],
|
|
193
|
+
bookingDetail: null,
|
|
194
|
+
bookingId: undefined
|
|
195
|
+
}, {
|
|
196
|
+
isEdit: false,
|
|
197
|
+
isInScheduleByDate: ScheduleModule.isInScheduleByDate,
|
|
198
|
+
surcharge_list: surchargeList,
|
|
199
|
+
scheduleById: {}
|
|
200
|
+
});
|
|
201
|
+
return {
|
|
202
|
+
surchargeList: surchargeList,
|
|
203
|
+
surchargeAmount: surchargeAmount
|
|
204
|
+
};
|
|
205
|
+
}
|
|
168
206
|
}]);
|
|
169
207
|
return SummaryModule;
|
|
170
208
|
}(BaseModule);
|
|
@@ -7,6 +7,49 @@ export declare const calculatePriceDetails: (shopInfo: any, items: CartItem[], i
|
|
|
7
7
|
* @param item
|
|
8
8
|
*/
|
|
9
9
|
export declare const getBundleDiscountList: (bundle: any[]) => any[];
|
|
10
|
+
/**
|
|
11
|
+
* 计算订单税费(折扣前/折扣后),并把单品税费信息回写到商品数据上(用于明细展示/后续计算)。
|
|
12
|
+
*
|
|
13
|
+
* - **折扣前税费**:`originTax`
|
|
14
|
+
* - **折扣后税费**:`tax`(会考虑 `computed.shopDiscount` 对每个商品的分摊影响)
|
|
15
|
+
* - **税率/是否含税**:优先取 `bookingDetail.tax_rate` / `bookingDetail.is_price_include_tax`,取不到再回退到 `options.tax_rate` / `options.is_price_include_tax`
|
|
16
|
+
*
|
|
17
|
+
* **副作用(会修改入参商品对象)**:
|
|
18
|
+
* - 主商品:写入 `item.original_tax_fee` / `item.tax_fee`(四舍五入保留两位)
|
|
19
|
+
* - bundle 原价子商品:写入 `bundleItem.original_tax_fee` / `bundleItem.tax_fee`
|
|
20
|
+
* - 加时商品(`relation_details`):写入 `atItem.tax_fee`
|
|
21
|
+
* - 税费舍入差值:追加到最后一个“含税商品”的 `tax_fee_rounding_remainder` / `original_tax_fee_rounding_remainder`
|
|
22
|
+
*
|
|
23
|
+
* @param params 入参集合(RORO)
|
|
24
|
+
* @param params.service 服务商品数组(主商品)。通常是购物车商品结构(可能包含 `bundle` / `relation_details`)
|
|
25
|
+
* @param params.addons 附加商品数组(可选)。结构同商品数组
|
|
26
|
+
* @param params.bookingDetail 订单详情(编辑/详情场景用于读取后端税率配置),可选
|
|
27
|
+
* @param params.bookingId 订单/预约 ID(编辑/详情场景识别用),可选
|
|
28
|
+
* @param options 计算选项
|
|
29
|
+
* @param options.isEdit 是否处于“编辑中”。当前实现不强依赖该值(历史逻辑保留),但建议按真实状态传入
|
|
30
|
+
* @param options.computed 预计算结果(用于折扣分摊)
|
|
31
|
+
* @param options.computed.productExpectAmount 商品期望总金额(用于按比例分摊折扣)
|
|
32
|
+
* @param options.computed.shopDiscount 店铺折扣总额(用于按比例分摊到商品)
|
|
33
|
+
* @param options.tax_rate 管理端税率(百分比,如 5 表示 5%)。仅当 `bookingDetail.tax_rate` 不存在时生效
|
|
34
|
+
* @param options.is_price_include_tax 是否含税:`0` 不含税、`1` 含税。仅当 `bookingDetail.is_price_include_tax` 不存在时生效
|
|
35
|
+
* @returns 税费汇总(number,金额单位与商品价格一致,四舍五入保留两位)
|
|
36
|
+
* @returns.originTax 折扣前税费合计
|
|
37
|
+
* @returns.tax 折扣后税费合计
|
|
38
|
+
*/
|
|
39
|
+
export declare const getTax: ({ service, addons, bookingDetail, bookingId }: {
|
|
40
|
+
service?: any;
|
|
41
|
+
addons?: any;
|
|
42
|
+
bookingDetail?: any;
|
|
43
|
+
bookingId?: number | undefined;
|
|
44
|
+
}, options: {
|
|
45
|
+
isEdit: boolean;
|
|
46
|
+
computed: Record<string, number>;
|
|
47
|
+
tax_rate?: number;
|
|
48
|
+
is_price_include_tax?: number;
|
|
49
|
+
} & Record<string, any>) => {
|
|
50
|
+
originTax: number;
|
|
51
|
+
tax: number;
|
|
52
|
+
};
|
|
10
53
|
/**
|
|
11
54
|
* 计算商品小计(不含其他费用)
|
|
12
55
|
* @param items - 购物车商品数组
|
|
@@ -38,14 +81,52 @@ export declare const calculateDeposit: (items: CartItem[]) => {
|
|
|
38
81
|
protocols: any[];
|
|
39
82
|
hasDeposit: never;
|
|
40
83
|
} | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* 计算订单附加费金额(订单级别合计)。
|
|
86
|
+
*
|
|
87
|
+
* - **详情未编辑**(`!options.isEdit && bookingId`)且存在后端详情时:直接返回 `bookingDetail.surcharge_fee`
|
|
88
|
+
* - **新增/编辑**时:对 `surcharge`(通常为 `getSurcharge` 的返回值)按 `item.value` 求和
|
|
89
|
+
*
|
|
90
|
+
* @param params 入参集合(RORO)
|
|
91
|
+
* @param params.bookingDetail 订单详情(详情未编辑时用于读取后端的 `surcharge_fee`),可选
|
|
92
|
+
* @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
|
|
93
|
+
* @param surcharge 附加费列表(通常来自 `getSurcharge`),元素结构至少包含 `value: number`
|
|
94
|
+
* @param options 计算选项
|
|
95
|
+
* @param options.isEdit 是否处于“编辑中”。`false` 时会优先走后端金额直取逻辑(若存在)
|
|
96
|
+
* @returns 订单附加费金额(number,金额单位与商品价格一致)
|
|
97
|
+
*/
|
|
41
98
|
export declare const getSurchargeAmount: ({ bookingDetail, bookingId }: {
|
|
42
99
|
bookingDetail?: any;
|
|
43
100
|
bookingId?: number | undefined;
|
|
44
101
|
}, surcharge: any[], options: any) => any;
|
|
45
102
|
/**
|
|
46
103
|
* 订单附加费各项信息
|
|
47
|
-
*
|
|
48
|
-
*
|
|
104
|
+
*
|
|
105
|
+
* - **详情未编辑**(`!options.isEdit && bookingId`)时:直接返回 `bookingDetail.surcharge`(后端计算结果)
|
|
106
|
+
* - **新增/编辑**时:按 `options.surcharge_list` 逐条配置计算本次订单的附加费
|
|
107
|
+
*
|
|
108
|
+
* 规则要点:
|
|
109
|
+
* - 匹配范围包含:主商品(`service`)、原价 bundle 子商品(`item.bundle`)、加时商品(`item.relation_details`)、以及 addons(`addons.value`)
|
|
110
|
+
* - 固定附加费 `fixed`:只加一次,再按商品数量分摊(向下取整保留两位),剩余小数会以 `surcharge_rounding_remainder` 形式抹平到最后一个商品
|
|
111
|
+
* - 百分比附加费 `percentage`:按每个商品(价格 * 数量)分别计算再累加
|
|
112
|
+
* - 当 `open_product === 0`:不回写到商品,只在订单级别累加;否则会把单品附加费回写到商品
|
|
113
|
+
*
|
|
114
|
+
* **副作用(可能修改入参商品对象)**:
|
|
115
|
+
* - 当 `open_product !== 0` 时:写入 `item.surcharge_fee`(单品单数量附加费,保留两位、向下取整)
|
|
116
|
+
* - 写入 `item.relation_surcharge_ids`(关联到的 surcharge 配置 id 列表)
|
|
117
|
+
* - 写入 `item.surcharge_rounding_remainder`(用于抹平固定附加费/总额舍入差)
|
|
118
|
+
*
|
|
119
|
+
* @param params 入参集合(RORO)
|
|
120
|
+
* @param params.service 服务商品数组(主商品)。元素可能包含 `bundle` / `relation_details`
|
|
121
|
+
* @param params.addons 附加商品容器。当前实现读取 `addons.value` 作为商品数组(所以通常传 `{ value: CartItem[] }`)
|
|
122
|
+
* @param params.bookingDetail 订单详情(详情未编辑时用于直接取后端的 surcharge 列表),可选
|
|
123
|
+
* @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
|
|
124
|
+
* @param options 计算选项
|
|
125
|
+
* @param options.isEdit 是否处于“编辑中”。`false` 且存在 `bookingId` 时会走详情直取逻辑
|
|
126
|
+
* @param options.surcharge_list 附加费配置列表(后端下发)。缺失/为空则返回空数组
|
|
127
|
+
* @param options.isInScheduleByDate 判断日期是否落在某个 schedule 内的方法(通常来自 ScheduleModule)
|
|
128
|
+
* @param options.scheduleById schedule 映射表:`{ [scheduleId]: schedule }`(用于根据配置的 `available_schedule_ids` 做日程匹配)
|
|
129
|
+
* @returns 附加费列表(仅返回金额 > 0 的项)
|
|
49
130
|
*/
|
|
50
131
|
export declare const getSurcharge: ({ service, addons, bookingDetail, bookingId }: {
|
|
51
132
|
service: any;
|
|
@@ -20,14 +20,6 @@ export var calculatePriceDetails = function calculatePriceDetails(shopInfo, item
|
|
|
20
20
|
var subtotal = new Decimal(calculateSubtotal(items));
|
|
21
21
|
var subOriginTotal = new Decimal(calculateOriginSubtotal(items));
|
|
22
22
|
var totalTaxFee = new Decimal(calculateTaxFee(shopInfo, items));
|
|
23
|
-
// 税费
|
|
24
|
-
// const { tax, originTax } = getTax({ service: items, bookingDetail: null, bookingId: undefined }, {
|
|
25
|
-
// computed: {
|
|
26
|
-
// productExpectAmount: subtotal.toNumber(),
|
|
27
|
-
// shopDiscount: 0,
|
|
28
|
-
// },
|
|
29
|
-
// isEdit: false,
|
|
30
|
-
// });
|
|
31
23
|
// 订单附加费列表
|
|
32
24
|
var surcharge = getSurcharge({
|
|
33
25
|
service: items,
|
|
@@ -47,9 +39,23 @@ export var calculatePriceDetails = function calculatePriceDetails(shopInfo, item
|
|
|
47
39
|
}, surcharge, {
|
|
48
40
|
isEdit: false
|
|
49
41
|
}));
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
42
|
+
// 税费
|
|
43
|
+
var _getTax = getTax({
|
|
44
|
+
service: items,
|
|
45
|
+
bookingDetail: null,
|
|
46
|
+
bookingId: undefined
|
|
47
|
+
}, {
|
|
48
|
+
computed: {
|
|
49
|
+
productExpectAmount: subtotal.toNumber(),
|
|
50
|
+
shopDiscount: 0
|
|
51
|
+
},
|
|
52
|
+
isEdit: false,
|
|
53
|
+
tax_rate: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.tax_rate,
|
|
54
|
+
is_price_include_tax: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.is_price_include_tax
|
|
55
|
+
}),
|
|
56
|
+
tax = _getTax.tax,
|
|
57
|
+
originTax = _getTax.originTax;
|
|
58
|
+
var total = shopInfo !== null && shopInfo !== void 0 && shopInfo.is_price_include_tax ? subtotal.plus(surchargeAmount) : subtotal.plus(totalTaxFee).plus(surchargeAmount);
|
|
53
59
|
|
|
54
60
|
// 计算总价 不包含折扣卡商品券折扣信息价格
|
|
55
61
|
var originTotal = shopInfo !== null && shopInfo !== void 0 && shopInfo.is_price_include_tax ? subOriginTotal : subOriginTotal.plus(totalTaxFee);
|
|
@@ -62,7 +68,7 @@ export var calculatePriceDetails = function calculatePriceDetails(shopInfo, item
|
|
|
62
68
|
originTotal: originTotal.toFixed(2),
|
|
63
69
|
taxTitle: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.tax_title,
|
|
64
70
|
taxRate: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.tax_rate,
|
|
65
|
-
totalTaxFee:
|
|
71
|
+
totalTaxFee: tax,
|
|
66
72
|
isPriceIncludeTax: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.is_price_include_tax,
|
|
67
73
|
surcharge: surcharge,
|
|
68
74
|
surchargeAmount: surchargeAmount.toFixed(2),
|
|
@@ -99,12 +105,35 @@ var getProductDiscountProductDiscountDifference = function getProductDiscountPro
|
|
|
99
105
|
};
|
|
100
106
|
|
|
101
107
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
108
|
+
* 计算订单税费(折扣前/折扣后),并把单品税费信息回写到商品数据上(用于明细展示/后续计算)。
|
|
109
|
+
*
|
|
110
|
+
* - **折扣前税费**:`originTax`
|
|
111
|
+
* - **折扣后税费**:`tax`(会考虑 `computed.shopDiscount` 对每个商品的分摊影响)
|
|
112
|
+
* - **税率/是否含税**:优先取 `bookingDetail.tax_rate` / `bookingDetail.is_price_include_tax`,取不到再回退到 `options.tax_rate` / `options.is_price_include_tax`
|
|
113
|
+
*
|
|
114
|
+
* **副作用(会修改入参商品对象)**:
|
|
115
|
+
* - 主商品:写入 `item.original_tax_fee` / `item.tax_fee`(四舍五入保留两位)
|
|
116
|
+
* - bundle 原价子商品:写入 `bundleItem.original_tax_fee` / `bundleItem.tax_fee`
|
|
117
|
+
* - 加时商品(`relation_details`):写入 `atItem.tax_fee`
|
|
118
|
+
* - 税费舍入差值:追加到最后一个“含税商品”的 `tax_fee_rounding_remainder` / `original_tax_fee_rounding_remainder`
|
|
119
|
+
*
|
|
120
|
+
* @param params 入参集合(RORO)
|
|
121
|
+
* @param params.service 服务商品数组(主商品)。通常是购物车商品结构(可能包含 `bundle` / `relation_details`)
|
|
122
|
+
* @param params.addons 附加商品数组(可选)。结构同商品数组
|
|
123
|
+
* @param params.bookingDetail 订单详情(编辑/详情场景用于读取后端税率配置),可选
|
|
124
|
+
* @param params.bookingId 订单/预约 ID(编辑/详情场景识别用),可选
|
|
125
|
+
* @param options 计算选项
|
|
126
|
+
* @param options.isEdit 是否处于“编辑中”。当前实现不强依赖该值(历史逻辑保留),但建议按真实状态传入
|
|
127
|
+
* @param options.computed 预计算结果(用于折扣分摊)
|
|
128
|
+
* @param options.computed.productExpectAmount 商品期望总金额(用于按比例分摊折扣)
|
|
129
|
+
* @param options.computed.shopDiscount 店铺折扣总额(用于按比例分摊到商品)
|
|
130
|
+
* @param options.tax_rate 管理端税率(百分比,如 5 表示 5%)。仅当 `bookingDetail.tax_rate` 不存在时生效
|
|
131
|
+
* @param options.is_price_include_tax 是否含税:`0` 不含税、`1` 含税。仅当 `bookingDetail.is_price_include_tax` 不存在时生效
|
|
132
|
+
* @returns 税费汇总(number,金额单位与商品价格一致,四舍五入保留两位)
|
|
133
|
+
* @returns.originTax 折扣前税费合计
|
|
134
|
+
* @returns.tax 折扣后税费合计
|
|
106
135
|
*/
|
|
107
|
-
var getTax = function getTax(_ref, options) {
|
|
136
|
+
export var getTax = function getTax(_ref, options) {
|
|
108
137
|
var service = _ref.service,
|
|
109
138
|
addons = _ref.addons,
|
|
110
139
|
bookingDetail = _ref.bookingDetail,
|
|
@@ -115,11 +144,10 @@ var getTax = function getTax(_ref, options) {
|
|
|
115
144
|
is_price_include_tax = options.is_price_include_tax;
|
|
116
145
|
|
|
117
146
|
// 详情时未编辑的状态下, 取后端的值
|
|
118
|
-
if (!isEdit) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
147
|
+
// if (!isEdit) {
|
|
148
|
+
// return { tax: Number(bookingDetail?.tax_fee) || 0 };
|
|
149
|
+
// }
|
|
150
|
+
|
|
123
151
|
var totalOriginTax = new Decimal(0);
|
|
124
152
|
var totalTax = new Decimal(0);
|
|
125
153
|
if (service || addons) {
|
|
@@ -191,7 +219,6 @@ var processItemsTax = function processItemsTax(items, _ref2, options) {
|
|
|
191
219
|
_step;
|
|
192
220
|
try {
|
|
193
221
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
194
|
-
var _item$_extend$other;
|
|
195
222
|
var item = _step.value;
|
|
196
223
|
var quantity = new Decimal(item.num || 1);
|
|
197
224
|
var unitPrice = new Decimal(item.total || 0);
|
|
@@ -301,8 +328,8 @@ var processItemsTax = function processItemsTax(items, _ref2, options) {
|
|
|
301
328
|
var bundlePreciseTax = new Decimal(0);
|
|
302
329
|
var bundleRoundedOriginTax = new Decimal(0);
|
|
303
330
|
var bundleRoundedTax = new Decimal(0);
|
|
304
|
-
if (Array.isArray(
|
|
305
|
-
var _iterator3 = _createForOfIteratorHelper(item.
|
|
331
|
+
if (Array.isArray(item === null || item === void 0 ? void 0 : item.bundle)) {
|
|
332
|
+
var _iterator3 = _createForOfIteratorHelper(item === null || item === void 0 ? void 0 : item.bundle),
|
|
306
333
|
_step3;
|
|
307
334
|
try {
|
|
308
335
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
@@ -375,7 +402,6 @@ var processItemsTax = function processItemsTax(items, _ref2, options) {
|
|
|
375
402
|
_iterator3.f();
|
|
376
403
|
}
|
|
377
404
|
}
|
|
378
|
-
|
|
379
405
|
// 主商品的原始税费和折后税费(精确值)
|
|
380
406
|
var originalTaxFeePrecise = originalTaxPerItemPrecise.plus(bundlePreciseOriginTax);
|
|
381
407
|
var taxFeePrecise = maxDiscountedTaxPerItemPrecise.plus(bundlePreciseTax);
|
|
@@ -419,7 +445,7 @@ var processItemsTax = function processItemsTax(items, _ref2, options) {
|
|
|
419
445
|
}
|
|
420
446
|
if (taxRemainder !== 0) {
|
|
421
447
|
if (lastTaxableItem.type === 'main') {
|
|
422
|
-
lastTaxableItem.item.
|
|
448
|
+
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
|
|
423
449
|
} else {
|
|
424
450
|
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
|
|
425
451
|
}
|
|
@@ -582,7 +608,20 @@ export var calculateDeposit = function calculateDeposit(items) {
|
|
|
582
608
|
return undefined;
|
|
583
609
|
};
|
|
584
610
|
|
|
585
|
-
|
|
611
|
+
/**
|
|
612
|
+
* 计算订单附加费金额(订单级别合计)。
|
|
613
|
+
*
|
|
614
|
+
* - **详情未编辑**(`!options.isEdit && bookingId`)且存在后端详情时:直接返回 `bookingDetail.surcharge_fee`
|
|
615
|
+
* - **新增/编辑**时:对 `surcharge`(通常为 `getSurcharge` 的返回值)按 `item.value` 求和
|
|
616
|
+
*
|
|
617
|
+
* @param params 入参集合(RORO)
|
|
618
|
+
* @param params.bookingDetail 订单详情(详情未编辑时用于读取后端的 `surcharge_fee`),可选
|
|
619
|
+
* @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
|
|
620
|
+
* @param surcharge 附加费列表(通常来自 `getSurcharge`),元素结构至少包含 `value: number`
|
|
621
|
+
* @param options 计算选项
|
|
622
|
+
* @param options.isEdit 是否处于“编辑中”。`false` 时会优先走后端金额直取逻辑(若存在)
|
|
623
|
+
* @returns 订单附加费金额(number,金额单位与商品价格一致)
|
|
624
|
+
*/
|
|
586
625
|
export var getSurchargeAmount = function getSurchargeAmount(_ref6, surcharge, options) {
|
|
587
626
|
var bookingDetail = _ref6.bookingDetail,
|
|
588
627
|
bookingId = _ref6.bookingId;
|
|
@@ -745,8 +784,32 @@ var isProductMatchSurchargeCondition = function isProductMatchSurchargeCondition
|
|
|
745
784
|
|
|
746
785
|
/**
|
|
747
786
|
* 订单附加费各项信息
|
|
748
|
-
*
|
|
749
|
-
*
|
|
787
|
+
*
|
|
788
|
+
* - **详情未编辑**(`!options.isEdit && bookingId`)时:直接返回 `bookingDetail.surcharge`(后端计算结果)
|
|
789
|
+
* - **新增/编辑**时:按 `options.surcharge_list` 逐条配置计算本次订单的附加费
|
|
790
|
+
*
|
|
791
|
+
* 规则要点:
|
|
792
|
+
* - 匹配范围包含:主商品(`service`)、原价 bundle 子商品(`item.bundle`)、加时商品(`item.relation_details`)、以及 addons(`addons.value`)
|
|
793
|
+
* - 固定附加费 `fixed`:只加一次,再按商品数量分摊(向下取整保留两位),剩余小数会以 `surcharge_rounding_remainder` 形式抹平到最后一个商品
|
|
794
|
+
* - 百分比附加费 `percentage`:按每个商品(价格 * 数量)分别计算再累加
|
|
795
|
+
* - 当 `open_product === 0`:不回写到商品,只在订单级别累加;否则会把单品附加费回写到商品
|
|
796
|
+
*
|
|
797
|
+
* **副作用(可能修改入参商品对象)**:
|
|
798
|
+
* - 当 `open_product !== 0` 时:写入 `item.surcharge_fee`(单品单数量附加费,保留两位、向下取整)
|
|
799
|
+
* - 写入 `item.relation_surcharge_ids`(关联到的 surcharge 配置 id 列表)
|
|
800
|
+
* - 写入 `item.surcharge_rounding_remainder`(用于抹平固定附加费/总额舍入差)
|
|
801
|
+
*
|
|
802
|
+
* @param params 入参集合(RORO)
|
|
803
|
+
* @param params.service 服务商品数组(主商品)。元素可能包含 `bundle` / `relation_details`
|
|
804
|
+
* @param params.addons 附加商品容器。当前实现读取 `addons.value` 作为商品数组(所以通常传 `{ value: CartItem[] }`)
|
|
805
|
+
* @param params.bookingDetail 订单详情(详情未编辑时用于直接取后端的 surcharge 列表),可选
|
|
806
|
+
* @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
|
|
807
|
+
* @param options 计算选项
|
|
808
|
+
* @param options.isEdit 是否处于“编辑中”。`false` 且存在 `bookingId` 时会走详情直取逻辑
|
|
809
|
+
* @param options.surcharge_list 附加费配置列表(后端下发)。缺失/为空则返回空数组
|
|
810
|
+
* @param options.isInScheduleByDate 判断日期是否落在某个 schedule 内的方法(通常来自 ScheduleModule)
|
|
811
|
+
* @param options.scheduleById schedule 映射表:`{ [scheduleId]: schedule }`(用于根据配置的 `available_schedule_ids` 做日程匹配)
|
|
812
|
+
* @returns 附加费列表(仅返回金额 > 0 的项)
|
|
750
813
|
*/
|
|
751
814
|
export var getSurcharge = function getSurcharge(_ref10, options) {
|
|
752
815
|
var service = _ref10.service,
|
|
@@ -988,7 +1051,6 @@ export var getSurcharge = function getSurcharge(_ref10, options) {
|
|
|
988
1051
|
var fixedSurcharge = new Decimal(1).div(productCount).times(fixed).times(100).floor().div(100).toFixed(2);
|
|
989
1052
|
var quantity = _item2.isMain ? _item2.quantity : _item2.quantity * _item2.mainQuantity;
|
|
990
1053
|
fixedTotal = fixedTotal.plus(new Decimal(fixedSurcharge).times(quantity).toNumber());
|
|
991
|
-
|
|
992
1054
|
// 如果是最后一个商品 判断fixed - fixedTotal 是否有剩余小数 如果有的话,追加抹平字段
|
|
993
1055
|
if (isLast && fixedTotal.gt(0)) {
|
|
994
1056
|
var remaining = new Decimal(fixed).minus(fixedTotal).toNumber();
|
|
@@ -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
|
}
|
|
@@ -23,6 +23,7 @@ __export(Summary_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(Summary_exports);
|
|
25
25
|
var import_BaseModule = require("../BaseModule");
|
|
26
|
+
var import_Schedule = require("../Schedule");
|
|
26
27
|
var import_utils = require("./utils");
|
|
27
28
|
var SummaryModule = class extends import_BaseModule.BaseModule {
|
|
28
29
|
constructor(name, version) {
|
|
@@ -87,6 +88,25 @@ var SummaryModule = class extends import_BaseModule.BaseModule {
|
|
|
87
88
|
});
|
|
88
89
|
}
|
|
89
90
|
}
|
|
91
|
+
getTaxforUtils(items, shopInfo, subtotal) {
|
|
92
|
+
return (0, import_utils.getTax)({ service: items, bookingDetail: null, bookingId: void 0 }, {
|
|
93
|
+
computed: {
|
|
94
|
+
productExpectAmount: subtotal.toNumber(),
|
|
95
|
+
shopDiscount: 0
|
|
96
|
+
},
|
|
97
|
+
isEdit: false,
|
|
98
|
+
tax_rate: shopInfo == null ? void 0 : shopInfo.tax_rate,
|
|
99
|
+
is_price_include_tax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
getSurchargeforUtils(items) {
|
|
103
|
+
const surchargeList = this.store.surchargeList;
|
|
104
|
+
const surchargeAmount = (0, import_utils.getSurcharge)({ service: items, addons: [], bookingDetail: null, bookingId: void 0 }, { isEdit: false, isInScheduleByDate: import_Schedule.ScheduleModule.isInScheduleByDate, surcharge_list: surchargeList, scheduleById: {} });
|
|
105
|
+
return {
|
|
106
|
+
surchargeList,
|
|
107
|
+
surchargeAmount
|
|
108
|
+
};
|
|
109
|
+
}
|
|
90
110
|
};
|
|
91
111
|
// Annotate the CommonJS export names for ESM import in node:
|
|
92
112
|
0 && (module.exports = {
|
|
@@ -7,6 +7,49 @@ export declare const calculatePriceDetails: (shopInfo: any, items: CartItem[], i
|
|
|
7
7
|
* @param item
|
|
8
8
|
*/
|
|
9
9
|
export declare const getBundleDiscountList: (bundle: any[]) => any[];
|
|
10
|
+
/**
|
|
11
|
+
* 计算订单税费(折扣前/折扣后),并把单品税费信息回写到商品数据上(用于明细展示/后续计算)。
|
|
12
|
+
*
|
|
13
|
+
* - **折扣前税费**:`originTax`
|
|
14
|
+
* - **折扣后税费**:`tax`(会考虑 `computed.shopDiscount` 对每个商品的分摊影响)
|
|
15
|
+
* - **税率/是否含税**:优先取 `bookingDetail.tax_rate` / `bookingDetail.is_price_include_tax`,取不到再回退到 `options.tax_rate` / `options.is_price_include_tax`
|
|
16
|
+
*
|
|
17
|
+
* **副作用(会修改入参商品对象)**:
|
|
18
|
+
* - 主商品:写入 `item.original_tax_fee` / `item.tax_fee`(四舍五入保留两位)
|
|
19
|
+
* - bundle 原价子商品:写入 `bundleItem.original_tax_fee` / `bundleItem.tax_fee`
|
|
20
|
+
* - 加时商品(`relation_details`):写入 `atItem.tax_fee`
|
|
21
|
+
* - 税费舍入差值:追加到最后一个“含税商品”的 `tax_fee_rounding_remainder` / `original_tax_fee_rounding_remainder`
|
|
22
|
+
*
|
|
23
|
+
* @param params 入参集合(RORO)
|
|
24
|
+
* @param params.service 服务商品数组(主商品)。通常是购物车商品结构(可能包含 `bundle` / `relation_details`)
|
|
25
|
+
* @param params.addons 附加商品数组(可选)。结构同商品数组
|
|
26
|
+
* @param params.bookingDetail 订单详情(编辑/详情场景用于读取后端税率配置),可选
|
|
27
|
+
* @param params.bookingId 订单/预约 ID(编辑/详情场景识别用),可选
|
|
28
|
+
* @param options 计算选项
|
|
29
|
+
* @param options.isEdit 是否处于“编辑中”。当前实现不强依赖该值(历史逻辑保留),但建议按真实状态传入
|
|
30
|
+
* @param options.computed 预计算结果(用于折扣分摊)
|
|
31
|
+
* @param options.computed.productExpectAmount 商品期望总金额(用于按比例分摊折扣)
|
|
32
|
+
* @param options.computed.shopDiscount 店铺折扣总额(用于按比例分摊到商品)
|
|
33
|
+
* @param options.tax_rate 管理端税率(百分比,如 5 表示 5%)。仅当 `bookingDetail.tax_rate` 不存在时生效
|
|
34
|
+
* @param options.is_price_include_tax 是否含税:`0` 不含税、`1` 含税。仅当 `bookingDetail.is_price_include_tax` 不存在时生效
|
|
35
|
+
* @returns 税费汇总(number,金额单位与商品价格一致,四舍五入保留两位)
|
|
36
|
+
* @returns.originTax 折扣前税费合计
|
|
37
|
+
* @returns.tax 折扣后税费合计
|
|
38
|
+
*/
|
|
39
|
+
export declare const getTax: ({ service, addons, bookingDetail, bookingId }: {
|
|
40
|
+
service?: any;
|
|
41
|
+
addons?: any;
|
|
42
|
+
bookingDetail?: any;
|
|
43
|
+
bookingId?: number | undefined;
|
|
44
|
+
}, options: {
|
|
45
|
+
isEdit: boolean;
|
|
46
|
+
computed: Record<string, number>;
|
|
47
|
+
tax_rate?: number;
|
|
48
|
+
is_price_include_tax?: number;
|
|
49
|
+
} & Record<string, any>) => {
|
|
50
|
+
originTax: number;
|
|
51
|
+
tax: number;
|
|
52
|
+
};
|
|
10
53
|
/**
|
|
11
54
|
* 计算商品小计(不含其他费用)
|
|
12
55
|
* @param items - 购物车商品数组
|
|
@@ -38,14 +81,52 @@ export declare const calculateDeposit: (items: CartItem[]) => {
|
|
|
38
81
|
protocols: any[];
|
|
39
82
|
hasDeposit: never;
|
|
40
83
|
} | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* 计算订单附加费金额(订单级别合计)。
|
|
86
|
+
*
|
|
87
|
+
* - **详情未编辑**(`!options.isEdit && bookingId`)且存在后端详情时:直接返回 `bookingDetail.surcharge_fee`
|
|
88
|
+
* - **新增/编辑**时:对 `surcharge`(通常为 `getSurcharge` 的返回值)按 `item.value` 求和
|
|
89
|
+
*
|
|
90
|
+
* @param params 入参集合(RORO)
|
|
91
|
+
* @param params.bookingDetail 订单详情(详情未编辑时用于读取后端的 `surcharge_fee`),可选
|
|
92
|
+
* @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
|
|
93
|
+
* @param surcharge 附加费列表(通常来自 `getSurcharge`),元素结构至少包含 `value: number`
|
|
94
|
+
* @param options 计算选项
|
|
95
|
+
* @param options.isEdit 是否处于“编辑中”。`false` 时会优先走后端金额直取逻辑(若存在)
|
|
96
|
+
* @returns 订单附加费金额(number,金额单位与商品价格一致)
|
|
97
|
+
*/
|
|
41
98
|
export declare const getSurchargeAmount: ({ bookingDetail, bookingId }: {
|
|
42
99
|
bookingDetail?: any;
|
|
43
100
|
bookingId?: number | undefined;
|
|
44
101
|
}, surcharge: any[], options: any) => any;
|
|
45
102
|
/**
|
|
46
103
|
* 订单附加费各项信息
|
|
47
|
-
*
|
|
48
|
-
*
|
|
104
|
+
*
|
|
105
|
+
* - **详情未编辑**(`!options.isEdit && bookingId`)时:直接返回 `bookingDetail.surcharge`(后端计算结果)
|
|
106
|
+
* - **新增/编辑**时:按 `options.surcharge_list` 逐条配置计算本次订单的附加费
|
|
107
|
+
*
|
|
108
|
+
* 规则要点:
|
|
109
|
+
* - 匹配范围包含:主商品(`service`)、原价 bundle 子商品(`item.bundle`)、加时商品(`item.relation_details`)、以及 addons(`addons.value`)
|
|
110
|
+
* - 固定附加费 `fixed`:只加一次,再按商品数量分摊(向下取整保留两位),剩余小数会以 `surcharge_rounding_remainder` 形式抹平到最后一个商品
|
|
111
|
+
* - 百分比附加费 `percentage`:按每个商品(价格 * 数量)分别计算再累加
|
|
112
|
+
* - 当 `open_product === 0`:不回写到商品,只在订单级别累加;否则会把单品附加费回写到商品
|
|
113
|
+
*
|
|
114
|
+
* **副作用(可能修改入参商品对象)**:
|
|
115
|
+
* - 当 `open_product !== 0` 时:写入 `item.surcharge_fee`(单品单数量附加费,保留两位、向下取整)
|
|
116
|
+
* - 写入 `item.relation_surcharge_ids`(关联到的 surcharge 配置 id 列表)
|
|
117
|
+
* - 写入 `item.surcharge_rounding_remainder`(用于抹平固定附加费/总额舍入差)
|
|
118
|
+
*
|
|
119
|
+
* @param params 入参集合(RORO)
|
|
120
|
+
* @param params.service 服务商品数组(主商品)。元素可能包含 `bundle` / `relation_details`
|
|
121
|
+
* @param params.addons 附加商品容器。当前实现读取 `addons.value` 作为商品数组(所以通常传 `{ value: CartItem[] }`)
|
|
122
|
+
* @param params.bookingDetail 订单详情(详情未编辑时用于直接取后端的 surcharge 列表),可选
|
|
123
|
+
* @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
|
|
124
|
+
* @param options 计算选项
|
|
125
|
+
* @param options.isEdit 是否处于“编辑中”。`false` 且存在 `bookingId` 时会走详情直取逻辑
|
|
126
|
+
* @param options.surcharge_list 附加费配置列表(后端下发)。缺失/为空则返回空数组
|
|
127
|
+
* @param options.isInScheduleByDate 判断日期是否落在某个 schedule 内的方法(通常来自 ScheduleModule)
|
|
128
|
+
* @param options.scheduleById schedule 映射表:`{ [scheduleId]: schedule }`(用于根据配置的 `available_schedule_ids` 做日程匹配)
|
|
129
|
+
* @returns 附加费列表(仅返回金额 > 0 的项)
|
|
49
130
|
*/
|
|
50
131
|
export declare const getSurcharge: ({ service, addons, bookingDetail, bookingId }: {
|
|
51
132
|
service: any;
|
|
@@ -36,7 +36,8 @@ __export(utils_exports, {
|
|
|
36
36
|
calculateTaxFee: () => calculateTaxFee,
|
|
37
37
|
getBundleDiscountList: () => getBundleDiscountList,
|
|
38
38
|
getSurcharge: () => getSurcharge,
|
|
39
|
-
getSurchargeAmount: () => getSurchargeAmount
|
|
39
|
+
getSurchargeAmount: () => getSurchargeAmount,
|
|
40
|
+
getTax: () => getTax
|
|
40
41
|
});
|
|
41
42
|
module.exports = __toCommonJS(utils_exports);
|
|
42
43
|
var import_decimal = __toESM(require("decimal.js"));
|
|
@@ -46,7 +47,16 @@ var calculatePriceDetails = (shopInfo, items, isInScheduleByDate, surchargeList)
|
|
|
46
47
|
const totalTaxFee = new import_decimal.default(calculateTaxFee(shopInfo, items));
|
|
47
48
|
const surcharge = getSurcharge({ service: items, addons: [], bookingDetail: null, bookingId: void 0 }, { isEdit: false, isInScheduleByDate, surcharge_list: surchargeList, scheduleById: {} });
|
|
48
49
|
const surchargeAmount = new import_decimal.default(getSurchargeAmount({ bookingDetail: null, bookingId: void 0 }, surcharge, { isEdit: false }));
|
|
49
|
-
const
|
|
50
|
+
const { tax, originTax } = getTax({ service: items, bookingDetail: null, bookingId: void 0 }, {
|
|
51
|
+
computed: {
|
|
52
|
+
productExpectAmount: subtotal.toNumber(),
|
|
53
|
+
shopDiscount: 0
|
|
54
|
+
},
|
|
55
|
+
isEdit: false,
|
|
56
|
+
tax_rate: shopInfo == null ? void 0 : shopInfo.tax_rate,
|
|
57
|
+
is_price_include_tax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax
|
|
58
|
+
});
|
|
59
|
+
const total = (shopInfo == null ? void 0 : shopInfo.is_price_include_tax) ? subtotal.plus(surchargeAmount) : subtotal.plus(totalTaxFee).plus(surchargeAmount);
|
|
50
60
|
const originTotal = (shopInfo == null ? void 0 : shopInfo.is_price_include_tax) ? subOriginTotal : subOriginTotal.plus(totalTaxFee);
|
|
51
61
|
const deposit = calculateDeposit(items);
|
|
52
62
|
return {
|
|
@@ -55,7 +65,7 @@ var calculatePriceDetails = (shopInfo, items, isInScheduleByDate, surchargeList)
|
|
|
55
65
|
originTotal: originTotal.toFixed(2),
|
|
56
66
|
taxTitle: shopInfo == null ? void 0 : shopInfo.tax_title,
|
|
57
67
|
taxRate: shopInfo == null ? void 0 : shopInfo.tax_rate,
|
|
58
|
-
totalTaxFee:
|
|
68
|
+
totalTaxFee: tax,
|
|
59
69
|
isPriceIncludeTax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax,
|
|
60
70
|
surcharge,
|
|
61
71
|
surchargeAmount: surchargeAmount.toFixed(2),
|
|
@@ -83,6 +93,221 @@ var getProductDiscountProductDiscountDifference = (item) => {
|
|
|
83
93
|
return pre + (cur.metadata.product_discount_difference || 0);
|
|
84
94
|
}, 0);
|
|
85
95
|
};
|
|
96
|
+
var getTax = ({ service, addons, bookingDetail, bookingId }, options) => {
|
|
97
|
+
const { isEdit, computed, tax_rate, is_price_include_tax } = options;
|
|
98
|
+
let totalOriginTax = new import_decimal.default(0);
|
|
99
|
+
let totalTax = new import_decimal.default(0);
|
|
100
|
+
if (service || addons) {
|
|
101
|
+
if (service == null ? void 0 : service.length) {
|
|
102
|
+
const serviceResult = processItemsTax(service, { bookingDetail, bookingId }, {
|
|
103
|
+
tax_rate,
|
|
104
|
+
is_price_include_tax,
|
|
105
|
+
computed
|
|
106
|
+
});
|
|
107
|
+
totalOriginTax = totalOriginTax.plus(serviceResult.originTax);
|
|
108
|
+
totalTax = totalTax.plus(serviceResult.tax);
|
|
109
|
+
}
|
|
110
|
+
if (addons == null ? void 0 : addons.length) {
|
|
111
|
+
const addonsResult = processItemsTax(addons, { bookingDetail, bookingId }, {
|
|
112
|
+
tax_rate,
|
|
113
|
+
is_price_include_tax,
|
|
114
|
+
computed
|
|
115
|
+
});
|
|
116
|
+
totalOriginTax = totalOriginTax.plus(addonsResult.originTax);
|
|
117
|
+
totalTax = totalTax.plus(addonsResult.tax);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
originTax: totalOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber(),
|
|
122
|
+
tax: totalTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber()
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
var processItemsTax = (items, { bookingDetail, bookingId }, options) => {
|
|
126
|
+
const { tax_rate, is_price_include_tax, computed } = options;
|
|
127
|
+
const { shopDiscount, productExpectAmount } = computed;
|
|
128
|
+
let preciseOriginTax = new import_decimal.default(0);
|
|
129
|
+
let preciseTax = new import_decimal.default(0);
|
|
130
|
+
let roundedOriginTax = new import_decimal.default(0);
|
|
131
|
+
let roundedTax = new import_decimal.default(0);
|
|
132
|
+
let lastTaxableItem = null;
|
|
133
|
+
for (let item of items) {
|
|
134
|
+
const quantity = new import_decimal.default(item.num || 1);
|
|
135
|
+
const unitPrice = new import_decimal.default(item.total || 0);
|
|
136
|
+
const mainProductPrice = new import_decimal.default(getMainProductTotal(item) || 0);
|
|
137
|
+
let originalTaxPerItemPrecise = getProductItemTax(
|
|
138
|
+
{
|
|
139
|
+
...item,
|
|
140
|
+
total: mainProductPrice.add((item == null ? void 0 : item.surcharge_fee) || 0).toNumber(),
|
|
141
|
+
quantity: 1
|
|
142
|
+
},
|
|
143
|
+
{ bookingDetail, bookingId },
|
|
144
|
+
{ tax_rate, is_price_include_tax }
|
|
145
|
+
);
|
|
146
|
+
let itemDiscount = new import_decimal.default(0);
|
|
147
|
+
if (productExpectAmount > 0) {
|
|
148
|
+
itemDiscount = unitPrice.dividedBy(productExpectAmount).times(shopDiscount);
|
|
149
|
+
}
|
|
150
|
+
let mainItemDiscount = new import_decimal.default(0);
|
|
151
|
+
if (unitPrice.greaterThan(0)) {
|
|
152
|
+
mainItemDiscount = mainProductPrice.dividedBy(productExpectAmount).times(shopDiscount);
|
|
153
|
+
}
|
|
154
|
+
const mainItemDiscountedUnitPrice = mainProductPrice.minus(mainItemDiscount).add((item == null ? void 0 : item.surcharge_fee) || 0);
|
|
155
|
+
const maxDiscountedTaxPerItemPrecise = getProductItemTax(
|
|
156
|
+
{
|
|
157
|
+
...item,
|
|
158
|
+
total: mainItemDiscountedUnitPrice.toNumber(),
|
|
159
|
+
price: item.total,
|
|
160
|
+
quantity: 1
|
|
161
|
+
},
|
|
162
|
+
{ bookingDetail, bookingId },
|
|
163
|
+
{ tax_rate, is_price_include_tax }
|
|
164
|
+
);
|
|
165
|
+
const maxDiscountedTaxPerItemRounded = maxDiscountedTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
166
|
+
item.main_product_attached_bundle_tax_fee = maxDiscountedTaxPerItemRounded.toNumber();
|
|
167
|
+
if (maxDiscountedTaxPerItemPrecise.gt(0)) {
|
|
168
|
+
lastTaxableItem = { type: "main", item };
|
|
169
|
+
}
|
|
170
|
+
let addTimePreciseTax = new import_decimal.default(0);
|
|
171
|
+
let addTimeRoundedTax = new import_decimal.default(0);
|
|
172
|
+
if (Array.isArray(item.relation_details)) {
|
|
173
|
+
for (let atItem of item.relation_details) {
|
|
174
|
+
const _originTotal = new import_decimal.default(
|
|
175
|
+
atItem.selling_price || atItem.price || 0
|
|
176
|
+
);
|
|
177
|
+
let _discountedTotal = _originTotal;
|
|
178
|
+
if (productExpectAmount > 0) {
|
|
179
|
+
_discountedTotal = _originTotal.minus(
|
|
180
|
+
_originTotal.dividedBy(productExpectAmount).times(shopDiscount)
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
const addTimeTaxPerItemPrecise = getProductItemTax(
|
|
184
|
+
{
|
|
185
|
+
...atItem,
|
|
186
|
+
total: _discountedTotal.add((atItem == null ? void 0 : atItem.surcharge_fee) || 0).toNumber(),
|
|
187
|
+
quantity: atItem.product_quantity || atItem.num || 1
|
|
188
|
+
},
|
|
189
|
+
{ bookingDetail, bookingId },
|
|
190
|
+
{ tax_rate, is_price_include_tax }
|
|
191
|
+
);
|
|
192
|
+
const addTimeTaxPerItemRounded = addTimeTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
193
|
+
atItem.tax_fee = addTimeTaxPerItemRounded.toNumber();
|
|
194
|
+
addTimePreciseTax = addTimePreciseTax.plus(addTimeTaxPerItemPrecise);
|
|
195
|
+
addTimeRoundedTax = addTimeRoundedTax.plus(addTimeTaxPerItemRounded);
|
|
196
|
+
if (addTimeTaxPerItemPrecise.gt(0)) {
|
|
197
|
+
lastTaxableItem = { type: "addTime", item: atItem };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
let bundlePreciseOriginTax = new import_decimal.default(0);
|
|
202
|
+
let bundlePreciseTax = new import_decimal.default(0);
|
|
203
|
+
let bundleRoundedOriginTax = new import_decimal.default(0);
|
|
204
|
+
let bundleRoundedTax = new import_decimal.default(0);
|
|
205
|
+
if (Array.isArray(item == null ? void 0 : item.bundle)) {
|
|
206
|
+
for (let bundleItem of item == null ? void 0 : item.bundle) {
|
|
207
|
+
if (getBundleItemIsOriginalPrice(bundleItem)) {
|
|
208
|
+
const bundleQuantity = new import_decimal.default(bundleItem.quantity || 1);
|
|
209
|
+
const bundleUnitPrice = new import_decimal.default(
|
|
210
|
+
bundleItem.bundle_selling_price ?? bundleItem.price ?? 0
|
|
211
|
+
);
|
|
212
|
+
const bundleOriginalTaxPerItemPrecise = getProductItemTax(
|
|
213
|
+
{
|
|
214
|
+
...bundleItem,
|
|
215
|
+
total: bundleUnitPrice.add((bundleItem == null ? void 0 : bundleItem.surcharge_fee) || 0).toNumber(),
|
|
216
|
+
quantity: 1
|
|
217
|
+
},
|
|
218
|
+
{ bookingDetail, bookingId },
|
|
219
|
+
{ tax_rate, is_price_include_tax }
|
|
220
|
+
);
|
|
221
|
+
let bundleItemDiscount = new import_decimal.default(0);
|
|
222
|
+
if (productExpectAmount > 0) {
|
|
223
|
+
bundleItemDiscount = bundleUnitPrice.dividedBy(productExpectAmount).times(shopDiscount);
|
|
224
|
+
}
|
|
225
|
+
const bundleDiscountedUnitPrice = bundleUnitPrice.minus(bundleItemDiscount).add((bundleItem == null ? void 0 : bundleItem.surcharge_fee) || 0);
|
|
226
|
+
const bundleDiscountedTaxPerItemPrecise = getProductItemTax(
|
|
227
|
+
{
|
|
228
|
+
...bundleItem,
|
|
229
|
+
total: bundleDiscountedUnitPrice.toNumber(),
|
|
230
|
+
quantity: 1
|
|
231
|
+
},
|
|
232
|
+
{ bookingDetail, bookingId },
|
|
233
|
+
{ tax_rate, is_price_include_tax }
|
|
234
|
+
);
|
|
235
|
+
const bundleOriginalTaxPerItemRounded = bundleOriginalTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
236
|
+
const bundleDiscountedTaxPerItemRounded = bundleDiscountedTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
237
|
+
bundleItem.original_tax_fee = bundleOriginalTaxPerItemRounded.toNumber();
|
|
238
|
+
bundleItem.tax_fee = bundleDiscountedTaxPerItemRounded.toNumber();
|
|
239
|
+
bundlePreciseOriginTax = bundlePreciseOriginTax.plus(bundleOriginalTaxPerItemPrecise.times(bundleQuantity));
|
|
240
|
+
bundlePreciseTax = bundlePreciseTax.plus(bundleDiscountedTaxPerItemPrecise.times(bundleQuantity));
|
|
241
|
+
bundleRoundedOriginTax = bundleRoundedOriginTax.plus(bundleOriginalTaxPerItemRounded.times(bundleQuantity));
|
|
242
|
+
bundleRoundedTax = bundleRoundedTax.plus(bundleDiscountedTaxPerItemRounded.times(bundleQuantity));
|
|
243
|
+
if (bundleDiscountedTaxPerItemPrecise.gt(0)) {
|
|
244
|
+
lastTaxableItem = { type: "bundle", item: bundleItem };
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const originalTaxFeePrecise = originalTaxPerItemPrecise.plus(bundlePreciseOriginTax);
|
|
250
|
+
const taxFeePrecise = maxDiscountedTaxPerItemPrecise.plus(bundlePreciseTax);
|
|
251
|
+
const originalTaxFeeRounded = originalTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).plus(bundleRoundedOriginTax);
|
|
252
|
+
const taxFeeRounded = maxDiscountedTaxPerItemRounded.plus(bundleRoundedTax);
|
|
253
|
+
item.original_tax_fee = originalTaxFeeRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
254
|
+
item.tax_fee = taxFeeRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
255
|
+
preciseOriginTax = preciseOriginTax.plus(originalTaxFeePrecise.times(quantity)).plus(addTimePreciseTax);
|
|
256
|
+
preciseTax = preciseTax.plus(taxFeePrecise.times(quantity)).plus(addTimePreciseTax);
|
|
257
|
+
roundedOriginTax = roundedOriginTax.plus(originalTaxFeeRounded.times(quantity)).plus(addTimeRoundedTax);
|
|
258
|
+
roundedTax = roundedTax.plus(taxFeeRounded.times(quantity)).plus(addTimeRoundedTax);
|
|
259
|
+
}
|
|
260
|
+
const expectedOriginTax = preciseOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
261
|
+
const expectedTax = preciseTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
|
|
262
|
+
const originTaxRemainder = expectedOriginTax.minus(roundedOriginTax).toNumber();
|
|
263
|
+
const taxRemainder = expectedTax.minus(roundedTax).toNumber();
|
|
264
|
+
if (lastTaxableItem) {
|
|
265
|
+
if (originTaxRemainder !== 0) {
|
|
266
|
+
if (lastTaxableItem.type === "main") {
|
|
267
|
+
lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
|
|
268
|
+
} else {
|
|
269
|
+
lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (taxRemainder !== 0) {
|
|
273
|
+
if (lastTaxableItem.type === "main") {
|
|
274
|
+
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
|
|
275
|
+
} else {
|
|
276
|
+
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return { originTax: expectedOriginTax, tax: expectedTax };
|
|
281
|
+
};
|
|
282
|
+
var getProductItemTax = (item, state, options) => {
|
|
283
|
+
const { bookingDetail } = state;
|
|
284
|
+
const { tax_rate, is_price_include_tax } = options;
|
|
285
|
+
const productDiscountPrice = new import_decimal.default(item.total || 0);
|
|
286
|
+
const quantity = new import_decimal.default(item.num || 1);
|
|
287
|
+
if (productDiscountPrice.lte(0)) {
|
|
288
|
+
return new import_decimal.default(0);
|
|
289
|
+
}
|
|
290
|
+
const currentTaxRate = new import_decimal.default(
|
|
291
|
+
(bookingDetail == null ? void 0 : bookingDetail.tax_rate) ?? (tax_rate ? tax_rate / 100 : 0)
|
|
292
|
+
);
|
|
293
|
+
const currentIsPriceIncludeTax = (bookingDetail == null ? void 0 : bookingDetail.is_price_include_tax) ?? is_price_include_tax ?? 0;
|
|
294
|
+
let singleItemTax = new import_decimal.default(0);
|
|
295
|
+
if (item.is_charge_tax === 0 || !item.is_charge_tax) {
|
|
296
|
+
singleItemTax = new import_decimal.default(0);
|
|
297
|
+
} else {
|
|
298
|
+
if (currentIsPriceIncludeTax === 0) {
|
|
299
|
+
singleItemTax = productDiscountPrice.times(currentTaxRate);
|
|
300
|
+
} else {
|
|
301
|
+
const divisor = new import_decimal.default(1).plus(currentTaxRate);
|
|
302
|
+
if (divisor.lte(0)) {
|
|
303
|
+
singleItemTax = new import_decimal.default(0);
|
|
304
|
+
} else {
|
|
305
|
+
singleItemTax = productDiscountPrice.dividedBy(divisor).times(currentTaxRate);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return singleItemTax.times(quantity);
|
|
310
|
+
};
|
|
86
311
|
var calculateSubtotal = (items) => {
|
|
87
312
|
if (!(items == null ? void 0 : items.length)) {
|
|
88
313
|
return "0.00";
|
|
@@ -492,5 +717,6 @@ var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
|
|
|
492
717
|
calculateTaxFee,
|
|
493
718
|
getBundleDiscountList,
|
|
494
719
|
getSurcharge,
|
|
495
|
-
getSurchargeAmount
|
|
720
|
+
getSurchargeAmount,
|
|
721
|
+
getTax
|
|
496
722
|
});
|