@pisell/pisellos 0.0.569 → 0.10.2

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 (328) hide show
  1. package/dist/core/index.js +10 -6
  2. package/dist/index.d.ts +0 -1
  3. package/dist/index.js +0 -3
  4. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  5. package/dist/model/strategy/adapter/walletPass/evaluator.js +7 -5
  6. package/dist/model/strategy/adapter/walletPass/example.js +26 -3
  7. package/dist/model/strategy/adapter/walletPass/index.js +5 -5
  8. package/dist/model/strategy/adapter/walletPass/type.d.ts +0 -3
  9. package/dist/model/strategy/adapter/walletPass/utils.d.ts +0 -26
  10. package/dist/model/strategy/adapter/walletPass/utils.js +17 -92
  11. package/dist/model/strategy/strategy-example.js +19 -5
  12. package/dist/modules/BaseModule.d.ts +1 -1
  13. package/dist/modules/BaseModule.js +8 -10
  14. package/dist/modules/Cart/index.js +3 -0
  15. package/dist/modules/Cart/utils/cartProduct.js +1 -0
  16. package/dist/modules/Cart/utils/cartResource.js +0 -2
  17. package/dist/modules/Cart/utils/changePrice.js +9 -16
  18. package/dist/modules/Date/index.js +5 -1
  19. package/dist/modules/Discount/index.d.ts +0 -1
  20. package/dist/modules/Discount/index.js +7 -22
  21. package/dist/modules/Discount/types.d.ts +0 -1
  22. package/dist/modules/OpenData/index.js +2 -0
  23. package/dist/modules/Order/index.js +70 -40
  24. package/dist/modules/Payment/index.js +162 -97
  25. package/dist/modules/Payment/types.d.ts +4 -8
  26. package/dist/modules/Payment/walletpass.d.ts +0 -2
  27. package/dist/modules/Payment/walletpass.js +5 -4
  28. package/dist/modules/ProductList/index.d.ts +1 -1
  29. package/dist/modules/ProductList/index.js +3 -12
  30. package/dist/modules/ProductList/types.d.ts +0 -1
  31. package/dist/modules/Rules/index.js +126 -427
  32. package/dist/modules/SalesSummary/utils.js +1 -2
  33. package/dist/modules/Schedule/getDateIsInSchedule.js +0 -5
  34. package/dist/modules/Schedule/index.js +1 -0
  35. package/dist/modules/Schedule/utils.js +1 -0
  36. package/dist/modules/Step/index.js +1 -0
  37. package/dist/modules/Summary/utils.js +22 -43
  38. package/dist/plugins/request.js +4 -1
  39. package/dist/plugins/window.js +6 -2
  40. package/dist/server/index.js +129 -97
  41. package/dist/server/modules/menu/index.js +41 -32
  42. package/dist/server/modules/order/index.js +4 -2
  43. package/dist/server/modules/products/index.js +42 -24
  44. package/dist/server/modules/quotation/index.js +38 -29
  45. package/dist/server/modules/resource/index.js +4 -3
  46. package/dist/server/modules/schedule/index.js +35 -27
  47. package/dist/server/utils/product.js +1 -0
  48. package/dist/solution/BaseSales/index.js +41 -38
  49. package/dist/solution/BookingByStep/index.d.ts +1 -1
  50. package/dist/solution/BookingByStep/index.js +60 -11
  51. package/dist/solution/BookingByStep/utils/capacity.js +11 -1
  52. package/dist/solution/BookingByStep/utils/resources.js +3 -1
  53. package/dist/solution/BookingByStep/utils/timeslots.js +43 -2
  54. package/dist/solution/BookingTicket/index.d.ts +1 -1
  55. package/dist/solution/BookingTicket/index.js +2 -0
  56. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +7 -6
  57. package/dist/solution/BookingTicket/utils/scan/handleScan.js +31 -25
  58. package/dist/solution/BookingTicket/utils/scan/index.js +10 -6
  59. package/dist/solution/BuyTickets/index.js +12 -9
  60. package/dist/solution/Checkout/index.js +252 -177
  61. package/dist/solution/Checkout/utils/index.js +16 -4
  62. package/dist/solution/RegisterAndLogin/index.js +76 -30
  63. package/dist/solution/ScanOrder/index.js +60 -50
  64. package/dist/solution/ShopDiscount/index.js +14 -15
  65. package/dist/solution/ShopDiscount/types.d.ts +4 -5
  66. package/dist/solution/ShopDiscount/utils.d.ts +0 -9
  67. package/dist/solution/ShopDiscount/utils.js +0 -9
  68. package/dist/solution/VenueBooking/index.d.ts +3 -31
  69. package/dist/solution/VenueBooking/index.js +496 -651
  70. package/dist/solution/VenueBooking/types.d.ts +1 -3
  71. package/dist/solution/VenueBooking/types.js +0 -1
  72. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
  73. package/dist/solution/VenueBooking/utils/dateSummary.js +25 -12
  74. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
  75. package/dist/solution/VenueBooking/utils/timeSlot.js +4 -9
  76. package/dist/types/index.d.ts +1 -1
  77. package/dist/utils/task.js +18 -15
  78. package/dist/utils/watch.js +1 -0
  79. package/lib/apis/picoding.js +0 -2
  80. package/lib/core/index.js +132 -130
  81. package/lib/effects/index.js +57 -46
  82. package/lib/index.d.ts +0 -1
  83. package/lib/index.js +50 -92
  84. package/lib/model/index.js +21 -14
  85. package/lib/model/strategy/adapter/dataVariant/adapter.js +50 -38
  86. package/lib/model/strategy/adapter/dataVariant/evaluator.js +236 -162
  87. package/lib/model/strategy/adapter/dataVariant/examples.js +237 -229
  88. package/lib/model/strategy/adapter/dataVariant/index.js +34 -39
  89. package/lib/model/strategy/adapter/dataVariant/type.js +28 -57
  90. package/lib/model/strategy/adapter/index.js +64 -100
  91. package/lib/model/strategy/adapter/itemRule/adapter.js +144 -156
  92. package/lib/model/strategy/adapter/itemRule/evaluator.js +48 -36
  93. package/lib/model/strategy/adapter/itemRule/examples.js +225 -295
  94. package/lib/model/strategy/adapter/itemRule/index.js +57 -83
  95. package/lib/model/strategy/adapter/itemRule/type.js +36 -97
  96. package/lib/model/strategy/adapter/promotion/adapter.js +63 -84
  97. package/lib/model/strategy/adapter/promotion/evaluator.js +231 -381
  98. package/lib/model/strategy/adapter/promotion/examples.js +159 -139
  99. package/lib/model/strategy/adapter/promotion/index.js +49 -1
  100. package/lib/model/strategy/adapter/promotion/type.js +35 -199
  101. package/lib/model/strategy/adapter/type.js +16 -4
  102. package/lib/model/strategy/adapter/walletPass/evaluator.js +152 -180
  103. package/lib/model/strategy/adapter/walletPass/example.js +190 -217
  104. package/lib/model/strategy/adapter/walletPass/index.js +51 -75
  105. package/lib/model/strategy/adapter/walletPass/locales.js +58 -36
  106. package/lib/model/strategy/adapter/walletPass/type.d.ts +0 -3
  107. package/lib/model/strategy/adapter/walletPass/type.js +16 -4
  108. package/lib/model/strategy/adapter/walletPass/utils.d.ts +0 -26
  109. package/lib/model/strategy/adapter/walletPass/utils.js +383 -678
  110. package/lib/model/strategy/engine.js +168 -270
  111. package/lib/model/strategy/index.js +34 -49
  112. package/lib/model/strategy/strategy-example.js +239 -243
  113. package/lib/model/strategy/type.js +40 -100
  114. package/lib/modules/Account/index.js +53 -39
  115. package/lib/modules/Account/types.js +33 -20
  116. package/lib/modules/AccountList/index.js +154 -116
  117. package/lib/modules/AccountList/types.js +31 -30
  118. package/lib/modules/AccountList/utils.js +30 -18
  119. package/lib/modules/BaseModule.d.ts +1 -1
  120. package/lib/modules/BaseModule.js +46 -25
  121. package/lib/modules/BookingContext/index.js +136 -158
  122. package/lib/modules/BookingContext/types.js +32 -46
  123. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +143 -131
  124. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +82 -75
  125. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +150 -170
  126. package/lib/modules/BookingContext/utils/flexible.js +55 -38
  127. package/lib/modules/BookingContext/utils/formatResourceList.js +34 -19
  128. package/lib/modules/BookingContext/utils/index.js +41 -124
  129. package/lib/modules/BookingContext/utils/noResource.js +70 -58
  130. package/lib/modules/BookingContext/utils/orderLineDisplay.js +41 -14
  131. package/lib/modules/BookingContext/utils/productExtend.js +155 -202
  132. package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
  133. package/lib/modules/BookingContext/utils/resourceSelection.js +41 -19
  134. package/lib/modules/BookingContext/utils/resources.js +167 -209
  135. package/lib/modules/BookingContext/utils/serviceTimes.js +116 -115
  136. package/lib/modules/BookingContext/utils/timeSlices.js +80 -70
  137. package/lib/modules/Cart/index.js +124 -170
  138. package/lib/modules/Cart/types.js +51 -46
  139. package/lib/modules/Cart/utils/cartAccount.js +39 -40
  140. package/lib/modules/Cart/utils/cartDate.js +61 -56
  141. package/lib/modules/Cart/utils/cartDiscount.js +33 -28
  142. package/lib/modules/Cart/utils/cartNote.js +32 -27
  143. package/lib/modules/Cart/utils/cartProduct.js +251 -321
  144. package/lib/modules/Cart/utils/cartRelationForms.js +35 -29
  145. package/lib/modules/Cart/utils/cartResource.js +78 -72
  146. package/lib/modules/Cart/utils/changePrice.js +50 -28
  147. package/lib/modules/Cart/utils/index.js +48 -106
  148. package/lib/modules/Customer/constants.js +34 -13
  149. package/lib/modules/Customer/index.js +169 -232
  150. package/lib/modules/Customer/types.js +35 -38
  151. package/lib/modules/Date/index.js +115 -116
  152. package/lib/modules/Date/types.js +28 -16
  153. package/lib/modules/Date/utils.js +123 -174
  154. package/lib/modules/Discount/index.d.ts +0 -1
  155. package/lib/modules/Discount/index.js +128 -130
  156. package/lib/modules/Discount/types.d.ts +0 -1
  157. package/lib/modules/Discount/types.js +31 -9
  158. package/lib/modules/Guests/index.js +56 -30
  159. package/lib/modules/Guests/types.js +33 -23
  160. package/lib/modules/Holder/index.js +189 -209
  161. package/lib/modules/Holder/types.js +16 -4
  162. package/lib/modules/Holder/utils.js +49 -20
  163. package/lib/modules/OpenData/index.js +76 -69
  164. package/lib/modules/OpenData/types.js +16 -4
  165. package/lib/modules/OpenData/utils.js +78 -44
  166. package/lib/modules/Order/index.js +1909 -1572
  167. package/lib/modules/Order/types.js +35 -78
  168. package/lib/modules/Order/utils/bundleDiscountHydration.js +74 -41
  169. package/lib/modules/Order/utils/manualProductDiscount.js +123 -124
  170. package/lib/modules/Order/utils/orderCollectionIdentity.js +210 -148
  171. package/lib/modules/Order/utils.js +634 -799
  172. package/lib/modules/Payment/cash.js +33 -20
  173. package/lib/modules/Payment/cashRecommendationAlgorithm.js +76 -145
  174. package/lib/modules/Payment/eftpos.js +30 -16
  175. package/lib/modules/Payment/index.js +378 -518
  176. package/lib/modules/Payment/mx51.js +0 -1
  177. package/lib/modules/Payment/types.d.ts +4 -8
  178. package/lib/modules/Payment/types.js +107 -216
  179. package/lib/modules/Payment/utils.js +48 -51
  180. package/lib/modules/Payment/walletpass.d.ts +0 -2
  181. package/lib/modules/Payment/walletpass.js +211 -226
  182. package/lib/modules/Product/index.js +46 -51
  183. package/lib/modules/Product/types.js +16 -4
  184. package/lib/modules/Product/utils.js +33 -32
  185. package/lib/modules/ProductList/index.d.ts +1 -1
  186. package/lib/modules/ProductList/index.js +117 -117
  187. package/lib/modules/ProductList/types.d.ts +0 -1
  188. package/lib/modules/ProductList/types.js +31 -9
  189. package/lib/modules/Quotation/index.js +100 -66
  190. package/lib/modules/Quotation/types.js +16 -4
  191. package/lib/modules/Resource/index.js +59 -27
  192. package/lib/modules/Resource/types.js +32 -22
  193. package/lib/modules/Resource/utils.js +38 -30
  194. package/lib/modules/ResourcePlanner/index.js +61 -60
  195. package/lib/modules/ResourcePlanner/planner.js +384 -346
  196. package/lib/modules/ResourcePlanner/types.js +16 -4
  197. package/lib/modules/Rules/index.js +903 -1475
  198. package/lib/modules/Rules/types.js +40 -17
  199. package/lib/modules/SalesSummary/index.js +90 -85
  200. package/lib/modules/SalesSummary/types.js +16 -4
  201. package/lib/modules/SalesSummary/utils.js +427 -351
  202. package/lib/modules/ScanOrderLogger/index.js +79 -59
  203. package/lib/modules/ScanOrderLogger/providers/feishu.js +78 -54
  204. package/lib/modules/ScanOrderLogger/providers/grafana.js +36 -13
  205. package/lib/modules/ScanOrderLogger/types.js +16 -4
  206. package/lib/modules/Schedule/getDateIsInSchedule.js +163 -339
  207. package/lib/modules/Schedule/index.js +114 -100
  208. package/lib/modules/Schedule/type.js +16 -4
  209. package/lib/modules/Schedule/types.js +16 -4
  210. package/lib/modules/Schedule/utils.js +291 -433
  211. package/lib/modules/Step/index.js +52 -40
  212. package/lib/modules/Step/tyeps.js +16 -4
  213. package/lib/modules/Summary/index.js +71 -66
  214. package/lib/modules/Summary/types.js +16 -4
  215. package/lib/modules/Summary/utils.js +418 -791
  216. package/lib/modules/SurchargeList/index.js +60 -46
  217. package/lib/modules/SurchargeList/types.js +16 -4
  218. package/lib/modules/index.js +63 -245
  219. package/lib/plugins/app.js +16 -4
  220. package/lib/plugins/index.js +25 -36
  221. package/lib/plugins/request.js +126 -137
  222. package/lib/plugins/shopStore.js +16 -4
  223. package/lib/plugins/user.js +16 -4
  224. package/lib/plugins/window.js +179 -171
  225. package/lib/server/index.js +2337 -2675
  226. package/lib/server/modules/floor-plan/index.js +123 -102
  227. package/lib/server/modules/floor-plan/types.js +30 -15
  228. package/lib/server/modules/index.js +68 -106
  229. package/lib/server/modules/menu/index.js +122 -146
  230. package/lib/server/modules/menu/types.js +31 -18
  231. package/lib/server/modules/order/index.js +642 -567
  232. package/lib/server/modules/order/types.js +32 -117
  233. package/lib/server/modules/order/utils/filterBookings.js +194 -219
  234. package/lib/server/modules/order/utils/filterOrders.js +92 -118
  235. package/lib/server/modules/payment/index.js +83 -59
  236. package/lib/server/modules/payment/types.js +16 -4
  237. package/lib/server/modules/products/index.js +459 -575
  238. package/lib/server/modules/products/types.js +34 -44
  239. package/lib/server/modules/quotation/index.js +172 -137
  240. package/lib/server/modules/quotation/types.js +31 -21
  241. package/lib/server/modules/resource/index.js +184 -213
  242. package/lib/server/modules/resource/types.js +33 -42
  243. package/lib/server/modules/schedule/index.js +123 -135
  244. package/lib/server/modules/schedule/types.js +21 -14
  245. package/lib/server/modules/schedule/utils.js +163 -334
  246. package/lib/server/types.js +16 -4
  247. package/lib/server/utils/index.js +23 -25
  248. package/lib/server/utils/product.js +139 -196
  249. package/lib/server/utils/schedule.js +41 -34
  250. package/lib/server/utils/small-ticket.js +456 -478
  251. package/lib/server/utils/time.js +49 -40
  252. package/lib/solution/BaseSales/index.js +1016 -850
  253. package/lib/solution/BaseSales/types.js +37 -41
  254. package/lib/solution/BaseSales/utils/cartPromotion.js +460 -611
  255. package/lib/solution/BaseSales/utils/parseSalesResponse.js +105 -85
  256. package/lib/solution/BaseSales/utils/quotationPrice.js +114 -56
  257. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +143 -102
  258. package/lib/solution/BaseSales/utils.js +140 -155
  259. package/lib/solution/BookingByStep/index.d.ts +1 -1
  260. package/lib/solution/BookingByStep/index.js +1340 -1530
  261. package/lib/solution/BookingByStep/types.js +99 -40
  262. package/lib/solution/BookingByStep/utils/capacity.js +160 -192
  263. package/lib/solution/BookingByStep/utils/products.js +52 -42
  264. package/lib/solution/BookingByStep/utils/resources.js +330 -527
  265. package/lib/solution/BookingByStep/utils/stock.js +44 -65
  266. package/lib/solution/BookingByStep/utils/timeslots.js +131 -129
  267. package/lib/solution/BookingTicket/index.d.ts +1 -1
  268. package/lib/solution/BookingTicket/index.js +459 -543
  269. package/lib/solution/BookingTicket/types.js +77 -99
  270. package/lib/solution/BookingTicket/utils/addProductDecision.js +184 -219
  271. package/lib/solution/BookingTicket/utils/addTimeAvailability.js +89 -58
  272. package/lib/solution/BookingTicket/utils/bookingStatus.js +78 -107
  273. package/lib/solution/BookingTicket/utils/cartView.js +94 -110
  274. package/lib/solution/BookingTicket/utils/exampleData.js +0 -185
  275. package/lib/solution/BookingTicket/utils/orderCustomer.js +41 -18
  276. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +86 -219
  277. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +93 -144
  278. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +91 -79
  279. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +41 -54
  280. package/lib/solution/BookingTicket/utils/scan/handleScan.js +81 -84
  281. package/lib/solution/BookingTicket/utils/scan/index.js +104 -98
  282. package/lib/solution/BookingTicket/utils/scan/scanCache.js +43 -90
  283. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +64 -52
  284. package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +58 -56
  285. package/lib/solution/BuyTickets/index.js +70 -67
  286. package/lib/solution/BuyTickets/types.js +38 -22
  287. package/lib/solution/Checkout/index.js +1158 -1451
  288. package/lib/solution/Checkout/types.js +61 -91
  289. package/lib/solution/Checkout/utils/index.js +156 -228
  290. package/lib/solution/PlaceOrder/index.js +0 -55
  291. package/lib/solution/RegisterAndLogin/config.js +460 -493
  292. package/lib/solution/RegisterAndLogin/index.js +630 -633
  293. package/lib/solution/RegisterAndLogin/types.js +76 -189
  294. package/lib/solution/RegisterAndLogin/utils.js +125 -183
  295. package/lib/solution/Sales/index.js +320 -317
  296. package/lib/solution/Sales/types.js +33 -27
  297. package/lib/solution/ScanOrder/index.js +862 -831
  298. package/lib/solution/ScanOrder/types.js +34 -33
  299. package/lib/solution/ScanOrder/utils.js +371 -406
  300. package/lib/solution/ShopDiscount/index.js +233 -235
  301. package/lib/solution/ShopDiscount/types.d.ts +4 -5
  302. package/lib/solution/ShopDiscount/types.js +37 -15
  303. package/lib/solution/ShopDiscount/utils.d.ts +0 -9
  304. package/lib/solution/ShopDiscount/utils.js +172 -309
  305. package/lib/solution/UnifiedBookingSales/index.js +405 -379
  306. package/lib/solution/UnifiedBookingSales/types.js +31 -12
  307. package/lib/solution/VenueBooking/index.d.ts +3 -31
  308. package/lib/solution/VenueBooking/index.js +916 -967
  309. package/lib/solution/VenueBooking/types.d.ts +1 -3
  310. package/lib/solution/VenueBooking/types.js +39 -20
  311. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
  312. package/lib/solution/VenueBooking/utils/dateSummary.js +62 -25
  313. package/lib/solution/VenueBooking/utils/resource.js +54 -31
  314. package/lib/solution/VenueBooking/utils/slotMerge.js +107 -94
  315. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
  316. package/lib/solution/VenueBooking/utils/timeSlot.js +133 -138
  317. package/lib/solution/VenueBooking/utils.js +67 -130
  318. package/lib/solution/index.js +41 -124
  319. package/lib/store/createStore.js +29 -32
  320. package/lib/types/index.d.ts +1 -1
  321. package/lib/types/index.js +16 -4
  322. package/lib/utils/task.js +36 -36
  323. package/lib/utils/watch.js +47 -81
  324. package/package.json +2 -4
  325. package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
  326. package/dist/solution/VenueBooking/utils/smartPricing.js +0 -233
  327. package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
  328. package/lib/solution/VenueBooking/utils/smartPricing.js +0 -192
