@pisell/pisellos 0.0.568 → 0.10.1

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 (588) 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/evaluator.js +3 -2
  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 +24 -96
  11. package/dist/model/strategy/strategy-example.js +19 -5
  12. package/dist/modules/BaseModule.d.ts +2 -2
  13. package/dist/modules/BaseModule.js +12 -14
  14. package/dist/modules/BookingContext/index.d.ts +48 -0
  15. package/dist/modules/BookingContext/index.js +566 -0
  16. package/dist/modules/BookingContext/types.d.ts +102 -0
  17. package/dist/modules/BookingContext/types.js +51 -0
  18. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  19. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +302 -0
  20. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  21. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +149 -0
  22. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
  23. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +249 -0
  24. package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
  25. package/dist/modules/BookingContext/utils/flexible.js +56 -0
  26. package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  27. package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
  28. package/dist/modules/BookingContext/utils/index.d.ts +11 -0
  29. package/dist/modules/BookingContext/utils/index.js +11 -0
  30. package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
  31. package/dist/modules/BookingContext/utils/noResource.js +77 -0
  32. package/dist/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
  33. package/dist/modules/BookingContext/utils/orderLineDisplay.js +36 -0
  34. package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
  35. package/dist/modules/BookingContext/utils/productExtend.js +339 -0
  36. package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  37. package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
  38. package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  39. package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
  40. package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
  41. package/dist/modules/BookingContext/utils/resources.js +486 -0
  42. package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  43. package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
  44. package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  45. package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
  46. package/dist/modules/Cart/index.js +3 -0
  47. package/dist/modules/Cart/utils/cartProduct.js +27 -5
  48. package/dist/modules/Cart/utils/cartResource.js +0 -2
  49. package/dist/modules/Cart/utils/changePrice.js +11 -11
  50. package/dist/modules/Customer/index.d.ts +20 -0
  51. package/dist/modules/Customer/index.js +172 -83
  52. package/dist/modules/Customer/types.d.ts +2 -0
  53. package/dist/modules/Date/index.js +5 -1
  54. package/dist/modules/Discount/index.d.ts +2 -2
  55. package/dist/modules/Discount/index.js +43 -30
  56. package/dist/modules/Discount/types.d.ts +1 -1
  57. package/dist/modules/OpenData/index.d.ts +8 -0
  58. package/dist/modules/OpenData/index.js +38 -16
  59. package/dist/modules/Order/index.d.ts +449 -24
  60. package/dist/modules/Order/index.js +5460 -574
  61. package/dist/modules/Order/types.d.ts +693 -88
  62. package/dist/modules/Order/types.js +68 -1
  63. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  64. package/dist/modules/Order/utils/bundleDiscountHydration.js +144 -0
  65. package/dist/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  66. package/dist/modules/Order/utils/manualProductDiscount.js +210 -0
  67. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  68. package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
  69. package/dist/modules/Order/utils.d.ts +167 -18
  70. package/dist/modules/Order/utils.js +960 -165
  71. package/dist/modules/Payment/index.d.ts +10 -9
  72. package/dist/modules/Payment/index.js +573 -746
  73. package/dist/modules/Payment/types.d.ts +44 -24
  74. package/dist/modules/Payment/utils.d.ts +1 -1
  75. package/dist/modules/Payment/utils.js +4 -3
  76. package/dist/modules/Payment/walletpass.d.ts +0 -2
  77. package/dist/modules/Payment/walletpass.js +49 -33
  78. package/dist/modules/Product/types.d.ts +29 -7
  79. package/dist/modules/ProductList/index.d.ts +17 -13
  80. package/dist/modules/ProductList/index.js +182 -81
  81. package/dist/modules/ProductList/types.d.ts +16 -0
  82. package/dist/modules/Quotation/index.d.ts +22 -2
  83. package/dist/modules/Quotation/index.js +108 -42
  84. package/dist/modules/Quotation/types.d.ts +19 -0
  85. package/dist/modules/ResourcePlanner/index.d.ts +24 -0
  86. package/dist/modules/ResourcePlanner/index.js +181 -0
  87. package/dist/modules/ResourcePlanner/planner.d.ts +14 -0
  88. package/dist/modules/ResourcePlanner/planner.js +1069 -0
  89. package/dist/modules/ResourcePlanner/types.d.ts +227 -0
  90. package/dist/modules/ResourcePlanner/types.js +1 -0
  91. package/dist/modules/Rules/index.d.ts +8 -10
  92. package/dist/modules/Rules/index.js +324 -513
  93. package/dist/modules/Rules/types.d.ts +14 -3
  94. package/dist/modules/SalesSummary/index.d.ts +23 -26
  95. package/dist/modules/SalesSummary/index.js +152 -46
  96. package/dist/modules/SalesSummary/types.d.ts +9 -1
  97. package/dist/modules/SalesSummary/utils.d.ts +3 -22
  98. package/dist/modules/SalesSummary/utils.js +804 -165
  99. package/dist/modules/Schedule/getDateIsInSchedule.js +14 -12
  100. package/dist/modules/Schedule/index.d.ts +18 -5
  101. package/dist/modules/Schedule/index.js +79 -24
  102. package/dist/modules/Schedule/types.d.ts +2 -0
  103. package/dist/modules/Schedule/utils.js +1 -0
  104. package/dist/modules/Step/index.js +1 -0
  105. package/dist/modules/Summary/index.js +4 -3
  106. package/dist/modules/Summary/utils.js +22 -43
  107. package/dist/modules/SurchargeList/index.d.ts +18 -0
  108. package/dist/modules/SurchargeList/index.js +185 -0
  109. package/dist/modules/SurchargeList/types.d.ts +15 -0
  110. package/dist/modules/SurchargeList/types.js +1 -0
  111. package/dist/modules/index.d.ts +3 -0
  112. package/dist/modules/index.js +4 -1
  113. package/dist/plugins/app.d.ts +2 -0
  114. package/dist/plugins/request.d.ts +1 -0
  115. package/dist/plugins/request.js +4 -1
  116. package/dist/plugins/window.js +6 -2
  117. package/dist/server/index.d.ts +462 -8
  118. package/dist/server/index.js +6168 -680
  119. package/dist/server/modules/floor-plan/index.d.ts +39 -0
  120. package/dist/server/modules/floor-plan/index.js +595 -0
  121. package/dist/server/modules/floor-plan/types.d.ts +43 -0
  122. package/dist/server/modules/floor-plan/types.js +13 -0
  123. package/dist/server/modules/index.d.ts +7 -2
  124. package/dist/server/modules/index.js +6 -0
  125. package/dist/server/modules/menu/index.js +41 -32
  126. package/dist/server/modules/order/index.d.ts +207 -14
  127. package/dist/server/modules/order/index.js +2328 -379
  128. package/dist/server/modules/order/types.d.ts +76 -5
  129. package/dist/server/modules/order/types.js +14 -1
  130. package/dist/server/modules/order/utils/filterBookings.d.ts +7 -1
  131. package/dist/server/modules/order/utils/filterBookings.js +118 -11
  132. package/dist/server/modules/order/utils/filterOrders.js +242 -14
  133. package/dist/server/modules/payment/index.d.ts +28 -0
  134. package/dist/server/modules/payment/index.js +305 -0
  135. package/dist/server/modules/payment/types.d.ts +9 -0
  136. package/dist/server/modules/payment/types.js +1 -0
  137. package/dist/server/modules/products/index.d.ts +105 -14
  138. package/dist/server/modules/products/index.js +1416 -521
  139. package/dist/server/modules/products/types.d.ts +34 -1
  140. package/dist/server/modules/products/types.js +4 -0
  141. package/dist/server/modules/quotation/index.d.ts +39 -0
  142. package/dist/server/modules/quotation/index.js +298 -77
  143. package/dist/server/modules/resource/index.d.ts +2 -3
  144. package/dist/server/modules/resource/index.js +109 -86
  145. package/dist/server/modules/schedule/index.d.ts +6 -4
  146. package/dist/server/modules/schedule/index.js +145 -106
  147. package/dist/server/test.json +713 -0
  148. package/dist/server/types.d.ts +2 -0
  149. package/dist/server/utils/product.js +3 -2
  150. package/dist/server/utils/small-ticket.d.ts +71 -0
  151. package/dist/server/utils/small-ticket.js +963 -0
  152. package/dist/solution/BaseSales/index.d.ts +378 -0
  153. package/dist/solution/BaseSales/index.js +4009 -0
  154. package/dist/solution/BaseSales/types.d.ts +394 -0
  155. package/dist/solution/BaseSales/types.js +40 -0
  156. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
  157. package/dist/solution/BaseSales/utils/cartPromotion.js +1450 -0
  158. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +144 -0
  159. package/dist/solution/BaseSales/utils/parseSalesResponse.js +157 -0
  160. package/dist/solution/BaseSales/utils/quotationPrice.d.ts +18 -0
  161. package/dist/solution/BaseSales/utils/quotationPrice.js +250 -0
  162. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +63 -0
  163. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +218 -0
  164. package/dist/solution/BaseSales/utils.d.ts +40 -0
  165. package/dist/solution/BaseSales/utils.js +263 -0
  166. package/dist/solution/BookingByStep/index.d.ts +1 -1
  167. package/dist/solution/BookingByStep/index.js +60 -11
  168. package/dist/solution/BookingByStep/utils/capacity.js +11 -1
  169. package/dist/solution/BookingByStep/utils/resources.js +3 -1
  170. package/dist/solution/BookingByStep/utils/timeslots.js +43 -2
  171. package/dist/solution/BookingTicket/index.d.ts +393 -24
  172. package/dist/solution/BookingTicket/index.js +2508 -443
  173. package/dist/solution/BookingTicket/types.d.ts +191 -6
  174. package/dist/solution/BookingTicket/types.js +83 -10
  175. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
  176. package/dist/solution/BookingTicket/utils/addProductDecision.js +346 -0
  177. package/dist/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
  178. package/dist/solution/BookingTicket/utils/addTimeAvailability.js +95 -0
  179. package/dist/solution/BookingTicket/utils/bookingStatus.d.ts +77 -0
  180. package/dist/solution/BookingTicket/utils/bookingStatus.js +136 -0
  181. package/dist/solution/BookingTicket/utils/cartView.d.ts +29 -0
  182. package/dist/solution/BookingTicket/utils/cartView.js +209 -0
  183. package/dist/solution/BookingTicket/utils/exampleData.d.ts +123 -0
  184. package/dist/solution/BookingTicket/utils/exampleData.js +183 -0
  185. package/dist/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
  186. package/dist/solution/BookingTicket/utils/orderCustomer.js +31 -0
  187. package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
  188. package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.js +438 -0
  189. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  190. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +400 -0
  191. package/dist/solution/BookingTicket/utils/scan/cloudSearch.d.ts +4 -0
  192. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +42 -1
  193. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  194. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +56 -0
  195. package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  196. package/dist/solution/BookingTicket/utils/scan/handleScan.js +42 -28
  197. package/dist/solution/BookingTicket/utils/scan/index.d.ts +5 -0
  198. package/dist/solution/BookingTicket/utils/scan/index.js +30 -14
  199. package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  200. package/dist/solution/BookingTicket/utils/scan/scanProductValues.js +150 -0
  201. package/dist/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
  202. package/dist/solution/BookingTicket/utils/sessionCatalogStale.js +78 -0
  203. package/dist/solution/BuyTickets/index.js +12 -9
  204. package/dist/solution/Checkout/index.d.ts +1 -0
  205. package/dist/solution/Checkout/index.js +275 -209
  206. package/dist/solution/Checkout/utils/index.js +20 -8
  207. package/dist/solution/RegisterAndLogin/config.js +2 -10
  208. package/dist/solution/RegisterAndLogin/index.js +76 -30
  209. package/dist/solution/Sales/index.d.ts +50 -5
  210. package/dist/solution/Sales/index.js +484 -92
  211. package/dist/solution/Sales/types.d.ts +26 -2
  212. package/dist/solution/ScanOrder/index.d.ts +27 -21
  213. package/dist/solution/ScanOrder/index.js +519 -444
  214. package/dist/solution/ScanOrder/types.d.ts +33 -11
  215. package/dist/solution/ScanOrder/types.js +4 -5
  216. package/dist/solution/ScanOrder/utils.d.ts +4 -1
  217. package/dist/solution/ScanOrder/utils.js +109 -34
  218. package/dist/solution/ShopDiscount/index.js +18 -19
  219. package/dist/solution/ShopDiscount/types.d.ts +4 -5
  220. package/dist/solution/ShopDiscount/utils.d.ts +0 -9
  221. package/dist/solution/ShopDiscount/utils.js +0 -9
  222. package/dist/solution/UnifiedBookingSales/index.d.ts +183 -0
  223. package/dist/solution/UnifiedBookingSales/index.js +1871 -0
  224. package/dist/solution/UnifiedBookingSales/types.d.ts +143 -0
  225. package/dist/solution/UnifiedBookingSales/types.js +11 -0
  226. package/dist/solution/VenueBooking/index.d.ts +32 -51
  227. package/dist/solution/VenueBooking/index.js +741 -808
  228. package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -2
  229. package/dist/solution/VenueBooking/types.d.ts +1 -3
  230. package/dist/solution/VenueBooking/types.js +0 -1
  231. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
  232. package/dist/solution/VenueBooking/utils/dateSummary.js +25 -12
  233. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
  234. package/dist/solution/VenueBooking/utils/slotMerge.js +9 -3
  235. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
  236. package/dist/solution/VenueBooking/utils/timeSlot.js +4 -9
  237. package/dist/solution/index.d.ts +2 -0
  238. package/dist/solution/index.js +3 -1
  239. package/dist/types/index.d.ts +12 -2
  240. package/dist/utils/task.js +18 -15
  241. package/dist/utils/watch.js +1 -0
  242. package/lib/apis/picoding.js +0 -2
  243. package/lib/core/index.js +132 -130
  244. package/lib/effects/index.js +57 -46
  245. package/lib/index.d.ts +0 -1
  246. package/lib/index.js +50 -92
  247. package/lib/model/index.js +21 -14
  248. package/lib/model/strategy/adapter/dataVariant/adapter.js +50 -38
  249. package/lib/model/strategy/adapter/dataVariant/evaluator.js +236 -162
  250. package/lib/model/strategy/adapter/dataVariant/examples.js +237 -229
  251. package/lib/model/strategy/adapter/dataVariant/index.js +34 -39
  252. package/lib/model/strategy/adapter/dataVariant/type.js +28 -57
  253. package/lib/model/strategy/adapter/index.js +64 -100
  254. package/lib/model/strategy/adapter/itemRule/adapter.js +144 -156
  255. package/lib/model/strategy/adapter/itemRule/evaluator.js +48 -36
  256. package/lib/model/strategy/adapter/itemRule/examples.js +225 -295
  257. package/lib/model/strategy/adapter/itemRule/index.js +57 -83
  258. package/lib/model/strategy/adapter/itemRule/type.js +36 -97
  259. package/lib/model/strategy/adapter/promotion/adapter.js +63 -84
  260. package/lib/model/strategy/adapter/promotion/evaluator.js +233 -382
  261. package/lib/model/strategy/adapter/promotion/examples.js +159 -139
  262. package/lib/model/strategy/adapter/promotion/index.js +0 -1
  263. package/lib/model/strategy/adapter/promotion/type.js +35 -199
  264. package/lib/model/strategy/adapter/type.js +16 -4
  265. package/lib/model/strategy/adapter/walletPass/evaluator.js +152 -180
  266. package/lib/model/strategy/adapter/walletPass/example.js +190 -217
  267. package/lib/model/strategy/adapter/walletPass/index.js +51 -75
  268. package/lib/model/strategy/adapter/walletPass/locales.js +58 -36
  269. package/lib/model/strategy/adapter/walletPass/type.d.ts +0 -3
  270. package/lib/model/strategy/adapter/walletPass/type.js +16 -4
  271. package/lib/model/strategy/adapter/walletPass/utils.d.ts +0 -26
  272. package/lib/model/strategy/adapter/walletPass/utils.js +383 -676
  273. package/lib/model/strategy/engine.js +168 -270
  274. package/lib/model/strategy/index.js +34 -49
  275. package/lib/model/strategy/strategy-example.js +239 -243
  276. package/lib/model/strategy/type.js +40 -100
  277. package/lib/modules/Account/index.js +53 -39
  278. package/lib/modules/Account/types.js +33 -20
  279. package/lib/modules/AccountList/index.js +154 -116
  280. package/lib/modules/AccountList/types.js +31 -30
  281. package/lib/modules/AccountList/utils.js +30 -18
  282. package/lib/modules/BaseModule.d.ts +2 -2
  283. package/lib/modules/BaseModule.js +50 -29
  284. package/lib/modules/BookingContext/index.d.ts +48 -0
  285. package/lib/modules/BookingContext/index.js +368 -0
  286. package/lib/modules/BookingContext/types.d.ts +102 -0
  287. package/lib/modules/BookingContext/types.js +34 -0
  288. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  289. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +298 -0
  290. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  291. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +155 -0
  292. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
  293. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +222 -0
  294. package/lib/modules/BookingContext/utils/flexible.d.ts +28 -0
  295. package/lib/modules/BookingContext/utils/flexible.js +80 -0
  296. package/lib/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  297. package/lib/modules/BookingContext/utils/formatResourceList.js +50 -0
  298. package/lib/modules/BookingContext/utils/index.d.ts +11 -0
  299. package/lib/modules/BookingContext/utils/index.js +43 -0
  300. package/lib/modules/BookingContext/utils/noResource.d.ts +13 -0
  301. package/lib/modules/BookingContext/utils/noResource.js +90 -0
  302. package/lib/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
  303. package/lib/modules/BookingContext/utils/orderLineDisplay.js +56 -0
  304. package/lib/modules/BookingContext/utils/productExtend.d.ts +72 -0
  305. package/lib/modules/BookingContext/utils/productExtend.js +283 -0
  306. package/lib/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  307. package/lib/modules/BookingContext/utils/resourceErrors.js +80 -0
  308. package/lib/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  309. package/lib/modules/BookingContext/utils/resourceSelection.js +46 -0
  310. package/lib/modules/BookingContext/utils/resources.d.ts +80 -0
  311. package/lib/modules/BookingContext/utils/resources.js +377 -0
  312. package/lib/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  313. package/lib/modules/BookingContext/utils/serviceTimes.js +162 -0
  314. package/lib/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  315. package/lib/modules/BookingContext/utils/timeSlices.js +124 -0
  316. package/lib/modules/Cart/index.js +124 -170
  317. package/lib/modules/Cart/types.js +51 -46
  318. package/lib/modules/Cart/utils/cartAccount.js +39 -40
  319. package/lib/modules/Cart/utils/cartDate.js +61 -56
  320. package/lib/modules/Cart/utils/cartDiscount.js +33 -28
  321. package/lib/modules/Cart/utils/cartNote.js +32 -27
  322. package/lib/modules/Cart/utils/cartProduct.js +261 -309
  323. package/lib/modules/Cart/utils/cartRelationForms.js +35 -29
  324. package/lib/modules/Cart/utils/cartResource.js +78 -72
  325. package/lib/modules/Cart/utils/changePrice.js +59 -31
  326. package/lib/modules/Cart/utils/index.js +48 -106
  327. package/lib/modules/Customer/constants.js +34 -13
  328. package/lib/modules/Customer/index.d.ts +20 -0
  329. package/lib/modules/Customer/index.js +207 -217
  330. package/lib/modules/Customer/types.d.ts +2 -0
  331. package/lib/modules/Customer/types.js +35 -38
  332. package/lib/modules/Date/index.js +115 -116
  333. package/lib/modules/Date/types.js +28 -16
  334. package/lib/modules/Date/utils.js +123 -174
  335. package/lib/modules/Discount/index.d.ts +2 -2
  336. package/lib/modules/Discount/index.js +133 -119
  337. package/lib/modules/Discount/types.d.ts +1 -1
  338. package/lib/modules/Discount/types.js +31 -9
  339. package/lib/modules/Guests/index.js +56 -30
  340. package/lib/modules/Guests/types.js +33 -23
  341. package/lib/modules/Holder/index.js +189 -209
  342. package/lib/modules/Holder/types.js +16 -4
  343. package/lib/modules/Holder/utils.js +49 -20
  344. package/lib/modules/OpenData/index.d.ts +8 -0
  345. package/lib/modules/OpenData/index.js +88 -63
  346. package/lib/modules/OpenData/types.js +16 -4
  347. package/lib/modules/OpenData/utils.js +78 -44
  348. package/lib/modules/Order/index.d.ts +449 -24
  349. package/lib/modules/Order/index.js +4184 -514
  350. package/lib/modules/Order/types.d.ts +693 -88
  351. package/lib/modules/Order/types.js +35 -24
  352. package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  353. package/lib/modules/Order/utils/bundleDiscountHydration.js +139 -0
  354. package/lib/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  355. package/lib/modules/Order/utils/manualProductDiscount.js +206 -0
  356. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  357. package/lib/modules/Order/utils/orderCollectionIdentity.js +415 -0
  358. package/lib/modules/Order/utils.d.ts +167 -18
  359. package/lib/modules/Order/utils.js +1085 -414
  360. package/lib/modules/Payment/cash.js +33 -20
  361. package/lib/modules/Payment/cashRecommendationAlgorithm.js +76 -145
  362. package/lib/modules/Payment/eftpos.js +30 -16
  363. package/lib/modules/Payment/index.d.ts +10 -9
  364. package/lib/modules/Payment/index.js +402 -636
  365. package/lib/modules/Payment/mx51.js +0 -1
  366. package/lib/modules/Payment/types.d.ts +44 -24
  367. package/lib/modules/Payment/types.js +107 -216
  368. package/lib/modules/Payment/utils.d.ts +1 -1
  369. package/lib/modules/Payment/utils.js +50 -52
  370. package/lib/modules/Payment/walletpass.d.ts +0 -2
  371. package/lib/modules/Payment/walletpass.js +216 -221
  372. package/lib/modules/Product/index.js +46 -51
  373. package/lib/modules/Product/types.d.ts +29 -7
  374. package/lib/modules/Product/types.js +16 -4
  375. package/lib/modules/Product/utils.js +33 -32
  376. package/lib/modules/ProductList/index.d.ts +17 -13
  377. package/lib/modules/ProductList/index.js +161 -120
  378. package/lib/modules/ProductList/types.d.ts +16 -0
  379. package/lib/modules/ProductList/types.js +31 -9
  380. package/lib/modules/Quotation/index.d.ts +22 -2
  381. package/lib/modules/Quotation/index.js +154 -64
  382. package/lib/modules/Quotation/types.d.ts +19 -0
  383. package/lib/modules/Quotation/types.js +16 -4
  384. package/lib/modules/Resource/index.js +59 -27
  385. package/lib/modules/Resource/types.js +32 -22
  386. package/lib/modules/Resource/utils.js +38 -30
  387. package/lib/modules/ResourcePlanner/index.d.ts +24 -0
  388. package/lib/modules/ResourcePlanner/index.js +148 -0
  389. package/lib/modules/ResourcePlanner/planner.d.ts +14 -0
  390. package/lib/modules/ResourcePlanner/planner.js +933 -0
  391. package/lib/modules/ResourcePlanner/types.d.ts +227 -0
  392. package/lib/modules/ResourcePlanner/types.js +17 -0
  393. package/lib/modules/Rules/index.d.ts +8 -10
  394. package/lib/modules/Rules/index.js +960 -1440
  395. package/lib/modules/Rules/types.d.ts +14 -3
  396. package/lib/modules/Rules/types.js +40 -17
  397. package/lib/modules/SalesSummary/index.d.ts +23 -26
  398. package/lib/modules/SalesSummary/index.js +134 -61
  399. package/lib/modules/SalesSummary/types.d.ts +9 -1
  400. package/lib/modules/SalesSummary/types.js +16 -4
  401. package/lib/modules/SalesSummary/utils.d.ts +3 -22
  402. package/lib/modules/SalesSummary/utils.js +814 -233
  403. package/lib/modules/ScanOrderLogger/index.js +79 -59
  404. package/lib/modules/ScanOrderLogger/providers/feishu.js +78 -54
  405. package/lib/modules/ScanOrderLogger/providers/grafana.js +36 -13
  406. package/lib/modules/ScanOrderLogger/types.js +16 -4
  407. package/lib/modules/Schedule/getDateIsInSchedule.js +169 -338
  408. package/lib/modules/Schedule/index.d.ts +18 -5
  409. package/lib/modules/Schedule/index.js +153 -104
  410. package/lib/modules/Schedule/type.js +16 -4
  411. package/lib/modules/Schedule/types.d.ts +2 -0
  412. package/lib/modules/Schedule/types.js +16 -4
  413. package/lib/modules/Schedule/utils.js +291 -433
  414. package/lib/modules/Step/index.js +52 -40
  415. package/lib/modules/Step/tyeps.js +16 -4
  416. package/lib/modules/Summary/index.js +71 -66
  417. package/lib/modules/Summary/types.js +16 -4
  418. package/lib/modules/Summary/utils.js +418 -791
  419. package/lib/modules/SurchargeList/index.d.ts +18 -0
  420. package/lib/modules/SurchargeList/index.js +109 -0
  421. package/lib/modules/SurchargeList/types.d.ts +15 -0
  422. package/lib/modules/SurchargeList/types.js +17 -0
  423. package/lib/modules/index.d.ts +3 -0
  424. package/lib/modules/index.js +63 -212
  425. package/lib/plugins/app.d.ts +2 -0
  426. package/lib/plugins/app.js +16 -4
  427. package/lib/plugins/index.js +25 -36
  428. package/lib/plugins/request.d.ts +1 -0
  429. package/lib/plugins/request.js +126 -137
  430. package/lib/plugins/shopStore.js +16 -4
  431. package/lib/plugins/user.js +16 -4
  432. package/lib/plugins/window.js +179 -171
  433. package/lib/server/index.d.ts +462 -8
  434. package/lib/server/index.js +4520 -1162
  435. package/lib/server/modules/floor-plan/index.d.ts +39 -0
  436. package/lib/server/modules/floor-plan/index.js +327 -0
  437. package/lib/server/modules/floor-plan/types.d.ts +43 -0
  438. package/lib/server/modules/floor-plan/types.js +34 -0
  439. package/lib/server/modules/index.d.ts +7 -2
  440. package/lib/server/modules/index.js +67 -84
  441. package/lib/server/modules/menu/index.js +122 -146
  442. package/lib/server/modules/menu/types.js +31 -18
  443. package/lib/server/modules/order/index.d.ts +207 -14
  444. package/lib/server/modules/order/index.js +1543 -285
  445. package/lib/server/modules/order/types.d.ts +76 -5
  446. package/lib/server/modules/order/types.js +32 -107
  447. package/lib/server/modules/order/utils/filterBookings.d.ts +7 -1
  448. package/lib/server/modules/order/utils/filterBookings.js +259 -176
  449. package/lib/server/modules/order/utils/filterOrders.js +293 -94
  450. package/lib/server/modules/payment/index.d.ts +28 -0
  451. package/lib/server/modules/payment/index.js +192 -0
  452. package/lib/server/modules/payment/types.d.ts +9 -0
  453. package/lib/server/modules/payment/types.js +17 -0
  454. package/lib/server/modules/products/index.d.ts +105 -14
  455. package/lib/server/modules/products/index.js +850 -475
  456. package/lib/server/modules/products/types.d.ts +34 -1
  457. package/lib/server/modules/products/types.js +34 -41
  458. package/lib/server/modules/quotation/index.d.ts +39 -0
  459. package/lib/server/modules/quotation/index.js +254 -75
  460. package/lib/server/modules/quotation/types.js +31 -21
  461. package/lib/server/modules/resource/index.d.ts +2 -3
  462. package/lib/server/modules/resource/index.js +240 -243
  463. package/lib/server/modules/resource/types.js +33 -42
  464. package/lib/server/modules/schedule/index.d.ts +6 -4
  465. package/lib/server/modules/schedule/index.js +146 -147
  466. package/lib/server/modules/schedule/types.js +21 -14
  467. package/lib/server/modules/schedule/utils.js +163 -334
  468. package/lib/server/test.json +713 -0
  469. package/lib/server/types.d.ts +2 -0
  470. package/lib/server/types.js +16 -4
  471. package/lib/server/utils/index.js +23 -25
  472. package/lib/server/utils/product.js +140 -197
  473. package/lib/server/utils/schedule.js +41 -34
  474. package/lib/server/utils/small-ticket.d.ts +71 -0
  475. package/lib/server/utils/small-ticket.js +904 -0
  476. package/lib/server/utils/time.js +49 -40
  477. package/lib/solution/BaseSales/index.d.ts +378 -0
  478. package/lib/solution/BaseSales/index.js +2533 -0
  479. package/lib/solution/BaseSales/types.d.ts +394 -0
  480. package/lib/solution/BaseSales/types.js +43 -0
  481. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
  482. package/lib/solution/BaseSales/utils/cartPromotion.js +1004 -0
  483. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +144 -0
  484. package/lib/solution/BaseSales/utils/parseSalesResponse.js +160 -0
  485. package/lib/solution/BaseSales/utils/quotationPrice.d.ts +18 -0
  486. package/lib/solution/BaseSales/utils/quotationPrice.js +289 -0
  487. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +63 -0
  488. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +256 -0
  489. package/lib/solution/BaseSales/utils.d.ts +40 -0
  490. package/lib/solution/BaseSales/utils.js +244 -0
  491. package/lib/solution/BookingByStep/index.d.ts +1 -1
  492. package/lib/solution/BookingByStep/index.js +1340 -1530
  493. package/lib/solution/BookingByStep/types.js +99 -40
  494. package/lib/solution/BookingByStep/utils/capacity.js +160 -192
  495. package/lib/solution/BookingByStep/utils/products.js +52 -42
  496. package/lib/solution/BookingByStep/utils/resources.js +330 -527
  497. package/lib/solution/BookingByStep/utils/stock.js +44 -65
  498. package/lib/solution/BookingByStep/utils/timeslots.js +131 -129
  499. package/lib/solution/BookingTicket/index.d.ts +393 -24
  500. package/lib/solution/BookingTicket/index.js +1374 -184
  501. package/lib/solution/BookingTicket/types.d.ts +191 -6
  502. package/lib/solution/BookingTicket/types.js +79 -40
  503. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
  504. package/lib/solution/BookingTicket/utils/addProductDecision.js +318 -0
  505. package/lib/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
  506. package/lib/solution/BookingTicket/utils/addTimeAvailability.js +125 -0
  507. package/lib/solution/BookingTicket/utils/bookingStatus.d.ts +77 -0
  508. package/lib/solution/BookingTicket/utils/bookingStatus.js +107 -0
  509. package/lib/solution/BookingTicket/utils/cartView.d.ts +29 -0
  510. package/lib/solution/BookingTicket/utils/cartView.js +184 -0
  511. package/lib/solution/BookingTicket/utils/exampleData.d.ts +123 -0
  512. package/lib/solution/BookingTicket/utils/exampleData.js +0 -0
  513. package/lib/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
  514. package/lib/solution/BookingTicket/utils/orderCustomer.js +58 -0
  515. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
  516. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +254 -0
  517. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  518. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +169 -0
  519. package/lib/solution/BookingTicket/utils/scan/cloudSearch.d.ts +4 -0
  520. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +97 -64
  521. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  522. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +51 -0
  523. package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  524. package/lib/solution/BookingTicket/utils/scan/handleScan.js +81 -82
  525. package/lib/solution/BookingTicket/utils/scan/index.d.ts +5 -0
  526. package/lib/solution/BookingTicket/utils/scan/index.js +109 -91
  527. package/lib/solution/BookingTicket/utils/scan/scanCache.js +43 -90
  528. package/lib/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  529. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +127 -0
  530. package/lib/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
  531. package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +85 -0
  532. package/lib/solution/BuyTickets/index.js +70 -67
  533. package/lib/solution/BuyTickets/types.js +38 -22
  534. package/lib/solution/Checkout/index.d.ts +1 -0
  535. package/lib/solution/Checkout/index.js +1169 -1463
  536. package/lib/solution/Checkout/types.js +61 -91
  537. package/lib/solution/Checkout/utils/index.js +156 -228
  538. package/lib/solution/PlaceOrder/index.js +0 -55
  539. package/lib/solution/RegisterAndLogin/config.js +462 -503
  540. package/lib/solution/RegisterAndLogin/index.js +630 -633
  541. package/lib/solution/RegisterAndLogin/types.js +76 -189
  542. package/lib/solution/RegisterAndLogin/utils.js +125 -183
  543. package/lib/solution/Sales/index.d.ts +50 -5
  544. package/lib/solution/Sales/index.js +498 -238
  545. package/lib/solution/Sales/types.d.ts +26 -2
  546. package/lib/solution/Sales/types.js +33 -27
  547. package/lib/solution/ScanOrder/index.d.ts +27 -21
  548. package/lib/solution/ScanOrder/index.js +936 -864
  549. package/lib/solution/ScanOrder/types.d.ts +33 -11
  550. package/lib/solution/ScanOrder/types.js +34 -34
  551. package/lib/solution/ScanOrder/utils.d.ts +4 -1
  552. package/lib/solution/ScanOrder/utils.js +422 -385
  553. package/lib/solution/ShopDiscount/index.js +233 -235
  554. package/lib/solution/ShopDiscount/types.d.ts +4 -5
  555. package/lib/solution/ShopDiscount/types.js +37 -15
  556. package/lib/solution/ShopDiscount/utils.d.ts +0 -9
  557. package/lib/solution/ShopDiscount/utils.js +172 -309
  558. package/lib/solution/UnifiedBookingSales/index.d.ts +183 -0
  559. package/lib/solution/UnifiedBookingSales/index.js +1076 -0
  560. package/lib/solution/UnifiedBookingSales/types.d.ts +143 -0
  561. package/lib/solution/UnifiedBookingSales/types.js +33 -0
  562. package/lib/solution/VenueBooking/index.d.ts +32 -51
  563. package/lib/solution/VenueBooking/index.js +1008 -984
  564. package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -2
  565. package/lib/solution/VenueBooking/types.d.ts +1 -3
  566. package/lib/solution/VenueBooking/types.js +39 -20
  567. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
  568. package/lib/solution/VenueBooking/utils/dateSummary.js +62 -25
  569. package/lib/solution/VenueBooking/utils/resource.js +54 -31
  570. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
  571. package/lib/solution/VenueBooking/utils/slotMerge.js +109 -90
  572. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
  573. package/lib/solution/VenueBooking/utils/timeSlot.js +133 -138
  574. package/lib/solution/VenueBooking/utils.js +67 -130
  575. package/lib/solution/index.d.ts +2 -0
  576. package/lib/solution/index.js +41 -102
  577. package/lib/store/createStore.js +29 -32
  578. package/lib/types/index.d.ts +12 -2
  579. package/lib/types/index.js +16 -4
  580. package/lib/utils/task.js +36 -36
  581. package/lib/utils/watch.js +47 -81
  582. package/package.json +2 -4
  583. package/dist/solution/Checkout/appointmentDemo.json +0 -1
  584. package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
  585. package/dist/solution/VenueBooking/utils/smartPricing.js +0 -233
  586. package/lib/solution/Checkout/appointmentDemo.json +0 -1
  587. package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
  588. package/lib/solution/VenueBooking/utils/smartPricing.js +0 -192
