@pisell/pisellos 2.2.311 → 2.2.312-vm.0

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 (303) hide show
  1. package/dist/apis/picoding.d.ts.map +1 -0
  2. package/dist/core/index.d.ts.map +1 -0
  3. package/dist/effects/index.d.ts.map +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +1 -0
  7. package/dist/inventory/index.d.ts +92 -0
  8. package/dist/inventory/index.d.ts.map +1 -0
  9. package/dist/inventory/index.js +509 -0
  10. package/dist/model/index.d.ts.map +1 -0
  11. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts.map +1 -0
  12. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts.map +1 -0
  13. package/dist/model/strategy/adapter/dataVariant/examples.d.ts.map +1 -0
  14. package/dist/model/strategy/adapter/dataVariant/index.d.ts.map +1 -0
  15. package/dist/model/strategy/adapter/dataVariant/type.d.ts.map +1 -0
  16. package/dist/model/strategy/adapter/index.d.ts.map +1 -0
  17. package/dist/model/strategy/adapter/itemRule/adapter.d.ts.map +1 -0
  18. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts.map +1 -0
  19. package/dist/model/strategy/adapter/itemRule/examples.d.ts.map +1 -0
  20. package/dist/model/strategy/adapter/itemRule/index.d.ts.map +1 -0
  21. package/dist/model/strategy/adapter/itemRule/type.d.ts.map +1 -0
  22. package/dist/model/strategy/adapter/promotion/adapter.d.ts.map +1 -0
  23. package/dist/model/strategy/adapter/promotion/evaluator.d.ts.map +1 -0
  24. package/dist/model/strategy/adapter/promotion/examples.d.ts.map +1 -0
  25. package/dist/model/strategy/adapter/promotion/index.d.ts.map +1 -0
  26. package/dist/model/strategy/adapter/promotion/type.d.ts.map +1 -0
  27. package/dist/model/strategy/adapter/type.d.ts.map +1 -0
  28. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts.map +1 -0
  29. package/dist/model/strategy/adapter/walletPass/example.d.ts.map +1 -0
  30. package/dist/model/strategy/adapter/walletPass/index.d.ts.map +1 -0
  31. package/dist/model/strategy/adapter/walletPass/locales.d.ts.map +1 -0
  32. package/dist/model/strategy/adapter/walletPass/type.d.ts.map +1 -0
  33. package/dist/model/strategy/adapter/walletPass/utils.d.ts.map +1 -0
  34. package/dist/model/strategy/engine.d.ts.map +1 -0
  35. package/dist/model/strategy/index.d.ts.map +1 -0
  36. package/dist/model/strategy/strategy-example.d.ts.map +1 -0
  37. package/dist/model/strategy/type.d.ts.map +1 -0
  38. package/dist/modules/Account/index.d.ts.map +1 -0
  39. package/dist/modules/Account/types.d.ts.map +1 -0
  40. package/dist/modules/AccountList/index.d.ts.map +1 -0
  41. package/dist/modules/AccountList/types.d.ts.map +1 -0
  42. package/dist/modules/AccountList/utils.d.ts.map +1 -0
  43. package/dist/modules/BaseModule.d.ts.map +1 -0
  44. package/dist/modules/BookingContext/index.d.ts.map +1 -0
  45. package/dist/modules/BookingContext/types.d.ts.map +1 -0
  46. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts.map +1 -0
  47. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts.map +1 -0
  48. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts.map +1 -0
  49. package/dist/modules/BookingContext/utils/flexible.d.ts.map +1 -0
  50. package/dist/modules/BookingContext/utils/formatResourceList.d.ts.map +1 -0
  51. package/dist/modules/BookingContext/utils/index.d.ts.map +1 -0
  52. package/dist/modules/BookingContext/utils/noResource.d.ts.map +1 -0
  53. package/dist/modules/BookingContext/utils/orderLineDisplay.d.ts.map +1 -0
  54. package/dist/modules/BookingContext/utils/productExtend.d.ts.map +1 -0
  55. package/dist/modules/BookingContext/utils/resourceErrors.d.ts.map +1 -0
  56. package/dist/modules/BookingContext/utils/resourceSelection.d.ts.map +1 -0
  57. package/dist/modules/BookingContext/utils/resources.d.ts.map +1 -0
  58. package/dist/modules/BookingContext/utils/serviceTimes.d.ts.map +1 -0
  59. package/dist/modules/BookingContext/utils/timeSlices.d.ts.map +1 -0
  60. package/dist/modules/Cart/index.d.ts.map +1 -0
  61. package/dist/modules/Cart/types.d.ts.map +1 -0
  62. package/dist/modules/Cart/utils/cartAccount.d.ts.map +1 -0
  63. package/dist/modules/Cart/utils/cartDate.d.ts.map +1 -0
  64. package/dist/modules/Cart/utils/cartDiscount.d.ts.map +1 -0
  65. package/dist/modules/Cart/utils/cartNote.d.ts.map +1 -0
  66. package/dist/modules/Cart/utils/cartProduct.d.ts.map +1 -0
  67. package/dist/modules/Cart/utils/cartRelationForms.d.ts.map +1 -0
  68. package/dist/modules/Cart/utils/cartResource.d.ts.map +1 -0
  69. package/dist/modules/Cart/utils/changePrice.d.ts.map +1 -0
  70. package/dist/modules/Cart/utils/index.d.ts.map +1 -0
  71. package/dist/modules/Customer/constants.d.ts.map +1 -0
  72. package/dist/modules/Customer/index.d.ts.map +1 -0
  73. package/dist/modules/Customer/types.d.ts.map +1 -0
  74. package/dist/modules/Date/index.d.ts.map +1 -0
  75. package/dist/modules/Date/types.d.ts.map +1 -0
  76. package/dist/modules/Date/utils.d.ts.map +1 -0
  77. package/dist/modules/Discount/availability.d.ts.map +1 -0
  78. package/dist/modules/Discount/entitlementPass.d.ts.map +1 -0
  79. package/dist/modules/Discount/index.d.ts.map +1 -0
  80. package/dist/modules/Discount/index.js +1 -0
  81. package/dist/modules/Discount/types.d.ts.map +1 -0
  82. package/dist/modules/Guests/index.d.ts.map +1 -0
  83. package/dist/modules/Guests/types.d.ts.map +1 -0
  84. package/dist/modules/Holder/index.d.ts.map +1 -0
  85. package/dist/modules/Holder/types.d.ts.map +1 -0
  86. package/dist/modules/Holder/utils.d.ts.map +1 -0
  87. package/dist/modules/OpenData/index.d.ts.map +1 -0
  88. package/dist/modules/OpenData/types.d.ts.map +1 -0
  89. package/dist/modules/OpenData/utils.d.ts.map +1 -0
  90. package/dist/modules/Order/index.d.ts +25 -3
  91. package/dist/modules/Order/index.d.ts.map +1 -0
  92. package/dist/modules/Order/index.js +1647 -1211
  93. package/dist/modules/Order/payment-utils.d.ts.map +1 -0
  94. package/dist/modules/Order/salesNotes.d.ts.map +1 -0
  95. package/dist/modules/Order/types.d.ts +7 -0
  96. package/dist/modules/Order/types.d.ts.map +1 -0
  97. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts.map +1 -0
  98. package/dist/modules/Order/utils/discountProductLineIdentity.d.ts.map +1 -0
  99. package/dist/modules/Order/utils/discountProductLineIdentity.js +2 -2
  100. package/dist/modules/Order/utils/manualProductDiscount.d.ts.map +1 -0
  101. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts.map +1 -0
  102. package/dist/modules/Order/utils/productVoucherGroups.d.ts +15 -0
  103. package/dist/modules/Order/utils/productVoucherGroups.d.ts.map +1 -0
  104. package/dist/modules/Order/utils/productVoucherGroups.js +115 -0
  105. package/dist/modules/Order/utils/virtualSettlement.d.ts.map +1 -0
  106. package/dist/modules/Order/utils/weighedProduct.d.ts.map +1 -0
  107. package/dist/modules/Order/utils.d.ts.map +1 -0
  108. package/dist/modules/Payment/cash.d.ts.map +1 -0
  109. package/dist/modules/Payment/cashRecommendationAlgorithm.d.ts.map +1 -0
  110. package/dist/modules/Payment/eftpos.d.ts.map +1 -0
  111. package/dist/modules/Payment/index.d.ts.map +1 -0
  112. package/dist/modules/Payment/mx51.d.ts.map +1 -0
  113. package/dist/modules/Payment/types.d.ts.map +1 -0
  114. package/dist/modules/Payment/utils.d.ts.map +1 -0
  115. package/dist/modules/Payment/walletpass.d.ts.map +1 -0
  116. package/dist/modules/Product/index.d.ts.map +1 -0
  117. package/dist/modules/Product/types.d.ts.map +1 -0
  118. package/dist/modules/Product/utils.d.ts.map +1 -0
  119. package/dist/modules/ProductList/clientDataVariants.d.ts.map +1 -0
  120. package/dist/modules/ProductList/index.d.ts.map +1 -0
  121. package/dist/modules/ProductList/index.js +33 -12
  122. package/dist/modules/ProductList/types.d.ts.map +1 -0
  123. package/dist/modules/Quotation/index.d.ts.map +1 -0
  124. package/dist/modules/Quotation/types.d.ts.map +1 -0
  125. package/dist/modules/Resource/index.d.ts.map +1 -0
  126. package/dist/modules/Resource/types.d.ts.map +1 -0
  127. package/dist/modules/Resource/utils.d.ts.map +1 -0
  128. package/dist/modules/ResourcePlanner/index.d.ts.map +1 -0
  129. package/dist/modules/ResourcePlanner/localClock.d.ts.map +1 -0
  130. package/dist/modules/ResourcePlanner/planner.d.ts.map +1 -0
  131. package/dist/modules/ResourcePlanner/types.d.ts.map +1 -0
  132. package/dist/modules/Rules/index.d.ts +2 -0
  133. package/dist/modules/Rules/index.d.ts.map +1 -0
  134. package/dist/modules/Rules/index.js +29 -21
  135. package/dist/modules/Rules/types.d.ts.map +1 -0
  136. package/dist/modules/SalesSummary/index.d.ts.map +1 -0
  137. package/dist/modules/SalesSummary/types.d.ts.map +1 -0
  138. package/dist/modules/SalesSummary/utils.d.ts.map +1 -0
  139. package/dist/modules/ScanOrderLogger/index.d.ts.map +1 -0
  140. package/dist/modules/ScanOrderLogger/providers/feishu.d.ts.map +1 -0
  141. package/dist/modules/ScanOrderLogger/providers/grafana.d.ts.map +1 -0
  142. package/dist/modules/ScanOrderLogger/types.d.ts.map +1 -0
  143. package/dist/modules/Schedule/getDateIsInSchedule.d.ts.map +1 -0
  144. package/dist/modules/Schedule/index.d.ts.map +1 -0
  145. package/dist/modules/Schedule/type.d.ts.map +1 -0
  146. package/dist/modules/Schedule/types.d.ts.map +1 -0
  147. package/dist/modules/Schedule/utils.d.ts.map +1 -0
  148. package/dist/modules/Step/index.d.ts.map +1 -0
  149. package/dist/modules/Step/tyeps.d.ts.map +1 -0
  150. package/dist/modules/Summary/index.d.ts.map +1 -0
  151. package/dist/modules/Summary/types.d.ts.map +1 -0
  152. package/dist/modules/Summary/utils.d.ts.map +1 -0
  153. package/dist/modules/SurchargeList/index.d.ts.map +1 -0
  154. package/dist/modules/SurchargeList/types.d.ts.map +1 -0
  155. package/dist/modules/index.d.ts.map +1 -0
  156. package/dist/plugins/app.d.ts.map +1 -0
  157. package/dist/plugins/index.d.ts.map +1 -0
  158. package/dist/plugins/request.d.ts.map +1 -0
  159. package/dist/plugins/shopStore.d.ts.map +1 -0
  160. package/dist/plugins/user.d.ts.map +1 -0
  161. package/dist/plugins/window.d.ts.map +1 -0
  162. package/dist/server/index.d.ts.map +1 -0
  163. package/dist/server/modules/floor-plan/index.d.ts.map +1 -0
  164. package/dist/server/modules/floor-plan/types.d.ts.map +1 -0
  165. package/dist/server/modules/index.d.ts.map +1 -0
  166. package/dist/server/modules/menu/index.d.ts.map +1 -0
  167. package/dist/server/modules/menu/types.d.ts.map +1 -0
  168. package/dist/server/modules/order/index.d.ts.map +1 -0
  169. package/dist/server/modules/order/types.d.ts.map +1 -0
  170. package/dist/server/modules/order/utils/filterBookings.d.ts.map +1 -0
  171. package/dist/server/modules/order/utils/filterOrders.d.ts.map +1 -0
  172. package/dist/server/modules/payment/index.d.ts.map +1 -0
  173. package/dist/server/modules/payment/types.d.ts.map +1 -0
  174. package/dist/server/modules/products/index.d.ts.map +1 -0
  175. package/dist/server/modules/products/types.d.ts.map +1 -0
  176. package/dist/server/modules/quotation/index.d.ts.map +1 -0
  177. package/dist/server/modules/quotation/types.d.ts.map +1 -0
  178. package/dist/server/modules/resource/index.d.ts.map +1 -0
  179. package/dist/server/modules/resource/types.d.ts.map +1 -0
  180. package/dist/server/modules/schedule/index.d.ts.map +1 -0
  181. package/dist/server/modules/schedule/types.d.ts.map +1 -0
  182. package/dist/server/modules/schedule/utils.d.ts.map +1 -0
  183. package/dist/server/types.d.ts.map +1 -0
  184. package/dist/server/utils/index.d.ts.map +1 -0
  185. package/dist/server/utils/product.d.ts.map +1 -0
  186. package/dist/server/utils/schedule.d.ts.map +1 -0
  187. package/dist/server/utils/small-ticket.d.ts.map +1 -0
  188. package/dist/server/utils/time.d.ts.map +1 -0
  189. package/dist/solution/BaseSales/index.d.ts +16 -1
  190. package/dist/solution/BaseSales/index.d.ts.map +1 -0
  191. package/dist/solution/BaseSales/index.js +1363 -1176
  192. package/dist/solution/BaseSales/types.d.ts.map +1 -0
  193. package/dist/solution/BaseSales/utils/cartPromotion.d.ts.map +1 -0
  194. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts.map +1 -0
  195. package/dist/solution/BaseSales/utils/quotationPrice.d.ts.map +1 -0
  196. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts.map +1 -0
  197. package/dist/solution/BaseSales/utils.d.ts.map +1 -0
  198. package/dist/solution/BookingByStep/index.d.ts.map +1 -0
  199. package/dist/solution/BookingByStep/types.d.ts.map +1 -0
  200. package/dist/solution/BookingByStep/utils/capacity.d.ts.map +1 -0
  201. package/dist/solution/BookingByStep/utils/products.d.ts.map +1 -0
  202. package/dist/solution/BookingByStep/utils/resources.d.ts.map +1 -0
  203. package/dist/solution/BookingByStep/utils/stock.d.ts.map +1 -0
  204. package/dist/solution/BookingByStep/utils/timeslots.d.ts.map +1 -0
  205. package/dist/solution/BookingTicket/index.d.ts.map +1 -0
  206. package/dist/solution/BookingTicket/index.js +198 -108
  207. package/dist/solution/BookingTicket/types.d.ts +14 -2
  208. package/dist/solution/BookingTicket/types.d.ts.map +1 -0
  209. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +1 -1
  210. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts.map +1 -0
  211. package/dist/solution/BookingTicket/utils/addProductDecision.js +4 -3
  212. package/dist/solution/BookingTicket/utils/addTimeAvailability.d.ts.map +1 -0
  213. package/dist/solution/BookingTicket/utils/bookingStatus.d.ts.map +1 -0
  214. package/dist/solution/BookingTicket/utils/cartView.d.ts.map +1 -0
  215. package/dist/solution/BookingTicket/utils/exampleData.d.ts.map +1 -0
  216. package/dist/solution/BookingTicket/utils/orderCustomer.d.ts.map +1 -0
  217. package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts.map +1 -0
  218. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts.map +1 -0
  219. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +94 -58
  220. package/dist/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.d.ts +10 -0
  221. package/dist/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.d.ts.map +1 -0
  222. package/dist/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.js +117 -0
  223. package/dist/solution/BookingTicket/utils/scan/cloudSearch.d.ts.map +1 -0
  224. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +1 -0
  225. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts.map +1 -0
  226. package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts.map +1 -0
  227. package/dist/solution/BookingTicket/utils/scan/handleScan.js +2 -1
  228. package/dist/solution/BookingTicket/utils/scan/index.d.ts.map +1 -0
  229. package/dist/solution/BookingTicket/utils/scan/scanCache.d.ts.map +1 -0
  230. package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts.map +1 -0
  231. package/dist/solution/BookingTicket/utils/sessionCatalogStale.d.ts.map +1 -0
  232. package/dist/solution/BookingTicket/utils/weighingProductSku.d.ts.map +1 -0
  233. package/dist/solution/BuyTickets/index.d.ts.map +1 -0
  234. package/dist/solution/BuyTickets/types.d.ts.map +1 -0
  235. package/dist/solution/Checkout/index.d.ts.map +1 -0
  236. package/dist/solution/Checkout/types.d.ts.map +1 -0
  237. package/dist/solution/Checkout/utils/index.d.ts.map +1 -0
  238. package/dist/solution/PlaceOrder/index.d.ts.map +1 -0
  239. package/dist/solution/RegisterAndLogin/config.d.ts.map +1 -0
  240. package/dist/solution/RegisterAndLogin/index.d.ts.map +1 -0
  241. package/dist/solution/RegisterAndLogin/types.d.ts.map +1 -0
  242. package/dist/solution/RegisterAndLogin/utils.d.ts.map +1 -0
  243. package/dist/solution/Sales/index.d.ts.map +1 -0
  244. package/dist/solution/Sales/types.d.ts.map +1 -0
  245. package/dist/solution/ScanOrder/index.d.ts.map +1 -0
  246. package/dist/solution/ScanOrder/types.d.ts.map +1 -0
  247. package/dist/solution/ScanOrder/utils.d.ts.map +1 -0
  248. package/dist/solution/ShopDiscount/index.d.ts.map +1 -0
  249. package/dist/solution/ShopDiscount/types.d.ts.map +1 -0
  250. package/dist/solution/ShopDiscount/utils.d.ts.map +1 -0
  251. package/dist/solution/UnifiedBookingSales/index.d.ts +1 -1
  252. package/dist/solution/UnifiedBookingSales/index.d.ts.map +1 -0
  253. package/dist/solution/UnifiedBookingSales/index.js +63 -43
  254. package/dist/solution/UnifiedBookingSales/remoteOccupancyCache.d.ts.map +1 -0
  255. package/dist/solution/UnifiedBookingSales/types.d.ts.map +1 -0
  256. package/dist/solution/VenueBooking/index.d.ts.map +1 -0
  257. package/dist/solution/VenueBooking/types.d.ts.map +1 -0
  258. package/dist/solution/VenueBooking/utils/dateSummary.d.ts.map +1 -0
  259. package/dist/solution/VenueBooking/utils/resource.d.ts.map +1 -0
  260. package/dist/solution/VenueBooking/utils/slotMerge.d.ts.map +1 -0
  261. package/dist/solution/VenueBooking/utils/timeSlot.d.ts.map +1 -0
  262. package/dist/solution/VenueBooking/utils.d.ts.map +1 -0
  263. package/dist/solution/index.d.ts.map +1 -0
  264. package/dist/store/createStore.d.ts.map +1 -0
  265. package/dist/types/index.d.ts.map +1 -0
  266. package/dist/utils/os-private-payload.d.ts.map +1 -0
  267. package/dist/utils/payment-number.d.ts.map +1 -0
  268. package/dist/utils/platform.d.ts +2 -0
  269. package/dist/utils/platform.d.ts.map +1 -0
  270. package/dist/utils/platform.js +6 -0
  271. package/dist/utils/task.d.ts.map +1 -0
  272. package/dist/utils/watch.d.ts.map +1 -0
  273. package/lib/index.d.ts +1 -0
  274. package/lib/index.js +12 -0
  275. package/lib/inventory/index.d.ts +92 -0
  276. package/lib/inventory/index.js +287 -0
  277. package/lib/model/strategy/adapter/promotion/index.js +46 -1
  278. package/lib/modules/Discount/index.js +1 -0
  279. package/lib/modules/Order/index.d.ts +25 -3
  280. package/lib/modules/Order/index.js +145 -11
  281. package/lib/modules/Order/types.d.ts +7 -0
  282. package/lib/modules/Order/utils/discountProductLineIdentity.js +1 -1
  283. package/lib/modules/Order/utils/productVoucherGroups.d.ts +15 -0
  284. package/lib/modules/Order/utils/productVoucherGroups.js +64 -0
  285. package/lib/modules/ProductList/index.js +15 -0
  286. package/lib/modules/Rules/index.d.ts +2 -0
  287. package/lib/modules/Rules/index.js +6 -0
  288. package/lib/solution/BaseSales/index.d.ts +16 -1
  289. package/lib/solution/BaseSales/index.js +89 -9
  290. package/lib/solution/BookingTicket/index.js +36 -2
  291. package/lib/solution/BookingTicket/types.d.ts +14 -2
  292. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +1 -1
  293. package/lib/solution/BookingTicket/utils/addProductDecision.js +4 -3
  294. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +14 -2
  295. package/lib/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.d.ts +10 -0
  296. package/lib/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.js +71 -0
  297. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +1 -0
  298. package/lib/solution/BookingTicket/utils/scan/handleScan.js +2 -1
  299. package/lib/solution/UnifiedBookingSales/index.d.ts +1 -1
  300. package/lib/solution/UnifiedBookingSales/index.js +14 -3
  301. package/lib/utils/platform.d.ts +2 -0
  302. package/lib/utils/platform.js +7 -0
  303. package/package.json +4 -2
