@pisell/pisellos 0.0.567 → 0.0.568

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.
Files changed (228) hide show
  1. package/dist/core/index.js +6 -9
  2. package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -2
  3. package/dist/model/strategy/adapter/walletPass/example.js +3 -26
  4. package/dist/model/strategy/adapter/walletPass/utils.js +0 -3
  5. package/dist/model/strategy/strategy-example.js +5 -19
  6. package/dist/modules/Cart/index.js +0 -3
  7. package/dist/modules/Cart/utils/cartProduct.js +0 -1
  8. package/dist/modules/Date/index.js +1 -5
  9. package/dist/modules/Discount/index.js +1 -4
  10. package/dist/modules/OpenData/index.js +0 -2
  11. package/dist/modules/Order/index.d.ts +1 -1
  12. package/dist/modules/Order/index.js +14 -41
  13. package/dist/modules/Payment/index.js +142 -270
  14. package/dist/modules/Payment/walletpass.js +4 -5
  15. package/dist/modules/Rules/index.js +0 -7
  16. package/dist/modules/Schedule/utils.js +0 -1
  17. package/dist/modules/Step/index.js +0 -1
  18. package/dist/plugins/request.js +1 -4
  19. package/dist/plugins/window.js +2 -6
  20. package/dist/server/index.js +88 -121
  21. package/dist/server/modules/menu/index.js +32 -41
  22. package/dist/server/modules/products/index.js +29 -49
  23. package/dist/server/modules/quotation/index.js +29 -38
  24. package/dist/server/modules/resource/index.js +3 -4
  25. package/dist/server/modules/schedule/index.js +32 -40
  26. package/dist/server/utils/product.js +0 -1
  27. package/dist/solution/BookingByStep/index.d.ts +1 -1
  28. package/dist/solution/BookingByStep/index.js +7 -59
  29. package/dist/solution/BookingByStep/utils/capacity.js +1 -11
  30. package/dist/solution/BookingByStep/utils/resources.js +1 -3
  31. package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
  32. package/dist/solution/BookingTicket/index.d.ts +1 -1
  33. package/dist/solution/BookingTicket/index.js +5 -7
  34. package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
  35. package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
  36. package/dist/solution/BuyTickets/index.js +9 -12
  37. package/dist/solution/Checkout/index.js +177 -246
  38. package/dist/solution/Checkout/utils/index.js +4 -16
  39. package/dist/solution/RegisterAndLogin/index.js +30 -76
  40. package/dist/solution/ScanOrder/index.js +50 -60
  41. package/dist/solution/ShopDiscount/index.js +2 -7
  42. package/dist/solution/VenueBooking/index.d.ts +5 -0
  43. package/dist/solution/VenueBooking/index.js +364 -327
  44. package/dist/utils/task.js +15 -18
  45. package/dist/utils/watch.js +0 -1
  46. package/lib/apis/picoding.js +2 -0
  47. package/lib/core/index.js +130 -131
  48. package/lib/effects/index.js +46 -57
  49. package/lib/index.js +92 -53
  50. package/lib/model/index.js +14 -21
  51. package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
  52. package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
  53. package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
  54. package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
  55. package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
  56. package/lib/model/strategy/adapter/index.js +100 -64
  57. package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
  58. package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
  59. package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
  60. package/lib/model/strategy/adapter/itemRule/index.js +83 -57
  61. package/lib/model/strategy/adapter/itemRule/type.js +97 -36
  62. package/lib/model/strategy/adapter/promotion/adapter.js +84 -63
  63. package/lib/model/strategy/adapter/promotion/evaluator.js +381 -231
  64. package/lib/model/strategy/adapter/promotion/examples.js +139 -159
  65. package/lib/model/strategy/adapter/promotion/index.js +1 -49
  66. package/lib/model/strategy/adapter/promotion/type.js +199 -35
  67. package/lib/model/strategy/adapter/type.js +4 -16
  68. package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -152
  69. package/lib/model/strategy/adapter/walletPass/example.js +217 -190
  70. package/lib/model/strategy/adapter/walletPass/index.js +75 -51
  71. package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
  72. package/lib/model/strategy/adapter/walletPass/type.js +4 -16
  73. package/lib/model/strategy/adapter/walletPass/utils.js +652 -402
  74. package/lib/model/strategy/engine.js +270 -168
  75. package/lib/model/strategy/index.js +49 -34
  76. package/lib/model/strategy/strategy-example.js +243 -239
  77. package/lib/model/strategy/type.js +100 -40
  78. package/lib/modules/Account/index.js +39 -53
  79. package/lib/modules/Account/types.js +20 -33
  80. package/lib/modules/AccountList/index.js +116 -154
  81. package/lib/modules/AccountList/types.js +30 -31
  82. package/lib/modules/AccountList/utils.js +18 -30
  83. package/lib/modules/BaseModule.js +22 -45
  84. package/lib/modules/Cart/index.js +170 -124
  85. package/lib/modules/Cart/types.js +46 -51
  86. package/lib/modules/Cart/utils/cartAccount.js +40 -39
  87. package/lib/modules/Cart/utils/cartDate.js +56 -61
  88. package/lib/modules/Cart/utils/cartDiscount.js +28 -33
  89. package/lib/modules/Cart/utils/cartNote.js +27 -32
  90. package/lib/modules/Cart/utils/cartProduct.js +306 -241
  91. package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
  92. package/lib/modules/Cart/utils/cartResource.js +72 -78
  93. package/lib/modules/Cart/utils/changePrice.js +26 -62
  94. package/lib/modules/Cart/utils/index.js +106 -48
  95. package/lib/modules/Customer/constants.js +13 -34
  96. package/lib/modules/Customer/index.js +216 -153
  97. package/lib/modules/Customer/types.js +38 -35
  98. package/lib/modules/Date/index.js +116 -115
  99. package/lib/modules/Date/types.js +16 -28
  100. package/lib/modules/Date/utils.js +174 -123
  101. package/lib/modules/Discount/index.js +117 -113
  102. package/lib/modules/Discount/types.js +9 -31
  103. package/lib/modules/Guests/index.js +30 -56
  104. package/lib/modules/Guests/types.js +23 -33
  105. package/lib/modules/Holder/index.js +209 -189
  106. package/lib/modules/Holder/types.js +4 -16
  107. package/lib/modules/Holder/utils.js +20 -49
  108. package/lib/modules/OpenData/index.js +63 -74
  109. package/lib/modules/OpenData/types.js +4 -16
  110. package/lib/modules/OpenData/utils.js +44 -78
  111. package/lib/modules/Order/index.d.ts +1 -1
  112. package/lib/modules/Order/index.js +332 -320
  113. package/lib/modules/Order/types.js +24 -33
  114. package/lib/modules/Order/utils.js +350 -284
  115. package/lib/modules/Payment/cash.js +20 -33
  116. package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
  117. package/lib/modules/Payment/eftpos.js +16 -30
  118. package/lib/modules/Payment/index.js +566 -432
  119. package/lib/modules/Payment/mx51.js +1 -0
  120. package/lib/modules/Payment/types.js +216 -107
  121. package/lib/modules/Payment/utils.js +50 -47
  122. package/lib/modules/Payment/walletpass.js +221 -203
  123. package/lib/modules/Product/index.js +51 -46
  124. package/lib/modules/Product/types.js +4 -16
  125. package/lib/modules/Product/utils.js +32 -33
  126. package/lib/modules/ProductList/index.js +111 -110
  127. package/lib/modules/ProductList/types.js +9 -31
  128. package/lib/modules/Quotation/index.js +60 -82
  129. package/lib/modules/Quotation/types.js +4 -16
  130. package/lib/modules/Resource/index.js +27 -59
  131. package/lib/modules/Resource/types.js +22 -32
  132. package/lib/modules/Resource/utils.js +30 -38
  133. package/lib/modules/Rules/index.js +1172 -872
  134. package/lib/modules/Rules/types.js +17 -40
  135. package/lib/modules/SalesSummary/index.js +59 -68
  136. package/lib/modules/SalesSummary/types.js +4 -16
  137. package/lib/modules/SalesSummary/utils.js +176 -193
  138. package/lib/modules/ScanOrderLogger/index.js +59 -79
  139. package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
  140. package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
  141. package/lib/modules/ScanOrderLogger/types.js +4 -16
  142. package/lib/modules/Schedule/getDateIsInSchedule.js +334 -167
  143. package/lib/modules/Schedule/index.js +97 -107
  144. package/lib/modules/Schedule/type.js +4 -16
  145. package/lib/modules/Schedule/types.js +4 -16
  146. package/lib/modules/Schedule/utils.js +433 -291
  147. package/lib/modules/Step/index.js +40 -52
  148. package/lib/modules/Step/tyeps.js +4 -16
  149. package/lib/modules/Summary/index.js +66 -70
  150. package/lib/modules/Summary/types.js +4 -16
  151. package/lib/modules/Summary/utils.js +782 -429
  152. package/lib/modules/index.js +212 -57
  153. package/lib/plugins/app.js +4 -16
  154. package/lib/plugins/index.js +36 -25
  155. package/lib/plugins/request.js +137 -126
  156. package/lib/plugins/shopStore.js +4 -16
  157. package/lib/plugins/user.js +4 -16
  158. package/lib/plugins/window.js +171 -179
  159. package/lib/server/index.js +882 -623
  160. package/lib/server/modules/index.js +85 -59
  161. package/lib/server/modules/menu/index.js +146 -122
  162. package/lib/server/modules/menu/types.js +18 -31
  163. package/lib/server/modules/order/index.js +195 -231
  164. package/lib/server/modules/order/types.js +107 -32
  165. package/lib/server/modules/order/utils/filterBookings.js +174 -140
  166. package/lib/server/modules/order/utils/filterOrders.js +89 -60
  167. package/lib/server/modules/products/index.js +430 -335
  168. package/lib/server/modules/products/types.js +41 -34
  169. package/lib/server/modules/quotation/index.js +76 -77
  170. package/lib/server/modules/quotation/types.js +21 -31
  171. package/lib/server/modules/resource/index.js +216 -187
  172. package/lib/server/modules/resource/types.js +42 -33
  173. package/lib/server/modules/schedule/index.js +134 -119
  174. package/lib/server/modules/schedule/types.js +14 -21
  175. package/lib/server/modules/schedule/utils.js +334 -163
  176. package/lib/server/types.js +4 -16
  177. package/lib/server/utils/index.js +25 -23
  178. package/lib/server/utils/product.js +196 -139
  179. package/lib/server/utils/schedule.js +34 -41
  180. package/lib/server/utils/time.js +40 -49
  181. package/lib/solution/BookingByStep/index.d.ts +1 -1
  182. package/lib/solution/BookingByStep/index.js +1530 -1343
  183. package/lib/solution/BookingByStep/types.js +40 -99
  184. package/lib/solution/BookingByStep/utils/capacity.js +192 -160
  185. package/lib/solution/BookingByStep/utils/products.js +42 -52
  186. package/lib/solution/BookingByStep/utils/resources.js +527 -330
  187. package/lib/solution/BookingByStep/utils/stock.js +65 -44
  188. package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
  189. package/lib/solution/BookingTicket/index.d.ts +1 -1
  190. package/lib/solution/BookingTicket/index.js +147 -122
  191. package/lib/solution/BookingTicket/types.js +38 -64
  192. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +64 -80
  193. package/lib/solution/BookingTicket/utils/scan/handleScan.js +82 -80
  194. package/lib/solution/BookingTicket/utils/scan/index.js +90 -94
  195. package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
  196. package/lib/solution/BuyTickets/index.js +67 -70
  197. package/lib/solution/BuyTickets/types.js +22 -38
  198. package/lib/solution/Checkout/index.js +1451 -1158
  199. package/lib/solution/Checkout/types.js +91 -61
  200. package/lib/solution/Checkout/utils/index.js +227 -158
  201. package/lib/solution/PlaceOrder/index.js +55 -0
  202. package/lib/solution/RegisterAndLogin/config.js +493 -460
  203. package/lib/solution/RegisterAndLogin/index.js +633 -630
  204. package/lib/solution/RegisterAndLogin/types.js +189 -76
  205. package/lib/solution/RegisterAndLogin/utils.js +183 -125
  206. package/lib/solution/Sales/index.js +218 -200
  207. package/lib/solution/Sales/types.js +27 -33
  208. package/lib/solution/ScanOrder/index.js +803 -840
  209. package/lib/solution/ScanOrder/types.js +34 -34
  210. package/lib/solution/ScanOrder/utils.js +372 -331
  211. package/lib/solution/ShopDiscount/index.js +230 -236
  212. package/lib/solution/ShopDiscount/types.js +15 -37
  213. package/lib/solution/ShopDiscount/utils.js +309 -172
  214. package/lib/solution/VenueBooking/index.d.ts +5 -0
  215. package/lib/solution/VenueBooking/index.js +886 -929
  216. package/lib/solution/VenueBooking/types.js +20 -40
  217. package/lib/solution/VenueBooking/utils/dateSummary.js +22 -54
  218. package/lib/solution/VenueBooking/utils/resource.js +31 -54
  219. package/lib/solution/VenueBooking/utils/slotMerge.js +88 -106
  220. package/lib/solution/VenueBooking/utils/smartPricing.js +112 -100
  221. package/lib/solution/VenueBooking/utils/timeSlot.js +133 -132
  222. package/lib/solution/VenueBooking/utils.js +130 -67
  223. package/lib/solution/index.js +102 -37
  224. package/lib/store/createStore.js +32 -29
  225. package/lib/types/index.js +4 -16
  226. package/lib/utils/task.js +36 -36
  227. package/lib/utils/watch.js +81 -47
  228. package/package.json +2 -1
