@pisell/pisellos 0.0.568 → 0.0.569

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 (413) hide show
  1. package/dist/model/strategy/adapter/promotion/evaluator.js +3 -2
  2. package/dist/model/strategy/adapter/walletPass/utils.js +7 -4
  3. package/dist/modules/BaseModule.d.ts +2 -2
  4. package/dist/modules/BaseModule.js +4 -4
  5. package/dist/modules/BookingContext/index.d.ts +48 -0
  6. package/dist/modules/BookingContext/index.js +566 -0
  7. package/dist/modules/BookingContext/types.d.ts +102 -0
  8. package/dist/modules/BookingContext/types.js +51 -0
  9. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  10. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +302 -0
  11. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  12. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +149 -0
  13. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
  14. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +249 -0
  15. package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
  16. package/dist/modules/BookingContext/utils/flexible.js +56 -0
  17. package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  18. package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
  19. package/dist/modules/BookingContext/utils/index.d.ts +11 -0
  20. package/dist/modules/BookingContext/utils/index.js +11 -0
  21. package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
  22. package/dist/modules/BookingContext/utils/noResource.js +77 -0
  23. package/dist/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
  24. package/dist/modules/BookingContext/utils/orderLineDisplay.js +36 -0
  25. package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
  26. package/dist/modules/BookingContext/utils/productExtend.js +339 -0
  27. package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  28. package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
  29. package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  30. package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
  31. package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
  32. package/dist/modules/BookingContext/utils/resources.js +486 -0
  33. package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  34. package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
  35. package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  36. package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
  37. package/dist/modules/Cart/utils/cartProduct.js +26 -5
  38. package/dist/modules/Cart/utils/changePrice.js +27 -20
  39. package/dist/modules/Customer/index.d.ts +20 -0
  40. package/dist/modules/Customer/index.js +172 -83
  41. package/dist/modules/Customer/types.d.ts +2 -0
  42. package/dist/modules/Discount/index.d.ts +2 -1
  43. package/dist/modules/Discount/index.js +37 -9
  44. package/dist/modules/Discount/types.d.ts +1 -0
  45. package/dist/modules/OpenData/index.d.ts +8 -0
  46. package/dist/modules/OpenData/index.js +36 -16
  47. package/dist/modules/Order/index.d.ts +448 -23
  48. package/dist/modules/Order/index.js +5417 -561
  49. package/dist/modules/Order/types.d.ts +693 -88
  50. package/dist/modules/Order/types.js +68 -1
  51. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  52. package/dist/modules/Order/utils/bundleDiscountHydration.js +144 -0
  53. package/dist/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  54. package/dist/modules/Order/utils/manualProductDiscount.js +210 -0
  55. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  56. package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
  57. package/dist/modules/Order/utils.d.ts +167 -18
  58. package/dist/modules/Order/utils.js +960 -165
  59. package/dist/modules/Payment/index.d.ts +10 -9
  60. package/dist/modules/Payment/index.js +465 -703
  61. package/dist/modules/Payment/types.d.ts +40 -16
  62. package/dist/modules/Payment/utils.d.ts +1 -1
  63. package/dist/modules/Payment/utils.js +4 -3
  64. package/dist/modules/Payment/walletpass.js +44 -29
  65. package/dist/modules/Product/types.d.ts +29 -7
  66. package/dist/modules/ProductList/index.d.ts +17 -13
  67. package/dist/modules/ProductList/index.js +184 -74
  68. package/dist/modules/ProductList/types.d.ts +17 -0
  69. package/dist/modules/Quotation/index.d.ts +22 -2
  70. package/dist/modules/Quotation/index.js +108 -42
  71. package/dist/modules/Quotation/types.d.ts +19 -0
  72. package/dist/modules/ResourcePlanner/index.d.ts +24 -0
  73. package/dist/modules/ResourcePlanner/index.js +181 -0
  74. package/dist/modules/ResourcePlanner/planner.d.ts +14 -0
  75. package/dist/modules/ResourcePlanner/planner.js +1069 -0
  76. package/dist/modules/ResourcePlanner/types.d.ts +227 -0
  77. package/dist/modules/ResourcePlanner/types.js +1 -0
  78. package/dist/modules/Rules/index.d.ts +8 -10
  79. package/dist/modules/Rules/index.js +221 -109
  80. package/dist/modules/Rules/types.d.ts +14 -3
  81. package/dist/modules/SalesSummary/index.d.ts +23 -26
  82. package/dist/modules/SalesSummary/index.js +152 -46
  83. package/dist/modules/SalesSummary/types.d.ts +9 -1
  84. package/dist/modules/SalesSummary/utils.d.ts +3 -22
  85. package/dist/modules/SalesSummary/utils.js +803 -163
  86. package/dist/modules/Schedule/getDateIsInSchedule.js +14 -7
  87. package/dist/modules/Schedule/index.d.ts +18 -5
  88. package/dist/modules/Schedule/index.js +78 -24
  89. package/dist/modules/Schedule/types.d.ts +2 -0
  90. package/dist/modules/Summary/index.js +4 -3
  91. package/dist/modules/SurchargeList/index.d.ts +18 -0
  92. package/dist/modules/SurchargeList/index.js +185 -0
  93. package/dist/modules/SurchargeList/types.d.ts +15 -0
  94. package/dist/modules/SurchargeList/types.js +1 -0
  95. package/dist/modules/index.d.ts +3 -0
  96. package/dist/modules/index.js +4 -1
  97. package/dist/plugins/app.d.ts +2 -0
  98. package/dist/plugins/request.d.ts +1 -0
  99. package/dist/server/index.d.ts +462 -8
  100. package/dist/server/index.js +6112 -656
  101. package/dist/server/modules/floor-plan/index.d.ts +39 -0
  102. package/dist/server/modules/floor-plan/index.js +595 -0
  103. package/dist/server/modules/floor-plan/types.d.ts +43 -0
  104. package/dist/server/modules/floor-plan/types.js +13 -0
  105. package/dist/server/modules/index.d.ts +7 -2
  106. package/dist/server/modules/index.js +6 -0
  107. package/dist/server/modules/order/index.d.ts +207 -14
  108. package/dist/server/modules/order/index.js +2326 -379
  109. package/dist/server/modules/order/types.d.ts +76 -5
  110. package/dist/server/modules/order/types.js +14 -1
  111. package/dist/server/modules/order/utils/filterBookings.d.ts +7 -1
  112. package/dist/server/modules/order/utils/filterBookings.js +118 -11
  113. package/dist/server/modules/order/utils/filterOrders.js +242 -14
  114. package/dist/server/modules/payment/index.d.ts +28 -0
  115. package/dist/server/modules/payment/index.js +305 -0
  116. package/dist/server/modules/payment/types.d.ts +9 -0
  117. package/dist/server/modules/payment/types.js +1 -0
  118. package/dist/server/modules/products/index.d.ts +105 -14
  119. package/dist/server/modules/products/index.js +1393 -516
  120. package/dist/server/modules/products/types.d.ts +34 -1
  121. package/dist/server/modules/products/types.js +4 -0
  122. package/dist/server/modules/quotation/index.d.ts +39 -0
  123. package/dist/server/modules/quotation/index.js +278 -66
  124. package/dist/server/modules/resource/index.d.ts +2 -3
  125. package/dist/server/modules/resource/index.js +108 -86
  126. package/dist/server/modules/schedule/index.d.ts +6 -4
  127. package/dist/server/modules/schedule/index.js +116 -85
  128. package/dist/server/test.json +713 -0
  129. package/dist/server/types.d.ts +2 -0
  130. package/dist/server/utils/product.js +2 -2
  131. package/dist/server/utils/small-ticket.d.ts +71 -0
  132. package/dist/server/utils/small-ticket.js +963 -0
  133. package/dist/solution/BaseSales/index.d.ts +378 -0
  134. package/dist/solution/BaseSales/index.js +4006 -0
  135. package/dist/solution/BaseSales/types.d.ts +394 -0
  136. package/dist/solution/BaseSales/types.js +40 -0
  137. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
  138. package/dist/solution/BaseSales/utils/cartPromotion.js +1450 -0
  139. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +144 -0
  140. package/dist/solution/BaseSales/utils/parseSalesResponse.js +157 -0
  141. package/dist/solution/BaseSales/utils/quotationPrice.d.ts +18 -0
  142. package/dist/solution/BaseSales/utils/quotationPrice.js +250 -0
  143. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +63 -0
  144. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +218 -0
  145. package/dist/solution/BaseSales/utils.d.ts +40 -0
  146. package/dist/solution/BaseSales/utils.js +263 -0
  147. package/dist/solution/BookingByStep/index.d.ts +1 -1
  148. package/dist/solution/BookingTicket/index.d.ts +394 -25
  149. package/dist/solution/BookingTicket/index.js +2506 -443
  150. package/dist/solution/BookingTicket/types.d.ts +191 -6
  151. package/dist/solution/BookingTicket/types.js +83 -10
  152. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
  153. package/dist/solution/BookingTicket/utils/addProductDecision.js +346 -0
  154. package/dist/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
  155. package/dist/solution/BookingTicket/utils/addTimeAvailability.js +95 -0
  156. package/dist/solution/BookingTicket/utils/bookingStatus.d.ts +77 -0
  157. package/dist/solution/BookingTicket/utils/bookingStatus.js +136 -0
  158. package/dist/solution/BookingTicket/utils/cartView.d.ts +29 -0
  159. package/dist/solution/BookingTicket/utils/cartView.js +209 -0
  160. package/dist/solution/BookingTicket/utils/exampleData.d.ts +123 -0
  161. package/dist/solution/BookingTicket/utils/exampleData.js +183 -0
  162. package/dist/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
  163. package/dist/solution/BookingTicket/utils/orderCustomer.js +31 -0
  164. package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
  165. package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.js +438 -0
  166. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  167. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +400 -0
  168. package/dist/solution/BookingTicket/utils/scan/cloudSearch.d.ts +4 -0
  169. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +41 -1
  170. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  171. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +56 -0
  172. package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  173. package/dist/solution/BookingTicket/utils/scan/handleScan.js +11 -3
  174. package/dist/solution/BookingTicket/utils/scan/index.d.ts +5 -0
  175. package/dist/solution/BookingTicket/utils/scan/index.js +20 -8
  176. package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  177. package/dist/solution/BookingTicket/utils/scan/scanProductValues.js +150 -0
  178. package/dist/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
  179. package/dist/solution/BookingTicket/utils/sessionCatalogStale.js +78 -0
  180. package/dist/solution/Checkout/index.d.ts +1 -0
  181. package/dist/solution/Checkout/index.js +25 -34
  182. package/dist/solution/Checkout/utils/index.js +4 -4
  183. package/dist/solution/RegisterAndLogin/config.js +2 -10
  184. package/dist/solution/Sales/index.d.ts +50 -5
  185. package/dist/solution/Sales/index.js +484 -92
  186. package/dist/solution/Sales/types.d.ts +26 -2
  187. package/dist/solution/ScanOrder/index.d.ts +27 -21
  188. package/dist/solution/ScanOrder/index.js +499 -434
  189. package/dist/solution/ScanOrder/types.d.ts +33 -11
  190. package/dist/solution/ScanOrder/types.js +4 -5
  191. package/dist/solution/ScanOrder/utils.d.ts +4 -1
  192. package/dist/solution/ScanOrder/utils.js +109 -34
  193. package/dist/solution/ShopDiscount/index.js +4 -4
  194. package/dist/solution/UnifiedBookingSales/index.d.ts +183 -0
  195. package/dist/solution/UnifiedBookingSales/index.js +1871 -0
  196. package/dist/solution/UnifiedBookingSales/types.d.ts +143 -0
  197. package/dist/solution/UnifiedBookingSales/types.js +11 -0
  198. package/dist/solution/VenueBooking/index.d.ts +29 -20
  199. package/dist/solution/VenueBooking/index.js +301 -213
  200. package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -2
  201. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
  202. package/dist/solution/VenueBooking/utils/slotMerge.js +9 -3
  203. package/dist/solution/index.d.ts +2 -0
  204. package/dist/solution/index.js +3 -1
  205. package/dist/types/index.d.ts +11 -1
  206. package/lib/model/strategy/adapter/promotion/evaluator.js +3 -2
  207. package/lib/model/strategy/adapter/walletPass/utils.js +6 -4
  208. package/lib/modules/BaseModule.d.ts +2 -2
  209. package/lib/modules/BaseModule.js +4 -4
  210. package/lib/modules/BookingContext/index.d.ts +48 -0
  211. package/lib/modules/BookingContext/index.js +390 -0
  212. package/lib/modules/BookingContext/types.d.ts +102 -0
  213. package/lib/modules/BookingContext/types.js +48 -0
  214. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  215. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +286 -0
  216. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  217. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +148 -0
  218. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
  219. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +242 -0
  220. package/lib/modules/BookingContext/utils/flexible.d.ts +28 -0
  221. package/lib/modules/BookingContext/utils/flexible.js +63 -0
  222. package/lib/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  223. package/lib/modules/BookingContext/utils/formatResourceList.js +35 -0
  224. package/lib/modules/BookingContext/utils/index.d.ts +11 -0
  225. package/lib/modules/BookingContext/utils/index.js +126 -0
  226. package/lib/modules/BookingContext/utils/noResource.d.ts +13 -0
  227. package/lib/modules/BookingContext/utils/noResource.js +78 -0
  228. package/lib/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
  229. package/lib/modules/BookingContext/utils/orderLineDisplay.js +29 -0
  230. package/lib/modules/BookingContext/utils/productExtend.d.ts +72 -0
  231. package/lib/modules/BookingContext/utils/productExtend.js +330 -0
  232. package/lib/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  233. package/lib/modules/BookingContext/utils/resourceErrors.js +80 -0
  234. package/lib/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  235. package/lib/modules/BookingContext/utils/resourceSelection.js +24 -0
  236. package/lib/modules/BookingContext/utils/resources.d.ts +80 -0
  237. package/lib/modules/BookingContext/utils/resources.js +419 -0
  238. package/lib/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  239. package/lib/modules/BookingContext/utils/serviceTimes.js +161 -0
  240. package/lib/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  241. package/lib/modules/BookingContext/utils/timeSlices.js +114 -0
  242. package/lib/modules/Cart/utils/cartProduct.js +27 -5
  243. package/lib/modules/Cart/utils/changePrice.js +20 -14
  244. package/lib/modules/Customer/index.d.ts +20 -0
  245. package/lib/modules/Customer/index.js +63 -10
  246. package/lib/modules/Customer/types.d.ts +2 -0
  247. package/lib/modules/Discount/index.d.ts +2 -1
  248. package/lib/modules/Discount/index.js +18 -2
  249. package/lib/modules/Discount/types.d.ts +1 -0
  250. package/lib/modules/OpenData/index.d.ts +8 -0
  251. package/lib/modules/OpenData/index.js +21 -3
  252. package/lib/modules/Order/index.d.ts +448 -23
  253. package/lib/modules/Order/index.js +3641 -308
  254. package/lib/modules/Order/types.d.ts +693 -88
  255. package/lib/modules/Order/types.js +55 -1
  256. package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  257. package/lib/modules/Order/utils/bundleDiscountHydration.js +106 -0
  258. package/lib/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  259. package/lib/modules/Order/utils/manualProductDiscount.js +207 -0
  260. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  261. package/lib/modules/Order/utils/orderCollectionIdentity.js +353 -0
  262. package/lib/modules/Order/utils.d.ts +167 -18
  263. package/lib/modules/Order/utils.js +974 -138
  264. package/lib/modules/Payment/index.d.ts +10 -9
  265. package/lib/modules/Payment/index.js +30 -124
  266. package/lib/modules/Payment/types.d.ts +40 -16
  267. package/lib/modules/Payment/utils.d.ts +1 -1
  268. package/lib/modules/Payment/utils.js +4 -3
  269. package/lib/modules/Payment/walletpass.js +16 -6
  270. package/lib/modules/Product/types.d.ts +29 -7
  271. package/lib/modules/ProductList/index.d.ts +17 -13
  272. package/lib/modules/ProductList/index.js +92 -51
  273. package/lib/modules/ProductList/types.d.ts +17 -0
  274. package/lib/modules/Quotation/index.d.ts +22 -2
  275. package/lib/modules/Quotation/index.js +76 -20
  276. package/lib/modules/Quotation/types.d.ts +19 -0
  277. package/lib/modules/ResourcePlanner/index.d.ts +24 -0
  278. package/lib/modules/ResourcePlanner/index.js +147 -0
  279. package/lib/modules/ResourcePlanner/planner.d.ts +14 -0
  280. package/lib/modules/ResourcePlanner/planner.js +895 -0
  281. package/lib/modules/ResourcePlanner/types.d.ts +227 -0
  282. package/lib/modules/ResourcePlanner/types.js +5 -0
  283. package/lib/modules/Rules/index.d.ts +8 -10
  284. package/lib/modules/Rules/index.js +152 -60
  285. package/lib/modules/Rules/types.d.ts +14 -3
  286. package/lib/modules/SalesSummary/index.d.ts +23 -26
  287. package/lib/modules/SalesSummary/index.js +84 -16
  288. package/lib/modules/SalesSummary/types.d.ts +9 -1
  289. package/lib/modules/SalesSummary/utils.d.ts +3 -22
  290. package/lib/modules/SalesSummary/utils.js +616 -111
  291. package/lib/modules/Schedule/getDateIsInSchedule.js +14 -7
  292. package/lib/modules/Schedule/index.d.ts +18 -5
  293. package/lib/modules/Schedule/index.js +49 -14
  294. package/lib/modules/Schedule/types.d.ts +2 -0
  295. package/lib/modules/Summary/index.js +2 -2
  296. package/lib/modules/SurchargeList/index.d.ts +18 -0
  297. package/lib/modules/SurchargeList/index.js +95 -0
  298. package/lib/modules/SurchargeList/types.d.ts +15 -0
  299. package/lib/modules/SurchargeList/types.js +5 -0
  300. package/lib/modules/index.d.ts +3 -0
  301. package/lib/modules/index.js +33 -0
  302. package/lib/plugins/app.d.ts +2 -0
  303. package/lib/plugins/request.d.ts +1 -0
  304. package/lib/server/index.d.ts +462 -8
  305. package/lib/server/index.js +3901 -205
  306. package/lib/server/modules/floor-plan/index.d.ts +39 -0
  307. package/lib/server/modules/floor-plan/index.js +306 -0
  308. package/lib/server/modules/floor-plan/types.d.ts +43 -0
  309. package/lib/server/modules/floor-plan/types.js +19 -0
  310. package/lib/server/modules/index.d.ts +7 -2
  311. package/lib/server/modules/index.js +21 -0
  312. package/lib/server/modules/order/index.d.ts +207 -14
  313. package/lib/server/modules/order/index.js +1324 -141
  314. package/lib/server/modules/order/types.d.ts +76 -5
  315. package/lib/server/modules/order/types.js +11 -1
  316. package/lib/server/modules/order/utils/filterBookings.d.ts +7 -1
  317. package/lib/server/modules/order/utils/filterBookings.js +119 -11
  318. package/lib/server/modules/order/utils/filterOrders.js +238 -13
  319. package/lib/server/modules/payment/index.d.ts +28 -0
  320. package/lib/server/modules/payment/index.js +168 -0
  321. package/lib/server/modules/payment/types.d.ts +9 -0
  322. package/lib/server/modules/payment/types.js +5 -0
  323. package/lib/server/modules/products/index.d.ts +105 -14
  324. package/lib/server/modules/products/index.js +588 -97
  325. package/lib/server/modules/products/types.d.ts +34 -1
  326. package/lib/server/modules/products/types.js +3 -0
  327. package/lib/server/modules/quotation/index.d.ts +39 -0
  328. package/lib/server/modules/quotation/index.js +145 -1
  329. package/lib/server/modules/resource/index.d.ts +2 -3
  330. package/lib/server/modules/resource/index.js +71 -45
  331. package/lib/server/modules/schedule/index.d.ts +6 -4
  332. package/lib/server/modules/schedule/index.js +55 -44
  333. package/lib/server/test.json +713 -0
  334. package/lib/server/types.d.ts +2 -0
  335. package/lib/server/utils/product.js +2 -2
  336. package/lib/server/utils/small-ticket.d.ts +71 -0
  337. package/lib/server/utils/small-ticket.js +926 -0
  338. package/lib/solution/BaseSales/index.d.ts +378 -0
  339. package/lib/solution/BaseSales/index.js +2367 -0
  340. package/lib/solution/BaseSales/types.d.ts +394 -0
  341. package/lib/solution/BaseSales/types.js +47 -0
  342. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
  343. package/lib/solution/BaseSales/utils/cartPromotion.js +1155 -0
  344. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +144 -0
  345. package/lib/solution/BaseSales/utils/parseSalesResponse.js +140 -0
  346. package/lib/solution/BaseSales/utils/quotationPrice.d.ts +18 -0
  347. package/lib/solution/BaseSales/utils/quotationPrice.js +231 -0
  348. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +63 -0
  349. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +215 -0
  350. package/lib/solution/BaseSales/utils.d.ts +40 -0
  351. package/lib/solution/BaseSales/utils.js +259 -0
  352. package/lib/solution/BookingByStep/index.d.ts +1 -1
  353. package/lib/solution/BookingTicket/index.d.ts +394 -25
  354. package/lib/solution/BookingTicket/index.js +1350 -76
  355. package/lib/solution/BookingTicket/types.d.ts +191 -6
  356. package/lib/solution/BookingTicket/types.js +71 -10
  357. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
  358. package/lib/solution/BookingTicket/utils/addProductDecision.js +353 -0
  359. package/lib/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
  360. package/lib/solution/BookingTicket/utils/addTimeAvailability.js +94 -0
  361. package/lib/solution/BookingTicket/utils/bookingStatus.d.ts +77 -0
  362. package/lib/solution/BookingTicket/utils/bookingStatus.js +136 -0
  363. package/lib/solution/BookingTicket/utils/cartView.d.ts +29 -0
  364. package/lib/solution/BookingTicket/utils/cartView.js +200 -0
  365. package/lib/solution/BookingTicket/utils/exampleData.d.ts +123 -0
  366. package/lib/solution/BookingTicket/utils/exampleData.js +185 -0
  367. package/lib/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
  368. package/lib/solution/BookingTicket/utils/orderCustomer.js +35 -0
  369. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
  370. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +387 -0
  371. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  372. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +220 -0
  373. package/lib/solution/BookingTicket/utils/scan/cloudSearch.d.ts +4 -0
  374. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +24 -3
  375. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  376. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +64 -0
  377. package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  378. package/lib/solution/BookingTicket/utils/scan/handleScan.js +4 -2
  379. package/lib/solution/BookingTicket/utils/scan/index.d.ts +5 -0
  380. package/lib/solution/BookingTicket/utils/scan/index.js +14 -2
  381. package/lib/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  382. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +115 -0
  383. package/lib/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
  384. package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +83 -0
  385. package/lib/solution/Checkout/index.d.ts +1 -0
  386. package/lib/solution/Checkout/index.js +18 -19
  387. package/lib/solution/Checkout/utils/index.js +4 -4
  388. package/lib/solution/RegisterAndLogin/config.js +2 -10
  389. package/lib/solution/Sales/index.d.ts +50 -5
  390. package/lib/solution/Sales/index.js +296 -39
  391. package/lib/solution/Sales/types.d.ts +26 -2
  392. package/lib/solution/ScanOrder/index.d.ts +27 -21
  393. package/lib/solution/ScanOrder/index.js +144 -103
  394. package/lib/solution/ScanOrder/types.d.ts +33 -11
  395. package/lib/solution/ScanOrder/types.js +4 -5
  396. package/lib/solution/ScanOrder/utils.d.ts +4 -1
  397. package/lib/solution/ScanOrder/utils.js +98 -26
  398. package/lib/solution/ShopDiscount/index.js +3 -3
  399. package/lib/solution/UnifiedBookingSales/index.d.ts +183 -0
  400. package/lib/solution/UnifiedBookingSales/index.js +1050 -0
  401. package/lib/solution/UnifiedBookingSales/types.d.ts +143 -0
  402. package/lib/solution/UnifiedBookingSales/types.js +14 -0
  403. package/lib/solution/VenueBooking/index.d.ts +29 -20
  404. package/lib/solution/VenueBooking/index.js +169 -94
  405. package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -2
  406. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
  407. package/lib/solution/VenueBooking/utils/slotMerge.js +9 -3
  408. package/lib/solution/index.d.ts +2 -0
  409. package/lib/solution/index.js +22 -0
  410. package/lib/types/index.d.ts +11 -1
  411. package/package.json +1 -1
  412. package/dist/solution/Checkout/appointmentDemo.json +0 -1
  413. package/lib/solution/Checkout/appointmentDemo.json +0 -1
