@pisell/pisellos 2.3.74 → 2.3.76

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 (283) hide show
  1. package/dist/core/index.js +6 -10
  2. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  3. package/dist/model/strategy/adapter/walletPass/example.js +3 -26
  4. package/dist/model/strategy/strategy-example.js +5 -19
  5. package/dist/modules/Cart/index.js +0 -3
  6. package/dist/modules/Cart/utils/cartProduct.js +0 -1
  7. package/dist/modules/Date/index.js +1 -5
  8. package/dist/modules/Discount/index.js +2 -4
  9. package/dist/modules/OpenData/index.js +0 -2
  10. package/dist/modules/Order/index.d.ts +1 -1
  11. package/dist/modules/Order/index.js +75 -91
  12. package/dist/modules/Order/types.d.ts +3 -1
  13. package/dist/modules/Payment/index.js +97 -162
  14. package/dist/modules/Rules/index.js +1 -4
  15. package/dist/modules/Schedule/index.js +0 -1
  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 +97 -129
  21. package/dist/server/modules/menu/index.js +32 -41
  22. package/dist/server/modules/order/index.js +2 -4
  23. package/dist/server/modules/products/index.js +24 -42
  24. package/dist/server/modules/quotation/index.js +29 -38
  25. package/dist/server/modules/resource/index.js +3 -4
  26. package/dist/server/modules/schedule/index.js +27 -35
  27. package/dist/server/utils/product.js +0 -1
  28. package/dist/solution/BaseSales/index.js +100 -72
  29. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +5 -0
  30. package/dist/solution/BaseSales/utils/cartPromotion.js +15 -6
  31. package/dist/solution/BookingByStep/index.js +7 -59
  32. package/dist/solution/BookingByStep/utils/capacity.js +1 -11
  33. package/dist/solution/BookingByStep/utils/resources.js +1 -3
  34. package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
  35. package/dist/solution/BookingTicket/index.js +0 -2
  36. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +6 -7
  37. package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
  38. package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
  39. package/dist/solution/BuyTickets/index.js +9 -12
  40. package/dist/solution/Checkout/index.js +177 -252
  41. package/dist/solution/Checkout/utils/index.js +4 -16
  42. package/dist/solution/RegisterAndLogin/index.js +30 -76
  43. package/dist/solution/ScanOrder/index.js +50 -60
  44. package/dist/solution/ShopDiscount/index.js +2 -7
  45. package/dist/solution/VenueBooking/index.js +45 -55
  46. package/dist/utils/task.js +15 -18
  47. package/dist/utils/watch.js +0 -1
  48. package/lib/apis/picoding.js +2 -0
  49. package/lib/core/index.js +134 -134
  50. package/lib/effects/index.js +46 -57
  51. package/lib/index.js +82 -49
  52. package/lib/model/index.js +14 -21
  53. package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
  54. package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
  55. package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
  56. package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
  57. package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
  58. package/lib/model/strategy/adapter/index.js +100 -64
  59. package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
  60. package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
  61. package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
  62. package/lib/model/strategy/adapter/itemRule/index.js +83 -57
  63. package/lib/model/strategy/adapter/itemRule/type.js +97 -36
  64. package/lib/model/strategy/adapter/promotion/adapter.js +91 -69
  65. package/lib/model/strategy/adapter/promotion/evaluator.js +444 -310
  66. package/lib/model/strategy/adapter/promotion/examples.js +222 -234
  67. package/lib/model/strategy/adapter/promotion/index.js +1 -0
  68. package/lib/model/strategy/adapter/promotion/type.js +243 -36
  69. package/lib/model/strategy/adapter/type.js +4 -16
  70. package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -150
  71. package/lib/model/strategy/adapter/walletPass/example.js +217 -190
  72. package/lib/model/strategy/adapter/walletPass/index.js +75 -51
  73. package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
  74. package/lib/model/strategy/adapter/walletPass/type.js +4 -16
  75. package/lib/model/strategy/adapter/walletPass/utils.js +588 -378
  76. package/lib/model/strategy/engine.js +270 -168
  77. package/lib/model/strategy/index.js +49 -34
  78. package/lib/model/strategy/strategy-example.js +243 -239
  79. package/lib/model/strategy/type.js +100 -40
  80. package/lib/modules/Account/index.js +39 -53
  81. package/lib/modules/Account/types.js +20 -33
  82. package/lib/modules/AccountList/index.js +116 -154
  83. package/lib/modules/AccountList/types.js +30 -31
  84. package/lib/modules/AccountList/utils.js +18 -30
  85. package/lib/modules/BaseModule.js +23 -42
  86. package/lib/modules/BookingContext/index.js +158 -136
  87. package/lib/modules/BookingContext/types.js +46 -32
  88. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +138 -146
  89. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +78 -83
  90. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +170 -150
  91. package/lib/modules/BookingContext/utils/flexible.js +38 -55
  92. package/lib/modules/BookingContext/utils/formatResourceList.js +19 -34
  93. package/lib/modules/BookingContext/utils/index.js +124 -41
  94. package/lib/modules/BookingContext/utils/noResource.js +58 -70
  95. package/lib/modules/BookingContext/utils/orderLineDisplay.js +14 -41
  96. package/lib/modules/BookingContext/utils/productExtend.js +202 -155
  97. package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
  98. package/lib/modules/BookingContext/utils/resourceSelection.js +19 -41
  99. package/lib/modules/BookingContext/utils/resources.js +209 -167
  100. package/lib/modules/BookingContext/utils/serviceTimes.js +115 -116
  101. package/lib/modules/BookingContext/utils/timeSlices.js +76 -86
  102. package/lib/modules/Cart/index.js +170 -124
  103. package/lib/modules/Cart/types.js +46 -51
  104. package/lib/modules/Cart/utils/cartAccount.js +40 -39
  105. package/lib/modules/Cart/utils/cartDate.js +56 -61
  106. package/lib/modules/Cart/utils/cartDiscount.js +28 -33
  107. package/lib/modules/Cart/utils/cartNote.js +27 -32
  108. package/lib/modules/Cart/utils/cartProduct.js +321 -251
  109. package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
  110. package/lib/modules/Cart/utils/cartResource.js +70 -78
  111. package/lib/modules/Cart/utils/changePrice.js +22 -50
  112. package/lib/modules/Cart/utils/index.js +106 -48
  113. package/lib/modules/Customer/constants.js +13 -34
  114. package/lib/modules/Customer/index.js +235 -172
  115. package/lib/modules/Customer/types.js +38 -35
  116. package/lib/modules/Date/index.js +116 -115
  117. package/lib/modules/Date/types.js +16 -28
  118. package/lib/modules/Date/utils.js +174 -123
  119. package/lib/modules/Discount/index.js +122 -127
  120. package/lib/modules/Discount/types.js +9 -31
  121. package/lib/modules/Guests/index.js +30 -56
  122. package/lib/modules/Guests/types.js +23 -33
  123. package/lib/modules/Holder/index.js +209 -189
  124. package/lib/modules/Holder/types.js +4 -16
  125. package/lib/modules/Holder/utils.js +20 -49
  126. package/lib/modules/OpenData/index.js +70 -76
  127. package/lib/modules/OpenData/types.js +4 -16
  128. package/lib/modules/OpenData/utils.js +44 -78
  129. package/lib/modules/Order/index.d.ts +1 -1
  130. package/lib/modules/Order/index.js +1733 -2121
  131. package/lib/modules/Order/payment-utils.js +77 -120
  132. package/lib/modules/Order/types.d.ts +3 -1
  133. package/lib/modules/Order/types.js +88 -35
  134. package/lib/modules/Order/utils/bundleDiscountHydration.js +41 -74
  135. package/lib/modules/Order/utils/discountProductLineIdentity.js +142 -100
  136. package/lib/modules/Order/utils/manualProductDiscount.js +124 -123
  137. package/lib/modules/Order/utils/orderCollectionIdentity.js +184 -244
  138. package/lib/modules/Order/utils.js +814 -647
  139. package/lib/modules/Payment/cash.js +20 -33
  140. package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
  141. package/lib/modules/Payment/eftpos.js +16 -30
  142. package/lib/modules/Payment/index.js +532 -399
  143. package/lib/modules/Payment/mx51.js +1 -0
  144. package/lib/modules/Payment/types.js +230 -108
  145. package/lib/modules/Payment/utils.js +52 -51
  146. package/lib/modules/Payment/walletpass.js +485 -660
  147. package/lib/modules/Product/index.js +51 -46
  148. package/lib/modules/Product/types.js +4 -16
  149. package/lib/modules/Product/utils.js +32 -33
  150. package/lib/modules/ProductList/index.js +113 -123
  151. package/lib/modules/ProductList/types.js +9 -31
  152. package/lib/modules/Quotation/index.js +81 -118
  153. package/lib/modules/Quotation/types.js +4 -16
  154. package/lib/modules/Resource/index.js +27 -59
  155. package/lib/modules/Resource/types.js +22 -32
  156. package/lib/modules/Resource/utils.js +30 -38
  157. package/lib/modules/ResourcePlanner/index.js +25 -23
  158. package/lib/modules/ResourcePlanner/localClock.js +54 -119
  159. package/lib/modules/ResourcePlanner/planner.js +589 -770
  160. package/lib/modules/ResourcePlanner/types.js +10 -29
  161. package/lib/modules/Rules/index.js +1218 -959
  162. package/lib/modules/Rules/types.js +17 -40
  163. package/lib/modules/SalesSummary/index.js +85 -90
  164. package/lib/modules/SalesSummary/types.js +4 -16
  165. package/lib/modules/SalesSummary/utils.js +355 -430
  166. package/lib/modules/ScanOrderLogger/index.js +59 -79
  167. package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
  168. package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
  169. package/lib/modules/ScanOrderLogger/types.js +4 -16
  170. package/lib/modules/Schedule/getDateIsInSchedule.js +334 -163
  171. package/lib/modules/Schedule/index.js +100 -114
  172. package/lib/modules/Schedule/type.js +4 -16
  173. package/lib/modules/Schedule/types.js +4 -16
  174. package/lib/modules/Schedule/utils.js +433 -291
  175. package/lib/modules/Step/index.js +40 -52
  176. package/lib/modules/Step/tyeps.js +4 -16
  177. package/lib/modules/Summary/index.js +66 -71
  178. package/lib/modules/Summary/types.js +4 -16
  179. package/lib/modules/Summary/utils.js +773 -418
  180. package/lib/modules/SurchargeList/index.js +46 -60
  181. package/lib/modules/SurchargeList/types.js +4 -16
  182. package/lib/modules/index.js +245 -63
  183. package/lib/plugins/app.js +4 -16
  184. package/lib/plugins/index.js +36 -25
  185. package/lib/plugins/request.js +137 -126
  186. package/lib/plugins/shopStore.js +4 -16
  187. package/lib/plugins/user.js +4 -16
  188. package/lib/plugins/window.js +171 -179
  189. package/lib/server/index.js +3050 -2665
  190. package/lib/server/modules/floor-plan/index.js +118 -134
  191. package/lib/server/modules/floor-plan/types.js +15 -30
  192. package/lib/server/modules/index.js +106 -68
  193. package/lib/server/modules/menu/index.js +142 -122
  194. package/lib/server/modules/menu/types.js +18 -31
  195. package/lib/server/modules/order/index.js +784 -1002
  196. package/lib/server/modules/order/types.js +122 -33
  197. package/lib/server/modules/order/utils/filterBookings.js +219 -194
  198. package/lib/server/modules/order/utils/filterOrders.js +118 -92
  199. package/lib/server/modules/payment/index.js +59 -83
  200. package/lib/server/modules/payment/types.js +4 -16
  201. package/lib/server/modules/products/index.js +583 -471
  202. package/lib/server/modules/products/types.js +44 -34
  203. package/lib/server/modules/quotation/index.js +137 -172
  204. package/lib/server/modules/quotation/types.js +21 -31
  205. package/lib/server/modules/resource/index.js +220 -186
  206. package/lib/server/modules/resource/types.js +42 -33
  207. package/lib/server/modules/schedule/index.js +135 -123
  208. package/lib/server/modules/schedule/types.js +14 -21
  209. package/lib/server/modules/schedule/utils.js +334 -163
  210. package/lib/server/types.js +4 -16
  211. package/lib/server/utils/index.js +25 -23
  212. package/lib/server/utils/product.js +196 -139
  213. package/lib/server/utils/schedule.js +34 -41
  214. package/lib/server/utils/small-ticket.js +479 -456
  215. package/lib/server/utils/time.js +40 -49
  216. package/lib/solution/BaseSales/index.js +1220 -1412
  217. package/lib/solution/BaseSales/types.js +42 -38
  218. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +5 -0
  219. package/lib/solution/BaseSales/utils/cartPromotion.js +652 -498
  220. package/lib/solution/BaseSales/utils/parseSalesResponse.js +85 -105
  221. package/lib/solution/BaseSales/utils/quotationPrice.js +56 -114
  222. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +108 -145
  223. package/lib/solution/BaseSales/utils.js +158 -143
  224. package/lib/solution/BookingByStep/index.js +1527 -1340
  225. package/lib/solution/BookingByStep/types.js +40 -99
  226. package/lib/solution/BookingByStep/utils/capacity.js +192 -160
  227. package/lib/solution/BookingByStep/utils/products.js +42 -52
  228. package/lib/solution/BookingByStep/utils/resources.js +527 -330
  229. package/lib/solution/BookingByStep/utils/stock.js +65 -44
  230. package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
  231. package/lib/solution/BookingTicket/index.js +607 -522
  232. package/lib/solution/BookingTicket/types.js +99 -77
  233. package/lib/solution/BookingTicket/utils/addProductDecision.js +226 -189
  234. package/lib/solution/BookingTicket/utils/addTimeAvailability.js +58 -89
  235. package/lib/solution/BookingTicket/utils/bookingStatus.js +107 -78
  236. package/lib/solution/BookingTicket/utils/cartView.js +114 -99
  237. package/lib/solution/BookingTicket/utils/exampleData.js +185 -0
  238. package/lib/solution/BookingTicket/utils/orderCustomer.js +18 -41
  239. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +219 -86
  240. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +168 -116
  241. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +79 -91
  242. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +54 -41
  243. package/lib/solution/BookingTicket/utils/scan/handleScan.js +84 -81
  244. package/lib/solution/BookingTicket/utils/scan/index.js +98 -104
  245. package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
  246. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +52 -64
  247. package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +56 -58
  248. package/lib/solution/BookingTicket/utils/weighingProductSku.js +34 -48
  249. package/lib/solution/BuyTickets/index.js +67 -70
  250. package/lib/solution/BuyTickets/types.js +22 -38
  251. package/lib/solution/Checkout/index.js +1451 -1158
  252. package/lib/solution/Checkout/types.js +91 -61
  253. package/lib/solution/Checkout/utils/index.js +228 -156
  254. package/lib/solution/PlaceOrder/index.js +55 -0
  255. package/lib/solution/RegisterAndLogin/config.js +493 -460
  256. package/lib/solution/RegisterAndLogin/index.js +633 -630
  257. package/lib/solution/RegisterAndLogin/types.js +189 -76
  258. package/lib/solution/RegisterAndLogin/utils.js +183 -125
  259. package/lib/solution/Sales/index.js +328 -324
  260. package/lib/solution/Sales/types.js +27 -33
  261. package/lib/solution/ScanOrder/index.js +832 -864
  262. package/lib/solution/ScanOrder/types.js +33 -34
  263. package/lib/solution/ScanOrder/utils.js +409 -374
  264. package/lib/solution/ShopDiscount/index.js +226 -232
  265. package/lib/solution/ShopDiscount/types.js +15 -37
  266. package/lib/solution/ShopDiscount/utils.js +300 -172
  267. package/lib/solution/UnifiedBookingSales/index.js +1035 -1201
  268. package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +99 -159
  269. package/lib/solution/UnifiedBookingSales/types.js +10 -32
  270. package/lib/solution/VenueBooking/index.js +811 -879
  271. package/lib/solution/VenueBooking/types.js +19 -39
  272. package/lib/solution/VenueBooking/utils/dateSummary.js +27 -56
  273. package/lib/solution/VenueBooking/utils/resource.js +31 -54
  274. package/lib/solution/VenueBooking/utils/slotMerge.js +94 -107
  275. package/lib/solution/VenueBooking/utils/timeSlot.js +132 -132
  276. package/lib/solution/VenueBooking/utils.js +130 -67
  277. package/lib/solution/index.js +124 -41
  278. package/lib/store/createStore.js +32 -29
  279. package/lib/types/index.js +4 -16
  280. package/lib/utils/payment-number.js +26 -46
  281. package/lib/utils/task.js +36 -36
  282. package/lib/utils/watch.js +81 -47
  283. package/package.json +2 -1