@@ -1,499 +1,774 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
-
29
- // src/modules/Summary/utils.ts
30
- var utils_exports = {};
31
- __export(utils_exports, {
32
- calcDiscountListDifference: () => calcDiscountListDifference,
33
- calculateDeposit: () => calculateDeposit,
34
- calculateOriginSubtotal: () => calculateOriginSubtotal,
35
- calculatePriceDetails: () => calculatePriceDetails,
36
- calculateSubtotal: () => calculateSubtotal,
37
- calculateTaxFee: () => calculateTaxFee,
38
- getBundleDiscountList: () => getBundleDiscountList,
39
- getProductDiscountProductDiscountDifference: () => getProductDiscountProductDiscountDifference,
40
- getSurcharge: () => getSurcharge,
41
- getSurchargeAmount: () => getSurchargeAmount,
42
- getTax: () => getTax
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
43
5
  });
44
- module.exports = __toCommonJS(utils_exports);
45
- var import_decimal = __toESM(require("decimal.js"));
46
- var import_utils = require("../Product/utils");
47
- var import_dayjs = __toESM(require("dayjs"));
48
- var calculatePriceDetails = (shopInfo, items, isInScheduleByDate, surchargeList, scheduleById) => {
49
- const subtotal = new import_decimal.default(calculateSubtotal(items));
50
- const subOriginTotal = new import_decimal.default(calculateOriginSubtotal(items));
51
- const totalTaxFee = new import_decimal.default(calculateTaxFee(shopInfo, items));
52
- const surcharge = getSurcharge({ service: items, addons: [], bookingDetail: null, bookingId: void 0 }, { isEdit: false, isInScheduleByDate, surcharge_list: surchargeList, scheduleById });
53
- const surchargeAmount = new import_decimal.default(getSurchargeAmount({ bookingDetail: null, bookingId: void 0 }, surcharge, { isEdit: false }));
54
- const { tax, originTax } = getTax({ service: items, bookingDetail: null, bookingId: void 0 }, {
6
+ exports.getTax = exports.getSurchargeAmount = exports.getSurcharge = exports.getProductDiscountProductDiscountDifference = exports.getBundleDiscountList = exports.calculateTaxFee = exports.calculateSubtotal = exports.calculatePriceDetails = exports.calculateOriginSubtotal = exports.calculateDeposit = exports.calcDiscountListDifference = void 0;
7
+ var _decimal = _interopRequireDefault(require("decimal.js"));
8
+ var _utils = require("../Product/utils");
9
+ var _dayjs = _interopRequireDefault(require("dayjs"));
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ const calculatePriceDetails = (shopInfo, items, isInScheduleByDate, surchargeList, scheduleById) => {
12
+ const subtotal = new _decimal.default(calculateSubtotal(items));
13
+ const subOriginTotal = new _decimal.default(calculateOriginSubtotal(items));
14
+ const totalTaxFee = new _decimal.default(calculateTaxFee(shopInfo, items));
15
+ // 订单附加费列表
16
+ const surcharge = getSurcharge({
17
+ service: items,
18
+ addons: [],
19
+ bookingDetail: null,
20
+ bookingId: undefined
21
+ }, {
22
+ isEdit: false,
23
+ isInScheduleByDate,
24
+ surcharge_list: surchargeList,
25
+ scheduleById
26
+ });
27
+ // 订单附加费金额
28
+ const surchargeAmount = new _decimal.default(getSurchargeAmount({
29
+ bookingDetail: null,
30
+ bookingId: undefined
31
+ }, surcharge, {
32
+ isEdit: false
33
+ }));
34
+ // 税费
35
+ const {
36
+ tax,
37
+ originTax
38
+ } = getTax({
39
+ service: items,
40
+ bookingDetail: null,
41
+ bookingId: undefined
42
+ }, {
55
43
  computed: {
56
44
  productExpectAmount: subtotal.toNumber(),
57
45
  shopDiscount: 0
58
46
  },
59
47
  isEdit: false,
60
- tax_rate: shopInfo == null ? void 0 : shopInfo.tax_rate,
61
- is_price_include_tax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax
48
+ tax_rate: shopInfo?.tax_rate,
49
+ is_price_include_tax: shopInfo?.is_price_include_tax
62
50
  });
63
- const total = (shopInfo == null ? void 0 : shopInfo.is_price_include_tax) ? subtotal.plus(surchargeAmount) : subtotal.plus(tax).plus(surchargeAmount);
64
- const originTotal = (shopInfo == null ? void 0 : shopInfo.is_price_include_tax) ? subOriginTotal.plus(surchargeAmount) : subOriginTotal.plus(totalTaxFee).plus(surchargeAmount);
51
+ const total = shopInfo?.is_price_include_tax ? subtotal.plus(surchargeAmount) : subtotal.plus(tax).plus(surchargeAmount);
52
+
53
+ // 计算总价 不包含折扣卡商品券折扣信息价格
54
+ const originTotal = shopInfo?.is_price_include_tax ? subOriginTotal.plus(surchargeAmount) : subOriginTotal.plus(totalTaxFee).plus(surchargeAmount);
55
+
56
+ // 计算定金
65
57
  const deposit = calculateDeposit(items);
66
58
  return {
67
59
  subtotal: subtotal.toFixed(2),
68
60
  total: total.toFixed(2),
69
61
  originTotal: originTotal.toFixed(2),
70
- taxTitle: shopInfo == null ? void 0 : shopInfo.tax_title,
71
- taxRate: shopInfo == null ? void 0 : shopInfo.tax_rate,
62
+ taxTitle: shopInfo?.tax_title,
63
+ taxRate: shopInfo?.tax_rate,
72
64
  totalTaxFee: tax,
73
- isPriceIncludeTax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax,
65
+ isPriceIncludeTax: shopInfo?.is_price_include_tax,
74
66
  surcharge,
75
67
  surchargeAmount: surchargeAmount.toFixed(2),
76
68
  deposit
77
69
  };
78
70
  };
79
- var getBundleDiscountList = (bundle) => {
71
+
72
+ /**
73
+ * 获取子商品折扣信息
74
+ * @param item
75
+ */
76
+ exports.calculatePriceDetails = calculatePriceDetails;
77
+ const getBundleDiscountList = bundle => {
80
78
  if (!bundle) {
81
79
  return [];
82
80
  }
83
81
  let discountList = [];
84
- bundle.forEach((d) => {
82
+ bundle.forEach(d => {
85
83
  if (d.discount_list && Array.isArray(d.discount_list)) {
86
- discountList.push(...d.discount_list.filter((item) => !item.id));
84
+ discountList.push(...d.discount_list.filter(item => !item.id));
87
85
  }
88
86
  });
89
87
  return discountList;
90
88
  };
91
- var calcDiscountListDifference = (discountList) => {
89
+ exports.getBundleDiscountList = getBundleDiscountList;
90
+ const calcDiscountListDifference = discountList => {
92
91
  return discountList.reduce((pre, cur) => {
93
- var _a;
94
- return pre.plus(((_a = cur == null ? void 0 : cur.metadata) == null ? void 0 : _a.product_discount_difference) || 0);
95
- }, new import_decimal.default(0)).toNumber();
92
+ return pre.plus(cur?.metadata?.product_discount_difference || 0);
93
+ }, new _decimal.default(0)).toNumber();
96
94
  };
97
- var getProductDiscountProductDiscountDifference = (item) => {
98
- var _a, _b, _c, _d;
99
- const mainDiscountList = ((_b = (_a = item._origin) == null ? void 0 : _a.product) == null ? void 0 : _b.discount_list) || [];
100
- const bundleDiscountList = getBundleDiscountList(((_d = (_c = item._origin) == null ? void 0 : _c.product) == null ? void 0 : _d.product_bundle) || []);
95
+ exports.calcDiscountListDifference = calcDiscountListDifference;
96
+ const getProductDiscountProductDiscountDifference = item => {
97
+ const mainDiscountList = item._origin?.product?.discount_list || [];
98
+ const bundleDiscountList = getBundleDiscountList(item._origin?.product?.product_bundle || []);
101
99
  const discountList = [...mainDiscountList, ...bundleDiscountList];
102
100
  return calcDiscountListDifference(discountList);
103
101
  };
104
- var getTax = ({ service, addons, bookingDetail, bookingId }, options) => {
105
- const { isEdit, computed, tax_rate, is_price_include_tax } = options;
106
- let totalOriginTax = new import_decimal.default(0);
107
- let totalTax = new import_decimal.default(0);
102
+
103
+ /**
104
+ * 计算订单税费(折扣前/折扣后),并把单品税费信息回写到商品数据上(用于明细展示/后续计算)。
105
+ *
106
+ * - **折扣前税费**:`originTax`
107
+ * - **折扣后税费**:`tax`(会考虑 `computed.shopDiscount` 对每个商品的分摊影响)
108
+ * - **税率/是否含税**:优先取 `bookingDetail.tax_rate` / `bookingDetail.is_price_include_tax`,取不到再回退到 `options.tax_rate` / `options.is_price_include_tax`
109
+ *
110
+ * **副作用(会修改入参商品对象)**:
111
+ * - 主商品:写入 `item.original_tax_fee` / `item.tax_fee`(四舍五入保留两位)
112
+ * - bundle 原价子商品:写入 `bundleItem.original_tax_fee` / `bundleItem.tax_fee`
113
+ * - 加时商品(`relation_details`):写入 `atItem.tax_fee`
114
+ * - 税费舍入差值:追加到最后一个“含税商品”的 `tax_fee_rounding_remainder` / `original_tax_fee_rounding_remainder`
115
+ *
116
+ * @param params 入参集合(RORO)
117
+ * @param params.service 服务商品数组(主商品)。通常是购物车商品结构(可能包含 `bundle` / `relation_details`)
118
+ * @param params.addons 附加商品数组(可选)。结构同商品数组
119
+ * @param params.bookingDetail 订单详情(编辑/详情场景用于读取后端税率配置),可选
120
+ * @param params.bookingId 订单/预约 ID(编辑/详情场景识别用),可选
121
+ * @param options 计算选项
122
+ * @param options.isEdit 是否处于“编辑中”。当前实现不强依赖该值(历史逻辑保留),但建议按真实状态传入
123
+ * @param options.computed 预计算结果(用于折扣分摊)
124
+ * @param options.computed.productExpectAmount 商品期望总金额(用于按比例分摊折扣)
125
+ * @param options.computed.shopDiscount 店铺折扣总额(用于按比例分摊到商品)
126
+ * @param options.tax_rate 管理端税率(百分比,如 5 表示 5%)。仅当 `bookingDetail.tax_rate` 不存在时生效
127
+ * @param options.is_price_include_tax 是否含税:`0` 不含税、`1` 含税。仅当 `bookingDetail.is_price_include_tax` 不存在时生效
128
+ * @returns 税费汇总(number,金额单位与商品价格一致,四舍五入保留两位)
129
+ * @returns.originTax 折扣前税费合计
130
+ * @returns.tax 折扣后税费合计
131
+ */
132
+ exports.getProductDiscountProductDiscountDifference = getProductDiscountProductDiscountDifference;
133
+ const getTax = ({
134
+ service,
135
+ addons,
136
+ bookingDetail,
137
+ bookingId
138
+ }, options) => {
139
+ const {
140
+ isEdit,
141
+ computed,
142
+ tax_rate,
143
+ is_price_include_tax
144
+ } = options;
145
+
146
+ // 详情时未编辑的状态下, 取后端的值
147
+ // if (!isEdit) {
148
+ // return { tax: Number(bookingDetail?.tax_fee) || 0 };
149
+ // }
150
+
151
+ let totalOriginTax = new _decimal.default(0);
152
+ let totalTax = new _decimal.default(0);
108
153
  if (service || addons) {
109
- if (service == null ? void 0 : service.length) {
110
- const serviceResult = processItemsTax(service.map((item) => {
154
+ // 处理服务商品
155
+ if (service?.length) {
156
+ const serviceResult = processItemsTax(service.map(item => {
111
157
  return {
112
158
  ...item,
113
- option: (item == null ? void 0 : item.option) || (item == null ? void 0 : item.options) || [],
114
- bundle: (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || []
159
+ option: item?.option || item?.options || [],
160
+ bundle: item?.bundle || item?.bundles || []
115
161
  };
116
- }), { bookingDetail, bookingId }, {
162
+ }), {
163
+ bookingDetail,
164
+ bookingId
165
+ }, {
117
166
  tax_rate,
118
167
  is_price_include_tax,
119
- computed
168
+ computed: computed
120
169
  });
121
170
  totalOriginTax = totalOriginTax.plus(serviceResult.originTax);
122
171
  totalTax = totalTax.plus(serviceResult.tax);
123
172
  }
124
- if (addons == null ? void 0 : addons.length) {
125
- const addonsResult = processItemsTax(addons, { bookingDetail, bookingId }, {
173
+
174
+ // 处理附加商品
175
+ if (addons?.length) {
176
+ const addonsResult = processItemsTax(addons, {
177
+ bookingDetail,
178
+ bookingId
179
+ }, {
126
180
  tax_rate,
127
181
  is_price_include_tax,
128
- computed
182
+ computed: computed
129
183
  });
130
184
  totalOriginTax = totalOriginTax.plus(addonsResult.originTax);
131
185
  totalTax = totalTax.plus(addonsResult.tax);
132
186
  }
133
187
  }
134
188
  return {
135
- originTax: totalOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber(),
136
- tax: totalTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber()
189
+ originTax: totalOriginTax.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP).toNumber(),
190
+ tax: totalTax.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP).toNumber()
137
191
  };
138
192
  };
193
+ exports.getTax = getTax;
139
194
  function getDiscountedTaxableBase(input) {
140
- const { basePrice, discount, surchargeFee } = input;
141
- if (surchargeFee.lte(0) && basePrice.lte(0))
142
- return new import_decimal.default(0);
195
+ const {
196
+ basePrice,
197
+ discount,
198
+ surchargeFee
199
+ } = input;
200
+ if (surchargeFee.lte(0) && basePrice.lte(0)) return new _decimal.default(0);
143
201
  const discountedBase = basePrice.minus(discount);
144
- if (discountedBase.lte(0))
145
- return surchargeFee;
202
+ if (discountedBase.lte(0)) return surchargeFee;
146
203
  return discountedBase.plus(surchargeFee);
147
204
  }
148
- var processItemsTax = (items, { bookingDetail, bookingId }, options) => {
149
- const { tax_rate, is_price_include_tax, computed } = options;
150
- const { shopDiscount, productExpectAmount } = computed;
151
- let preciseOriginTax = new import_decimal.default(0);
152
- let preciseTax = new import_decimal.default(0);
153
- let roundedOriginTax = new import_decimal.default(0);
154
- let roundedTax = new import_decimal.default(0);
205
+
206
+ /**
207
+ * 处理商品税费计算(折扣前后)
208
+ * 支持税费舍入差值追加到最后一个含税商品的 tax_fee_rounding_remainder / original_tax_fee_rounding_remainder 字段
209
+ * @param items 商品数组
210
+ * @param state 状态
211
+ * @param options 选项
212
+ * @param computed 计算结果
213
+ * @returns 累积的税费信息
214
+ */
215
+ const processItemsTax = (items, {
216
+ bookingDetail,
217
+ bookingId
218
+ }, options) => {
219
+ const {
220
+ tax_rate,
221
+ is_price_include_tax,
222
+ computed
223
+ } = options;
224
+ const {
225
+ shopDiscount,
226
+ productExpectAmount
227
+ } = computed;
228
+
229
+ // 精确税费累加(不四舍五入)
230
+ let preciseOriginTax = new _decimal.default(0);
231
+ let preciseTax = new _decimal.default(0);
232
+ // 四舍五入后的税费累加
233
+ let roundedOriginTax = new _decimal.default(0);
234
+ let roundedTax = new _decimal.default(0);
235
+
236
+ /**
237
+ * 最后一个含税商品的引用(按物理位置)
238
+ * 用于追加税费舍入差值
239
+ */
155
240
  let lastTaxableItem = null;
156
241
  for (let item of items) {
157
- const quantity = new import_decimal.default(item.num || 1);
158
- const unitPrice = new import_decimal.default(item.total || 0);
159
- const mainProductPrice = new import_decimal.default(getMainProductTotal({
242
+ const quantity = new _decimal.default(item.num || 1);
243
+ const unitPrice = new _decimal.default(item.total || 0);
244
+ const mainProductPrice = new _decimal.default(getMainProductTotal({
160
245
  ...item,
161
- option: (item == null ? void 0 : item.option) || (item == null ? void 0 : item.options) || [],
162
- bundle: (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || []
246
+ option: item?.option || item?.options || [],
247
+ bundle: item?.bundle || item?.bundles || []
163
248
  }) || 0);
249
+
250
+ // 计算原始税费(折扣前)- 单个商品(精确值)
164
251
  const originalTaxableBase = getDiscountedTaxableBase({
165
252
  basePrice: mainProductPrice,
166
- discount: new import_decimal.default(0),
167
- surchargeFee: new import_decimal.default((item == null ? void 0 : item.surcharge_fee) || 0)
253
+ discount: new _decimal.default(0),
254
+ surchargeFee: new _decimal.default(item?.surcharge_fee || 0)
255
+ });
256
+ let originalTaxPerItemPrecise = getProductItemTax({
257
+ ...item,
258
+ total: originalTaxableBase.toNumber(),
259
+ quantity: 1
260
+ }, {
261
+ bookingDetail,
262
+ bookingId
263
+ }, {
264
+ tax_rate,
265
+ is_price_include_tax
168
266
  });
169
- let originalTaxPerItemPrecise = getProductItemTax(
170
- {
171
- ...item,
172
- total: originalTaxableBase.toNumber(),
173
- quantity: 1
174
- },
175
- { bookingDetail, bookingId },
176
- { tax_rate, is_price_include_tax }
177
- );
178
- let itemDiscount = new import_decimal.default(0);
267
+
268
+ // 计算平摊到该商品的折扣
269
+ let itemDiscount = new _decimal.default(0);
179
270
  if (productExpectAmount > 0) {
180
271
  itemDiscount = unitPrice.dividedBy(productExpectAmount).times(shopDiscount);
181
272
  }
182
- let mainItemDiscount = new import_decimal.default(0);
273
+
274
+ // 按比例计算主商品应分摊的折扣
275
+ let mainItemDiscount = new _decimal.default(0);
183
276
  if (unitPrice.greaterThan(0)) {
184
277
  mainItemDiscount = mainProductPrice.dividedBy(productExpectAmount).times(shopDiscount);
185
278
  }
186
279
  const mainItemDiscountedUnitPrice = getDiscountedTaxableBase({
187
280
  basePrice: mainProductPrice,
188
281
  discount: mainItemDiscount,
189
- surchargeFee: new import_decimal.default((item == null ? void 0 : item.surcharge_fee) || 0)
282
+ surchargeFee: new _decimal.default(item?.surcharge_fee || 0)
283
+ });
284
+
285
+ // 计算折后税费(折扣后)- 主商品的税费(精确值)
286
+ const maxDiscountedTaxPerItemPrecise = getProductItemTax({
287
+ ...item,
288
+ total: mainItemDiscountedUnitPrice.toNumber(),
289
+ price: item.total,
290
+ quantity: 1
291
+ }, {
292
+ bookingDetail,
293
+ bookingId
294
+ }, {
295
+ tax_rate,
296
+ is_price_include_tax
190
297
  });
191
- const maxDiscountedTaxPerItemPrecise = getProductItemTax(
192
- {
193
- ...item,
194
- total: mainItemDiscountedUnitPrice.toNumber(),
195
- price: item.total,
196
- quantity: 1
197
- },
198
- { bookingDetail, bookingId },
199
- { tax_rate, is_price_include_tax }
200
- );
201
- const maxDiscountedTaxPerItemRounded = maxDiscountedTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
298
+
299
+ // 四舍五入后的值
300
+ const maxDiscountedTaxPerItemRounded = maxDiscountedTaxPerItemPrecise.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
301
+
302
+ // 保存到商品扩展信息中(保留两位小数)
202
303
  item.main_product_attached_bundle_tax_fee = maxDiscountedTaxPerItemRounded.toNumber();
304
+
305
+ // 如果主商品有税费,记录为最后一个含税商品
203
306
  if (maxDiscountedTaxPerItemPrecise.gt(0)) {
204
- lastTaxableItem = { type: "main", item };
307
+ lastTaxableItem = {
308
+ type: 'main',
309
+ item
310
+ };
205
311
  }
206
- let addTimePreciseTax = new import_decimal.default(0);
207
- let addTimeRoundedTax = new import_decimal.default(0);
312
+
313
+ // 注意:加时商品独立计算,不考虑主商品数量
314
+ let addTimePreciseTax = new _decimal.default(0);
315
+ let addTimeRoundedTax = new _decimal.default(0);
208
316
  if (Array.isArray(item.relation_details)) {
209
317
  for (let atItem of item.relation_details) {
210
- const _originTotal = new import_decimal.default(
211
- atItem.selling_price || atItem.price || 0
212
- );
213
- const addTimeDiscount = productExpectAmount > 0 ? _originTotal.dividedBy(productExpectAmount).times(shopDiscount) : new import_decimal.default(0);
318
+ // 计算单件加时商品折扣后价格
319
+ const _originTotal = new _decimal.default(atItem.selling_price || atItem.price || 0);
320
+ const addTimeDiscount = productExpectAmount > 0 ? _originTotal.dividedBy(productExpectAmount).times(shopDiscount) : new _decimal.default(0);
214
321
  const _discountedTotal = getDiscountedTaxableBase({
215
322
  basePrice: _originTotal,
216
323
  discount: addTimeDiscount,
217
- surchargeFee: new import_decimal.default((atItem == null ? void 0 : atItem.surcharge_fee) || 0)
324
+ surchargeFee: new _decimal.default(atItem?.surcharge_fee || 0)
325
+ });
326
+ const addTimeTaxPerItemPrecise = getProductItemTax({
327
+ ...atItem,
328
+ total: _discountedTotal.toNumber(),
329
+ quantity: atItem.product_quantity || atItem.num || 1
330
+ }, {
331
+ bookingDetail,
332
+ bookingId
333
+ }, {
334
+ tax_rate,
335
+ is_price_include_tax
218
336
  });
219
- const addTimeTaxPerItemPrecise = getProductItemTax(
220
- {
221
- ...atItem,
222
- total: _discountedTotal.toNumber(),
223
- quantity: atItem.product_quantity || atItem.num || 1
224
- },
225
- { bookingDetail, bookingId },
226
- { tax_rate, is_price_include_tax }
227
- );
228
- const addTimeTaxPerItemRounded = addTimeTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
337
+ const addTimeTaxPerItemRounded = addTimeTaxPerItemPrecise.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
338
+
339
+ // 保存到加时商品上(四舍五入后的值)
229
340
  atItem.tax_fee = addTimeTaxPerItemRounded.toNumber();
230
341
  addTimePreciseTax = addTimePreciseTax.plus(addTimeTaxPerItemPrecise);
231
342
  addTimeRoundedTax = addTimeRoundedTax.plus(addTimeTaxPerItemRounded);
343
+
344
+ // 如果加时商品有税费,记录为最后一个含税商品
232
345
  if (addTimeTaxPerItemPrecise.gt(0)) {
233
- lastTaxableItem = { type: "addTime", item: atItem };
346
+ lastTaxableItem = {
347
+ type: 'addTime',
348
+ item: atItem
349
+ };
234
350
  }
235
351
  }
236
352
  }
237
- let bundlePreciseOriginTax = new import_decimal.default(0);
238
- let bundlePreciseTax = new import_decimal.default(0);
239
- let bundleRoundedOriginTax = new import_decimal.default(0);
240
- let bundleRoundedTax = new import_decimal.default(0);
241
- if (Array.isArray(item == null ? void 0 : item.bundle)) {
242
- for (let bundleItem of item == null ? void 0 : item.bundle) {
353
+
354
+ // 处理 bundle 子商品(仅原价子商品)
355
+ let bundlePreciseOriginTax = new _decimal.default(0);
356
+ let bundlePreciseTax = new _decimal.default(0);
357
+ let bundleRoundedOriginTax = new _decimal.default(0);
358
+ let bundleRoundedTax = new _decimal.default(0);
359
+ if (Array.isArray(item?.bundle)) {
360
+ for (let bundleItem of item?.bundle) {
361
+ // 只处理原价的子商品
243
362
  if (getBundleItemIsOriginalPrice(bundleItem)) {
244
- const bundleQuantity = new import_decimal.default(bundleItem.num || bundleItem.quantity || 1);
245
- const bundleUnitPrice = new import_decimal.default(
246
- bundleItem.bundle_selling_price ?? bundleItem.price ?? 0
247
- );
363
+ const bundleQuantity = new _decimal.default(bundleItem.num || bundleItem.quantity || 1);
364
+ const bundleUnitPrice = new _decimal.default(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0);
365
+
366
+ // 计算原始税费(折扣前)- 单个商品(精确值)
248
367
  const bundleOriginalTaxableBase = getDiscountedTaxableBase({
249
368
  basePrice: bundleUnitPrice,
250
- discount: new import_decimal.default(0),
251
- surchargeFee: new import_decimal.default((bundleItem == null ? void 0 : bundleItem.surcharge_fee) || 0)
369
+ discount: new _decimal.default(0),
370
+ surchargeFee: new _decimal.default(bundleItem?.surcharge_fee || 0)
371
+ });
372
+ const bundleOriginalTaxPerItemPrecise = getProductItemTax({
373
+ ...bundleItem,
374
+ total: bundleOriginalTaxableBase.toNumber(),
375
+ quantity: 1
376
+ }, {
377
+ bookingDetail,
378
+ bookingId
379
+ }, {
380
+ tax_rate,
381
+ is_price_include_tax
252
382
  });
253
- const bundleOriginalTaxPerItemPrecise = getProductItemTax(
254
- {
255
- ...bundleItem,
256
- total: bundleOriginalTaxableBase.toNumber(),
257
- quantity: 1
258
- },
259
- { bookingDetail, bookingId },
260
- { tax_rate, is_price_include_tax }
261
- );
262
- let bundleItemDiscount = new import_decimal.default(0);
383
+
384
+ // 计算平摊到该bundle商品的折扣
385
+ let bundleItemDiscount = new _decimal.default(0);
263
386
  if (productExpectAmount > 0) {
264
387
  bundleItemDiscount = bundleUnitPrice.dividedBy(productExpectAmount).times(shopDiscount);
265
388
  }
389
+
390
+ // bundle商品折后单价
266
391
  const bundleDiscountedUnitPrice = getDiscountedTaxableBase({
267
392
  basePrice: bundleUnitPrice,
268
393
  discount: bundleItemDiscount,
269
- surchargeFee: new import_decimal.default((bundleItem == null ? void 0 : bundleItem.surcharge_fee) || 0)
394
+ surchargeFee: new _decimal.default(bundleItem?.surcharge_fee || 0)
395
+ });
396
+
397
+ // 计算折后税费(折扣后)- 单个商品(精确值)
398
+ const bundleDiscountedTaxPerItemPrecise = getProductItemTax({
399
+ ...bundleItem,
400
+ total: bundleDiscountedUnitPrice.toNumber(),
401
+ quantity: 1
402
+ }, {
403
+ bookingDetail,
404
+ bookingId
405
+ }, {
406
+ tax_rate,
407
+ is_price_include_tax
270
408
  });
271
- const bundleDiscountedTaxPerItemPrecise = getProductItemTax(
272
- {
273
- ...bundleItem,
274
- total: bundleDiscountedUnitPrice.toNumber(),
275
- quantity: 1
276
- },
277
- { bookingDetail, bookingId },
278
- { tax_rate, is_price_include_tax }
279
- );
280
- const bundleOriginalTaxPerItemRounded = bundleOriginalTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
281
- const bundleDiscountedTaxPerItemRounded = bundleDiscountedTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
409
+
410
+ // 四舍五入后的值
411
+ const bundleOriginalTaxPerItemRounded = bundleOriginalTaxPerItemPrecise.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
412
+ const bundleDiscountedTaxPerItemRounded = bundleDiscountedTaxPerItemPrecise.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
413
+
414
+ // 保存到bundle商品上(单个商品的税费,四舍五入后)
282
415
  bundleItem.original_tax_fee = bundleOriginalTaxPerItemRounded.toNumber();
283
416
  bundleItem.tax_fee = bundleDiscountedTaxPerItemRounded.toNumber();
417
+
418
+ // 累加bundle税费(需要乘以bundle数量)
284
419
  bundlePreciseOriginTax = bundlePreciseOriginTax.plus(bundleOriginalTaxPerItemPrecise.times(bundleQuantity));
285
420
  bundlePreciseTax = bundlePreciseTax.plus(bundleDiscountedTaxPerItemPrecise.times(bundleQuantity));
286
421
  bundleRoundedOriginTax = bundleRoundedOriginTax.plus(bundleOriginalTaxPerItemRounded.times(bundleQuantity));
287
422
  bundleRoundedTax = bundleRoundedTax.plus(bundleDiscountedTaxPerItemRounded.times(bundleQuantity));
423
+
424
+ // 如果bundle商品有税费,记录为最后一个含税商品
288
425
  if (bundleDiscountedTaxPerItemPrecise.gt(0)) {
289
- lastTaxableItem = { type: "bundle", item: bundleItem };
426
+ lastTaxableItem = {
427
+ type: 'bundle',
428
+ item: bundleItem
429
+ };
290
430
  }
291
431
  }
292
432
  }
293
433
  }
434
+ // 主商品的原始税费和折后税费(精确值)
294
435
  const originalTaxFeePrecise = originalTaxPerItemPrecise.plus(bundlePreciseOriginTax);
295
436
  const taxFeePrecise = maxDiscountedTaxPerItemPrecise.plus(bundlePreciseTax);
296
- const originalTaxFeeRounded = originalTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).plus(bundleRoundedOriginTax);
437
+
438
+ // 主商品的原始税费和折后税费(四舍五入后)
439
+ const originalTaxFeeRounded = originalTaxPerItemPrecise.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP).plus(bundleRoundedOriginTax);
297
440
  const taxFeeRounded = maxDiscountedTaxPerItemRounded.plus(bundleRoundedTax);
298
- item.original_tax_fee = originalTaxFeeRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
299
- item.tax_fee = taxFeeRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
441
+
442
+ // 保存到商品扩展信息中(四舍五入后的值)
443
+ item.original_tax_fee = originalTaxFeeRounded.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP).toNumber();
444
+ item.tax_fee = taxFeeRounded.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP).toNumber();
445
+
446
+ // 累加到总税费(乘以数量)
300
447
  preciseOriginTax = preciseOriginTax.plus(originalTaxFeePrecise.times(quantity)).plus(addTimePreciseTax);
301
448
  preciseTax = preciseTax.plus(taxFeePrecise.times(quantity)).plus(addTimePreciseTax);
302
449
  roundedOriginTax = roundedOriginTax.plus(originalTaxFeeRounded.times(quantity)).plus(addTimeRoundedTax);
303
450
  roundedTax = roundedTax.plus(taxFeeRounded.times(quantity)).plus(addTimeRoundedTax);
304
451
  }
305
- const expectedOriginTax = preciseOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
306
- const expectedTax = preciseTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
452
+
453
+ // 计算期望的总税费(精确累加后四舍五入)
454
+ const expectedOriginTax = preciseOriginTax.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
455
+ const expectedTax = preciseTax.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
456
+
457
+ // 计算舍入差值
307
458
  const originTaxRemainder = expectedOriginTax.minus(roundedOriginTax).toNumber();
308
459
  const taxRemainder = expectedTax.minus(roundedTax).toNumber();
460
+
461
+ // 将差值追加到最后一个含税商品
309
462
  if (lastTaxableItem) {
310
463
  if (originTaxRemainder !== 0) {
311
- if (lastTaxableItem.type === "main") {
464
+ if (lastTaxableItem.type === 'main') {
312
465
  lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
313
466
  } else {
314
467
  lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
315
468
  }
316
469
  }
317
470
  if (taxRemainder !== 0) {
318
- if (lastTaxableItem.type === "main") {
471
+ if (lastTaxableItem.type === 'main') {
319
472
  lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
320
473
  } else {
321
474
  lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
322
475
  }
323
476
  }
324
477
  }
325
- return { originTax: expectedOriginTax, tax: expectedTax };
478
+ return {
479
+ originTax: expectedOriginTax,
480
+ tax: expectedTax
481
+ };
326
482
  };
327
- var getProductItemTax = (item, state, options) => {
328
- const { bookingDetail } = state;
329
- const { tax_rate, is_price_include_tax } = options;
330
- const productDiscountPrice = new import_decimal.default(item.total || 0);
331
- const quantity = new import_decimal.default(item.quantity ?? item.num ?? 1);
483
+
484
+ /**
485
+ * 计算单个商品的税费(返回精确值,不四舍五入)
486
+ * @param item 商品信息
487
+ * @param state 状态
488
+ * @param options 选项
489
+ * @returns 精确的税费值(Decimal类型)
490
+ */
491
+ const getProductItemTax = (item, state, options) => {
492
+ const {
493
+ bookingDetail
494
+ } = state;
495
+ const {
496
+ tax_rate,
497
+ is_price_include_tax
498
+ } = options;
499
+
500
+ // 折扣后的金额 = 商品金额 - 商品折扣
501
+ const productDiscountPrice = new _decimal.default(item.total || 0);
502
+ /**
503
+ * 注意:该函数被多处以“单件税费”方式调用(调用方会显式传入 quantity: 1),
504
+ * 因此这里必须优先使用 `item.quantity`,否则会出现数量被重复相乘(外层再乘一次 num)的情况。
505
+ */
506
+ const quantity = new _decimal.default(item.quantity ?? item.num ?? 1);
507
+
508
+ // 如果商品金额小于或等于0,不计算税费
332
509
  if (productDiscountPrice.lte(0)) {
333
- return new import_decimal.default(0);
510
+ return new _decimal.default(0);
334
511
  }
335
- const currentTaxRate = new import_decimal.default(
336
- (bookingDetail == null ? void 0 : bookingDetail.tax_rate) ?? (tax_rate ? tax_rate / 100 : 0)
337
- );
338
- const currentIsPriceIncludeTax = (bookingDetail == null ? void 0 : bookingDetail.is_price_include_tax) ?? is_price_include_tax ?? 0;
339
- let singleItemTax = new import_decimal.default(0);
512
+
513
+ // 优先从 bookingDetail 取税率和是否含税设置,取不到则从 options 中取(兼容新增模式)
514
+ // 注意:bookingDetail中的tax_rate不需要除以100,options 中的tax_rate需要除以100
515
+ const currentTaxRate = new _decimal.default(bookingDetail?.tax_rate ?? (tax_rate ? tax_rate / 100 : 0));
516
+ const currentIsPriceIncludeTax = bookingDetail?.is_price_include_tax ?? is_price_include_tax ?? 0;
517
+ let singleItemTax = new _decimal.default(0);
518
+
519
+ // 计算单个商品税费, 一次性商品 is_charge_tax 可能为空
340
520
  if (item.is_charge_tax === 0 || !item.is_charge_tax) {
341
- singleItemTax = new import_decimal.default(0);
521
+ // 该商品不需要收税
522
+ singleItemTax = new _decimal.default(0);
342
523
  } else {
524
+ // 该商品需要收税
343
525
  if (currentIsPriceIncludeTax === 0) {
526
+ // 价格不含税:管理端填写的单价是不含税的价格
344
527
  singleItemTax = productDiscountPrice.times(currentTaxRate);
345
528
  } else {
346
- const divisor = new import_decimal.default(1).plus(currentTaxRate);
529
+ // 价格含税:管理端填写的单价是含税的价格
530
+ // 含税总价 = 不含税价 + (不含税价 * 税率) = 不含税价 * (1 + 税率)
531
+ // 商品不含税价 = 含税总价 / (1 + 税率)
532
+ // 税 = 不含税价 * 税率
533
+ const divisor = new _decimal.default(1).plus(currentTaxRate);
347
534
  if (divisor.lte(0)) {
348
- singleItemTax = new import_decimal.default(0);
535
+ // 如果 (1 + 税率) <= 0,说明税率异常,不计算税费
536
+ singleItemTax = new _decimal.default(0);
349
537
  } else {
350
538
  singleItemTax = productDiscountPrice.dividedBy(divisor).times(currentTaxRate);
351
539
  }
352
540
  }
353
541
  }
542
+
543
+ // 结果 = 单个商品税费 × 数量(返回精确值,不四舍五入)
354
544
  return singleItemTax.times(quantity);
355
545
  };
356
- var calculateSubtotal = (items) => {
357
- if (!(items == null ? void 0 : items.length)) {
358
- return "0.00";
546
+
547
+ /**
548
+ * 计算商品小计(不含其他费用)
549
+ * @param items - 购物车商品数组
550
+ * @returns 商品总价字符串,保留2位小数
551
+ */
552
+ const calculateSubtotal = items => {
553
+ if (!items?.length) {
554
+ return '0.00';
359
555
  }
360
556
  const subtotal = items.reduce((sum, item) => {
361
- const cartItemTotalPrice = new import_decimal.default(item.summaryTotal || 0);
557
+ const cartItemTotalPrice = new _decimal.default(item.summaryTotal || 0);
362
558
  const productDiscountProductDiscountDifference = getProductDiscountProductDiscountDifference(item);
363
559
  return sum.plus(cartItemTotalPrice).sub(productDiscountProductDiscountDifference);
364
- }, new import_decimal.default(0));
560
+ }, new _decimal.default(0));
365
561
  return subtotal.toFixed(2);
366
562
  };
367
- var calculateOriginSubtotal = (items) => {
368
- if (!(items == null ? void 0 : items.length)) {
369
- return "0.00";
563
+
564
+ /**
565
+ * 计算商品小计(不含其他费用 不包含折扣卡商品券抵扣金额)
566
+ * @param items - 购物车商品数组
567
+ * @returns 商品总价字符串,保留2位小数
568
+ */
569
+ exports.calculateSubtotal = calculateSubtotal;
570
+ const calculateOriginSubtotal = items => {
571
+ if (!items?.length) {
572
+ return '0.00';
370
573
  }
371
574
  const subtotal = items.reduce((sum, item) => {
372
- const cartItemTotalPrice = new import_decimal.default(item.summaryOriginTotal || 0);
575
+ const cartItemTotalPrice = new _decimal.default(item.summaryOriginTotal || 0);
373
576
  return sum.plus(cartItemTotalPrice);
374
- }, new import_decimal.default(0));
577
+ }, new _decimal.default(0));
375
578
  return subtotal.toFixed(2);
376
579
  };
377
- var calculateTaxFee = (shopInfo, items) => {
378
- if (!(items == null ? void 0 : items.length)) {
379
- return "0.00";
580
+
581
+ /**
582
+ * @title: 单个商品的税费
583
+ * @description:
584
+ * 单个商品的税费 = 商品销售单价(折扣后) * 税率 * is_charge_tax /( 1+ 税率 * is_price_include_tax)
585
+ * $taxFee = $price * $taxRate * $isChargeTax / (1 + $taxRate * $isPriceIncludeTax);
586
+ * @return {*}
587
+ * @Author: xiangfeng.xue
588
+ */
589
+ exports.calculateOriginSubtotal = calculateOriginSubtotal;
590
+ const calculateTaxFee = (shopInfo, items) => {
591
+ if (!items?.length) {
592
+ return '0.00';
380
593
  }
381
- const { is_price_include_tax, tax_rate } = shopInfo || {};
594
+ const {
595
+ is_price_include_tax,
596
+ tax_rate
597
+ } = shopInfo || {};
382
598
  const totalTaxFee = items.reduce((sum, item) => {
383
- const cartItemTotalPrice = new import_decimal.default(item.summaryTotal || 0);
384
- const taxRate = new import_decimal.default(tax_rate || 0).div(100);
385
- const productTaxRate = cartItemTotalPrice.times(taxRate).times((item == null ? void 0 : item.is_charge_tax) || 0).div(taxRate.times(is_price_include_tax || 0).plus(1));
599
+ const cartItemTotalPrice = new _decimal.default(item.summaryTotal || 0);
600
+ const taxRate = new _decimal.default(tax_rate || 0).div(100);
601
+ const productTaxRate = cartItemTotalPrice.times(taxRate).times(item?.is_charge_tax || 0).div(taxRate.times(is_price_include_tax || 0).plus(1));
386
602
  return sum.plus(productTaxRate);
387
- }, new import_decimal.default(0));
603
+ }, new _decimal.default(0));
388
604
  return totalTaxFee;
389
605
  };
390
- var getCartItemDepositData = (item) => {
391
- var _a, _b, _c, _d;
606
+ exports.calculateTaxFee = calculateTaxFee;
607
+ const getCartItemDepositData = item => {
392
608
  const target = item;
393
- return ((_a = target == null ? void 0 : target._productOrigin) == null ? void 0 : _a.custom_deposit_data) || ((_b = target == null ? void 0 : target._origin) == null ? void 0 : _b.custom_deposit_data) || ((_d = (_c = target == null ? void 0 : target._origin) == null ? void 0 : _c.product) == null ? void 0 : _d.custom_deposit_data);
609
+ return target?._productOrigin?.custom_deposit_data || target?._origin?.custom_deposit_data || target?._origin?.product?.custom_deposit_data;
394
610
  };
395
- var getCartItemQuantity = (item) => {
396
- return new import_decimal.default((item == null ? void 0 : item.num) || 1);
611
+ const getCartItemQuantity = item => {
612
+ return new _decimal.default(item?.num || 1);
397
613
  };
398
- var calculateCartItemDepositTotal = (item) => {
399
- var _a;
614
+ const calculateCartItemDepositTotal = item => {
400
615
  const depositData = getCartItemDepositData(item);
401
- if ((depositData == null ? void 0 : depositData.has_deposit) == 1 && typeof (depositData == null ? void 0 : depositData.deposit_fixed) === "string" && typeof (depositData == null ? void 0 : depositData.deposit_percentage) === "string") {
402
- const lineTotal = new import_decimal.default(item.summaryTotal ?? item.total ?? 0);
616
+ if (depositData?.has_deposit == 1 && typeof depositData?.deposit_fixed === 'string' && typeof depositData?.deposit_percentage === 'string') {
617
+ const lineTotal = new _decimal.default(item.summaryTotal ?? item.total ?? 0);
403
618
  const quantity = getCartItemQuantity(item);
404
- const fixedTotal = new import_decimal.default(depositData.deposit_fixed || 0).times(quantity);
405
- const percentageTotal = new import_decimal.default(depositData.deposit_percentage || 0).times(lineTotal);
619
+ const fixedTotal = new _decimal.default(depositData.deposit_fixed || 0).times(quantity);
620
+ const percentageTotal = new _decimal.default(depositData.deposit_percentage || 0).times(lineTotal);
406
621
  return fixedTotal.plus(percentageTotal);
407
622
  }
408
- return new import_decimal.default(((_a = item == null ? void 0 : item.deposit) == null ? void 0 : _a.total) || 0);
623
+ return new _decimal.default(item?.deposit?.total || 0);
409
624
  };
410
- var calculateDeposit = (items) => {
411
- if (!(items == null ? void 0 : items.length)) {
412
- return void 0;
625
+
626
+ /**
627
+ * @title: 计算定金
628
+ * @param items - 购物车商品数组
629
+ * @returns 定金字符串,保留2位小数
630
+ */
631
+ const calculateDeposit = items => {
632
+ if (!items?.length) {
633
+ return undefined;
413
634
  }
414
635
  const protocols = [];
415
636
  let hasDeposit = false;
416
637
  const total = items.reduce((sum, item) => {
417
- var _a, _b;
418
- if (item == null ? void 0 : item.deposit) {
638
+ if (item?.deposit) {
419
639
  hasDeposit = true;
420
640
  const cartItemTotalPrice = calculateCartItemDepositTotal(item);
421
- (_b = (_a = item == null ? void 0 : item.deposit) == null ? void 0 : _a.protocols) == null ? void 0 : _b.forEach((protocol) => {
422
- if (protocols.findIndex((p) => p.id === protocol.id) === -1) {
641
+ // 将协议数据去重合并
642
+ item?.deposit?.protocols?.forEach(protocol => {
643
+ if (protocols.findIndex(p => p.id === protocol.id) === -1) {
423
644
  protocols.push(protocol);
424
645
  }
425
646
  });
426
647
  return sum.plus(cartItemTotalPrice);
427
648
  }
428
649
  return sum;
429
- }, new import_decimal.default(0));
650
+ }, new _decimal.default(0));
430
651
  if (hasDeposit) {
431
- return { total: total.toFixed(2), protocols, hasDeposit };
652
+ return {
653
+ total: total.toFixed(2),
654
+ protocols,
655
+ hasDeposit
656
+ };
432
657
  }
433
- return void 0;
658
+ return undefined;
434
659
  };
435
- var getSurchargeAmount = ({ bookingDetail, bookingId }, surcharge, options) => {
436
- const { isEdit } = options;
660
+
661
+ /**
662
+ * 计算订单附加费金额(订单级别合计)。
663
+ *
664
+ * - **详情未编辑**(`!options.isEdit && bookingId`)且存在后端详情时:直接返回 `bookingDetail.surcharge_fee`
665
+ * - **新增/编辑**时:对 `surcharge`(通常为 `getSurcharge` 的返回值)按 `item.value` 求和
666
+ *
667
+ * @param params 入参集合(RORO)
668
+ * @param params.bookingDetail 订单详情(详情未编辑时用于读取后端的 `surcharge_fee`),可选
669
+ * @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
670
+ * @param surcharge 附加费列表(通常来自 `getSurcharge`),元素结构至少包含 `value: number`
671
+ * @param options 计算选项
672
+ * @param options.isEdit 是否处于“编辑中”。`false` 时会优先走后端金额直取逻辑(若存在)
673
+ * @returns 订单附加费金额(number,金额单位与商品价格一致)
674
+ */
675
+ exports.calculateDeposit = calculateDeposit;
676
+ const getSurchargeAmount = ({
677
+ bookingDetail,
678
+ bookingId
679
+ }, surcharge, options) => {
680
+ const {
681
+ isEdit
682
+ } = options;
683
+ // 订单未变更过
437
684
  if (!isEdit) {
685
+ // 有后端数据则直接使用后端的数据
438
686
  if (bookingDetail && bookingId) {
439
687
  return Number(bookingDetail.surcharge_fee);
440
688
  }
441
689
  }
442
- if (!Array.isArray(surcharge))
443
- return 0;
690
+ if (!Array.isArray(surcharge)) return 0;
691
+ // 新增状态使用 getSurcharge 的返回值进行求和
444
692
  return surcharge.reduce((total, item) => {
445
693
  return total.plus(item.value || 0);
446
- }, new import_decimal.default(0)).toNumber();
694
+ }, new _decimal.default(0)).toNumber();
447
695
  };
448
- var getBundleItemIsOriginalPrice = (item) => {
449
- return (item == null ? void 0 : item.price_type) === "markup" && (item == null ? void 0 : item.price_type_ext) === "product_price";
696
+
697
+ // bundle商品是否是原价
698
+ exports.getSurchargeAmount = getSurchargeAmount;
699
+ const getBundleItemIsOriginalPrice = item => {
700
+ return item?.price_type === 'markup' && item?.price_type_ext === 'product_price';
450
701
  };
451
- var getBundleItemIsMarkupPrice = (item) => {
452
- return (item == null ? void 0 : item.price_type) === "markup" && ((item == null ? void 0 : item.price_type_ext) === "" || !(item == null ? void 0 : item.price_type_ext));
702
+
703
+ // bundle商品是否是加价
704
+ const getBundleItemIsMarkupPrice = item => {
705
+ return item?.price_type === 'markup' && (item?.price_type_ext === '' || !item?.price_type_ext);
453
706
  };
454
- var getBundleItemIsDiscountPrice = (item) => {
455
- return (item == null ? void 0 : item.price_type) === "markdown" && ((item == null ? void 0 : item.price_type_ext) === "" || !(item == null ? void 0 : item.price_type_ext));
707
+
708
+ // bundle商品是否是减价
709
+ const getBundleItemIsDiscountPrice = item => {
710
+ return item?.price_type === 'markdown' && (item?.price_type_ext === '' || !item?.price_type_ext);
456
711
  };
457
- var getBundleItemIsMarkupOrDiscountPrice = (item) => {
712
+
713
+ // bundle商品是否是加价或减价
714
+ const getBundleItemIsMarkupOrDiscountPrice = item => {
458
715
  return getBundleItemIsMarkupPrice(item) || getBundleItemIsDiscountPrice(item);
459
716
  };
460
- var getDiscountAmount = (discounts) => {
717
+ const getDiscountAmount = discounts => {
461
718
  return (discounts || []).reduce((total, discount) => {
462
- return total.add(new import_decimal.default(discount.amount || 0));
463
- }, new import_decimal.default(0)).toNumber();
719
+ return total.add(new _decimal.default(discount.amount || 0));
720
+ }, new _decimal.default(0)).toNumber();
464
721
  };
465
- var getMainProductTotal = (item) => {
466
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
467
- let total = new import_decimal.default(
468
- (item == null ? void 0 : item.main_product_selling_price) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.main_product_selling_price) ?? ((_b = item == null ? void 0 : item.metadata) == null ? void 0 : _b.main_product_original_price) ?? 0
469
- );
470
- const hasMainProductPrice = (item == null ? void 0 : item.main_product_selling_price) != null || ((_c = item == null ? void 0 : item.metadata) == null ? void 0 : _c.main_product_selling_price) != null || ((_d = item == null ? void 0 : item.metadata) == null ? void 0 : _d.main_product_original_price) != null;
722
+
723
+ /**
724
+ * 获取主商品加价减价后的总价 (主商品价格 + 子商品加价减价)
725
+ */
726
+ const getMainProductTotal = item => {
727
+ // 新语义 v2 下 `main_product_selling_price` / `metadata.main_product_selling_price`
728
+ // 已经是"含 option、含主商品折扣"的主价,直接作为主商品基准,无需再减折扣或加 option。
729
+ // 仅需叠加 markup / markdown 类 bundle(原价 bundle 的税费单独处理)。
730
+ let total = new _decimal.default(item?.main_product_selling_price ?? item?.metadata?.main_product_selling_price ?? item?.metadata?.main_product_original_price ?? 0);
731
+
732
+ // 做个兜底 如果新语义价格字段都没有,则切换回老逻辑
733
+ const hasMainProductPrice = item?.main_product_selling_price != null || item?.metadata?.main_product_selling_price != null || item?.metadata?.main_product_original_price != null;
471
734
  if (!hasMainProductPrice) {
472
- total = new import_decimal.default((item == null ? void 0 : item.main_product_selling_price) ?? ((_e = item == null ? void 0 : item.metadata) == null ? void 0 : _e.main_product_selling_price) ?? item.price ?? 0);
473
- const discount = ((_g = (_f = item == null ? void 0 : item._origin) == null ? void 0 : _f.product) == null ? void 0 : _g.discount_list) || ((_j = (_i = (_h = item == null ? void 0 : item._originData) == null ? void 0 : _h.product) == null ? void 0 : _i.discount_list) == null ? void 0 : _j.filter((item2) => {
474
- var _a2;
475
- return !((_a2 = item2 == null ? void 0 : item2.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
476
- })) || [];
735
+ total = new _decimal.default(item?.main_product_selling_price ?? item?.metadata?.main_product_selling_price ?? item.price ?? 0);
736
+ const discount = item?._origin?.product?.discount_list || item?._originData?.product?.discount_list?.filter(item => {
737
+ return !item?.metadata?.custom_product_bundle_map_id;
738
+ }) || [];
477
739
  const mainProductDiscountAmount = getDiscountAmount(discount);
478
740
  total = total.minus(mainProductDiscountAmount);
479
- if ((item == null ? void 0 : item.option) && Array.isArray(item == null ? void 0 : item.option)) {
480
- total = total.add(item == null ? void 0 : item.option.reduce((t, option) => {
481
- return t.add(new import_decimal.default(option.price || 0).mul(option.num || 1));
482
- }, new import_decimal.default(0)));
741
+
742
+ // 单规格
743
+ if (item?.option && Array.isArray(item?.option)) {
744
+ total = total.add(item?.option.reduce((t, option) => {
745
+ return t.add(new _decimal.default(option.price || 0).mul(option.num || 1));
746
+ }, new _decimal.default(0)));
483
747
  }
484
748
  }
485
- for (let bundleItem of (item == null ? void 0 : item.bundle) || []) {
749
+ for (let bundleItem of item?.bundle || []) {
486
750
  if (getBundleItemIsMarkupOrDiscountPrice(bundleItem)) {
487
- const bundleItemTotal = new import_decimal.default(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0);
751
+ // IMPORTANT: 套餐子商品如果应用了 discount,bundle_selling_price 和 price 其实都已经是折后价格了,不需要单独再减一次
752
+ const bundleItemTotal = new _decimal.default(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0);
488
753
  total = total.add(bundleItemTotal);
489
754
  }
490
755
  }
491
756
  return total.toNumber();
492
757
  };
493
- var isProductMatchSurchargeCondition = (item, options) => {
494
- const isInScheduleByDate = options == null ? void 0 : options.isInScheduleByDate;
495
- const { surchargeConfig, scheduleById = {} } = options;
496
- const { startDate, product_id, isCustomItem } = item;
758
+ /**
759
+ * 判断商品是否符合附加费条件
760
+ */
761
+ const isProductMatchSurchargeCondition = (item, options) => {
762
+ const isInScheduleByDate = options?.isInScheduleByDate;
763
+ const {
764
+ surchargeConfig,
765
+ scheduleById = {}
766
+ } = options;
767
+ const {
768
+ startDate,
769
+ product_id,
770
+ isCustomItem
771
+ } = item;
497
772
  const {
498
773
  open_product = 0,
499
774
  // 1 | 0
@@ -507,35 +782,50 @@ var isProductMatchSurchargeCondition = (item, options) => {
507
782
  // custom | all(所有日程)
508
783
  available_schedule_ids = []
509
784
  } = surchargeConfig;
785
+
786
+ // 判断商品是否符合条件
510
787
  let isProductMatch = false;
511
788
  if (open_product === 0) {
789
+ // 未开启商品限制,所有商品都符合
512
790
  isProductMatch = true;
513
791
  } else {
792
+ // 开启了商品限制
514
793
  if (is_all === 1) {
794
+ // 所有商品都收取附加费
515
795
  isProductMatch = true;
516
796
  } else {
797
+ // 指定商品收取附加费
517
798
  if (isCustomItem) {
799
+ // 自定义商品:如果是指定商品模式,自定义商品不符合条件
800
+ // 因为自定义商品没有 product_id,无法匹配到指定商品列表
518
801
  isProductMatch = false;
519
802
  } else {
803
+ // 普通商品:检查是否在指定商品列表中
520
804
  isProductMatch = available_product_ids.includes(product_id);
521
805
  }
522
806
  }
523
807
  }
808
+
809
+ // 判断日程是否符合条件
524
810
  let isScheduleMatch = false;
525
811
  if (open_schedule === 0) {
812
+ // 未开启日程限制,所有日程都符合
526
813
  isScheduleMatch = true;
527
814
  } else {
528
- if (schedule_type === "all") {
815
+ // 开启了日程限制
816
+ if (schedule_type === 'all') {
817
+ // 所有日程都收取附加费
529
818
  isScheduleMatch = true;
530
819
  } else {
820
+ // 指定日程收取附加费
531
821
  for (let j = 0; j < available_schedule_ids.length; j++) {
532
822
  const scheduleId = available_schedule_ids[j];
533
823
  const schedule = scheduleById[scheduleId];
534
824
  if (schedule) {
535
825
  const isInSchedule = isInScheduleByDate({
536
826
  // date: startDate?.format('YYYY-MM-DD HH:mm:ss') || '',
537
- date: startDate || "",
538
- schedule
827
+ date: startDate || '',
828
+ schedule: schedule
539
829
  });
540
830
  if (isInSchedule) {
541
831
  isScheduleMatch = true;
@@ -545,195 +835,264 @@ var isProductMatchSurchargeCondition = (item, options) => {
545
835
  }
546
836
  }
547
837
  }
838
+
839
+ // 商品和日程条件都要满足(取交集)
548
840
  return isProductMatch && isScheduleMatch;
549
841
  };
550
- var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
551
- var _a, _b, _c, _d;
552
- const { isEdit, isInScheduleByDate, surcharge_list, scheduleById } = options;
553
- const firstAppointmentCartItem = (_a = service.filter(
554
- (n) => !(0, import_utils.isNormalProduct)(n._productOrigin)
555
- )) == null ? void 0 : _a[0];
556
- let startDate = "";
842
+
843
+ /**
844
+ * 订单附加费各项信息
845
+ *
846
+ * - **详情未编辑**(`!options.isEdit && bookingId`)时:直接返回 `bookingDetail.surcharge`(后端计算结果)
847
+ * - **新增/编辑**时:按 `options.surcharge_list` 逐条配置计算本次订单的附加费
848
+ *
849
+ * 规则要点:
850
+ * - 匹配范围包含:主商品(`service`)、原价 bundle 子商品(`item.bundle`)、加时商品(`item.relation_details`)、以及 addons(`addons.value`)
851
+ * - 固定附加费 `fixed`:只加一次,再按商品数量分摊(向下取整保留两位),剩余小数会以 `surcharge_rounding_remainder` 形式抹平到最后一个商品
852
+ * - 百分比附加费 `percentage`:按每个商品(价格 * 数量)分别计算再累加
853
+ * - 当 `open_product === 0`:不回写到商品,只在订单级别累加;否则会把单品附加费回写到商品
854
+ *
855
+ * **副作用(可能修改入参商品对象)**:
856
+ * - 当 `open_product !== 0` 时:写入 `item.surcharge_fee`(单品单数量附加费,保留两位、向下取整)
857
+ * - 写入 `item.relation_surcharge_ids`(关联到的 surcharge 配置 id 列表)
858
+ * - 写入 `item.surcharge_rounding_remainder`(用于抹平固定附加费/总额舍入差)
859
+ *
860
+ * @param params 入参集合(RORO)
861
+ * @param params.service 服务商品数组(主商品)。元素可能包含 `bundle` / `relation_details`
862
+ * @param params.addons 附加商品容器。当前实现读取 `addons.value` 作为商品数组(所以通常传 `{ value: CartItem[] }`)
863
+ * @param params.bookingDetail 订单详情(详情未编辑时用于直接取后端的 surcharge 列表),可选
864
+ * @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
865
+ * @param options 计算选项
866
+ * @param options.isEdit 是否处于“编辑中”。`false` 且存在 `bookingId` 时会走详情直取逻辑
867
+ * @param options.surcharge_list 附加费配置列表(后端下发)。缺失/为空则返回空数组
868
+ * @param options.isInScheduleByDate 判断日期是否落在某个 schedule 内的方法(通常来自 ScheduleModule)
869
+ * @param options.scheduleById schedule 映射表:`{ [scheduleId]: schedule }`(用于根据配置的 `available_schedule_ids` 做日程匹配)
870
+ * @returns 附加费列表(仅返回金额 > 0 的项)
871
+ */
872
+ const getSurcharge = ({
873
+ service,
874
+ addons,
875
+ bookingDetail,
876
+ bookingId
877
+ }, options) => {
878
+ const {
879
+ isEdit,
880
+ isInScheduleByDate,
881
+ surcharge_list,
882
+ scheduleById
883
+ } = options;
884
+ // 在所有商品里试着找 start_date,如果没有则用当前时间
885
+ const firstAppointmentCartItem = service.filter(n => !(0, _utils.isNormalProduct)(n._productOrigin))?.[0];
886
+ let startDate = '';
557
887
  if (firstAppointmentCartItem) {
558
- startDate = firstAppointmentCartItem.start_date + " " + firstAppointmentCartItem.start_time + ":00";
888
+ startDate = firstAppointmentCartItem.start_date + ' ' + firstAppointmentCartItem.start_time + ':00';
559
889
  } else {
560
- startDate = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
890
+ startDate = (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss');
561
891
  }
892
+ // 编辑状态, 且未修改商品时直接从详情取出
562
893
  if (!isEdit && bookingId) {
563
- if (Array.isArray(bookingDetail == null ? void 0 : bookingDetail.surcharge)) {
564
- return ((bookingDetail == null ? void 0 : bookingDetail.surcharge) || []).filter((d) => Number(d.amount) > 0).map(
565
- (d, index) => {
566
- return {
567
- key: `custom_surcharge_${index}`,
568
- // label:
569
- // d.name[state.locale || 'en'] ||
570
- // d.name['en'] ||
571
- // d.name['original'],
572
- label: d.name,
573
- value: d.amount,
574
- name: d.name,
575
- surcharge_id: d.id,
576
- description: d.description,
577
- // 后端说这个固定传 default
578
- type: "default",
579
- fixed: d.fixed,
580
- amount: d.amount,
581
- percentage: d.percentage
582
- };
583
- }
584
- );
894
+ if (Array.isArray(bookingDetail?.surcharge)) {
895
+ return (bookingDetail?.surcharge || []).filter(d => Number(d.amount) > 0).map((d, index) => {
896
+ return {
897
+ key: `custom_surcharge_${index}`,
898
+ // label:
899
+ // d.name[state.locale || 'en'] ||
900
+ // d.name['en'] ||
901
+ // d.name['original'],
902
+ label: d.name,
903
+ value: d.amount,
904
+ name: d.name,
905
+ surcharge_id: d.id,
906
+ description: d.description,
907
+ // 后端说这个固定传 default
908
+ type: 'default',
909
+ fixed: d.fixed,
910
+ amount: d.amount,
911
+ percentage: d.percentage
912
+ };
913
+ });
585
914
  }
586
915
  return [];
587
916
  }
588
- resetItemsSurchargeSideEffects({ service, addons });
589
- if (!Array.isArray(surcharge_list) || !(surcharge_list == null ? void 0 : surcharge_list.length))
590
- return [];
917
+
918
+ // 用于“计算总价”的场景:每次调用都应重新计算(避免重复调用导致 surcharge_fee 累加)
919
+ // 注意:同一次调用内仍会在多条 surcharge 配置之间累加
920
+ resetItemsSurchargeSideEffects({
921
+ service,
922
+ addons
923
+ });
924
+
925
+ // 无附加费规则
926
+ if (!Array.isArray(surcharge_list) || !surcharge_list?.length) return [];
927
+
928
+ // 分别计算每种附加费总和
591
929
  const surchargeWithAmount = [];
930
+
931
+ // 遍历每种附加费配置
592
932
  for (let i = 0; i < surcharge_list.length; i++) {
593
933
  const surchargeConfig = surcharge_list[i];
594
934
  const {
595
- percentage = "0",
596
- fixed = "0",
935
+ percentage = '0',
936
+ fixed = '0',
597
937
  id,
598
938
  type,
599
939
  description,
600
940
  open_product
601
941
  } = surchargeConfig;
942
+
943
+ // 收集所有符合条件的商品
602
944
  const matchedItems = [];
945
+
946
+ // 检查service中符合条件的商品
603
947
  if (Array.isArray(service)) {
604
948
  for (let item of service) {
605
- if (isProductMatchSurchargeCondition(
606
- {
607
- isCustomItem: item.isCustomItem,
608
- startDate,
609
- product_id: item.id
610
- },
611
- {
612
- surchargeConfig,
613
- scheduleById: scheduleById || {},
614
- isInScheduleByDate
615
- }
616
- )) {
949
+ // 主商品符合附加费条件
950
+ if (isProductMatchSurchargeCondition({
951
+ isCustomItem: item.isCustomItem,
952
+ startDate,
953
+ product_id: item.id
954
+ }, {
955
+ surchargeConfig,
956
+ scheduleById: scheduleById || {},
957
+ isInScheduleByDate: isInScheduleByDate
958
+ })) {
959
+ // 主商品加价减价后的总价
617
960
  const total = getMainProductTotal({
618
961
  ...item,
619
- option: (item == null ? void 0 : item.option) || (item == null ? void 0 : item.options) || [],
620
- bundle: (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || []
962
+ option: item?.option || item?.options || [],
963
+ bundle: item?.bundle || item?.bundles || []
621
964
  });
622
965
  const mainQuantity = item.num || 1;
623
966
  matchedItems.push({
624
- total,
967
+ total: total,
625
968
  // addTimeTotal: getRelationDetailsTotal(
626
969
  // item._extend.relation_details || []
627
970
  // ),
628
971
  isMain: true,
629
972
  quantity: mainQuantity,
630
973
  item,
631
- mainQuantity
632
- // 主商品的mainQuantity等于自己的quantity
974
+ mainQuantity: mainQuantity // 主商品的mainQuantity等于自己的quantity
633
975
  });
634
976
  }
635
- const arr = (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || [];
977
+ const arr = item?.bundle || item?.bundles || [];
978
+ // 遍历子商品 原价商品符合附加费条件
636
979
  for (let bundleItem of arr) {
637
- if (getBundleItemIsOriginalPrice(bundleItem) && isProductMatchSurchargeCondition(
638
- {
639
- isCustomItem: false,
640
- startDate,
641
- product_id: bundleItem._bundle_product_id
642
- },
643
- {
644
- surchargeConfig,
645
- scheduleById: scheduleById || {},
646
- isInScheduleByDate
647
- }
648
- )) {
980
+ // bundle商品是原价且符合附加费条件
981
+ if (getBundleItemIsOriginalPrice(bundleItem) && isProductMatchSurchargeCondition({
982
+ isCustomItem: false,
983
+ startDate,
984
+ product_id: bundleItem._bundle_product_id
985
+ }, {
986
+ surchargeConfig,
987
+ scheduleById: scheduleById || {},
988
+ isInScheduleByDate: isInScheduleByDate
989
+ })) {
649
990
  const mainQuantity = item.num || 1;
650
991
  matchedItems.push({
651
992
  isMain: false,
652
- total: Number(
653
- bundleItem.bundle_selling_price ?? bundleItem.price ?? 0
654
- ),
993
+ total: Number(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0),
655
994
  quantity: bundleItem.num || bundleItem.quantity || 1,
656
995
  item: bundleItem,
657
- mainQuantity
658
- // 子商品的mainQuantity是所属主商品的quantity
996
+ mainQuantity: mainQuantity // 子商品的mainQuantity是所属主商品的quantity
659
997
  });
660
998
  }
661
999
  }
1000
+
1001
+ // 加时商品符合附加费条件
662
1002
  for (let relationDetail of item.relation_details || []) {
663
- if (isProductMatchSurchargeCondition(
664
- {
665
- isCustomItem: false,
666
- startDate,
667
- product_id: relationDetail.product_id
668
- },
669
- {
670
- surchargeConfig,
671
- scheduleById: scheduleById || {},
672
- isInScheduleByDate
673
- }
674
- )) {
1003
+ if (isProductMatchSurchargeCondition({
1004
+ isCustomItem: false,
1005
+ startDate,
1006
+ product_id: relationDetail.product_id
1007
+ }, {
1008
+ surchargeConfig,
1009
+ scheduleById: scheduleById || {},
1010
+ isInScheduleByDate: isInScheduleByDate
1011
+ })) {
675
1012
  matchedItems.push({
676
1013
  isMain: false,
677
- total: Number(
678
- (relationDetail == null ? void 0 : relationDetail.price) || ((_b = relationDetail == null ? void 0 : relationDetail.metadata) == null ? void 0 : _b.main_product_attached_bundle_selling_price)
679
- ),
1014
+ total: Number(relationDetail?.price || relationDetail?.metadata?.main_product_attached_bundle_selling_price),
680
1015
  quantity: relationDetail.num || relationDetail.quantity || 1,
681
1016
  item: relationDetail,
682
- mainQuantity: 1
683
- // 加时商品不受主商品数量影响
1017
+ mainQuantity: 1 // 加时商品不受主商品数量影响
684
1018
  });
685
1019
  }
686
1020
  }
687
1021
  }
688
1022
  }
689
- if (Array.isArray(addons == null ? void 0 : addons.value)) {
1023
+
1024
+ // 检查addons中符合条件的商品
1025
+ if (Array.isArray(addons?.value)) {
690
1026
  for (let item of addons.value) {
691
- if (isProductMatchSurchargeCondition({ ...item, startDate }, {
1027
+ if (isProductMatchSurchargeCondition({
1028
+ ...item,
1029
+ startDate
1030
+ }, {
692
1031
  surchargeConfig,
693
1032
  scheduleById: scheduleById || {},
694
- isInScheduleByDate
1033
+ isInScheduleByDate: isInScheduleByDate
695
1034
  })) {
696
1035
  matchedItems.push({
697
1036
  isMain: true,
698
1037
  total: Number(item.total),
699
1038
  quantity: item.num || 1,
700
- item,
701
- mainQuantity: 1
702
- // addons独立商品,mainQuantity为1
1039
+ item: item,
1040
+ mainQuantity: 1 // addons独立商品,mainQuantity为1
703
1041
  });
704
1042
  }
705
1043
  }
706
1044
  }
707
1045
  let finalAmount = 0;
1046
+
1047
+ // 计算商品总数:主商品和addons按quantity计算,子商品(bundle item)需要乘以主商品数量
708
1048
  const productCount = matchedItems.reduce((total, item) => {
709
1049
  if (item.isMain) {
1050
+ // 主商品和addons商品
710
1051
  return total + (item.num || item.quantity || 1);
711
1052
  } else {
1053
+ // 子商品(bundle item)和加时商品
1054
+ // 加时商品的 mainQuantity = 1,所以不受影响
1055
+ // bundle item 的 mainQuantity = 主商品数量,需要乘以实际数量
712
1056
  return total + (item.num || item.quantity || 1) * (item.mainQuantity || 1);
713
1057
  }
714
1058
  }, 0);
715
- let fixedTotal = new import_decimal.default(0);
716
- let productTotalSurcharge = new import_decimal.default(0);
1059
+
1060
+ // 追加进入的固定附加费总值
1061
+ let fixedTotal = new _decimal.default(0);
1062
+ // 追加到商品的附加费总值 用于追加抹平字段
1063
+ let productTotalSurcharge = new _decimal.default(0);
717
1064
  if (matchedItems.length > 0) {
718
- let configTotal = new import_decimal.default(0);
719
- if (fixed && new import_decimal.default(fixed).gt(0)) {
1065
+ // 基于每个商品计算附加费:max(0, 商品价格) * rate + fixed
1066
+ let configTotal = new _decimal.default(0);
1067
+
1068
+ // 计算固定附加费 - 只加一次
1069
+ if (fixed && new _decimal.default(fixed).gt(0)) {
720
1070
  configTotal = configTotal.plus(fixed);
721
1071
  }
722
- if (percentage && new import_decimal.default(percentage).gt(0) || fixed) {
723
- const percentageRate = new import_decimal.default(percentage);
1072
+
1073
+ // 计算百分比附加费 - 对每个商品单独计算
1074
+ if (percentage && new _decimal.default(percentage).gt(0) || fixed) {
1075
+ const percentageRate = new _decimal.default(percentage);
724
1076
  for (let [index, item] of matchedItems.entries()) {
725
1077
  const isLast = index === matchedItems.length - 1;
726
- const itemPrice = new import_decimal.default(Math.max(0, item.total || 0));
727
- const itemQuantity = new import_decimal.default(item.isMain ? item.quantity || 1 : item.quantity * item.mainQuantity || 1);
728
- const addTimeTotal = new import_decimal.default(item.addTimeTotal || 0);
1078
+ // 对每个商品:max(0, 价格) * 数量 * 费率
1079
+ const itemPrice = new _decimal.default(Math.max(0, item.total || 0));
1080
+ const itemQuantity = new _decimal.default(item.isMain ? item.quantity || 1 : item.quantity * item.mainQuantity || 1);
1081
+ const addTimeTotal = new _decimal.default(item.addTimeTotal || 0);
1082
+ // 单个商品总附加费
729
1083
  const itemTotalSurcharge = itemPrice.times(itemQuantity).plus(addTimeTotal).times(percentageRate);
730
1084
  configTotal = configTotal.plus(itemTotalSurcharge);
1085
+
1086
+ // 单个商品单数量附加费
731
1087
  const itemSurcharge = itemPrice.times(percentageRate);
732
- const fixedSurcharge = new import_decimal.default(1).div(productCount).times(fixed).times(100).floor().div(100).toFixed(2);
1088
+
1089
+ // 固定附加费 = 1 / 商品数量 * 固定附加费(向下取整保留两位小数)
1090
+ const fixedSurcharge = new _decimal.default(1).div(productCount).times(fixed).times(100).floor().div(100).toFixed(2);
733
1091
  const quantity = item.isMain ? item.quantity : item.quantity * item.mainQuantity;
734
- fixedTotal = fixedTotal.plus(new import_decimal.default(fixedSurcharge).times(quantity).toNumber());
1092
+ fixedTotal = fixedTotal.plus(new _decimal.default(fixedSurcharge).times(quantity).toNumber());
1093
+ // 如果是最后一个商品 判断fixed - fixedTotal 是否有剩余小数 如果有的话,追加抹平字段
735
1094
  if (isLast && fixedTotal.gt(0)) {
736
- const remaining = new import_decimal.default(fixed).minus(fixedTotal).toNumber();
1095
+ const remaining = new _decimal.default(fixed).minus(fixedTotal).toNumber();
737
1096
  if (remaining > 0) {
738
1097
  productTotalSurcharge = productTotalSurcharge.plus(remaining);
739
1098
  if (item.isMain) {
@@ -743,36 +1102,44 @@ var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
743
1102
  }
744
1103
  }
745
1104
  }
1105
+ // 只有当 open_product !== 0 时,才将附加费追加到商品身上
1106
+ // open_product === 0 表示商品未开启该附加费,只在订单级别累加
746
1107
  if (open_product !== 0) {
747
1108
  if (item.isMain) {
748
- const originSurchargeFee = new import_decimal.default(item.item.surcharge_fee || 0);
749
- const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, import_decimal.default.ROUND_DOWN).toNumber();
750
- productTotalSurcharge = productTotalSurcharge.plus(new import_decimal.default(surchargeFee).times(itemQuantity).toNumber());
1109
+ const originSurchargeFee = new _decimal.default(item.item.surcharge_fee || 0);
1110
+ // 保留两位小数
1111
+ const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, _decimal.default.ROUND_DOWN).toNumber();
1112
+ productTotalSurcharge = productTotalSurcharge.plus(new _decimal.default(surchargeFee).times(itemQuantity).toNumber());
751
1113
  item.item.surcharge_fee = surchargeFee;
752
- item.item.relation_surcharge_ids = [...((_c = item.item) == null ? void 0 : _c.relation_surcharge_ids) || [], id];
1114
+ item.item.relation_surcharge_ids = [...(item.item?.relation_surcharge_ids || []), id];
753
1115
  } else {
754
- const originSurchargeFee = new import_decimal.default(item.item.surcharge_fee || 0);
755
- const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, import_decimal.default.ROUND_DOWN).toNumber();
756
- productTotalSurcharge = productTotalSurcharge.plus(new import_decimal.default(surchargeFee).times(itemQuantity).toNumber());
1116
+ const originSurchargeFee = new _decimal.default(item.item.surcharge_fee || 0);
1117
+ // 保留两位小数
1118
+ const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, _decimal.default.ROUND_DOWN).toNumber();
1119
+ productTotalSurcharge = productTotalSurcharge.plus(new _decimal.default(surchargeFee).times(itemQuantity).toNumber());
757
1120
  item.item.surcharge_fee = surchargeFee;
758
- item.item.relation_surcharge_ids = [...((_d = item.item) == null ? void 0 : _d.relation_surcharge_ids) || [], id];
1121
+ item.item.relation_surcharge_ids = [...(item.item?.relation_surcharge_ids || []), id];
759
1122
  }
760
1123
  }
1124
+ // 最后一个商品 判断configTotal - productTotalSurcharge 是否有剩余小数 如果有的话,追加抹平字段
761
1125
  if (isLast && configTotal.minus(productTotalSurcharge).gt(0)) {
762
- const configTotalRounded = configTotal.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
1126
+ // 四舍五入configTotal
1127
+ const configTotalRounded = configTotal.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
763
1128
  if (item.isMain) {
764
- let newRoundingRemainder = new import_decimal.default(item.item.surcharge_rounding_remainder || 0);
1129
+ let newRoundingRemainder = new _decimal.default(item.item.surcharge_rounding_remainder || 0);
765
1130
  newRoundingRemainder = newRoundingRemainder.plus(configTotalRounded.minus(productTotalSurcharge));
766
1131
  item.item.surcharge_rounding_remainder = newRoundingRemainder.toNumber();
767
1132
  } else {
768
- let newRoundingRemainder = new import_decimal.default(item.item.surcharge_rounding_remainder || 0);
1133
+ let newRoundingRemainder = new _decimal.default(item.item.surcharge_rounding_remainder || 0);
769
1134
  newRoundingRemainder = newRoundingRemainder.plus(configTotalRounded.minus(productTotalSurcharge));
770
1135
  item.item.surcharge_rounding_remainder = newRoundingRemainder.toNumber();
771
1136
  }
772
1137
  }
773
1138
  }
774
1139
  }
775
- finalAmount = configTotal.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
1140
+
1141
+ // 如果该配置有金额,则添加到结果中
1142
+ finalAmount = configTotal.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP).toNumber();
776
1143
  }
777
1144
  const name = surchargeConfig.name || {};
778
1145
  if (Number(finalAmount) <= 0) {
@@ -787,7 +1154,7 @@ var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
787
1154
  surcharge_id: id,
788
1155
  description,
789
1156
  // 后端说固定传 default
790
- type: "default",
1157
+ type: 'default',
791
1158
  fixed,
792
1159
  amount: finalAmount,
793
1160
  percentage,
@@ -798,10 +1165,13 @@ var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
798
1165
  }
799
1166
  return surchargeWithAmount;
800
1167
  };
801
- function resetItemsSurchargeSideEffects({ service, addons }) {
802
- const resetItem = (item) => {
803
- if (!item)
804
- return;
1168
+ exports.getSurcharge = getSurcharge;
1169
+ function resetItemsSurchargeSideEffects({
1170
+ service,
1171
+ addons
1172
+ }) {
1173
+ const resetItem = item => {
1174
+ if (!item) return;
805
1175
  item.surcharge_fee = 0;
806
1176
  item.surcharge_rounding_remainder = 0;
807
1177
  item.relation_surcharge_ids = [];
@@ -809,29 +1179,12 @@ function resetItemsSurchargeSideEffects({ service, addons }) {
809
1179
  if (Array.isArray(service)) {
810
1180
  for (let item of service) {
811
1181
  resetItem(item);
812
- const arr = (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || [];
813
- for (let bundleItem of arr)
814
- resetItem(bundleItem);
815
- for (let relationDetail of (item == null ? void 0 : item.relation_details) || [])
816
- resetItem(relationDetail);
1182
+ const arr = item?.bundle || item?.bundles || [];
1183
+ for (let bundleItem of arr) resetItem(bundleItem);
1184
+ for (let relationDetail of item?.relation_details || []) resetItem(relationDetail);
817
1185
  }
818
1186
  }
819
- if (Array.isArray(addons == null ? void 0 : addons.value)) {
820
- for (let item of addons.value)
821
- resetItem(item);
1187
+ if (Array.isArray(addons?.value)) {
1188
+ for (let item of addons.value) resetItem(item);
822
1189
  }
823
- }
824
- // Annotate the CommonJS export names for ESM import in node:
825
- 0 && (module.exports = {
826
- calcDiscountListDifference,
827
- calculateDeposit,
828
- calculateOriginSubtotal,
829
- calculatePriceDetails,
830
- calculateSubtotal,
831
- calculateTaxFee,
832
- getBundleDiscountList,
833
- getProductDiscountProductDiscountDifference,
834
- getSurcharge,
835
- getSurchargeAmount,
836
- getTax
837
- });
1190
+ }