@@ -0,0 +1,895 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DEFAULT_RESOURCE_PLANNER_SELECTION = exports.DEFAULT_RESOURCE_PLANNER_CONTEXT = void 0;
7
+ exports.autoAssignResources = autoAssignResources;
8
+ exports.buildDemandIntervals = buildDemandIntervals;
9
+ exports.evaluateResourceForInterval = evaluateResourceForInterval;
10
+ exports.normalizePlannerContext = normalizePlannerContext;
11
+ exports.queryPlannerAvailability = queryPlannerAvailability;
12
+ exports.resolveAssignableSlots = resolveAssignableSlots;
13
+ exports.validateAssignments = validateAssignments;
14
+ var _dayjs = _interopRequireDefault(require("dayjs"));
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
+ const DEFAULT_RESOURCE_PLANNER_CONTEXT = exports.DEFAULT_RESOURCE_PLANNER_CONTEXT = {
17
+ products: [],
18
+ resources: [],
19
+ externalEvents: [],
20
+ slotDurationMinutes: 30,
21
+ businessStartTime: '09:00',
22
+ businessEndTime: '18:00'
23
+ };
24
+ const DEFAULT_RESOURCE_PLANNER_SELECTION = exports.DEFAULT_RESOURCE_PLANNER_SELECTION = {
25
+ productIds: [],
26
+ resourceIds: [],
27
+ assignments: []
28
+ };
29
+ function normalizePlannerContext(input = {}) {
30
+ return {
31
+ products: Array.isArray(input.products) ? input.products : [],
32
+ resources: Array.isArray(input.resources) ? input.resources : [],
33
+ externalEvents: Array.isArray(input.externalEvents) ? input.externalEvents : [],
34
+ slotDurationMinutes: input.slotDurationMinutes || DEFAULT_RESOURCE_PLANNER_CONTEXT.slotDurationMinutes,
35
+ businessStartTime: input.businessStartTime || DEFAULT_RESOURCE_PLANNER_CONTEXT.businessStartTime,
36
+ businessEndTime: input.businessEndTime || DEFAULT_RESOURCE_PLANNER_CONTEXT.businessEndTime
37
+ };
38
+ }
39
+ function sameId(left, right) {
40
+ return String(left) === String(right);
41
+ }
42
+ function dateOf(value) {
43
+ return (0, _dayjs.default)(value).format('YYYY-MM-DD');
44
+ }
45
+ function timeOf(value) {
46
+ return (0, _dayjs.default)(value).format('HH:mm');
47
+ }
48
+ function toDateTime(date, time) {
49
+ if (/^\d{4}-\d{2}-\d{2}/.test(time)) return (0, _dayjs.default)(time);
50
+ return (0, _dayjs.default)(`${date} ${time.length === 5 ? `${time}:00` : time}`);
51
+ }
52
+ function overlaps(startA, endA, startB, endB) {
53
+ return startA.isBefore(endB) && endA.isAfter(startB);
54
+ }
55
+ function containsRange(outerStart, outerEnd, innerStart, innerEnd) {
56
+ return !innerStart.isBefore(outerStart) && !innerEnd.isAfter(outerEnd);
57
+ }
58
+ function maxDayjs(left, right) {
59
+ return left.isAfter(right) ? left : right;
60
+ }
61
+ function minDayjs(left, right) {
62
+ return left.isBefore(right) ? left : right;
63
+ }
64
+ function addDays(start, end) {
65
+ const result = [];
66
+ let cursor = (0, _dayjs.default)(start);
67
+ const finalDay = (0, _dayjs.default)(end);
68
+ while (!cursor.isAfter(finalDay, 'day')) {
69
+ result.push(cursor.format('YYYY-MM-DD'));
70
+ cursor = cursor.add(1, 'day');
71
+ }
72
+ return result;
73
+ }
74
+ function getQueryProducts(products, query) {
75
+ if (!query.productIds?.length) return products;
76
+ return products.filter(product => query.productIds.some(id => sameId(id, product.id)));
77
+ }
78
+ function getQueryResources(resources, query) {
79
+ if (!query.resourceIds?.length) return resources;
80
+ return resources.filter(resource => query.resourceIds.some(id => sameId(id, resource.id)));
81
+ }
82
+ function matchesResourceRequirement(resource, requirement) {
83
+ const isFormlessCandidate = resource.formId == null;
84
+ const formMatches = requirement.formId == null || isFormlessCandidate || sameId(requirement.formId, resource.formId);
85
+ const resourceMatches = !requirement.resourceIds?.length || isFormlessCandidate || requirement.resourceIds.some(id => sameId(id, resource.id));
86
+ return formMatches && resourceMatches;
87
+ }
88
+ function resolveProductTitle(product) {
89
+ const rawTitle = product.raw?.title || product.raw?.name || product.raw?.product_title;
90
+ if (typeof product.title === 'string') return product.title;
91
+ if (typeof rawTitle === 'string') return rawTitle;
92
+ if (rawTitle && typeof rawTitle === 'object') {
93
+ return rawTitle.en || rawTitle.zh || rawTitle.default || Object.values(rawTitle)[0];
94
+ }
95
+ return undefined;
96
+ }
97
+ function buildDemandIntervals(products, query, context) {
98
+ const dates = query.date ? [query.date] : query.dateRange ? addDays(query.dateRange.start, query.dateRange.end) : [];
99
+ const selectedProducts = getQueryProducts(products, query);
100
+ const intervals = [];
101
+ for (const product of selectedProducts) {
102
+ const quantity = Math.max(1, Number(product.quantity || 1));
103
+ const capacityRequired = Math.max(1, Number(query.pax || product.capacityRequired || 1));
104
+ const requirements = product.resourceRequirements || [];
105
+ if (product.kind === 'session' || product.kind === 'venue_slot') {
106
+ const schedules = product.schedule || [];
107
+ for (const schedule of schedules) {
108
+ const scheduleDate = dateOf(schedule.start_at);
109
+ if (dates.length > 0 && !dates.includes(scheduleDate)) continue;
110
+ const start = (0, _dayjs.default)(schedule.start_at);
111
+ const end = (0, _dayjs.default)(schedule.end_at);
112
+ intervals.push({
113
+ id: `${product.id}:${start.toISOString()}:${end.toISOString()}`,
114
+ productId: product.id,
115
+ source: product.kind,
116
+ date: dateOf(schedule.start_at),
117
+ start_at: start.toISOString(),
118
+ end_at: end.toISOString(),
119
+ durationMinutes: Math.max(1, end.diff(start, 'minute')),
120
+ quantity,
121
+ capacityRequired,
122
+ resourceRequirements: requirements
123
+ });
124
+ }
125
+ continue;
126
+ }
127
+ if (product.kind === 'duration') {
128
+ const duration = Math.max(1, Number(product.durationMinutes || 30));
129
+ for (const currentDate of dates) {
130
+ const start = query.startTime ? toDateTime(currentDate, query.startTime) : toDateTime(currentDate, context?.businessStartTime || DEFAULT_RESOURCE_PLANNER_CONTEXT.businessStartTime);
131
+ let end = query.startTime && query.endTime ? toDateTime(currentDate, query.endTime) : query.startTime ? start.add(duration, 'minute') : toDateTime(currentDate, context?.businessEndTime || DEFAULT_RESOURCE_PLANNER_CONTEXT.businessEndTime);
132
+ if (!end.isAfter(start)) end = end.add(1, 'day');
133
+ intervals.push({
134
+ id: `${product.id}:${currentDate}:${query.startTime || 'range'}`,
135
+ productId: product.id,
136
+ source: 'duration',
137
+ date: currentDate,
138
+ start_at: start.toISOString(),
139
+ end_at: end.toISOString(),
140
+ durationMinutes: duration,
141
+ quantity,
142
+ capacityRequired,
143
+ resourceRequirements: requirements
144
+ });
145
+ }
146
+ }
147
+ }
148
+ return intervals;
149
+ }
150
+ function getEventsForResource(resource, contextEvents) {
151
+ const embeddedEvents = resource.times.flatMap(time => time.event_list || []);
152
+ return [...embeddedEvents, ...contextEvents.filter(event => sameId(event.resourceId ?? event.resource_id, resource.id))].filter(Boolean);
153
+ }
154
+ function collectEventsByResource(resources, contextEvents) {
155
+ const eventsByResource = new Map();
156
+ resources.forEach(resource => {
157
+ eventsByResource.set(String(resource.id), getEventsForResource(resource, contextEvents));
158
+ });
159
+ return eventsByResource;
160
+ }
161
+ function getWorkingSegmentsForInterval(resource, interval) {
162
+ const intervalStart = (0, _dayjs.default)(interval.start_at);
163
+ const intervalEnd = (0, _dayjs.default)(interval.end_at);
164
+ return resource.times.map(time => {
165
+ const start = maxDayjs((0, _dayjs.default)(time.start_at), intervalStart);
166
+ const end = minDayjs((0, _dayjs.default)(time.end_at), intervalEnd);
167
+ return {
168
+ start,
169
+ end
170
+ };
171
+ }).filter(segment => segment.end.isAfter(segment.start));
172
+ }
173
+ function mergeBusySegments(segments) {
174
+ const sorted = [...segments].filter(segment => segment.end.isAfter(segment.start)).sort((left, right) => left.start.valueOf() - right.start.valueOf());
175
+ const merged = [];
176
+ sorted.forEach(segment => {
177
+ const previous = merged[merged.length - 1];
178
+ if (previous && !segment.start.isAfter(previous.end)) {
179
+ previous.end = maxDayjs(previous.end, segment.end);
180
+ } else {
181
+ merged.push({
182
+ ...segment
183
+ });
184
+ }
185
+ });
186
+ return merged;
187
+ }
188
+ function subtractBusyIntervals(workingSegments, events) {
189
+ const available = [];
190
+ workingSegments.forEach(working => {
191
+ const busySegments = mergeBusySegments(events.filter(event => overlaps(working.start, working.end, (0, _dayjs.default)(event.start_at), (0, _dayjs.default)(event.end_at))).map(event => ({
192
+ start: maxDayjs((0, _dayjs.default)(event.start_at), working.start),
193
+ end: minDayjs((0, _dayjs.default)(event.end_at), working.end)
194
+ })));
195
+ let cursor = working.start;
196
+ busySegments.forEach(busy => {
197
+ if (busy.start.isAfter(cursor)) {
198
+ available.push({
199
+ start: cursor,
200
+ end: busy.start
201
+ });
202
+ }
203
+ if (busy.end.isAfter(cursor)) cursor = busy.end;
204
+ });
205
+ if (working.end.isAfter(cursor)) {
206
+ available.push({
207
+ start: cursor,
208
+ end: working.end
209
+ });
210
+ }
211
+ });
212
+ return available;
213
+ }
214
+ function buildCapacityRanges(params) {
215
+ const {
216
+ workingSegments,
217
+ events,
218
+ maxCapacity,
219
+ requiredCapacity
220
+ } = params;
221
+ const ranges = [];
222
+ workingSegments.forEach(working => {
223
+ const boundaries = new Map([[working.start.valueOf(), working.start], [working.end.valueOf(), working.end]]);
224
+ events.forEach(event => {
225
+ const eventStart = (0, _dayjs.default)(event.start_at);
226
+ const eventEnd = (0, _dayjs.default)(event.end_at);
227
+ if (!overlaps(working.start, working.end, eventStart, eventEnd)) return;
228
+ const clippedStart = maxDayjs(eventStart, working.start);
229
+ const clippedEnd = minDayjs(eventEnd, working.end);
230
+ boundaries.set(clippedStart.valueOf(), clippedStart);
231
+ boundaries.set(clippedEnd.valueOf(), clippedEnd);
232
+ });
233
+ const points = Array.from(boundaries.values()).sort((left, right) => left.valueOf() - right.valueOf());
234
+ for (let index = 0; index < points.length - 1; index += 1) {
235
+ const start = points[index];
236
+ const end = points[index + 1];
237
+ if (!end.isAfter(start)) continue;
238
+ const usedCapacity = events.filter(event => overlaps(start, end, (0, _dayjs.default)(event.start_at), (0, _dayjs.default)(event.end_at))).reduce((sum, event) => sum + Math.max(1, Number(event.pax || 1)), 0);
239
+ const remainingCapacity = Math.max(0, maxCapacity - usedCapacity);
240
+ if (remainingCapacity < requiredCapacity) continue;
241
+ const status = remainingCapacity < maxCapacity ? 'limited' : 'available';
242
+ const previous = ranges[ranges.length - 1];
243
+ if (previous && previous.end.isSame(start) && previous.remainingCapacity === remainingCapacity && previous.maxCapacity === maxCapacity && previous.status === status) {
244
+ previous.end = end;
245
+ } else {
246
+ ranges.push({
247
+ start,
248
+ end,
249
+ remainingCapacity,
250
+ maxCapacity,
251
+ status
252
+ });
253
+ }
254
+ }
255
+ });
256
+ return ranges;
257
+ }
258
+ function rangeFitsDuration(segment, durationMinutes) {
259
+ return segment.end.diff(segment.start, 'minute') >= durationMinutes;
260
+ }
261
+ function makeAvailabilityRangeCell(params) {
262
+ const {
263
+ interval,
264
+ resource,
265
+ segment
266
+ } = params;
267
+ const maxCapacity = Math.max(1, Number(segment.maxCapacity || resource.capacity || 1));
268
+ const remainingCapacity = resource.resourceType === 'single' ? 1 : Math.max(0, Number(segment.remainingCapacity ?? maxCapacity));
269
+ const status = resource.resourceType === 'single' ? 'available' : segment.status || (remainingCapacity < maxCapacity ? 'limited' : 'available');
270
+ return {
271
+ key: `${interval.productId}:${resource.id}:${segment.start.toISOString()}:${segment.end.toISOString()}`,
272
+ productId: interval.productId,
273
+ resourceId: resource.id,
274
+ date: interval.date,
275
+ start_at: segment.start.toISOString(),
276
+ end_at: segment.end.toISOString(),
277
+ startTime: segment.start.format('HH:mm'),
278
+ endTime: segment.end.format('HH:mm'),
279
+ durationMinutes: interval.durationMinutes,
280
+ cellType: 'availability_range',
281
+ status,
282
+ remainingCapacity,
283
+ maxCapacity,
284
+ reasonCodes: [],
285
+ conflicts: []
286
+ };
287
+ }
288
+ function buildAvailabilityCellsForResource(params) {
289
+ const {
290
+ resource,
291
+ interval,
292
+ events
293
+ } = params;
294
+ const requiredCapacity = Math.max(1, Number(interval.capacityRequired || 1));
295
+ const durationMinutes = Math.max(1, Number(interval.durationMinutes || 1));
296
+ const maxCapacity = Math.max(1, Number(resource.capacity || 1));
297
+ let workingSegments = getWorkingSegmentsForInterval(resource, interval);
298
+ const now = (0, _dayjs.default)();
299
+ workingSegments = workingSegments.map(segment => ({
300
+ start: segment.end.isAfter(now) ? maxDayjs(segment.start, now) : segment.start,
301
+ end: segment.end
302
+ })).filter(segment => segment.end.isAfter(segment.start));
303
+ const availableSegments = resource.resourceType === 'single' ? subtractBusyIntervals(workingSegments, events).map(segment => ({
304
+ ...segment,
305
+ remainingCapacity: 1,
306
+ maxCapacity: 1,
307
+ status: 'available'
308
+ })) : buildCapacityRanges({
309
+ workingSegments,
310
+ events,
311
+ maxCapacity,
312
+ requiredCapacity
313
+ });
314
+ return availableSegments.filter(segment => rangeFitsDuration(segment, durationMinutes)).map(segment => makeAvailabilityRangeCell({
315
+ interval,
316
+ resource,
317
+ segment
318
+ }));
319
+ }
320
+ function evaluateResourceForInterval(params) {
321
+ const {
322
+ resource,
323
+ interval,
324
+ context
325
+ } = params;
326
+ const start = (0, _dayjs.default)(interval.start_at);
327
+ const end = (0, _dayjs.default)(interval.end_at);
328
+ const conflicts = [];
329
+ const reasonCodes = [];
330
+ const maxCapacity = Math.max(1, Number(resource.capacity || 1));
331
+ const requiredCapacity = Math.max(1, Number(interval.capacityRequired || 1));
332
+ if (start.isBefore((0, _dayjs.default)())) {
333
+ reasonCodes.push('past');
334
+ conflicts.push({
335
+ type: 'past',
336
+ message: '时间已过期',
337
+ resourceId: resource.id,
338
+ productId: interval.productId
339
+ });
340
+ }
341
+ const insideResourceTime = resource.times.some(time => {
342
+ return containsRange((0, _dayjs.default)(time.start_at), (0, _dayjs.default)(time.end_at), start, end);
343
+ });
344
+ if (!insideResourceTime) {
345
+ reasonCodes.push('outside_resource_time');
346
+ conflicts.push({
347
+ type: 'outside_resource_time',
348
+ message: '所选时间不在资源可用时间内',
349
+ resourceId: resource.id,
350
+ productId: interval.productId
351
+ });
352
+ }
353
+ const events = getEventsForResource(resource, context.externalEvents);
354
+ const overlapping = events.filter(event => overlaps(start, end, (0, _dayjs.default)(event.start_at), (0, _dayjs.default)(event.end_at)));
355
+ const usedCapacity = resource.resourceType === 'single' ? overlapping.length : overlapping.reduce((sum, event) => sum + Math.max(1, Number(event.pax || 1)), 0);
356
+ const remainingCapacity = resource.resourceType === 'single' ? overlapping.length > 0 ? 0 : 1 : Math.max(0, maxCapacity - usedCapacity);
357
+ if (overlapping.length > 0 && resource.resourceType === 'single') {
358
+ reasonCodes.push('remote_event_overlap');
359
+ conflicts.push(...overlapping.map(event => ({
360
+ type: 'remote_event_overlap',
361
+ message: '资源时间被已有预约占用',
362
+ event,
363
+ resourceId: resource.id,
364
+ productId: interval.productId
365
+ })));
366
+ }
367
+ if (resource.resourceType !== 'single' && remainingCapacity < requiredCapacity) {
368
+ reasonCodes.push('capacity_full');
369
+ conflicts.push({
370
+ type: 'capacity_full',
371
+ message: '资源剩余容量不足',
372
+ resourceId: resource.id,
373
+ productId: interval.productId
374
+ });
375
+ }
376
+ let status = 'available';
377
+ if (reasonCodes.includes('past')) status = 'past';else if (reasonCodes.includes('outside_resource_time')) status = 'unavailable';else if (reasonCodes.includes('remote_event_overlap') || reasonCodes.includes('capacity_full')) {
378
+ status = 'full';
379
+ } else if (remainingCapacity < maxCapacity) {
380
+ status = 'limited';
381
+ }
382
+ return {
383
+ key: `${interval.productId}:${resource.id}:${interval.start_at}:${interval.end_at}`,
384
+ productId: interval.productId,
385
+ resourceId: resource.id,
386
+ date: interval.date,
387
+ start_at: interval.start_at,
388
+ end_at: interval.end_at,
389
+ startTime: timeOf(interval.start_at),
390
+ endTime: timeOf(interval.end_at),
391
+ durationMinutes: interval.durationMinutes,
392
+ cellType: status === 'available' || status === 'limited' ? 'fixed_interval' : 'unavailable',
393
+ status,
394
+ remainingCapacity,
395
+ maxCapacity,
396
+ reasonCodes,
397
+ conflicts
398
+ };
399
+ }
400
+ function aggregateStatus(cells) {
401
+ if (!cells.length) return 'unavailable';
402
+ if (cells.some(cell => cell.status === 'available')) return 'available';
403
+ if (cells.some(cell => cell.status === 'limited')) return 'limited';
404
+ if (cells.some(cell => cell.status === 'past')) return 'past';
405
+ if (cells.some(cell => cell.status === 'full')) return 'full';
406
+ if (cells.some(cell => cell.status === 'conflict')) return 'conflict';
407
+ return 'unavailable';
408
+ }
409
+ function uniqueReasonCodes(cells) {
410
+ return Array.from(new Set(cells.flatMap(cell => cell.reasonCodes || [])));
411
+ }
412
+ function buildProductOptions(products, cells, query) {
413
+ const queryProducts = getQueryProducts(products, query);
414
+ return queryProducts.map(product => {
415
+ const productCells = cells.filter(cell => sameId(cell.productId, product.id));
416
+ const status = product.kind === 'normal' ? 'available' : aggregateStatus(productCells);
417
+ return {
418
+ productId: product.id,
419
+ title: resolveProductTitle(product),
420
+ status,
421
+ reasonCodes: uniqueReasonCodes(productCells)
422
+ };
423
+ });
424
+ }
425
+ function buildResourceOptions(resources, cells, query) {
426
+ const queryResources = getQueryResources(resources, query);
427
+ return queryResources.map(resource => {
428
+ const resourceCells = cells.filter(cell => cell.resourceId !== undefined && sameId(cell.resourceId, resource.id));
429
+ const bestCell = resourceCells.find(cell => cell.status === 'available') || resourceCells.find(cell => cell.status === 'limited') || resourceCells[0];
430
+ return {
431
+ resourceId: resource.id,
432
+ resourceName: resource.name,
433
+ resourceFormId: resource.formId,
434
+ resourceType: resource.resourceType,
435
+ status: resourceCells.length ? aggregateStatus(resourceCells) : 'unavailable',
436
+ remainingCapacity: bestCell?.remainingCapacity,
437
+ maxCapacity: bestCell?.maxCapacity || resource.capacity,
438
+ reasonCodes: uniqueReasonCodes(resourceCells)
439
+ };
440
+ });
441
+ }
442
+ function buildDateSummary(cells, query) {
443
+ const dates = query.date ? [query.date] : query.dateRange ? addDays(query.dateRange.start, query.dateRange.end) : Array.from(new Set(cells.map(cell => cell.date).filter(Boolean)));
444
+ return dates.map(date => {
445
+ const dateCells = cells.filter(cell => cell.date === date);
446
+ const availableCount = dateCells.filter(cell => cell.status === 'available' || cell.status === 'limited').length;
447
+ return {
448
+ date,
449
+ status: dateCells.length ? aggregateStatus(dateCells) : 'unavailable',
450
+ availableCount,
451
+ totalCount: dateCells.length
452
+ };
453
+ });
454
+ }
455
+ function buildTimeLabels(date, context, query) {
456
+ if (!date) return [];
457
+ const slotMinutes = query.slotDurationMinutes || context.slotDurationMinutes;
458
+ const labels = [];
459
+ let cursor = toDateTime(date, context.businessStartTime);
460
+ let end = toDateTime(date, context.businessEndTime);
461
+ if (!end.isAfter(cursor)) end = end.add(1, 'day');
462
+ while (cursor.isBefore(end)) {
463
+ labels.push(cursor.format('HH:mm'));
464
+ cursor = cursor.add(slotMinutes, 'minute');
465
+ }
466
+ return labels;
467
+ }
468
+ function buildGridSlotInterval(product, date, label, context, query) {
469
+ const slotMinutes = product.kind === 'duration' ? Math.max(1, Number(product.durationMinutes || query.slotDurationMinutes || context.slotDurationMinutes)) : query.slotDurationMinutes || context.slotDurationMinutes;
470
+ const start = toDateTime(date, label);
471
+ const end = start.add(slotMinutes, 'minute');
472
+ return {
473
+ id: `${product.id}:${date}:${label}`,
474
+ productId: product.id,
475
+ source: product.kind === 'session' ? 'session' : product.kind === 'venue_slot' ? 'venue_slot' : 'duration',
476
+ date,
477
+ start_at: start.toISOString(),
478
+ end_at: end.toISOString(),
479
+ durationMinutes: slotMinutes,
480
+ quantity: Math.max(1, Number(product.quantity || 1)),
481
+ capacityRequired: Math.max(1, Number(query.pax || product.capacityRequired || 1)),
482
+ resourceRequirements: product.resourceRequirements || []
483
+ };
484
+ }
485
+ function buildTimeGrid(context, query, cells) {
486
+ const date = query.date || query.dateRange?.start;
487
+ const products = getQueryProducts(context.products, query).filter(product => product.kind !== 'normal');
488
+ const resources = getQueryResources(context.resources, query);
489
+ const timeLabels = buildTimeLabels(date, context, query);
490
+ if (!date || !products.length || !resources.length) {
491
+ return {
492
+ date,
493
+ timeLabels,
494
+ resources: []
495
+ };
496
+ }
497
+ const rows = resources.map(resource => {
498
+ const slots = timeLabels.map(label => {
499
+ const product = products[0];
500
+ const interval = buildGridSlotInterval(product, date, label, context, query);
501
+ const start = (0, _dayjs.default)(interval.start_at);
502
+ const end = (0, _dayjs.default)(interval.end_at);
503
+ const cell = cells.find(item => sameId(item.productId, product.id) && sameId(item.resourceId, resource.id) && item.date === date && (item.status === 'available' || item.status === 'limited') && containsRange((0, _dayjs.default)(item.start_at), (0, _dayjs.default)(item.end_at), start, end));
504
+ return {
505
+ startTime: label,
506
+ endTime: (0, _dayjs.default)(interval.end_at).format('HH:mm'),
507
+ status: cell?.status || 'unavailable',
508
+ resourceId: resource.id,
509
+ productId: product.id,
510
+ remainingCapacity: cell?.remainingCapacity,
511
+ maxCapacity: cell?.maxCapacity || resource.capacity,
512
+ reasonCodes: cell?.reasonCodes || ['outside_available_range']
513
+ };
514
+ });
515
+ return {
516
+ resourceId: resource.id,
517
+ resourceName: resource.name,
518
+ resourceFormId: resource.formId,
519
+ slots
520
+ };
521
+ });
522
+ return {
523
+ date,
524
+ timeLabels,
525
+ resources: rows
526
+ };
527
+ }
528
+ function queryPlannerAvailability(contextInput, query = {}) {
529
+ const context = normalizePlannerContext(contextInput);
530
+ const intervals = buildDemandIntervals(context.products, query, context);
531
+ const resources = getQueryResources(context.resources, query);
532
+ const eventsByResource = collectEventsByResource(resources, context.externalEvents);
533
+ const cells = [];
534
+ for (const interval of intervals) {
535
+ const candidateResources = resources.filter(resource => {
536
+ const requirements = interval.resourceRequirements || [];
537
+ if (!requirements.length) return true;
538
+ return requirements.some(requirement => matchesResourceRequirement(resource, requirement));
539
+ });
540
+ if (!candidateResources.length) {
541
+ cells.push({
542
+ key: `${interval.productId}:missing-resource:${interval.start_at}`,
543
+ productId: interval.productId,
544
+ date: interval.date,
545
+ start_at: interval.start_at,
546
+ end_at: interval.end_at,
547
+ startTime: timeOf(interval.start_at),
548
+ endTime: timeOf(interval.end_at),
549
+ durationMinutes: interval.durationMinutes,
550
+ cellType: 'unavailable',
551
+ status: 'unavailable',
552
+ reasonCodes: ['missing_resource'],
553
+ conflicts: [{
554
+ type: 'missing_resource',
555
+ message: '没有匹配商品需求的资源',
556
+ productId: interval.productId
557
+ }]
558
+ });
559
+ continue;
560
+ }
561
+ candidateResources.forEach(resource => {
562
+ if (interval.source === 'duration' && !query.startTime) {
563
+ cells.push(...buildAvailabilityCellsForResource({
564
+ resource,
565
+ interval,
566
+ events: eventsByResource.get(String(resource.id)) || []
567
+ }));
568
+ return;
569
+ }
570
+ cells.push(evaluateResourceForInterval({
571
+ resource,
572
+ interval,
573
+ context
574
+ }));
575
+ });
576
+ }
577
+ return {
578
+ query,
579
+ demandIntervals: intervals,
580
+ productOptions: buildProductOptions(context.products, cells, query),
581
+ resourceOptions: buildResourceOptions(context.resources, cells, query),
582
+ dateSummary: buildDateSummary(cells, query),
583
+ timeGrid: buildTimeGrid(context, query, cells),
584
+ cells
585
+ };
586
+ }
587
+ function getIntervalRequirements(interval) {
588
+ return interval.resourceRequirements.length ? interval.resourceRequirements : [{
589
+ capacityRequired: interval.capacityRequired,
590
+ required: true
591
+ }];
592
+ }
593
+ function buildAssignableCandidateGroups(params) {
594
+ const {
595
+ interval,
596
+ cells,
597
+ resources
598
+ } = params;
599
+ const conflicts = [];
600
+ const groups = getIntervalRequirements(interval).map(requirement => {
601
+ const candidateCells = cells.filter(cell => {
602
+ if (!sameId(cell.productId, interval.productId)) return false;
603
+ if (cell.date !== interval.date) return false;
604
+ if (cell.resourceId === undefined) return false;
605
+ if (cell.status !== 'available' && cell.status !== 'limited') return false;
606
+ const cellStart = (0, _dayjs.default)(cell.start_at);
607
+ const cellEnd = (0, _dayjs.default)(cell.end_at);
608
+ const intervalStart = (0, _dayjs.default)(interval.start_at);
609
+ const intervalEnd = (0, _dayjs.default)(interval.end_at);
610
+ return containsRange(cellStart, cellEnd, intervalStart, intervalEnd) || interval.source === 'duration';
611
+ });
612
+ return candidateCells.flatMap(cell => {
613
+ const resource = resources.find(item => sameId(item.id, cell.resourceId));
614
+ if (!resource || !matchesResourceRequirement(resource, requirement)) return [];
615
+ return [{
616
+ requirement,
617
+ resource,
618
+ cell
619
+ }];
620
+ });
621
+ });
622
+ groups.forEach((group, index) => {
623
+ if (group.length) return;
624
+ conflicts.push({
625
+ type: 'missing_resource',
626
+ message: '没有匹配商品需求的可用资源',
627
+ productId: interval.productId,
628
+ resourceId: interval.resourceRequirements[index]?.resourceIds?.[0]
629
+ });
630
+ });
631
+ return {
632
+ groups,
633
+ conflicts
634
+ };
635
+ }
636
+ function combineCandidateGroups(groups) {
637
+ if (!groups.length || groups.some(group => group.length === 0)) return [];
638
+ return groups.reduce((combinations, group) => combinations.flatMap(combination => group.map(candidate => [...combination, candidate])), [[]]);
639
+ }
640
+ function buildSlotFromCandidates(params) {
641
+ const {
642
+ interval,
643
+ candidates,
644
+ start,
645
+ end
646
+ } = params;
647
+ if (!end.isAfter(start)) return null;
648
+ const status = candidates.some(candidate => candidate.cell.status === 'limited') ? 'limited' : 'available';
649
+ const assignments = candidates.map(candidate => ({
650
+ productId: interval.productId,
651
+ resourceId: candidate.resource.id,
652
+ start_at: start.toISOString(),
653
+ end_at: end.toISOString(),
654
+ capacityRequired: Math.max(1, Number(candidate.requirement.capacityRequired || interval.capacityRequired || 1))
655
+ }));
656
+ return {
657
+ key: [interval.productId, start.toISOString(), end.toISOString(), ...candidates.map(candidate => candidate.resource.id)].join(':'),
658
+ productId: interval.productId,
659
+ date: interval.date,
660
+ start_at: start.toISOString(),
661
+ end_at: end.toISOString(),
662
+ startTime: start.format('HH:mm'),
663
+ endTime: end.format('HH:mm'),
664
+ durationMinutes: Math.max(1, end.diff(start, 'minute')),
665
+ status,
666
+ resources: candidates.map(candidate => ({
667
+ resourceId: candidate.resource.id,
668
+ resourceName: candidate.resource.name,
669
+ resourceFormId: candidate.resource.formId,
670
+ resourceType: candidate.resource.resourceType,
671
+ capacityRequired: Math.max(1, Number(candidate.requirement.capacityRequired || interval.capacityRequired || 1)),
672
+ remainingCapacity: candidate.cell.remainingCapacity,
673
+ maxCapacity: candidate.cell.maxCapacity
674
+ })),
675
+ assignments,
676
+ conflicts: []
677
+ };
678
+ }
679
+ function buildSlotsForInterval(params) {
680
+ const {
681
+ interval,
682
+ candidates,
683
+ query,
684
+ context
685
+ } = params;
686
+ const start = candidates.reduce((current, candidate) => maxDayjs(current, (0, _dayjs.default)(candidate.cell.start_at)), (0, _dayjs.default)(interval.start_at));
687
+ const end = candidates.reduce((current, candidate) => minDayjs(current, (0, _dayjs.default)(candidate.cell.end_at)), (0, _dayjs.default)(interval.end_at));
688
+ const durationMinutes = Math.max(1, Number(interval.durationMinutes || 1));
689
+ if (interval.source !== 'duration' || query.startTime) {
690
+ const fixedStart = (0, _dayjs.default)(interval.start_at);
691
+ const fixedEnd = (0, _dayjs.default)(interval.end_at);
692
+ if (containsRange(start, end, fixedStart, fixedEnd) || candidates.every(candidate => candidate.cell.cellType === 'fixed_interval')) {
693
+ const slot = buildSlotFromCandidates({
694
+ interval,
695
+ candidates,
696
+ start: fixedStart,
697
+ end: fixedEnd
698
+ });
699
+ return slot ? [slot] : [];
700
+ }
701
+ return [];
702
+ }
703
+ const stepMinutes = Math.max(1, Number(query.slotDurationMinutes || context.slotDurationMinutes || 30));
704
+ const slots = [];
705
+ let cursor = start;
706
+ while (!cursor.add(durationMinutes, 'minute').isAfter(end)) {
707
+ const slotEnd = cursor.add(durationMinutes, 'minute');
708
+ const slot = buildSlotFromCandidates({
709
+ interval,
710
+ candidates,
711
+ start: cursor,
712
+ end: slotEnd
713
+ });
714
+ if (slot) slots.push(slot);
715
+ cursor = cursor.add(stepMinutes, 'minute');
716
+ }
717
+ return slots;
718
+ }
719
+ function resolveAssignableSlots(contextInput, query = {}) {
720
+ const context = normalizePlannerContext(contextInput);
721
+ const projection = queryPlannerAvailability(context, query);
722
+ const resources = getQueryResources(context.resources, query);
723
+ const slotsByKey = new Map();
724
+ const conflicts = [];
725
+ projection.demandIntervals.forEach(interval => {
726
+ const {
727
+ groups,
728
+ conflicts: groupConflicts
729
+ } = buildAssignableCandidateGroups({
730
+ interval,
731
+ cells: projection.cells,
732
+ resources
733
+ });
734
+ conflicts.push(...groupConflicts);
735
+ combineCandidateGroups(groups).forEach(candidates => {
736
+ buildSlotsForInterval({
737
+ interval,
738
+ candidates,
739
+ query,
740
+ context
741
+ }).forEach(slot => {
742
+ if (!slotsByKey.has(slot.key)) slotsByKey.set(slot.key, slot);
743
+ });
744
+ });
745
+ });
746
+ return {
747
+ projection,
748
+ slots: Array.from(slotsByKey.values()),
749
+ conflicts
750
+ };
751
+ }
752
+ function autoAssignResources(contextInput, query = {}) {
753
+ const baseContext = normalizePlannerContext(contextInput);
754
+ const projection = queryPlannerAvailability(baseContext, query);
755
+ const assignments = [];
756
+ const conflicts = [];
757
+ const missingTimeProductIds = new Set();
758
+ for (const interval of projection.demandIntervals) {
759
+ if (interval.source === 'duration' && !query.startTime) {
760
+ const productKey = String(interval.productId);
761
+ if (!missingTimeProductIds.has(productKey)) {
762
+ missingTimeProductIds.add(productKey);
763
+ conflicts.push({
764
+ type: 'missing_time',
765
+ message: 'duration 商品需要先确定开始时间后才能自动分配资源',
766
+ productId: interval.productId
767
+ });
768
+ }
769
+ continue;
770
+ }
771
+ const contextWithAssignments = withAssignmentEvents(baseContext, assignments);
772
+ const candidateResources = getQueryResources(contextWithAssignments.resources, query).filter(resource => {
773
+ const requirements = interval.resourceRequirements || [];
774
+ if (!requirements.length) return true;
775
+ return requirements.some(requirement => matchesResourceRequirement(resource, requirement));
776
+ });
777
+ const availableCell = candidateResources.map(resource => evaluateResourceForInterval({
778
+ resource,
779
+ interval,
780
+ context: contextWithAssignments
781
+ })).find(cell => cell.status === 'available' || cell.status === 'limited');
782
+ if (!availableCell?.resourceId) {
783
+ conflicts.push({
784
+ type: 'missing_resource',
785
+ message: '无法为商品自动分配可用资源',
786
+ productId: interval.productId
787
+ });
788
+ continue;
789
+ }
790
+ assignments.push({
791
+ productId: interval.productId,
792
+ resourceId: availableCell.resourceId,
793
+ start_at: interval.start_at,
794
+ end_at: interval.end_at,
795
+ capacityRequired: interval.capacityRequired
796
+ });
797
+ }
798
+ return {
799
+ assignments,
800
+ conflicts
801
+ };
802
+ }
803
+ function withAssignmentEvents(context, assignments) {
804
+ if (!assignments.length) return context;
805
+ return {
806
+ ...context,
807
+ externalEvents: [...context.externalEvents, ...assignments.map(assignment => ({
808
+ resourceId: assignment.resourceId,
809
+ start_at: assignment.start_at,
810
+ end_at: assignment.end_at,
811
+ pax: assignment.capacityRequired || 1,
812
+ source: 'selection'
813
+ }))]
814
+ };
815
+ }
816
+ function validateAssignments(contextInput, selection) {
817
+ if (selection.assignments.length > 0) {
818
+ const context = normalizePlannerContext(contextInput);
819
+ const conflicts = [];
820
+ for (let index = 0; index < selection.assignments.length; index += 1) {
821
+ const assignment = selection.assignments[index];
822
+ const product = context.products.find(item => sameId(item.id, assignment.productId));
823
+ const resource = context.resources.find(item => sameId(item.id, assignment.resourceId));
824
+ if (!product) {
825
+ conflicts.push({
826
+ type: 'missing_resource',
827
+ message: 'assignment 对应的商品不存在',
828
+ productId: assignment.productId
829
+ });
830
+ continue;
831
+ }
832
+ if (!resource) {
833
+ conflicts.push({
834
+ type: 'missing_resource',
835
+ message: 'assignment 对应的资源不存在',
836
+ productId: assignment.productId,
837
+ resourceId: assignment.resourceId
838
+ });
839
+ continue;
840
+ }
841
+ const start = (0, _dayjs.default)(assignment.start_at);
842
+ const end = (0, _dayjs.default)(assignment.end_at);
843
+ const interval = {
844
+ id: `${assignment.productId}:${assignment.resourceId}:${assignment.start_at}:${assignment.end_at}`,
845
+ productId: assignment.productId,
846
+ source: product.kind === 'session' ? 'session' : product.kind === 'venue_slot' ? 'venue_slot' : 'duration',
847
+ date: start.format('YYYY-MM-DD'),
848
+ start_at: assignment.start_at,
849
+ end_at: assignment.end_at,
850
+ durationMinutes: Math.max(1, end.diff(start, 'minute')),
851
+ quantity: Math.max(1, Number(product.quantity || 1)),
852
+ capacityRequired: Math.max(1, Number(assignment.capacityRequired || product.capacityRequired || 1)),
853
+ resourceRequirements: product.resourceRequirements || []
854
+ };
855
+ const cell = evaluateResourceForInterval({
856
+ resource,
857
+ interval,
858
+ context
859
+ });
860
+ if (cell.status !== 'available' && cell.status !== 'limited') {
861
+ conflicts.push(...cell.conflicts);
862
+ }
863
+ const priorContext = withAssignmentEvents(context, selection.assignments.slice(0, index));
864
+ const selfConflictCell = evaluateResourceForInterval({
865
+ resource,
866
+ interval,
867
+ context: priorContext
868
+ });
869
+ if (selfConflictCell.status !== 'available' && selfConflictCell.status !== 'limited') {
870
+ conflicts.push(...selfConflictCell.conflicts.map(conflict => ({
871
+ ...conflict,
872
+ type: 'cart_overlap',
873
+ message: '本次选择中存在资源时间冲突'
874
+ })));
875
+ }
876
+ }
877
+ return {
878
+ ok: conflicts.length === 0,
879
+ conflicts
880
+ };
881
+ }
882
+ const projection = queryPlannerAvailability(contextInput, {
883
+ productIds: selection.productIds,
884
+ date: selection.date,
885
+ startTime: selection.startTime,
886
+ endTime: selection.endTime,
887
+ resourceIds: selection.resourceIds,
888
+ mode: selection.mode
889
+ });
890
+ const conflicts = projection.cells.filter(cell => cell.status !== 'available' && cell.status !== 'limited').flatMap(cell => cell.conflicts);
891
+ return {
892
+ ok: conflicts.length === 0,
893
+ conflicts
894
+ };
895
+ }