@@ -1,137 +1,94 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
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/solution/BaseSales/utils/cartPromotion.ts
30
+ var cartPromotion_exports = {};
31
+ __export(cartPromotion_exports, {
32
+ appendPromotionTags: () => appendPromotionTags,
33
+ buildConsolidateKeyForPromotion: () => buildConsolidateKeyForPromotion,
34
+ calculateUnfulfilledPromotions: () => calculateUnfulfilledPromotions,
35
+ extractProductMatchIdentifiersFromStrategyConfig: () => extractProductMatchIdentifiersFromStrategyConfig,
36
+ getOrderProductBasePrice: () => getOrderProductBasePrice,
37
+ getOrderProductOriginalPriceForPromotion: () => getOrderProductOriginalPriceForPromotion,
38
+ getOrderProductUid: () => getOrderProductUid,
39
+ mergeIdenticalPromotionCartLines: () => mergeIdenticalPromotionCartLines,
40
+ processCartPromotion: () => processCartPromotion,
41
+ resolveStrategyEligibleProducts: () => resolveStrategyEligibleProducts,
42
+ resolveStrategyRequiredQuantity: () => resolveStrategyRequiredQuantity
5
43
  });
6
- exports.appendPromotionTags = appendPromotionTags;
7
- exports.buildConsolidateKeyForPromotion = buildConsolidateKeyForPromotion;
8
- exports.calculateUnfulfilledPromotions = calculateUnfulfilledPromotions;
9
- exports.extractProductMatchIdentifiersFromStrategyConfig = extractProductMatchIdentifiersFromStrategyConfig;
10
- exports.getOrderProductBasePrice = getOrderProductBasePrice;
11
- exports.getOrderProductOriginalPriceForPromotion = getOrderProductOriginalPriceForPromotion;
12
- exports.getOrderProductUid = getOrderProductUid;
13
- exports.mergeIdenticalPromotionCartLines = mergeIdenticalPromotionCartLines;
14
- exports.processCartPromotion = processCartPromotion;
15
- exports.resolveStrategyEligibleProducts = resolveStrategyEligibleProducts;
16
- exports.resolveStrategyRequiredQuantity = resolveStrategyRequiredQuantity;
17
- var _decimal = _interopRequireDefault(require("decimal.js"));
18
- var _lodashEs = require("lodash-es");
19
- var _utils = require("../../../modules/Order/utils");
20
- var _utils2 = require("../../ScanOrder/utils");
21
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
- /**
23
- * Cart promotion 工具集(OS 内部纯函数)
24
- *
25
- * 这是 `private-materials/components/booking/hooks/usePromotion.ts` 中促销/赠品
26
- * 核心计算(evaluator → 拆分 / 计价 → 赠品差异化 / 未满足提示 / 标签)的 OS 等价实现。
27
- *
28
- * 与 legacy 的关键差异:
29
- * - legacy 操作 booking `_extend.*` 形状;OS 操作 `OrderProduct.metadata.*` 形状。
30
- * - 行唯一标识不再用 `_id`,统一改用 `metadata.unique_identification_number`。
31
- * - 赠品标签存到 `metadata._giftInfo`;主商品促销信息存到 `metadata._promotion`;
32
- * 商品卡列表的促销 tag 存到 `metadata._promotionTags`。
33
- *
34
- * 仅暴露纯函数,不持有任何状态;评估器以参数注入。
35
- *
36
- * @example
37
- * const evaluator = appHelper.utils.promotionEvaluator;
38
- * const result = processCartPromotion(tempOrder.products, evaluator);
39
- * // result.products: 处理后的商品(带 _promotion / 拆分)
40
- * // result.giftActions: 需要 add / reduce / remove 的赠品操作
41
- * // result.unfulfilledPromotions: 未满足策略列表(购物车底部 alert)
42
- */
43
-
44
- // ============================================
45
- // 类型定义
46
- // ============================================
47
-
48
- /** Cart 评估器协议(只描述本文件用到的方法,避免循环依赖) */
49
-
50
- /** 单个赠品减量项 */
51
-
52
- /** 赠品新增项 */
53
-
54
- /** 赠品操作集合(OS 侧根据它落地 tempOrder.products) */
55
-
56
- /** 未满足促销提示项(购物车底部 alert 数据源) */
57
-
58
- /** 商品卡促销标签结构(写入 `metadata._promotionTags`) */
59
-
60
- /** processCartPromotion 输出 */
61
-
62
- // ============================================
63
- // 字段适配 helper
64
- // ============================================
65
-
66
- /**
67
- * 获取商品的「主商品基础价」用于评估器入参。
68
- *
69
- * 优先级(与 OS v2 schema 一致):
70
- * 1. `metadata.source_product_price`
71
- * 2. `metadata.main_product_original_price` 减去 option 合计
72
- * 3. `original_price`
73
- */
44
+ module.exports = __toCommonJS(cartPromotion_exports);
45
+ var import_decimal = __toESM(require("decimal.js"));
46
+ var import_lodash_es = require("lodash-es");
47
+ var import_utils = require("../../../modules/Order/utils");
48
+ var import_utils2 = require("../../ScanOrder/utils");
74
49
  function getOrderProductBasePrice(product) {
75
- const metadata = product?.metadata || {};
76
- const optionSum = (0, _utils.sumOptionUnitPrice)((0, _utils.getProductSkuOptions)(product)).toNumber();
77
- if (metadata.source_product_price !== undefined) {
78
- const v = Number(metadata.source_product_price);
79
- return Number.isFinite(v) ? v : 0;
50
+ const metadata = (product == null ? void 0 : product.metadata) || {};
51
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product)).toNumber();
52
+ if (metadata.source_product_price !== void 0) {
53
+ const v2 = Number(metadata.source_product_price);
54
+ return Number.isFinite(v2) ? v2 : 0;
80
55
  }