@@ -11,6 +11,7 @@ var _utils2 = require("../Product/utils");
11
11
  var _weighedProduct = require("./utils/weighedProduct");
12
12
  var _dayjs = _interopRequireDefault(require("dayjs"));
13
13
  var _availability = require("../Discount/availability");
14
+ var _productVoucherGroups = require("./utils/productVoucherGroups");
14
15
  var _osPrivatePayload = require("../../utils/os-private-payload");
15
16
  var _salesNotes = require("./salesNotes");
16
17
  var _paymentUtils = require("./payment-utils");
@@ -137,6 +138,62 @@ class OrderModule extends _BaseModule.BaseModule {
137
138
  rulesHooksOverride;
138
139
  moduleHooksOverride;
139
140
  orderHooks;
141
+ cartCommandQueue = Promise.resolve();
142
+ queueCartCommand(run) {
143
+ if (!this.orderHooks?.onBeforeCartCommit && !this.store.tempOrder?._extend?.productVoucherGroups?.length) return run();
144
+ const pending = this.cartCommandQueue.then(run, run);
145
+ this.cartCommandQueue = pending.catch(() => undefined);
146
+ return pending;
147
+ }
148
+
149
+ /** Use the exact Order normalizers/merge rules on a private draft, not a second projection. */
150
+ beginCartMutation() {
151
+ const current = this.ensureTempOrder();
152
+ const guard = this.orderHooks?.onBeforeCartCommit;
153
+ if (!guard && !current._extend?.productVoucherGroups?.length) return {
154
+ draft: current,
155
+ commit: undefined
156
+ };
157
+ const before = (0, _lodashEs.cloneDeep)(current);
158
+ const draft = (0, _lodashEs.cloneDeep)(current);
159
+ return {
160
+ draft,
161
+ commit: async () => {
162
+ (0, _productVoucherGroups.validateProductVoucherGroups)(draft, this.getDiscountList(), before);
163
+ await guard?.({
164
+ currentItems: (0, _lodashEs.cloneDeep)(before.products),
165
+ proposedItems: (0, _lodashEs.cloneDeep)(draft.products)
166
+ });
167
+ if (this.store.tempOrder !== current || guard !== this.orderHooks?.onBeforeCartCommit || !(0, _lodashEs.isEqual)(current, before)) {
168
+ throw Object.assign(new Error('The cart changed. Please try again.'), {
169
+ code: 'SALES_GUARD_REJECTED'
170
+ });
171
+ }
172
+ Object.assign(current, draft);
173
+ return current;
174
+ }
175
+ };
176
+ }
177
+
178
+ /** Serializes checkout preparation with local cart commands; hydration remains outside this guard. */
179
+ async prepareCheckout(prepare) {
180
+ const run = async () => {
181
+ const order = this.ensureTempOrder();
182
+ (0, _productVoucherGroups.validateProductVoucherGroups)(order, this.getDiscountList(), undefined, true);
183
+ const items = (0, _lodashEs.cloneDeep)(order.products);
184
+ const result = await prepare(items);
185
+ if (this.store.tempOrder !== order || !(0, _lodashEs.isEqual)(order.products, items)) {
186
+ throw Object.assign(new Error('The cart changed. Please try again.'), {
187
+ code: 'SALES_GUARD_REJECTED'
188
+ });
189
+ }
190
+ (0, _productVoucherGroups.validateProductVoucherGroups)(order, this.getDiscountList(), undefined, true);
191
+ return result;
192
+ };
193
+ const pending = this.cartCommandQueue.then(run, run);
194
+ this.cartCommandQueue = pending.catch(() => undefined);
195
+ return pending;
196
+ }
140
197
  otherParams;
141
198
  // ─── 促销/赠品 ────────────────────────────────────
142
199
  /** 评估器引用;由 SalesSdkProvider 注入,未注入时 applyPromotion 静默跳过 */
@@ -424,8 +481,11 @@ class OrderModule extends _BaseModule.BaseModule {
424
481
  * @example
425
482
  * orderModule.updateOtherParams({ cacheId: 'cache-2', channel: 'pos' });
426
483
  */
427
- updateOtherParams(params) {
484
+ updateOtherParams(params, options) {
428
485
  const otherParams = params || {};
486
+ if (options && Object.prototype.hasOwnProperty.call(options, 'hooks')) {
487
+ this.moduleHooksOverride = options.hooks;
488
+ }
429
489
  this.syncSessionStorageOptions(otherParams);
430
490
  this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
431
491
  this.rulesHooksOverride = otherParams.rules?.hooks;
@@ -509,6 +569,26 @@ class OrderModule extends _BaseModule.BaseModule {
509
569
  hooks: this.rulesHooksOverride || this.createDefaultRulesHooks()
510
570
  });
511
571
  this.store.rules = rules;
572
+ rules.setDiscountScope((product, discount) => (0, _productVoucherGroups.allowsProductVoucher)(this.store.tempOrder, product, discount));
573
+ }
574
+ setProductVoucherGroups(groups) {
575
+ const order = this.ensureTempOrder();
576
+ const ids = new Set();
577
+ const keys = new Set();
578
+ const known = new Map(this.getDiscountList().map(discount => [String(discount.id), discount]));
579
+ for (const group of groups) {
580
+ if (!group.key || keys.has(group.key)) throw (0, _productVoucherGroups.voucherGroupError)();
581
+ keys.add(group.key);
582
+ for (const id of group.discountIds) {
583
+ const discount = known.get(String(id));
584
+ if (!discount || (discount.tag || discount.type) !== 'good_pass' || ids.has(String(id))) throw (0, _productVoucherGroups.voucherGroupError)();
585
+ ids.add(String(id));
586
+ }
587
+ }
588
+ this.ensureExtend(order).productVoucherGroups = (0, _lodashEs.cloneDeep)(groups);
589
+ }
590
+ validateProductVoucherSelection() {
591
+ (0, _productVoucherGroups.validateProductVoucherGroups)(this.ensureTempOrder(), this.getDiscountList(), undefined, true);
512
592
  }
513
593
  createDefaultRulesHooks() {
514
594
  return (0, _utils.createDefaultOrderRulesHooks)(() => this.store.tempOrder?.bookings || []);
@@ -660,7 +740,7 @@ class OrderModule extends _BaseModule.BaseModule {
660
740
  apply: false
661
741
  });
662
742
  }
663
- async scanCode(code, customerId) {
743
+ async scanCode(code, customerId, options) {
664
744
  if (this.isActiveVirtualSettlementOrder(this.store.tempOrder)) {
665
745
  return {
666
746
  type: 'clientCalc',
@@ -671,16 +751,22 @@ class OrderModule extends _BaseModule.BaseModule {
671
751
  unavailableReason: _types2.UnavailableReason.ProductNotApplicable
672
752
  };
673
753
  }
754
+ const scanOrderKey = this.getDiscountConfigOrderIdentityKey(this.store.tempOrder);
674
755
  const resultDiscountWithReason = (await this.store.discount?.batchSearch(code, {
675
756
  customerId
676
757
  })) || {
677
758
  discountList: [],
678
759
  unavailableReasonKey: null
679
760
  };
761
+ if (scanOrderKey !== this.getDiscountConfigOrderIdentityKey(this.store.tempOrder)) {
762
+ throw Object.assign(new Error('The scan session ended.'), {
763
+ code: 'SALES_GUARD_REJECTED'
764
+ });
765
+ }
680
766
  const {
681
- discountList: resultDiscountList,
682
767
  unavailableReasonKey
683
768
  } = resultDiscountWithReason;
769
+ const resultDiscountList = resultDiscountWithReason.discountList.filter(discount => !options?.productVouchersOnly || (discount.tag || discount.type) === 'good_pass');
684
770
  const rulesModule = this.store.rules;
685
771
  if (!rulesModule) {
686
772
  return {
@@ -707,7 +793,7 @@ class OrderModule extends _BaseModule.BaseModule {
707
793
  isScan: true
708
794
  }));
709
795
  const currentSelected = this.getDiscountList().filter(n => n.isSelected);
710
- if (currentSelected.length && currentSelected.some(n => withScanList.some(m => m.id === n.id))) {
796
+ if (currentSelected.length && (options?.productVouchersOnly ? withScanList.every(scanned => currentSelected.some(selected => selected.id === scanned.id)) : currentSelected.some(n => withScanList.some(m => m.id === n.id)))) {
711
797
  await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
712
798
  return {
713
799
  type: 'clientCalc',
@@ -2196,8 +2282,12 @@ class OrderModule extends _BaseModule.BaseModule {
2196
2282
  ...existed,
2197
2283
  ...(origin !== undefined ? {
2198
2284
  origin
2285
+ } : {}),
2286
+ ...(rawProduct._productVoucherGroupKey ? {
2287
+ productVoucherGroupKey: rawProduct._productVoucherGroupKey
2199
2288
  } : {})
2200
2289
  };
2290
+ delete normalizedProduct._productVoucherGroupKey;
2201
2291
  delete normalizedProduct._origin;
2202
2292
  delete normalizedProduct.unique_identification_number;
2203
2293
  }
@@ -3463,6 +3553,7 @@ class OrderModule extends _BaseModule.BaseModule {
3463
3553
  const isIncomingCustomItem = productToAdd.metadata?.origin?.isCustomItem === true || productToAdd._origin?.isCustomItem === true;
3464
3554
  const shouldForceNewLine = disableMerge || !!booking || hasIncomingGoodPass || isIncomingPersistedEntitlementPass || hasIncomingBookingUid || isIncomingCustomItem || isWeighingProduct;
3465
3555
  const matchedIndex = shouldForceNewLine ? -1 : tempOrder.products.findIndex(item => {
3556
+ if ((0, _productVoucherGroups.productVoucherGroupKey)(tempOrder, item) !== productToAdd._productVoucherGroupKey) return false;
3466
3557
  if (this.hasGoodPassDiscount(item)) return false;
3467
3558
  const isRuntimeEntitlementPass = this.isRuntimeEntitlementAppend(item, tempOrder);
3468
3559
  if (isIncomingEntitlementAppend !== isRuntimeEntitlementPass) {
@@ -3642,7 +3733,18 @@ class OrderModule extends _BaseModule.BaseModule {
3642
3733
  * // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
3643
3734
  */
3644
3735
  async addProductToOrder(product, booking, options) {
3645
- const tempOrder = this.ensureTempOrder();
3736
+ return this.queueCartCommand(() => this.addProductToOrderDraft(product, booking, options));
3737
+ }
3738
+ async addProductToOrderDraft(product, booking, options) {
3739
+ const mutation = this.beginCartMutation();
3740
+ let tempOrder = mutation.draft;
3741
+ if (options?.productVoucherGroupKey) {
3742
+ if (!tempOrder._extend?.productVoucherGroups?.some(group => group.key === options.productVoucherGroupKey)) throw (0, _productVoucherGroups.voucherGroupError)();
3743
+ product = {
3744
+ ...product,
3745
+ _productVoucherGroupKey: options.productVoucherGroupKey
3746
+ };
3747
+ }
3646
3748
  const salesNoteDrafts = (options?.salesNotes || []).map(draft => ({
3647
3749
  note_type: String(draft.note_type || '').trim(),
3648
3750
  text: {
@@ -3736,6 +3838,7 @@ class OrderModule extends _BaseModule.BaseModule {
3736
3838
  rollbackProductAndNotesMutation();
3737
3839
  throw error;
3738
3840
  }
3841
+ if (mutation.commit) tempOrder = await mutation.commit();
3739
3842
  await this.finalizeProductOrderMutation(tempOrder);
3740
3843
  this.logInfo('addProductToOrder success', {
3741
3844
  product_id: product.product_id,
@@ -3754,7 +3857,11 @@ class OrderModule extends _BaseModule.BaseModule {
3754
3857
  * ]);
3755
3858
  */
3756
3859
  async addProductsToOrder(items, options) {
3757
- const tempOrder = this.ensureTempOrder();
3860
+ return this.queueCartCommand(() => this.addProductsToOrderDraft(items, options));
3861
+ }
3862
+ async addProductsToOrderDraft(items, options) {
3863
+ const mutation = this.beginCartMutation();
3864
+ let tempOrder = mutation.draft;
3758
3865
  if (!Array.isArray(items) || items.length === 0) return tempOrder.products;
3759
3866
  for (const item of items || []) {
3760
3867
  const {
@@ -3777,6 +3884,7 @@ class OrderModule extends _BaseModule.BaseModule {
3777
3884
  const appendResult = this.appendProductLineToTempOrder(tempOrder, product, booking);
3778
3885
  if (appendResult) await appendResult;
3779
3886
  }
3887
+ if (mutation.commit) tempOrder = await mutation.commit();
3780
3888
  await this.finalizeProductOrderMutation(tempOrder, options);
3781
3889
  this.logInfo('addProductsToOrder success', {
3782
3890
  itemsCount: items.length
@@ -4109,9 +4217,14 @@ class OrderModule extends _BaseModule.BaseModule {
4109
4217
  return tempOrder.products[productIndex].metadata?.unique_identification_number;
4110
4218
  }
4111
4219
  async updateOrderProduct(params) {
4112
- const tempOrder = this.ensureTempOrder();
4220
+ return this.queueCartCommand(() => this.updateOrderProductDraft(params));
4221
+ }
4222
+ async updateOrderProductDraft(params) {
4223
+ const mutation = this.beginCartMutation();
4224
+ let tempOrder = mutation.draft;
4113
4225
  const reapplyWeighedDiscountProductUids = [];
4114
4226
  const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params, reapplyWeighedDiscountProductUids);
4227
+ if (mutation.commit) tempOrder = await mutation.commit();
4115
4228
  const promotionPayload = await this.evaluatePromotion();
4116
4229
  this.applyDiscount({
4117
4230
  reapplyWeighedDiscountProductUids,
@@ -4129,7 +4242,11 @@ class OrderModule extends _BaseModule.BaseModule {
4129
4242
  return tempOrder.products;
4130
4243
  }
4131
4244
  async updateOrderProducts(paramsList) {
4132
- const tempOrder = this.ensureTempOrder();
4245
+ return this.queueCartCommand(() => this.updateOrderProductsDraft(paramsList));
4246
+ }
4247
+ async updateOrderProductsDraft(paramsList) {
4248
+ const mutation = this.beginCartMutation();
4249
+ let tempOrder = mutation.draft;
4133
4250
  if (!paramsList.length) {
4134
4251
  return tempOrder.products;
4135
4252
  }
@@ -4142,6 +4259,7 @@ class OrderModule extends _BaseModule.BaseModule {
4142
4259
  }
4143
4260
  return acc;
4144
4261
  }, []);
4262
+ if (mutation.commit) tempOrder = await mutation.commit();
4145
4263
  await this.finalizeAfterProductsMutation(tempOrder, {
4146
4264
  reapplyWeighedDiscountProductUids,
4147
4265
  reapplyBookingDiscountProductUids: reapplyBookingDiscountProductUids.length ? reapplyBookingDiscountProductUids : undefined
@@ -4152,6 +4270,9 @@ class OrderModule extends _BaseModule.BaseModule {
4152
4270
  return tempOrder.products;
4153
4271
  }
4154
4272
  async updateOrderProductQuantity(params) {
4273
+ return this.queueCartCommand(() => this.updateOrderProductQuantityDraft(params));
4274
+ }
4275
+ async updateOrderProductQuantityDraft(params) {
4155
4276
  const {
4156
4277
  product_id,
4157
4278
  product_variant_id,
@@ -4161,7 +4282,8 @@ class OrderModule extends _BaseModule.BaseModule {
4161
4282
  product_sku,
4162
4283
  product_bundle
4163
4284
  } = params;
4164
- const tempOrder = this.ensureTempOrder();
4285
+ const mutation = this.beginCartMutation();
4286
+ let tempOrder = mutation.draft;
4165
4287
  this.repairDuplicateProductLineIdentities(tempOrder);
4166
4288
  const identityLookup = {
4167
4289
  product_id,
@@ -4218,6 +4340,7 @@ class OrderModule extends _BaseModule.BaseModule {
4218
4340
  }
4219
4341
  }
4220
4342
  tempOrder.products[productIndex] = normalizedProduct;
4343
+ if (mutation.commit) tempOrder = await mutation.commit();
4221
4344
  this.prepareVirtualSettlementTempOrder(tempOrder);
4222
4345
  const isVirtualSettlement = this.isActiveVirtualSettlementOrder(tempOrder);
4223
4346
  const promotionPayload = !isVirtualSettlement ? await this.evaluatePromotion() : null;
@@ -4294,7 +4417,11 @@ class OrderModule extends _BaseModule.BaseModule {
4294
4417
  * await order.removeProductsFromOrder([identityA, identityB]);
4295
4418
  */
4296
4419
  async removeProductsFromOrder(identities, options) {
4297
- const tempOrder = this.ensureTempOrder();
4420
+ return this.queueCartCommand(() => this.removeProductsFromOrderDraft(identities, options));
4421
+ }
4422
+ async removeProductsFromOrderDraft(identities, options) {
4423
+ const mutation = this.beginCartMutation();
4424
+ let tempOrder = mutation.draft;
4298
4425
  if (!identities.length) {
4299
4426
  return tempOrder.products;
4300
4427
  }
@@ -4361,6 +4488,7 @@ class OrderModule extends _BaseModule.BaseModule {
4361
4488
  }
4362
4489
  }
4363
4490
  this.removeSalesNotesForMissingProductLines(tempOrder);
4491
+ if (mutation.commit) tempOrder = await mutation.commit();
4364
4492
  await this.finalizeAfterProductsMutation(tempOrder);
4365
4493
  this.logInfo('removeProductsFromOrder success', {
4366
4494
  identities
@@ -4376,7 +4504,11 @@ class OrderModule extends _BaseModule.BaseModule {
4376
4504
  * 普通整单 note 保持不变;以商品行为主体的 Sales Notes 同步删除。
4377
4505
  */
4378
4506
  async clearOrderCartLines() {
4379
- const tempOrder = this.ensureTempOrder();
4507
+ return this.queueCartCommand(() => this.clearOrderCartLinesDraft());
4508
+ }
4509
+ async clearOrderCartLinesDraft() {
4510
+ const mutation = this.beginCartMutation();
4511
+ let tempOrder = mutation.draft;
4380
4512
  this.ensureSalesNotesLoadedForMutation(tempOrder);
4381
4513
  tempOrder.products = [];
4382
4514
  tempOrder.bookings = [];
@@ -4389,6 +4521,7 @@ class OrderModule extends _BaseModule.BaseModule {
4389
4521
  productsByUid: {}
4390
4522
  };
4391
4523
  }
4524
+ if (mutation.commit) tempOrder = await mutation.commit();
4392
4525
  const promotionPayload = await this.evaluatePromotion();
4393
4526
  this.applyDiscount();
4394
4527
  this.sanitizeTempOrderProducts(tempOrder);
@@ -4525,6 +4658,7 @@ class OrderModule extends _BaseModule.BaseModule {
4525
4658
  }
4526
4659
  async runSubmitTempOrder(params) {
4527
4660
  const tempOrder = this.ensureTempOrder();
4661
+ (0, _productVoucherGroups.validateProductVoucherGroups)(tempOrder, this.getDiscountList(), undefined, true);
4528
4662
  this.prepareVirtualSettlementTempOrder(tempOrder);
4529
4663
  const isOnlineStorePlatform = this.isOnlineStorePlatform();
4530
4664
  const shouldConfirmPendingVoucherPayments = params?.confirmPendingVoucherPayments !== false;
@@ -438,6 +438,8 @@ export type AddProductBookingInput = Record<string, any>;
438
438
  * 避免步进器修改数量改变该组展示位置。
439
439
  */
440
440
  export interface AddProductToOrderOptions {
441
+ /** Associates a selection with an existing runtime voucher group. */
442
+ productVoucherGroupKey?: string;
441
443
  insertAfterProductUid?: string;
442
444
  /** 跳过同商品/规格匹配,始终新增购物车行。 */
443
445
  disableMerge?: boolean;
@@ -517,6 +519,11 @@ export type OrderProductMergeDecisionResult = boolean | {
517
519
  [key: string]: any;
518
520
  };
519
521
  export interface OrderHooksConfig {
522
+ /** Awaited before a local cart draft is published. Reject to leave the live order unchanged. */
523
+ onBeforeCartCommit?: (context: {
524
+ currentItems: readonly OrderProduct[];
525
+ proposedItems: readonly OrderProduct[];
526
+ }) => void | Promise<void>;
520
527
  onBeforeMergeProductToOrder?: (context: OrderProductMergeDecisionContext) => OrderProductMergeDecisionResult | Promise<OrderProductMergeDecisionResult>;
521
528
  }
522
529
  /**
@@ -192,7 +192,7 @@ function consolidateDiscountFreeProductLines(tempOrder) {
192
192
  bundle_selling_price: String(bundle?.bundle_selling_price ?? '')
193
193
  }))
194
194
  });
195
- const mergeKey = [discountSplitOriginUid, product.product_id, product.product_variant_id ?? 0, fingerprint, priceSignature].join('#');
195
+ const mergeKey = [discountSplitOriginUid, productUid ? tempOrder._extend?.productsByUid?.[productUid]?.productVoucherGroupKey ?? '' : '', product.product_id, product.product_variant_id ?? 0, fingerprint, priceSignature].join('#');
196
196
  const matchedIndex = productIndexByKey.get(mergeKey);
197
197
 
198
198
  // 当前拆分来源 + 商品结构组合第一次出现时,保留该行作为回并目标。
@@ -0,0 +1,15 @@
1
+ import type { Discount } from '../../Discount/types';
2
+ import type { OrderTempOrder } from '../types';
3
+ /** Runtime-only allocation constraints. Never copied into order/product metadata. */
4
+ export interface ProductVoucherGroup {
5
+ key: string;
6
+ discountIds: Array<number | string>;
7
+ }
8
+ export declare function productVoucherGroupKey(order: OrderTempOrder, product: any): string | undefined;
9
+ export declare function isUsableProductVoucher(discount: Discount): boolean;
10
+ export declare function voucherGroupError(): Error & {
11
+ code: string;
12
+ };
13
+ export declare function allowsProductVoucher(order: OrderTempOrder | null | undefined, product: any, discount: Discount): boolean;
14
+ /** Reductions stay possible when a voucher expires; checkout always requires full coverage. */
15
+ export declare function validateProductVoucherGroups(order: OrderTempOrder, discounts: Discount[], previous?: OrderTempOrder, requireCoverage?: boolean): void;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.allowsProductVoucher = allowsProductVoucher;
7
+ exports.isUsableProductVoucher = isUsableProductVoucher;
8
+ exports.productVoucherGroupKey = productVoucherGroupKey;
9
+ exports.validateProductVoucherGroups = validateProductVoucherGroups;
10
+ exports.voucherGroupError = voucherGroupError;
11
+ var _availability = require("../../Discount/availability");
12
+ var _dayjs = _interopRequireDefault(require("dayjs"));
13
+ var _utils = require("../../../solution/ShopDiscount/utils");
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ /** Runtime-only allocation constraints. Never copied into order/product metadata. */
16
+
17
+ function productVoucherGroupKey(order, product) {
18
+ const uid = product?.metadata?.unique_identification_number ?? product?.unique_identification_number;
19
+ return order._extend?.productsByUid?.[String(uid)]?.productVoucherGroupKey;
20
+ }
21
+ function isUsableProductVoucher(discount) {
22
+ return (discount.tag || discount.type) === 'good_pass' && !discount.isEditMode && !discount.isDisabled && !(0, _availability.getDiscountUsageBlockReason)(discount) && !(0, _utils.getDiscountTimeUnavailableReason)(discount, (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss'));
23
+ }
24
+ function voucherGroupError() {
25
+ return Object.assign(new Error('The selected items no longer match the available vouchers. Please adjust your selection.'), {
26
+ code: 'PRODUCT_VOUCHER_GROUP_INVALID'
27
+ });
28
+ }
29
+ function allowsProductVoucher(order, product, discount) {
30
+ const groups = order?._extend?.productVoucherGroups;
31
+ if (!order || !groups?.length) return true;
32
+ const key = productVoucherGroupKey(order, product);
33
+ if (!key) return !groups.some(group => group.discountIds.some(id => String(id) === String(discount.id)));
34
+ return (discount.tag || discount.type) === 'good_pass' && Boolean(groups.find(group => group.key === key)?.discountIds.some(id => String(id) === String(discount.id)));
35
+ }
36
+
37
+ /** Reductions stay possible when a voucher expires; checkout always requires full coverage. */
38
+ function validateProductVoucherGroups(order, discounts, previous, requireCoverage = false) {
39
+ const groups = order._extend?.productVoucherGroups;
40
+ if (!groups?.length) return;
41
+ const usedIds = new Set();
42
+ const byId = new Map(discounts.filter(isUsableProductVoucher).map(discount => [String(discount.id), discount]));
43
+ const quantity = item => Number(item.num ?? item.product_quantity ?? 0);
44
+ for (const group of groups) {
45
+ const items = order.products.filter(item => productVoucherGroupKey(order, item) === group.key);
46
+ const selected = items.reduce((sum, item) => sum + quantity(item), 0);
47
+ const before = previous?.products.filter(item => productVoucherGroupKey(previous, item) === group.key).reduce((sum, item) => sum + quantity(item), 0) ?? 0;
48
+ if (!requireCoverage && previous && selected <= before) continue;
49
+ const ids = new Set(group.discountIds.map(String).filter(id => byId.has(id)));
50
+ if (!Number.isInteger(selected) || selected < 0 || selected > ids.size) throw voucherGroupError();
51
+ if (!requireCoverage) continue;
52
+ for (const item of items) {
53
+ const applied = (item.discount_list || []).filter(entry => (entry.type || entry.tag) === 'good_pass');
54
+ // Rules splits a good_pass allocation into one physical line per instance.
55
+ const id = String(applied[0]?.discount?.resource_id ?? '');
56
+ const voucher = byId.get(id);
57
+ if (quantity(item) !== 1 || applied.length !== 1 || !ids.has(id) || !voucher?.isAvailable || voucher.config?.isAvailable === false || usedIds.has(id)) throw voucherGroupError();
58
+ usedIds.add(id);
59
+ }
60
+ }
61
+ if (order.products.some(item => !groups.some(group => group.key === productVoucherGroupKey(order, item)))) {
62
+ throw voucherGroupError();
63
+ }
64
+ }
@@ -66,7 +66,13 @@ class ProductList extends _BaseModule.BaseModule {
66
66
  * productList.updateOtherParams({ channel: 'pos' });
67
67
  */
68
68
  updateOtherParams(params) {
69
+ const previousScope = this.otherParams.catalogScopeKey;
69
70
  this.otherParams = params || {};
71
+ if (previousScope !== this.otherParams.catalogScopeKey && (previousScope || this.otherParams.catalogScopeKey)) {
72
+ this.store.list = [];
73
+ this.rawProductPriceSources.clear();
74
+ this.core.effects.emit(`${this.name}:changed`, this.store.list);
75
+ }
70
76
  }
71
77
  async storeChange(path, value) {
72
78
  // No longer needed - products are stored as plain objects instead of Product instances
@@ -101,6 +107,12 @@ class ProductList extends _BaseModule.BaseModule {
101
107
  status = 'published',
102
108
  strategy_context
103
109
  } = {}, options) {
110
+ const scope = this.otherParams.catalogScopeKey;
111
+ const assertScope = () => {
112
+ if (scope !== this.otherParams.catalogScopeKey) throw Object.assign(new Error('Product catalog context changed'), {
113
+ name: 'AbortError'
114
+ });
115
+ };
104
116
  // // 如果 schedule_ids 为空,则需要尝试从 schedule 模块里获取
105
117
  // if (!schedule_ids?.length) {
106
118
  // const schedule_ids_data = this.store.schedule
@@ -180,6 +192,7 @@ class ProductList extends _BaseModule.BaseModule {
180
192
  const handledByOsServer = (0, _clientDataVariants.isProductQueryHandledByOsServer)(this.core, this.request);
181
193
  const originalCallback = options?.callback;
182
194
  const subscriptionCallback = typeof originalCallback === 'function' ? async result => {
195
+ if (scope !== this.otherParams.catalogScopeKey) return;
183
196
  const callbackList = result?.data?.list;
184
197
  if (!Array.isArray(callbackList)) {
185
198
  originalCallback(result);
@@ -197,6 +210,7 @@ class ProductList extends _BaseModule.BaseModule {
197
210
  queryPayload,
198
211
  handledByOsServer
199
212
  });
213
+ assertScope();
200
214
  await this.addProduct(products);
201
215
  originalCallback(handledByOsServer ? result : {
202
216
  ...result,
@@ -212,6 +226,7 @@ class ProductList extends _BaseModule.BaseModule {
212
226
  subscriberId: options?.subscriberId,
213
227
  customToast: () => {}
214
228
  });
229
+ assertScope();
215
230
  if (!handledByOsServer && Array.isArray(productsData.data.list)) {
216
231
  this.replaceRawProductQueryResult(productsData.data.list, product_ids);
217
232
  }
@@ -9,6 +9,8 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
9
9
  private store;
10
10
  window: WindowPlugin;
11
11
  private hooks;
12
+ private discountScope?;
13
+ setDiscountScope(scope: (product: any, discount: Discount) => boolean): void;
12
14
  constructor(name?: string, version?: string);
13
15
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
14
16
  setRulesList(rulesList: Rules[]): Promise<void>;
@@ -20,6 +20,10 @@ class RulesModule extends _BaseModule.BaseModule {
20
20
  store;
21
21
  window; // WindowPlugin 实例
22
22
  hooks;
23
+ discountScope;
24
+ setDiscountScope(scope) {
25
+ this.discountScope = scope;
26
+ }
23
27
  constructor(name, version) {
24
28
  super(name, version);
25
29
  this.hooks = {};
@@ -722,6 +726,7 @@ class RulesModule extends _BaseModule.BaseModule {
722
726
 
723
727
  // 辅助函数:检查商品是否对某个折扣卡可用
724
728
  const checkItemApplicableForDiscount = (flatItem, discount) => {
729
+ if (this.discountScope && !this.discountScope(flatItem.originProduct, discount)) return false;
725
730
  if (discount.config?.isAvailable === false) return false;
726
731
  let product;
727
732
  if (flatItem.type === 'main') {
@@ -1093,6 +1098,7 @@ class RulesModule extends _BaseModule.BaseModule {
1093
1098
 
1094
1099
  // 找到适用于此商品的所有优惠券,仅考虑isSelected不为false的优惠券
1095
1100
  const applicableDiscounts = sortedDiscountList.filter(discount => {
1101
+ if (this.discountScope && !this.discountScope(originProduct, discount)) return false;
1096
1102
  if (this.isItemRewardProductDiscount(product)) return false;
1097
1103
  // 🔥 检查策略可用性(针对全额抵扣卡和折扣卡)
1098
1104
  const discountType = discount.tag || discount.type;
@@ -1,3 +1,4 @@
1
+ import { InventoryController, type CheckoutRuntimeSnapshot } from '../../inventory';
1
2
  import { Module, ModuleOptions, PisellCore } from '../../types';
2
3
  import { BaseModule } from '../../modules/BaseModule';
3
4
  import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentOptions, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
@@ -47,6 +48,8 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
47
48
  protected appPlugin: AppPlugin;
48
49
  protected store: BaseSalesState;
49
50
  protected otherParams: Record<string, any>;
51
+ getInventory(): InventoryController | undefined;
52
+ prepareCheckout(signal?: AbortSignal): Promise<CheckoutRuntimeSnapshot | undefined>;
50
53
  protected cacheId: string | undefined;
51
54
  /**
52
55
  * 由已在初始化阶段解析过设备短号的业务解决方案写入。
@@ -166,6 +169,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
166
169
  * 可覆盖此方法并把未识别的 name 委托给 `super.createSubModule(name)`。
167
170
  */
168
171
  protected createSubModule(moduleName: string): Module | null;
172
+ private inventoryOrderHooks?;
169
173
  protected getSubModuleHooks(moduleName: string): any;
170
174
  /**
171
175
  * 构造传给 BaseSales 子模块的完整运行态参数,保证初始化和后续同步语义一致。
@@ -203,7 +207,11 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
203
207
  private isActiveVirtualSettlementOrder;
204
208
  private isHistoricalVirtualSettlementOrder;
205
209
  private syncAppDataToTempOrder;
210
+ private initialization?;
211
+ /** Hosts can await readiness without changing Core's synchronous registration API. */
212
+ whenInitialized(): Promise<void>;
206
213
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
214
+ private initializeSalesRuntime;
207
215
  destroy(): Promise<void>;
208
216
  /**
209
217
  * 加载销售订单到统一 tempOrder 工作区。
@@ -306,7 +314,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
306
314
  discountList: Discount[];
307
315
  originalDiscountList?: Discount[];
308
316
  }): Promise<void>;
309
- scanPromotionCode(code: string, customerId?: number): Promise<BaseSalesScanCodeResult>;
317
+ scanPromotionCode(code: string, customerId?: number, options?: {
318
+ productVouchersOnly?: boolean;
319
+ }): Promise<BaseSalesScanCodeResult>;
310
320
  setDiscountSelected(params: {
311
321
  discountId: number;
312
322
  isSelected: boolean;
@@ -498,6 +508,11 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
498
508
  private hasSmartPricingStrategies;
499
509
  shouldRecalculateProductBookingPricesForContextChange(params: BaseSalesPriceRecalculationContextChange): boolean;
500
510
  calculateProductBookingPrices(paramsList: BaseSalesCalculateProductBookingPriceParams[]): Promise<BaseSalesProductBookingPriceResult[]>;
511
+ setProductVoucherGroups(groups: Array<{
512
+ key: string;
513
+ discountIds: Array<number | string>;
514
+ }>): void;
515
+ validateProductVoucherSelection(): void;
501
516
  addProductToOrder(product: Partial<BaseSalesOrderProduct> & BaseSalesOrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions): Promise<import("../../modules/Order/types").OrderProduct[]>;
502
517
  updateOrderProduct(params: UpdateOrderProductParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
503
518
  updateOrderProducts(paramsList: UpdateOrderProductParams[]): Promise<import("../../modules/Order/types").OrderProduct[]>;