@@ -0,0 +1,2533 @@
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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/solution/BaseSales/index.ts
31
+ var BaseSales_exports = {};
32
+ __export(BaseSales_exports, {
33
+ BaseSalesImpl: () => BaseSalesImpl
34
+ });
35
+ module.exports = __toCommonJS(BaseSales_exports);
36
+ var import_BaseModule = require("../../modules/BaseModule");
37
+ var import_types = require("./types");
38
+ var import_Order = require("../../modules/Order");
39
+ var import_decimal = __toESM(require("decimal.js"));
40
+ var import_lodash_es = require("lodash-es");
41
+ var import_types2 = require("../BookingByStep/types");
42
+ var import_utils = require("../../modules/Order/utils");
43
+ var import_orderCollectionIdentity = require("../../modules/Order/utils/orderCollectionIdentity");
44
+ var import_dayjs = __toESM(require("dayjs"));
45
+ __reExport(BaseSales_exports, require("./types"), module.exports);
46
+ var import_Quotation = require("../../modules/Quotation");
47
+ var import_transformBaseProductToOrderProduct = require("./utils/transformBaseProductToOrderProduct");
48
+ var import_quotationPrice = require("./utils/quotationPrice");
49
+ var SERVER_ORDER_CHANGED_EVENT = "order:onOrdersChanged";
50
+ function isBaseSalesManualProductDiscountProduct(product) {
51
+ var _a, _b;
52
+ return ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.is_manual_discount) === true || ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.is_manual_discount) === 1 || ((product == null ? void 0 : product.discount_list) || []).some((item) => (item == null ? void 0 : item.type) === "product");
53
+ }
54
+ function getBaseSalesProductUid(product) {
55
+ var _a;
56
+ const uid = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) || (product == null ? void 0 : product.unique_identification_number);
57
+ if (uid === void 0 || uid === null || uid === "")
58
+ return null;
59
+ return String(uid);
60
+ }
61
+ function preserveManualProductDiscountProducts(previousProducts, nextProducts) {
62
+ const previousByUid = /* @__PURE__ */ new Map();
63
+ (previousProducts || []).forEach((product, index) => {
64
+ const uid = getBaseSalesProductUid(product);
65
+ if (uid)
66
+ previousByUid.set(uid, product);
67
+ previousByUid.set(`__index__:${index}`, product);
68
+ });
69
+ return (nextProducts || []).map((product, index) => {
70
+ const uid = getBaseSalesProductUid(product);
71
+ const previous = (uid ? previousByUid.get(uid) : void 0) || previousByUid.get(`__index__:${index}`);
72
+ return previous && isBaseSalesManualProductDiscountProduct(previous) ? previous : product;
73
+ });
74
+ }
75
+ function isBaseSalesHistoricalDiscountEntry(discount) {
76
+ return Boolean(
77
+ (discount == null ? void 0 : discount.isEditMode) || (discount == null ? void 0 : discount.isDisabled) || (discount == null ? void 0 : discount.order_discount_id) != null
78
+ );
79
+ }
80
+ var BASE_SALES_PERSISTENT_ID_FIELD_BY_KIND = {
81
+ product: "order_detail_id",
82
+ booking: "schedule_event_id",
83
+ payment: "order_payment_id"
84
+ };
85
+ function getBaseSalesOrderCollectionKind(key) {
86
+ if (key === "products")
87
+ return "product";
88
+ if (key === "bookings")
89
+ return "booking";
90
+ if (key === "payments" || key === "payment")
91
+ return "payment";
92
+ return null;
93
+ }
94
+ function isSameBaseSalesOrderRecord(left, right) {
95
+ if (!left || !right || typeof left !== "object" || typeof right !== "object")
96
+ return false;
97
+ const leftIdentities = new Set(
98
+ [left.order_id, left.id, left.external_sale_number, left.order_number].filter((value) => value !== void 0 && value !== null && value !== "").map(String)
99
+ );
100
+ if (leftIdentities.size === 0)
101
+ return false;
102
+ return [right.order_id, right.id, right.external_sale_number, right.order_number].some(
103
+ (value) => value !== void 0 && value !== null && value !== "" && leftIdentities.has(String(value))
104
+ );
105
+ }
106
+ function isBaseSalesBlankValue(value) {
107
+ return value === void 0 || value === null || value === "";
108
+ }
109
+ function mergeBaseSalesProductSnapshotFields(currentItem, loadedItem) {
110
+ var _a, _b, _c;
111
+ const mergedItem = (0, import_lodash_es.cloneDeep)(loadedItem);
112
+ if (isBaseSalesBlankValue(mergedItem.product_cover) && !isBaseSalesBlankValue(currentItem == null ? void 0 : currentItem.product_cover)) {
113
+ mergedItem.product_cover = currentItem.product_cover;
114
+ }
115
+ const currentHolderConfig = (_a = currentItem == null ? void 0 : currentItem.metadata) == null ? void 0 : _a.holder_config;
116
+ if ((((_b = mergedItem.metadata) == null ? void 0 : _b.holder_config) === void 0 || ((_c = mergedItem.metadata) == null ? void 0 : _c.holder_config) === null) && currentHolderConfig !== void 0 && currentHolderConfig !== null) {
117
+ mergedItem.metadata = {
118
+ ...mergedItem.metadata || {},
119
+ holder_config: currentHolderConfig
120
+ };
121
+ }
122
+ return mergedItem;
123
+ }
124
+ function mergeBaseSalesCollectionItem(kind, currentItem, incomingItem, uidRemaps) {
125
+ const currentReferenceUid = (0, import_orderCollectionIdentity.getOrderCollectionReferenceUid)(kind, currentItem);
126
+ const incomingReferenceUid = (0, import_orderCollectionIdentity.getOrderCollectionReferenceUid)(kind, incomingItem);
127
+ const identityMergedItem = (0, import_orderCollectionIdentity.mergeOrderCollectionItems)(
128
+ kind,
129
+ currentItem,
130
+ incomingItem
131
+ );
132
+ const mergedUid = (0, import_orderCollectionIdentity.getOrderCollectionUid)(kind, identityMergedItem);
133
+ if (mergedUid) {
134
+ for (const from of /* @__PURE__ */ new Set([currentReferenceUid, incomingReferenceUid])) {
135
+ if (!from || from === mergedUid)
136
+ continue;
137
+ uidRemaps.push({
138
+ kind,
139
+ from,
140
+ to: mergedUid,
141
+ persistentId: (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, incomingItem) || (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, currentItem)
142
+ });
143
+ }
144
+ }
145
+ const mergedItem = mergedUid ? (0, import_orderCollectionIdentity.setOrderCollectionUid)(kind, incomingItem, mergedUid) : (0, import_lodash_es.cloneDeep)(incomingItem);
146
+ const persistentIdField = BASE_SALES_PERSISTENT_ID_FIELD_BY_KIND[kind];
147
+ if (isBaseSalesBlankValue(mergedItem[persistentIdField]) && !isBaseSalesBlankValue(identityMergedItem[persistentIdField])) {
148
+ mergedItem[persistentIdField] = identityMergedItem[persistentIdField];
149
+ }
150
+ return kind === "product" ? mergeBaseSalesProductSnapshotFields(currentItem, mergedItem) : mergedItem;
151
+ }
152
+ function mergeBaseSalesOrderCollection(kind, currentValue, incomingValue, strategy, uidRemaps) {
153
+ const currentItems = (0, import_orderCollectionIdentity.normalizeOrderCollection)(kind, currentValue, {
154
+ ensureUid: false
155
+ }).items;
156
+ const incomingItems = (0, import_orderCollectionIdentity.normalizeOrderCollection)(kind, incomingValue, {
157
+ ensureUid: false
158
+ }).items;
159
+ if (strategy === "authoritative-incoming") {
160
+ const result2 = (0, import_lodash_es.cloneDeep)(incomingItems);
161
+ currentItems.forEach((currentItem) => {
162
+ const incomingIndex = result2.findIndex(
163
+ (incomingItem) => (0, import_orderCollectionIdentity.isSameOrderCollectionItem)(kind, currentItem, incomingItem)
164
+ );
165
+ if (incomingIndex !== -1) {
166
+ result2[incomingIndex] = mergeBaseSalesCollectionItem(
167
+ kind,
168
+ currentItem,
169
+ result2[incomingIndex],
170
+ uidRemaps
171
+ );
172
+ return;
173
+ }
174
+ if (!(0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, currentItem)) {
175
+ result2.push((0, import_lodash_es.cloneDeep)(currentItem));
176
+ }
177
+ });
178
+ return result2;
179
+ }
180
+ const result = (0, import_lodash_es.cloneDeep)(currentItems);
181
+ incomingItems.forEach((incomingItem) => {
182
+ const currentIndex = result.findIndex(
183
+ (currentItem) => (0, import_orderCollectionIdentity.isSameOrderCollectionItem)(kind, currentItem, incomingItem)
184
+ );
185
+ if (currentIndex !== -1) {
186
+ result[currentIndex] = mergeBaseSalesCollectionItem(
187
+ kind,
188
+ result[currentIndex],
189
+ incomingItem,
190
+ uidRemaps
191
+ );
192
+ return;
193
+ }
194
+ result.push((0, import_lodash_es.cloneDeep)(incomingItem));
195
+ });
196
+ return result;
197
+ }
198
+ function normalizeBaseSalesRecordCollections(sourceRecord, options) {
199
+ const normalizedRecord = (0, import_orderCollectionIdentity.normalizeOrderCollections)(
200
+ (0, import_lodash_es.cloneDeep)(sourceRecord || {}),
201
+ options
202
+ ).order;
203
+ if (Array.isArray(normalizedRecord.payment)) {
204
+ normalizedRecord.payment = (0, import_orderCollectionIdentity.normalizeOrderCollection)(
205
+ "payment",
206
+ normalizedRecord.payment,
207
+ options
208
+ ).items;
209
+ }
210
+ return normalizedRecord;
211
+ }
212
+ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, strategy) {
213
+ const normalizedLoadedRecord = normalizeBaseSalesRecordCollections(
214
+ loadedRecord || {},
215
+ { ensureUid: false }
216
+ );
217
+ if (!currentTempOrder) {
218
+ return normalizeBaseSalesRecordCollections(normalizedLoadedRecord);
219
+ }
220
+ const normalizedCurrentTempOrder = normalizeBaseSalesRecordCollections(
221
+ currentTempOrder,
222
+ { ensureUid: false }
223
+ );
224
+ const uidRemaps = [];
225
+ const mergedRecord = (0, import_lodash_es.mergeWith)(
226
+ normalizedCurrentTempOrder,
227
+ normalizedLoadedRecord,
228
+ (currentValue, loadedValue, key) => {
229
+ const collectionKind = getBaseSalesOrderCollectionKind(key);
230
+ if (collectionKind && Array.isArray(loadedValue)) {
231
+ return mergeBaseSalesOrderCollection(
232
+ collectionKind,
233
+ Array.isArray(currentValue) ? currentValue : [],
234
+ loadedValue,
235
+ strategy,
236
+ uidRemaps
237
+ );
238
+ }
239
+ if (Array.isArray(currentValue) && Array.isArray(loadedValue)) {
240
+ return [
241
+ ...(0, import_lodash_es.cloneDeep)(currentValue),
242
+ ...(0, import_lodash_es.cloneDeep)(loadedValue)
243
+ ];
244
+ }
245
+ if (Array.isArray(loadedValue))
246
+ return (0, import_lodash_es.cloneDeep)(loadedValue);
247
+ if (Array.isArray(currentValue) && loadedValue === void 0) {
248
+ return (0, import_lodash_es.cloneDeep)(currentValue);
249
+ }
250
+ return void 0;
251
+ }
252
+ );
253
+ delete mergedRecord.request_unique_idempotency_token;
254
+ return normalizeBaseSalesRecordCollections(
255
+ (0, import_orderCollectionIdentity.applyOrderCollectionUidRemaps)(mergedRecord, uidRemaps)
256
+ );
257
+ }
258
+ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
259
+ constructor(name, version) {
260
+ super(name, version);
261
+ this.defaultName = "baseSales";
262
+ this.defaultVersion = "1.0.0";
263
+ this.isSolution = true;
264
+ this.initializeOptions = {};
265
+ this.store = {
266
+ order: void 0
267
+ };
268
+ this.otherParams = {};
269
+ // 当前缓存中已加载的最新 SalesDetail;只读 getter 走它对外暴露详情数据。
270
+ this.currentSalesDetail = null;
271
+ this.discountConfigCacheKey = null;
272
+ this.hasManualDiscountSelection = false;
273
+ this.reusedSharedSubModuleNames = /* @__PURE__ */ new Set();
274
+ this.paymentMethodsCache = [];
275
+ this.queuedAutoPaymentSync = false;
276
+ this.autoPaymentSyncFlushing = false;
277
+ this.autoPaymentSyncTimer = null;
278
+ this.salesDetailLoadInFlightCount = 0;
279
+ this.salesDetailLoadSequence = 0;
280
+ this.salesDetailHydrateQueue = Promise.resolve();
281
+ this.serverOrderChangeUnsubscribe = null;
282
+ this.serverOrderChangeHydrateInFlight = null;
283
+ this.queuedServerOrderChanges = [];
284
+ this.serverOrderChangeSyncEnabled = false;
285
+ }
286
+ /**
287
+ * 子类可覆盖此方法以追加/收敛要注册的子模块。
288
+ * 默认包含通用销售模块:products / order / salesSummary / schedule / payment / quotation。
289
+ */
290
+ getRegisteredModuleNames() {
291
+ return ["products", "order", "salesSummary", "schedule", "payment", "quotation"];
292
+ }
293
+ getReusableSharedSubModule(moduleName) {
294
+ var _a, _b;
295
+ if (moduleName !== "schedule" && moduleName !== "quotation")
296
+ return null;
297
+ return ((_b = (_a = this.core) == null ? void 0 : _a.getModule) == null ? void 0 : _b.call(_a, moduleName)) || null;
298
+ }
299
+ isScheduleListLoaded(scheduleModule) {
300
+ if (!scheduleModule)
301
+ return false;
302
+ if (typeof scheduleModule.isScheduleListLoaded === "function") {
303
+ return scheduleModule.isScheduleListLoaded();
304
+ }
305
+ if (typeof scheduleModule.getScheduleList === "function") {
306
+ return Array.isArray(scheduleModule.getScheduleList());
307
+ }
308
+ return false;
309
+ }
310
+ /**
311
+ * 记录信息日志
312
+ */
313
+ logInfo(title, metadata) {
314
+ if (this.logger) {
315
+ const tempOrder = this.getTempOrder();
316
+ this.logger.addLog({
317
+ type: "info",
318
+ title: `[BaseSales] ${tempOrder == null ? void 0 : tempOrder.order_id} ${tempOrder == null ? void 0 : tempOrder.external_sale_number} ${title}`,
319
+ metadata: metadata || {}
320
+ });
321
+ }
322
+ }
323
+ /**
324
+ * 记录警告日志
325
+ */
326
+ logWarning(title, metadata) {
327
+ if (this.logger) {
328
+ const tempOrder = this.getTempOrder();
329
+ this.logger.addLog({
330
+ type: "warning",
331
+ title: `[BaseSales] ${tempOrder == null ? void 0 : tempOrder.order_id} ${tempOrder == null ? void 0 : tempOrder.external_sale_number} ${title}`,
332
+ metadata: metadata || {}
333
+ });
334
+ }
335
+ }
336
+ /**
337
+ * 记录错误日志
338
+ */
339
+ logError(title, metadata) {
340
+ if (this.logger) {
341
+ const tempOrder = this.getTempOrder();
342
+ this.logger.addLog({
343
+ type: "error",
344
+ title: `[BaseSales] ${tempOrder == null ? void 0 : tempOrder.order_id} ${tempOrder == null ? void 0 : tempOrder.external_sale_number} ${title}`,
345
+ metadata: metadata || {}
346
+ });
347
+ }
348
+ }
349
+ isCurrentSalesOrderRecord(order) {
350
+ var _a, _b;
351
+ const currentTempOrder = (_b = (_a = this.store.order) == null ? void 0 : _a.getTempOrder) == null ? void 0 : _b.call(_a);
352
+ const currentRecords = [
353
+ currentTempOrder,
354
+ this.currentSalesDetail
355
+ ].filter(Boolean);
356
+ return currentRecords.some((record) => isSameBaseSalesOrderRecord(record, order));
357
+ }
358
+ setServerOrderChangeSyncEnabled(enabled) {
359
+ this.serverOrderChangeSyncEnabled = enabled;
360
+ if (!enabled)
361
+ this.queuedServerOrderChanges = [];
362
+ }
363
+ queueLatestServerOrderChange(order) {
364
+ const snapshot = (0, import_lodash_es.cloneDeep)(order);
365
+ const existingIndex = this.queuedServerOrderChanges.findIndex(
366
+ (queued) => isSameBaseSalesOrderRecord(queued, snapshot)
367
+ );
368
+ if (existingIndex >= 0) {
369
+ this.queuedServerOrderChanges[existingIndex] = snapshot;
370
+ return;
371
+ }
372
+ this.queuedServerOrderChanges.push(snapshot);
373
+ }
374
+ async drainQueuedServerOrderChanges() {
375
+ if (!this.serverOrderChangeSyncEnabled || this.salesDetailLoadInFlightCount > 0 || this.serverOrderChangeHydrateInFlight || this.queuedServerOrderChanges.length === 0)
376
+ return;
377
+ const changedOrders = this.queuedServerOrderChanges;
378
+ this.queuedServerOrderChanges = [];
379
+ await this.syncCurrentSalesDetailFromServerOrderChange({ changedOrders });
380
+ }
381
+ async syncCurrentSalesDetailFromServerOrderChange(payload) {
382
+ const changedOrders = Array.isArray(payload) ? payload : Array.isArray(payload == null ? void 0 : payload.changedOrders) ? payload.changedOrders : (payload == null ? void 0 : payload.data) && typeof payload.data === "object" ? [payload.data] : [];
383
+ if (!this.serverOrderChangeSyncEnabled)
384
+ return;
385
+ if (this.salesDetailLoadInFlightCount > 0) {
386
+ changedOrders.forEach(
387
+ (order) => this.queueLatestServerOrderChange(order)
388
+ );
389
+ return;
390
+ }
391
+ const changedOrder = changedOrders.find(
392
+ (order) => this.isCurrentSalesOrderRecord(order)
393
+ );
394
+ if (!changedOrder)
395
+ return;
396
+ if (this.serverOrderChangeHydrateInFlight) {
397
+ this.queueLatestServerOrderChange(changedOrder);
398
+ return;
399
+ }
400
+ if (!this.store.order)
401
+ return;
402
+ this.serverOrderChangeHydrateInFlight = (async () => {
403
+ var _a, _b;
404
+ const currentTempOrder = (_b = (_a = this.store.order).getTempOrder) == null ? void 0 : _b.call(_a);
405
+ const record = mergeSalesDetailRecordWithTempOrder(
406
+ currentTempOrder,
407
+ changedOrder,
408
+ "authoritative-incoming"
409
+ );
410
+ const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
411
+ recalcOnHydrate: false
412
+ });
413
+ this.currentSalesDetail = sales;
414
+ await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
415
+ })();
416
+ try {
417
+ await this.serverOrderChangeHydrateInFlight;
418
+ } finally {
419
+ this.serverOrderChangeHydrateInFlight = null;
420
+ await this.drainQueuedServerOrderChanges();
421
+ }
422
+ }
423
+ registerServerOrderChangeSync() {
424
+ var _a, _b;
425
+ (_a = this.serverOrderChangeUnsubscribe) == null ? void 0 : _a.call(this);
426
+ const effects = (_b = this.core) == null ? void 0 : _b.effects;
427
+ if (!effects || typeof effects.on !== "function")
428
+ return;
429
+ this.serverOrderChangeUnsubscribe = effects.on(SERVER_ORDER_CHANGED_EVENT, (payload) => {
430
+ return this.syncCurrentSalesDetailFromServerOrderChange(payload).catch((error) => {
431
+ this.logError("sync sales detail from server order change failed", {
432
+ error: error instanceof Error ? error.message : String(error)
433
+ });
434
+ });
435
+ });
436
+ }
437
+ async hydrateLatestLoadedSalesDetail(record, loadSequence) {
438
+ let hydratedSales = null;
439
+ let skippedBeforeHydrate = false;
440
+ const hydrateTask = async () => {
441
+ if (loadSequence !== this.salesDetailLoadSequence) {
442
+ skippedBeforeHydrate = true;
443
+ return;
444
+ }
445
+ if (!this.store.order)
446
+ throw new Error("order 模块未初始化");
447
+ const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
448
+ recalcOnHydrate: false
449
+ });
450
+ hydratedSales = sales;
451
+ if (loadSequence !== this.salesDetailLoadSequence)
452
+ return;
453
+ this.currentSalesDetail = sales;
454
+ await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
455
+ };
456
+ const queuedTask = this.salesDetailHydrateQueue.then(hydrateTask, hydrateTask);
457
+ this.salesDetailHydrateQueue = queuedTask.then(
458
+ () => void 0,
459
+ () => void 0
460
+ );
461
+ await queuedTask;
462
+ if (skippedBeforeHydrate)
463
+ return record;
464
+ return hydratedSales || this.currentSalesDetail || record;
465
+ }
466
+ hydrateOrderPaymentNames(payments) {
467
+ if (!payments.length)
468
+ return [];
469
+ if (!this.paymentMethodsCache.length) {
470
+ return payments.map((payment) => ({ ...payment }));
471
+ }
472
+ const paymentMethodById = /* @__PURE__ */ new Map();
473
+ const paymentMethodByCode = /* @__PURE__ */ new Map();
474
+ this.paymentMethodsCache.forEach((method) => {
475
+ if ((method == null ? void 0 : method.id) !== void 0 && (method == null ? void 0 : method.id) !== null) {
476
+ paymentMethodById.set(String(method.id), method);
477
+ }
478
+ if (method == null ? void 0 : method.code) {
479
+ paymentMethodByCode.set(String(method.code), method);
480
+ }
481
+ });
482
+ return payments.map((payment) => {
483
+ const nextPayment = { ...payment };
484
+ if (nextPayment.name)
485
+ return nextPayment;
486
+ const paymentMethod = paymentMethodById.get(String(nextPayment.custom_payment_id)) || paymentMethodByCode.get(String(nextPayment.code));
487
+ if (!(paymentMethod == null ? void 0 : paymentMethod.name))
488
+ return nextPayment;
489
+ return {
490
+ ...nextPayment,
491
+ name: paymentMethod.name
492
+ };
493
+ });
494
+ }
495
+ get payment() {
496
+ return this.store.payment;
497
+ }
498
+ getCurrentOrderCustomerId() {
499
+ var _a, _b;
500
+ const tempOrder = (_b = (_a = this.store.order) == null ? void 0 : _a.getTempOrder) == null ? void 0 : _b.call(_a);
501
+ const customerId = tempOrder == null ? void 0 : tempOrder.customer_id;
502
+ if (customerId === null || customerId === void 0)
503
+ return void 0;
504
+ return customerId;
505
+ }
506
+ normalizePriceContextCustomerId(customerId) {
507
+ if (customerId === void 0 || customerId === null || customerId === "")
508
+ return null;
509
+ return String(customerId);
510
+ }
511
+ applyQuotationScheduleResolver(quotation) {
512
+ const scheduleModule = this.store.schedule;
513
+ if (!scheduleModule)
514
+ return;
515
+ const scheduleById = /* @__PURE__ */ new Map();
516
+ const scheduleList = typeof scheduleModule.getScheduleList === "function" ? scheduleModule.getScheduleList() : [];
517
+ if (Array.isArray(scheduleList)) {
518
+ scheduleList.forEach((schedule) => {
519
+ if ((schedule == null ? void 0 : schedule.id) !== void 0 && (schedule == null ? void 0 : schedule.id) !== null) {
520
+ scheduleById.set(String(schedule.id), schedule);
521
+ }
522
+ });
523
+ }
524
+ quotation.setScheduleResolver((id) => {
525
+ var _a, _b;
526
+ const scheduleId = String(id);
527
+ if (scheduleById.has(scheduleId))
528
+ return scheduleById.get(scheduleId);
529
+ const schedules = ((_a = scheduleModule.getScheduleListByIds) == null ? void 0 : _a.call(scheduleModule, [id])) || ((_b = scheduleModule.getScheduleByIds) == null ? void 0 : _b.call(scheduleModule, [id])) || [];
530
+ if (schedules[0])
531
+ scheduleById.set(scheduleId, schedules[0]);
532
+ return schedules[0];
533
+ });
534
+ }
535
+ async loadQuotationForPriceQuery(params) {
536
+ var _a;
537
+ if (!params.quotation)
538
+ return;
539
+ this.applyQuotationScheduleResolver(params.quotation);
540
+ await params.quotation.loadQuotations({
541
+ channel: params.channel || ((_a = this.otherParams) == null ? void 0 : _a.channel),
542
+ customer_id: params.customer_id
543
+ });
544
+ }
545
+ getPriceQueryProductId(product) {
546
+ const productId = Number((product == null ? void 0 : product.product_id) ?? (product == null ? void 0 : product.id));
547
+ if (!Number.isFinite(productId))
548
+ return null;
549
+ return productId;
550
+ }
551
+ getPriceQuerySchedule(params) {
552
+ const booking = params.booking || {};
553
+ if (typeof booking.start_date === "string" && booking.start_date.trim()) {
554
+ const scheduleDate = booking.start_date.trim();
555
+ const startTime = typeof booking.start_time === "string" && booking.start_time.trim() ? booking.start_time.trim() : "00:00:00";
556
+ const datetime = (0, import_dayjs.default)(`${scheduleDate} ${startTime}`);
557
+ return {
558
+ schedule_date: scheduleDate,
559
+ schedule_datetime: datetime.isValid() ? datetime.format("YYYY-MM-DD HH:mm:ss") : `${scheduleDate} ${startTime}`
560
+ };
561
+ }
562
+ if (typeof params.datetime === "string" && params.datetime.trim()) {
563
+ const datetime = (0, import_dayjs.default)(params.datetime.trim());
564
+ if (datetime.isValid()) {
565
+ return {
566
+ schedule_date: datetime.format("YYYY-MM-DD"),
567
+ schedule_datetime: datetime.format("YYYY-MM-DD HH:mm:ss")
568
+ };
569
+ }
570
+ }
571
+ const now = (0, import_dayjs.default)();
572
+ return {
573
+ schedule_date: now.format("YYYY-MM-DD"),
574
+ schedule_datetime: now.format("YYYY-MM-DD HH:mm:ss")
575
+ };
576
+ }
577
+ async loadProductsForPriceQuery(params) {
578
+ var _a, _b;
579
+ const ids = Array.from(new Set(
580
+ params.ids.filter((id) => Number.isFinite(id))
581
+ ));
582
+ const productsById = /* @__PURE__ */ new Map();
583
+ if (!ids.length || !this.request)
584
+ return productsById;
585
+ try {
586
+ const response = await this.request.post("/product/query", {
587
+ ids,
588
+ open_quotation: 1,
589
+ open_bundle: 1,
590
+ status: "published",
591
+ num: 1,
592
+ skip: 1,
593
+ customer_id: params.customerId,
594
+ schedule_date: params.schedule.schedule_date,
595
+ schedule_datetime: params.schedule.schedule_datetime,
596
+ application_code: params.channel || ((_a = this.otherParams) == null ? void 0 : _a.channel)
597
+ }, {
598
+ osServer: true,
599
+ customToast: () => {
600
+ }
601
+ });
602
+ const list = ((_b = response == null ? void 0 : response.data) == null ? void 0 : _b.list) || (response == null ? void 0 : response.list) || [];
603
+ if (!Array.isArray(list))
604
+ return productsById;
605
+ list.forEach((item) => {
606
+ const productId = Number((item == null ? void 0 : item.id) ?? (item == null ? void 0 : item.product_id));
607
+ if (Number.isFinite(productId))
608
+ productsById.set(productId, item);
609
+ });
610
+ return productsById;
611
+ } catch (error) {
612
+ this.logWarning("loadProductsForPriceQuery: 商品批量重查失败,使用入参 fallback", {
613
+ ids,
614
+ error: error instanceof Error ? error.message : String(error)
615
+ });
616
+ return productsById;
617
+ }
618
+ }
619
+ async loadProductForPriceQuery(params, customerId) {
620
+ const product = params.product || {};
621
+ const productId = this.getPriceQueryProductId(product);
622
+ if (productId === null || !this.request)
623
+ return null;
624
+ const schedule = this.getPriceQuerySchedule(params);
625
+ const productsById = await this.loadProductsForPriceQuery({
626
+ ids: [productId],
627
+ schedule,
628
+ customerId,
629
+ channel: params.channel
630
+ });
631
+ return productsById.get(productId) || null;
632
+ }
633
+ getAuthoritativeBundleItems(product) {
634
+ if (Array.isArray(product == null ? void 0 : product.product_bundle))
635
+ return product.product_bundle;
636
+ const groups = Array.isArray(product == null ? void 0 : product.bundle_group) ? product.bundle_group : Array.isArray(product == null ? void 0 : product.bundleGroup) ? product.bundleGroup : [];
637
+ return groups.flatMap((group) => {
638
+ const items = Array.isArray(group == null ? void 0 : group.bundle_item) ? group.bundle_item : Array.isArray(group == null ? void 0 : group.bundleItem) ? group.bundleItem : [];
639
+ return items.map((item) => ({
640
+ ...item,
641
+ group_id: (item == null ? void 0 : item.group_id) ?? (group == null ? void 0 : group.id),
642
+ bundle_group_id: (item == null ? void 0 : item.bundle_group_id) ?? (item == null ? void 0 : item.group_id) ?? (group == null ? void 0 : group.id)
643
+ }));
644
+ });
645
+ }
646
+ findAuthoritativeBundleItem(bundle, candidates) {
647
+ const bundleId = bundle.bundle_id ?? bundle.id;
648
+ if (bundleId != null) {
649
+ const matchedById = candidates.find((item) => String((item == null ? void 0 : item.bundle_id) ?? (item == null ? void 0 : item.id)) === String(bundleId));
650
+ if (matchedById)
651
+ return matchedById;
652
+ }
653
+ const productId = bundle.bundle_product_id ?? bundle._bundle_product_id;
654
+ const groupId = bundle.bundle_group_id ?? bundle.group_id;
655
+ return candidates.find((item) => {
656
+ const itemProductId = (item == null ? void 0 : item.bundle_product_id) ?? (item == null ? void 0 : item._bundle_product_id);
657
+ const itemGroupId = (item == null ? void 0 : item.bundle_group_id) ?? (item == null ? void 0 : item.group_id);
658
+ if (productId == null || String(itemProductId) !== String(productId))
659
+ return false;
660
+ if (groupId == null)
661
+ return true;
662
+ return String(itemGroupId) === String(groupId);
663
+ }) || null;
664
+ }
665
+ getAuthoritativeBundleUnitPrice(bundle) {
666
+ return bundle.price ?? bundle.bundle_selling_price ?? bundle.custom_price ?? bundle.product_price ?? bundle.base_price;
667
+ }
668
+ mergeProductForPriceQuery(product, authoritativeProduct) {
669
+ if (!authoritativeProduct)
670
+ return product;
671
+ const selectedBundles = Array.isArray(product.product_bundle) ? product.product_bundle : [];
672
+ const authoritativeBundles = this.getAuthoritativeBundleItems(authoritativeProduct);
673
+ const productBundle = selectedBundles.map((bundle) => {
674
+ const authoritativeBundle = this.findAuthoritativeBundleItem(bundle, authoritativeBundles);
675
+ const unitPrice = authoritativeBundle ? this.getAuthoritativeBundleUnitPrice(authoritativeBundle) : void 0;
676
+ if (unitPrice === void 0 || unitPrice === null || unitPrice === "")
677
+ return bundle;
678
+ return {
679
+ ...bundle,
680
+ price: unitPrice,
681
+ bundle_selling_price: unitPrice,
682
+ base_price: (authoritativeBundle == null ? void 0 : authoritativeBundle.base_price) ?? bundle.base_price,
683
+ product_price: (authoritativeBundle == null ? void 0 : authoritativeBundle.product_price) ?? bundle.product_price
684
+ };
685
+ });
686
+ return {
687
+ ...product,
688
+ ...authoritativeProduct,
689
+ id: product.id ?? authoritativeProduct.id,
690
+ product_id: product.product_id ?? authoritativeProduct.product_id ?? authoritativeProduct.id,
691
+ product_variant_id: product.product_variant_id ?? authoritativeProduct.product_variant_id ?? 0,
692
+ num: product.num ?? product.quantity ?? authoritativeProduct.num,
693
+ quantity: product.quantity ?? product.num ?? authoritativeProduct.quantity,
694
+ product_sku: (() => {
695
+ const authoritativeSku = (0, import_utils.ensureProductSku)(authoritativeProduct);
696
+ const productSku = (0, import_utils.ensureProductSku)(product);
697
+ const hasProductSku = product.product_sku && typeof product.product_sku === "object";
698
+ return {
699
+ ...authoritativeSku,
700
+ ...productSku,
701
+ option: hasProductSku ? productSku.option : authoritativeSku.option
702
+ };
703
+ })(),
704
+ product_bundle: productBundle,
705
+ metadata: product.metadata ?? authoritativeProduct.metadata
706
+ };
707
+ }
708
+ getSubmitOrderSalesChannel() {
709
+ var _a;
710
+ return (_a = this.otherParams) == null ? void 0 : _a.channel;
711
+ }
712
+ /**
713
+ * 工厂入口:根据子模块名实例化对应模块。
714
+ * 默认使用 BookingByStep 公共 `createModule`。子类若需引入额外类型(如 customer),
715
+ * 可覆盖此方法并把未识别的 name 委托给 `super.createSubModule(name)`。
716
+ */
717
+ createSubModule(moduleName) {
718
+ if (moduleName === "quotation") {
719
+ return new import_Quotation.QuotationModule(`${this.name}_quotation`);
720
+ }
721
+ return (0, import_types2.createModule)(moduleName, this.name);
722
+ }
723
+ getSubModuleHooks(moduleName) {
724
+ var _a, _b;
725
+ const optionHooks = this.initializeOptions.hooks || {};
726
+ const otherHooks = this.otherParams.hooks || {};
727
+ if (moduleName === "order") {
728
+ const directOrderHooks = optionHooks;
729
+ return optionHooks.order || ((_a = this.otherParams.order) == null ? void 0 : _a.hooks) || otherHooks.order || (directOrderHooks.onBeforeMergeProductToOrder ? directOrderHooks : void 0);
730
+ }
731
+ return optionHooks[moduleName] || ((_b = this.otherParams[moduleName]) == null ? void 0 : _b.hooks) || otherHooks[moduleName];
732
+ }
733
+ /**
734
+ * 构造传给 BaseSales 子模块的完整运行态参数,保证初始化和后续同步语义一致。
735
+ *
736
+ * @example
737
+ * const params = this.buildSubModuleOtherParams();
738
+ * this.core.registerModule(orderModule, { otherParams: params });
739
+ */
740
+ buildSubModuleOtherParams() {
741
+ return {
742
+ ...this.otherParams,
743
+ salesSummaryModuleName: `${this.name}_salesSummary`,
744
+ fatherModule: this.name,
745
+ openCache: this.cacheId ? true : false,
746
+ cacheId: this.cacheId
747
+ };
748
+ }
749
+ /**
750
+ * 将父级 otherParams 的变更显式同步给已注册的子模块。
751
+ *
752
+ * @example
753
+ * await this.syncOtherParamsToSubModules({ channel: 'pos' });
754
+ */
755
+ async syncOtherParamsToSubModules(changedParams, { cover = false } = {}) {
756
+ const nextSubModuleOtherParams = this.buildSubModuleOtherParams();
757
+ await Promise.all(
758
+ Object.entries(this.store).map(async ([moduleName, subModule]) => {
759
+ if (this.reusedSharedSubModuleNames.has(moduleName)) {
760
+ return;
761
+ }
762
+ const targetModule = subModule;
763
+ if (!targetModule || typeof targetModule.updateOtherParams !== "function") {
764
+ return;
765
+ }
766
+ await targetModule.updateOtherParams(nextSubModuleOtherParams, {
767
+ changedParams,
768
+ cover
769
+ });
770
+ })
771
+ );
772
+ }
773
+ /**
774
+ * 读取 sessionStorage[this.name][cacheId],作为子模块 initialState 的来源。
775
+ * sessionStorage 损坏时静默忽略,按空状态注册。
776
+ */
777
+ readSessionCacheData() {
778
+ if (!this.cacheId || !this.window)
779
+ return {};
780
+ try {
781
+ const sessionData = this.window.sessionStorage.getItem(this.name);
782
+ if (!sessionData)
783
+ return {};
784
+ const data = JSON.parse(sessionData);
785
+ return data && data[this.cacheId] || {};
786
+ } catch {
787
+ return {};
788
+ }
789
+ }
790
+ getAppData(key) {
791
+ var _a, _b, _c, _d, _e, _f;
792
+ const getData = (_b = (_a = this.appPlugin).getData) == null ? void 0 : _b.call(_a);
793
+ if (typeof getData === "function")
794
+ return getData(key);
795
+ const app = this.appPlugin.getApp();
796
+ const coreData = (_f = (_d = (_c = app == null ? void 0 : app.models) == null ? void 0 : _c.getStore) == null ? void 0 : (_e = _d.call(_c)).getDataByModel) == null ? void 0 : _f.call(_e, "core", "core");
797
+ return coreData == null ? void 0 : coreData[key];
798
+ }
799
+ syncAppDataToTempOrder(tempOrder) {
800
+ const isPriceIncludeTax = this.getAppData("is_price_include_tax");
801
+ const taxCountryCode = this.getAppData("tax_country_code");
802
+ const currencyCode = this.getAppData("shop_currency_code");
803
+ const currencySymbol = this.getAppData("shop_symbol");
804
+ let isChanged = false;
805
+ if (isPriceIncludeTax !== void 0) {
806
+ const nextIsPriceIncludeTax = Number(isPriceIncludeTax);
807
+ if ((nextIsPriceIncludeTax === 0 || nextIsPriceIncludeTax === 1) && tempOrder.is_price_include_tax !== nextIsPriceIncludeTax) {
808
+ tempOrder.is_price_include_tax = nextIsPriceIncludeTax;
809
+ isChanged = true;
810
+ }
811
+ }
812
+ if (taxCountryCode !== void 0) {
813
+ const nextTaxCountryCode = String(taxCountryCode || "");
814
+ if (tempOrder.tax_country_code !== nextTaxCountryCode) {
815
+ tempOrder.tax_country_code = nextTaxCountryCode;
816
+ isChanged = true;
817
+ }
818
+ }
819
+ if (currencyCode !== void 0) {
820
+ const nextCurrencyCode = String(currencyCode || "");
821
+ if (tempOrder.currency_code !== nextCurrencyCode) {
822
+ tempOrder.currency_code = nextCurrencyCode;
823
+ isChanged = true;
824
+ }
825
+ }
826
+ if (currencySymbol !== void 0) {
827
+ const nextCurrencySymbol = String(currencySymbol || "");
828
+ if (tempOrder.currency_symbol !== nextCurrencySymbol) {
829
+ tempOrder.currency_symbol = nextCurrencySymbol;
830
+ isChanged = true;
831
+ }
832
+ }
833
+ return isChanged;
834
+ }
835
+ async initialize(core, options = {}) {
836
+ var _a, _b, _c, _d;
837
+ this.core = core;
838
+ this.initializeOptions = options || {};
839
+ this.otherParams = options.otherParams || {};
840
+ this.cacheId = (_a = this.otherParams) == null ? void 0 : _a.cacheId;
841
+ this.reusedSharedSubModuleNames.clear();
842
+ this.window = core.getPlugin("window");
843
+ this.request = core.getPlugin("request");
844
+ this.appPlugin = core.getPlugin("app");
845
+ if (!this.appPlugin) {
846
+ }
847
+ const app = (_c = (_b = this.appPlugin) == null ? void 0 : _b.getApp) == null ? void 0 : _c.call(_b);
848
+ this.logger = app == null ? void 0 : app.logger;
849
+ const targetCacheData = this.readSessionCacheData();
850
+ const moduleNames = this.getRegisteredModuleNames();
851
+ moduleNames.forEach((step) => {
852
+ const reusedModule = this.getReusableSharedSubModule(step);
853
+ if (reusedModule) {
854
+ this.store[step] = reusedModule;
855
+ this.reusedSharedSubModuleNames.add(step);
856
+ return;
857
+ }
858
+ const targetModule = this.createSubModule(step);
859
+ if (!targetModule) {
860
+ throw new Error(`模块 ${step} 不存在`);
861
+ }
862
+ const hooks = this.getSubModuleHooks(step);
863
+ this.store[step] = targetModule;
864
+ this.core.registerModule(targetModule, {
865
+ initialState: (targetCacheData == null ? void 0 : targetCacheData[targetModule.name]) || {},
866
+ ...hooks ? { hooks } : {},
867
+ otherParams: this.buildSubModuleOtherParams()
868
+ });
869
+ });
870
+ if (this.store.schedule && !this.isScheduleListLoaded(this.store.schedule)) {
871
+ await this.store.schedule.loadAllSchedule();
872
+ }
873
+ if (this.store.order && typeof ((_d = this.otherParams) == null ? void 0 : _d.enableTempOrderPersist) === "boolean") {
874
+ this.store.order.setEnableTempOrderPersist(
875
+ this.otherParams.enableTempOrderPersist
876
+ );
877
+ }
878
+ await this.getPaymentMethodsAsync();
879
+ this.registerServerOrderChangeSync();
880
+ this.core.effects.emit(`${this.name}:onInited`, {});
881
+ }
882
+ async destroy() {
883
+ var _a;
884
+ (_a = this.serverOrderChangeUnsubscribe) == null ? void 0 : _a.call(this);
885
+ this.serverOrderChangeUnsubscribe = null;
886
+ Object.keys(this.store).forEach((key) => {
887
+ if (this.reusedSharedSubModuleNames.has(key))
888
+ return;
889
+ const sub = this.store[key];
890
+ if (sub && typeof sub.destroy === "function") {
891
+ try {
892
+ sub.destroy();
893
+ } catch (error) {
894
+ console.warn(`[BaseSales] 子模块 ${key} 销毁失败`, error);
895
+ }
896
+ }
897
+ });
898
+ this.currentSalesDetail = null;
899
+ this.queuedServerOrderChanges = [];
900
+ this.salesDetailLoadSequence += 1;
901
+ await this.core.effects.emit(`${this.name}:onDestroy`, {});
902
+ super.destroy();
903
+ }
904
+ /**
905
+ * 加载销售订单到统一 tempOrder 工作区。
906
+ * 统一通过 OrderModule 的 sales detail lookup 加载订单详情。
907
+ *
908
+ * 子类可在 `super.loadSalesDetail` 之后基于返回的 `sales` 做业务侧装配
909
+ * (比如把 `sales.customer` 写入 CustomerModule、emit 业务 hook 等)。
910
+ */
911
+ async loadSalesDetail(orderIdOrParams) {
912
+ if (!this.store.order)
913
+ throw new Error("order 模块未初始化");
914
+ const loadSequence = ++this.salesDetailLoadSequence;
915
+ this.salesDetailLoadInFlightCount += 1;
916
+ try {
917
+ const params = typeof orderIdOrParams === "object" ? orderIdOrParams : { orderId: orderIdOrParams };
918
+ const externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
919
+ const preloadedSalesDetail = params.preloadedSalesDetail;
920
+ const lookup = params.orderId ?? externalSaleNumber ?? params.orderNumber ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.order_id) ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.external_sale_number) ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.order_number);
921
+ if (!preloadedSalesDetail && (lookup === void 0 || lookup === null || lookup === "")) {
922
+ throw new Error("加载销售详情需要 orderId、externalSaleNumber 或 orderNumber");
923
+ }
924
+ const loadedRecord = preloadedSalesDetail ?? await this.store.order.getSalesOrderByLookup({
925
+ lookup,
926
+ forceRemote: params.forceRemote
927
+ });
928
+ if (!preloadedSalesDetail && (!loadedRecord || loadedRecord.code !== 200)) {
929
+ const message = loadedRecord && (loadedRecord.message || loadedRecord.msg) || `加载销售详情失败: ${lookup}`;
930
+ throw new Error(message);
931
+ }
932
+ const remoteRecord = preloadedSalesDetail ?? loadedRecord.data;
933
+ const currentTempOrder = params.merge ? this.store.order.getTempOrder() : null;
934
+ const record = params.merge ? mergeSalesDetailRecordWithTempOrder(
935
+ currentTempOrder,
936
+ remoteRecord,
937
+ "preserve-local"
938
+ ) : remoteRecord;
939
+ return await this.hydrateLatestLoadedSalesDetail(record, loadSequence);
940
+ } finally {
941
+ this.salesDetailLoadInFlightCount = Math.max(
942
+ 0,
943
+ this.salesDetailLoadInFlightCount - 1
944
+ );
945
+ if (this.salesDetailLoadInFlightCount === 0) {
946
+ try {
947
+ await this.drainQueuedServerOrderChanges();
948
+ } catch (error) {
949
+ this.logError("drain queued server order changes failed", {
950
+ error: error instanceof Error ? error.message : String(error)
951
+ });
952
+ }
953
+ }
954
+ }
955
+ }
956
+ /** 获取当前已加载的销售详情(只读快照)。未加载过则返回 null。 */
957
+ getSalesOrder() {
958
+ return this.currentSalesDetail;
959
+ }
960
+ /** 获取销售详情顶部业务字段(订单号/状态/金额等通用字段集合)。 */
961
+ getOrderHeader() {
962
+ if (!this.currentSalesDetail)
963
+ return null;
964
+ return this.currentSalesDetail.header || this.currentSalesDetail;
965
+ }
966
+ /** 获取所有 booking(含 root + children),按服务端原始顺序输出。 */
967
+ getBookings() {
968
+ var _a;
969
+ return ((_a = this.currentSalesDetail) == null ? void 0 : _a.bookings) || [];
970
+ }
971
+ /** 获取根 booking(is_next === 0 / is_root === 1),多个时取第一个。 */
972
+ getRootBooking() {
973
+ if (!this.currentSalesDetail)
974
+ return null;
975
+ if (this.currentSalesDetail.rootBooking)
976
+ return this.currentSalesDetail.rootBooking;
977
+ const bookings = this.currentSalesDetail.bookings || [];
978
+ return bookings.find((booking) => {
979
+ const parentId = booking == null ? void 0 : booking.parent_id;
980
+ return parentId === 0 || parentId === null || parentId === void 0;
981
+ }) || null;
982
+ }
983
+ /** 按 product_uid 反查 booking 列表(用于商品行 ↔ booking 映射)。 */
984
+ getChildBookingsByProductUid(productUid) {
985
+ var _a;
986
+ if (!this.currentSalesDetail || !productUid)
987
+ return [];
988
+ const indexed = (_a = this.currentSalesDetail.bookingsByProductUid) == null ? void 0 : _a[productUid];
989
+ if (indexed)
990
+ return indexed;
991
+ return (this.currentSalesDetail.bookings || []).filter((booking) => {
992
+ var _a2;
993
+ const uid = (booking == null ? void 0 : booking.product_uid) || ((_a2 = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a2.product_uid);
994
+ return String(uid || "") === String(productUid);
995
+ });
996
+ }
997
+ /** 获取支付列表(已支付/退款等明细)。 */
998
+ getPayments() {
999
+ var _a;
1000
+ return ((_a = this.currentSalesDetail) == null ? void 0 : _a.payments) || [];
1001
+ }
1002
+ /** 获取附加费用(运费/服务费/税费等)。 */
1003
+ getSurcharges() {
1004
+ var _a;
1005
+ return ((_a = this.currentSalesDetail) == null ? void 0 : _a.surcharges) || [];
1006
+ }
1007
+ getTempOrder() {
1008
+ var _a;
1009
+ const result = ((_a = this.store.order) == null ? void 0 : _a.getTempOrder()) || null;
1010
+ return result;
1011
+ }
1012
+ async replaceTempOrder(tempOrder) {
1013
+ if (!this.store.order)
1014
+ throw new Error("order 模块未初始化");
1015
+ const nextTempOrder = await this.store.order.replaceTempOrder(tempOrder);
1016
+ await this.effectsEmit("onTempOrderReplaced", { tempOrder: nextTempOrder });
1017
+ return nextTempOrder;
1018
+ }
1019
+ getOrderIdentity() {
1020
+ if (!this.store.order)
1021
+ return null;
1022
+ return this.store.order.getOrderIdentity();
1023
+ }
1024
+ getOrderSnapshot() {
1025
+ if (!this.store.order)
1026
+ return null;
1027
+ return this.store.order.getOrderSnapshot();
1028
+ }
1029
+ getOrderSyncState() {
1030
+ if (!this.store.order)
1031
+ return "local";
1032
+ return this.store.order.getOrderSyncState();
1033
+ }
1034
+ getOrderAmountSnapshot() {
1035
+ if (!this.store.order)
1036
+ return null;
1037
+ return this.store.order.getOrderAmountSnapshot();
1038
+ }
1039
+ getTempOrderNote() {
1040
+ if (!this.store.order)
1041
+ return "";
1042
+ return this.store.order.getTempOrderNote();
1043
+ }
1044
+ updateTempOrderNote(note, sync = false) {
1045
+ try {
1046
+ if (!this.store.order)
1047
+ throw new Error("order 模块未初始化");
1048
+ const result = this.store.order.updateTempOrderNote(note, sync);
1049
+ return result;
1050
+ } catch (error) {
1051
+ throw error;
1052
+ }
1053
+ }
1054
+ updateRemoteOrderNote(orderId, note) {
1055
+ if (!this.store.order)
1056
+ throw new Error("order 模块未初始化");
1057
+ this.store.order.syncTempOrderNoteToRemote(orderId, note);
1058
+ }
1059
+ updateTempOrderShopDiscount(amount) {
1060
+ if (!this.store.order)
1061
+ throw new Error("order 模块未初始化");
1062
+ return this.store.order.updateTempOrderShopDiscount(amount);
1063
+ }
1064
+ updateTempOrderDepositAmount(amount) {
1065
+ if (!this.store.order)
1066
+ throw new Error("order 模块未初始化");
1067
+ return this.store.order.updateTempOrderDepositAmount(amount);
1068
+ }
1069
+ updateTempOrderContactsInfo(contactsInfo) {
1070
+ if (!this.store.order)
1071
+ throw new Error("order 模块未初始化");
1072
+ return this.store.order.updateTempOrderContactsInfo(contactsInfo);
1073
+ }
1074
+ /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
1075
+ setEnableTempOrderPersist(enabled) {
1076
+ if (!this.store.order)
1077
+ throw new Error("order 模块未初始化");
1078
+ this.store.order.setEnableTempOrderPersist(enabled);
1079
+ }
1080
+ /** 是否允许 saveDraft 写入 IndexedDB 草稿。 */
1081
+ isTempOrderPersistEnabled() {
1082
+ if (!this.store.order)
1083
+ return false;
1084
+ return this.store.order.isTempOrderPersistEnabled();
1085
+ }
1086
+ ensureTempOrder() {
1087
+ if (!this.store.order)
1088
+ throw new Error("order 模块未初始化");
1089
+ return this.store.order.ensureTempOrder();
1090
+ }
1091
+ // 主动创建临时订单;若已存在则直接返回已有订单
1092
+ async addNewOrder() {
1093
+ try {
1094
+ if (!this.store.order)
1095
+ throw new Error("order 模块未初始化");
1096
+ const tempOrder = await this.store.order.addNewOrder();
1097
+ if (this.syncAppDataToTempOrder(tempOrder) && this.isTempOrderPersistEnabled()) {
1098
+ this.store.order.persistTempOrder();
1099
+ await this.store.order.saveDraft();
1100
+ }
1101
+ return tempOrder;
1102
+ } catch (error) {
1103
+ throw error;
1104
+ }
1105
+ }
1106
+ async saveDraft() {
1107
+ if (!this.store.order)
1108
+ throw new Error("order 模块未初始化");
1109
+ return this.store.order.saveDraft();
1110
+ }
1111
+ // 重置 tempOrder 与与上一单强相关的运行态(resource/entryPaxNumber/enabledReservationRuleProducts),
1112
+ // 适用于从支付页通过 react-router 跳回继续下单时清理残留数据
1113
+ async restoreOrder() {
1114
+ try {
1115
+ if (!this.store.order) {
1116
+ throw new Error("scanOrder 解决方案需要 order 模块支持");
1117
+ }
1118
+ const tempOrder = this.store.order.restoreOrder();
1119
+ this.currentSalesDetail = null;
1120
+ this.discountConfigCacheKey = null;
1121
+ this.hasManualDiscountSelection = false;
1122
+ await this.effectsEmit("onTempOrderReplaced", { tempOrder });
1123
+ if (this.syncAppDataToTempOrder(tempOrder) && this.isTempOrderPersistEnabled()) {
1124
+ this.store.order.persistTempOrder();
1125
+ await this.store.order.saveDraft();
1126
+ }
1127
+ return tempOrder;
1128
+ } catch (error) {
1129
+ throw error;
1130
+ }
1131
+ }
1132
+ /**
1133
+ * 仅清空 tempOrder 购物车行(products / bookings / discount_list)。
1134
+ * 同步清空内存中的 salesDetail 商品/预约视图,避免编辑态仍读到旧 bookings。
1135
+ */
1136
+ async clearOrderCartLines() {
1137
+ try {
1138
+ if (!this.store.order)
1139
+ throw new Error("order 模块未初始化");
1140
+ const tempOrder = await this.store.order.clearOrderCartLines();
1141
+ if (this.currentSalesDetail) {
1142
+ this.currentSalesDetail = {
1143
+ ...this.currentSalesDetail,
1144
+ products: [],
1145
+ bookings: [],
1146
+ rootBooking: null,
1147
+ bookingsByProductUid: {},
1148
+ discount_list: []
1149
+ };
1150
+ }
1151
+ await this.effectsEmit("onTempOrderReplaced", { tempOrder });
1152
+ if (this.syncAppDataToTempOrder(tempOrder) && this.isTempOrderPersistEnabled()) {
1153
+ this.store.order.persistTempOrder();
1154
+ await this.store.order.saveDraft();
1155
+ }
1156
+ return tempOrder;
1157
+ } catch (error) {
1158
+ throw error;
1159
+ }
1160
+ }
1161
+ getOrderProducts() {
1162
+ if (!this.store.order)
1163
+ throw new Error("order 模块未初始化");
1164
+ const products = this.store.order.getOrderProducts();
1165
+ return products;
1166
+ }
1167
+ async getSummary() {
1168
+ try {
1169
+ if (!this.store.order)
1170
+ throw new Error("order 模块未初始化");
1171
+ const summary = await this.store.order.getOrderSummary();
1172
+ return summary;
1173
+ } catch (error) {
1174
+ throw error;
1175
+ }
1176
+ }
1177
+ getHistoricalProductDiscountList(products) {
1178
+ const historyDiscountList = [];
1179
+ products.forEach((item) => {
1180
+ if (!this.isPersistedOrderProduct(item))
1181
+ return;
1182
+ (item.discount_list || []).forEach((discount) => {
1183
+ var _a, _b, _c, _d, _e, _f;
1184
+ const discountId = ((_a = discount.discount) == null ? void 0 : _a.resource_id) || discount.id;
1185
+ if (!discountId || !["good_pass", "discount_card"].includes(discount.type))
1186
+ return;
1187
+ const quantity = item.quantity || item.num || item.product_quantity || 1;
1188
+ const savedAmount = new import_decimal.default(discount.amount || 0).times(quantity).plus(((_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.product_discount_difference) || 0);
1189
+ const index = historyDiscountList.findIndex((n) => n.id === discountId);
1190
+ if (index !== -1) {
1191
+ historyDiscountList[index] = {
1192
+ ...historyDiscountList[index],
1193
+ amount: new import_decimal.default(historyDiscountList[index].amount || 0).plus(discount.amount || 0).toNumber(),
1194
+ savedAmount: savedAmount.plus(historyDiscountList[index].savedAmount || 0).toNumber()
1195
+ };
1196
+ return;
1197
+ }
1198
+ historyDiscountList.push({
1199
+ ...discount,
1200
+ id: discountId,
1201
+ tag: discount.tag || discount.type,
1202
+ name: discount.name || ((_d = (_c = discount.discount) == null ? void 0 : _c.title) == null ? void 0 : _d.auto),
1203
+ format_title: ((_e = discount.discount) == null ? void 0 : _e.title) || discount.format_title,
1204
+ isEditMode: true,
1205
+ limited_relation_product_data: {},
1206
+ savedAmount: savedAmount.toNumber(),
1207
+ isAvailable: true,
1208
+ isDisabled: true,
1209
+ isSelected: true,
1210
+ product_id: ((_f = discount.discount) == null ? void 0 : _f.product_id) || discount.product_id
1211
+ });
1212
+ });
1213
+ });
1214
+ return historyDiscountList;
1215
+ }
1216
+ isPersistedOrderProduct(product) {
1217
+ const orderDetailId = product.order_detail_id ?? product.orderDetailId;
1218
+ if (orderDetailId !== void 0 && orderDetailId !== null && orderDetailId !== "") {
1219
+ return true;
1220
+ }
1221
+ const bookingId = product.booking_id ?? product.bookingId;
1222
+ return bookingId !== void 0 && bookingId !== null && bookingId !== "";
1223
+ }
1224
+ mergeHistoricalDiscountList(discountList, products) {
1225
+ const historyDiscountList = this.getHistoricalProductDiscountList(products);
1226
+ const historyIds = new Set(historyDiscountList.map((discount) => discount.id));
1227
+ return [
1228
+ ...historyDiscountList,
1229
+ ...(discountList || []).filter((discount) => {
1230
+ if (!historyIds.has(discount.id))
1231
+ return true;
1232
+ return !isBaseSalesHistoricalDiscountEntry(discount);
1233
+ })
1234
+ ];
1235
+ }
1236
+ shouldSkipAutoApplyFetchedDiscountsInEditMode(params) {
1237
+ if (params.discountAction !== "edit")
1238
+ return false;
1239
+ if (!params.products.length)
1240
+ return false;
1241
+ const hasDraftProduct = params.products.some((product) => !this.isPersistedOrderProduct(product));
1242
+ if (hasDraftProduct)
1243
+ return false;
1244
+ const hasSelectedDiscount = params.currentDiscountList.some(
1245
+ (discount) => discount.isSelected || discount.isEditMode || discount.isManualSelect
1246
+ );
1247
+ if (hasSelectedDiscount)
1248
+ return false;
1249
+ return !params.nextDiscountList.some(
1250
+ (discount) => discount.isSelected || discount.isEditMode || discount.isManualSelect
1251
+ );
1252
+ }
1253
+ mergeCurrentDiscountSelectionState(discountList, currentDiscountList) {
1254
+ if (!currentDiscountList.length)
1255
+ return discountList;
1256
+ const currentDiscountMap = /* @__PURE__ */ new Map();
1257
+ currentDiscountList.forEach((discount) => {
1258
+ currentDiscountMap.set(
1259
+ `${discount.id}:${isBaseSalesHistoricalDiscountEntry(discount) ? "historical" : "runtime"}`,
1260
+ discount
1261
+ );
1262
+ });
1263
+ return discountList.map((discount) => {
1264
+ const currentDiscount = currentDiscountMap.get(
1265
+ `${discount.id}:${isBaseSalesHistoricalDiscountEntry(discount) ? "historical" : "runtime"}`
1266
+ );
1267
+ if (!currentDiscount)
1268
+ return discount;
1269
+ if (currentDiscount.isManualSelect) {
1270
+ return {
1271
+ ...discount,
1272
+ isSelected: false,
1273
+ isManualSelect: true
1274
+ };
1275
+ }
1276
+ if (currentDiscount.isSelected) {
1277
+ return {
1278
+ ...discount,
1279
+ isSelected: true,
1280
+ isManualSelect: false
1281
+ };
1282
+ }
1283
+ return discount;
1284
+ });
1285
+ }
1286
+ async loadDiscountConfig(params) {
1287
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
1288
+ if (!this.store.order)
1289
+ throw new Error("order 模块未初始化");
1290
+ const tempOrder = this.store.order.ensureTempOrder();
1291
+ const orderStore = this.store.order.store || {};
1292
+ const discountModule = orderStore.discount;
1293
+ const rulesModule = orderStore.rules;
1294
+ const orderId = tempOrder.order_id || ((_b = (_a = this.getOrderIdentity) == null ? void 0 : _a.call(this)) == null ? void 0 : _b.orderId);
1295
+ const customerId = Number(
1296
+ (params == null ? void 0 : params.customerId) || tempOrder.customer_id || ((_c = tempOrder.customer) == null ? void 0 : _c.id) || ((_e = (_d = tempOrder._extend) == null ? void 0 : _d.customerSnapshot) == null ? void 0 : _e.id) || ((_g = (_f = tempOrder._extend) == null ? void 0 : _f.customerSnapshot) == null ? void 0 : _g.customer_id) || 0
1297
+ );
1298
+ const currentDiscountList = ((_h = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _h.call(discountModule)) || [];
1299
+ const originalDiscountList = ((_i = discountModule == null ? void 0 : discountModule.getOriginalDiscountList) == null ? void 0 : _i.call(discountModule)) || [];
1300
+ const hasManualDiscountSelection = this.hasManualDiscountSelection || currentDiscountList.some((discount) => discount.isManualSelect);
1301
+ const discountAction = (params == null ? void 0 : params.action) || (orderId ? "edit" : "create");
1302
+ const discountConfigCacheKey = [
1303
+ customerId,
1304
+ discountAction,
1305
+ Number(orderId) || 0
1306
+ ].join(":");
1307
+ let preparedDiscountList = [];
1308
+ if (customerId && customerId !== 1) {
1309
+ if (this.discountConfigCacheKey === discountConfigCacheKey) {
1310
+ preparedDiscountList = originalDiscountList;
1311
+ } else {
1312
+ preparedDiscountList = await this.store.order.loadDiscountConfig({
1313
+ customerId,
1314
+ action: discountAction,
1315
+ orderId: Number(orderId) || void 0,
1316
+ apply: false
1317
+ });
1318
+ this.discountConfigCacheKey = discountConfigCacheKey;
1319
+ await ((_j = discountModule == null ? void 0 : discountModule.setOriginalDiscountList) == null ? void 0 : _j.call(discountModule, preparedDiscountList));
1320
+ }
1321
+ }
1322
+ if (hasManualDiscountSelection && currentDiscountList.length) {
1323
+ return {
1324
+ productList: tempOrder.products || [],
1325
+ discountList: currentDiscountList,
1326
+ availableWalletIds: this.getAvailableWalletIds()
1327
+ };
1328
+ }
1329
+ let nextDiscountList = this.mergeHistoricalDiscountList(
1330
+ preparedDiscountList || ((_k = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _k.call(discountModule)) || [],
1331
+ tempOrder.products || []
1332
+ );
1333
+ nextDiscountList = this.mergeCurrentDiscountSelectionState(
1334
+ nextDiscountList,
1335
+ currentDiscountList
1336
+ );
1337
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
1338
+ const shouldSkipAutoApplyFetchedDiscounts = this.shouldSkipAutoApplyFetchedDiscountsInEditMode({
1339
+ discountAction,
1340
+ products: tempOrder.products || [],
1341
+ currentDiscountList,
1342
+ nextDiscountList
1343
+ });
1344
+ if (shouldSkipAutoApplyFetchedDiscounts) {
1345
+ const summary2 = await this.store.order.recalculateSummary({ createIfMissing: true });
1346
+ this.store.order.persistTempOrder();
1347
+ await this.effectsEmit("onDiscountApplied", {
1348
+ productList: tempOrder.products || [],
1349
+ discountList: nextDiscountList,
1350
+ selectedDiscountList: tempOrder.discount_list || [],
1351
+ tempOrder
1352
+ });
1353
+ return {
1354
+ productList: tempOrder.products || [],
1355
+ discountList: nextDiscountList,
1356
+ availableWalletIds: this.getAvailableWalletIds()
1357
+ };
1358
+ }
1359
+ if (rulesModule) {
1360
+ const orderTotalAmount = Number(((_l = orderStore.summary) == null ? void 0 : _l.total_amount) || 0);
1361
+ console.log("[BaseSales.applyDiscountConfig.calcDiscount]");
1362
+ const result = rulesModule.calcDiscount({
1363
+ productList: tempOrder.products,
1364
+ discountList: nextDiscountList,
1365
+ holders: [],
1366
+ isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1367
+ orderTotalAmount
1368
+ }) || { productList: tempOrder.products, discountList: nextDiscountList };
1369
+ if (result.productList) {
1370
+ tempOrder.products = preserveManualProductDiscountProducts(
1371
+ tempOrder.products,
1372
+ result.productList
1373
+ );
1374
+ }
1375
+ for (const product of tempOrder.products || []) {
1376
+ const productUid = (_m = product.metadata) == null ? void 0 : _m.unique_identification_number;
1377
+ const runtimeOrigin = productUid ? (_p = (_o = (_n = tempOrder._extend) == null ? void 0 : _n.productsByUid) == null ? void 0 : _o[productUid]) == null ? void 0 : _p.origin : void 0;
1378
+ if ((runtimeOrigin == null ? void 0 : runtimeOrigin.isManualDiscount) || isBaseSalesManualProductDiscountProduct(product))
1379
+ continue;
1380
+ const totalPerUnitDiscount = (product.discount_list || []).reduce(
1381
+ (sum, pd) => sum + Number(pd.amount || 0),
1382
+ 0
1383
+ );
1384
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
1385
+ const sourcePrice = ((_q = product.metadata) == null ? void 0 : _q.source_product_price) ?? (((_r = product.metadata) == null ? void 0 : _r.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
1386
+ const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
1387
+ const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
1388
+ if (product.metadata) {
1389
+ product.metadata.main_product_selling_price = newMainSellingPrice;
1390
+ product.metadata.price_schema_version = 2;
1391
+ }
1392
+ product.selling_price = (0, import_utils.composeLinePrice)({
1393
+ mainPrice: newMainSellingPrice,
1394
+ bundle: product.product_bundle
1395
+ });
1396
+ }
1397
+ if (result.discountList) {
1398
+ nextDiscountList = this.mergeHistoricalDiscountList(
1399
+ result.discountList,
1400
+ tempOrder.products || []
1401
+ );
1402
+ import_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
1403
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
1404
+ tempOrder.discount_list = nextDiscountList.filter((discount) => discount.isSelected);
1405
+ }
1406
+ }
1407
+ const summary = await this.store.order.recalculateSummary({ createIfMissing: true });
1408
+ this.store.order.persistTempOrder();
1409
+ await this.effectsEmit("onDiscountApplied", {
1410
+ productList: tempOrder.products || [],
1411
+ discountList: nextDiscountList,
1412
+ selectedDiscountList: tempOrder.discount_list || [],
1413
+ tempOrder
1414
+ });
1415
+ return {
1416
+ productList: tempOrder.products || [],
1417
+ discountList: nextDiscountList,
1418
+ availableWalletIds: this.getAvailableWalletIds()
1419
+ };
1420
+ }
1421
+ getAvailableWalletIds() {
1422
+ var _a;
1423
+ if (!((_a = this.store.order) == null ? void 0 : _a.getAvailableWalletIds))
1424
+ return [];
1425
+ return this.store.order.getAvailableWalletIds();
1426
+ }
1427
+ async bestDiscount(cb) {
1428
+ var _a, _b, _c;
1429
+ if (!this.store.order)
1430
+ throw new Error("order 模块未初始化");
1431
+ const tempOrder = this.store.order.ensureTempOrder();
1432
+ const orderStore = this.store.order.store || {};
1433
+ const discountModule = orderStore.discount;
1434
+ const rulesModule = orderStore.rules;
1435
+ const originalDiscountList = ((_a = discountModule == null ? void 0 : discountModule.getOriginalDiscountList) == null ? void 0 : _a.call(discountModule)) || this.getDiscountList();
1436
+ const currentDiscountList = ((_b = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
1437
+ let nextDiscountList = this.mergeHistoricalDiscountList(
1438
+ originalDiscountList || [],
1439
+ tempOrder.products || []
1440
+ );
1441
+ let result = {
1442
+ productList: tempOrder.products || [],
1443
+ discountList: nextDiscountList
1444
+ };
1445
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
1446
+ if (rulesModule) {
1447
+ const orderTotalAmount = Number(((_c = orderStore.summary) == null ? void 0 : _c.total_amount) || 0);
1448
+ console.log("[BaseSales.bestDiscount.calcDiscount]");
1449
+ result = rulesModule.calcDiscount({
1450
+ productList: tempOrder.products,
1451
+ discountList: nextDiscountList,
1452
+ holders: [],
1453
+ isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1454
+ orderTotalAmount
1455
+ }) || result;
1456
+ if (result.productList) {
1457
+ tempOrder.products = preserveManualProductDiscountProducts(
1458
+ tempOrder.products,
1459
+ result.productList
1460
+ );
1461
+ }
1462
+ if (result.discountList) {
1463
+ nextDiscountList = this.mergeHistoricalDiscountList(
1464
+ result.discountList,
1465
+ tempOrder.products || []
1466
+ );
1467
+ import_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
1468
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
1469
+ tempOrder.discount_list = nextDiscountList.filter((discount) => discount.isSelected);
1470
+ result = {
1471
+ productList: tempOrder.products,
1472
+ discountList: nextDiscountList
1473
+ };
1474
+ }
1475
+ }
1476
+ await this.store.order.recalculateSummary({ createIfMissing: true });
1477
+ this.store.order.persistTempOrder();
1478
+ await this.effectsEmit("onDiscountApplied", {
1479
+ productList: tempOrder.products || [],
1480
+ discountList: nextDiscountList,
1481
+ selectedDiscountList: tempOrder.discount_list || [],
1482
+ tempOrder
1483
+ });
1484
+ cb == null ? void 0 : cb(result);
1485
+ return result;
1486
+ }
1487
+ getDiscountList() {
1488
+ if (!this.store.order)
1489
+ return [];
1490
+ return this.store.order.getDiscountList();
1491
+ }
1492
+ /** 读取 Discount 模块原始券列表(未经过 bookingTime 等过滤)。 */
1493
+ getOriginalDiscountList() {
1494
+ var _a, _b;
1495
+ if (!this.store.order)
1496
+ return [];
1497
+ const discountModule = (_a = this.store.order.store) == null ? void 0 : _a.discount;
1498
+ return ((_b = discountModule == null ? void 0 : discountModule.getOriginalDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
1499
+ }
1500
+ /**
1501
+ * 同步写入 Discount 模块的 discountList / originalDiscountList。
1502
+ * 供 Holder 补全等场景在 OS store 层更新 machinecode holder 字段。
1503
+ */
1504
+ async replaceDiscountStoreLists(params) {
1505
+ var _a;
1506
+ if (!this.store.order)
1507
+ throw new Error("order 模块未初始化");
1508
+ const discountModule = (_a = this.store.order.store) == null ? void 0 : _a.discount;
1509
+ if (!discountModule)
1510
+ return;
1511
+ if (params.originalDiscountList) {
1512
+ await discountModule.setOriginalDiscountList(params.originalDiscountList);
1513
+ }
1514
+ await discountModule.setDiscountList(params.discountList);
1515
+ }
1516
+ async scanPromotionCode(code, customerId) {
1517
+ try {
1518
+ if (!this.store.order)
1519
+ throw new Error("order 模块未初始化");
1520
+ const raw = await this.store.order.scanCode(code, customerId);
1521
+ if (raw.isAvailable) {
1522
+ await this.store.order.recalculateSummary({ createIfMissing: true });
1523
+ this.store.order.persistTempOrder();
1524
+ const tempOrder = this.store.order.ensureTempOrder();
1525
+ await this.effectsEmit("onDiscountApplied", {
1526
+ productList: tempOrder.products || [],
1527
+ discountList: this.store.order.getDiscountList(),
1528
+ selectedDiscountList: tempOrder.discount_list || [],
1529
+ tempOrder
1530
+ });
1531
+ }
1532
+ return {
1533
+ isAvailable: raw.isAvailable,
1534
+ type: raw.type,
1535
+ unavailableReason: raw.unavailableReason,
1536
+ scannedDiscountList: raw.scannedDiscountList
1537
+ };
1538
+ } catch (error) {
1539
+ throw error;
1540
+ }
1541
+ }
1542
+ // TODO 需要优化,这段逻辑太长了,里面应该有些历史遗留问题
1543
+ async setDiscountSelected(params) {
1544
+ var _a, _b, _c, _d, _e, _f, _g;
1545
+ try {
1546
+ if (!this.store.order)
1547
+ throw new Error("order 模块未初始化");
1548
+ const list = this.store.order.getDiscountList();
1549
+ const updated = list.map(
1550
+ (d) => d.id === params.discountId && !isBaseSalesHistoricalDiscountEntry(d) ? {
1551
+ ...d,
1552
+ isSelected: params.isSelected,
1553
+ isManualSelect: !params.isSelected
1554
+ } : d
1555
+ );
1556
+ this.hasManualDiscountSelection = true;
1557
+ const tempOrder = this.store.order.ensureTempOrder();
1558
+ const orderStore = this.store.order.store || {};
1559
+ const discountModule = orderStore.discount;
1560
+ const rulesModule = orderStore.rules;
1561
+ let nextDiscountList = updated;
1562
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(updated));
1563
+ if (rulesModule) {
1564
+ const orderTotalAmount = Number(((_a = orderStore.summary) == null ? void 0 : _a.total_amount) || 0);
1565
+ console.log("[BaseSales.setDiscountSelected.calcDiscount]");
1566
+ const result = rulesModule.calcDiscount(
1567
+ {
1568
+ productList: tempOrder.products,
1569
+ discountList: updated,
1570
+ holders: [],
1571
+ isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1572
+ orderTotalAmount
1573
+ },
1574
+ {
1575
+ discountId: params.discountId,
1576
+ isSelected: params.isSelected
1577
+ }
1578
+ ) || { productList: tempOrder.products, discountList: updated };
1579
+ if (result == null ? void 0 : result.productList) {
1580
+ tempOrder.products = preserveManualProductDiscountProducts(
1581
+ tempOrder.products,
1582
+ result.productList
1583
+ );
1584
+ }
1585
+ if (result == null ? void 0 : result.discountList) {
1586
+ nextDiscountList = result.discountList;
1587
+ if (!params.isSelected) {
1588
+ const beforeSelectedIds = new Set(
1589
+ updated.filter((d) => d.isSelected).map((d) => d.id)
1590
+ );
1591
+ for (const d of nextDiscountList) {
1592
+ if (d.isSelected && !beforeSelectedIds.has(d.id)) {
1593
+ d.isSelected = false;
1594
+ d.isManualSelect = true;
1595
+ d.appliedProductDetails = [];
1596
+ }
1597
+ }
1598
+ }
1599
+ }
1600
+ }
1601
+ const selectedResourceIds = new Set(
1602
+ nextDiscountList.filter((d) => d.isSelected).map((d) => d.id)
1603
+ );
1604
+ const filterSelectedDiscountDetails = (discountList) => (discountList || []).filter((pd) => {
1605
+ var _a2;
1606
+ const rid = ((_a2 = pd.discount) == null ? void 0 : _a2.resource_id) ?? pd.id;
1607
+ return rid != null && selectedResourceIds.has(rid);
1608
+ });
1609
+ for (const product of tempOrder.products) {
1610
+ const productUid = (_b = product.metadata) == null ? void 0 : _b.unique_identification_number;
1611
+ const runtimeOrigin = productUid ? (_e = (_d = (_c = tempOrder._extend) == null ? void 0 : _c.productsByUid) == null ? void 0 : _d[productUid]) == null ? void 0 : _e.origin : void 0;
1612
+ if ((runtimeOrigin == null ? void 0 : runtimeOrigin.isManualDiscount) || isBaseSalesManualProductDiscountProduct(product))
1613
+ continue;
1614
+ product.discount_list = filterSelectedDiscountDetails(product.discount_list);
1615
+ if (Array.isArray(product.product_bundle)) {
1616
+ product.product_bundle = product.product_bundle.map((bundle) => {
1617
+ const nextBundleDiscountList = filterSelectedDiscountDetails(bundle == null ? void 0 : bundle.discount_list);
1618
+ const shouldRestoreBundlePrice = nextBundleDiscountList.length === 0;
1619
+ const restoredBundlePrice = (bundle == null ? void 0 : bundle.original_price) ?? (bundle == null ? void 0 : bundle.product_price) ?? (bundle == null ? void 0 : bundle.price);
1620
+ return {
1621
+ ...bundle,
1622
+ ...shouldRestoreBundlePrice ? {
1623
+ price: restoredBundlePrice,
1624
+ bundle_selling_price: restoredBundlePrice
1625
+ } : {},
1626
+ discount_list: nextBundleDiscountList
1627
+ };
1628
+ });
1629
+ }
1630
+ const totalPerUnitDiscount = (product.discount_list || []).reduce(
1631
+ (sum, pd) => sum + (pd.amount || 0),
1632
+ 0
1633
+ );
1634
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
1635
+ const sourcePrice = ((_f = product.metadata) == null ? void 0 : _f.source_product_price) ?? (((_g = product.metadata) == null ? void 0 : _g.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
1636
+ const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
1637
+ const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
1638
+ if (product.metadata) {
1639
+ product.metadata.main_product_selling_price = newMainSellingPrice;
1640
+ product.metadata.price_schema_version = 2;
1641
+ }
1642
+ product.selling_price = (0, import_utils.composeLinePrice)({
1643
+ mainPrice: newMainSellingPrice,
1644
+ bundle: product.product_bundle
1645
+ });
1646
+ }
1647
+ import_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
1648
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
1649
+ tempOrder.discount_list = (nextDiscountList || []).filter((d) => d.isSelected);
1650
+ await this.store.order.recalculateSummary({ createIfMissing: true });
1651
+ this.store.order.persistTempOrder();
1652
+ this.effectsEmit("onDiscountApplied", {
1653
+ productList: tempOrder.products,
1654
+ discountList: nextDiscountList,
1655
+ selectedDiscountList: tempOrder.discount_list,
1656
+ tempOrder
1657
+ });
1658
+ } catch (error) {
1659
+ throw error;
1660
+ }
1661
+ }
1662
+ async applyDiscountCalculationResult(result) {
1663
+ try {
1664
+ if (!this.store.order)
1665
+ throw new Error("order 模块未初始化");
1666
+ if (!result)
1667
+ return;
1668
+ const tempOrder = this.store.order.ensureTempOrder();
1669
+ const orderStore = this.store.order.store || {};
1670
+ const discountModule = orderStore.discount;
1671
+ if (result.productList) {
1672
+ tempOrder.products = preserveManualProductDiscountProducts(
1673
+ tempOrder.products,
1674
+ result.productList
1675
+ );
1676
+ }
1677
+ if (result.discountList) {
1678
+ import_Order.OrderModule.populateSavedAmounts(
1679
+ tempOrder.products,
1680
+ result.discountList
1681
+ );
1682
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(result.discountList));
1683
+ tempOrder.discount_list = result.discountList.filter(
1684
+ (discount) => discount.isSelected
1685
+ );
1686
+ }
1687
+ await this.store.order.recalculateSummary({ createIfMissing: true });
1688
+ this.store.order.persistTempOrder();
1689
+ await this.effectsEmit("onDiscountApplied", {
1690
+ productList: tempOrder.products || [],
1691
+ discountList: result.discountList || [],
1692
+ selectedDiscountList: tempOrder.discount_list || [],
1693
+ tempOrder
1694
+ });
1695
+ } catch (error) {
1696
+ throw error;
1697
+ }
1698
+ }
1699
+ async submitScanOrder(params) {
1700
+ return this.submitSalesOrder(params);
1701
+ }
1702
+ /**
1703
+ * 提交当前 Sales 订单。
1704
+ *
1705
+ * PaymentModal 场景通过 smallTicketDataFlag=1 请求 B 端小票数据;
1706
+ * payments 会交给 OrderModule 统一映射为 Sales 协议支付项。
1707
+ */
1708
+ async submitSalesOrder(params) {
1709
+ var _a, _b, _c, _d;
1710
+ if (!this.store.order) {
1711
+ throw new Error("BaseSales 解决方案需要 order 模块支持");
1712
+ }
1713
+ const inferredPaymentStatus = this.getSubmitPaymentStatus(params == null ? void 0 : params.paymentStatus);
1714
+ const smallTicketDataFlag = (params == null ? void 0 : params.smallTicketDataFlag) ?? this.getDefaultCheckoutSmallTicketDataFlag();
1715
+ const submitParams = {
1716
+ cacheId: this.cacheId,
1717
+ platform: (_a = this.otherParams) == null ? void 0 : _a.platform,
1718
+ businessCode: ((_b = this.otherParams) == null ? void 0 : _b.businessCode) || ((_c = this.otherParams) == null ? void 0 : _c.business_code),
1719
+ channel: this.getSubmitOrderSalesChannel(),
1720
+ type: (_d = this.otherParams) == null ? void 0 : _d.type,
1721
+ request_unique_idempotency_token: this.store.order.generateIdempotencyToken(),
1722
+ ...(params == null ? void 0 : params.payments) !== void 0 ? { payments: params.payments } : {},
1723
+ ...inferredPaymentStatus !== void 0 ? { paymentStatus: inferredPaymentStatus } : {},
1724
+ ...smallTicketDataFlag !== void 0 ? { smallTicketDataFlag } : {},
1725
+ ...(params == null ? void 0 : params.confirmPendingVoucherPayments) !== void 0 ? { confirmPendingVoucherPayments: params.confirmPendingVoucherPayments } : {},
1726
+ ...(params == null ? void 0 : params.enhancePayload) !== void 0 ? { enhancePayload: params.enhancePayload } : {}
1727
+ };
1728
+ return this.shouldUseCheckoutSyncTask() ? this.store.order.submitTempOrder(submitParams) : this.store.order.submitTempOrderAsync(submitParams);
1729
+ }
1730
+ async submitTempOrderAsync(params) {
1731
+ var _a, _b, _c, _d;
1732
+ if (!this.store.order) {
1733
+ throw new Error("BaseSales 解决方案需要 order 模块支持");
1734
+ }
1735
+ const inferredPaymentStatus = this.getSubmitPaymentStatus(params == null ? void 0 : params.paymentStatus);
1736
+ const smallTicketDataFlag = (params == null ? void 0 : params.smallTicketDataFlag) ?? this.getDefaultCheckoutSmallTicketDataFlag();
1737
+ const submitParams = {
1738
+ cacheId: this.cacheId,
1739
+ platform: (_a = this.otherParams) == null ? void 0 : _a.platform,
1740
+ businessCode: ((_b = this.otherParams) == null ? void 0 : _b.businessCode) || ((_c = this.otherParams) == null ? void 0 : _c.business_code),
1741
+ channel: this.getSubmitOrderSalesChannel(),
1742
+ type: (_d = this.otherParams) == null ? void 0 : _d.type,
1743
+ request_unique_idempotency_token: this.store.order.generateIdempotencyToken(),
1744
+ ...(params == null ? void 0 : params.payments) !== void 0 ? { payments: params.payments } : {},
1745
+ ...inferredPaymentStatus !== void 0 ? { paymentStatus: inferredPaymentStatus } : {},
1746
+ ...smallTicketDataFlag !== void 0 ? { smallTicketDataFlag } : {},
1747
+ ...(params == null ? void 0 : params.confirmPendingVoucherPayments) !== void 0 ? { confirmPendingVoucherPayments: params.confirmPendingVoucherPayments } : {},
1748
+ ...(params == null ? void 0 : params.enhancePayload) !== void 0 ? { enhancePayload: params.enhancePayload } : {}
1749
+ };
1750
+ return this.store.order.submitTempOrderAsync(submitParams);
1751
+ }
1752
+ /**
1753
+ * 默认保持 WebPOS 的本地待同步订单模式;需要云端确认后才算成功的渠道可覆盖此策略。
1754
+ * otherParams.checkoutSyncTaskEnabled 优先,便于同一 solution 按入口恢复旧行为。
1755
+ */
1756
+ shouldUseCheckoutSyncTask() {
1757
+ var _a;
1758
+ const configured = (_a = this.otherParams) == null ? void 0 : _a.checkoutSyncTaskEnabled;
1759
+ return typeof configured === "boolean" ? configured : true;
1760
+ }
1761
+ /** 可由特定 solution 为真实 checkout 补充默认收据数据请求。 */
1762
+ getDefaultCheckoutSmallTicketDataFlag() {
1763
+ return void 0;
1764
+ }
1765
+ async printLocalOrderReceipt(lookup) {
1766
+ var _a, _b, _c, _d, _e, _f, _g;
1767
+ if (!this.store.order) {
1768
+ throw new Error("BaseSales 解决方案需要 order 模块支持");
1769
+ }
1770
+ const hasLookup = lookup !== void 0 && lookup !== null && lookup !== "";
1771
+ const lookupPayload = typeof lookup === "number" ? { order_id: lookup } : { external_sale_number: lookup };
1772
+ const context = {
1773
+ platform: (_a = this.otherParams) == null ? void 0 : _a.platform,
1774
+ businessCode: ((_b = this.otherParams) == null ? void 0 : _b.businessCode) || ((_c = this.otherParams) == null ? void 0 : _c.business_code),
1775
+ channel: this.getSubmitOrderSalesChannel(),
1776
+ type: (_d = this.otherParams) == null ? void 0 : _d.type
1777
+ };
1778
+ const payload = hasLookup ? {
1779
+ ...lookupPayload,
1780
+ lookup_order_from_db: 1,
1781
+ small_ticket_data_flag: 1,
1782
+ platform: context.platform,
1783
+ business_code: context.businessCode,
1784
+ order_sales_channel: context.channel,
1785
+ type: context.type
1786
+ } : this.store.order.buildCurrentSubmitPayloadForLocalPrint({
1787
+ cacheId: this.cacheId,
1788
+ platform: context.platform,
1789
+ businessCode: context.businessCode,
1790
+ channel: context.channel,
1791
+ type: context.type
1792
+ });
1793
+ const response = await this.request.post("/local/print-order", payload, {
1794
+ osServer: true,
1795
+ customToast: () => {
1796
+ }
1797
+ });
1798
+ if (!hasLookup) {
1799
+ await ((_g = (_f = this.store.order).applyLocalPrintOrderNumbers) == null ? void 0 : _g.call(_f, (_e = response == null ? void 0 : response.data) == null ? void 0 : _e.order));
1800
+ }
1801
+ return response;
1802
+ }
1803
+ getSubmitPaymentStatus(paymentStatus) {
1804
+ var _a, _b;
1805
+ if (paymentStatus !== void 0)
1806
+ return paymentStatus;
1807
+ const amountSnapshot = (_b = (_a = this.store.order) == null ? void 0 : _a.getOrderAmountSnapshot) == null ? void 0 : _b.call(_a);
1808
+ if (!amountSnapshot)
1809
+ return void 0;
1810
+ try {
1811
+ return new import_decimal.default(amountSnapshot.amountGap || 0).lte(0) ? "paid" : void 0;
1812
+ } catch {
1813
+ return void 0;
1814
+ }
1815
+ }
1816
+ async syncPaymentsToOrder(params) {
1817
+ var _a, _b;
1818
+ if (!this.store.order)
1819
+ throw new Error("order 模块未初始化");
1820
+ const businessCode = params.businessCode ?? ((_a = this.otherParams) == null ? void 0 : _a.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.business_code);
1821
+ const channel = params.channel ?? this.getSubmitOrderSalesChannel();
1822
+ const syncParams = {
1823
+ ...params,
1824
+ checkoutSyncTaskEnabled: this.shouldUseCheckoutSyncTask(),
1825
+ ...businessCode !== void 0 ? { businessCode } : {},
1826
+ ...channel !== void 0 ? { channel } : {}
1827
+ };
1828
+ const syncState = this.store.order.getOrderSyncState();
1829
+ if (params.submitWhenPaid && syncState === "submitting") {
1830
+ this.queueLatestAutoPaymentSync();
1831
+ return this.store.order.syncPaymentsToOrder(syncParams);
1832
+ }
1833
+ const payments = params.payments || [];
1834
+ await this.effectsEmit(import_types.BaseSalesHookNames.onPaymentSyncStart, {
1835
+ payments,
1836
+ params: syncParams,
1837
+ amountSnapshot: this.store.order.getOrderAmountSnapshot(),
1838
+ orderSnapshot: this.store.order.getOrderSnapshot()
1839
+ });
1840
+ try {
1841
+ const syncResult = await this.store.order.syncPaymentsToOrder(syncParams);
1842
+ const latestPayments = this.store.order.getOrderPayments();
1843
+ const amountSnapshot = this.store.order.getOrderAmountSnapshot();
1844
+ const orderSnapshot = this.store.order.getOrderSnapshot();
1845
+ const syncPayload = {
1846
+ ok: true,
1847
+ syncResult,
1848
+ payments: latestPayments,
1849
+ params: syncParams,
1850
+ amountSnapshot,
1851
+ orderSnapshot,
1852
+ isFullyPaid: syncResult.isFullyPaid,
1853
+ isOrderFullyPaid: syncResult.isOrderFullyPaid,
1854
+ isDepositFullyPaid: syncResult.isDepositFullyPaid,
1855
+ paymentStage: syncResult.paymentStage,
1856
+ depositAmount: syncResult.depositAmount,
1857
+ orderExpectedAmount: syncResult.orderExpectedAmount
1858
+ };
1859
+ await this.effectsEmit(import_types.BaseSalesHookNames.onPaymentSyncEnd, syncPayload);
1860
+ if (syncResult.isDepositFullyPaid && !syncResult.isOrderFullyPaid) {
1861
+ await this.effectsEmit(import_types.BaseSalesHookNames.onDepositPaymentSyncEnd, syncPayload);
1862
+ }
1863
+ this.scheduleQueuedAutoPaymentSyncFlush(0);
1864
+ return syncResult;
1865
+ } catch (error) {
1866
+ await this.effectsEmit(import_types.BaseSalesHookNames.onPaymentSyncEnd, {
1867
+ ok: false,
1868
+ error,
1869
+ payments: this.store.order.getOrderPayments(),
1870
+ params: syncParams,
1871
+ amountSnapshot: this.store.order.getOrderAmountSnapshot(),
1872
+ orderSnapshot: this.store.order.getOrderSnapshot()
1873
+ });
1874
+ this.scheduleQueuedAutoPaymentSyncFlush(0);
1875
+ throw error;
1876
+ }
1877
+ }
1878
+ /** 读取当前 BaseSales 订单上下文中的 Sales 协议支付项。 */
1879
+ getOrderPayments() {
1880
+ if (!this.store.order)
1881
+ return [];
1882
+ const payments = this.store.order.getOrderPayments();
1883
+ return this.hydrateOrderPaymentNames(payments);
1884
+ }
1885
+ /** 覆盖当前订单支付项,内部由 OrderModule 清洗为 Sales 协议字段。 */
1886
+ setOrderPayments(payments) {
1887
+ if (!this.store.order)
1888
+ throw new Error("order 模块未初始化");
1889
+ return this.store.order.setOrderPayments(payments);
1890
+ }
1891
+ getPaymentStatusForSync(payments) {
1892
+ const order = this.store.order;
1893
+ if (!order)
1894
+ throw new Error("order 模块未初始化");
1895
+ const completion = order.getPaymentCompletion(payments);
1896
+ return completion.isOrderFullyPaid ? "paid" : "partially_paid";
1897
+ }
1898
+ queueLatestAutoPaymentSync() {
1899
+ this.queuedAutoPaymentSync = true;
1900
+ this.scheduleQueuedAutoPaymentSyncFlush();
1901
+ }
1902
+ scheduleQueuedAutoPaymentSyncFlush(delay = 100) {
1903
+ if (!this.queuedAutoPaymentSync)
1904
+ return;
1905
+ if (this.autoPaymentSyncTimer)
1906
+ return;
1907
+ this.autoPaymentSyncTimer = setTimeout(() => {
1908
+ this.autoPaymentSyncTimer = null;
1909
+ void this.flushQueuedAutoPaymentSync();
1910
+ }, delay);
1911
+ }
1912
+ async flushQueuedAutoPaymentSync() {
1913
+ if (!this.store.order)
1914
+ return;
1915
+ if (!this.queuedAutoPaymentSync || this.autoPaymentSyncFlushing)
1916
+ return;
1917
+ if (this.store.order.getOrderSyncState() === "submitting") {
1918
+ this.scheduleQueuedAutoPaymentSyncFlush();
1919
+ return;
1920
+ }
1921
+ this.autoPaymentSyncFlushing = true;
1922
+ try {
1923
+ while (this.queuedAutoPaymentSync) {
1924
+ this.queuedAutoPaymentSync = false;
1925
+ const payments = this.store.order.getOrderPayments();
1926
+ if (!payments.length)
1927
+ continue;
1928
+ await this.syncPaymentsToOrder({
1929
+ payments,
1930
+ paymentStatus: this.getPaymentStatusForSync(payments),
1931
+ submitWhenPaid: true,
1932
+ smallTicketDataFlag: 1
1933
+ });
1934
+ }
1935
+ } catch (error) {
1936
+ this.logError("queued auto sync payments failed", {
1937
+ error: error instanceof Error ? error.message : String(error)
1938
+ });
1939
+ } finally {
1940
+ this.autoPaymentSyncFlushing = false;
1941
+ if (this.queuedAutoPaymentSync) {
1942
+ this.scheduleQueuedAutoPaymentSyncFlush(0);
1943
+ }
1944
+ }
1945
+ }
1946
+ /** 追加单个支付项到当前订单。 */
1947
+ addOrderPayment(payment) {
1948
+ var _a;
1949
+ if (!this.store.order)
1950
+ throw new Error("order 模块未初始化");
1951
+ const paymentRecord = payment;
1952
+ const paymentAmount = new import_decimal.default(paymentRecord.amount || 0);
1953
+ if (paymentAmount.isZero()) {
1954
+ this.logWarning("addOrderPayment: 支付金额为 0,跳过添加支付项", {
1955
+ payment: paymentRecord
1956
+ });
1957
+ return this.store.order.getOrderPayments();
1958
+ }
1959
+ const metadata = paymentRecord.metadata && typeof paymentRecord.metadata === "object" ? { ...paymentRecord.metadata } : {};
1960
+ const shopWalletPassId = (_a = this.otherParams) == null ? void 0 : _a.shop_wallet_pass_id;
1961
+ if (shopWalletPassId !== void 0 && shopWalletPassId !== null) {
1962
+ metadata.shop_wallet_pass_id = shopWalletPassId;
1963
+ }
1964
+ if (!metadata.unique_payment_number) {
1965
+ metadata.unique_payment_number = (0, import_utils.createUuidV4)();
1966
+ }
1967
+ const paymentTimestamp = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
1968
+ const paymentTime = paymentRecord.payment_time ?? paymentTimestamp;
1969
+ const createdAt = paymentRecord.created_at ?? paymentTimestamp;
1970
+ const serviceCharge = paymentRecord.service_charge && typeof paymentRecord.service_charge === "object" ? paymentRecord.service_charge : null;
1971
+ const calculatedServiceFee = serviceCharge ? new import_decimal.default(paymentRecord.origin_amount ?? paymentRecord.amount ?? 0).times(serviceCharge.percentage || 0).plus(serviceCharge.amount || 0).toDecimalPlaces(2).toFixed(2) : void 0;
1972
+ const payments = this.store.order.addOrderPayment({
1973
+ ...paymentRecord,
1974
+ ...calculatedServiceFee !== void 0 ? { service_fee: calculatedServiceFee } : {},
1975
+ metadata,
1976
+ payment_time: paymentTime,
1977
+ created_at: createdAt
1978
+ });
1979
+ const amountSnapshot = this.store.order.getOrderAmountSnapshot();
1980
+ const syncState = this.store.order.getOrderSyncState();
1981
+ if (amountSnapshot) {
1982
+ if (syncState === "submitting") {
1983
+ this.queueLatestAutoPaymentSync();
1984
+ return payments;
1985
+ }
1986
+ void this.syncPaymentsToOrder({
1987
+ payments,
1988
+ paymentStatus: this.getPaymentStatusForSync(payments),
1989
+ submitWhenPaid: true,
1990
+ smallTicketDataFlag: 1
1991
+ }).catch((error) => {
1992
+ this.logError("auto sync payments failed", {
1993
+ error: error instanceof Error ? error.message : String(error)
1994
+ });
1995
+ });
1996
+ }
1997
+ return payments;
1998
+ }
1999
+ /** 更新当前订单中的指定支付项。 */
2000
+ updateOrderPayment(paymentIdentity, updates) {
2001
+ if (!this.store.order)
2002
+ throw new Error("order 模块未初始化");
2003
+ return this.store.order.updateOrderPayment(paymentIdentity, updates);
2004
+ }
2005
+ /** 删除当前订单中的指定支付项。 */
2006
+ deleteOrderPayment(paymentIdentity) {
2007
+ if (!this.store.order)
2008
+ throw new Error("order 模块未初始化");
2009
+ return this.store.order.deleteOrderPayment(paymentIdentity);
2010
+ }
2011
+ /** 覆盖 wallet pass 支付项,同时保留普通支付项。 */
2012
+ updateVoucherOrderPayments(payments, options) {
2013
+ if (!this.store.order)
2014
+ throw new Error("order 模块未初始化");
2015
+ return this.store.order.updateVoucherOrderPayments(payments, options);
2016
+ }
2017
+ confirmPendingVoucherPayments() {
2018
+ if (!this.store.order)
2019
+ throw new Error("order 模块未初始化");
2020
+ return this.store.order.confirmPendingVoucherPayments();
2021
+ }
2022
+ discardPendingVoucherPayments() {
2023
+ if (!this.store.order)
2024
+ throw new Error("order 模块未初始化");
2025
+ return this.store.order.discardPendingVoucherPayments();
2026
+ }
2027
+ getWalletProductList() {
2028
+ var _a, _b;
2029
+ const tempOrder = (_a = this.store.order) == null ? void 0 : _a.getTempOrder();
2030
+ if (!((_b = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _b.length))
2031
+ return [];
2032
+ const walletProducts = tempOrder == null ? void 0 : tempOrder.products.map((product) => {
2033
+ const metadata = product.metadata || {};
2034
+ const rawHolderId = product.holder_id ?? metadata.holder_id;
2035
+ const holderIdValue = Array.isArray(rawHolderId) ? rawHolderId[0] : rawHolderId;
2036
+ const holder_id = Number.isInteger(Number(holderIdValue)) ? Number(holderIdValue) : void 0;
2037
+ return {
2038
+ product_id: product.product_id || 0,
2039
+ product_variant_id: String(product.product_variant_id ?? ""),
2040
+ quantity: product.num || 1,
2041
+ is_price_include_tax: tempOrder.is_price_include_tax,
2042
+ is_charge_tax: product.is_charge_tax ?? 0,
2043
+ tax_fee: product.tax_fee,
2044
+ selling_price: Number(product.selling_price || 0),
2045
+ discount_list: product.discount_list || [],
2046
+ holder_id,
2047
+ original_price: product.original_price,
2048
+ main_product_original_price: metadata.main_product_original_price ?? product.original_price,
2049
+ main_product_selling_price: metadata.main_product_selling_price ?? product.selling_price,
2050
+ metadata: {
2051
+ main_product_attached_bundle_tax_fee: metadata.main_product_attached_bundle_tax_fee,
2052
+ main_product_attached_bundle_surcharge_fee: metadata.main_product_attached_bundle_surcharge_fee,
2053
+ surcharge_rounding_remainder: metadata.surcharge_rounding_remainder
2054
+ },
2055
+ product_bundle: (product.product_bundle || []).map((bundle) => {
2056
+ const bundleMetadata = bundle.metadata || {};
2057
+ return {
2058
+ is_price_include_tax: tempOrder.is_price_include_tax,
2059
+ // 套餐子项在 tempOrder 上常为 id(如 1718),prepare/deduction 协议要求 bundle_id
2060
+ bundle_id: bundle.bundle_id ?? bundle.id,
2061
+ bundle_product_id: bundle.bundle_product_id ?? bundle._bundle_product_id,
2062
+ bundle_group_id: bundle.bundle_group_id ?? bundle.group_id,
2063
+ bundle_variant_id: bundle.bundle_variant_id,
2064
+ price_type: bundle.price_type,
2065
+ price_type_ext: bundle.price_type_ext,
2066
+ bundle_sum_price: bundle.bundle_sum_price,
2067
+ bundle_selling_price: bundle.bundle_selling_price,
2068
+ num: bundle.num,
2069
+ is_charge_tax: bundle.is_charge_tax,
2070
+ tax_fee: bundle.tax_fee,
2071
+ metadata: {
2072
+ surcharge_fee: bundleMetadata.surcharge_fee,
2073
+ surcharge_rounding_remainder: bundleMetadata.surcharge_rounding_remainder
2074
+ }
2075
+ };
2076
+ })
2077
+ };
2078
+ });
2079
+ return walletProducts;
2080
+ }
2081
+ async initWalletData(params) {
2082
+ if (!this.store.order)
2083
+ throw new Error("order 模块未初始化");
2084
+ if (!this.store.payment)
2085
+ throw new Error("payment 模块未初始化");
2086
+ const snapshot = this.store.order.getOrderSnapshot();
2087
+ const tempOrder = snapshot == null ? void 0 : snapshot.tempOrder;
2088
+ const amount = snapshot == null ? void 0 : snapshot.amount;
2089
+ if (!tempOrder || !amount) {
2090
+ return {
2091
+ walletRecommendList: [],
2092
+ userIdentificationCodes: [],
2093
+ transformList: [],
2094
+ noApplicableVoucher: [],
2095
+ products: []
2096
+ };
2097
+ }
2098
+ const walletBusinessData = {
2099
+ customer_id: tempOrder.customer_id ? Number(tempOrder.customer_id) : void 0,
2100
+ holder: tempOrder.holder,
2101
+ amountInfo: {
2102
+ totalAmount: amount.totalAmount,
2103
+ subTotal: amount.summary.product_amount || amount.summary.product_expect_amount || amount.totalAmount,
2104
+ depositAmount: amount.depositAmount,
2105
+ isDeposit: tempOrder.is_deposit
2106
+ },
2107
+ products: this.getWalletProductList(),
2108
+ order_wait_pay_amount: (params == null ? void 0 : params.order_wait_pay_amount) ?? Number(amount.amountGap || 0),
2109
+ is_price_include_tax: tempOrder.is_price_include_tax ?? this.otherParams.is_price_include_tax ?? 1,
2110
+ ...snapshot.identity.orderId ? { payment_order_id: String(snapshot.identity.orderId) } : {}
2111
+ };
2112
+ const result = await this.store.payment.wallet.initializeWalletDataFromBusinessAsync(
2113
+ walletBusinessData
2114
+ );
2115
+ await this.core.effects.emit(`${this.name}:onWalletDataInitialized`, {
2116
+ orderId: snapshot.identity.orderId,
2117
+ customerId: walletBusinessData.customer_id,
2118
+ walletBusinessData: {
2119
+ customer_id: walletBusinessData.customer_id,
2120
+ amountInfo: walletBusinessData.amountInfo,
2121
+ order_wait_pay_amount: walletBusinessData.order_wait_pay_amount
2122
+ },
2123
+ timestamp: Date.now()
2124
+ });
2125
+ return result;
2126
+ }
2127
+ /**
2128
+ * 更新当前订单客户字段。
2129
+ *
2130
+ * 这是 PaymentModal 客户切换的订单事实入口;外部客户模块同步应由
2131
+ * 调用方通过 onCustomerChange 回调完成。
2132
+ */
2133
+ updateOrderCustomer(customer) {
2134
+ if (!this.store.order)
2135
+ throw new Error("order 模块未初始化");
2136
+ const result = this.store.order.updateTempOrderCustomer(customer);
2137
+ this.store.order.recalculateSummary({ createIfMissing: true });
2138
+ this.store.order.persistTempOrder();
2139
+ return result;
2140
+ }
2141
+ /** 获取可用支付方式列表,供 PaymentModal 渲染支付选项。 */
2142
+ async getPaymentMethodsAsync() {
2143
+ try {
2144
+ const response = await this.request.get("/pay/custom-payment/all", {
2145
+ filterPaymentMethods: true
2146
+ }, {
2147
+ osServer: true
2148
+ });
2149
+ const paymentMethods = (response == null ? void 0 : response.data) || [];
2150
+ this.paymentMethodsCache = Array.isArray(paymentMethods) ? [...paymentMethods] : [];
2151
+ return this.getPaymentMethods();
2152
+ } catch (error) {
2153
+ this.logWarning("getPaymentMethodsAsync: 获取支付方式列表失败,使用缓存列表", {
2154
+ error: error instanceof Error ? error.message : String(error)
2155
+ });
2156
+ return this.getPaymentMethods();
2157
+ }
2158
+ }
2159
+ /** 同步读取初始化时缓存的支付方式列表。 */
2160
+ getPaymentMethods() {
2161
+ return [...this.paymentMethodsCache];
2162
+ }
2163
+ /** 轻量舍入能力,供现金支付 UI 计算 rounding_amount。 */
2164
+ roundAmount(params) {
2165
+ const amount = new import_decimal.default(params.amount || 0);
2166
+ const interval = new import_decimal.default(params.interval || 0.05);
2167
+ const rule = params.rule || "standard_rounding";
2168
+ const quotient = amount.div(interval);
2169
+ let roundedQuotient;
2170
+ if (rule === "always_up") {
2171
+ roundedQuotient = quotient.ceil();
2172
+ } else if (rule === "always_down") {
2173
+ roundedQuotient = quotient.floor();
2174
+ } else if (rule === "standard_down") {
2175
+ roundedQuotient = quotient.toDecimalPlaces(0, import_decimal.default.ROUND_HALF_DOWN);
2176
+ } else {
2177
+ roundedQuotient = quotient.toDecimalPlaces(0, import_decimal.default.ROUND_HALF_UP);
2178
+ }
2179
+ const roundedAmount = roundedQuotient.times(interval).toDecimalPlaces(2);
2180
+ return {
2181
+ originalAmount: amount.toFixed(2),
2182
+ roundedAmount: roundedAmount.toFixed(2),
2183
+ roundingDifference: roundedAmount.minus(amount).toFixed(2)
2184
+ };
2185
+ }
2186
+ /**
2187
+ * 发送支付链接。
2188
+ *
2189
+ * 如果没有 orderIds 或显式 submitBeforeSend,会先提交当前本地订单到云端;
2190
+ * 只有成功拿到远端 order_id 后才调用 OrderModule 发送邮件。
2191
+ */
2192
+ async sendCustomerPayLink(params) {
2193
+ var _a, _b;
2194
+ if (!this.store.order)
2195
+ throw new Error("order 模块未初始化");
2196
+ let orderIds = params.order_ids || params.orderIds || [];
2197
+ if (!orderIds.length || params.submitBeforeSend) {
2198
+ const submitResult = await this.submitSalesOrder({
2199
+ smallTicketDataFlag: 1
2200
+ });
2201
+ const orderId = ((_a = submitResult == null ? void 0 : submitResult.data) == null ? void 0 : _a.order_id) ?? (submitResult == null ? void 0 : submitResult.order_id) ?? ((_b = submitResult == null ? void 0 : submitResult.data) == null ? void 0 : _b.id) ?? (submitResult == null ? void 0 : submitResult.id);
2202
+ if (!orderId) {
2203
+ throw new Error("本地订单提交云端失败,无法发送支付链接");
2204
+ }
2205
+ orderIds = [orderId];
2206
+ }
2207
+ return this.store.order.sendCustomerPayLink({
2208
+ emails: params.emails,
2209
+ notify_action: params.notify_action,
2210
+ order_ids: orderIds
2211
+ });
2212
+ }
2213
+ transformBaseProductToOrderProduct(params) {
2214
+ return (0, import_transformBaseProductToOrderProduct.transformBaseProductToOrderProduct)(params);
2215
+ }
2216
+ async calculateProductBookingPrice(params) {
2217
+ const quotation = this.store.quotation;
2218
+ const customerId = params.customer_id ?? this.getCurrentOrderCustomerId();
2219
+ const authoritativeProduct = await this.loadProductForPriceQuery(params, customerId);
2220
+ const product = this.mergeProductForPriceQuery(params.product, authoritativeProduct);
2221
+ await this.loadQuotationForPriceQuery({
2222
+ quotation,
2223
+ customer_id: customerId,
2224
+ channel: params.channel
2225
+ });
2226
+ return (0, import_quotationPrice.calculateBaseSalesProductBookingPrice)({
2227
+ ...params,
2228
+ product,
2229
+ fallback_price: authoritativeProduct ? void 0 : params.fallback_price,
2230
+ customer_id: customerId,
2231
+ quotation
2232
+ });
2233
+ }
2234
+ getQuotationCustomerScopeInfo() {
2235
+ const quotation = this.store.quotation;
2236
+ if (quotation && typeof quotation.getQuotationCustomerScopeInfo === "function") {
2237
+ return quotation.getQuotationCustomerScopeInfo();
2238
+ }
2239
+ const list = typeof (quotation == null ? void 0 : quotation.getQuotationList) === "function" ? quotation.getQuotationList() : [];
2240
+ const customerById = /* @__PURE__ */ new Map();
2241
+ const quotationScopes = (Array.isArray(list) ? list : []).filter((item) => Array.isArray(item == null ? void 0 : item.customer) && item.customer.length > 0).map((item) => {
2242
+ const localSeen = /* @__PURE__ */ new Set();
2243
+ const customers = item.customer.filter((customer) => {
2244
+ const customerId = this.normalizePriceContextCustomerId(customer == null ? void 0 : customer.id);
2245
+ if (!customerId || localSeen.has(customerId))
2246
+ return false;
2247
+ localSeen.add(customerId);
2248
+ if (!customerById.has(customerId))
2249
+ customerById.set(customerId, customer);
2250
+ return true;
2251
+ });
2252
+ return {
2253
+ quotationId: item.id,
2254
+ quotationName: item.name,
2255
+ customerIds: customers.map((customer) => String(customer.id)),
2256
+ customers
2257
+ };
2258
+ });
2259
+ return {
2260
+ quotationCount: Array.isArray(list) ? list.length : 0,
2261
+ hasCustomerScopedQuotations: quotationScopes.length > 0,
2262
+ allQuotationsCustomerScoped: Array.isArray(list) && list.length > 0 && quotationScopes.length === list.length,
2263
+ customerIds: Array.from(customerById.keys()),
2264
+ customers: Array.from(customerById.values()),
2265
+ quotationScopes
2266
+ };
2267
+ }
2268
+ shouldRecalculateProductBookingPricesForContextChange(params) {
2269
+ const scopeInfo = this.getQuotationCustomerScopeInfo();
2270
+ const scopedCustomerIds = new Set(scopeInfo.customerIds.map((id) => String(id)));
2271
+ const previousCustomerId = this.normalizePriceContextCustomerId(params.previousCustomerId);
2272
+ const nextCustomerId = this.normalizePriceContextCustomerId(params.nextCustomerId);
2273
+ const previousInScope = previousCustomerId ? scopedCustomerIds.has(previousCustomerId) : false;
2274
+ const nextInScope = nextCustomerId ? scopedCustomerIds.has(nextCustomerId) : false;
2275
+ let shouldRecalculate = false;
2276
+ if (scopeInfo.hasCustomerScopedQuotations) {
2277
+ if (previousInScope) {
2278
+ shouldRecalculate = true;
2279
+ } else if (!previousCustomerId && !nextInScope) {
2280
+ shouldRecalculate = false;
2281
+ } else {
2282
+ shouldRecalculate = nextInScope;
2283
+ }
2284
+ }
2285
+ return shouldRecalculate;
2286
+ }
2287
+ async calculateProductBookingPrices(paramsList) {
2288
+ var _a, _b;
2289
+ if (!paramsList.length)
2290
+ return [];
2291
+ const quotation = this.store.quotation;
2292
+ const customerId = ((_a = paramsList[0]) == null ? void 0 : _a.customer_id) ?? this.getCurrentOrderCustomerId();
2293
+ const productMapsByGroup = /* @__PURE__ */ new Map();
2294
+ const groups = /* @__PURE__ */ new Map();
2295
+ paramsList.forEach((params) => {
2296
+ var _a2;
2297
+ const product = params.product || {};
2298
+ const productId = this.getPriceQueryProductId(product);
2299
+ if (productId === null)
2300
+ return;
2301
+ const schedule = this.getPriceQuerySchedule(params);
2302
+ const channel = params.channel || ((_a2 = this.otherParams) == null ? void 0 : _a2.channel);
2303
+ const groupKey = [
2304
+ schedule.schedule_date,
2305
+ schedule.schedule_datetime,
2306
+ channel || ""
2307
+ ].join("|");
2308
+ const group = groups.get(groupKey) || {
2309
+ ids: /* @__PURE__ */ new Set(),
2310
+ schedule,
2311
+ channel
2312
+ };
2313
+ group.ids.add(productId);
2314
+ groups.set(groupKey, group);
2315
+ });
2316
+ await Promise.all(
2317
+ Array.from(groups.entries()).map(async ([groupKey, group]) => {
2318
+ const productsById = await this.loadProductsForPriceQuery({
2319
+ ids: Array.from(group.ids),
2320
+ schedule: group.schedule,
2321
+ customerId,
2322
+ channel: group.channel
2323
+ });
2324
+ productMapsByGroup.set(groupKey, productsById);
2325
+ })
2326
+ );
2327
+ await this.loadQuotationForPriceQuery({
2328
+ quotation,
2329
+ customer_id: customerId,
2330
+ channel: (_b = paramsList[0]) == null ? void 0 : _b.channel
2331
+ });
2332
+ return paramsList.map((params) => {
2333
+ var _a2, _b2;
2334
+ const productInput = params.product || {};
2335
+ const productId = this.getPriceQueryProductId(productInput);
2336
+ const schedule = this.getPriceQuerySchedule(params);
2337
+ const channel = params.channel || ((_a2 = this.otherParams) == null ? void 0 : _a2.channel);
2338
+ const groupKey = [
2339
+ schedule.schedule_date,
2340
+ schedule.schedule_datetime,
2341
+ channel || ""
2342
+ ].join("|");
2343
+ const authoritativeProduct = productId === null ? null : ((_b2 = productMapsByGroup.get(groupKey)) == null ? void 0 : _b2.get(productId)) || null;
2344
+ const product = this.mergeProductForPriceQuery(productInput, authoritativeProduct);
2345
+ return (0, import_quotationPrice.calculateBaseSalesProductBookingPrice)({
2346
+ ...params,
2347
+ product,
2348
+ fallback_price: authoritativeProduct ? void 0 : params.fallback_price,
2349
+ customer_id: customerId,
2350
+ quotation
2351
+ });
2352
+ });
2353
+ }
2354
+ async addProductToOrder(product, booking) {
2355
+ try {
2356
+ if (!this.store.order)
2357
+ throw new Error("order 模块未初始化");
2358
+ const products = await this.store.order.addProductToOrder(product, booking);
2359
+ return products;
2360
+ } catch (error) {
2361
+ throw error;
2362
+ }
2363
+ }
2364
+ async updateOrderProduct(params) {
2365
+ try {
2366
+ if (!this.store.order)
2367
+ throw new Error("order 模块未初始化");
2368
+ const products = await this.store.order.updateOrderProduct(params);
2369
+ return products;
2370
+ } catch (error) {
2371
+ throw error;
2372
+ }
2373
+ }
2374
+ async updateOrderProducts(paramsList) {
2375
+ try {
2376
+ if (!this.store.order)
2377
+ throw new Error("order 模块未初始化");
2378
+ const products = await this.store.order.updateOrderProducts(paramsList);
2379
+ return products;
2380
+ } catch (error) {
2381
+ throw error;
2382
+ }
2383
+ }
2384
+ async updateOrderProductQuantity(params) {
2385
+ try {
2386
+ if (!this.store.order)
2387
+ throw new Error("order 模块未初始化");
2388
+ const products = await this.store.order.updateOrderProductQuantity(params);
2389
+ return products;
2390
+ } catch (error) {
2391
+ throw error;
2392
+ }
2393
+ }
2394
+ updateOrderBooking(params) {
2395
+ try {
2396
+ if (!this.store.order)
2397
+ throw new Error("order 模块未初始化");
2398
+ return this.store.order.updateOrderBooking(params);
2399
+ } catch (error) {
2400
+ throw error;
2401
+ }
2402
+ }
2403
+ /**
2404
+ * 设置单行商品备注(与整单 `updateTempOrderNote` 区分)。
2405
+ * 多行同 SKU 时必须传入与删除/更新一致的 unique_identification_number。
2406
+ */
2407
+ async setOrderProductLineNote(identity, note) {
2408
+ try {
2409
+ const params = {
2410
+ product_id: identity.product_id,
2411
+ product_variant_id: identity.product_variant_id,
2412
+ updates: { note: String(note || "") }
2413
+ };
2414
+ if (identity.unique_identification_number !== void 0) {
2415
+ params.unique_identification_number = identity.unique_identification_number;
2416
+ }
2417
+ if (identity.product_sku !== void 0) {
2418
+ params.product_sku = identity.product_sku;
2419
+ }
2420
+ if (identity.product_bundle !== void 0)
2421
+ params.product_bundle = identity.product_bundle;
2422
+ const products = await this.updateOrderProduct(params);
2423
+ return products;
2424
+ } catch (error) {
2425
+ throw error;
2426
+ }
2427
+ }
2428
+ /**
2429
+ * 批量删除购物车行,末尾仅一次促销重算。
2430
+ *
2431
+ * @example
2432
+ * await baseSales.removeProductsFromOrder([identityA, identityB]);
2433
+ */
2434
+ async removeProductsFromOrder(identities) {
2435
+ try {
2436
+ if (!this.store.order)
2437
+ throw new Error("order 模块未初始化");
2438
+ return await this.store.order.removeProductsFromOrder(identities);
2439
+ } catch (error) {
2440
+ throw error;
2441
+ }
2442
+ }
2443
+ async removeProductFromOrder(identity) {
2444
+ return this.removeProductsFromOrder([identity]);
2445
+ }
2446
+ // ─── 促销/赠品 透传(迁移自 booking usePromotion) ────────────────
2447
+ /**
2448
+ * 注入促销评估器到底层 OrderModule。
2449
+ *
2450
+ * @example
2451
+ * solution.setPromotionEvaluator(appHelper.utils.promotionEvaluator);
2452
+ */
2453
+ setPromotionEvaluator(evaluator) {
2454
+ if (!this.store.order)
2455
+ throw new Error("order 模块未初始化");
2456
+ this.store.order.setPromotionEvaluator(evaluator);
2457
+ }
2458
+ /**
2459
+ * 注入赠品选择 resolver。UI 层(SalesSdk)通过 bridge 提供。
2460
+ *
2461
+ * @example
2462
+ * solution.setGiftSelectResolver(async (ctx) => bridge.request(ctx));
2463
+ */
2464
+ setGiftSelectResolver(resolver) {
2465
+ if (!this.store.order)
2466
+ throw new Error("order 模块未初始化");
2467
+ this.store.order.setGiftSelectResolver(resolver);
2468
+ }
2469
+ /**
2470
+ * 为商品目录追加促销标签,供 SalesSdkProductProvider 等商品列表入口复用。
2471
+ *
2472
+ * @example
2473
+ * const products = solution.appendPromotionTags(catalogProducts);
2474
+ */
2475
+ appendPromotionTags(products) {
2476
+ if (!this.store.order)
2477
+ throw new Error("order 模块未初始化");
2478
+ return this.store.order.appendPromotionTags(products);
2479
+ }
2480
+ /**
2481
+ * 主动触发一次促销应用(一般写路径会自动触发,少数场景如客户切换后可手动调)。
2482
+ */
2483
+ async applyPromotion() {
2484
+ if (!this.store.order)
2485
+ throw new Error("order 模块未初始化");
2486
+ await this.store.order.applyPromotion();
2487
+ }
2488
+ /** 最近一次促销计算输出的未满足提示。 */
2489
+ getUnfulfilledPromotions() {
2490
+ var _a;
2491
+ return ((_a = this.store.order) == null ? void 0 : _a.getUnfulfilledPromotions()) || [];
2492
+ }
2493
+ /** 最近一次促销计算输出的赠品操作 diff。 */
2494
+ getLastGiftActions() {
2495
+ var _a;
2496
+ return ((_a = this.store.order) == null ? void 0 : _a.getLastGiftActions()) || null;
2497
+ }
2498
+ // 获取商品列表
2499
+ // TODO 需要跟 webpos 内的对齐一下
2500
+ async getProductList() {
2501
+ var _a, _b, _c;
2502
+ const menu_list_ids = ((_b = (_a = this.otherParams) == null ? void 0 : _a.dineInConfig) == null ? void 0 : _b["menu.associated_menus"].map((n) => Number(n.value))) || [];
2503
+ try {
2504
+ const res = await ((_c = this.store.products) == null ? void 0 : _c.loadProducts({
2505
+ menu_list_ids,
2506
+ cacheId: this.cacheId,
2507
+ schedule_date: (0, import_dayjs.default)().format("YYYY-MM-DD"),
2508
+ schedule_datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
2509
+ }));
2510
+ return res;
2511
+ } catch (error) {
2512
+ throw error;
2513
+ }
2514
+ }
2515
+ getOtherParams() {
2516
+ return this.otherParams;
2517
+ }
2518
+ async setOtherParams(params, { cover = false } = {}) {
2519
+ var _a;
2520
+ if (cover) {
2521
+ this.otherParams = { ...params };
2522
+ } else {
2523
+ this.otherParams = { ...this.otherParams, ...params };
2524
+ }
2525
+ this.cacheId = (_a = this.otherParams) == null ? void 0 : _a.cacheId;
2526
+ await this.syncOtherParamsToSubModules(params, { cover });
2527
+ }
2528
+ };
2529
+ // Annotate the CommonJS export names for ESM import in node:
2530
+ 0 && (module.exports = {
2531
+ BaseSalesImpl,
2532
+ ...require("./types")
2533
+ });