81
- if (metadata.main_product_original_price !== undefined) {
82
- const v = Number(metadata.main_product_original_price) - optionSum;
83
- return Number.isFinite(v) ? v : 0;
56
+ if (metadata.main_product_original_price !== void 0) {
57
+ const v2 = Number(metadata.main_product_original_price) - optionSum;
58
+ return Number.isFinite(v2) ? v2 : 0;
84
59
  }
85
- const v = Number(product?.original_price ?? product?.selling_price ?? 0);
60
+ const v = Number((product == null ? void 0 : product.original_price) ?? (product == null ? void 0 : product.selling_price) ?? 0);
86
61
  return Number.isFinite(v) ? v : 0;
87
62
  }
88
-
89
- /**
90
- * 促销均摊专用原价(对齐 legacy `getMainOriginalPrice` 语义)。
91
- *
92
- * 必须用券前原价做 X_ITEMS_FOR_Y_PRICE 比例拆分;`source_product_price` 在上一轮 applyPromotion
93
- * 后可能已被写成促销价(如 5 / 9 / 1),若继续用它会导致同商品两行出现 9+1 而非 5+5。
94
- *
95
- * @example
96
- * getOrderProductOriginalPriceForPromotion({ metadata: { source_product_price: '9', main_product_original_price: '5.80' } });
97
- * // => 5.8
98
- */
99
63
  function getOrderProductOriginalPriceForPromotion(product) {
100
- const metadata = product?.metadata || {};
101
- const optionSum = (0, _utils.sumOptionUnitPrice)((0, _utils.getProductSkuOptions)(product)).toNumber();
102
- if (metadata.main_product_original_price !== undefined && metadata.main_product_original_price !== null && metadata.main_product_original_price !== '') {
64
+ var _a;
65
+ const metadata = (product == null ? void 0 : product.metadata) || {};
66
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product)).toNumber();
67
+ if (metadata.main_product_original_price !== void 0 && metadata.main_product_original_price !== null && metadata.main_product_original_price !== "") {
103
68
  const v = Number(metadata.main_product_original_price) - optionSum;
104
- if (Number.isFinite(v) && v >= 0) return v;
69
+ if (Number.isFinite(v) && v >= 0)
70
+ return v;
105
71
  }
106
- const promoOriginal = metadata._promotion?.originalPrice;
107
- if (promoOriginal !== undefined && promoOriginal !== null && promoOriginal !== '') {
72
+ const promoOriginal = (_a = metadata._promotion) == null ? void 0 : _a.originalPrice;
73
+ if (promoOriginal !== void 0 && promoOriginal !== null && promoOriginal !== "") {
108
74
  const v = Number(promoOriginal);
109
- if (Number.isFinite(v) && v >= 0) return v;
75
+ if (Number.isFinite(v) && v >= 0)
76
+ return v;
110
77
  }
111
78
  return getOrderProductBasePrice(product);
112
79
  }
113
-
114
- /**
115
- * 写入/清除促销 discount_list(type=promotion)。
116
- *
117
- * applyDiscount → applyProductDiscountPrices 会从 source_product_price 减去 discount_list 合计
118
- * 重算 main_product_selling_price;保留券前 source 时必须同步写入促销差额,否则会还原成原价。
119
- *
120
- * @example
121
- * updatePromotionDiscountList(line, { title: '2 items for $10', amount: '17.00', original_amount: '22.00', fixed_amount: '17.00' });
122
- */
123
80
  function updatePromotionDiscountList(item, promotionDiscount) {
124
81
  let discountList = Array.isArray(item.discount_list) ? [...item.discount_list] : [];
125
- discountList = discountList.filter(d => d?.type !== 'promotion');
82
+ discountList = discountList.filter((d) => (d == null ? void 0 : d.type) !== "promotion");
126
83
  if (promotionDiscount) {
127
84
  discountList.push({
128
- type: 'promotion',
85
+ type: "promotion",
129
86
  amount: promotionDiscount.amount,
130
87
  discount: {
131
88
  original_amount: promotionDiscount.original_amount,
132
89
  fixed_amount: promotionDiscount.fixed_amount,
133
90
  title: promotionDiscount.title,
134
- resource_id: ''
91
+ resource_id: ""
135
92
  }
136
93
  });
137
94
  }
@@ -141,38 +98,30 @@ function updatePromotionDiscountList(item, promotionDiscount) {
141
98
  delete item.discount_list;
142
99
  }
143
100
  }