@@ -1,479 +1,756 @@
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 : subOriginTotal.plus(totalTaxFee);
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 : subOriginTotal.plus(totalTaxFee);
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 calculateDeposit = (items) => {
391
- if (!(items == null ? void 0 : items.length)) {
392
- return void 0;
606
+
607
+ /**
608
+ * @title: 计算定金
609
+ * @param items - 购物车商品数组
610
+ * @returns 定金字符串,保留2位小数
611
+ */
612
+ exports.calculateTaxFee = calculateTaxFee;
613
+ const calculateDeposit = items => {
614
+ if (!items?.length) {
615
+ return undefined;
393
616
  }
394
617
  const protocols = [];
395
618
  let hasDeposit = false;
396
619
  const total = items.reduce((sum, item) => {
397
- var _a, _b, _c;
398
- if (item == null ? void 0 : item.deposit) {
620
+ if (item?.deposit) {
399
621
  hasDeposit = true;
400
- const cartItemTotalPrice = new import_decimal.default(((_a = item == null ? void 0 : item.deposit) == null ? void 0 : _a.total) || 0);
401
- (_c = (_b = item == null ? void 0 : item.deposit) == null ? void 0 : _b.protocols) == null ? void 0 : _c.forEach((protocol) => {
402
- if (protocols.findIndex((p) => p.id === protocol.id) === -1) {
622
+ const cartItemTotalPrice = new _decimal.default(item?.deposit?.total || 0);
623
+ // 将协议数据去重合并
624
+ item?.deposit?.protocols?.forEach(protocol => {
625
+ if (protocols.findIndex(p => p.id === protocol.id) === -1) {
403
626
  protocols.push(protocol);
404
627
  }
405
628
  });
406
629
  return sum.plus(cartItemTotalPrice);
407
630
  }
408
631
  return sum;
409
- }, new import_decimal.default(0));
632
+ }, new _decimal.default(0));
410
633
  if (hasDeposit) {
411
- return { total: total.toFixed(2), protocols, hasDeposit };
634
+ return {
635
+ total: total.toFixed(2),
636
+ protocols,
637
+ hasDeposit
638
+ };
412
639
  }
413
- return void 0;
640
+ return undefined;
414
641
  };
415
- var getSurchargeAmount = ({ bookingDetail, bookingId }, surcharge, options) => {
416
- const { isEdit } = options;
642
+
643
+ /**
644
+ * 计算订单附加费金额(订单级别合计)。
645
+ *
646
+ * - **详情未编辑**(`!options.isEdit && bookingId`)且存在后端详情时:直接返回 `bookingDetail.surcharge_fee`
647
+ * - **新增/编辑**时:对 `surcharge`(通常为 `getSurcharge` 的返回值)按 `item.value` 求和
648
+ *
649
+ * @param params 入参集合(RORO)
650
+ * @param params.bookingDetail 订单详情(详情未编辑时用于读取后端的 `surcharge_fee`),可选
651
+ * @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
652
+ * @param surcharge 附加费列表(通常来自 `getSurcharge`),元素结构至少包含 `value: number`
653
+ * @param options 计算选项
654
+ * @param options.isEdit 是否处于“编辑中”。`false` 时会优先走后端金额直取逻辑(若存在)
655
+ * @returns 订单附加费金额(number,金额单位与商品价格一致)
656
+ */
657
+ exports.calculateDeposit = calculateDeposit;
658
+ const getSurchargeAmount = ({
659
+ bookingDetail,
660
+ bookingId
661
+ }, surcharge, options) => {
662
+ const {
663
+ isEdit
664
+ } = options;
665
+ // 订单未变更过
417
666
  if (!isEdit) {
667
+ // 有后端数据则直接使用后端的数据
418
668
  if (bookingDetail && bookingId) {
419
669
  return Number(bookingDetail.surcharge_fee);
420
670
  }
421
671
  }
422
- if (!Array.isArray(surcharge))
423
- return 0;
672
+ if (!Array.isArray(surcharge)) return 0;
673
+ // 新增状态使用 getSurcharge 的返回值进行求和
424
674
  return surcharge.reduce((total, item) => {
425
675
  return total.plus(item.value || 0);
426
- }, new import_decimal.default(0)).toNumber();
676
+ }, new _decimal.default(0)).toNumber();
427
677
  };
428
- var getBundleItemIsOriginalPrice = (item) => {
429
- return (item == null ? void 0 : item.price_type) === "markup" && (item == null ? void 0 : item.price_type_ext) === "product_price";
678
+
679
+ // bundle商品是否是原价
680
+ exports.getSurchargeAmount = getSurchargeAmount;
681
+ const getBundleItemIsOriginalPrice = item => {
682
+ return item?.price_type === 'markup' && item?.price_type_ext === 'product_price';
430
683
  };
431
- var getBundleItemIsMarkupPrice = (item) => {
432
- 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));
684
+
685
+ // bundle商品是否是加价
686
+ const getBundleItemIsMarkupPrice = item => {
687
+ return item?.price_type === 'markup' && (item?.price_type_ext === '' || !item?.price_type_ext);
433
688
  };
434
- var getBundleItemIsDiscountPrice = (item) => {
435
- 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));
689
+
690
+ // bundle商品是否是减价
691
+ const getBundleItemIsDiscountPrice = item => {
692
+ return item?.price_type === 'markdown' && (item?.price_type_ext === '' || !item?.price_type_ext);
436
693
  };
437
- var getBundleItemIsMarkupOrDiscountPrice = (item) => {
694
+
695
+ // bundle商品是否是加价或减价
696
+ const getBundleItemIsMarkupOrDiscountPrice = item => {
438
697
  return getBundleItemIsMarkupPrice(item) || getBundleItemIsDiscountPrice(item);
439
698
  };
440
- var getDiscountAmount = (discounts) => {
699
+ const getDiscountAmount = discounts => {
441
700
  return (discounts || []).reduce((total, discount) => {
442
- return total.add(new import_decimal.default(discount.amount || 0));
443
- }, new import_decimal.default(0)).toNumber();
701
+ return total.add(new _decimal.default(discount.amount || 0));
702
+ }, new _decimal.default(0)).toNumber();
444
703
  };
445
- var getMainProductTotal = (item) => {
446
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
447
- let total = new import_decimal.default(
448
- (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
449
- );
450
- 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;
704
+
705
+ /**
706
+ * 获取主商品加价减价后的总价 (主商品价格 + 子商品加价减价)
707
+ */
708
+ const getMainProductTotal = item => {
709
+ // 新语义 v2 `main_product_selling_price` / `metadata.main_product_selling_price`
710
+ // 已经是"含 option、含主商品折扣"的主价,直接作为主商品基准,无需再减折扣或加 option。
711
+ // 仅需叠加 markup / markdown 类 bundle(原价 bundle 的税费单独处理)。
712
+ let total = new _decimal.default(item?.main_product_selling_price ?? item?.metadata?.main_product_selling_price ?? item?.metadata?.main_product_original_price ?? 0);
713
+
714
+ // 做个兜底 如果新语义价格字段都没有,则切换回老逻辑
715
+ const hasMainProductPrice = item?.main_product_selling_price != null || item?.metadata?.main_product_selling_price != null || item?.metadata?.main_product_original_price != null;
451
716
  if (!hasMainProductPrice) {
452
- 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);
453
- 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) => {
454
- var _a2;
455
- return !((_a2 = item2 == null ? void 0 : item2.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
456
- })) || [];
717
+ total = new _decimal.default(item?.main_product_selling_price ?? item?.metadata?.main_product_selling_price ?? item.price ?? 0);
718
+ const discount = item?._origin?.product?.discount_list || item?._originData?.product?.discount_list?.filter(item => {
719
+ return !item?.metadata?.custom_product_bundle_map_id;
720
+ }) || [];
457
721
  const mainProductDiscountAmount = getDiscountAmount(discount);
458
722
  total = total.minus(mainProductDiscountAmount);
459
- if ((item == null ? void 0 : item.option) && Array.isArray(item == null ? void 0 : item.option)) {
460
- total = total.add(item == null ? void 0 : item.option.reduce((t, option) => {
461
- return t.add(new import_decimal.default(option.price || 0).mul(option.num || 1));
462
- }, new import_decimal.default(0)));
723
+
724
+ // 单规格
725
+ if (item?.option && Array.isArray(item?.option)) {
726
+ total = total.add(item?.option.reduce((t, option) => {
727
+ return t.add(new _decimal.default(option.price || 0).mul(option.num || 1));
728
+ }, new _decimal.default(0)));
463
729
  }
464
730
  }
465
- for (let bundleItem of (item == null ? void 0 : item.bundle) || []) {
731
+ for (let bundleItem of item?.bundle || []) {
466
732
  if (getBundleItemIsMarkupOrDiscountPrice(bundleItem)) {
467
- const bundleItemTotal = new import_decimal.default(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0);
733
+ // IMPORTANT: 套餐子商品如果应用了 discount,bundle_selling_price price 其实都已经是折后价格了,不需要单独再减一次
734
+ const bundleItemTotal = new _decimal.default(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0);
468
735
  total = total.add(bundleItemTotal);
469
736
  }
470
737
  }
471
738
  return total.toNumber();
472
739
  };
473
- var isProductMatchSurchargeCondition = (item, options) => {
474
- const isInScheduleByDate = options == null ? void 0 : options.isInScheduleByDate;
475
- const { surchargeConfig, scheduleById = {} } = options;
476
- const { startDate, product_id, isCustomItem } = item;
740
+ /**
741
+ * 判断商品是否符合附加费条件
742
+ */
743
+ const isProductMatchSurchargeCondition = (item, options) => {
744
+ const isInScheduleByDate = options?.isInScheduleByDate;
745
+ const {
746
+ surchargeConfig,
747
+ scheduleById = {}
748
+ } = options;
749
+ const {
750
+ startDate,
751
+ product_id,
752
+ isCustomItem
753
+ } = item;
477
754
  const {
478
755
  open_product = 0,
479
756
  // 1 | 0
@@ -487,35 +764,50 @@ var isProductMatchSurchargeCondition = (item, options) => {
487
764
  // custom | all(所有日程)
488
765
  available_schedule_ids = []
489
766
  } = surchargeConfig;
767
+
768
+ // 判断商品是否符合条件
490
769
  let isProductMatch = false;
491
770
  if (open_product === 0) {
771
+ // 未开启商品限制,所有商品都符合
492
772
  isProductMatch = true;
493
773
  } else {
774
+ // 开启了商品限制
494
775
  if (is_all === 1) {
776
+ // 所有商品都收取附加费
495
777
  isProductMatch = true;
496
778
  } else {
779
+ // 指定商品收取附加费
497
780
  if (isCustomItem) {
781
+ // 自定义商品:如果是指定商品模式,自定义商品不符合条件
782
+ // 因为自定义商品没有 product_id,无法匹配到指定商品列表
498
783
  isProductMatch = false;
499
784
  } else {
785
+ // 普通商品:检查是否在指定商品列表中
500
786
  isProductMatch = available_product_ids.includes(product_id);
501
787
  }
502
788
  }
503
789
  }
790
+
791
+ // 判断日程是否符合条件
504
792
  let isScheduleMatch = false;
505
793
  if (open_schedule === 0) {
794
+ // 未开启日程限制,所有日程都符合
506
795
  isScheduleMatch = true;
507
796
  } else {
508
- if (schedule_type === "all") {
797
+ // 开启了日程限制
798
+ if (schedule_type === 'all') {
799
+ // 所有日程都收取附加费
509
800
  isScheduleMatch = true;
510
801
  } else {
802
+ // 指定日程收取附加费
511
803
  for (let j = 0; j < available_schedule_ids.length; j++) {
512
804
  const scheduleId = available_schedule_ids[j];
513
805
  const schedule = scheduleById[scheduleId];
514
806
  if (schedule) {
515
807
  const isInSchedule = isInScheduleByDate({
516
808
  // date: startDate?.format('YYYY-MM-DD HH:mm:ss') || '',
517
- date: startDate || "",
518
- schedule
809
+ date: startDate || '',
810
+ schedule: schedule
519
811
  });
520
812
  if (isInSchedule) {
521
813
  isScheduleMatch = true;
@@ -525,195 +817,264 @@ var isProductMatchSurchargeCondition = (item, options) => {
525
817
  }
526
818
  }
527
819
  }
820
+
821
+ // 商品和日程条件都要满足(取交集)
528
822
  return isProductMatch && isScheduleMatch;
529
823
  };
530
- var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
531
- var _a, _b, _c, _d;
532
- const { isEdit, isInScheduleByDate, surcharge_list, scheduleById } = options;
533
- const firstAppointmentCartItem = (_a = service.filter(
534
- (n) => !(0, import_utils.isNormalProduct)(n._productOrigin)
535
- )) == null ? void 0 : _a[0];
536
- let startDate = "";
824
+
825
+ /**
826
+ * 订单附加费各项信息
827
+ *
828
+ * - **详情未编辑**(`!options.isEdit && bookingId`)时:直接返回 `bookingDetail.surcharge`(后端计算结果)
829
+ * - **新增/编辑**时:按 `options.surcharge_list` 逐条配置计算本次订单的附加费
830
+ *
831
+ * 规则要点:
832
+ * - 匹配范围包含:主商品(`service`)、原价 bundle 子商品(`item.bundle`)、加时商品(`item.relation_details`)、以及 addons(`addons.value`)
833
+ * - 固定附加费 `fixed`:只加一次,再按商品数量分摊(向下取整保留两位),剩余小数会以 `surcharge_rounding_remainder` 形式抹平到最后一个商品
834
+ * - 百分比附加费 `percentage`:按每个商品(价格 * 数量)分别计算再累加
835
+ * - 当 `open_product === 0`:不回写到商品,只在订单级别累加;否则会把单品附加费回写到商品
836
+ *
837
+ * **副作用(可能修改入参商品对象)**:
838
+ * - 当 `open_product !== 0` 时:写入 `item.surcharge_fee`(单品单数量附加费,保留两位、向下取整)
839
+ * - 写入 `item.relation_surcharge_ids`(关联到的 surcharge 配置 id 列表)
840
+ * - 写入 `item.surcharge_rounding_remainder`(用于抹平固定附加费/总额舍入差)
841
+ *
842
+ * @param params 入参集合(RORO)
843
+ * @param params.service 服务商品数组(主商品)。元素可能包含 `bundle` / `relation_details`
844
+ * @param params.addons 附加商品容器。当前实现读取 `addons.value` 作为商品数组(所以通常传 `{ value: CartItem[] }`)
845
+ * @param params.bookingDetail 订单详情(详情未编辑时用于直接取后端的 surcharge 列表),可选
846
+ * @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
847
+ * @param options 计算选项
848
+ * @param options.isEdit 是否处于“编辑中”。`false` 且存在 `bookingId` 时会走详情直取逻辑
849
+ * @param options.surcharge_list 附加费配置列表(后端下发)。缺失/为空则返回空数组
850
+ * @param options.isInScheduleByDate 判断日期是否落在某个 schedule 内的方法(通常来自 ScheduleModule)
851
+ * @param options.scheduleById schedule 映射表:`{ [scheduleId]: schedule }`(用于根据配置的 `available_schedule_ids` 做日程匹配)
852
+ * @returns 附加费列表(仅返回金额 > 0 的项)
853
+ */
854
+ const getSurcharge = ({
855
+ service,
856
+ addons,
857
+ bookingDetail,
858
+ bookingId
859
+ }, options) => {
860
+ const {
861
+ isEdit,
862
+ isInScheduleByDate,
863
+ surcharge_list,
864
+ scheduleById
865
+ } = options;
866
+ // 在所有商品里试着找 start_date,如果没有则用当前时间
867
+ const firstAppointmentCartItem = service.filter(n => !(0, _utils.isNormalProduct)(n._productOrigin))?.[0];
868
+ let startDate = '';
537
869
  if (firstAppointmentCartItem) {
538
- startDate = firstAppointmentCartItem.start_date + " " + firstAppointmentCartItem.start_time + ":00";
870
+ startDate = firstAppointmentCartItem.start_date + ' ' + firstAppointmentCartItem.start_time + ':00';
539
871
  } else {
540
- startDate = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
872
+ startDate = (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss');
541
873
  }
874
+ // 编辑状态, 且未修改商品时直接从详情取出
542
875
  if (!isEdit && bookingId) {
543
- if (Array.isArray(bookingDetail == null ? void 0 : bookingDetail.surcharge)) {
544
- return ((bookingDetail == null ? void 0 : bookingDetail.surcharge) || []).filter((d) => Number(d.amount) > 0).map(
545
- (d, index) => {
546
- return {
547
- key: `custom_surcharge_${index}`,
548
- // label:
549
- // d.name[state.locale || 'en'] ||
550
- // d.name['en'] ||
551
- // d.name['original'],
552
- label: d.name,
553
- value: d.amount,
554
- name: d.name,
555
- surcharge_id: d.id,
556
- description: d.description,
557
- // 后端说这个固定传 default
558
- type: "default",
559
- fixed: d.fixed,
560
- amount: d.amount,
561
- percentage: d.percentage
562
- };
563
- }
564
- );
876
+ if (Array.isArray(bookingDetail?.surcharge)) {
877
+ return (bookingDetail?.surcharge || []).filter(d => Number(d.amount) > 0).map((d, index) => {
878
+ return {
879
+ key: `custom_surcharge_${index}`,
880
+ // label:
881
+ // d.name[state.locale || 'en'] ||
882
+ // d.name['en'] ||
883
+ // d.name['original'],
884
+ label: d.name,
885
+ value: d.amount,
886
+ name: d.name,
887
+ surcharge_id: d.id,
888
+ description: d.description,
889
+ // 后端说这个固定传 default
890
+ type: 'default',
891
+ fixed: d.fixed,
892
+ amount: d.amount,
893
+ percentage: d.percentage
894
+ };
895
+ });
565
896
  }
566
897
  return [];
567
898
  }
568
- resetItemsSurchargeSideEffects({ service, addons });
569
- if (!Array.isArray(surcharge_list) || !(surcharge_list == null ? void 0 : surcharge_list.length))
570
- return [];
899
+
900
+ // 用于“计算总价”的场景:每次调用都应重新计算(避免重复调用导致 surcharge_fee 累加)
901
+ // 注意:同一次调用内仍会在多条 surcharge 配置之间累加
902
+ resetItemsSurchargeSideEffects({
903
+ service,
904
+ addons
905
+ });
906
+
907
+ // 无附加费规则
908
+ if (!Array.isArray(surcharge_list) || !surcharge_list?.length) return [];
909
+
910
+ // 分别计算每种附加费总和
571
911
  const surchargeWithAmount = [];
912
+
913
+ // 遍历每种附加费配置
572
914
  for (let i = 0; i < surcharge_list.length; i++) {
573
915
  const surchargeConfig = surcharge_list[i];
574
916
  const {
575
- percentage = "0",
576
- fixed = "0",
917
+ percentage = '0',
918
+ fixed = '0',
577
919
  id,
578
920
  type,
579
921
  description,
580
922
  open_product
581
923
  } = surchargeConfig;
924
+
925
+ // 收集所有符合条件的商品
582
926
  const matchedItems = [];
927
+
928
+ // 检查service中符合条件的商品
583
929
  if (Array.isArray(service)) {
584
930
  for (let item of service) {
585
- if (isProductMatchSurchargeCondition(
586
- {
587
- isCustomItem: item.isCustomItem,
588
- startDate,
589
- product_id: item.id
590
- },
591
- {
592
- surchargeConfig,
593
- scheduleById: scheduleById || {},
594
- isInScheduleByDate
595
- }
596
- )) {
931
+ // 主商品符合附加费条件
932
+ if (isProductMatchSurchargeCondition({
933
+ isCustomItem: item.isCustomItem,
934
+ startDate,
935
+ product_id: item.id
936
+ }, {
937
+ surchargeConfig,
938
+ scheduleById: scheduleById || {},
939
+ isInScheduleByDate: isInScheduleByDate
940
+ })) {
941
+ // 主商品加价减价后的总价
597
942
  const total = getMainProductTotal({
598
943
  ...item,
599
- option: (item == null ? void 0 : item.option) || (item == null ? void 0 : item.options) || [],
600
- bundle: (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || []
944
+ option: item?.option || item?.options || [],
945
+ bundle: item?.bundle || item?.bundles || []
601
946
  });
602
947
  const mainQuantity = item.num || 1;
603
948
  matchedItems.push({
604
- total,
949
+ total: total,
605
950
  // addTimeTotal: getRelationDetailsTotal(
606
951
  // item._extend.relation_details || []
607
952
  // ),
608
953
  isMain: true,
609
954
  quantity: mainQuantity,
610
955
  item,
611
- mainQuantity
612
- // 主商品的mainQuantity等于自己的quantity
956
+ mainQuantity: mainQuantity // 主商品的mainQuantity等于自己的quantity
613
957
  });
614
958
  }
615
- const arr = (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || [];
959
+ const arr = item?.bundle || item?.bundles || [];
960
+ // 遍历子商品 原价商品符合附加费条件
616
961
  for (let bundleItem of arr) {
617
- if (getBundleItemIsOriginalPrice(bundleItem) && isProductMatchSurchargeCondition(
618
- {
619
- isCustomItem: false,
620
- startDate,
621
- product_id: bundleItem._bundle_product_id
622
- },
623
- {
624
- surchargeConfig,
625
- scheduleById: scheduleById || {},
626
- isInScheduleByDate
627
- }
628
- )) {
962
+ // bundle商品是原价且符合附加费条件
963
+ if (getBundleItemIsOriginalPrice(bundleItem) && isProductMatchSurchargeCondition({
964
+ isCustomItem: false,
965
+ startDate,
966
+ product_id: bundleItem._bundle_product_id
967
+ }, {
968
+ surchargeConfig,
969
+ scheduleById: scheduleById || {},
970
+ isInScheduleByDate: isInScheduleByDate
971
+ })) {
629
972
  const mainQuantity = item.num || 1;
630
973
  matchedItems.push({
631
974
  isMain: false,
632
- total: Number(
633
- bundleItem.bundle_selling_price ?? bundleItem.price ?? 0
634
- ),
975
+ total: Number(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0),
635
976
  quantity: bundleItem.num || bundleItem.quantity || 1,
636
977
  item: bundleItem,
637
- mainQuantity
638
- // 子商品的mainQuantity是所属主商品的quantity
978
+ mainQuantity: mainQuantity // 子商品的mainQuantity是所属主商品的quantity
639
979
  });
640
980
  }
641
981
  }
982
+
983
+ // 加时商品符合附加费条件
642
984
  for (let relationDetail of item.relation_details || []) {
643
- if (isProductMatchSurchargeCondition(
644
- {
645
- isCustomItem: false,
646
- startDate,
647
- product_id: relationDetail.product_id
648
- },
649
- {
650
- surchargeConfig,
651
- scheduleById: scheduleById || {},
652
- isInScheduleByDate
653
- }
654
- )) {
985
+ if (isProductMatchSurchargeCondition({
986
+ isCustomItem: false,
987
+ startDate,
988
+ product_id: relationDetail.product_id
989
+ }, {
990
+ surchargeConfig,
991
+ scheduleById: scheduleById || {},
992
+ isInScheduleByDate: isInScheduleByDate
993
+ })) {
655
994
  matchedItems.push({
656
995
  isMain: false,
657
- total: Number(
658
- (relationDetail == null ? void 0 : relationDetail.price) || ((_b = relationDetail == null ? void 0 : relationDetail.metadata) == null ? void 0 : _b.main_product_attached_bundle_selling_price)
659
- ),
996
+ total: Number(relationDetail?.price || relationDetail?.metadata?.main_product_attached_bundle_selling_price),
660
997
  quantity: relationDetail.num || relationDetail.quantity || 1,
661
998
  item: relationDetail,
662
- mainQuantity: 1
663
- // 加时商品不受主商品数量影响
999
+ mainQuantity: 1 // 加时商品不受主商品数量影响
664
1000
  });
665
1001
  }
666
1002
  }
667
1003
  }
668
1004
  }
669
- if (Array.isArray(addons == null ? void 0 : addons.value)) {
1005
+
1006
+ // 检查addons中符合条件的商品
1007
+ if (Array.isArray(addons?.value)) {
670
1008
  for (let item of addons.value) {
671
- if (isProductMatchSurchargeCondition({ ...item, startDate }, {
1009
+ if (isProductMatchSurchargeCondition({
1010
+ ...item,
1011
+ startDate
1012
+ }, {
672
1013
  surchargeConfig,
673
1014
  scheduleById: scheduleById || {},
674
- isInScheduleByDate
1015
+ isInScheduleByDate: isInScheduleByDate
675
1016
  })) {
676
1017
  matchedItems.push({
677
1018
  isMain: true,
678
1019
  total: Number(item.total),
679
1020
  quantity: item.num || 1,
680
- item,
681
- mainQuantity: 1
682
- // addons独立商品,mainQuantity为1
1021
+ item: item,
1022
+ mainQuantity: 1 // addons独立商品,mainQuantity为1
683
1023
  });
684
1024
  }
685
1025
  }
686
1026
  }
687
1027
  let finalAmount = 0;
1028
+
1029
+ // 计算商品总数:主商品和addons按quantity计算,子商品(bundle item)需要乘以主商品数量
688
1030
  const productCount = matchedItems.reduce((total, item) => {
689
1031
  if (item.isMain) {
1032
+ // 主商品和addons商品
690
1033
  return total + (item.num || item.quantity || 1);
691
1034
  } else {
1035
+ // 子商品(bundle item)和加时商品
1036
+ // 加时商品的 mainQuantity = 1,所以不受影响
1037
+ // bundle item 的 mainQuantity = 主商品数量,需要乘以实际数量
692
1038
  return total + (item.num || item.quantity || 1) * (item.mainQuantity || 1);
693
1039
  }
694
1040
  }, 0);
695
- let fixedTotal = new import_decimal.default(0);
696
- let productTotalSurcharge = new import_decimal.default(0);
1041
+
1042
+ // 追加进入的固定附加费总值
1043
+ let fixedTotal = new _decimal.default(0);
1044
+ // 追加到商品的附加费总值 用于追加抹平字段
1045
+ let productTotalSurcharge = new _decimal.default(0);
697
1046
  if (matchedItems.length > 0) {
698
- let configTotal = new import_decimal.default(0);
699
- if (fixed && new import_decimal.default(fixed).gt(0)) {
1047
+ // 基于每个商品计算附加费:max(0, 商品价格) * rate + fixed
1048
+ let configTotal = new _decimal.default(0);
1049
+
1050
+ // 计算固定附加费 - 只加一次
1051
+ if (fixed && new _decimal.default(fixed).gt(0)) {
700
1052
  configTotal = configTotal.plus(fixed);
701
1053
  }
702
- if (percentage && new import_decimal.default(percentage).gt(0) || fixed) {
703
- const percentageRate = new import_decimal.default(percentage);
1054
+
1055
+ // 计算百分比附加费 - 对每个商品单独计算
1056
+ if (percentage && new _decimal.default(percentage).gt(0) || fixed) {
1057
+ const percentageRate = new _decimal.default(percentage);
704
1058
  for (let [index, item] of matchedItems.entries()) {
705
1059
  const isLast = index === matchedItems.length - 1;
706
- const itemPrice = new import_decimal.default(Math.max(0, item.total || 0));
707
- const itemQuantity = new import_decimal.default(item.isMain ? item.quantity || 1 : item.quantity * item.mainQuantity || 1);
708
- const addTimeTotal = new import_decimal.default(item.addTimeTotal || 0);
1060
+ // 对每个商品:max(0, 价格) * 数量 * 费率
1061
+ const itemPrice = new _decimal.default(Math.max(0, item.total || 0));
1062
+ const itemQuantity = new _decimal.default(item.isMain ? item.quantity || 1 : item.quantity * item.mainQuantity || 1);
1063
+ const addTimeTotal = new _decimal.default(item.addTimeTotal || 0);
1064
+ // 单个商品总附加费
709
1065
  const itemTotalSurcharge = itemPrice.times(itemQuantity).plus(addTimeTotal).times(percentageRate);
710
1066
  configTotal = configTotal.plus(itemTotalSurcharge);
1067
+
1068
+ // 单个商品单数量附加费
711
1069
  const itemSurcharge = itemPrice.times(percentageRate);
712
- const fixedSurcharge = new import_decimal.default(1).div(productCount).times(fixed).times(100).floor().div(100).toFixed(2);
1070
+
1071
+ // 固定附加费 = 1 / 商品数量 * 固定附加费(向下取整保留两位小数)
1072
+ const fixedSurcharge = new _decimal.default(1).div(productCount).times(fixed).times(100).floor().div(100).toFixed(2);
713
1073
  const quantity = item.isMain ? item.quantity : item.quantity * item.mainQuantity;
714
- fixedTotal = fixedTotal.plus(new import_decimal.default(fixedSurcharge).times(quantity).toNumber());
1074
+ fixedTotal = fixedTotal.plus(new _decimal.default(fixedSurcharge).times(quantity).toNumber());
1075
+ // 如果是最后一个商品 判断fixed - fixedTotal 是否有剩余小数 如果有的话,追加抹平字段
715
1076
  if (isLast && fixedTotal.gt(0)) {
716
- const remaining = new import_decimal.default(fixed).minus(fixedTotal).toNumber();
1077
+ const remaining = new _decimal.default(fixed).minus(fixedTotal).toNumber();
717
1078
  if (remaining > 0) {
718
1079
  productTotalSurcharge = productTotalSurcharge.plus(remaining);
719
1080
  if (item.isMain) {
@@ -723,36 +1084,44 @@ var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
723
1084
  }
724
1085
  }
725
1086
  }
1087
+ // 只有当 open_product !== 0 时,才将附加费追加到商品身上
1088
+ // open_product === 0 表示商品未开启该附加费,只在订单级别累加
726
1089
  if (open_product !== 0) {
727
1090
  if (item.isMain) {
728
- const originSurchargeFee = new import_decimal.default(item.item.surcharge_fee || 0);
729
- const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, import_decimal.default.ROUND_DOWN).toNumber();
730
- productTotalSurcharge = productTotalSurcharge.plus(new import_decimal.default(surchargeFee).times(itemQuantity).toNumber());
1091
+ const originSurchargeFee = new _decimal.default(item.item.surcharge_fee || 0);
1092
+ // 保留两位小数
1093
+ const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, _decimal.default.ROUND_DOWN).toNumber();
1094
+ productTotalSurcharge = productTotalSurcharge.plus(new _decimal.default(surchargeFee).times(itemQuantity).toNumber());
731
1095
  item.item.surcharge_fee = surchargeFee;
732
- item.item.relation_surcharge_ids = [...((_c = item.item) == null ? void 0 : _c.relation_surcharge_ids) || [], id];
1096
+ item.item.relation_surcharge_ids = [...(item.item?.relation_surcharge_ids || []), id];
733
1097
  } else {
734
- const originSurchargeFee = new import_decimal.default(item.item.surcharge_fee || 0);
735
- const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, import_decimal.default.ROUND_DOWN).toNumber();
736
- productTotalSurcharge = productTotalSurcharge.plus(new import_decimal.default(surchargeFee).times(itemQuantity).toNumber());
1098
+ const originSurchargeFee = new _decimal.default(item.item.surcharge_fee || 0);
1099
+ // 保留两位小数
1100
+ const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, _decimal.default.ROUND_DOWN).toNumber();
1101
+ productTotalSurcharge = productTotalSurcharge.plus(new _decimal.default(surchargeFee).times(itemQuantity).toNumber());
737
1102
  item.item.surcharge_fee = surchargeFee;
738
- item.item.relation_surcharge_ids = [...((_d = item.item) == null ? void 0 : _d.relation_surcharge_ids) || [], id];
1103
+ item.item.relation_surcharge_ids = [...(item.item?.relation_surcharge_ids || []), id];
739
1104
  }
740
1105
  }
1106
+ // 最后一个商品 判断configTotal - productTotalSurcharge 是否有剩余小数 如果有的话,追加抹平字段
741
1107
  if (isLast && configTotal.minus(productTotalSurcharge).gt(0)) {
742
- const configTotalRounded = configTotal.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
1108
+ // 四舍五入configTotal
1109
+ const configTotalRounded = configTotal.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
743
1110
  if (item.isMain) {
744
- let newRoundingRemainder = new import_decimal.default(item.item.surcharge_rounding_remainder || 0);
1111
+ let newRoundingRemainder = new _decimal.default(item.item.surcharge_rounding_remainder || 0);
745
1112
  newRoundingRemainder = newRoundingRemainder.plus(configTotalRounded.minus(productTotalSurcharge));
746
1113
  item.item.surcharge_rounding_remainder = newRoundingRemainder.toNumber();
747
1114
  } else {
748
- let newRoundingRemainder = new import_decimal.default(item.item.surcharge_rounding_remainder || 0);
1115
+ let newRoundingRemainder = new _decimal.default(item.item.surcharge_rounding_remainder || 0);
749
1116
  newRoundingRemainder = newRoundingRemainder.plus(configTotalRounded.minus(productTotalSurcharge));
750
1117
  item.item.surcharge_rounding_remainder = newRoundingRemainder.toNumber();
751
1118
  }
752
1119
  }
753
1120
  }
754
1121
  }
755
- finalAmount = configTotal.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
1122
+
1123
+ // 如果该配置有金额,则添加到结果中
1124
+ finalAmount = configTotal.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP).toNumber();
756
1125
  }
757
1126
  const name = surchargeConfig.name || {};
758
1127
  if (Number(finalAmount) <= 0) {
@@ -767,7 +1136,7 @@ var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
767
1136
  surcharge_id: id,
768
1137
  description,
769
1138
  // 后端说固定传 default
770
- type: "default",
1139
+ type: 'default',
771
1140
  fixed,
772
1141
  amount: finalAmount,
773
1142
  percentage,
@@ -778,10 +1147,13 @@ var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
778
1147
  }
779
1148
  return surchargeWithAmount;
780
1149
  };
781
- function resetItemsSurchargeSideEffects({ service, addons }) {
782
- const resetItem = (item) => {
783
- if (!item)
784
- return;
1150
+ exports.getSurcharge = getSurcharge;
1151
+ function resetItemsSurchargeSideEffects({
1152
+ service,
1153
+ addons
1154
+ }) {
1155
+ const resetItem = item => {
1156
+ if (!item) return;
785
1157
  item.surcharge_fee = 0;
786
1158
  item.surcharge_rounding_remainder = 0;
787
1159
  item.relation_surcharge_ids = [];
@@ -789,29 +1161,12 @@ function resetItemsSurchargeSideEffects({ service, addons }) {
789
1161
  if (Array.isArray(service)) {
790
1162
  for (let item of service) {
791
1163
  resetItem(item);
792
- const arr = (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || [];
793
- for (let bundleItem of arr)
794
- resetItem(bundleItem);
795
- for (let relationDetail of (item == null ? void 0 : item.relation_details) || [])
796
- resetItem(relationDetail);
1164
+ const arr = item?.bundle || item?.bundles || [];
1165
+ for (let bundleItem of arr) resetItem(bundleItem);
1166
+ for (let relationDetail of item?.relation_details || []) resetItem(relationDetail);
797
1167
  }
798
1168
  }
799
- if (Array.isArray(addons == null ? void 0 : addons.value)) {
800
- for (let item of addons.value)
801
- resetItem(item);
1169
+ if (Array.isArray(addons?.value)) {
1170
+ for (let item of addons.value) resetItem(item);
802
1171
  }
803
- }
804
- // Annotate the CommonJS export names for ESM import in node:
805
- 0 && (module.exports = {
806
- calcDiscountListDifference,
807
- calculateDeposit,
808
- calculateOriginSubtotal,
809
- calculatePriceDetails,
810
- calculateSubtotal,
811
- calculateTaxFee,
812
- getBundleDiscountList,
813
- getProductDiscountProductDiscountDifference,
814
- getSurcharge,
815
- getSurchargeAmount,
816
- getTax
817
- });
1172
+ }