144
- const X_ITEMS_FOR_Y_PRICE = 'X_ITEMS_FOR_Y_PRICE';
145
- const BUY_X_GET_Y_FREE = 'BUY_X_GET_Y_FREE';
146
-
147
- /**
148
- * 将促销单价写入 OrderProduct(含 metadata 三字段 + promotion discount_list)。
149
- *
150
- * @example
151
- * applyPromoUnitPriceToLine(newItem, { promoUnitPrice: '5.00', originalBasePrice: 1, strategyTitle: '2 for 10' });
152
- */
101
+ var X_ITEMS_FOR_Y_PRICE = "X_ITEMS_FOR_Y_PRICE";
153
102
  function applyPromoUnitPriceToLine(item, input) {
154
103
  const metadata = item.metadata || (item.metadata = {});
155
- const optionSum = (0, _utils.sumOptionUnitPrice)((0, _utils.getProductSkuOptions)(item)).toNumber();
156
- const promoUnitPrice = new _decimal.default(Number(input.promoUnitPrice) || 0).toDecimalPlaces(2).toFixed(2);
157
- const mainSelling = new _decimal.default(Number(promoUnitPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
158
- const catalogSource = new _decimal.default(input.originalBasePrice).toDecimalPlaces(2).toFixed(2);
104
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(item)).toNumber();
105
+ const promoUnitPrice = new import_decimal.default(Number(input.promoUnitPrice) || 0).toDecimalPlaces(2).toFixed(2);
106
+ const mainSelling = new import_decimal.default(Number(promoUnitPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
107
+ const catalogSource = new import_decimal.default(input.originalBasePrice).toDecimalPlaces(2).toFixed(2);
159
108
  metadata.source_product_price = catalogSource;
160
- metadata.main_product_original_price = new _decimal.default(Number(catalogSource) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
109
+ metadata.main_product_original_price = new import_decimal.default(Number(catalogSource) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
161
110
  metadata.main_product_selling_price = mainSelling;
162
111
  metadata.price_schema_version = 2;
163
- item.selling_price = (0, _utils.composeLinePrice)({
112
+ item.selling_price = (0, import_utils.composeLinePrice)({
164
113
  mainPrice: mainSelling,
165
114
  bundle: item.product_bundle
166
115
  });
167
- item.original_price = (0, _utils.composeLinePrice)({
116
+ item.original_price = (0, import_utils.composeLinePrice)({
168
117
  mainPrice: metadata.main_product_original_price,
169
118
  bundle: item.product_bundle,
170
119
  useOriginalBundle: true
171
120
  });
172
- const discountAmount = new _decimal.default(input.originalBasePrice).minus(Number(promoUnitPrice) || 0).toDecimalPlaces(2).toFixed(2);
121
+ const discountAmount = new import_decimal.default(input.originalBasePrice).minus(Number(promoUnitPrice) || 0).toDecimalPlaces(2).toFixed(2);
173
122
  if (Number(catalogSource) !== Number(promoUnitPrice)) {
174
123
  updatePromotionDiscountList(item, {
175
- title: input.strategyTitle || '',
124
+ title: input.strategyTitle || "",
176
125
  amount: discountAmount,
177
126
  original_amount: catalogSource,
178
127
  fixed_amount: discountAmount
@@ -182,86 +131,90 @@ function applyPromoUnitPriceToLine(item, input) {
182
131
  }
183
132
  }
184
133
  function getPromotionActionType(promotion) {
185
- if (promotion?.actionType) return String(promotion.actionType);
186
- const actions = promotion?.strategyMetadata?.actions;
187
- if (Array.isArray(actions) && actions[0]?.type) return String(actions[0].type);
188
- return undefined;
134
+ var _a, _b;
135
+ if (promotion == null ? void 0 : promotion.actionType)
136
+ return String(promotion.actionType);
137
+ const actions = (_a = promotion == null ? void 0 : promotion.strategyMetadata) == null ? void 0 : _a.actions;
138
+ if (Array.isArray(actions) && ((_b = actions[0]) == null ? void 0 : _b.type))
139
+ return String(actions[0].type);
140
+ return void 0;
189
141
  }
190
-
191
- /**
192
- * 同款行凑满 X件Y元 且仅该行参与时,按 Y/X 计算期望单价(2 件 $10 → $5)。
193
- *
194
- * @example
195
- * resolveXItemsExpectedUnitPrice({ actionType: 'X_ITEMS_FOR_Y_PRICE', actionDetail: { x: 2, price: 10 } }, 2);
196
- */
197
142
  function resolveXItemsExpectedUnitPrice(promotion, sourceCartNum) {
198
- if (getPromotionActionType(promotion) !== X_ITEMS_FOR_Y_PRICE) return undefined;
199
- const detail = promotion?.actionDetail;
200
- const x = Number(detail?.x);
201
- const y = Number(detail?.price);
202
- if (!Number.isFinite(x) || x <= 0 || !Number.isFinite(y)) return undefined;
203
- if (sourceCartNum < x) return undefined;
204
- return Number(new _decimal.default(y).div(x).toDecimalPlaces(2).toFixed(2));
143
+ if (getPromotionActionType(promotion) !== X_ITEMS_FOR_Y_PRICE)
144
+ return void 0;
145
+ const detail = promotion == null ? void 0 : promotion.actionDetail;
146
+ const x = Number(detail == null ? void 0 : detail.x);
147
+ const y = Number(detail == null ? void 0 : detail.price);
148
+ if (!Number.isFinite(x) || x <= 0 || !Number.isFinite(y))
149
+ return void 0;
150
+ if (sourceCartNum < x)
151
+ return void 0;
152
+ return Number(new import_decimal.default(y).div(x).toDecimalPlaces(2).toFixed(2));
205
153
  }
206
-
207
- /**
208
- * 合并「同商品 + 同规格指纹 + 同促销策略 + 同促销单价」的参与促销行(num 累加)。
209
- * 避免 Browse Items 连续加购同款时拆成多行且单价被错误均摊。
210
- *
211
- * @example
212
- * mergeIdenticalPromotionCartLines(processedProducts);
213
- */
214
154
  function mergeIdenticalPromotionCartLines(products) {
155
+ var _a, _b, _c, _d;
215
156
  if (!Array.isArray(products) || products.length <= 1) {
216
- return [...(products || [])];
157
+ return [...products || []];
217
158
  }
218
159
  const merged = [];
219
- const indexByKey = new Map();
160
+ const indexByKey = /* @__PURE__ */ new Map();
220
161
  for (const line of products) {
221
162
  if (getGiftInfo(line)) {
222
163
  merged.push(line);
223
164
  continue;
224
165
  }
225
- const promotion = line?.metadata?._promotion;
226
- if (!promotion?.inPromotion || !promotion.strategyId) {
166
+ const promotion = (_a = line == null ? void 0 : line.metadata) == null ? void 0 : _a._promotion;
167
+ if (!(promotion == null ? void 0 : promotion.inPromotion) || !promotion.strategyId) {
227
168
  merged.push(line);
228
169
  continue;
229
170
  }
230
- const fingerprint = (0, _utils2.buildProductLineFingerprint)((0, _utils.getProductSkuOptions)(line), line.product_bundle);
231
- const unitPrice = String(line.metadata?.source_product_price ?? line.selling_price ?? '');
232
- const promoUnitPrice = String(promotion.finalPrice ?? line.metadata?.main_product_selling_price ?? '');
171
+ const fingerprint = (0, import_utils2.buildProductLineFingerprint)(
172
+ (0, import_utils.getProductSkuOptions)(line),
173
+ line.product_bundle
174
+ );
175
+ const unitPrice = String(
176
+ ((_b = line.metadata) == null ? void 0 : _b.source_product_price) ?? line.selling_price ?? ""
177
+ );
178
+ const promoUnitPrice = String(
179
+ promotion.finalPrice ?? ((_c = line.metadata) == null ? void 0 : _c.main_product_selling_price) ?? ""
180
+ );
233
181
  const noteSignature = getProductLineNoteSignature(line);
234
182
  const lineMergeBoundary = getPromotionLineMergeBoundary(line);
235
- const bookingUid = line?.booking_uid ?? line?.metadata?.booking_uid;
236
- const orderDetailId = line?.order_detail_id ?? line?.orderDetailId;
237
- const mergeKey = [line.product_id, line.product_variant_id ?? 0, fingerprint, noteSignature, lineMergeBoundary, bookingUid ? String(bookingUid) : '', orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '' ? String(orderDetailId) : '', promotion.strategyId, unitPrice, promoUnitPrice].join('#');
183
+ const bookingUid = (line == null ? void 0 : line.booking_uid) ?? ((_d = line == null ? void 0 : line.metadata) == null ? void 0 : _d.booking_uid);
184
+ const orderDetailId = (line == null ? void 0 : line.order_detail_id) ?? (line == null ? void 0 : line.orderDetailId);
185
+ const mergeKey = [
186
+ line.product_id,
187
+ line.product_variant_id ?? 0,
188
+ fingerprint,
189
+ noteSignature,
190
+ lineMergeBoundary,
191
+ bookingUid ? String(bookingUid) : "",
192
+ orderDetailId !== void 0 && orderDetailId !== null && orderDetailId !== "" ? String(orderDetailId) : "",
193
+ promotion.strategyId,
194
+ unitPrice,
195
+ promoUnitPrice
196
+ ].join("#");
238
197
  const hitIndex = indexByKey.get(mergeKey);
239
- if (hitIndex === undefined) {
198
+ if (hitIndex === void 0) {
240
199
  indexByKey.set(mergeKey, merged.length);
241
200
  merged.push(line);
242
201
  continue;
243
202
  }
244
203
  const target = merged[hitIndex];
245
- target.num = (0, _utils2.getSafeProductNum)(Number(target.num || 0) + Number(line.num || 0));
204
+ target.num = (0, import_utils2.getSafeProductNum)(Number(target.num || 0) + Number(line.num || 0));
246
205
  }
247
206
  return merged;
248
207
  }
249
-
250
- /**
251
- * 同一原购物车行被多个「inPromotion」评估结果命中时(如买赠不改价 + X件Y元),
252
- * 优先保留 X件Y元 定价,并恢复加购前的行数量。
253
- *
254
- * @example
255
- * dedupePromotionProcessedLines(processedProducts);
256
- */
257
208
  function dedupePromotionProcessedLines(lines) {
258
- if (!Array.isArray(lines) || lines.length <= 1) return [...(lines || [])];
209
+ var _a, _b, _c, _d, _e, _f, _g, _h;
210
+ if (!Array.isArray(lines) || lines.length <= 1)
211
+ return [...lines || []];
259
212
  const passthrough = [];
260
- const buckets = new Map();
213
+ const buckets = /* @__PURE__ */ new Map();
261
214
  for (const line of lines) {
262
- const promo = line?.metadata?._promotion;
263
- const originalUid = String(line._originalProductUid || getOrderProductUid(line) || '');
264
- if (!promo?.inPromotion || !originalUid) {
215
+ const promo = (_a = line == null ? void 0 : line.metadata) == null ? void 0 : _a._promotion;
216
+ const originalUid = String(line._originalProductUid || getOrderProductUid(line) || "");
217
+ if (!(promo == null ? void 0 : promo.inPromotion) || !originalUid) {
265
218
  passthrough.push(line);
266
219
  continue;
267
220
  }
@@ -269,11 +222,13 @@ function dedupePromotionProcessedLines(lines) {
269
222
  group.push(line);
270
223
  buckets.set(originalUid, group);
271
224
  }
272
- const promotionDelta = line => {
273
- const promo = line.metadata?._promotion;
274
- const original = Number(promo?.originalPrice);
275
- const final = Number(promo?.finalPrice);
276
- if (!Number.isFinite(original) || !Number.isFinite(final)) return 0;
225
+ const promotionDelta = (line) => {
226
+ var _a2;
227
+ const promo = (_a2 = line.metadata) == null ? void 0 : _a2._promotion;
228
+ const original = Number(promo == null ? void 0 : promo.originalPrice);
229
+ const final = Number(promo == null ? void 0 : promo.finalPrice);
230
+ if (!Number.isFinite(original) || !Number.isFinite(final))
231
+ return 0;
277
232
  return Math.abs(original - final);
278
233
  };
279
234
  const deduped = [...passthrough];
@@ -282,53 +237,73 @@ function dedupePromotionProcessedLines(lines) {
282
237
  deduped.push(group[0]);
283
238
  continue;
284
239
  }
285
- const sourceCartNum = Math.max(...group.map(line => Number(line._sourceCartNum || line.num || 0)));
286
- const pricingLines = group.filter(line => promotionDelta(line) > 0);
287
- const xItemsLines = (pricingLines.length ? pricingLines : group).filter(line => getPromotionActionType(line.metadata?._promotion) === X_ITEMS_FOR_Y_PRICE);
240
+ const sourceCartNum = Math.max(
241
+ ...group.map((line) => Number(line._sourceCartNum || line.num || 0))
242
+ );
243
+ const pricingLines = group.filter((line) => promotionDelta(line) > 0);
244
+ const xItemsLines = (pricingLines.length ? pricingLines : group).filter(
245
+ (line) => {
246
+ var _a2;
247
+ return getPromotionActionType((_a2 = line.metadata) == null ? void 0 : _a2._promotion) === X_ITEMS_FOR_Y_PRICE;
248
+ }
249
+ );
288
250
  const pool = xItemsLines.length ? xItemsLines : pricingLines.length ? pricingLines : group;
289
251
  let winner = pool[0];
290
- const expectedUnit = resolveXItemsExpectedUnitPrice(winner.metadata?._promotion, sourceCartNum);
252
+ const expectedUnit = resolveXItemsExpectedUnitPrice(
253
+ (_b = winner.metadata) == null ? void 0 : _b._promotion,
254
+ sourceCartNum
255
+ );
291
256
  if (expectedUnit != null && pool.length > 1) {
292
257
  winner = pool.reduce((best, line) => {
293
- const bestDiff = Math.abs(Number(best.metadata?._promotion?.finalPrice) - expectedUnit);
294
- const lineDiff = Math.abs(Number(line.metadata?._promotion?.finalPrice) - expectedUnit);
258
+ var _a2, _b2, _c2, _d2;
259
+ const bestDiff = Math.abs(Number((_b2 = (_a2 = best.metadata) == null ? void 0 : _a2._promotion) == null ? void 0 : _b2.finalPrice) - expectedUnit);
260
+ const lineDiff = Math.abs(Number((_d2 = (_c2 = line.metadata) == null ? void 0 : _c2._promotion) == null ? void 0 : _d2.finalPrice) - expectedUnit);
295
261
  return lineDiff < bestDiff ? line : best;
296
262
  }, pool[0]);
297
263
  } else if (pool.length > 1 && !expectedUnit) {
298
264
  winner = pool.reduce((best, line) => {
299
- const bestFinal = Number(best.metadata?._promotion?.finalPrice);
300
- const lineFinal = Number(line.metadata?._promotion?.finalPrice);
301
- const original = Number(line.metadata?._promotion?.originalPrice);
265
+ var _a2, _b2, _c2, _d2, _e2, _f2;
266
+ const bestFinal = Number((_b2 = (_a2 = best.metadata) == null ? void 0 : _a2._promotion) == null ? void 0 : _b2.finalPrice);
267
+ const lineFinal = Number((_d2 = (_c2 = line.metadata) == null ? void 0 : _c2._promotion) == null ? void 0 : _d2.finalPrice);
268
+ const original = Number((_f2 = (_e2 = line.metadata) == null ? void 0 : _e2._promotion) == null ? void 0 : _f2.originalPrice);
302
269
  if (Number.isFinite(original) && lineFinal >= original && bestFinal >= original) {
303
270
  return lineFinal < bestFinal ? line : best;
304
271
  }
305
272
  return promotionDelta(line) > promotionDelta(best) ? line : best;
306
273
  }, pool[0]);
307
274
  }
308
-
309
- // X件Y元:评估器会按单件均摊产出多条 inPromotion 行(如 $1 + $9),
310
- // dedupe 应合并为「同组 X件Y元 行 num 之和」,不能用 sourceCartNum(整单 3 件)。
311
- const winnerIsXItems = getPromotionActionType(winner.metadata?._promotion) === X_ITEMS_FOR_Y_PRICE;
275
+ const winnerIsXItems = getPromotionActionType((_c = winner.metadata) == null ? void 0 : _c._promotion) === X_ITEMS_FOR_Y_PRICE;
312
276
  if (winnerIsXItems) {
313
- const xItemsGroupLines = group.filter(line => getPromotionActionType(line.metadata?._promotion) === X_ITEMS_FOR_Y_PRICE);
314
- const evaluatedPromoQty = xItemsGroupLines.reduce((sum, line) => sum + Number(line.num || 0), 0);
315
- winner.num = (0, _utils2.getSafeProductNum)(evaluatedPromoQty || winner.num || 1);
277
+ const xItemsGroupLines = group.filter(
278
+ (line) => {
279
+ var _a2;
280
+ return getPromotionActionType((_a2 = line.metadata) == null ? void 0 : _a2._promotion) === X_ITEMS_FOR_Y_PRICE;
281
+ }
282
+ );
283
+ const evaluatedPromoQty = xItemsGroupLines.reduce(
284
+ (sum, line) => sum + Number(line.num || 0),
285
+ 0
286
+ );
287
+ winner.num = (0, import_utils2.getSafeProductNum)(evaluatedPromoQty || winner.num || 1);
316
288
  } else {
317
- winner.num = (0, _utils2.getSafeProductNum)(sourceCartNum || winner.num || 1);
289
+ winner.num = (0, import_utils2.getSafeProductNum)(sourceCartNum || winner.num || 1);
318
290
  }
319
- const recomputeUnit = resolveXItemsExpectedUnitPrice(winner.metadata?._promotion, sourceCartNum);
291
+ const recomputeUnit = resolveXItemsExpectedUnitPrice(
292
+ (_d = winner.metadata) == null ? void 0 : _d._promotion,
293
+ sourceCartNum
294
+ );
320
295
  if (recomputeUnit != null) {
321
296
  const promo = winner.metadata._promotion;
322
297
  applyPromoUnitPriceToLine(winner, {
323
298
  promoUnitPrice: recomputeUnit,
324
299
  originalBasePrice: Number(promo.originalPrice),
325
- strategyTitle: promo.strategyMetadata?.name
300
+ strategyTitle: (_e = promo.strategyMetadata) == null ? void 0 : _e.name
326
301
  });
327
302
  promo.finalPrice = recomputeUnit;
328
303
  }
329
304
  for (const line of group) {
330
- const giftInfo = line.metadata?._promotion?.giftInfo;
331
- if (giftInfo && winner.metadata?._promotion && !winner.metadata._promotion.giftInfo) {
305
+ const giftInfo = (_g = (_f = line.metadata) == null ? void 0 : _f._promotion) == null ? void 0 : _g.giftInfo;
306
+ if (giftInfo && ((_h = winner.metadata) == null ? void 0 : _h._promotion) && !winner.metadata._promotion.giftInfo) {
332
307
  winner.metadata._promotion.giftInfo = giftInfo;
333
308
  }
334
309
  }
@@ -336,127 +311,132 @@ function dedupePromotionProcessedLines(lines) {
336
311
  }
337
312
  return deduped;
338
313
  }
339
-
340
- /** 获取行 uid(统一以 `metadata.unique_identification_number` 为唯一键) */
341
314
  function getOrderProductUid(product) {
342
- return String(product?.metadata?.unique_identification_number ?? product?.unique_identification_number ?? '');
315
+ var _a;
316
+ return String(
317
+ ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) ?? (product == null ? void 0 : product.unique_identification_number) ?? ""
318
+ );
343
319
  }
344
320
  function getGiftInfo(product) {
345
- return product?.metadata?._giftInfo || product?._giftInfo || null;
321
+ var _a;
322
+ return ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a._giftInfo) || (product == null ? void 0 : product._giftInfo) || null;
346
323
  }
347
324
  function getProductLineNoteSignature(product) {
348
- const note = product?.note;
349
- if (typeof note !== 'string') return '';
325
+ const note = product == null ? void 0 : product.note;
326
+ if (typeof note !== "string")
327
+ return "";
350
328
  const normalizedNote = note.trim();
351
- if (!normalizedNote) return '';
329
+ if (!normalizedNote)
330
+ return "";
352
331
  const uid = getOrderProductUid(product);
353
332
  return uid ? `note:${uid}` : `note:${normalizedNote}`;
354
333
  }
355
-
356
- /**
357
- * 编辑订单时,历史行仍参与整车促销评估,但不能与本次新增行合并。
358
- * 以历史行 uid 作为促销前后的行边界;新增行返回空边界,仍保留原有合并语义。
359
- */
360
334
  function getPromotionLineMergeBoundary(product) {
361
- if (product?.metadata?.is_edit_for_runtime !== true) return '';
335
+ var _a;
336
+ if (((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.is_edit_for_runtime) !== true)
337
+ return "";
362
338
  return `edit:${getOrderProductUid(product)}`;
363
339
  }
364
340
  function isPersistedGeneratedVoucher(product) {
365
- const orderDetailId = product?.order_detail_id ?? product?.orderDetailId;
366
- if (orderDetailId === undefined || orderDetailId === null || orderDetailId === '') {
341
+ const orderDetailId = (product == null ? void 0 : product.order_detail_id) ?? (product == null ? void 0 : product.orderDetailId);
342
+ if (orderDetailId === void 0 || orderDetailId === null || orderDetailId === "") {
367
343
  return false;
368
344
  }
369
- const metadata = product?.metadata || {};
370
- return product?.extension_type === 'product_voucher' || metadata.parent_order_detail_id !== undefined || metadata.gift_card_type !== undefined;
345
+ const metadata = (product == null ? void 0 : product.metadata) || {};
346
+ return (product == null ? void 0 : product.extension_type) === "product_voucher" || metadata.parent_order_detail_id !== void 0 || metadata.gift_card_type !== void 0;
371
347
  }
372
348
  function getProductBundleForEvaluator(product) {
373
- const bundles = Array.isArray(product?.product_bundle) ? product.product_bundle : [];
374
- return bundles.map(b => ({
375
- product_id: b?.bundle_product_id ?? b?._bundle_product_id ?? b?.product_id,
376
- product_variant_id: b?.bundle_variant_id ?? b?.product_variant_id ?? 0,
377
- quantity: Number(b?.num ?? b?.quantity ?? 1) || 1,
378
- price: Number(b?.bundle_selling_price ?? b?.price ?? 0) || 0,
379
- original_price: Number(b?.original_price ?? b?.product_price ?? b?.price ?? 0) || 0,
380
- id: b?.bundle_id ?? b?.id ?? 0,
381
- _bundle_product_id: b?._bundle_product_id ?? b?.bundle_product_id ?? b?.product_id
349
+ const bundles = Array.isArray(product == null ? void 0 : product.product_bundle) ? product.product_bundle : [];
350
+ return bundles.map((b) => ({
351
+ product_id: (b == null ? void 0 : b.bundle_product_id) ?? (b == null ? void 0 : b._bundle_product_id) ?? (b == null ? void 0 : b.product_id),
352
+ product_variant_id: (b == null ? void 0 : b.bundle_variant_id) ?? (b == null ? void 0 : b.product_variant_id) ?? 0,
353
+ quantity: Number((b == null ? void 0 : b.num) ?? (b == null ? void 0 : b.quantity) ?? 1) || 1,
354
+ price: Number((b == null ? void 0 : b.bundle_selling_price) ?? (b == null ? void 0 : b.price) ?? 0) || 0,
355
+ original_price: Number((b == null ? void 0 : b.original_price) ?? (b == null ? void 0 : b.product_price) ?? (b == null ? void 0 : b.price) ?? 0) || 0,
356
+ id: (b == null ? void 0 : b.bundle_id) ?? (b == null ? void 0 : b.id) ?? 0,
357
+ _bundle_product_id: (b == null ? void 0 : b._bundle_product_id) ?? (b == null ? void 0 : b.bundle_product_id) ?? (b == null ? void 0 : b.product_id)
382
358
  }));
383
359
  }
384
-
385
- /**
386
- * 促销评估前合并同 SKU 拆分行(含促销/原价行),避免加购后仅前 2 件享受优惠。
387
- * 带 `booking_uid` 的预约行不参与合并(每次加车独立 booking + 商品行)。
388
- *
389
- * @example
390
- * consolidateMainProductsForPromotion([
391
- * { item: promoLineNum2, originalListIndex: 0 },
392
- * { item: regularLineNum2, originalListIndex: 1 },
393
- * ]);
394
- * // => 单行 num=4,清除 _promotion 后重新评估
395
- */
396
360
  function buildConsolidateKeyForPromotion(item) {
397
- const fingerprint = (0, _utils2.buildProductLineFingerprint)((0, _utils.getProductSkuOptions)(item), item.product_bundle);
361
+ var _a;
362
+ const fingerprint = (0, import_utils2.buildProductLineFingerprint)(
363
+ (0, import_utils.getProductSkuOptions)(item),
364
+ item.product_bundle
365
+ );
398
366
  const noteSignature = getProductLineNoteSignature(item);
399
367
  const lineMergeBoundary = getPromotionLineMergeBoundary(item);
400
- const bookingUid = item?.booking_uid ?? item?.metadata?.booking_uid;
401
- const orderDetailId = item?.order_detail_id ?? item?.orderDetailId;
402
- if (orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '') {
403
- return [item.product_id, item.product_variant_id ?? 0, fingerprint, noteSignature, lineMergeBoundary, String(orderDetailId)].join('#');
404
- }
405
- if (bookingUid !== undefined && bookingUid !== null && String(bookingUid) !== '') {
406
- return [item.product_id, item.product_variant_id ?? 0, fingerprint, noteSignature, lineMergeBoundary, String(bookingUid)].join('#');
407
- }
408
- return [item.product_id, item.product_variant_id ?? 0, fingerprint, noteSignature, lineMergeBoundary].join('#');
368
+ const bookingUid = (item == null ? void 0 : item.booking_uid) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.booking_uid);
369
+ const orderDetailId = (item == null ? void 0 : item.order_detail_id) ?? (item == null ? void 0 : item.orderDetailId);
370
+ if (orderDetailId !== void 0 && orderDetailId !== null && orderDetailId !== "") {
371
+ return [
372
+ item.product_id,
373
+ item.product_variant_id ?? 0,
374
+ fingerprint,
375
+ noteSignature,
376
+ lineMergeBoundary,
377
+ String(orderDetailId)
378
+ ].join("#");
379
+ }
380
+ if (bookingUid !== void 0 && bookingUid !== null && String(bookingUid) !== "") {
381
+ return [
382
+ item.product_id,
383
+ item.product_variant_id ?? 0,
384
+ fingerprint,
385
+ noteSignature,
386
+ lineMergeBoundary,
387
+ String(bookingUid)
388
+ ].join("#");
389
+ }
390
+ return [
391
+ item.product_id,
392
+ item.product_variant_id ?? 0,
393
+ fingerprint,
394
+ noteSignature,
395
+ lineMergeBoundary
396
+ ].join("#");
409
397
  }
410
398
  function consolidateMainProductsForPromotion(entries) {
399
+ var _a, _b;
411
400
  if (!Array.isArray(entries) || entries.length <= 1) {
412
- return [...(entries || [])];
401
+ return [...entries || []];
413
402
  }
414
- const groups = new Map();
415
- for (const {
416
- item,
417
- originalListIndex
418
- } of entries) {
403
+ const groups = /* @__PURE__ */ new Map();
404
+ for (const { item, originalListIndex } of entries) {
419
405
  const key = buildConsolidateKeyForPromotion(item);
420
- const wasInPromotion = item?.metadata?._promotion?.inPromotion === true;
406
+ const wasInPromotion = ((_b = (_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a._promotion) == null ? void 0 : _b.inPromotion) === true;
421
407
  const existing = groups.get(key);
422
408
  if (!existing) {
423
- const mergedItem = (0, _lodashEs.cloneDeep)(item);
409
+ const mergedItem = (0, import_lodash_es.cloneDeep)(item);
424
410
  const metadata = mergedItem.metadata || {};
425
411
  delete metadata._promotion;
426
412
  mergedItem.metadata = metadata;
427
413
  if (Array.isArray(mergedItem.product_bundle)) {
428
414
  for (const bundle of mergedItem.product_bundle) {
429
- if (bundle && typeof bundle === 'object') delete bundle._promotion;
415
+ if (bundle && typeof bundle === "object")
416
+ delete bundle._promotion;
430
417
  }
431
418
  }
432
419
  if (wasInPromotion) {
433
420
  mergedItem._wasInPromotionBeforeConsolidate = true;
434
421
  }
435
- groups.set(key, {
436
- item: mergedItem,
437
- originalListIndex
438
- });
422
+ groups.set(key, { item: mergedItem, originalListIndex });
439
423
  continue;
440
424
  }
441
- existing.item.num = (0, _utils2.getSafeProductNum)(Number(existing.item.num || 0) + Number(item.num || 0));
425
+ existing.item.num = (0, import_utils2.getSafeProductNum)(
426
+ Number(existing.item.num || 0) + Number(item.num || 0)
427
+ );
442
428
  if (wasInPromotion) {
443
429
  existing.item._wasInPromotionBeforeConsolidate = true;
444
430
  }
445
431
  }
446
432
  return Array.from(groups.values());
447
433
  }
448
-
449
- /**
450
- * X件Y元 整组凑满时按每组 x 件拆开展示(4 件 → 2 行各 2 件 $10)。
451
- *
452
- * @example
453
- * splitXItemsPromoLinesByGroup(mergedLines, strategyActionMap);
454
- */
455
434
  function splitXItemsPromoLinesByGroup(lines, strategyActionMap) {
435
+ var _a;
456
436
  const result = [];
457
437
  for (const line of lines) {
458
- const promo = line?.metadata?._promotion;
459
- if (!promo?.inPromotion || !promo.strategyId) {
438
+ const promo = (_a = line == null ? void 0 : line.metadata) == null ? void 0 : _a._promotion;
439
+ if (!(promo == null ? void 0 : promo.inPromotion) || !promo.strategyId) {
460
440
  result.push(line);
461
441
  continue;
462
442
  }
@@ -465,105 +445,76 @@ function splitXItemsPromoLinesByGroup(lines, strategyActionMap) {
465
445
  continue;
466
446
  }
467
447
  const actionMeta = strategyActionMap.get(promo.strategyId);
468
- const detail = actionMeta?.actionDetail ?? promo.actionDetail;
469
- const x = Number(detail?.x);
448
+ const detail = (actionMeta == null ? void 0 : actionMeta.actionDetail) ?? promo.actionDetail;
449
+ const x = Number(detail == null ? void 0 : detail.x);
470
450
  const num = Number(line.num || 0);
471
- const isCumulative = detail?.cumulative !== false;
451
+ const isCumulative = (detail == null ? void 0 : detail.cumulative) !== false;
472
452
  if (!isCumulative || !Number.isFinite(x) || x <= 0 || num <= x || num % x !== 0) {
473
453
  result.push(line);
474
454
  continue;
475
455
  }
476
456
  const groupCount = num / x;
477
457
  for (let i = 0; i < groupCount; i++) {
478
- const splitLine = (0, _lodashEs.cloneDeep)(line);
479
- splitLine.num = (0, _utils2.getSafeProductNum)(x);
458
+ const splitLine = (0, import_lodash_es.cloneDeep)(line);
459
+ splitLine.num = (0, import_utils2.getSafeProductNum)(x);
480
460
  splitLine.metadata = {
481
- ...(splitLine.metadata || {}),
482
- unique_identification_number: (0, _utils.createUuidV4)()
461
+ ...splitLine.metadata || {},
462
+ unique_identification_number: (0, import_utils.createUuidV4)()
483
463
  };
484
464
  result.push(splitLine);
485
465
  }
486
466
  }
487
467
  return result;
488
468
  }
489
-
490
- /** 生成新 numeric id(仅用于评估器内部追踪) */
491
469
  function generateNumericId() {
492
- return Math.floor(Math.random() * 1_000_000_000) + Date.now();
470
+ return Math.floor(Math.random() * 1e9) + Date.now();
493
471
  }
494
-
495
- /**
496
- * 把 OrderProduct 转成 evaluator 的 PromotionProduct(仅评估期使用)。
497
- *
498
- * 注意:评估器是「无状态、按 product_id + variant 组」工作的;这里给每行分配一个
499
- * numericId 用于关联回原 OrderProduct(通过 originalItemMap)。
500
- */
501
472
  function convertToPromotionProduct(product, index) {
502
- const metadata = product?.metadata || {};
473
+ const metadata = (product == null ? void 0 : product.metadata) || {};
503
474
  const numericId = generateNumericId();
504
475
  const originalItem = product;
505
476
  return {
506
477
  id: numericId,
507
- product_id: Number(product?.product_id ?? 0) || 0,
508
- product_variant_id: Number(product?.product_variant_id ?? 0) || 0,
509
- name: metadata.product_name || product?.title || '',
478
+ product_id: Number((product == null ? void 0 : product.product_id) ?? 0) || 0,
479
+ product_variant_id: Number((product == null ? void 0 : product.product_variant_id) ?? 0) || 0,
480
+ name: metadata.product_name || (product == null ? void 0 : product.title) || "",
510
481
  price: getOrderProductOriginalPriceForPromotion(product),
511
- quantity: Number(product?.num ?? 1) || 1,
482
+ quantity: Number((product == null ? void 0 : product.num) ?? 1) || 1,
512
483
  bundle: getProductBundleForEvaluator(product),
513
484
  _originalItem: originalItem,
514
485
  _originalId: getOrderProductUid(product),
515
486
  _originalIndex: index
516
487
  };
517
488
  }
518
-
519
- // ============================================
520
- // 主流程:processCartPromotion
521
- // ============================================
522
-
523
- /**
524
- * 计算赠品差异化操作(toAdd / toReduce / toRemove)。
525
- *
526
- * 与 legacy `calculateGiftActions` 等价;唯一差别是行键从 `_id` 改成 `metadata.unique_identification_number`。
527
- */
528
489
  function calculateGiftActions(gifts, existingGifts) {
490
+ var _a, _b, _c;
529
491
  const toAdd = [];
530
492
  const toReduce = [];
531
493
  const toRemove = [];
532
-
533
- // 按 strategyId 分组现有赠品
534
- const existingByStrategy = new Map();
494
+ const existingByStrategy = /* @__PURE__ */ new Map();
535
495
  for (const gift of existingGifts) {
536
- const strategyId = getGiftInfo(gift)?.strategyId;
537
- if (!strategyId) continue;
496
+ const strategyId = (_a = getGiftInfo(gift)) == null ? void 0 : _a.strategyId;
497
+ if (!strategyId)
498
+ continue;
538
499
  const existing = existingByStrategy.get(strategyId);
539
- const qty = Number(gift?.num ?? 1) || 1;
500
+ const qty = Number((gift == null ? void 0 : gift.num) ?? 1) || 1;
540
501
  if (existing) {
541
502
  existing.items.push(gift);
542
503
  existing.totalQuantity += qty;
543
504
  } else {
544
- existingByStrategy.set(strategyId, {
545
- items: [gift],
546
- totalQuantity: qty
547
- });
505
+ existingByStrategy.set(strategyId, { items: [gift], totalQuantity: qty });
548
506
  }
549
507
  }
550
- const processedStrategyIds = new Set();
508
+ const processedStrategyIds = /* @__PURE__ */ new Set();
551
509
  for (const giftInfo of gifts) {
552
- const {
553
- strategyId,
554
- strategyName,
555
- giftCount,
556
- giftOptions,
557
- sourceProductIds
558
- } = giftInfo;
510
+ const { strategyId, strategyName, giftCount, giftOptions, sourceProductIds } = giftInfo;
559
511
  processedStrategyIds.add(strategyId);
560
512
  const existing = existingByStrategy.get(strategyId);
561
- const existingCount = existing?.totalQuantity ?? 0;
513
+ const existingCount = (existing == null ? void 0 : existing.totalQuantity) ?? 0;
562
514
  const diff = giftCount - existingCount;
563
515
  if (diff > 0) {
564
- // 判断「用户手动减赠品」: 若评估器的 giftCount 没变,diff>0 说明是手动减,跳过补回
565
- const lastEvaluated = getGiftInfo(existing?.items?.[0])?.lastEvaluatedGiftCount;
566
- const strategyChanged = lastEvaluated === undefined || giftCount !== lastEvaluated;
516
+ const lastEvaluated = (_c = getGiftInfo((_b = existing == null ? void 0 : existing.items) == null ? void 0 : _b[0])) == null ? void 0 : _c.lastEvaluatedGiftCount;
517
+ const strategyChanged = lastEvaluated === void 0 || giftCount !== lastEvaluated;
567
518
  if (strategyChanged) {
568
519
  toAdd.push({
569
520
  strategyId,
@@ -574,124 +525,99 @@ function calculateGiftActions(gifts, existingGifts) {
574
525
  });
575
526
  }
576
527
  } else if (diff < 0) {
577
- // 减赠品:后进先出
578
528
  let remaining = Math.abs(diff);
579
529
  const reduceItems = [];
580
530
  const removeIds = [];
581
- const reversed = [...(existing?.items || [])].reverse();
531
+ const reversed = [...(existing == null ? void 0 : existing.items) || []].reverse();
582
532
  for (const giftItem of reversed) {
583
- if (remaining <= 0) break;
533
+ if (remaining <= 0)
534
+ break;
584
535
  const uid = getOrderProductUid(giftItem);
585
- const qty = Number(giftItem?.num ?? 1) || 1;
536
+ const qty = Number((giftItem == null ? void 0 : giftItem.num) ?? 1) || 1;
586
537
  if (qty <= remaining) {
587
538
  removeIds.push(uid);
588
539
  remaining -= qty;
589
540
  } else {
590
- reduceItems.push({
591
- uid,
592
- currentQuantity: qty,
593
- newQuantity: qty - remaining
594
- });
541
+ reduceItems.push({ uid, currentQuantity: qty, newQuantity: qty - remaining });
595
542
  remaining = 0;
596
543
  }
597
544
  }
598
- if (reduceItems.length > 0) toReduce.push({
599
- strategyId,
600
- items: reduceItems
601
- });
545
+ if (reduceItems.length > 0)
546
+ toReduce.push({ strategyId, items: reduceItems });
602
547
  toRemove.push(...removeIds);
603
548
  }
604
549
  }
605
-
606
- // 失效策略的赠品:全部 remove
607
550
  for (const [strategyId, existing] of existingByStrategy) {
608
- if (processedStrategyIds.has(strategyId)) continue;
551
+ if (processedStrategyIds.has(strategyId))
552
+ continue;
609
553
  for (const giftItem of existing.items) {
610
554
  toRemove.push(getOrderProductUid(giftItem));
611
555
  }
612
556
  }
613
- return {
614
- toAdd,
615
- toReduce,
616
- toRemove
617
- };
557
+ return { toAdd, toReduce, toRemove };
618
558
  }
619
-
620
- /**
621
- * 从策略配置的 product_match 规则提取可参与商品列表。
622
- *
623
- * @example
624
- * extractProductMatchIdentifiersFromStrategyConfig(strategyConfig);
625
- * // => [{ product_id: 60736, product_variant_id: 0 }]
626
- */
627
559
  function extractProductMatchIdentifiersFromStrategyConfig(strategyConfig) {
628
- const rules = strategyConfig?.conditions?.rules;
629
- if (!Array.isArray(rules)) return [];
560
+ var _a;
561
+ const rules = (_a = strategyConfig == null ? void 0 : strategyConfig.conditions) == null ? void 0 : _a.rules;
562
+ if (!Array.isArray(rules))
563
+ return [];
630
564
  for (const rule of rules) {
631
- if (rule?.field === 'productIdAndVariantId' && (rule?.operator === 'product_match' || rule?.operator === 'object_in') && Array.isArray(rule?.value)) {
632
- return rule.value.map(item => ({
633
- product_id: Number(item?.product_id) || 0,
634
- product_variant_id: Number(item?.product_variant_id) || 0
635
- })).filter(item => item.product_id > 0);
565
+ if ((rule == null ? void 0 : rule.field) === "productIdAndVariantId" && ((rule == null ? void 0 : rule.operator) === "product_match" || (rule == null ? void 0 : rule.operator) === "object_in") && Array.isArray(rule == null ? void 0 : rule.value)) {
566
+ return rule.value.map((item) => ({
567
+ product_id: Number(item == null ? void 0 : item.product_id) || 0,
568
+ product_variant_id: Number(item == null ? void 0 : item.product_variant_id) || 0
569
+ })).filter((item) => item.product_id > 0);
636
570
  }
637
571
  }
638
572
  return [];
639
573
  }
640
-
641
- /**
642
- * 解析策略凑单所需件数(evaluator 原始返回可能不含 requiredQuantity)。
643
- *
644
- * @example
645
- * resolveStrategyRequiredQuantity({ actionType: 'X_ITEMS_FOR_Y_PRICE', actionDetail: { x: 2 } });
646
- */
647
574
  function resolveStrategyRequiredQuantity(matched) {
648
575
  const preset = Number(matched.requiredQuantity);
649
- if (Number.isFinite(preset) && preset > 0) return preset;
576
+ if (Number.isFinite(preset) && preset > 0)
577
+ return preset;
650
578
  const detail = matched.actionDetail || {};
651
- if (matched.actionType === 'X_ITEMS_FOR_Y_PRICE') {
579
+ if (matched.actionType === "X_ITEMS_FOR_Y_PRICE") {
652
580
  return Number(detail.x) || 2;
653
581
  }
654
- if (matched.actionType === 'BUY_X_GET_Y_FREE') {
582
+ if (matched.actionType === "BUY_X_GET_Y_FREE") {
655
583
  return Number(detail.buyQuantity) || 1;
656
584
  }
657
585
  return 1;
658
586
  }
659
-
660
- /**
661
- * 解析 Browse Items 弹窗候选商品(优先 eligibleProducts,否则读 strategyConfig)。
662
- *
663
- * @example
664
- * resolveStrategyEligibleProducts(matchedStrategy);
665
- */
666
587
  function resolveStrategyEligibleProducts(matched) {
667
588
  if (Array.isArray(matched.eligibleProducts) && matched.eligibleProducts.length > 0) {
668
589
  return matched.eligibleProducts;
669
590
  }
670
591
  return extractProductMatchIdentifiersFromStrategyConfig(matched.strategyConfig);
671
592
  }
672
-
673
- /**
674
- * 计算未满足促销条件(用于购物车底部「再买 N 件即可享受 XX」alert)。
675
- *
676
- * 数据源:商品的 `metadata._promotion.inPromotion === false`(来自 processCartPromotion
677
- * 第 8 步追加的「有适用策略但当前未参与促销」标记)。
678
- */
679
593
  function calculateUnfulfilledPromotions(processedProducts, applicableStrategiesResult, mainProducts) {
680
- const unfulfilledMap = new Map();
594
+ var _a, _b;
595
+ const unfulfilledMap = /* @__PURE__ */ new Map();
681
596
  for (let i = 0; i < processedProducts.length; i++) {
682
597
  const product = processedProducts[i];
683
- const promotion = product?.metadata?._promotion;
684
- if (!promotion || promotion.inPromotion !== false) continue;
598
+ const promotion = (_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a._promotion;
599
+ if (!promotion || promotion.inPromotion !== false)
600
+ continue;
685
601
  const strategyId = promotion.strategyId;
686
- if (!strategyId) continue;
687
- const lookupUid = String(product?._originalProductUid ?? product?.metadata?.unique_identification_number ?? '');
688
- const originalIndex = mainProducts.findIndex(item => getOrderProductUid(item) === lookupUid);
689
- if (originalIndex === -1) continue;
602
+ if (!strategyId)
603
+ continue;
604
+ const lookupUid = String(
605
+ (product == null ? void 0 : product._originalProductUid) ?? ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.unique_identification_number) ?? ""
606
+ );
607
+ const originalIndex = mainProducts.findIndex(
608
+ (item) => getOrderProductUid(item) === lookupUid
609
+ );
610
+ if (originalIndex === -1)
611
+ continue;
690
612
  const strategyData = applicableStrategiesResult[originalIndex];
691
- if (!strategyData || !strategyData.hasApplicableStrategy) continue;
692
- const matched = strategyData.applicableStrategies.find(s => s.strategyId === strategyId);
693
- if (!matched) continue;
694
- const quantity = Number(product?.num ?? 1) || 1;
613
+ if (!strategyData || !strategyData.hasApplicableStrategy)
614
+ continue;
615
+ const matched = strategyData.applicableStrategies.find(
616
+ (s) => s.strategyId === strategyId
617
+ );
618
+ if (!matched)
619
+ continue;
620
+ const quantity = Number((product == null ? void 0 : product.num) ?? 1) || 1;
695
621
  if (unfulfilledMap.has(strategyId)) {
696
622
  unfulfilledMap.get(strategyId).currentQuantity += quantity;
697
623
  } else {
@@ -712,47 +638,32 @@ function calculateUnfulfilledPromotions(processedProducts, applicableStrategiesR
712
638
  for (const data of unfulfilledMap.values()) {
713
639
  const needQuantity = data.requiredQuantity - data.currentQuantity;
714
640
  if (needQuantity > 0) {
715
- result.push({
716
- ...data,
717
- needQuantity
718
- });
641
+ result.push({ ...data, needQuantity });
719
642
  }
720
643
  }
721
644
  return result;
722
645
  }
723
-
724
- /**
725
- * 给商品列表追加促销标签(写入 `metadata._promotionTags`),供 ProductCard 渲染。
726
- *
727
- * - 没有适用策略的商品会清除 `_promotionTags`(避免脏数据)。
728
- * - 仅基于 product_id 匹配(matchVariant=false),与商品卡通用场景对齐。
729
- *
730
- * @example
731
- * const list = appendPromotionTags(catalog, evaluator);
732
- * // list[i].metadata._promotionTags = [{ text, type, strategyId }]
733
- */
734
646
  function appendPromotionTags(products, evaluator) {
735
647
  if (!Array.isArray(products) || products.length === 0 || !evaluator) {
736
648
  return products || [];
737
649
  }
738
-
739
- // 评估器期望的 product shape,最少字段集
740
650
  const evaluatorInput = products.map((item, index) => ({
741
651
  id: index,
742
- product_id: Number(item?.id ?? item?.product_id ?? 0) || 0,
743
- product_variant_id: Number(item?.product_variant_id ?? 0) || 0,
744
- name: item?.title || item?.name || '',
745
- price: Number(item?.price ?? 0) || 0,
746
- quantity: Number(item?.quantity ?? 1) || 1,
652
+ product_id: Number((item == null ? void 0 : item.id) ?? (item == null ? void 0 : item.product_id) ?? 0) || 0,
653
+ product_variant_id: Number((item == null ? void 0 : item.product_variant_id) ?? 0) || 0,
654
+ name: (item == null ? void 0 : item.title) || (item == null ? void 0 : item.name) || "",
655
+ price: Number((item == null ? void 0 : item.price) ?? 0) || 0,
656
+ quantity: Number((item == null ? void 0 : item.quantity) ?? 1) || 1,
747
657
  bundle: []
748
658
  }));
749
- const strategies = evaluator.getProductsApplicableStrategies({
750
- products: evaluatorInput
751
- }, false);
659
+ const strategies = evaluator.getProductsApplicableStrategies(
660
+ { products: evaluatorInput },
661
+ false
662
+ );
752
663
  return products.map((item, index) => {
753
664
  const data = strategies[index];
754
665
  const tags = [];
755
- if (data?.hasApplicableStrategy) {
666
+ if (data == null ? void 0 : data.hasApplicableStrategy) {
756
667
  for (const strategy of data.applicableStrategies) {
757
668
  if (strategy.display) {
758
669
  tags.push({
@@ -763,58 +674,24 @@ function appendPromotionTags(products, evaluator) {
763
674
  }
764
675
  }
765
676
  }
766
- // 商品卡兼容两种位置:顶层 `_promotionTags` 与 `metadata._promotionTags`
767
- // ProductCard 现有实现读顶层(详见 productSelect/ProductCard/index.tsx),
768
- // 此处同时写顶层以保持视图直连;OrderProduct 行版本走 metadata(避免顶层非协议字段)。
769
677
  if (tags.length === 0) {
770
- const {
771
- _promotionTags,
772
- ...rest
773
- } = item;
774
- void _promotionTags;
678
+ const { _promotionTags, ...rest } = item;
775
679
  return rest;
776
680
  }
777
- return {
778
- ...item,
779
- _promotionTags: tags
780
- };
681
+ return { ...item, _promotionTags: tags };
781
682
  });
782
683
  }
783
-
784
- /**
785
- * 处理购物车的促销计算与赠品差异化。
786
- *
787
- * 流程:
788
- * 1. 分离 main / gift / edit-product 三类(带 `booking_id` 的编辑态商品不参与促销)
789
- * 2. 转 PromotionProduct 喂评估器 → 拿到 `evaluateCartWithPricing` 与 `getProductsApplicableStrategies`
790
- * 3. 把 PricedProduct 映射回 OrderProduct 形态:
791
- * - 参与促销的,写 `metadata._promotion` + 调整 `selling_price` / `main_product_selling_price`
792
- * - 拆分的,生成新 uid,复制原行其它字段
793
- * 4. 计算 `_giftInfo` 挂主商品(每个策略首个主商品)
794
- * 5. 计算 `giftActions`(toAdd / toReduce / toRemove)
795
- * 6. 计算 `unfulfilledPromotions`
796
- *
797
- * @example
798
- * const { products, giftActions, unfulfilledPromotions } = processCartPromotion(
799
- * tempOrder.products,
800
- * evaluator,
801
- * );
802
- */
803
684
  function processCartPromotion(list, evaluator, options) {
685
+ var _a, _b, _c, _d, _e, _f, _g, _h;
804
686
  const empty = {
805
687
  products: Array.isArray(list) ? [...list] : [],
806
688
  totalDiscount: 0,
807
689
  gifts: [],
808
- giftActions: {
809
- toAdd: [],
810
- toReduce: [],
811
- toRemove: []
812
- },
690
+ giftActions: { toAdd: [], toReduce: [], toRemove: [] },
813
691
  unfulfilledPromotions: []
814
692
  };
815
- if (!list || list.length === 0 || !evaluator) return empty;
816
-
817
- // 0. 分类
693
+ if (!list || list.length === 0 || !evaluator)
694
+ return empty;
818
695
  const mainProductsWithIndex = [];
819
696
  const existingGiftsWithIndex = [];
820
697
  const editProductsWithIndex = [];
@@ -822,47 +699,34 @@ function processCartPromotion(list, evaluator, options) {
822
699
  const item = list[i];
823
700
  const giftInfo = getGiftInfo(item);
824
701
  if (isPersistedGeneratedVoucher(item)) {
825
- editProductsWithIndex.push({
826
- item,
827
- originalListIndex: i
828
- });
702
+ editProductsWithIndex.push({ item, originalListIndex: i });
829
703
  } else if (giftInfo) {
830
- existingGiftsWithIndex.push({
831
- item,
832
- originalListIndex: i
833
- });
834
- } else if (item?.booking_id !== undefined && item?.booking_id !== null && item.booking_id !== 0 && item.booking_id !== '0') {
835
- editProductsWithIndex.push({
836
- item,
837
- originalListIndex: i
838
- });
704
+ existingGiftsWithIndex.push({ item, originalListIndex: i });
705
+ } else if ((item == null ? void 0 : item.booking_id) !== void 0 && (item == null ? void 0 : item.booking_id) !== null && item.booking_id !== 0 && item.booking_id !== "0") {
706
+ editProductsWithIndex.push({ item, originalListIndex: i });
839
707
  } else {
840
- mainProductsWithIndex.push({
841
- item,
842
- originalListIndex: i
843
- });
708
+ mainProductsWithIndex.push({ item, originalListIndex: i });
844
709
  }
845
710
  }
846
- const consolidatedMainProductsWithIndex = consolidateMainProductsForPromotion(mainProductsWithIndex);
847
- const mainProducts = consolidatedMainProductsWithIndex.map(x => x.item);
848
- const existingGifts = existingGiftsWithIndex.map(x => x.item);
711
+ const consolidatedMainProductsWithIndex = consolidateMainProductsForPromotion(
712
+ mainProductsWithIndex
713
+ );
714
+ const mainProducts = consolidatedMainProductsWithIndex.map((x) => x.item);
715
+ const existingGifts = existingGiftsWithIndex.map((x) => x.item);
849
716
  if (mainProducts.length === 0) {
850
- const editProducts = editProductsWithIndex.map(x => x.item);
717
+ const editProducts = editProductsWithIndex.map((x) => x.item);
851
718
  if (existingGifts.length > 0) {
852
719
  const toRemove = [];
853
720
  for (const gift of existingGifts) {
854
721
  const uid = getOrderProductUid(gift);
855
- if (uid) toRemove.push(uid);
722
+ if (uid)
723
+ toRemove.push(uid);
856
724
  }
857
725
  return {
858
726
  products: editProducts,
859
727
  totalDiscount: 0,
860
728
  gifts: [],
861
- giftActions: {
862
- toAdd: [],
863
- toReduce: [],
864
- toRemove
865
- },
729
+ giftActions: { toAdd: [], toReduce: [], toRemove },
866
730
  unfulfilledPromotions: []
867
731
  };
868
732
  }
@@ -871,108 +735,92 @@ function processCartPromotion(list, evaluator, options) {
871
735
  products: editProducts.length > 0 ? editProducts : [...list]
872
736
  };
873
737
  }
874
-
875
- // 1. 转 PromotionProduct
876
738
  const promotionProducts = [];
877
- const originalItemMap = new Map();
878
- const productsForStrategies = consolidatedMainProductsWithIndex.map(({
879
- item
880
- }, i) => ({
881
- id: i,
882
- product_id: Number(item?.product_id ?? 0) || 0,
883
- product_variant_id: Number(item?.product_variant_id ?? 0) || 0,
884
- name: item?.metadata?.product_name || item?.title || '',
885
- price: getOrderProductBasePrice(item),
886
- quantity: Number(item?.num ?? 1) || 1,
887
- bundle: getProductBundleForEvaluator(item)
888
- }));
739
+ const originalItemMap = /* @__PURE__ */ new Map();
740
+ const productsForStrategies = consolidatedMainProductsWithIndex.map(({ item }, i) => {
741
+ var _a2;
742
+ return {
743
+ id: i,
744
+ product_id: Number((item == null ? void 0 : item.product_id) ?? 0) || 0,
745
+ product_variant_id: Number((item == null ? void 0 : item.product_variant_id) ?? 0) || 0,
746
+ name: ((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.product_name) || (item == null ? void 0 : item.title) || "",
747
+ price: getOrderProductBasePrice(item),
748
+ quantity: Number((item == null ? void 0 : item.num) ?? 1) || 1,
749
+ bundle: getProductBundleForEvaluator(item)
750
+ };
751
+ });
889
752
  for (let i = 0; i < consolidatedMainProductsWithIndex.length; i++) {
890
- const {
891
- item,
892
- originalListIndex
893
- } = consolidatedMainProductsWithIndex[i];
753
+ const { item, originalListIndex } = consolidatedMainProductsWithIndex[i];
894
754
  const promotionProduct = convertToPromotionProduct(item, originalListIndex);
895
755
  promotionProducts.push(promotionProduct);
896
- originalItemMap.set(promotionProduct.id, {
897
- item,
898
- index: originalListIndex
899
- });
756
+ originalItemMap.set(promotionProduct.id, { item, index: originalListIndex });
900
757
  }
901
-
902
- // 2. 拿适用策略
903
758
  const applicableStrategiesResult = evaluator.getProductsApplicableStrategies({
904
759
  products: productsForStrategies,
905
- channel: options?.channel
760
+ channel: options == null ? void 0 : options.channel
906
761
  });
907
- const strategyActionMap = new Map();
762
+ const strategyActionMap = /* @__PURE__ */ new Map();
908
763
  for (const row of applicableStrategiesResult || []) {
909
- for (const strategy of row?.applicableStrategies || []) {
910
- if (!strategy?.strategyId) continue;
764
+ for (const strategy of (row == null ? void 0 : row.applicableStrategies) || []) {
765
+ if (!(strategy == null ? void 0 : strategy.strategyId))
766
+ continue;
911
767
  strategyActionMap.set(strategy.strategyId, {
912
768
  actionType: strategy.actionType,
913
769
  actionDetail: strategy.actionDetail
914
770
  });
915
771
  }
916
772
  }
917
-
918
- // 3. 评估器
919
773
  const result = evaluator.evaluateCartWithPricing({
920
774
  products: promotionProducts,
921
- channel: options?.channel
775
+ channel: options == null ? void 0 : options.channel
922
776
  });
923
-
924
- // 4. 收集每个策略的 sourceProductIds(参与策略的主商品 uid)
925
- const strategySourceProductIds = new Map();
777
+ const strategySourceProductIds = /* @__PURE__ */ new Map();
926
778
  for (const priced of result.products) {
927
779
  if (priced.inPromotion && priced.strategyId) {
928
780
  const sourceId = priced.originalId ?? priced.id;
929
781
  const originalData = originalItemMap.get(sourceId);
930
782
  if (originalData) {
931
783
  const uid = getOrderProductUid(originalData.item);
932
- if (!uid) continue;
784
+ if (!uid)
785
+ continue;
933
786
  const arr = strategySourceProductIds.get(priced.strategyId) || [];
934
- if (!arr.includes(uid)) arr.push(uid);
787
+ if (!arr.includes(uid))
788
+ arr.push(uid);
935
789
  strategySourceProductIds.set(priced.strategyId, arr);
936
790
  }
937
791
  }
938
792
  }
939
-
940
- // 5. 扩展 gifts,加 sourceProductIds
941
- const extendedGifts = result.gifts.map(gift => ({
793
+ const extendedGifts = result.gifts.map((gift) => ({
942
794
  ...gift,
943
795
  sourceProductIds: strategySourceProductIds.get(gift.strategyId) || []
944
796
  }));
945
-
946
- // 6. PricedProduct → OrderProduct(含拆分与价格调整)
947
- const strategyGiftInfoMap = new Map();
948
- for (const gift of extendedGifts) strategyGiftInfoMap.set(gift.strategyId, gift);
949
- const strategyGiftInfoOwner = new Map();
797
+ const strategyGiftInfoMap = /* @__PURE__ */ new Map();
798
+ for (const gift of extendedGifts)
799
+ strategyGiftInfoMap.set(gift.strategyId, gift);
800
+ const strategyGiftInfoOwner = /* @__PURE__ */ new Map();
950
801
  const processedProducts = [];
951
802
  for (const priced of result.products) {
952
803
  const rawSourceId = priced.originalId ?? priced.id;
953
804
  const sourceId = Number(rawSourceId);
954
- const originalData = Number.isFinite(sourceId) ? originalItemMap.get(sourceId) : undefined;
955
- if (!originalData) continue;
956
- const {
957
- item: originalItem,
958
- index: originalIndex
959
- } = originalData;
805
+ const originalData = Number.isFinite(sourceId) ? originalItemMap.get(sourceId) : void 0;
806
+ if (!originalData)
807
+ continue;
808
+ const { item: originalItem, index: originalIndex } = originalData;
960
809
  const pricedProductId = Number(priced.product_id ?? 0);
961
810
  const originalProductId = Number(originalItem.product_id ?? 0);
962
811
  if (pricedProductId > 0 && originalProductId > 0 && pricedProductId !== originalProductId) {
963
812
  continue;
964
813
  }
965
- const newItem = (0, _lodashEs.cloneDeep)(originalItem);
814
+ const newItem = (0, import_lodash_es.cloneDeep)(originalItem);
966
815
  const metadata = newItem.metadata || {};
967
- const sourceCartNum = (0, _utils2.getSafeProductNum)(originalItem.num);
816
+ const sourceCartNum = (0, import_utils2.getSafeProductNum)(originalItem.num);
968
817
  newItem._sourceCartNum = sourceCartNum;
969
-
970
- // 清掉历史促销字段
971
- const wasInPromotion = metadata._promotion?.inPromotion === true || originalItem._wasInPromotionBeforeConsolidate === true;
818
+ const wasInPromotion = ((_a = metadata._promotion) == null ? void 0 : _a.inPromotion) === true || originalItem._wasInPromotionBeforeConsolidate === true;
972
819
  delete metadata._promotion;
973
820
  if (Array.isArray(newItem.product_bundle)) {
974
821
  for (const b of newItem.product_bundle) {
975
- if (b && typeof b === 'object') delete b._promotion;
822
+ if (b && typeof b === "object")
823
+ delete b._promotion;
976
824
  }
977
825
  }
978
826
  const originalBasePrice = getOrderProductOriginalPriceForPromotion(originalItem);
@@ -980,32 +828,29 @@ function processCartPromotion(list, evaluator, options) {
980
828
  const priceUnchangedPromo = priced.inPromotion && Number(priced.finalPrice) === Number(originalBasePrice);
981
829
  if (shouldModifyPrice) {
982
830
  if (priced.inPromotion && !priceUnchangedPromo) {
983
- const promoUnitPrice = new _decimal.default(priced.finalPrice).toDecimalPlaces(2).toFixed(2);
831
+ const promoUnitPrice = new import_decimal.default(priced.finalPrice).toDecimalPlaces(2).toFixed(2);
984
832
  applyPromoUnitPriceToLine(newItem, {
985
833
  promoUnitPrice,
986
834
  originalBasePrice,
987
- strategyTitle: priced.strategyMetadata?.name
835
+ strategyTitle: (_b = priced.strategyMetadata) == null ? void 0 : _b.name
988
836
  });
989
837
  } else {
990
- // 撤销上一轮促销:还原 selling_price 到 main_product_original_price 派生值
991
- const optionSum = (0, _utils.sumOptionUnitPrice)((0, _utils.getProductSkuOptions)(newItem)).toNumber();
992
- const sourceRestore = new _decimal.default(originalBasePrice).toDecimalPlaces(2).toFixed(2);
993
- const mainRestore = new _decimal.default(Number(sourceRestore) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
838
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(newItem)).toNumber();
839
+ const sourceRestore = new import_decimal.default(originalBasePrice).toDecimalPlaces(2).toFixed(2);
840
+ const mainRestore = new import_decimal.default(Number(sourceRestore) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
994
841
  metadata.source_product_price = sourceRestore;
995
842
  metadata.main_product_selling_price = mainRestore;
996
843
  metadata.price_schema_version = 2;
997
- newItem.selling_price = (0, _utils.composeLinePrice)({
844
+ newItem.selling_price = (0, import_utils.composeLinePrice)({
998
845
  mainPrice: mainRestore,
999
846
  bundle: newItem.product_bundle
1000
847
  });
1001
848
  updatePromotionDiscountList(newItem, null);
1002
849
  }
1003
850
  }
1004
- newItem.num = priced.isSplit ? (0, _utils2.getSafeProductNum)(priced.quantity) : sourceCartNum;
1005
-
1006
- // 拆分行:生成新 uid,复制原行
851
+ newItem.num = priced.isSplit ? (0, import_utils2.getSafeProductNum)(priced.quantity) : sourceCartNum;
1007
852
  if (priced.isSplit) {
1008
- metadata.unique_identification_number = (0, _utils.createUuidV4)();
853
+ metadata.unique_identification_number = (0, import_utils.createUuidV4)();
1009
854
  }
1010
855
  if (priced.strategyId) {
1011
856
  const actionMeta = strategyActionMap.get(priced.strategyId);
@@ -1015,19 +860,17 @@ function processCartPromotion(list, evaluator, options) {
1015
860
  inPromotion: priced.inPromotion,
1016
861
  originalPrice: originalBasePrice,
1017
862
  finalPrice: priced.finalPrice,
1018
- actionType: actionMeta?.actionType,
1019
- actionDetail: actionMeta?.actionDetail
863
+ actionType: actionMeta == null ? void 0 : actionMeta.actionType,
864
+ actionDetail: actionMeta == null ? void 0 : actionMeta.actionDetail
1020
865
  };
1021
866
  const bundleIdx = priced.matchedBundleIndex;
1022
- if (bundleIdx !== undefined && Array.isArray(newItem.product_bundle) && newItem.product_bundle[bundleIdx]) {
867
+ if (bundleIdx !== void 0 && Array.isArray(newItem.product_bundle) && newItem.product_bundle[bundleIdx]) {
1023
868
  newItem.product_bundle[bundleIdx]._promotion = promotionInfo;
1024
869
  } else {
1025
870
  metadata._promotion = promotionInfo;
1026
871
  }
1027
872
  }
1028
873
  newItem.metadata = metadata;
1029
-
1030
- // 5.1 第一个参与「买X送Y」策略的主商品,挂 giftInfo
1031
874
  if (priced.inPromotion && priced.strategyId) {
1032
875
  const gift = strategyGiftInfoMap.get(priced.strategyId);
1033
876
  if (gift && Array.isArray(gift.giftOptions) && gift.giftOptions.length > 0 && !strategyGiftInfoOwner.has(priced.strategyId)) {
@@ -1037,79 +880,74 @@ function processCartPromotion(list, evaluator, options) {
1037
880
  giftOptions: gift.giftOptions
1038
881
  };
1039
882
  const bundleIdx = priced.matchedBundleIndex;
1040
- if (bundleIdx !== undefined && Array.isArray(newItem.product_bundle) && newItem.product_bundle[bundleIdx]?._promotion) {
883
+ if (bundleIdx !== void 0 && Array.isArray(newItem.product_bundle) && ((_c = newItem.product_bundle[bundleIdx]) == null ? void 0 : _c._promotion)) {
1041
884
  newItem.product_bundle[bundleIdx]._promotion.giftInfo = giftInfoData;
1042
885
  } else if (metadata._promotion) {
1043
886
  metadata._promotion.giftInfo = giftInfoData;
1044
887
  }
1045
- strategyGiftInfoOwner.set(priced.strategyId, getOrderProductUid(newItem));
888
+ strategyGiftInfoOwner.set(
889
+ priced.strategyId,
890
+ getOrderProductUid(newItem)
891
+ );
1046
892
  }
1047
893
  }
1048
-
1049
- // 记录原商品 uid(用于排序与未满足匹配)
1050
894
  newItem._sortIndex = originalIndex;
1051
895
  newItem._sortSubIndex = priced.inPromotion ? 0 : 1;
1052
896
  newItem._originalProductUid = getOrderProductUid(originalItem);
1053
897
  processedProducts.push(newItem);
1054
898
  }
1055
-
1056
- // 7. 赠品/编辑商品原样拼回;同时同步赠品的 sourceProductIds / sourceProductId
1057
- for (const {
1058
- item,
1059
- originalListIndex
1060
- } of existingGiftsWithIndex) {
899
+ for (const { item, originalListIndex } of existingGiftsWithIndex) {
1061
900
  const next = item;
1062
901
  next._sortIndex = originalListIndex;
1063
902
  next._sortSubIndex = 0;
1064
- const strategyId = getGiftInfo(next)?.strategyId;
903
+ const strategyId = (_d = getGiftInfo(next)) == null ? void 0 : _d.strategyId;
1065
904
  if (strategyId) {
1066
905
  const latest = strategyGiftInfoMap.get(strategyId);
1067
906
  const owner = strategyGiftInfoOwner.get(strategyId);
1068
- if (latest && next.metadata?._giftInfo) {
907
+ if (latest && ((_e = next.metadata) == null ? void 0 : _e._giftInfo)) {
1069
908
  next.metadata._giftInfo.sourceProductIds = latest.sourceProductIds;
1070
909
  }
1071
- if (owner && next.metadata?._giftInfo) {
910
+ if (owner && ((_f = next.metadata) == null ? void 0 : _f._giftInfo)) {
1072
911
  next.metadata._giftInfo.sourceProductId = owner;
1073
912
  }
1074
913
  }
1075
914
  processedProducts.push(next);
1076
915
  }
1077
- for (const {
1078
- item,
1079
- originalListIndex
1080
- } of editProductsWithIndex) {
916
+ for (const { item, originalListIndex } of editProductsWithIndex) {
1081
917
  const next = item;
1082
918
  next._sortIndex = originalListIndex;
1083
919
  next._sortSubIndex = 0;
1084
920
  processedProducts.push(next);
1085
921
  }
1086
-
1087
- // 8. 排序回原顺序,参与促销的拆分行排在前
1088
922
  processedProducts.sort((a, b) => {
1089
- if (a._sortIndex !== b._sortIndex) return a._sortIndex - b._sortIndex;
923
+ if (a._sortIndex !== b._sortIndex)
924
+ return a._sortIndex - b._sortIndex;
1090
925
  return a._sortSubIndex - b._sortSubIndex;
1091
926
  });
1092
-
1093
- // 8.1 同款参与促销行:先去重(买赠+满减并存)再合并 num
1094
927
  const dedupedPromotionLines = dedupePromotionProcessedLines(processedProducts);
1095
928
  processedProducts.splice(0, processedProducts.length, ...dedupedPromotionLines);
1096
929
  const mergedPromotionLines = mergeIdenticalPromotionCartLines(processedProducts);
1097
930
  processedProducts.splice(0, processedProducts.length, ...mergedPromotionLines);
1098
931
  const splitPromoLines = splitXItemsPromoLinesByGroup(processedProducts, strategyActionMap);
1099
932
  processedProducts.splice(0, processedProducts.length, ...splitPromoLines);
1100
-
1101
- // 9. 给「有适用策略但未参与促销」的主商品打 inPromotion:false
1102
933
  for (const product of processedProducts) {
1103
934
  const metadata = product.metadata || {};
1104
- if (metadata._promotion) continue;
1105
- if (getGiftInfo(product)) continue;
935
+ if (metadata._promotion)
936
+ continue;
937
+ if (getGiftInfo(product))
938
+ continue;
1106
939
  const lookupUid = String(product._originalProductUid ?? getOrderProductUid(product));
1107
- const originalIndex = mainProducts.findIndex(item => getOrderProductUid(item) === lookupUid);
1108
- if (originalIndex === -1) continue;
940
+ const originalIndex = mainProducts.findIndex(
941
+ (item) => getOrderProductUid(item) === lookupUid
942
+ );
943
+ if (originalIndex === -1)
944
+ continue;
1109
945
  const strategyData = applicableStrategiesResult[originalIndex];
1110
- if (!strategyData || !strategyData.hasApplicableStrategy) continue;
946
+ if (!strategyData || !strategyData.hasApplicableStrategy)
947
+ continue;
1111
948
  const first = strategyData.applicableStrategies[0];
1112
- if (!first) continue;
949
+ if (!first)
950
+ continue;
1113
951
  const originalPrice = getOrderProductOriginalPriceForPromotion(mainProducts[originalIndex]);
1114
952
  metadata._promotion = {
1115
953
  strategyId: first.strategyId,
@@ -1120,24 +958,21 @@ function processCartPromotion(list, evaluator, options) {
1120
958
  };
1121
959
  product.metadata = metadata;
1122
960
  }
1123
-
1124
- // 10. 赠品操作(在更新 lastEvaluatedGiftCount 前做对比)
1125
961
  const giftActions = calculateGiftActions(extendedGifts, existingGifts);
1126
-
1127
- // 10.1 更新 lastEvaluatedGiftCount,便于下次评估时判别「策略已变」
1128
962
  for (const gift of existingGifts) {
1129
- const strategyId = getGiftInfo(gift)?.strategyId;
1130
- if (!strategyId) continue;
963
+ const strategyId = (_g = getGiftInfo(gift)) == null ? void 0 : _g.strategyId;
964
+ if (!strategyId)
965
+ continue;
1131
966
  const latest = strategyGiftInfoMap.get(strategyId);
1132
- if (latest && gift.metadata?._giftInfo) {
967
+ if (latest && ((_h = gift.metadata) == null ? void 0 : _h._giftInfo)) {
1133
968
  gift.metadata._giftInfo.lastEvaluatedGiftCount = latest.giftCount;
1134
969
  }
1135
970
  }
1136
-
1137
- // 11. 未满足促销
1138
- const unfulfilledPromotions = calculateUnfulfilledPromotions(processedProducts, applicableStrategiesResult, mainProducts);
1139
-
1140
- // 12. 清理排序辅助字段
971
+ const unfulfilledPromotions = calculateUnfulfilledPromotions(
972
+ processedProducts,
973
+ applicableStrategiesResult,
974
+ mainProducts
975
+ );
1141
976
  for (const product of processedProducts) {
1142
977
  delete product._sortIndex;
1143
978
  delete product._sortSubIndex;
@@ -1152,4 +987,18 @@ function processCartPromotion(list, evaluator, options) {
1152
987
  giftActions,
1153
988
  unfulfilledPromotions
1154
989
  };
1155
- }
990
+ }
991
+ // Annotate the CommonJS export names for ESM import in node:
992
+ 0 && (module.exports = {
993
+ appendPromotionTags,
994
+ buildConsolidateKeyForPromotion,
995
+ calculateUnfulfilledPromotions,
996
+ extractProductMatchIdentifiersFromStrategyConfig,
997
+ getOrderProductBasePrice,
998
+ getOrderProductOriginalPriceForPromotion,
999
+ getOrderProductUid,
1000
+ mergeIdenticalPromotionCartLines,
1001
+ processCartPromotion,
1002
+ resolveStrategyEligibleProducts,
1003
+ resolveStrategyRequiredQuantity
1004
+ });