@pisell/pisellos 2.3.74 → 2.3.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/dist/core/index.js +6 -10
  2. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  3. package/dist/model/strategy/adapter/walletPass/example.js +3 -26
  4. package/dist/model/strategy/strategy-example.js +5 -19
  5. package/dist/modules/Cart/index.js +0 -3
  6. package/dist/modules/Cart/utils/cartProduct.js +0 -1
  7. package/dist/modules/Date/index.js +1 -5
  8. package/dist/modules/Discount/index.js +2 -4
  9. package/dist/modules/OpenData/index.js +0 -2
  10. package/dist/modules/Order/index.d.ts +1 -1
  11. package/dist/modules/Order/index.js +75 -91
  12. package/dist/modules/Order/types.d.ts +3 -1
  13. package/dist/modules/Payment/index.js +97 -162
  14. package/dist/modules/Rules/index.js +1 -4
  15. package/dist/modules/Schedule/index.js +0 -1
  16. package/dist/modules/Schedule/utils.js +0 -1
  17. package/dist/modules/Step/index.js +0 -1
  18. package/dist/plugins/request.js +1 -4
  19. package/dist/plugins/window.js +2 -6
  20. package/dist/server/index.js +97 -129
  21. package/dist/server/modules/menu/index.js +32 -41
  22. package/dist/server/modules/order/index.js +2 -4
  23. package/dist/server/modules/products/index.js +24 -42
  24. package/dist/server/modules/quotation/index.js +29 -38
  25. package/dist/server/modules/resource/index.js +3 -4
  26. package/dist/server/modules/schedule/index.js +27 -35
  27. package/dist/server/utils/product.js +0 -1
  28. package/dist/solution/BaseSales/index.js +100 -72
  29. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +5 -0
  30. package/dist/solution/BaseSales/utils/cartPromotion.js +15 -6
  31. package/dist/solution/BookingByStep/index.js +7 -59
  32. package/dist/solution/BookingByStep/utils/capacity.js +1 -11
  33. package/dist/solution/BookingByStep/utils/resources.js +1 -3
  34. package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
  35. package/dist/solution/BookingTicket/index.js +0 -2
  36. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +6 -7
  37. package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
  38. package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
  39. package/dist/solution/BuyTickets/index.js +9 -12
  40. package/dist/solution/Checkout/index.js +177 -252
  41. package/dist/solution/Checkout/utils/index.js +4 -16
  42. package/dist/solution/RegisterAndLogin/index.js +30 -76
  43. package/dist/solution/ScanOrder/index.js +50 -60
  44. package/dist/solution/ShopDiscount/index.js +2 -7
  45. package/dist/solution/VenueBooking/index.js +45 -55
  46. package/dist/utils/task.js +15 -18
  47. package/dist/utils/watch.js +0 -1
  48. package/lib/apis/picoding.js +2 -0
  49. package/lib/core/index.js +134 -134
  50. package/lib/effects/index.js +46 -57
  51. package/lib/index.js +82 -49
  52. package/lib/model/index.js +14 -21
  53. package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
  54. package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
  55. package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
  56. package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
  57. package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
  58. package/lib/model/strategy/adapter/index.js +100 -64
  59. package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
  60. package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
  61. package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
  62. package/lib/model/strategy/adapter/itemRule/index.js +83 -57
  63. package/lib/model/strategy/adapter/itemRule/type.js +97 -36
  64. package/lib/model/strategy/adapter/promotion/adapter.js +91 -69
  65. package/lib/model/strategy/adapter/promotion/evaluator.js +444 -310
  66. package/lib/model/strategy/adapter/promotion/examples.js +222 -234
  67. package/lib/model/strategy/adapter/promotion/index.js +1 -0
  68. package/lib/model/strategy/adapter/promotion/type.js +243 -36
  69. package/lib/model/strategy/adapter/type.js +4 -16
  70. package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -150
  71. package/lib/model/strategy/adapter/walletPass/example.js +217 -190
  72. package/lib/model/strategy/adapter/walletPass/index.js +75 -51
  73. package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
  74. package/lib/model/strategy/adapter/walletPass/type.js +4 -16
  75. package/lib/model/strategy/adapter/walletPass/utils.js +588 -378
  76. package/lib/model/strategy/engine.js +270 -168
  77. package/lib/model/strategy/index.js +49 -34
  78. package/lib/model/strategy/strategy-example.js +243 -239
  79. package/lib/model/strategy/type.js +100 -40
  80. package/lib/modules/Account/index.js +39 -53
  81. package/lib/modules/Account/types.js +20 -33
  82. package/lib/modules/AccountList/index.js +116 -154
  83. package/lib/modules/AccountList/types.js +30 -31
  84. package/lib/modules/AccountList/utils.js +18 -30
  85. package/lib/modules/BaseModule.js +23 -42
  86. package/lib/modules/BookingContext/index.js +158 -136
  87. package/lib/modules/BookingContext/types.js +46 -32
  88. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +138 -146
  89. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +78 -83
  90. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +170 -150
  91. package/lib/modules/BookingContext/utils/flexible.js +38 -55
  92. package/lib/modules/BookingContext/utils/formatResourceList.js +19 -34
  93. package/lib/modules/BookingContext/utils/index.js +124 -41
  94. package/lib/modules/BookingContext/utils/noResource.js +58 -70
  95. package/lib/modules/BookingContext/utils/orderLineDisplay.js +14 -41
  96. package/lib/modules/BookingContext/utils/productExtend.js +202 -155
  97. package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
  98. package/lib/modules/BookingContext/utils/resourceSelection.js +19 -41
  99. package/lib/modules/BookingContext/utils/resources.js +209 -167
  100. package/lib/modules/BookingContext/utils/serviceTimes.js +115 -116
  101. package/lib/modules/BookingContext/utils/timeSlices.js +76 -86
  102. package/lib/modules/Cart/index.js +170 -124
  103. package/lib/modules/Cart/types.js +46 -51
  104. package/lib/modules/Cart/utils/cartAccount.js +40 -39
  105. package/lib/modules/Cart/utils/cartDate.js +56 -61
  106. package/lib/modules/Cart/utils/cartDiscount.js +28 -33
  107. package/lib/modules/Cart/utils/cartNote.js +27 -32
  108. package/lib/modules/Cart/utils/cartProduct.js +321 -251
  109. package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
  110. package/lib/modules/Cart/utils/cartResource.js +70 -78
  111. package/lib/modules/Cart/utils/changePrice.js +22 -50
  112. package/lib/modules/Cart/utils/index.js +106 -48
  113. package/lib/modules/Customer/constants.js +13 -34
  114. package/lib/modules/Customer/index.js +235 -172
  115. package/lib/modules/Customer/types.js +38 -35
  116. package/lib/modules/Date/index.js +116 -115
  117. package/lib/modules/Date/types.js +16 -28
  118. package/lib/modules/Date/utils.js +174 -123
  119. package/lib/modules/Discount/index.js +122 -127
  120. package/lib/modules/Discount/types.js +9 -31
  121. package/lib/modules/Guests/index.js +30 -56
  122. package/lib/modules/Guests/types.js +23 -33
  123. package/lib/modules/Holder/index.js +209 -189
  124. package/lib/modules/Holder/types.js +4 -16
  125. package/lib/modules/Holder/utils.js +20 -49
  126. package/lib/modules/OpenData/index.js +70 -76
  127. package/lib/modules/OpenData/types.js +4 -16
  128. package/lib/modules/OpenData/utils.js +44 -78
  129. package/lib/modules/Order/index.d.ts +1 -1
  130. package/lib/modules/Order/index.js +1733 -2121
  131. package/lib/modules/Order/payment-utils.js +77 -120
  132. package/lib/modules/Order/types.d.ts +3 -1
  133. package/lib/modules/Order/types.js +88 -35
  134. package/lib/modules/Order/utils/bundleDiscountHydration.js +41 -74
  135. package/lib/modules/Order/utils/discountProductLineIdentity.js +142 -100
  136. package/lib/modules/Order/utils/manualProductDiscount.js +124 -123
  137. package/lib/modules/Order/utils/orderCollectionIdentity.js +184 -244
  138. package/lib/modules/Order/utils.js +814 -647
  139. package/lib/modules/Payment/cash.js +20 -33
  140. package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
  141. package/lib/modules/Payment/eftpos.js +16 -30
  142. package/lib/modules/Payment/index.js +532 -399
  143. package/lib/modules/Payment/mx51.js +1 -0
  144. package/lib/modules/Payment/types.js +230 -108
  145. package/lib/modules/Payment/utils.js +52 -51
  146. package/lib/modules/Payment/walletpass.js +485 -660
  147. package/lib/modules/Product/index.js +51 -46
  148. package/lib/modules/Product/types.js +4 -16
  149. package/lib/modules/Product/utils.js +32 -33
  150. package/lib/modules/ProductList/index.js +113 -123
  151. package/lib/modules/ProductList/types.js +9 -31
  152. package/lib/modules/Quotation/index.js +81 -118
  153. package/lib/modules/Quotation/types.js +4 -16
  154. package/lib/modules/Resource/index.js +27 -59
  155. package/lib/modules/Resource/types.js +22 -32
  156. package/lib/modules/Resource/utils.js +30 -38
  157. package/lib/modules/ResourcePlanner/index.js +25 -23
  158. package/lib/modules/ResourcePlanner/localClock.js +54 -119
  159. package/lib/modules/ResourcePlanner/planner.js +589 -770
  160. package/lib/modules/ResourcePlanner/types.js +10 -29
  161. package/lib/modules/Rules/index.js +1218 -959
  162. package/lib/modules/Rules/types.js +17 -40
  163. package/lib/modules/SalesSummary/index.js +85 -90
  164. package/lib/modules/SalesSummary/types.js +4 -16
  165. package/lib/modules/SalesSummary/utils.js +355 -430
  166. package/lib/modules/ScanOrderLogger/index.js +59 -79
  167. package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
  168. package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
  169. package/lib/modules/ScanOrderLogger/types.js +4 -16
  170. package/lib/modules/Schedule/getDateIsInSchedule.js +334 -163
  171. package/lib/modules/Schedule/index.js +100 -114
  172. package/lib/modules/Schedule/type.js +4 -16
  173. package/lib/modules/Schedule/types.js +4 -16
  174. package/lib/modules/Schedule/utils.js +433 -291
  175. package/lib/modules/Step/index.js +40 -52
  176. package/lib/modules/Step/tyeps.js +4 -16
  177. package/lib/modules/Summary/index.js +66 -71
  178. package/lib/modules/Summary/types.js +4 -16
  179. package/lib/modules/Summary/utils.js +773 -418
  180. package/lib/modules/SurchargeList/index.js +46 -60
  181. package/lib/modules/SurchargeList/types.js +4 -16
  182. package/lib/modules/index.js +245 -63
  183. package/lib/plugins/app.js +4 -16
  184. package/lib/plugins/index.js +36 -25
  185. package/lib/plugins/request.js +137 -126
  186. package/lib/plugins/shopStore.js +4 -16
  187. package/lib/plugins/user.js +4 -16
  188. package/lib/plugins/window.js +171 -179
  189. package/lib/server/index.js +3050 -2665
  190. package/lib/server/modules/floor-plan/index.js +118 -134
  191. package/lib/server/modules/floor-plan/types.js +15 -30
  192. package/lib/server/modules/index.js +106 -68
  193. package/lib/server/modules/menu/index.js +142 -122
  194. package/lib/server/modules/menu/types.js +18 -31
  195. package/lib/server/modules/order/index.js +784 -1002
  196. package/lib/server/modules/order/types.js +122 -33
  197. package/lib/server/modules/order/utils/filterBookings.js +219 -194
  198. package/lib/server/modules/order/utils/filterOrders.js +118 -92
  199. package/lib/server/modules/payment/index.js +59 -83
  200. package/lib/server/modules/payment/types.js +4 -16
  201. package/lib/server/modules/products/index.js +583 -471
  202. package/lib/server/modules/products/types.js +44 -34
  203. package/lib/server/modules/quotation/index.js +137 -172
  204. package/lib/server/modules/quotation/types.js +21 -31
  205. package/lib/server/modules/resource/index.js +220 -186
  206. package/lib/server/modules/resource/types.js +42 -33
  207. package/lib/server/modules/schedule/index.js +135 -123
  208. package/lib/server/modules/schedule/types.js +14 -21
  209. package/lib/server/modules/schedule/utils.js +334 -163
  210. package/lib/server/types.js +4 -16
  211. package/lib/server/utils/index.js +25 -23
  212. package/lib/server/utils/product.js +196 -139
  213. package/lib/server/utils/schedule.js +34 -41
  214. package/lib/server/utils/small-ticket.js +479 -456
  215. package/lib/server/utils/time.js +40 -49
  216. package/lib/solution/BaseSales/index.js +1220 -1412
  217. package/lib/solution/BaseSales/types.js +42 -38
  218. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +5 -0
  219. package/lib/solution/BaseSales/utils/cartPromotion.js +652 -498
  220. package/lib/solution/BaseSales/utils/parseSalesResponse.js +85 -105
  221. package/lib/solution/BaseSales/utils/quotationPrice.js +56 -114
  222. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +108 -145
  223. package/lib/solution/BaseSales/utils.js +158 -143
  224. package/lib/solution/BookingByStep/index.js +1527 -1340
  225. package/lib/solution/BookingByStep/types.js +40 -99
  226. package/lib/solution/BookingByStep/utils/capacity.js +192 -160
  227. package/lib/solution/BookingByStep/utils/products.js +42 -52
  228. package/lib/solution/BookingByStep/utils/resources.js +527 -330
  229. package/lib/solution/BookingByStep/utils/stock.js +65 -44
  230. package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
  231. package/lib/solution/BookingTicket/index.js +607 -522
  232. package/lib/solution/BookingTicket/types.js +99 -77
  233. package/lib/solution/BookingTicket/utils/addProductDecision.js +226 -189
  234. package/lib/solution/BookingTicket/utils/addTimeAvailability.js +58 -89
  235. package/lib/solution/BookingTicket/utils/bookingStatus.js +107 -78
  236. package/lib/solution/BookingTicket/utils/cartView.js +114 -99
  237. package/lib/solution/BookingTicket/utils/exampleData.js +185 -0
  238. package/lib/solution/BookingTicket/utils/orderCustomer.js +18 -41
  239. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +219 -86
  240. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +168 -116
  241. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +79 -91
  242. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +54 -41
  243. package/lib/solution/BookingTicket/utils/scan/handleScan.js +84 -81
  244. package/lib/solution/BookingTicket/utils/scan/index.js +98 -104
  245. package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
  246. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +52 -64
  247. package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +56 -58
  248. package/lib/solution/BookingTicket/utils/weighingProductSku.js +34 -48
  249. package/lib/solution/BuyTickets/index.js +67 -70
  250. package/lib/solution/BuyTickets/types.js +22 -38
  251. package/lib/solution/Checkout/index.js +1451 -1158
  252. package/lib/solution/Checkout/types.js +91 -61
  253. package/lib/solution/Checkout/utils/index.js +228 -156
  254. package/lib/solution/PlaceOrder/index.js +55 -0
  255. package/lib/solution/RegisterAndLogin/config.js +493 -460
  256. package/lib/solution/RegisterAndLogin/index.js +633 -630
  257. package/lib/solution/RegisterAndLogin/types.js +189 -76
  258. package/lib/solution/RegisterAndLogin/utils.js +183 -125
  259. package/lib/solution/Sales/index.js +328 -324
  260. package/lib/solution/Sales/types.js +27 -33
  261. package/lib/solution/ScanOrder/index.js +832 -864
  262. package/lib/solution/ScanOrder/types.js +33 -34
  263. package/lib/solution/ScanOrder/utils.js +409 -374
  264. package/lib/solution/ShopDiscount/index.js +226 -232
  265. package/lib/solution/ShopDiscount/types.js +15 -37
  266. package/lib/solution/ShopDiscount/utils.js +300 -172
  267. package/lib/solution/UnifiedBookingSales/index.js +1035 -1201
  268. package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +99 -159
  269. package/lib/solution/UnifiedBookingSales/types.js +10 -32
  270. package/lib/solution/VenueBooking/index.js +811 -879
  271. package/lib/solution/VenueBooking/types.js +19 -39
  272. package/lib/solution/VenueBooking/utils/dateSummary.js +27 -56
  273. package/lib/solution/VenueBooking/utils/resource.js +31 -54
  274. package/lib/solution/VenueBooking/utils/slotMerge.js +94 -107
  275. package/lib/solution/VenueBooking/utils/timeSlot.js +132 -132
  276. package/lib/solution/VenueBooking/utils.js +130 -67
  277. package/lib/solution/index.js +124 -41
  278. package/lib/store/createStore.js +32 -29
  279. package/lib/types/index.js +4 -16
  280. package/lib/utils/payment-number.js +26 -46
  281. package/lib/utils/task.js +36 -36
  282. package/lib/utils/watch.js +81 -47
  283. package/package.json +2 -1
@@ -1,93 +1,88 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _exportNames = {
7
+ buildPlannerDiscountResult: true,
8
+ normalizeProductForAvailability: true,
9
+ buildAvailabilityResourcesFromV2: true,
10
+ collectAvailabilityResourceIds: true,
11
+ buildAvailabilityLineIdentity: true,
12
+ buildBookingFromAvailabilityAssignment: true,
13
+ buildBookingFromAvailabilityAssignments: true,
14
+ UnifiedBookingSalesImpl: true,
15
+ UnifiedBookingSales: true,
16
+ AvailabilityError: true
10
17
  };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ Object.defineProperty(exports, "AvailabilityError", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _ResourcePlanner.AvailabilityError;
16
22
  }
17
- return to;
18
- };
19
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/solution/UnifiedBookingSales/index.ts
31
- var UnifiedBookingSales_exports = {};
32
- __export(UnifiedBookingSales_exports, {
33
- AvailabilityError: () => import_ResourcePlanner2.AvailabilityError,
34
- UnifiedBookingSales: () => UnifiedBookingSales,
35
- UnifiedBookingSalesImpl: () => UnifiedBookingSalesImpl,
36
- buildAvailabilityLineIdentity: () => buildAvailabilityLineIdentity,
37
- buildAvailabilityResourcesFromV2: () => buildAvailabilityResourcesFromV2,
38
- buildBookingFromAvailabilityAssignment: () => buildBookingFromAvailabilityAssignment,
39
- buildBookingFromAvailabilityAssignments: () => buildBookingFromAvailabilityAssignments,
40
- buildPlannerDiscountResult: () => buildPlannerDiscountResult,
41
- collectAvailabilityResourceIds: () => collectAvailabilityResourceIds,
42
- normalizeProductForAvailability: () => normalizeProductForAvailability
43
23
  });
44
- module.exports = __toCommonJS(UnifiedBookingSales_exports);
45
- var import_dayjs = __toESM(require("dayjs"));
46
- var import_lodash_es = require("lodash-es");
47
- var import_modules = require("../../modules");
48
- var import_getDateIsInSchedule = require("../../modules/Schedule/getDateIsInSchedule");
49
- var import_ResourcePlanner = require("../../modules/ResourcePlanner");
50
- var import_types = require("./types");
51
- var import_remoteOccupancyCache = require("./remoteOccupancyCache");
52
- var import_BookingTicket = require("../BookingTicket");
53
- var import_localClock = require("../../modules/ResourcePlanner/localClock");
54
- __reExport(UnifiedBookingSales_exports, require("./types"), module.exports);
55
- var import_ResourcePlanner2 = require("../../modules/ResourcePlanner");
56
- var OPEN_DATA_SECTION_CODES = ["sale", "reservation", "fulfillment", "menu", "workflow", "basic", "checkout", "availability"];
57
- var OPEN_DATA_CACHE_TTL = 5 * 60 * 1e3;
24
+ exports.UnifiedBookingSalesImpl = exports.UnifiedBookingSales = void 0;
25
+ exports.buildAvailabilityLineIdentity = buildAvailabilityLineIdentity;
26
+ exports.buildAvailabilityResourcesFromV2 = buildAvailabilityResourcesFromV2;
27
+ exports.buildBookingFromAvailabilityAssignment = buildBookingFromAvailabilityAssignment;
28
+ exports.buildBookingFromAvailabilityAssignments = buildBookingFromAvailabilityAssignments;
29
+ exports.buildPlannerDiscountResult = buildPlannerDiscountResult;
30
+ exports.collectAvailabilityResourceIds = collectAvailabilityResourceIds;
31
+ exports.normalizeProductForAvailability = normalizeProductForAvailability;
32
+ var _dayjs = _interopRequireDefault(require("dayjs"));
33
+ var _lodashEs = require("lodash-es");
34
+ var _modules = require("../../modules");
35
+ var _getDateIsInSchedule = require("../../modules/Schedule/getDateIsInSchedule");
36
+ var _ResourcePlanner = require("../../modules/ResourcePlanner");
37
+ var _types = require("./types");
38
+ Object.keys(_types).forEach(function (key) {
39
+ if (key === "default" || key === "__esModule") return;
40
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
41
+ if (key in exports && exports[key] === _types[key]) return;
42
+ Object.defineProperty(exports, key, {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _types[key];
46
+ }
47
+ });
48
+ });
49
+ var _remoteOccupancyCache = require("./remoteOccupancyCache");
50
+ var _BookingTicket = require("../BookingTicket");
51
+ var _localClock = require("../../modules/ResourcePlanner/localClock");
52
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
53
+ const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'basic', 'checkout', 'availability'];
54
+ const OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
58
55
  function normalizePositiveInteger(value) {
59
56
  const normalized = Number(value);
60
- if (!Number.isInteger(normalized) || normalized <= 0)
61
- return void 0;
57
+ if (!Number.isInteger(normalized) || normalized <= 0) return undefined;
62
58
  return normalized;
63
59
  }
64
60
  function isRecord(value) {
65
- return !!value && typeof value === "object" && !Array.isArray(value);
61
+ return !!value && typeof value === 'object' && !Array.isArray(value);
66
62
  }
67
63
  function pickLocalizedText(value) {
68
- if (!value)
69
- return void 0;
70
- if (typeof value === "string")
71
- return value;
72
- if (typeof value === "object") {
64
+ if (!value) return undefined;
65
+ if (typeof value === 'string') return value;
66
+ if (typeof value === 'object') {
73
67
  return value.en || value.zh || value.default || Object.values(value)[0];
74
68
  }
75
69
  return String(value);
76
70
  }
77
71
  function resolvePlannerDiscountId(discount) {
78
- var _a;
79
- return ((_a = discount.discount) == null ? void 0 : _a.resource_id) ?? discount.resource_id ?? discount.id;
72
+ return discount.discount?.resource_id ?? discount.resource_id ?? discount.id;
80
73
  }
81
74
  function resolvePlannerDiscountTitle(discount) {
82
- var _a;
83
- return pickLocalizedText(
84
- discount.name || discount.format_title || ((_a = discount.discount) == null ? void 0 : _a.title) || discount.title
85
- );
75
+ return pickLocalizedText(discount.name || discount.format_title || discount.discount?.title || discount.title);
86
76
  }
87
77
  function isPlannerDiscountAvailable(discount) {
88
- var _a;
89
- return discount.isDisabled !== true && discount.isAvailable !== false && ((_a = discount.config) == null ? void 0 : _a.isAvailable) !== false;
78
+ return discount.isDisabled !== true && discount.isAvailable !== false && discount.config?.isAvailable !== false;
90
79
  }
80
+
81
+ /**
82
+ * Converts Rules/Order discount internals into a small UI-facing diagnostic. The result keeps
83
+ * candidate-card state separate from line-level applications: a selected card is not proof that
84
+ * it actually discounted a planner product.
85
+ */
91
86
  function buildPlannerDiscountResult(params) {
92
87
  const {
93
88
  customerId,
@@ -101,39 +96,34 @@ function buildPlannerDiscountResult(params) {
101
96
  } = params;
102
97
  const items = (discountList || []).reduce((result, discount) => {
103
98
  const id = resolvePlannerDiscountId(discount);
104
- if (id !== void 0 && id !== null) {
99
+ if (id !== undefined && id !== null) {
105
100
  result.push({
106
101
  id,
107
102
  name: resolvePlannerDiscountTitle(discount),
108
103
  type: discount.tag || discount.type,
109
104
  available: isPlannerDiscountAvailable(discount),
110
105
  selected: discount.isSelected === true,
111
- savedAmount: Number(discount.savedAmount || 0) || void 0,
106
+ savedAmount: Number(discount.savedAmount || 0) || undefined,
112
107
  unavailableReason: discount.unavailableReason || discount.reason
113
108
  });
114
109
  }
115
110
  return result;
116
111
  }, []);
117
- const discountNameById = new Map(items.map((item) => [String(item.id), item.name]));
112
+ const discountNameById = new Map(items.map(item => [String(item.id), item.name]));
118
113
  const applications = [];
119
- (products || []).forEach((product) => {
120
- const productDiscounts = [
121
- ...Array.isArray(product.discount_list) ? product.discount_list : [],
122
- ...Array.isArray(product.product_bundle) ? product.product_bundle.flatMap((bundle) => (bundle == null ? void 0 : bundle.discount_list) || []) : []
123
- ];
124
- productDiscounts.forEach((discount) => {
125
- var _a;
114
+ (products || []).forEach(product => {
115
+ const productDiscounts = [...(Array.isArray(product.discount_list) ? product.discount_list : []), ...(Array.isArray(product.product_bundle) ? product.product_bundle.flatMap(bundle => bundle?.discount_list || []) : [])];
116
+ productDiscounts.forEach(discount => {
126
117
  const type = discount.tag || discount.type;
127
- if (!["good_pass", "discount_card", "product_discount_card"].includes(type))
128
- return;
118
+ if (!['good_pass', 'discount_card', 'product_discount_card'].includes(type)) return;
129
119
  const discountId = resolvePlannerDiscountId(discount);
130
120
  applications.push({
131
121
  discountId,
132
- discountName: discountId === void 0 ? void 0 : discountNameById.get(String(discountId)),
122
+ discountName: discountId === undefined ? undefined : discountNameById.get(String(discountId)),
133
123
  discountType: type,
134
124
  productId: product.product_id ?? product.id,
135
125
  productTitle: pickLocalizedText(product.title || product.name || product.product_title),
136
- productUid: ((_a = product.metadata) == null ? void 0 : _a.unique_identification_number) || product.unique_identification_number,
126
+ productUid: product.metadata?.unique_identification_number || product.unique_identification_number,
137
127
  amount: Number(discount.amount || 0)
138
128
  });
139
129
  });
@@ -142,17 +132,16 @@ function buildPlannerDiscountResult(params) {
142
132
  status,
143
133
  customerId,
144
134
  preferredDiscountFound,
145
- preferredDiscountApplied: preferredDiscountId === void 0 || preferredDiscountId === null ? void 0 : items.some((item) => String(item.id) === String(preferredDiscountId) && item.selected) && applications.some((item) => String(item.discountId) === String(preferredDiscountId)),
146
- availableDiscounts: items.filter((item) => item.available),
147
- selectedDiscounts: items.filter((item) => item.selected),
135
+ preferredDiscountApplied: preferredDiscountId === undefined || preferredDiscountId === null ? undefined : items.some(item => String(item.id) === String(preferredDiscountId) && item.selected) && applications.some(item => String(item.discountId) === String(preferredDiscountId)),
136
+ availableDiscounts: items.filter(item => item.available),
137
+ selectedDiscounts: items.filter(item => item.selected),
148
138
  applications,
149
139
  summaryBefore,
150
140
  summaryAfter
151
141
  };
152
142
  }
153
143
  function toNumberId(value) {
154
- if (value === void 0 || value === null || value === "")
155
- return void 0;
144
+ if (value === undefined || value === null || value === '') return undefined;
156
145
  const parsed = Number(value);
157
146
  return Number.isFinite(parsed) ? parsed : String(value);
158
147
  }
@@ -161,51 +150,45 @@ function toCustomerId(value) {
161
150
  return Number.isFinite(parsed) && parsed > 1 ? parsed : null;
162
151
  }
163
152
  function resolveTempOrderCustomerId(tempOrder) {
164
- var _a, _b, _c, _d, _e;
165
- return toCustomerId(
166
- (tempOrder == null ? void 0 : tempOrder.customer_id) || ((_a = tempOrder == null ? void 0 : tempOrder.customer) == null ? void 0 : _a.id) || ((_c = (_b = tempOrder == null ? void 0 : tempOrder._extend) == null ? void 0 : _b.customerSnapshot) == null ? void 0 : _c.id) || ((_e = (_d = tempOrder == null ? void 0 : tempOrder._extend) == null ? void 0 : _d.customerSnapshot) == null ? void 0 : _e.customer_id)
167
- );
153
+ return toCustomerId(tempOrder?.customer_id || tempOrder?.customer?.id || tempOrder?._extend?.customerSnapshot?.id || tempOrder?._extend?.customerSnapshot?.customer_id);
168
154
  }
169
155
  function isLocalOrderId(orderId) {
170
- return typeof orderId === "string" && orderId.startsWith("local_order");
156
+ return typeof orderId === 'string' && orderId.startsWith('local_order');
171
157
  }
172
158
  function isCustomerBoundDiscount(discount) {
173
- const type = (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag);
174
- return type === "good_pass" || type === "discount_card" || type === "product_discount_card";
159
+ const type = discount?.type ?? discount?.tag;
160
+ return type === 'good_pass' || type === 'discount_card' || type === 'product_discount_card';
175
161
  }
176
162
  function filterCustomerBoundDiscounts(discountList) {
177
- if (!Array.isArray(discountList))
178
- return [];
179
- return discountList.filter((discount) => !isCustomerBoundDiscount(discount));
163
+ if (!Array.isArray(discountList)) return [];
164
+ return discountList.filter(discount => !isCustomerBoundDiscount(discount));
180
165
  }
181
- var DEFAULT_AVAILABILITY_SLOT_STEP_MINUTES = 30;
182
- var DEFAULT_AVAILABILITY_BUSINESS_HOURS = {
183
- startTime: "09:00",
184
- endTime: "18:00"
166
+ const DEFAULT_AVAILABILITY_SLOT_STEP_MINUTES = 30;
167
+ const DEFAULT_AVAILABILITY_BUSINESS_HOURS = {
168
+ startTime: '09:00',
169
+ endTime: '18:00'
185
170
  };
186
- var MAX_AVAILABILITY_RANGE_DAYS = 90;
187
- var MAX_AVAILABILITY_CONTEXT_REGISTRY = 128;
188
- var MAX_AVAILABILITY_PROJECTION_POOL = 16;
189
- var MAX_REMOTE_OCCUPANCY_RESOURCE_DATE_CELLS = 4096;
171
+ const MAX_AVAILABILITY_RANGE_DAYS = 90;
172
+ const MAX_AVAILABILITY_CONTEXT_REGISTRY = 128;
173
+ const MAX_AVAILABILITY_PROJECTION_POOL = 16;
174
+ const MAX_REMOTE_OCCUPANCY_RESOURCE_DATE_CELLS = 4096;
190
175
  function isValidClockTime(value) {
191
176
  const match = /^(\d{2}):(\d{2})$/.exec(value);
192
- if (!match)
193
- return false;
177
+ if (!match) return false;
194
178
  return Number(match[1]) < 24 && Number(match[2]) < 60;
195
179
  }
196
180
  function assertValidAvailabilityTimezone(timezoneName) {
197
- if (!String(timezoneName || "").trim()) {
198
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "timezone label 不能为空", {
181
+ if (!String(timezoneName || '').trim()) {
182
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', 'timezone label 不能为空', {
199
183
  timezone: timezoneName
200
184
  });
201
185
  }
202
186
  }
203
187
  function normalizeAvailabilityLocalDateTime(value, fixedOffsetMinutes) {
204
- if (value == null || value === "")
205
- return null;
188
+ if (value == null || value === '') return null;
206
189
  try {
207
- const localText = typeof (value == null ? void 0 : value.format) === "function" ? value.format("YYYY-MM-DDTHH:mm:ss") : String(value);
208
- return (0, import_localClock.formatLocalDateTime)((0, import_localClock.parseLocalDateTime)(localText), fixedOffsetMinutes);
190
+ const localText = typeof value?.format === 'function' ? value.format('YYYY-MM-DDTHH:mm:ss') : String(value);
191
+ return (0, _localClock.formatLocalDateTime)((0, _localClock.parseLocalDateTime)(localText), fixedOffsetMinutes);
209
192
  } catch {
210
193
  return null;
211
194
  }
@@ -213,46 +196,42 @@ function normalizeAvailabilityLocalDateTime(value, fixedOffsetMinutes) {
213
196
  function normalizeAvailabilityLocalDateTimeRange(params) {
214
197
  const startText = normalizeAvailabilityLocalDateTime(params.startAt, params.fixedOffsetMinutes);
215
198
  const endText = normalizeAvailabilityLocalDateTime(params.endAt, params.fixedOffsetMinutes);
216
- if (!startText || !endText)
217
- return null;
218
- const startScalar = (0, import_localClock.localDateTimeToScalar)((0, import_localClock.parseLocalDateTime)(startText));
219
- let endScalar = (0, import_localClock.localDateTimeToScalar)((0, import_localClock.parseLocalDateTime)(endText));
199
+ if (!startText || !endText) return null;
200
+ const startScalar = (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(startText));
201
+ let endScalar = (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(endText));
220
202
  if (endScalar <= startScalar && params.rollOverEnd) {
221
- endScalar = (0, import_localClock.addLocalCalendarDays)(endScalar, 1);
203
+ endScalar = (0, _localClock.addLocalCalendarDays)(endScalar, 1);
222
204
  }
223
- if (endScalar <= startScalar)
224
- return null;
205
+ if (endScalar <= startScalar) return null;
225
206
  return {
226
207
  startAt: startText,
227
- endAt: (0, import_localClock.formatLocalDateTime)(endScalar, params.fixedOffsetMinutes),
208
+ endAt: (0, _localClock.formatLocalDateTime)(endScalar, params.fixedOffsetMinutes),
228
209
  startScalar,
229
210
  endScalar
230
211
  };
231
212
  }
232
213
  function sameAvailabilityId(left, right) {
233
- return left !== void 0 && left !== null && right !== void 0 && right !== null && String(left) === String(right);
214
+ return left !== undefined && left !== null && right !== undefined && right !== null && String(left) === String(right);
234
215
  }
235
216
  function uniqueAvailabilityIds(values) {
236
- const result = /* @__PURE__ */ new Map();
237
- values.forEach((value) => {
217
+ const result = new Map();
218
+ values.forEach(value => {
238
219
  const id = toNumberId(value);
239
- if (id !== void 0)
240
- result.set(String(id), id);
220
+ if (id !== undefined) result.set(String(id), id);
241
221
  });
242
222
  return Array.from(result.values());
243
223
  }
244
224
  function assertAvailabilityCatalogProductIds(productIds, context) {
245
- if (productIds == null)
246
- return;
225
+ if (productIds == null) return;
247
226
  if (!Array.isArray(productIds)) {
248
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", `${context} 必须是 number[]`, {
227
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', `${context} 必须是 number[]`, {
249
228
  context,
250
229
  productIds
251
230
  });
252
231
  }
253
- const invalidIds = productIds.filter((id) => typeof id !== "number" || !Number.isFinite(id));
232
+ const invalidIds = productIds.filter(id => typeof id !== 'number' || !Number.isFinite(id));
254
233
  if (invalidIds.length > 0) {
255
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", `${context} 只能包含有限数值商品 ID`, {
234
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', `${context} 只能包含有限数值商品 ID`, {
256
235
  context,
257
236
  invalidIds,
258
237
  productIds
@@ -260,74 +239,63 @@ function assertAvailabilityCatalogProductIds(productIds, context) {
260
239
  }
261
240
  }
262
241
  function normalizeResourceType(_value) {
263
- return "single";
242
+ // 当前业务只支持每个资源组选择一个具体资源。
243
+ // 保留公共联合类型以兼容已有调用方,但暂不启用 multiple/capacity 分支。
244
+ return 'single';
264
245
  }
265
246
  function resolveProductKind(product) {
266
- var _a, _b, _c;
267
- if (product.duration || product.service_duration)
268
- return "duration";
269
- if (product.extension_type === "venue_slot")
270
- return "venue_slot";
271
- if (["session_product", "session_ticket"].includes(product.extension_type))
272
- return "session";
273
- if (((_a = product.cartDetailValue) == null ? void 0 : _a.session) || ((_c = (_b = product._extend) == null ? void 0 : _b.other) == null ? void 0 : _c.session) || product.session) {
274
- return "session";
275
- }
276
- const scheduleIds = product["schedule.ids"] || product.schedule_ids;
277
- if (Array.isArray(scheduleIds) && scheduleIds.length > 0)
278
- return "session";
279
- return "normal";
247
+ if (product.duration || product.service_duration) return 'duration';
248
+ if (product.extension_type === 'venue_slot') return 'venue_slot';
249
+ if (['session_product', 'session_ticket'].includes(product.extension_type)) return 'session';
250
+ if (product.cartDetailValue?.session || product._extend?.other?.session || product.session) {
251
+ return 'session';
252
+ }
253
+ const scheduleIds = product['schedule.ids'] || product.schedule_ids;
254
+ if (Array.isArray(scheduleIds) && scheduleIds.length > 0) return 'session';
255
+ return 'normal';
280
256
  }
281
257
  function expandScheduleDateRanges(values) {
282
- if (!Array.isArray(values))
283
- return [];
284
- const dates = /* @__PURE__ */ new Set();
285
- values.forEach((value) => {
286
- if (typeof value === "string") {
258
+ if (!Array.isArray(values)) return [];
259
+ const dates = new Set();
260
+ values.forEach(value => {
261
+ if (typeof value === 'string') {
287
262
  try {
288
- dates.add((0, import_localClock.formatLocalDate)((0, import_localClock.parseLocalDate)(value.slice(0, 10))));
263
+ dates.add((0, _localClock.formatLocalDate)((0, _localClock.parseLocalDate)(value.slice(0, 10))));
289
264
  } catch {
265
+ // Ignore invalid configuration entries.
290
266
  }
291
267
  return;
292
268
  }
293
- const startValue = (value == null ? void 0 : value.start) || (value == null ? void 0 : value.start_date) || (value == null ? void 0 : value.date);
294
- const endValue = (value == null ? void 0 : value.end) || (value == null ? void 0 : value.end_date) || startValue;
269
+ const startValue = value?.start || value?.start_date || value?.date;
270
+ const endValue = value?.end || value?.end_date || startValue;
295
271
  let start;
296
272
  let end;
297
273
  try {
298
- start = (0, import_localClock.localDateToScalarStart)((0, import_localClock.parseLocalDate)(String(startValue).slice(0, 10)));
299
- end = (0, import_localClock.localDateToScalarStart)((0, import_localClock.parseLocalDate)(String(endValue).slice(0, 10)));
274
+ start = (0, _localClock.localDateToScalarStart)((0, _localClock.parseLocalDate)(String(startValue).slice(0, 10)));
275
+ end = (0, _localClock.localDateToScalarStart)((0, _localClock.parseLocalDate)(String(endValue).slice(0, 10)));
300
276
  } catch {
301
277
  return;
302
278
  }
303
- if (end < start)
304
- return;
279
+ if (end < start) return;
305
280
  let cursor = start;
306
281
  let guard = 0;
307
282
  while (cursor <= end && guard < MAX_AVAILABILITY_RANGE_DAYS) {
308
- dates.add((0, import_localClock.formatLocalDate)(cursor));
309
- cursor = (0, import_localClock.addLocalCalendarDays)(cursor, 1);
283
+ dates.add((0, _localClock.formatLocalDate)(cursor));
284
+ cursor = (0, _localClock.addLocalCalendarDays)(cursor, 1);
310
285
  guard += 1;
311
286
  }
312
287
  });
313
288
  return Array.from(dates).sort();
314
289
  }
315
290
  function normalizeRequirementGroups(product) {
316
- var _a;
317
- const resources = (_a = product.product_resource) == null ? void 0 : _a.resources;
318
- if (!Array.isArray(resources))
319
- return [];
320
- return resources.filter((resource) => (resource == null ? void 0 : resource.status) !== 0).map((resource, index) => {
321
- var _a2, _b, _c;
291
+ const resources = product.product_resource?.resources;
292
+ if (!Array.isArray(resources)) return [];
293
+ return resources.filter(resource => resource?.status !== 0).map((resource, index) => {
322
294
  const formId = toNumberId(resource.id ?? resource.form_id);
323
295
  const required = resource.required ?? resource.status === 1;
324
296
  const resourceType = normalizeResourceType(resource.type);
325
- const combinedIds = ((_a2 = resource.combined_resource) == null ? void 0 : _a2.status) === 1 ? (_b = resource.combined_resource) == null ? void 0 : _b.resource_ids : [];
326
- const resourceIds = uniqueAvailabilityIds([
327
- ...Array.isArray(resource.default_resource) ? resource.default_resource : [],
328
- ...Array.isArray(resource.optional_resource) ? resource.optional_resource : [],
329
- ...Array.isArray(combinedIds) ? combinedIds : []
330
- ]);
297
+ const combinedIds = resource.combined_resource?.status === 1 ? resource.combined_resource?.resource_ids : [];
298
+ const resourceIds = uniqueAvailabilityIds([...(Array.isArray(resource.default_resource) ? resource.default_resource : []), ...(Array.isArray(resource.optional_resource) ? resource.optional_resource : []), ...(Array.isArray(combinedIds) ? combinedIds : [])]);
331
299
  const min = required ? 1 : 0;
332
300
  const max = 1;
333
301
  return {
@@ -340,30 +308,25 @@ function normalizeRequirementGroups(product) {
340
308
  min,
341
309
  max,
342
310
  resourceIds,
343
- capacityRequired: Math.max(1, Number(
344
- resource.capacity_required ?? ((_c = product.capacity) == null ? void 0 : _c.default) ?? product.capacity ?? 1
345
- ) || 1),
311
+ capacityRequired: Math.max(1, Number(resource.capacity_required ?? product.capacity?.default ?? product.capacity ?? 1) || 1),
346
312
  raw: resource
347
313
  };
348
314
  });
349
315
  }
350
316
  function normalizeScheduleRepeatType(value) {
351
- if (value === "daily" || value === 1 || value === "1")
352
- return "daily";
353
- if (value === "weekly" || value === 2 || value === "2")
354
- return "weekly";
355
- return "none";
317
+ if (value === 'daily' || value === 1 || value === '1') return 'daily';
318
+ if (value === 'weekly' || value === 2 || value === '2') return 'weekly';
319
+ return 'none';
356
320
  }
357
321
  function normalizeAbsoluteSessionRange(params) {
358
- const fixedOffsetMinutes = params.fixedOffsetMinutes ?? (0, import_localClock.captureRuntimeOffsetMinutes)();
322
+ const fixedOffsetMinutes = params.fixedOffsetMinutes ?? (0, _localClock.captureRuntimeOffsetMinutes)();
359
323
  const range = normalizeAvailabilityLocalDateTimeRange({
360
324
  startAt: params.startAt,
361
325
  endAt: params.endAt,
362
326
  fixedOffsetMinutes,
363
327
  rollOverEnd: true
364
328
  });
365
- if (!range)
366
- return null;
329
+ if (!range) return null;
367
330
  return {
368
331
  startAt: range.startAt,
369
332
  endAt: range.endAt,
@@ -375,7 +338,6 @@ function normalizeAbsoluteSessionRange(params) {
375
338
  };
376
339
  }
377
340
  function normalizeScheduleItem(schedule, fixedOffsetMinutes) {
378
- var _a, _b;
379
341
  const rules = [];
380
342
  const ranges = [];
381
343
  const scheduleId = toNumberId(schedule.id ?? schedule.schedule_id);
@@ -383,61 +345,61 @@ function normalizeScheduleItem(schedule, fixedOffsetMinutes) {
383
345
  const repeatRule = schedule.repeat_rule || {};
384
346
  const startAt = schedule.start_at || schedule.start || schedule.start_time;
385
347
  const endAt = schedule.end_at || schedule.end || schedule.end_time;
386
- const startDate = startAt ? String(startAt).slice(0, 10) : void 0;
387
- const configuredEndDate = ((_a = repeatRule.end) == null ? void 0 : _a.type) === "date" ? (_b = repeatRule.end) == null ? void 0 : _b.end_date : void 0;
388
- const endDate = configuredEndDate ? String(configuredEndDate).slice(0, 10) : void 0;
348
+ const startDate = startAt ? String(startAt).slice(0, 10) : undefined;
349
+ const configuredEndDate = repeatRule.end?.type === 'date' ? repeatRule.end?.end_date : undefined;
350
+ const endDate = configuredEndDate ? String(configuredEndDate).slice(0, 10) : undefined;
389
351
  const includedDates = expandScheduleDateRanges(repeatRule.included_date);
390
352
  const excludedDates = expandScheduleDateRanges(repeatRule.excluded_date);
391
- const addRule = (params) => {
392
- const mode = repeatType === "weekly" ? "weekly" : "daily";
353
+ const addRule = params => {
354
+ const mode = repeatType === 'weekly' ? 'weekly' : 'daily';
393
355
  rules.push({
394
- id: `${String(scheduleId ?? "schedule")}:${params.idSuffix}`,
356
+ id: `${String(scheduleId ?? 'schedule')}:${params.idSuffix}`,
395
357
  mode,
396
358
  startTime: params.startTime.slice(0, 5),
397
359
  endTime: params.endTime.slice(0, 5),
398
360
  startDate,
399
361
  endDate,
400
362
  frequency: Math.max(1, Number(repeatRule.frequency || 1)),
401
- weekdays: repeatType === "weekly" ? (repeatRule.frequency_date || []).map(Number).filter(Number.isFinite) : void 0,
363
+ weekdays: repeatType === 'weekly' ? (repeatRule.frequency_date || []).map(Number).filter(Number.isFinite) : undefined,
402
364
  includeDates: includedDates,
403
365
  excludeDates: excludedDates,
404
366
  scheduleRef: {
405
367
  scheduleId,
406
368
  timeSlotId: params.timeSlotId,
407
- source: `schedule_${schedule.type || "standard"}`
369
+ source: `schedule_${schedule.type || 'standard'}`
408
370
  }
409
371
  });
410
372
  };
411
- if (schedule.type === "designation") {
373
+ if (schedule.type === 'designation') {
412
374
  const designations = Array.isArray(schedule.designation) ? schedule.designation : schedule.designation ? [schedule.designation] : [];
413
- designations.forEach((designation) => {
375
+ designations.forEach(designation => {
414
376
  const range = normalizeAbsoluteSessionRange({
415
377
  startAt: `${designation.start_date} ${designation.start_time}`,
416
378
  endAt: `${designation.end_date || designation.start_date} ${designation.end_time}`,
417
379
  scheduleId,
418
- source: "schedule_designation",
380
+ source: 'schedule_designation',
419
381
  fixedOffsetMinutes
420
382
  });
421
- if (range)
422
- ranges.push(range);
383
+ if (range) ranges.push(range);
423
384
  });
424
- return { rules, ranges };
385
+ return {
386
+ rules,
387
+ ranges
388
+ };
425
389
  }
426
- if (schedule.type === "time-slots" && Array.isArray(schedule.time_slot)) {
390
+ if (schedule.type === 'time-slots' && Array.isArray(schedule.time_slot)) {
427
391
  schedule.time_slot.forEach((slot, index) => {
428
- if (!slot.start_time || !slot.end_time)
429
- return;
430
- if (repeatType === "none" && startDate) {
392
+ if (!slot.start_time || !slot.end_time) return;
393
+ if (repeatType === 'none' && startDate) {
431
394
  const range = normalizeAbsoluteSessionRange({
432
395
  startAt: `${startDate} ${slot.start_time}`,
433
396
  endAt: `${startDate} ${slot.end_time}`,
434
397
  scheduleId,
435
398
  timeSlotId: toNumberId(slot.id),
436
- source: "schedule_time_slot",
399
+ source: 'schedule_time_slot',
437
400
  fixedOffsetMinutes
438
401
  });
439
- if (range)
440
- ranges.push(range);
402
+ if (range) ranges.push(range);
441
403
  return;
442
404
  }
443
405
  addRule({
@@ -447,69 +409,70 @@ function normalizeScheduleItem(schedule, fixedOffsetMinutes) {
447
409
  timeSlotId: toNumberId(slot.id)
448
410
  });
449
411
  });
450
- return { rules, ranges };
412
+ return {
413
+ rules,
414
+ ranges
415
+ };
451
416
  }
452
417
  if (startAt && endAt) {
453
- if (repeatType === "none") {
418
+ if (repeatType === 'none') {
454
419
  const range = normalizeAbsoluteSessionRange({
455
420
  startAt,
456
421
  endAt,
457
422
  scheduleId,
458
- source: "schedule_standard",
423
+ source: 'schedule_standard',
459
424
  fixedOffsetMinutes
460
425
  });
461
- if (range)
462
- ranges.push(range);
426
+ if (range) ranges.push(range);
463
427
  } else {
464
428
  try {
465
429
  addRule({
466
- idSuffix: "standard",
467
- startTime: (0, import_localClock.formatLocalTime)(String(startAt), false),
468
- endTime: (0, import_localClock.formatLocalTime)(String(endAt), false)
430
+ idSuffix: 'standard',
431
+ startTime: (0, _localClock.formatLocalTime)(String(startAt), false),
432
+ endTime: (0, _localClock.formatLocalTime)(String(endAt), false)
469
433
  });
470
434
  } catch {
435
+ // Invalid schedule boundaries do not produce a recurring rule.
471
436
  }
472
437
  }
473
438
  }
474
- return { rules, ranges };
439
+ return {
440
+ rules,
441
+ ranges
442
+ };
475
443
  }
476
444
  function resolveProductScheduleItems(product, scheduleList) {
477
- const scheduleMap = new Map(scheduleList.map((schedule) => [String(schedule.id), schedule]));
478
- const rawSchedules = [product.schedules, product.schedule, product._schedule].flatMap((value) => Array.isArray(value) ? value : value ? [value] : []);
479
- const explicitIds = uniqueAvailabilityIds([
480
- ...Array.isArray(product["schedule.ids"]) ? product["schedule.ids"] : [],
481
- ...Array.isArray(product.schedule_ids) ? product.schedule_ids : [],
482
- ...rawSchedules.filter((item) => typeof item !== "object")
483
- ]);
484
- const result = /* @__PURE__ */ new Map();
485
- rawSchedules.filter((item) => item && typeof item === "object").forEach((schedule) => {
445
+ const scheduleMap = new Map(scheduleList.map(schedule => [String(schedule.id), schedule]));
446
+ const rawSchedules = [product.schedules, product.schedule, product._schedule].flatMap(value => Array.isArray(value) ? value : value ? [value] : []);
447
+ const explicitIds = uniqueAvailabilityIds([...(Array.isArray(product['schedule.ids']) ? product['schedule.ids'] : []), ...(Array.isArray(product.schedule_ids) ? product.schedule_ids : []), ...rawSchedules.filter(item => typeof item !== 'object')]);
448
+ const result = new Map();
449
+ rawSchedules.filter(item => item && typeof item === 'object').forEach(schedule => {
486
450
  result.set(String(schedule.id ?? JSON.stringify(schedule)), schedule);
487
451
  });
488
- explicitIds.forEach((id) => {
452
+ explicitIds.forEach(id => {
489
453
  const schedule = scheduleMap.get(String(id));
490
- if (schedule)
491
- result.set(String(id), schedule);
454
+ if (schedule) result.set(String(id), schedule);
492
455
  });
493
456
  return Array.from(result.values());
494
457
  }
495
- function normalizeProductForAvailability(product, scheduleList = [], fixedOffsetMinutes = (0, import_localClock.captureRuntimeOffsetMinutes)()) {
496
- var _a, _b, _c, _d, _e;
458
+
459
+ /** Converts ProductList and schedule records into the pure Availability vocabulary. */
460
+ function normalizeProductForAvailability(product, scheduleList = [], fixedOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)()) {
497
461
  const raw = product;
498
462
  const kind = resolveProductKind(raw);
499
463
  const sessionRules = [];
500
464
  const sessionRanges = [];
501
- const explicitSession = ((_a = raw.cartDetailValue) == null ? void 0 : _a.session) || ((_c = (_b = raw._extend) == null ? void 0 : _b.other) == null ? void 0 : _c.session) || raw.session;
465
+ const explicitSession = raw.cartDetailValue?.session || raw._extend?.other?.session || raw.session;
502
466
  const explicitRange = normalizeAbsoluteSessionRange({
503
- startAt: explicitSession == null ? void 0 : explicitSession.start_at,
504
- endAt: explicitSession == null ? void 0 : explicitSession.end_at,
505
- scheduleId: toNumberId(explicitSession == null ? void 0 : explicitSession.schedule_id),
506
- timeSlotId: toNumberId(explicitSession == null ? void 0 : explicitSession.time_slot_id),
507
- source: "product_session",
467
+ startAt: explicitSession?.start_at,
468
+ endAt: explicitSession?.end_at,
469
+ scheduleId: toNumberId(explicitSession?.schedule_id),
470
+ timeSlotId: toNumberId(explicitSession?.time_slot_id),
471
+ source: 'product_session',
508
472
  fixedOffsetMinutes
509
473
  });
510
- if (explicitRange)
511
- sessionRanges.push(explicitRange);
512
- resolveProductScheduleItems(raw, scheduleList).forEach((schedule) => {
474
+ if (explicitRange) sessionRanges.push(explicitRange);
475
+ resolveProductScheduleItems(raw, scheduleList).forEach(schedule => {
513
476
  const normalized = normalizeScheduleItem(schedule, fixedOffsetMinutes);
514
477
  sessionRules.push(...normalized.rules);
515
478
  sessionRanges.push(...normalized.ranges);
@@ -518,11 +481,11 @@ function normalizeProductForAvailability(product, scheduleList = [], fixedOffset
518
481
  id: raw.id ?? raw.product_id,
519
482
  title: pickLocalizedText(raw.title || raw.name || raw.product_title),
520
483
  kind,
521
- durationMinutes: kind === "duration" ? Math.max(1, Number(((_d = raw.duration) == null ? void 0 : _d.value) || raw.duration || raw.service_duration || 30) || 30) : void 0,
484
+ durationMinutes: kind === 'duration' ? Math.max(1, Number(raw.duration?.value || raw.duration || raw.service_duration || 30) || 30) : undefined,
522
485
  requirementGroups: normalizeRequirementGroups(raw),
523
486
  sessionRules,
524
487
  sessionRanges,
525
- capacityRequired: Math.max(1, Number(((_e = raw.capacity) == null ? void 0 : _e.default) || raw.capacity || 1) || 1),
488
+ capacityRequired: Math.max(1, Number(raw.capacity?.default || raw.capacity || 1) || 1),
526
489
  quantity: Math.max(1, Number(raw.num || raw.quantity || 1) || 1),
527
490
  cutOffPolicy: normalizeAvailabilityCutOffPolicy(raw.cut_off_time),
528
491
  raw
@@ -530,102 +493,121 @@ function normalizeProductForAvailability(product, scheduleList = [], fixedOffset
530
493
  }
531
494
  function normalizeAvailabilityCutOffNumber(value, context) {
532
495
  if (value == null) {
533
- return { reason: `${context} 缺失` };
496
+ return {
497
+ reason: `${context} 缺失`
498
+ };
534
499
  }
535
- if (typeof value === "string" && !value.trim()) {
536
- return { reason: `${context} 缺失` };
500
+ if (typeof value === 'string' && !value.trim()) {
501
+ return {
502
+ reason: `${context} 缺失`
503
+ };
537
504
  }
538
505
  const normalized = Number(value);
539
506
  if (!Number.isFinite(normalized) || normalized < 0) {
540
- return { reason: `${context} 必须是非负有限数` };
507
+ return {
508
+ reason: `${context} 必须是非负有限数`
509
+ };
541
510
  }
542
- return { value: normalized };
511
+ return {
512
+ value: normalized
513
+ };
543
514
  }
544
515
  function normalizeAvailabilityCutOffInteger(value, context) {
545
516
  const numeric = normalizeAvailabilityCutOffNumber(value, context);
546
- if (numeric.reason)
547
- return numeric;
517
+ if (numeric.reason) return numeric;
548
518
  if (!Number.isInteger(numeric.value)) {
549
- return { reason: `${context} 必须是非负整数` };
519
+ return {
520
+ reason: `${context} 必须是非负整数`
521
+ };
550
522
  }
551
- return { value: numeric.value };
523
+ return {
524
+ value: numeric.value
525
+ };
552
526
  }
553
527
  function invalidAvailabilityCutOffPolicy(reason) {
554
- return { type: "invalid", reason };
528
+ return {
529
+ type: 'invalid',
530
+ reason
531
+ };
555
532
  }
556
533
  function normalizeAvailabilityFutureDay(raw) {
557
- if (!Object.prototype.hasOwnProperty.call(raw, "future_day"))
558
- return {};
559
- const futureDay = normalizeAvailabilityCutOffInteger(raw.future_day, "cut_off_time.future_day");
560
- return futureDay.reason ? { reason: futureDay.reason } : { futureDay: futureDay.value };
534
+ if (!Object.prototype.hasOwnProperty.call(raw, 'future_day')) return {};
535
+ const futureDay = normalizeAvailabilityCutOffInteger(raw.future_day, 'cut_off_time.future_day');
536
+ return futureDay.reason ? {
537
+ reason: futureDay.reason
538
+ } : {
539
+ futureDay: futureDay.value
540
+ };
561
541
  }
562
542
  function normalizeAvailabilityCutOffPolicy(raw) {
563
- if (raw == null || raw === "")
564
- return void 0;
543
+ if (raw == null || raw === '') return undefined;
565
544
  if (!isRecord(raw)) {
566
- return invalidAvailabilityCutOffPolicy("cut_off_time 必须是对象");
545
+ return invalidAvailabilityCutOffPolicy('cut_off_time 必须是对象');
567
546
  }
568
547
  const futureDay = normalizeAvailabilityFutureDay(raw);
569
548
  if (futureDay.reason) {
570
549
  return invalidAvailabilityCutOffPolicy(futureDay.reason);
571
550
  }
572
- const type = String(raw.type ?? "").trim();
551
+ const type = String(raw.type ?? '').trim();
573
552
  if (!type) {
574
- return invalidAvailabilityCutOffPolicy("cut_off_time.type 缺失");
553
+ return invalidAvailabilityCutOffPolicy('cut_off_time.type 缺失');
575
554
  }
576
- if (type === "ongoing") {
555
+ if (type === 'ongoing') {
577
556
  if (!isRecord(raw.ongoing)) {
578
- return invalidAvailabilityCutOffPolicy("cut_off_time.ongoing 缺失");
557
+ return invalidAvailabilityCutOffPolicy('cut_off_time.ongoing 缺失');
579
558
  }
580
- const ongoingType = String(raw.ongoing.type ?? "").trim();
581
- if (ongoingType === "before_end") {
559
+ const ongoingType = String(raw.ongoing.type ?? '').trim();
560
+ if (ongoingType === 'before_end') {
582
561
  return {
583
- type: "ongoing",
584
- mode: "before_end",
585
- ...futureDay.futureDay === void 0 ? {} : { futureDay: futureDay.futureDay }
562
+ type: 'ongoing',
563
+ mode: 'before_end',
564
+ ...(futureDay.futureDay === undefined ? {} : {
565
+ futureDay: futureDay.futureDay
566
+ })
586
567
  };
587
568
  }
588
- if (ongoingType === "after_start") {
589
- const graceMinutes = normalizeAvailabilityCutOffNumber(
590
- raw.ongoing.unit,
591
- "cut_off_time.ongoing.unit"
592
- );
569
+ if (ongoingType === 'after_start') {
570
+ const graceMinutes = normalizeAvailabilityCutOffNumber(raw.ongoing.unit, 'cut_off_time.ongoing.unit');
593
571
  return graceMinutes.reason ? invalidAvailabilityCutOffPolicy(graceMinutes.reason) : {
594
- type: "ongoing",
595
- mode: "after_start",
572
+ type: 'ongoing',
573
+ mode: 'after_start',
596
574
  graceMinutes: graceMinutes.value,
597
- ...futureDay.futureDay === void 0 ? {} : { futureDay: futureDay.futureDay }
575
+ ...(futureDay.futureDay === undefined ? {} : {
576
+ futureDay: futureDay.futureDay
577
+ })
598
578
  };
599
579
  }
600
580
  return invalidAvailabilityCutOffPolicy(`未知的 cut_off_time.ongoing.type: ${ongoingType}`);
601
581
  }
602
- if (type === "before_start") {
582
+ if (type === 'before_start') {
603
583
  return {
604
- type: "before_start",
605
- ...futureDay.futureDay === void 0 ? {} : { futureDay: futureDay.futureDay }
584
+ type: 'before_start',
585
+ ...(futureDay.futureDay === undefined ? {} : {
586
+ futureDay: futureDay.futureDay
587
+ })
606
588
  };
607
589
  }
608
- if (type === "advance") {
609
- const unit = normalizeAvailabilityCutOffNumber(raw.unit, "cut_off_time.unit");
610
- if (unit.reason)
611
- return invalidAvailabilityCutOffPolicy(unit.reason);
612
- const unitType = String(raw.unit_type ?? "").trim();
613
- if (!["days", "hours", "minutes"].includes(unitType)) {
614
- return invalidAvailabilityCutOffPolicy("cut_off_time.unit_type 必须是 days|hours|minutes");
590
+ if (type === 'advance') {
591
+ const unit = normalizeAvailabilityCutOffNumber(raw.unit, 'cut_off_time.unit');
592
+ if (unit.reason) return invalidAvailabilityCutOffPolicy(unit.reason);
593
+ const unitType = String(raw.unit_type ?? '').trim();
594
+ if (!['days', 'hours', 'minutes'].includes(unitType)) {
595
+ return invalidAvailabilityCutOffPolicy('cut_off_time.unit_type 必须是 days|hours|minutes');
615
596
  }
616
597
  return {
617
- type: "advance",
598
+ type: 'advance',
618
599
  unit: unit.value,
619
- unitType,
620
- ...futureDay.futureDay === void 0 ? {} : { futureDay: futureDay.futureDay }
600
+ unitType: unitType,
601
+ ...(futureDay.futureDay === undefined ? {} : {
602
+ futureDay: futureDay.futureDay
603
+ })
621
604
  };
622
605
  }
623
606
  return invalidAvailabilityCutOffPolicy(`未知的 cut_off_time.type: ${type}`);
624
607
  }
625
- function normalizeResource(raw, fixedOffsetMinutes = (0, import_localClock.captureRuntimeOffsetMinutes)()) {
608
+ function normalizeResource(raw, fixedOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)()) {
626
609
  const id = raw.resourceId ?? raw.resource_id ?? raw.id;
627
- if (id === void 0 || id === null || id === "")
628
- return null;
610
+ if (id === undefined || id === null || id === '') return null;
629
611
  const rawWindows = raw.windows || raw.times || [];
630
612
  return {
631
613
  id,
@@ -634,123 +616,129 @@ function normalizeResource(raw, fixedOffsetMinutes = (0, import_localClock.captu
634
616
  code: raw.code,
635
617
  resourceType: normalizeResourceType(raw.type || raw.resourceType),
636
618
  capacity: Math.max(1, Number(raw.capacity || raw.max_capacity || 1) || 1),
637
- windows: (Array.isArray(rawWindows) ? rawWindows : []).flatMap((window) => {
619
+ windows: (Array.isArray(rawWindows) ? rawWindows : []).flatMap(window => {
638
620
  const range = normalizeAvailabilityLocalDateTimeRange({
639
621
  startAt: window.startAt || window.start_at || window.start,
640
622
  endAt: window.endAt || window.end_at || window.end,
641
623
  fixedOffsetMinutes,
642
624
  rollOverEnd: true
643
625
  });
644
- if (!range)
645
- return [];
646
- return [{ startAt: range.startAt, endAt: range.endAt, source: window.source, raw: window }];
626
+ if (!range) return [];
627
+ return [{
628
+ startAt: range.startAt,
629
+ endAt: range.endAt,
630
+ source: window.source,
631
+ raw: window
632
+ }];
647
633
  }),
648
634
  raw
649
635
  };
650
636
  }
651
637
  function normalizeScheduleIds(raw) {
652
638
  const ids = raw.schedule ?? raw.schedule_ids ?? raw.scheduleIds ?? [];
653
- return (Array.isArray(ids) ? ids : [ids]).map((id) => toNumberId(id)).filter((id) => id !== void 0);
639
+ return (Array.isArray(ids) ? ids : [ids]).map(id => toNumberId(id)).filter(id => id !== undefined);
654
640
  }
655
641
  function dateRangeDays(dateRange) {
656
- if (!(dateRange == null ? void 0 : dateRange.startDate) || !(dateRange == null ? void 0 : dateRange.endDate))
657
- return [];
642
+ if (!dateRange?.startDate || !dateRange?.endDate) return [];
658
643
  const dates = [];
659
- const startScalar = (0, import_localClock.localDateToScalarStart)((0, import_localClock.parseLocalDate)(dateRange.startDate));
660
- const endScalar = (0, import_localClock.localDateToScalarStart)((0, import_localClock.parseLocalDate)(dateRange.endDate));
661
- if (endScalar < startScalar)
662
- return dates;
663
- for (let cursor = startScalar; cursor <= endScalar; cursor = (0, import_localClock.addLocalCalendarDays)(cursor, 1)) {
664
- dates.push((0, import_localClock.formatLocalDate)(cursor));
644
+ const startScalar = (0, _localClock.localDateToScalarStart)((0, _localClock.parseLocalDate)(dateRange.startDate));
645
+ const endScalar = (0, _localClock.localDateToScalarStart)((0, _localClock.parseLocalDate)(dateRange.endDate));
646
+ if (endScalar < startScalar) return dates;
647
+ for (let cursor = startScalar; cursor <= endScalar; cursor = (0, _localClock.addLocalCalendarDays)(cursor, 1)) {
648
+ dates.push((0, _localClock.formatLocalDate)(cursor));
665
649
  }
666
650
  return dates;
667
651
  }
668
- function normalizeResourceOccupancy(rawEvent, resourceId, source = "remote", fixedOffsetMinutes = (0, import_localClock.captureRuntimeOffsetMinutes)()) {
669
- var _a, _b;
652
+ function normalizeResourceOccupancy(rawEvent, resourceId, source = 'remote', fixedOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)()) {
670
653
  const range = normalizeAvailabilityLocalDateTimeRange({
671
654
  startAt: rawEvent.start_at ?? rawEvent.startAt ?? rawEvent.start_time ?? rawEvent.startTime,
672
655
  endAt: rawEvent.end_at ?? rawEvent.endAt ?? rawEvent.end_time ?? rawEvent.endTime,
673
656
  fixedOffsetMinutes,
674
657
  rollOverEnd: false
675
658
  });
676
- if (!range)
677
- return null;
659
+ if (!range) return null;
678
660
  return {
679
- id: rawEvent.id == null ? void 0 : String(rawEvent.id),
661
+ id: rawEvent.id == null ? undefined : String(rawEvent.id),
680
662
  resourceId,
681
663
  startAt: range.startAt,
682
664
  endAt: range.endAt,
683
665
  pax: Number(rawEvent.pax ?? rawEvent.number ?? rawEvent.capacity ?? 1) || 1,
684
- source: rawEvent.source === "cart" || rawEvent.source === "selection" ? rawEvent.source : source,
666
+ source: rawEvent.source === 'cart' || rawEvent.source === 'selection' ? rawEvent.source : source,
685
667
  scheduleEventId: toNumberId(rawEvent.schedule_event_id ?? rawEvent.scheduleEventId),
686
668
  serverEventId: toNumberId(rawEvent.schedule_event_id ?? rawEvent.server_event_id ?? rawEvent.id),
687
- bookingUid: rawEvent.booking_uid ?? rawEvent.bookingUid ?? ((_a = rawEvent.metadata) == null ? void 0 : _a.unique_identification_number),
688
- productUid: rawEvent.product_uid ?? rawEvent.productUid ?? ((_b = rawEvent.metadata) == null ? void 0 : _b.product_uid),
669
+ bookingUid: rawEvent.booking_uid ?? rawEvent.bookingUid ?? rawEvent.metadata?.unique_identification_number,
670
+ productUid: rawEvent.product_uid ?? rawEvent.productUid ?? rawEvent.metadata?.product_uid,
689
671
  raw: rawEvent
690
672
  };
691
673
  }
692
674
  function buildResourceWindowFallbackTimes(params) {
693
- const { raw, dates, scheduleIds } = params;
694
- const fixedOffsetMinutes = params.fixedOffsetMinutes ?? (0, import_localClock.captureRuntimeOffsetMinutes)();
675
+ const {
676
+ raw,
677
+ dates,
678
+ scheduleIds
679
+ } = params;
680
+ const fixedOffsetMinutes = params.fixedOffsetMinutes ?? (0, _localClock.captureRuntimeOffsetMinutes)();
695
681
  const boundary = normalizeAvailabilityLocalDateTimeRange({
696
682
  startAt: raw.start_time || raw.start_at || raw.startTime,
697
683
  endAt: raw.end_time || raw.end_at || raw.endTime,
698
684
  fixedOffsetMinutes,
699
685
  rollOverEnd: true
700
686
  });
701
- if (!boundary)
702
- return [];
703
- return dates.flatMap((date) => {
704
- const dayStart = (0, import_localClock.localDateTimeToScalar)((0, import_localClock.parseLocalDateTime)(`${date}T00:00:00`));
705
- const dayEnd = (0, import_localClock.localDateTimeToScalar)((0, import_localClock.parseLocalDateTime)(`${date}T23:59:59`));
687
+ if (!boundary) return [];
688
+ return dates.flatMap(date => {
689
+ const dayStart = (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(`${date}T00:00:00`));
690
+ const dayEnd = (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(`${date}T23:59:59`));
706
691
  const start = Math.max(boundary.startScalar, dayStart);
707
692
  const end = Math.min(boundary.endScalar, dayEnd);
708
- if (end <= start)
709
- return [];
693
+ if (end <= start) return [];
710
694
  return [{
711
- start_at: (0, import_localClock.formatLocalDateTime)(start, fixedOffsetMinutes),
712
- end_at: (0, import_localClock.formatLocalDateTime)(end, fixedOffsetMinutes),
695
+ start_at: (0, _localClock.formatLocalDateTime)(start, fixedOffsetMinutes),
696
+ end_at: (0, _localClock.formatLocalDateTime)(end, fixedOffsetMinutes),
713
697
  schedule_ids: scheduleIds,
714
- source: "resource_window_fallback"
698
+ source: 'resource_window_fallback'
715
699
  }];
716
700
  });
717
701
  }
702
+
703
+ /**
704
+ * Materializes resource work windows locally from v2's schedule ids, then keeps its flat
705
+ * event_list as resource occupancy records. This deliberately avoids the older API's times -> event_list
706
+ * response nesting and lets one resource response serve any requested date range.
707
+ */
718
708
  function buildAvailabilityResourcesFromV2(params) {
719
- const scheduleMap = new Map(
720
- (params.scheduleList || []).map((schedule) => [String(schedule.id), schedule])
721
- );
709
+ const scheduleMap = new Map((params.scheduleList || []).map(schedule => [String(schedule.id), schedule]));
722
710
  const dates = dateRangeDays(params.dateRange);
723
711
  const resourceOccupancies = [];
724
- const fixedOffsetMinutes = params.fixedOffsetMinutes ?? (0, import_localClock.captureRuntimeOffsetMinutes)();
725
- const resources = (params.rawResources || []).map((raw) => {
712
+ const fixedOffsetMinutes = params.fixedOffsetMinutes ?? (0, _localClock.captureRuntimeOffsetMinutes)();
713
+ const resources = (params.rawResources || []).map(raw => {
726
714
  const resource = normalizeResource(raw, fixedOffsetMinutes);
727
- if (!resource)
728
- return null;
715
+ if (!resource) return null;
729
716
  const explicitWindows = [...resource.windows];
730
717
  const scheduleIds = normalizeScheduleIds(raw);
731
- const schedules = scheduleIds.map((id) => scheduleMap.get(String(id))).filter(Boolean);
732
- const matchedScheduleIds = new Set(schedules.map((schedule) => String(schedule.id)));
733
- const missingScheduleIds = scheduleIds.filter((id) => !matchedScheduleIds.has(String(id)));
718
+ const schedules = scheduleIds.map(id => scheduleMap.get(String(id))).filter(Boolean);
719
+ const matchedScheduleIds = new Set(schedules.map(schedule => String(schedule.id)));
720
+ const missingScheduleIds = scheduleIds.filter(id => !matchedScheduleIds.has(String(id)));
734
721
  if (missingScheduleIds.length > 0) {
735
722
  resource.raw = {
736
- ...resource.raw || raw,
723
+ ...(resource.raw || raw),
737
724
  _availabilityMissingScheduleIds: missingScheduleIds
738
725
  };
739
726
  }
740
- const materializedWindows = dates.flatMap((date) => schedules.flatMap((schedule) => (0, import_getDateIsInSchedule.getScheduleStartEndTimePoints)(date, [schedule]).flatMap((slot) => {
727
+ const materializedWindows = dates.flatMap(date => schedules.flatMap(schedule => (0, _getDateIsInSchedule.getScheduleStartEndTimePoints)(date, [schedule]).flatMap(slot => {
741
728
  const range = normalizeAvailabilityLocalDateTimeRange({
742
729
  startAt: slot.start_at,
743
730
  endAt: slot.end_at,
744
731
  fixedOffsetMinutes,
745
732
  rollOverEnd: true
746
733
  });
747
- if (!range)
748
- return [];
734
+ if (!range) return [];
749
735
  return [{
750
736
  startAt: range.startAt,
751
737
  endAt: range.endAt,
752
738
  source: `resource_schedule:${schedule.id}`,
753
- raw: { scheduleId: schedule.id }
739
+ raw: {
740
+ scheduleId: schedule.id
741
+ }
754
742
  }];
755
743
  })));
756
744
  resource.windows = materializedWindows.length > 0 ? materializedWindows : explicitWindows;
@@ -760,7 +748,7 @@ function buildAvailabilityResourcesFromV2(params) {
760
748
  dates,
761
749
  scheduleIds,
762
750
  fixedOffsetMinutes
763
- }).map((window) => ({
751
+ }).map(window => ({
764
752
  startAt: window.start_at,
765
753
  endAt: window.end_at,
766
754
  source: window.source,
@@ -768,40 +756,35 @@ function buildAvailabilityResourcesFromV2(params) {
768
756
  }));
769
757
  }
770
758
  const eventList = Array.isArray(raw.event_list) ? raw.event_list : [];
771
- eventList.forEach((event) => {
772
- const occupancy = normalizeResourceOccupancy(event, resource.id, "remote", fixedOffsetMinutes);
773
- if (occupancy)
774
- resourceOccupancies.push(occupancy);
759
+ eventList.forEach(event => {
760
+ const occupancy = normalizeResourceOccupancy(event, resource.id, 'remote', fixedOffsetMinutes);
761
+ if (occupancy) resourceOccupancies.push(occupancy);
775
762
  });
776
763
  return resource;
777
- }).filter((resource) => resource !== null);
764
+ }).filter(resource => resource !== null);
778
765
  return {
779
766
  resources,
780
767
  resourceOccupancies
781
768
  };
782
769
  }
770
+
771
+ /** Combines URL-locked resources with every resource referenced by the selected products. */
783
772
  function collectAvailabilityResourceIds(products, explicitResourceIds = []) {
784
- const ids = /* @__PURE__ */ new Map();
785
- const add = (value) => {
786
- if (value === void 0 || value === null || value === "")
787
- return;
773
+ const ids = new Map();
774
+ const add = value => {
775
+ if (value === undefined || value === null || value === '') return;
788
776
  ids.set(String(value), value);
789
777
  };
790
778
  explicitResourceIds.forEach(add);
791
- products.forEach((product) => {
792
- var _a;
793
- (_a = product.requirementGroups) == null ? void 0 : _a.forEach((requirement) => {
794
- var _a2;
795
- (_a2 = requirement.resourceIds) == null ? void 0 : _a2.forEach(add);
779
+ products.forEach(product => {
780
+ product.requirementGroups?.forEach(requirement => {
781
+ requirement.resourceIds?.forEach(add);
796
782
  });
797
783
  });
798
784
  return Array.from(ids.values());
799
785
  }
800
786
  function getProductLineUid(product) {
801
- var _a;
802
- return String(
803
- ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) ?? (product == null ? void 0 : product.unique_identification_number) ?? ""
804
- );
787
+ return String(product?.metadata?.unique_identification_number ?? product?.unique_identification_number ?? '');
805
788
  }
806
789
  function buildAvailabilityLineIdentity(product) {
807
790
  return {
@@ -821,25 +804,22 @@ function buildBookingFromAvailabilityAssignment(params) {
821
804
  });
822
805
  }
823
806
  function buildBookingFromAvailabilityAssignments(params) {
824
- const normalizedAssignments = (params.assignments || []).map((assignment) => {
807
+ const normalizedAssignments = (params.assignments || []).map(assignment => {
825
808
  const resourceId = assignment.resourceId ?? assignment.resource_id;
826
- const matchedGroup = (params.product.requirementGroups || []).find((group) => {
827
- var _a;
828
- return (_a = group.resourceIds) == null ? void 0 : _a.some((id) => sameAvailabilityId(id, resourceId));
829
- });
809
+ const matchedGroup = (params.product.requirementGroups || []).find(group => group.resourceIds?.some(id => sameAvailabilityId(id, resourceId)));
830
810
  return {
831
811
  productId: assignment.productId ?? assignment.product_id,
832
812
  resourceId,
833
- formId: assignment.formId ?? assignment.form_id ?? (matchedGroup == null ? void 0 : matchedGroup.formId),
813
+ formId: assignment.formId ?? assignment.form_id ?? matchedGroup?.formId,
834
814
  startAt: assignment.startAt ?? assignment.start_at,
835
815
  endAt: assignment.endAt ?? assignment.end_at,
836
- capacityRequired: assignment.capacityRequired ?? assignment.capacity_required ?? (matchedGroup == null ? void 0 : matchedGroup.capacityRequired),
816
+ capacityRequired: assignment.capacityRequired ?? assignment.capacity_required ?? matchedGroup?.capacityRequired,
837
817
  scheduleId: assignment.scheduleId ?? assignment.schedule_id,
838
818
  timeSlotId: assignment.timeSlotId ?? assignment.time_slot_id
839
819
  };
840
820
  });
841
821
  const first = normalizedAssignments[0];
842
- const fixedOffsetMinutes = params.fixedOffsetMinutes ?? (0, import_localClock.captureRuntimeOffsetMinutes)();
822
+ const fixedOffsetMinutes = params.fixedOffsetMinutes ?? (0, _localClock.captureRuntimeOffsetMinutes)();
843
823
  const range = normalizeAvailabilityLocalDateTimeRange({
844
824
  startAt: first.startAt,
845
825
  endAt: first.endAt,
@@ -847,24 +827,24 @@ function buildBookingFromAvailabilityAssignments(params) {
847
827
  rollOverEnd: false
848
828
  });
849
829
  if (!range) {
850
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "assignment 时间范围非法", {
830
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', 'assignment 时间范围非法', {
851
831
  assignments: params.assignments
852
832
  });
853
833
  }
854
834
  const candidate = {
855
835
  key: `${String(first.productId)}:${range.startAt}:${range.endAt}`,
856
836
  productId: first.productId,
857
- source: "duration_window",
837
+ source: 'duration_window',
858
838
  startAt: range.startAt,
859
839
  endAt: range.endAt,
860
840
  bookingStartAt: range.startAt,
861
841
  bookingEndAt: range.endAt,
862
842
  date: range.startAt.slice(0, 10),
863
- startTime: (0, import_localClock.formatLocalTime)(range.startAt, false),
864
- endTime: (0, import_localClock.formatLocalTime)(range.endAt, false),
865
- timezone: String(params.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone || "runtime"),
843
+ startTime: (0, _localClock.formatLocalTime)(range.startAt, false),
844
+ endTime: (0, _localClock.formatLocalTime)(range.endAt, false),
845
+ timezone: String(params.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone || 'runtime'),
866
846
  scheduleRefs: [],
867
- primaryScheduleRef: void 0
847
+ primaryScheduleRef: undefined
868
848
  };
869
849
  return buildBookingFromAvailabilitySelection({
870
850
  assignments: normalizedAssignments,
@@ -873,18 +853,13 @@ function buildBookingFromAvailabilityAssignments(params) {
873
853
  });
874
854
  }
875
855
  function getBookingUid(booking) {
876
- var _a;
877
- return String(
878
- ((_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.unique_identification_number) ?? (booking == null ? void 0 : booking.booking_uid) ?? ""
879
- );
856
+ return String(booking?.metadata?.unique_identification_number ?? booking?.booking_uid ?? '');
880
857
  }
881
858
  function stableValue(value) {
882
- if (Array.isArray(value))
883
- return value.map(stableValue);
884
- if (!value || typeof value !== "object")
885
- return value;
859
+ if (Array.isArray(value)) return value.map(stableValue);
860
+ if (!value || typeof value !== 'object') return value;
886
861
  return Object.keys(value).sort().reduce((result, key) => {
887
- if (value[key] !== void 0 && typeof value[key] !== "function") {
862
+ if (value[key] !== undefined && typeof value[key] !== 'function') {
888
863
  result[key] = stableValue(value[key]);
889
864
  }
890
865
  return result;
@@ -899,21 +874,17 @@ function hashText(value) {
899
874
  return (hash >>> 0).toString(36);
900
875
  }
901
876
  function resolveOrderRevision(tempOrder) {
902
- if (!tempOrder)
903
- return "order:none";
904
- const products = (Array.isArray(tempOrder.products) ? tempOrder.products : []).map((product) => {
905
- var _a;
906
- return {
907
- uid: getProductLineUid(product),
908
- productId: product.product_id ?? product.id,
909
- variantId: product.product_variant_id ?? 0,
910
- num: product.num ?? product.quantity ?? 1,
911
- bookingUid: product.booking_uid ?? ((_a = product.metadata) == null ? void 0 : _a.booking_uid),
912
- productSku: product.product_sku,
913
- productBundle: product.product_bundle
914
- };
915
- }).sort((left, right) => left.uid.localeCompare(right.uid));
916
- const bookings = (Array.isArray(tempOrder.bookings) ? tempOrder.bookings : []).map((booking) => ({
877
+ if (!tempOrder) return 'order:none';
878
+ const products = (Array.isArray(tempOrder.products) ? tempOrder.products : []).map(product => ({
879
+ uid: getProductLineUid(product),
880
+ productId: product.product_id ?? product.id,
881
+ variantId: product.product_variant_id ?? 0,
882
+ num: product.num ?? product.quantity ?? 1,
883
+ bookingUid: product.booking_uid ?? product.metadata?.booking_uid,
884
+ productSku: product.product_sku,
885
+ productBundle: product.product_bundle
886
+ })).sort((left, right) => left.uid.localeCompare(right.uid));
887
+ const bookings = (Array.isArray(tempOrder.bookings) ? tempOrder.bookings : []).map(booking => ({
917
888
  uid: getBookingUid(booking),
918
889
  scheduleEventId: booking.schedule_event_id,
919
890
  productUid: booking.product_uid,
@@ -924,10 +895,12 @@ function resolveOrderRevision(tempOrder) {
924
895
  endTime: booking.end_time,
925
896
  resources: booking.resources
926
897
  })).sort((left, right) => left.uid.localeCompare(right.uid));
927
- return `order:${hashText(JSON.stringify(stableValue({ products, bookings })))}`;
898
+ return `order:${hashText(JSON.stringify(stableValue({
899
+ products,
900
+ bookings
901
+ })))}`;
928
902
  }
929
903
  function buildBookingFromAvailabilitySelection(params) {
930
- var _a, _b, _c, _d;
931
904
  const {
932
905
  assignments,
933
906
  candidate,
@@ -937,12 +910,12 @@ function buildBookingFromAvailabilitySelection(params) {
937
910
  } = params;
938
911
  const bookingStartAt = candidate.bookingStartAt || candidate.startAt;
939
912
  const bookingEndAt = candidate.bookingEndAt || candidate.endAt;
940
- const startScalar = (0, import_localClock.localDateTimeToScalar)((0, import_localClock.parseLocalDateTime)(bookingStartAt));
941
- const endScalar = (0, import_localClock.localDateTimeToScalar)((0, import_localClock.parseLocalDateTime)(bookingEndAt));
942
- const scheduleId = ((_a = candidate.primaryScheduleRef) == null ? void 0 : _a.scheduleId) ?? ((_b = assignments.find((assignment) => assignment.scheduleId != null)) == null ? void 0 : _b.scheduleId);
943
- const timeSlotId = ((_c = candidate.primaryScheduleRef) == null ? void 0 : _c.timeSlotId) ?? ((_d = assignments.find((assignment) => assignment.timeSlotId != null)) == null ? void 0 : _d.timeSlotId);
944
- if (product.kind === "session" && scheduleId == null) {
945
- throw new import_ResourcePlanner.AvailabilityError("REVALIDATION_FAILED", "session 候选缺少真实 schedule identity", {
913
+ const startScalar = (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(bookingStartAt));
914
+ const endScalar = (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(bookingEndAt));
915
+ const scheduleId = candidate.primaryScheduleRef?.scheduleId ?? assignments.find(assignment => assignment.scheduleId != null)?.scheduleId;
916
+ const timeSlotId = candidate.primaryScheduleRef?.timeSlotId ?? assignments.find(assignment => assignment.timeSlotId != null)?.timeSlotId;
917
+ if (product.kind === 'session' && scheduleId == null) {
918
+ throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', 'session 候选缺少真实 schedule identity', {
946
919
  productId: product.id,
947
920
  candidateKey: candidate.key,
948
921
  scheduleRefs: candidate.scheduleRefs
@@ -953,123 +926,120 @@ function buildBookingFromAvailabilitySelection(params) {
953
926
  start_time: bookingStartAt.slice(11, 16),
954
927
  end_date: bookingEndAt.slice(0, 10),
955
928
  end_time: bookingEndAt.slice(11, 16),
956
- duration: Math.max(1, Math.trunc((endScalar - startScalar) / (60 * 1e3))),
957
- like_status: "common",
929
+ duration: Math.max(1, Math.trunc((endScalar - startScalar) / (60 * 1000))),
930
+ like_status: 'common',
958
931
  schedule_id: scheduleId ?? 0,
959
- resources: assignments.map((assignment) => {
960
- const matchedResource = resources.find((resource) => sameAvailabilityId(resource.id, assignment.resourceId));
961
- const resourceName = String((matchedResource == null ? void 0 : matchedResource.name) || "").trim();
932
+ resources: assignments.map(assignment => {
933
+ // requirementSelections 的提交协议只携带资源 ID;购物车展示则需要名称。
934
+ // commit 此时仍持有本次不可变 projection,因此直接按 ID 取回名称并
935
+ // 固化到 booking,避免 UI 再依赖 legacy BookingContext resourcesOriginMap。
936
+ const matchedResource = resources.find(resource => sameAvailabilityId(resource.id, assignment.resourceId));
937
+ const resourceName = String(matchedResource?.name || '').trim();
962
938
  return {
963
939
  id: assignment.resourceId,
964
940
  resource_id: assignment.resourceId,
965
941
  form_id: assignment.formId,
966
- relation_type: "form",
942
+ relation_type: 'form',
967
943
  relation_id: assignment.resourceId,
968
- like_status: "common",
944
+ like_status: 'common',
969
945
  capacity: assignment.capacityRequired || 1,
970
- ...resourceName ? { metadata: { resource_name: resourceName } } : {}
946
+ ...(resourceName ? {
947
+ metadata: {
948
+ resource_name: resourceName
949
+ }
950
+ } : {})
971
951
  };
972
952
  }),
973
953
  metadata: {
974
- ...bookingUid ? { unique_identification_number: bookingUid } : {},
954
+ ...(bookingUid ? {
955
+ unique_identification_number: bookingUid
956
+ } : {}),
975
957
  unified_booking_sales: true,
976
958
  availability_candidate_key: candidate.key,
977
959
  availability_source: candidate.source,
978
960
  availability_slice_start_at: candidate.startAt,
979
961
  availability_slice_end_at: candidate.endAt,
980
962
  availability_schedule_refs: candidate.scheduleRefs,
981
- ...timeSlotId == null ? {} : { time_slot_id: timeSlotId },
963
+ ...(timeSlotId == null ? {} : {
964
+ time_slot_id: timeSlotId
965
+ }),
982
966
  product_kind: product.kind
983
967
  }
984
968
  };
985
969
  }
986
- var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
987
- constructor() {
988
- super(...arguments);
989
- this.defaultName = "unifiedBookingSales";
990
- this.defaultVersion = "1.0.0";
991
- this.store = {};
992
- this.unifiedProductCatalog = [];
993
- this.openDataTarget = null;
994
- this.loadOpenDataInFlight = null;
995
- this.loadOpenDataInFlightTarget = null;
996
- this.availabilityRuntimeOffsetMinutes = null;
997
- this.availabilityScheduleCatalog = null;
998
- this.availabilityProjectionSequence = 0;
999
- this.availabilityContextSequence = 0;
1000
- this.availabilityLifecycleGeneration = 0;
1001
- this.availabilityContextRegistry = /* @__PURE__ */ new Map();
1002
- this.availabilityProjectionPool = /* @__PURE__ */ new Map();
1003
- this.availabilityPrepareInFlight = /* @__PURE__ */ new Map();
1004
- this.availabilityProjectionRefreshInFlight = /* @__PURE__ */ new Map();
1005
- this.availabilityRemoteOccupancyCache = new import_remoteOccupancyCache.AvailabilityRemoteOccupancyCache(
1006
- MAX_REMOTE_OCCUPANCY_RESOURCE_DATE_CELLS
1007
- );
1008
- this.availabilityRemoteResourceQueryInFlight = /* @__PURE__ */ new Map();
1009
- this.availabilityRemoteResourceQuerySequence = 0;
1010
- this.availabilityRemoteResourceEpoch = 0;
1011
- this.availabilityCommitLocks = /* @__PURE__ */ new Set();
1012
- }
970
+ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
971
+ defaultName = 'unifiedBookingSales';
972
+ defaultVersion = '1.0.0';
973
+ store = {};
974
+ unifiedProductCatalog = [];
975
+ openDataTarget = null;
976
+ loadOpenDataInFlight = null;
977
+ loadOpenDataInFlightTarget = null;
978
+ availabilityRuntimeOffsetMinutes = null;
979
+ availabilityScheduleCatalog = null;
980
+ availabilityProjectionSequence = 0;
981
+ availabilityContextSequence = 0;
982
+ availabilityLifecycleGeneration = 0;
983
+ availabilityContextRegistry = new Map();
984
+ availabilityProjectionPool = new Map();
985
+ availabilityPrepareInFlight = new Map();
986
+ availabilityProjectionRefreshInFlight = new Map();
987
+ availabilityRemoteOccupancyCache = new _remoteOccupancyCache.AvailabilityRemoteOccupancyCache(MAX_REMOTE_OCCUPANCY_RESOURCE_DATE_CELLS);
988
+ availabilityRemoteResourceQueryInFlight = new Map();
989
+ availabilityRemoteResourceQuerySequence = 0;
990
+ availabilityRemoteResourceEpoch = 0;
991
+ availabilityCommitLocks = new Set();
1013
992
  async initialize(core, options = {}) {
1014
- var _a, _b, _c, _d;
1015
993
  this.availabilityScheduleCatalog = null;
1016
994
  this.openDataTarget = null;
1017
- this.availabilityRuntimeOffsetMinutes = (0, import_localClock.captureRuntimeOffsetMinutes)();
995
+ this.availabilityRuntimeOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)();
1018
996
  this.clearAvailabilityRemoteResourceState();
1019
997
  await super.initialize(core, options);
1020
- const openDataBusinessCode = String(
1021
- ((_a = this.otherParams) == null ? void 0 : _a.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.business_code) ?? ""
1022
- ).trim();
1023
- const openDataChannel = String(((_c = this.otherParams) == null ? void 0 : _c.channel) ?? "").trim();
1024
- if (((_d = this.otherParams) == null ? void 0 : _d.openData) && openDataBusinessCode && openDataChannel) {
998
+ const openDataBusinessCode = String(this.otherParams?.businessCode ?? this.otherParams?.business_code ?? '').trim();
999
+ const openDataChannel = String(this.otherParams?.channel ?? '').trim();
1000
+ if (this.otherParams?.openData && openDataBusinessCode && openDataChannel) {
1025
1001
  this.openDataTarget = `${openDataBusinessCode}+${openDataChannel}`;
1026
1002
  }
1027
1003
  this.captureAvailabilityScheduleCatalog();
1028
1004
  }
1029
1005
  getSubmitOrderSalesChannel() {
1030
- var _a;
1031
- const channel = String(((_a = this.otherParams) == null ? void 0 : _a.channel) ?? "").trim();
1006
+ const channel = String(this.otherParams?.channel ?? '').trim();
1032
1007
  return channel || super.getSubmitOrderSalesChannel();
1033
1008
  }
1034
1009
  createAvailabilityFacadeError(code, message, details) {
1035
- return new import_ResourcePlanner.AvailabilityError(code, message, details);
1010
+ return new _ResourcePlanner.AvailabilityError(code, message, details);
1036
1011
  }
1037
1012
  getAvailabilityScopeDescriptor(otherParams = this.otherParams || {}) {
1038
1013
  return {
1039
- cacheId: this.cacheId || "",
1040
- businessCode: String(otherParams.businessCode ?? otherParams.business_code ?? ""),
1041
- channel: String(otherParams.channel ?? ""),
1042
- platform: String(otherParams.platform ?? ""),
1043
- businessTimezone: String(otherParams.businessTimezone ?? "")
1014
+ cacheId: this.cacheId || '',
1015
+ businessCode: String(otherParams.businessCode ?? otherParams.business_code ?? ''),
1016
+ channel: String(otherParams.channel ?? ''),
1017
+ platform: String(otherParams.platform ?? ''),
1018
+ businessTimezone: String(otherParams.businessTimezone ?? '')
1044
1019
  };
1045
1020
  }
1046
1021
  normalizeAvailabilityIdList(values) {
1047
- if (!Array.isArray(values) || values.length === 0)
1048
- return void 0;
1049
- const uniqueMap = /* @__PURE__ */ new Map();
1050
- values.forEach((value) => {
1022
+ if (!Array.isArray(values) || values.length === 0) return undefined;
1023
+ const uniqueMap = new Map();
1024
+ values.forEach(value => {
1051
1025
  uniqueMap.set(String(value), value);
1052
1026
  });
1053
1027
  return Array.from(uniqueMap.entries()).sort(([left], [right]) => left.localeCompare(right)).map(([, value]) => value);
1054
1028
  }
1055
1029
  normalizeAvailabilityStringList(values) {
1056
- if (!Array.isArray(values) || values.length === 0)
1057
- return void 0;
1030
+ if (!Array.isArray(values) || values.length === 0) return undefined;
1058
1031
  return Array.from(new Set(values.map(String))).sort((left, right) => left.localeCompare(right));
1059
1032
  }
1060
1033
  normalizeAvailabilityPrepareDescriptor(params) {
1061
- var _a;
1062
1034
  this.assertAvailabilityPrepareParams(params);
1063
- const timezone = String(
1064
- params.timezone || ((_a = this.otherParams) == null ? void 0 : _a.businessTimezone) || Intl.DateTimeFormat().resolvedOptions().timeZone || "Asia/Shanghai"
1065
- );
1035
+ const timezone = String(params.timezone || this.otherParams?.businessTimezone || Intl.DateTimeFormat().resolvedOptions().timeZone || 'Asia/Shanghai');
1066
1036
  assertValidAvailabilityTimezone(timezone);
1067
1037
  const dateRange = this.normalizeAvailabilityDateRange(params, timezone);
1068
1038
  const slotStepMinutes = params.slotStepMinutes || DEFAULT_AVAILABILITY_SLOT_STEP_MINUTES;
1069
1039
  const businessHours = params.businessHours || DEFAULT_AVAILABILITY_BUSINESS_HOURS;
1070
- const mode = params.mode || "appointment";
1040
+ const mode = params.mode || 'appointment';
1071
1041
  if (!isValidClockTime(businessHours.startTime) || !isValidClockTime(businessHours.endTime)) {
1072
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "businessHours 必须使用 HH:mm", {
1042
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', 'businessHours 必须使用 HH:mm', {
1073
1043
  businessHours
1074
1044
  });
1075
1045
  }
@@ -1081,63 +1051,58 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1081
1051
  dateRange,
1082
1052
  timezone,
1083
1053
  slotStepMinutes,
1084
- businessHours: { ...businessHours },
1054
+ businessHours: {
1055
+ ...businessHours
1056
+ },
1085
1057
  _availabilityOperatingHours: params._availabilityOperatingHours ? {
1086
1058
  source: params._availabilityOperatingHours.source,
1087
1059
  scheduleIds: [...params._availabilityOperatingHours.scheduleIds]
1088
- } : void 0,
1060
+ } : undefined,
1089
1061
  mode
1090
1062
  });
1091
1063
  }
1092
1064
  async resolveAvailabilityPrepareDefaults(params) {
1093
- var _a, _b, _c, _d;
1094
- const needsOperatingHours = params.businessHours === void 0;
1095
- const needsTimeSlice = params.slotStepMinutes === void 0;
1065
+ const needsOperatingHours = params.businessHours === undefined;
1066
+ const needsTimeSlice = params.slotStepMinutes === undefined;
1096
1067
  if (!needsOperatingHours && !needsTimeSlice) {
1097
1068
  return {
1098
1069
  ...params,
1099
1070
  _availabilityOperatingHours: {
1100
- source: "prepare_business_hours",
1071
+ source: 'prepare_business_hours',
1101
1072
  scheduleIds: []
1102
1073
  }
1103
1074
  };
1104
1075
  }
1105
- const businessCode = String(
1106
- ((_a = this.otherParams) == null ? void 0 : _a.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.business_code) ?? ""
1107
- ).trim();
1108
- const channel = String(((_c = this.otherParams) == null ? void 0 : _c.channel) ?? "").trim();
1076
+ const businessCode = String(this.otherParams?.businessCode ?? this.otherParams?.business_code ?? '').trim();
1077
+ const channel = String(this.otherParams?.channel ?? '').trim();
1109
1078
  const currentTarget = businessCode && channel ? `${businessCode}+${channel}` : null;
1110
- let openData = !currentTarget || this.openDataTarget === currentTarget ? (_d = this.otherParams) == null ? void 0 : _d.openData : null;
1079
+ let openData = !currentTarget || this.openDataTarget === currentTarget ? this.otherParams?.openData : null;
1111
1080
  if (!openData && this.store.openData) {
1112
1081
  try {
1113
1082
  openData = await this.getOpenData();
1114
1083
  } catch (error) {
1115
1084
  if (needsOperatingHours) {
1116
- throw this.createAvailabilityFacadeError(
1117
- "OPERATING_HOURS_RESOLVE_FAILED",
1118
- "无法读取店铺营业时间配置,请重试",
1119
- {
1120
- businessCode,
1121
- channel,
1122
- cause: error instanceof Error ? error.message : String(error)
1123
- }
1124
- );
1085
+ throw this.createAvailabilityFacadeError('OPERATING_HOURS_RESOLVE_FAILED', '无法读取店铺营业时间配置,请重试', {
1086
+ businessCode,
1087
+ channel,
1088
+ cause: error instanceof Error ? error.message : String(error)
1089
+ });
1125
1090
  }
1126
- console.warn("[UnifiedBookingSales] OpenData 时间切片配置加载失败,回退为默认值", error);
1091
+ console.warn('[UnifiedBookingSales] OpenData 时间切片配置加载失败,回退为默认值', error);
1127
1092
  }
1128
1093
  }
1129
- const operatingScheduleIds = this.normalizeAvailabilityIdList(
1130
- Array.isArray(openData == null ? void 0 : openData["availability.operating_hours"]) ? openData == null ? void 0 : openData["availability.operating_hours"] : void 0
1131
- ) || [];
1132
- const configuredTimeSlice = needsTimeSlice ? normalizePositiveInteger(openData == null ? void 0 : openData["reservation.time_slice"]) : void 0;
1094
+ const operatingScheduleIds = this.normalizeAvailabilityIdList(Array.isArray(openData?.['availability.operating_hours']) ? openData?.['availability.operating_hours'] : undefined) || [];
1095
+ const configuredTimeSlice = needsTimeSlice ? normalizePositiveInteger(openData?.['reservation.time_slice']) : undefined;
1133
1096
  return {
1134
1097
  ...params,
1135
- ...configuredTimeSlice ? { slotStepMinutes: configuredTimeSlice } : {},
1098
+ ...(configuredTimeSlice ? {
1099
+ slotStepMinutes: configuredTimeSlice
1100
+ } : {}),
1136
1101
  _availabilityOperatingHours: needsOperatingHours ? {
1137
- source: operatingScheduleIds.length > 0 ? "open_data_schedule" : "default_business_hours",
1102
+ source: operatingScheduleIds.length > 0 ? 'open_data_schedule' : 'default_business_hours',
1138
1103
  scheduleIds: operatingScheduleIds
1139
1104
  } : {
1140
- source: "prepare_business_hours",
1105
+ source: 'prepare_business_hours',
1141
1106
  scheduleIds: []
1142
1107
  }
1143
1108
  };
@@ -1169,24 +1134,27 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1169
1134
  resourceIds: this.normalizeAvailabilityIdList(params.resourceIds) || []
1170
1135
  }));
1171
1136
  }
1172
- async setOtherParams(params, { cover = false } = {}) {
1173
- var _a;
1137
+ async setOtherParams(params, {
1138
+ cover = false
1139
+ } = {}) {
1174
1140
  const previousScope = this.getAvailabilityScopeDescriptor(this.otherParams || {});
1175
- const explicitlySetsOpenData = Object.prototype.hasOwnProperty.call(params, "openData");
1176
- await super.setOtherParams(params, { cover });
1141
+ const explicitlySetsOpenData = Object.prototype.hasOwnProperty.call(params, 'openData');
1142
+ await super.setOtherParams(params, {
1143
+ cover
1144
+ });
1177
1145
  const nextScope = this.getAvailabilityScopeDescriptor(this.otherParams || {});
1178
1146
  if (explicitlySetsOpenData) {
1179
- this.openDataTarget = ((_a = this.otherParams) == null ? void 0 : _a.openData) && nextScope.businessCode && nextScope.channel ? `${nextScope.businessCode}+${nextScope.channel}` : null;
1147
+ this.openDataTarget = this.otherParams?.openData && nextScope.businessCode && nextScope.channel ? `${nextScope.businessCode}+${nextScope.channel}` : null;
1180
1148
  }
1181
1149
  const shouldResetAvailabilityState = previousScope.cacheId !== nextScope.cacheId || previousScope.businessCode !== nextScope.businessCode || previousScope.channel !== nextScope.channel || previousScope.platform !== nextScope.platform || previousScope.businessTimezone !== nextScope.businessTimezone;
1182
1150
  if (shouldResetAvailabilityState) {
1183
- await this.resetAvailabilityProjectionState("set_other_params_reset");
1151
+ await this.resetAvailabilityProjectionState('set_other_params_reset');
1184
1152
  }
1185
1153
  }
1186
1154
  async destroy() {
1187
1155
  this.availabilityScheduleCatalog = null;
1188
1156
  this.availabilityRuntimeOffsetMinutes = null;
1189
- await this.resetAvailabilityProjectionState("destroy");
1157
+ await this.resetAvailabilityProjectionState('destroy');
1190
1158
  await super.destroy();
1191
1159
  }
1192
1160
  createAvailabilityContextId() {
@@ -1198,35 +1166,45 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1198
1166
  }
1199
1167
  getAvailabilityRuntimeOffsetMinutes() {
1200
1168
  if (this.availabilityRuntimeOffsetMinutes === null) {
1201
- this.availabilityRuntimeOffsetMinutes = (0, import_localClock.captureRuntimeOffsetMinutes)();
1169
+ this.availabilityRuntimeOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)();
1202
1170
  }
1203
1171
  return this.availabilityRuntimeOffsetMinutes;
1204
1172
  }
1205
- getAvailabilityRuntimeDateTime(value = /* @__PURE__ */ new Date()) {
1206
- return (0, import_localClock.formatLocalDateTime)((0, import_localClock.localDateToScalar)(value), this.getAvailabilityRuntimeOffsetMinutes());
1173
+ getAvailabilityRuntimeDateTime(value = new Date()) {
1174
+ return (0, _localClock.formatLocalDateTime)((0, _localClock.localDateToScalar)(value), this.getAvailabilityRuntimeOffsetMinutes());
1207
1175
  }
1208
1176
  cloneAvailabilityPrepareParams(params) {
1209
- var _a, _b;
1210
- return (0, import_lodash_es.cloneDeep)({
1177
+ return (0, _lodashEs.cloneDeep)({
1211
1178
  ...params,
1212
- productIds: params.productIds ? [...params.productIds] : void 0,
1213
- resourceIds: params.resourceIds ? [...params.resourceIds] : void 0,
1214
- rawProducts: params.rawProducts ? (0, import_lodash_es.cloneDeep)(params.rawProducts) : void 0,
1215
- rawResources: params.rawResources ? (0, import_lodash_es.cloneDeep)(params.rawResources) : void 0,
1216
- rawOccupancies: params.rawOccupancies ? (0, import_lodash_es.cloneDeep)(params.rawOccupancies) : void 0,
1217
- editingProductLineUids: params.editingProductLineUids ? [...params.editingProductLineUids] : void 0,
1218
- dateRange: params.dateRange ? { ...params.dateRange } : void 0,
1219
- businessHours: params.businessHours ? { ...params.businessHours } : void 0,
1179
+ productIds: params.productIds ? [...params.productIds] : undefined,
1180
+ resourceIds: params.resourceIds ? [...params.resourceIds] : undefined,
1181
+ rawProducts: params.rawProducts ? (0, _lodashEs.cloneDeep)(params.rawProducts) : undefined,
1182
+ rawResources: params.rawResources ? (0, _lodashEs.cloneDeep)(params.rawResources) : undefined,
1183
+ rawOccupancies: params.rawOccupancies ? (0, _lodashEs.cloneDeep)(params.rawOccupancies) : undefined,
1184
+ editingProductLineUids: params.editingProductLineUids ? [...params.editingProductLineUids] : undefined,
1185
+ dateRange: params.dateRange ? {
1186
+ ...params.dateRange
1187
+ } : undefined,
1188
+ businessHours: params.businessHours ? {
1189
+ ...params.businessHours
1190
+ } : undefined,
1220
1191
  _availabilityOperatingHours: params._availabilityOperatingHours ? {
1221
1192
  source: params._availabilityOperatingHours.source,
1222
1193
  scheduleIds: [...params._availabilityOperatingHours.scheduleIds]
1223
- } : void 0,
1224
- catalogScope: ((_a = params.catalogScope) == null ? void 0 : _a.type) === "schedule" ? { ...params.catalogScope } : ((_b = params.catalogScope) == null ? void 0 : _b.type) === "productList" ? { type: "productList", params: { ...params.catalogScope.params } } : void 0
1194
+ } : undefined,
1195
+ catalogScope: params.catalogScope?.type === 'schedule' ? {
1196
+ ...params.catalogScope
1197
+ } : params.catalogScope?.type === 'productList' ? {
1198
+ type: 'productList',
1199
+ params: {
1200
+ ...params.catalogScope.params
1201
+ }
1202
+ } : undefined
1225
1203
  });
1226
1204
  }
1227
1205
  getAvailabilityDurationCandidateAnchorAt(projection) {
1228
- const value = projection == null ? void 0 : projection.meta.durationCandidateAnchorAt;
1229
- return typeof value === "string" && value.trim() ? value : void 0;
1206
+ const value = projection?.meta.durationCandidateAnchorAt;
1207
+ return typeof value === 'string' && value.trim() ? value : undefined;
1230
1208
  }
1231
1209
  createAvailabilityContextRef(context) {
1232
1210
  return {
@@ -1234,19 +1212,14 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1234
1212
  };
1235
1213
  }
1236
1214
  async emitAvailabilityDiagnostic(payload) {
1237
- var _a, _b, _c;
1238
- await ((_c = (_b = (_a = this.core) == null ? void 0 : _a.effects) == null ? void 0 : _b.emit) == null ? void 0 : _c.call(
1239
- _b,
1240
- `${this.name}:${import_types.UnifiedBookingSalesHooks.onAvailabilityProjectionDiagnostic}`,
1241
- {
1242
- ...payload,
1243
- registrySize: this.availabilityContextRegistry.size,
1244
- projectionPoolSize: this.availabilityProjectionPool.size
1245
- }
1246
- ));
1215
+ await this.core?.effects?.emit?.(`${this.name}:${_types.UnifiedBookingSalesHooks.onAvailabilityProjectionDiagnostic}`, {
1216
+ ...payload,
1217
+ registrySize: this.availabilityContextRegistry.size,
1218
+ projectionPoolSize: this.availabilityProjectionPool.size
1219
+ });
1247
1220
  }
1248
1221
  touchAvailabilityContext(context) {
1249
- context.lastAccessedAt = (/* @__PURE__ */ new Date()).toISOString();
1222
+ context.lastAccessedAt = new Date().toISOString();
1250
1223
  this.availabilityContextRegistry.delete(context.contextId);
1251
1224
  this.availabilityContextRegistry.set(context.contextId, context);
1252
1225
  }
@@ -1256,14 +1229,12 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1256
1229
  return entry;
1257
1230
  }
1258
1231
  removeAvailabilityProjection(projectionKey) {
1259
- if (!projectionKey)
1260
- return;
1232
+ if (!projectionKey) return;
1261
1233
  this.availabilityProjectionPool.delete(projectionKey);
1262
1234
  }
1263
1235
  removeAvailabilityContext(contextId) {
1264
1236
  const context = this.availabilityContextRegistry.get(contextId);
1265
- if (!context)
1266
- return;
1237
+ if (!context) return;
1267
1238
  this.removeAvailabilityProjection(context.activeProjectionKey);
1268
1239
  this.availabilityProjectionRefreshInFlight.delete(contextId);
1269
1240
  this.availabilityCommitLocks.delete(contextId);
@@ -1272,12 +1243,11 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1272
1243
  evictAvailabilityProjectionPool() {
1273
1244
  while (this.availabilityProjectionPool.size > MAX_AVAILABILITY_PROJECTION_POOL) {
1274
1245
  const oldestEntry = this.availabilityProjectionPool.entries().next().value;
1275
- if (!oldestEntry)
1276
- break;
1246
+ if (!oldestEntry) break;
1277
1247
  const [projectionKey, projectionEntry] = oldestEntry;
1278
1248
  this.availabilityProjectionPool.delete(projectionKey);
1279
1249
  const context = this.availabilityContextRegistry.get(projectionEntry.contextId);
1280
- if ((context == null ? void 0 : context.activeProjectionKey) === projectionKey) {
1250
+ if (context?.activeProjectionKey === projectionKey) {
1281
1251
  context.activeProjectionKey = null;
1282
1252
  context.refreshNonce += 1;
1283
1253
  }
@@ -1286,8 +1256,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1286
1256
  evictAvailabilityContextRegistry() {
1287
1257
  while (this.availabilityContextRegistry.size > MAX_AVAILABILITY_CONTEXT_REGISTRY) {
1288
1258
  const oldestContext = this.availabilityContextRegistry.entries().next().value;
1289
- if (!oldestContext)
1290
- break;
1259
+ if (!oldestContext) break;
1291
1260
  this.removeAvailabilityContext(oldestContext[0]);
1292
1261
  }
1293
1262
  }
@@ -1297,7 +1266,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1297
1266
  this.availabilityProjectionPool.clear();
1298
1267
  this.availabilityPrepareInFlight.clear();
1299
1268
  this.availabilityProjectionRefreshInFlight.clear();
1300
- this.availabilityContextRegistry.forEach((context) => {
1269
+ this.availabilityContextRegistry.forEach(context => {
1301
1270
  context.activeVersion += 1;
1302
1271
  context.activeProjectionKey = null;
1303
1272
  context.lastKnownOrderRevision = nextOrderRevision;
@@ -1322,40 +1291,39 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1322
1291
  });
1323
1292
  }
1324
1293
  isSessionStoragePersistEnabled() {
1325
- var _a;
1326
- return Boolean(
1327
- this.cacheId && ((_a = this.otherParams) == null ? void 0 : _a.enableSessionStoragePersist) === true
1328
- );
1294
+ return Boolean(this.cacheId && this.otherParams?.enableSessionStoragePersist === true);
1329
1295
  }
1330
1296
  shouldUseSessionStorageForSubModule(moduleName) {
1331
- return this.isSessionStoragePersistEnabled() && moduleName === "order";
1297
+ return this.isSessionStoragePersistEnabled() && moduleName === 'order';
1332
1298
  }
1299
+
1333
1300
  /**
1334
1301
  * 读取与当前 cacheId 同分桶的 Solution 会话状态。
1335
1302
  * 该状态独立于 otherParams,适合页面皮肤保存短生命周期 UI 状态。
1336
1303
  */
1337
1304
  getSessionStateValue(key) {
1338
- if (!key || !this.isSessionStoragePersistEnabled())
1339
- return void 0;
1305
+ if (!key || !this.isSessionStoragePersistEnabled()) return undefined;
1340
1306
  const cacheData = this.readSessionCacheData();
1341
- const solutionCache = cacheData == null ? void 0 : cacheData[this.name];
1307
+ const solutionCache = cacheData?.[this.name];
1342
1308
  if (!isRecord(solutionCache) || !isRecord(solutionCache.sessionState)) {
1343
- return void 0;
1309
+ return undefined;
1344
1310
  }
1345
1311
  return solutionCache.sessionState[key];
1346
1312
  }
1313
+
1347
1314
  /**
1348
1315
  * 写入与当前 cacheId 同分桶的 Solution 会话状态。
1349
1316
  * value 为 undefined 时删除该 key;存储失败不阻断业务流程。
1350
1317
  */
1351
1318
  setSessionStateValue(key, value) {
1352
- if (!key || !this.isSessionStoragePersistEnabled())
1353
- return;
1319
+ if (!key || !this.isSessionStoragePersistEnabled()) return;
1354
1320
  const cacheData = this.readSessionCacheData();
1355
- const solutionCache = cacheData == null ? void 0 : cacheData[this.name];
1321
+ const solutionCache = cacheData?.[this.name];
1356
1322
  const currentSessionState = isRecord(solutionCache) && isRecord(solutionCache.sessionState) ? solutionCache.sessionState : {};
1357
- const nextSessionState = { ...currentSessionState };
1358
- if (value === void 0) {
1323
+ const nextSessionState = {
1324
+ ...currentSessionState
1325
+ };
1326
+ if (value === undefined) {
1359
1327
  delete nextSessionState[key];
1360
1328
  } else {
1361
1329
  nextSessionState[key] = value;
@@ -1363,52 +1331,54 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1363
1331
  this.checkSaveCache({
1364
1332
  cacheId: this.cacheId,
1365
1333
  fatherModule: this.name,
1366
- store: { sessionState: nextSessionState },
1367
- cacheKey: ["sessionState"]
1334
+ store: {
1335
+ sessionState: nextSessionState
1336
+ },
1337
+ cacheKey: ['sessionState']
1368
1338
  });
1369
1339
  }
1340
+
1370
1341
  /**
1371
1342
  * 清除当前 cacheId 的可恢复订单快照,同时保留 Solution UI sessionState。
1372
1343
  * 用于支付跳转等终态场景,避免浏览器返回时恢复已提交订单。
1373
1344
  */
1374
1345
  clearSessionStorageOrderSnapshot() {
1375
- var _a, _b;
1376
- (_b = (_a = this.store.order) == null ? void 0 : _a.clearSessionStoragePersistedTempOrder) == null ? void 0 : _b.call(_a);
1346
+ this.store.order?.clearSessionStoragePersistedTempOrder?.();
1377
1347
  }
1348
+
1378
1349
  /**
1379
1350
  * Kiosk 不能把已收款订单留在本地等待重试:默认直接等待云端 checkout。
1380
1351
  * 兼容仍需要 WebPOS 待同步模式的入口可显式传 checkoutSyncTaskEnabled: true。
1381
1352
  */
1382
1353
  shouldUseCheckoutSyncTask() {
1383
- var _a;
1384
- const configured = (_a = this.otherParams) == null ? void 0 : _a.checkoutSyncTaskEnabled;
1385
- return typeof configured === "boolean" ? configured : false;
1354
+ const configured = this.otherParams?.checkoutSyncTaskEnabled;
1355
+ return typeof configured === 'boolean' ? configured : false;
1386
1356
  }
1357
+
1387
1358
  /** UnifiedBookingSales 的真实结账默认请求收据数据,供云端确认后再本地打印。 */
1388
1359
  getDefaultCheckoutSmallTicketDataFlag() {
1389
1360
  return 1;
1390
1361
  }
1391
1362
  getRegisteredModuleNames() {
1392
- return [...super.getRegisteredModuleNames(), "openData"];
1363
+ return [...super.getRegisteredModuleNames(), 'openData'];
1393
1364
  }
1394
1365
  createSubModule(moduleName) {
1395
- if (moduleName === "openData") {
1396
- return new import_modules.OpenDataModule(`${this.name}_openData`);
1366
+ if (moduleName === 'openData') {
1367
+ return new _modules.OpenDataModule(`${this.name}_openData`);
1397
1368
  }
1398
1369
  return super.createSubModule(moduleName);
1399
1370
  }
1400
1371
  async addNewOrder() {
1401
- var _a, _b, _c, _d;
1402
- const sessionRecord = this.isSessionStoragePersistEnabled() ? (_b = (_a = this.store.order) == null ? void 0 : _a.consumeSessionStorageRestore) == null ? void 0 : _b.call(_a) : null;
1372
+ const sessionRecord = this.isSessionStoragePersistEnabled() ? this.store.order?.consumeSessionStorageRestore?.() : null;
1403
1373
  if (sessionRecord) {
1404
1374
  await this.loadSalesDetail({
1405
1375
  preloadedSalesDetail: sessionRecord,
1406
- hydrateSource: "sessionStorage"
1376
+ hydrateSource: 'sessionStorage'
1407
1377
  });
1408
1378
  }
1409
1379
  const tempOrder = await super.addNewOrder();
1410
1380
  if (sessionRecord) {
1411
- (_c = this.store.order) == null ? void 0 : _c.persistTempOrder();
1381
+ this.store.order?.persistTempOrder();
1412
1382
  }
1413
1383
  if (this.isAuthenticatedCustomerUserPlatform()) {
1414
1384
  try {
@@ -1417,102 +1387,82 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1417
1387
  await this.refreshLegacySessionCustomerDiscounts(tempOrder);
1418
1388
  }
1419
1389
  } catch (error) {
1420
- console.warn(
1421
- "[UnifiedBookingSales] Failed to sync authenticated order customer after addNewOrder",
1422
- error
1423
- );
1390
+ console.warn('[UnifiedBookingSales] Failed to sync authenticated order customer after addNewOrder', error);
1424
1391
  }
1425
1392
  } else if (sessionRecord) {
1426
1393
  try {
1427
1394
  await this.refreshLegacySessionCustomerDiscounts(tempOrder);
1428
1395
  } catch (error) {
1429
- console.warn(
1430
- "[UnifiedBookingSales] Failed to refresh cached customer discounts after addNewOrder",
1431
- error
1432
- );
1396
+ console.warn('[UnifiedBookingSales] Failed to refresh cached customer discounts after addNewOrder', error);
1433
1397
  }
1434
1398
  }
1435
- return ((_d = this.store.order) == null ? void 0 : _d.getTempOrder()) || tempOrder;
1399
+ return this.store.order?.getTempOrder() || tempOrder;
1436
1400
  }
1437
1401
  async syncAuthenticatedOrderCustomer() {
1438
- var _a, _b, _c, _d, _e, _f;
1439
- if (!this.isAuthenticatedCustomerUserPlatform())
1440
- return false;
1441
- const authenticatedCustomer = (_d = (_c = (_b = (_a = this.core) == null ? void 0 : _a.getPlugin) == null ? void 0 : _b.call(_a, "user")) == null ? void 0 : _c.get) == null ? void 0 : _d.call(_c);
1442
- const authenticatedCustomerId = toCustomerId(authenticatedCustomer == null ? void 0 : authenticatedCustomer.id);
1443
- if (!authenticatedCustomerId)
1444
- return false;
1402
+ if (!this.isAuthenticatedCustomerUserPlatform()) return false;
1403
+ const authenticatedCustomer = this.core?.getPlugin?.('user')?.get?.();
1404
+ const authenticatedCustomerId = toCustomerId(authenticatedCustomer?.id);
1405
+ if (!authenticatedCustomerId) return false;
1445
1406
  const tempOrder = this.getTempOrder();
1446
1407
  const cachedCustomerId = resolveTempOrderCustomerId(tempOrder);
1447
1408
  if (cachedCustomerId !== null && cachedCustomerId !== authenticatedCustomerId) {
1448
1409
  await this.resetCachedCustomerDiscountState();
1449
1410
  }
1450
- (_f = (_e = this.store.customer) == null ? void 0 : _e.setSelectedCustomer) == null ? void 0 : _f.call(_e, authenticatedCustomer);
1411
+ this.store.customer?.setSelectedCustomer?.(authenticatedCustomer);
1451
1412
  this.setOrderCustomer(authenticatedCustomer);
1452
- await Promise.all([
1453
- this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId),
1454
- this.waitForOrderCustomerPromotionRefresh()
1455
- ]);
1413
+ await Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh()]);
1456
1414
  return true;
1457
1415
  }
1458
1416
  isAuthenticatedCustomerUserPlatform() {
1459
- var _a;
1460
- const platform = String(((_a = this.otherParams) == null ? void 0 : _a.platform) || "").toLowerCase();
1461
- return platform === "pc" || platform === "h5";
1417
+ const platform = String(this.otherParams?.platform || '').toLowerCase();
1418
+ return platform === 'pc' || platform === 'h5';
1462
1419
  }
1463
1420
  resolveDiscountOrderIdentity(tempOrder) {
1464
- var _a, _b, _c;
1465
- return (tempOrder == null ? void 0 : tempOrder.order_id) || ((_c = (_b = (_a = this.store.order) == null ? void 0 : _a.getOrderIdentity) == null ? void 0 : _b.call(_a)) == null ? void 0 : _c.orderId) || null;
1421
+ return tempOrder?.order_id || this.store.order?.getOrderIdentity?.()?.orderId || null;
1466
1422
  }
1467
1423
  resolveDiscountAction(orderId) {
1468
- if (!orderId || isLocalOrderId(orderId))
1469
- return "create";
1470
- return "edit";
1424
+ if (!orderId || isLocalOrderId(orderId)) return 'create';
1425
+ return 'edit';
1471
1426
  }
1472
1427
  async resetCachedCustomerDiscountState() {
1473
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
1474
- (_b = (_a = this.store.order) == null ? void 0 : _a.clearOrderCustomer) == null ? void 0 : _b.call(_a);
1475
- (_d = (_c = this.store.customer) == null ? void 0 : _c.setSelectedCustomer) == null ? void 0 : _d.call(_c, null);
1428
+ this.store.order?.clearOrderCustomer?.();
1429
+ this.store.customer?.setSelectedCustomer?.(null);
1476
1430
  this.discountConfigCacheKey = null;
1477
1431
  this.hasManualDiscountSelection = false;
1478
- const orderStore = ((_e = this.store.order) == null ? void 0 : _e.store) || {};
1432
+ const orderStore = this.store.order?.store || {};
1479
1433
  const discountModule = orderStore.discount;
1480
- const filteredOriginalDiscounts = filterCustomerBoundDiscounts(
1481
- ((_f = discountModule == null ? void 0 : discountModule.getOriginalDiscountList) == null ? void 0 : _f.call(discountModule)) || []
1482
- );
1483
- const filteredCurrentDiscounts = filterCustomerBoundDiscounts(
1484
- ((_g = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _g.call(discountModule)) || []
1485
- );
1486
- await ((_h = discountModule == null ? void 0 : discountModule.setOriginalDiscountList) == null ? void 0 : _h.call(discountModule, filteredOriginalDiscounts));
1487
- await ((_i = discountModule == null ? void 0 : discountModule.setDiscountList) == null ? void 0 : _i.call(discountModule, filteredCurrentDiscounts));
1488
- (_k = (_j = this.store.order) == null ? void 0 : _j.applyDiscount) == null ? void 0 : _k.call(_j);
1489
- await ((_m = (_l = this.store.order) == null ? void 0 : _l.recalculateSummary) == null ? void 0 : _m.call(_l, { createIfMissing: true }));
1490
- (_o = (_n = this.store.order) == null ? void 0 : _n.persistTempOrder) == null ? void 0 : _o.call(_n);
1434
+ const filteredOriginalDiscounts = filterCustomerBoundDiscounts(discountModule?.getOriginalDiscountList?.() || []);
1435
+ const filteredCurrentDiscounts = filterCustomerBoundDiscounts(discountModule?.getDiscountList?.() || []);
1436
+ await discountModule?.setOriginalDiscountList?.(filteredOriginalDiscounts);
1437
+ await discountModule?.setDiscountList?.(filteredCurrentDiscounts);
1438
+ this.store.order?.applyDiscount?.();
1439
+ await this.store.order?.recalculateSummary?.({
1440
+ createIfMissing: true
1441
+ });
1442
+ this.store.order?.persistTempOrder?.();
1491
1443
  }
1492
1444
  async refreshLegacySessionCustomerDiscounts(tempOrder) {
1493
1445
  const customerId = resolveTempOrderCustomerId(tempOrder);
1494
- if (!customerId)
1495
- return void 0;
1446
+ if (!customerId) return undefined;
1496
1447
  const loadDiscountConfig = super.loadDiscountConfig.bind(this);
1497
1448
  return await loadDiscountConfig({
1498
1449
  customerId,
1499
- action: this.resolveDiscountAction(
1500
- this.resolveDiscountOrderIdentity(tempOrder)
1501
- )
1450
+ action: this.resolveDiscountAction(this.resolveDiscountOrderIdentity(tempOrder))
1502
1451
  });
1503
1452
  }
1453
+
1504
1454
  /**
1505
1455
  * Loads OpenData without borrowing BookingTicket. Cache ownership is tied to the exact
1506
1456
  * business/channel target so a reused solution instance cannot leak another entry's menus.
1507
1457
  */
1508
1458
  async loadOpenData(params) {
1509
1459
  if (!this.store.openData) {
1510
- throw new Error("[UnifiedBookingSales] openData 模块未初始化");
1460
+ throw new Error('[UnifiedBookingSales] openData 模块未初始化');
1511
1461
  }
1512
- const businessCode = String(params.businessCode || "").trim();
1513
- const channel = String(params.channel || "").trim();
1462
+ const businessCode = String(params.businessCode || '').trim();
1463
+ const channel = String(params.channel || '').trim();
1514
1464
  if (!businessCode || !channel) {
1515
- throw new Error("[UnifiedBookingSales] OpenData 需要 businessCode 与 channel");
1465
+ throw new Error('[UnifiedBookingSales] OpenData 需要 businessCode 与 channel');
1516
1466
  }
1517
1467
  const target = `${businessCode}+${channel}`;
1518
1468
  const cachedData = this.store.openData.getOpenData();
@@ -1529,7 +1479,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1529
1479
  }
1530
1480
  this.loadOpenDataInFlightTarget = target;
1531
1481
  this.loadOpenDataInFlight = this.store.openData.fetchOpenData({
1532
- scope: "board",
1482
+ scope: 'board',
1533
1483
  target,
1534
1484
  section_code: [...OPEN_DATA_SECTION_CODES]
1535
1485
  });
@@ -1546,28 +1496,28 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1546
1496
  }
1547
1497
  }
1548
1498
  async getOpenData() {
1549
- var _a, _b, _c;
1550
- const businessCode = String(((_a = this.otherParams) == null ? void 0 : _a.businessCode) || "").trim();
1551
- const channel = String(((_b = this.otherParams) == null ? void 0 : _b.channel) || "").trim();
1552
- if (!businessCode || !channel)
1553
- return null;
1499
+ const businessCode = String(this.otherParams?.businessCode || '').trim();
1500
+ const channel = String(this.otherParams?.channel || '').trim();
1501
+ if (!businessCode || !channel) return null;
1554
1502
  const target = `${businessCode}+${channel}`;
1555
- const cachedData = ((_c = this.store.openData) == null ? void 0 : _c.getOpenData()) || null;
1556
- if (cachedData && this.openDataTarget === target)
1557
- return cachedData;
1558
- return this.loadOpenData({ businessCode, channel });
1503
+ const cachedData = this.store.openData?.getOpenData() || null;
1504
+ if (cachedData && this.openDataTarget === target) return cachedData;
1505
+ return this.loadOpenData({
1506
+ businessCode,
1507
+ channel
1508
+ });
1559
1509
  }
1510
+
1560
1511
  /**
1561
1512
  * Loads the product catalog used by both UI and Planner. Schedule data is requested with each
1562
1513
  * product because session products carry their fixed intervals there.
1563
1514
  */
1564
1515
  async loadProducts(params = {}, options) {
1565
- if (!this.store.products)
1566
- throw new Error("[UnifiedBookingSales] products 模块未初始化");
1567
- const schedule_date = params.schedule_date || (0, import_dayjs.default)().format("YYYY-MM-DD");
1568
- const schedule_datetime = params.schedule_datetime || `${schedule_date} ${(0, import_dayjs.default)().format("HH:mm:ss")}`;
1516
+ if (!this.store.products) throw new Error('[UnifiedBookingSales] products 模块未初始化');
1517
+ const schedule_date = params.schedule_date || (0, _dayjs.default)().format('YYYY-MM-DD');
1518
+ const schedule_datetime = params.schedule_datetime || `${schedule_date} ${(0, _dayjs.default)().format('HH:mm:ss')}`;
1569
1519
  const result = await this.store.products.loadProducts({
1570
- with_count: ["bundleGroup", "optionGroup"],
1520
+ with_count: ['bundleGroup', 'optionGroup'],
1571
1521
  with_schedule: 1,
1572
1522
  ...params,
1573
1523
  schedule_date,
@@ -1578,19 +1528,19 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1578
1528
  await this.core.effects.emit(`${this.name}:onProductsLoaded`, result);
1579
1529
  return result;
1580
1530
  }
1531
+
1581
1532
  /** Date-first entry point. It delegates protocol details and cache ownership to ScheduleModule. */
1582
1533
  async loadScheduleAvailableDate(params) {
1583
- if (!this.store.schedule)
1584
- throw new Error("[UnifiedBookingSales] schedule 模块未初始化");
1534
+ if (!this.store.schedule) throw new Error('[UnifiedBookingSales] schedule 模块未初始化');
1585
1535
  return this.store.schedule.loadScheduleAvailableDate(params);
1586
1536
  }
1537
+
1587
1538
  /**
1588
1539
  * Implements the date-first product pool: the chosen date's product ids plus globally sellable
1589
1540
  * other_product_ids. If a batch product query is unexpectedly empty, retry one id at a time so
1590
1541
  * a partial backend incompatibility does not hide the entire date's catalog.
1591
1542
  */
1592
1543
  async loadProductsByScheduleDate(params) {
1593
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1594
1544
  const {
1595
1545
  date,
1596
1546
  custom_page_id,
@@ -1598,11 +1548,10 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1598
1548
  product_ids,
1599
1549
  ...productLoadParams
1600
1550
  } = params;
1601
- if (!this.store.schedule)
1602
- throw new Error("[UnifiedBookingSales] schedule 模块未初始化");
1603
- const cachedDates = ((_b = (_a = this.store.schedule).getAvailabilityScheduleDateList) == null ? void 0 : _b.call(_a)) || [];
1604
- const hasCachedDate = cachedDates.some((item) => item.date === date);
1605
- const hasOtherProducts = (((_d = (_c = this.store.schedule).getOtherProductsIds) == null ? void 0 : _d.call(_c)) || []).length > 0;
1551
+ if (!this.store.schedule) throw new Error('[UnifiedBookingSales] schedule 模块未初始化');
1552
+ const cachedDates = this.store.schedule.getAvailabilityScheduleDateList?.() || [];
1553
+ const hasCachedDate = cachedDates.some(item => item.date === date);
1554
+ const hasOtherProducts = (this.store.schedule.getOtherProductsIds?.() || []).length > 0;
1606
1555
  if (!hasCachedDate && !hasOtherProducts) {
1607
1556
  await this.loadScheduleAvailableDate({
1608
1557
  startDate: date,
@@ -1611,12 +1560,9 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1611
1560
  channel
1612
1561
  });
1613
1562
  }
1614
- const scheduleDate = (_g = (_f = (_e = this.store.schedule).getAvailabilityScheduleDateList) == null ? void 0 : _f.call(_e)) == null ? void 0 : _g.find((item) => item.date === date);
1615
- const productIdFilter = (product_ids == null ? void 0 : product_ids.length) ? new Set(product_ids.map((id) => String(id))) : null;
1616
- const availableProductIds = [
1617
- ...(scheduleDate == null ? void 0 : scheduleDate.product_ids) || [],
1618
- ...((_i = (_h = this.store.schedule).getOtherProductsIds) == null ? void 0 : _i.call(_h)) || []
1619
- ].filter((id, index, self) => self.indexOf(id) === index).filter((id) => !productIdFilter || productIdFilter.has(String(id)));
1563
+ const scheduleDate = this.store.schedule.getAvailabilityScheduleDateList?.()?.find(item => item.date === date);
1564
+ const productIdFilter = product_ids?.length ? new Set(product_ids.map(id => String(id))) : null;
1565
+ const availableProductIds = [...(scheduleDate?.product_ids || []), ...(this.store.schedule.getOtherProductsIds?.() || [])].filter((id, index, self) => self.indexOf(id) === index).filter(id => !productIdFilter || productIdFilter.has(String(id)));
1620
1566
  if (!availableProductIds.length) {
1621
1567
  this.unifiedProductCatalog = [];
1622
1568
  await this.core.effects.emit(`${this.name}:onProductsLoaded`, []);
@@ -1627,8 +1573,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1627
1573
  product_ids: availableProductIds,
1628
1574
  schedule_date: date
1629
1575
  });
1630
- if (products.length || availableProductIds.length <= 1)
1631
- return products;
1576
+ if (products.length || availableProductIds.length <= 1) return products;
1632
1577
  const fallbackProducts = [];
1633
1578
  for (const productId of availableProductIds) {
1634
1579
  const result = await this.loadProducts({
@@ -1636,9 +1581,9 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1636
1581
  product_ids: [productId],
1637
1582
  schedule_date: date
1638
1583
  });
1639
- result.forEach((product) => {
1640
- const id = (product == null ? void 0 : product.id) ?? (product == null ? void 0 : product.product_id);
1641
- if (!fallbackProducts.some((item) => String((item == null ? void 0 : item.id) ?? (item == null ? void 0 : item.product_id)) === String(id))) {
1584
+ result.forEach(product => {
1585
+ const id = product?.id ?? product?.product_id;
1586
+ if (!fallbackProducts.some(item => String(item?.id ?? item?.product_id) === String(id))) {
1642
1587
  fallbackProducts.push(product);
1643
1588
  }
1644
1589
  });
@@ -1647,10 +1592,14 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1647
1592
  await this.core.effects.emit(`${this.name}:onProductsLoaded`, fallbackProducts);
1648
1593
  return fallbackProducts;
1649
1594
  }
1595
+
1650
1596
  /** Returns a copy so UI consumers cannot accidentally mutate the solution's product cache. */
1651
1597
  getProductCatalog() {
1652
- return { products: [...this.unifiedProductCatalog] };
1598
+ return {
1599
+ products: [...this.unifiedProductCatalog]
1600
+ };
1653
1601
  }
1602
+
1654
1603
  /**
1655
1604
  * Read-only compatibility view for salesSdk skins. It reconnects a booking to its product but
1656
1605
  * must not be used to mutate tempOrder; all writes go through BaseSales / planner APIs.
@@ -1682,6 +1631,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1682
1631
  // }),
1683
1632
  // };
1684
1633
  // }
1634
+
1685
1635
  /**
1686
1636
  * Loads the current customer's product coupons and discount cards after planner lines exist,
1687
1637
  * then optionally lets the existing Rules engine select the best valid combination. This is a
@@ -1689,7 +1639,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1689
1639
  */
1690
1640
  async applyPlannerDiscounts(params = {}) {
1691
1641
  const tempOrder = this.getTempOrder();
1692
- const requestedCustomerId = params.customerId ?? (tempOrder == null ? void 0 : tempOrder.customer_id);
1642
+ const requestedCustomerId = params.customerId ?? tempOrder?.customer_id;
1693
1643
  const parsedCustomerId = Number(requestedCustomerId);
1694
1644
  const customerId = Number.isFinite(parsedCustomerId) && parsedCustomerId > 1 ? parsedCustomerId : null;
1695
1645
  const summaryBefore = await this.getSummary();
@@ -1697,31 +1647,39 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1697
1647
  return buildPlannerDiscountResult({
1698
1648
  customerId: null,
1699
1649
  discountList: this.getDiscountList(),
1700
- products: (tempOrder == null ? void 0 : tempOrder.products) || [],
1650
+ products: tempOrder?.products || [],
1701
1651
  summaryBefore,
1702
1652
  summaryAfter: summaryBefore,
1703
- status: "no_customer"
1653
+ status: 'no_customer'
1704
1654
  });
1705
1655
  }
1706
- await this.loadDiscountConfig({ customerId, action: "create" });
1656
+ await this.loadDiscountConfig({
1657
+ customerId,
1658
+ action: 'create'
1659
+ });
1707
1660
  const preferredDiscountId = params.preferredDiscountId;
1708
- const preferredDiscount = preferredDiscountId === void 0 || preferredDiscountId === null ? void 0 : this.getDiscountList().find((discount) => String(resolvePlannerDiscountId(discount) ?? "") === String(preferredDiscountId));
1661
+ const preferredDiscount = preferredDiscountId === undefined || preferredDiscountId === null ? undefined : this.getDiscountList().find(discount => String(resolvePlannerDiscountId(discount) ?? '') === String(preferredDiscountId));
1709
1662
  if (preferredDiscount) {
1663
+ // A requested card is an explicit UI choice, not a best-effort preference. Clear prior
1664
+ // automatic selections first; otherwise Rules may keep the old selected card and silently
1665
+ // apply it instead of the card the customer clicked.
1710
1666
  const preferredId = resolvePlannerDiscountId(preferredDiscount);
1711
- const selectedOtherDiscounts = this.getDiscountList().filter((discount) => discount.isSelected === true && String(resolvePlannerDiscountId(discount) ?? "") !== String(preferredId));
1667
+ const selectedOtherDiscounts = this.getDiscountList().filter(discount => discount.isSelected === true && String(resolvePlannerDiscountId(discount) ?? '') !== String(preferredId));
1712
1668
  for (const discount of selectedOtherDiscounts) {
1713
1669
  const discountId = Number(resolvePlannerDiscountId(discount));
1714
1670
  if (Number.isFinite(discountId)) {
1715
- await this.setDiscountSelected({ discountId, isSelected: false });
1671
+ await this.setDiscountSelected({
1672
+ discountId,
1673
+ isSelected: false
1674
+ });
1716
1675
  }
1717
1676
  }
1718
1677
  await this.setDiscountSelected({
1719
1678
  discountId: Number(preferredId),
1720
1679
  isSelected: true
1721
1680
  });
1722
- } else if (preferredDiscountId === void 0 || preferredDiscountId === null) {
1723
- if (params.applyBestDiscount !== false)
1724
- await this.bestDiscount();
1681
+ } else if (preferredDiscountId === undefined || preferredDiscountId === null) {
1682
+ if (params.applyBestDiscount !== false) await this.bestDiscount();
1725
1683
  } else if (params.applyBestDiscount !== false) {
1726
1684
  await this.bestDiscount();
1727
1685
  }
@@ -1729,206 +1687,204 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1729
1687
  return buildPlannerDiscountResult({
1730
1688
  customerId,
1731
1689
  discountList: this.getDiscountList(),
1732
- products: (nextTempOrder == null ? void 0 : nextTempOrder.products) || [],
1690
+ products: nextTempOrder?.products || [],
1733
1691
  summaryBefore,
1734
1692
  summaryAfter: await this.getSummary(),
1735
- status: params.applyBestDiscount === false && !preferredDiscount ? "loaded" : "applied",
1693
+ status: params.applyBestDiscount === false && !preferredDiscount ? 'loaded' : 'applied',
1736
1694
  preferredDiscountId,
1737
- preferredDiscountFound: preferredDiscountId === void 0 || preferredDiscountId === null ? void 0 : Boolean(preferredDiscount)
1695
+ preferredDiscountFound: preferredDiscountId === undefined || preferredDiscountId === null ? undefined : Boolean(preferredDiscount)
1738
1696
  });
1739
1697
  }
1740
1698
  buildUnifiedOrderProduct(sourceProduct, ownershipKey, product) {
1741
- const normalizedProductRaw = (product == null ? void 0 : product.raw) || {};
1699
+ const normalizedProductRaw = product?.raw || {};
1742
1700
  const orderProduct = this.transformBaseProductToOrderProduct({
1743
1701
  payload: {
1744
1702
  ...sourceProduct,
1745
- id: sourceProduct.id ?? (product == null ? void 0 : product.id),
1746
- product_id: sourceProduct.product_id ?? sourceProduct.id ?? (product == null ? void 0 : product.id),
1747
- quantity: sourceProduct.quantity ?? sourceProduct.num ?? (product == null ? void 0 : product.quantity) ?? 1,
1703
+ id: sourceProduct.id ?? product?.id,
1704
+ product_id: sourceProduct.product_id ?? sourceProduct.id ?? product?.id,
1705
+ quantity: sourceProduct.quantity ?? sourceProduct.num ?? product?.quantity ?? 1,
1748
1706
  price: sourceProduct.price ?? normalizedProductRaw.price,
1749
1707
  selling_price: sourceProduct.selling_price ?? sourceProduct.price ?? normalizedProductRaw.selling_price ?? normalizedProductRaw.price,
1750
1708
  metadata: {
1751
- ...sourceProduct.metadata || {},
1709
+ ...(sourceProduct.metadata || {}),
1752
1710
  [ownershipKey]: true
1753
1711
  }
1754
1712
  },
1755
1713
  sourceProduct
1756
1714
  });
1757
- if (orderProduct && typeof orderProduct === "object") {
1715
+ if (orderProduct && typeof orderProduct === 'object') {
1716
+ // BaseSales may rebuild metadata from its price source. Stamp ownership after that transform
1717
+ // so each UnifiedBookingSales entry point can replace only its own temporary lines.
1758
1718
  orderProduct.metadata = {
1759
- ...orderProduct.metadata || {},
1719
+ ...(orderProduct.metadata || {}),
1760
1720
  [ownershipKey]: true
1761
1721
  };
1762
1722
  }
1763
1723
  return orderProduct;
1764
1724
  }
1725
+
1765
1726
  /** Replacing a staged selection is idempotent and never removes unrelated cart lines. */
1766
1727
  async removeExistingStagedLines(ownershipKey) {
1767
- var _a;
1768
- const existingLines = (((_a = this.getTempOrder()) == null ? void 0 : _a.products) || []).filter((product) => {
1769
- var _a2;
1770
- return ((_a2 = product == null ? void 0 : product.metadata) == null ? void 0 : _a2[ownershipKey]) === true;
1771
- });
1728
+ const existingLines = (this.getTempOrder()?.products || []).filter(product => product?.metadata?.[ownershipKey] === true);
1772
1729
  if (existingLines.length > 0) {
1773
1730
  await this.removeProductsFromOrder(existingLines.map(buildAvailabilityLineIdentity));
1774
1731
  }
1775
1732
  }
1776
1733
  async stageProducts(params, ownershipKey) {
1777
- var _a;
1778
1734
  const productIds = params.productIds || [];
1779
- if (!productIds.length)
1780
- return this.getTempOrder();
1781
- if ((_a = params.rawProducts) == null ? void 0 : _a.length) {
1735
+ if (!productIds.length) return this.getTempOrder();
1736
+ if (params.rawProducts?.length) {
1782
1737
  this.unifiedProductCatalog = params.rawProducts;
1783
1738
  } else {
1784
- const existingIds = new Set((this.unifiedProductCatalog || []).map((product) => String(product.id ?? product.product_id)));
1785
- const missingIds = productIds.filter((id) => !existingIds.has(String(id)));
1739
+ const existingIds = new Set((this.unifiedProductCatalog || []).map(product => String(product.id ?? product.product_id)));
1740
+ const missingIds = productIds.filter(id => !existingIds.has(String(id)));
1786
1741
  if (missingIds.length || params.productLoadParams) {
1787
1742
  await this.loadProducts({
1788
- ...params.productLoadParams || {},
1743
+ ...(params.productLoadParams || {}),
1789
1744
  product_ids: productIds.map(Number).filter(Number.isFinite)
1790
1745
  });
1791
1746
  }
1792
1747
  }
1793
1748
  await this.removeExistingStagedLines(ownershipKey);
1794
- const productIdSet = new Set(productIds.map((id) => String(id)));
1795
- const selectedProducts = (this.unifiedProductCatalog || []).filter((product) => productIdSet.has(String(product.id ?? product.product_id)));
1749
+ const productIdSet = new Set(productIds.map(id => String(id)));
1750
+ const selectedProducts = (this.unifiedProductCatalog || []).filter(product => productIdSet.has(String(product.id ?? product.product_id)));
1796
1751
  for (const sourceProduct of selectedProducts) {
1797
1752
  const productInput = this.buildUnifiedOrderProduct(sourceProduct, ownershipKey);
1798
- if (productInput)
1799
- await this.addProductToOrder(productInput);
1753
+ if (productInput) await this.addProductToOrder(productInput);
1800
1754
  }
1801
1755
  return this.getTempOrder();
1802
1756
  }
1757
+
1803
1758
  /**
1804
1759
  * Adds ordinary retail products without asking ResourcePlanner for booking facts.
1805
1760
  * Its staged lines have separate ownership so planner and retail skins can coexist safely.
1806
1761
  */
1807
1762
  async stageRetailProducts(params) {
1808
- return this.stageProducts(params, "unified_booking_sales_retail");
1763
+ return this.stageProducts(params, 'unified_booking_sales_retail');
1809
1764
  }
1765
+
1810
1766
  /**
1811
1767
  * Adds one retail line without replacing the cart's existing retail selection.
1812
1768
  * This is intentionally separate from stageRetailProducts(), whose contract is
1813
1769
  * "replace the staged selection" for demo and wizard-like callers.
1814
1770
  */
1815
1771
  async addRetailProduct(params) {
1816
- var _a, _b;
1817
1772
  const quantity = Math.floor(Number(params.quantity ?? 1));
1818
1773
  if (!Number.isFinite(quantity) || quantity <= 0) {
1819
- throw new Error("[UnifiedBookingSales] retail 商品数量必须大于 0");
1774
+ throw new Error('[UnifiedBookingSales] retail 商品数量必须大于 0');
1820
1775
  }
1821
- const productId = params.productId ?? ((_a = params.product) == null ? void 0 : _a.id) ?? ((_b = params.product) == null ? void 0 : _b.product_id);
1776
+ const productId = params.productId ?? params.product?.id ?? params.product?.product_id;
1822
1777
  let sourceProduct = params.product;
1823
- if (!sourceProduct && productId !== void 0 && productId !== null) {
1824
- sourceProduct = this.unifiedProductCatalog.find(
1825
- (product) => String(product.id ?? product.product_id) === String(productId)
1826
- );
1778
+ if (!sourceProduct && productId !== undefined && productId !== null) {
1779
+ sourceProduct = this.unifiedProductCatalog.find(product => String(product.id ?? product.product_id) === String(productId));
1827
1780
  }
1828
- if (!sourceProduct && productId !== void 0 && productId !== null) {
1781
+ if (!sourceProduct && productId !== undefined && productId !== null) {
1829
1782
  const products = await this.loadProducts({
1830
- ...params.productLoadParams || {},
1783
+ ...(params.productLoadParams || {}),
1831
1784
  product_ids: [Number(productId)].filter(Number.isFinite)
1832
1785
  });
1833
- sourceProduct = products.find(
1834
- (product) => String(product.id ?? product.product_id) === String(productId)
1835
- );
1786
+ sourceProduct = products.find(product => String(product.id ?? product.product_id) === String(productId));
1836
1787
  }
1837
1788
  if (!sourceProduct) {
1838
- throw new Error(`[UnifiedBookingSales] 未找到零售商品 ${String(productId ?? "")}`.trim());
1789
+ throw new Error(`[UnifiedBookingSales] 未找到零售商品 ${String(productId ?? '')}`.trim());
1839
1790
  }
1840
- const orderProduct = this.buildUnifiedOrderProduct(
1841
- {
1842
- ...sourceProduct,
1843
- quantity
1844
- },
1845
- "unified_booking_sales_retail"
1846
- );
1791
+ const orderProduct = this.buildUnifiedOrderProduct({
1792
+ ...sourceProduct,
1793
+ quantity
1794
+ }, 'unified_booking_sales_retail');
1847
1795
  if (!orderProduct) {
1848
- throw new Error("[UnifiedBookingSales] 无法生成零售商品订单行");
1796
+ throw new Error('[UnifiedBookingSales] 无法生成零售商品订单行');
1849
1797
  }
1850
1798
  return this.addProductToOrder(orderProduct);
1851
1799
  }
1852
1800
  normalizeAvailabilityDateRange(params, timezone) {
1853
- var _a, _b;
1854
- const today = (0, import_localClock.formatLocalDate)((0, import_localClock.localDateToScalar)(/* @__PURE__ */ new Date()));
1855
- const startDate = ((_a = params.dateRange) == null ? void 0 : _a.startDate) || today;
1856
- const endDate = ((_b = params.dateRange) == null ? void 0 : _b.endDate) || (0, import_localClock.formatLocalDate)((0, import_localClock.addLocalCalendarDays)((0, import_localClock.localDateToScalarStart)((0, import_localClock.parseLocalDate)(startDate)), 31));
1801
+ const today = (0, _localClock.formatLocalDate)((0, _localClock.localDateToScalar)(new Date()));
1802
+ const startDate = params.dateRange?.startDate || today;
1803
+ const endDate = params.dateRange?.endDate || (0, _localClock.formatLocalDate)((0, _localClock.addLocalCalendarDays)((0, _localClock.localDateToScalarStart)((0, _localClock.parseLocalDate)(startDate)), 31));
1857
1804
  let startScalar;
1858
1805
  let endScalar;
1859
1806
  try {
1860
- startScalar = (0, import_localClock.localDateToScalarStart)((0, import_localClock.parseLocalDate)(startDate));
1861
- endScalar = (0, import_localClock.localDateToScalarStart)((0, import_localClock.parseLocalDate)(endDate));
1807
+ startScalar = (0, _localClock.localDateToScalarStart)((0, _localClock.parseLocalDate)(startDate));
1808
+ endScalar = (0, _localClock.localDateToScalarStart)((0, _localClock.parseLocalDate)(endDate));
1862
1809
  } catch (error) {
1863
- throw new import_ResourcePlanner.AvailabilityError("INVALID_DATE_RANGE", "日期范围必须是有效的 YYYY-MM-DD 且结束日期不早于开始日期", {
1864
- dateRange: { startDate, endDate },
1810
+ throw new _ResourcePlanner.AvailabilityError('INVALID_DATE_RANGE', '日期范围必须是有效的 YYYY-MM-DD 且结束日期不早于开始日期', {
1811
+ dateRange: {
1812
+ startDate,
1813
+ endDate
1814
+ },
1865
1815
  timezone,
1866
1816
  cause: error instanceof Error ? error.message : String(error)
1867
1817
  });
1868
1818
  }
1869
1819
  if (endScalar < startScalar) {
1870
- throw new import_ResourcePlanner.AvailabilityError("INVALID_DATE_RANGE", "日期范围必须是有效的 YYYY-MM-DD 且结束日期不早于开始日期", {
1871
- dateRange: { startDate, endDate },
1820
+ throw new _ResourcePlanner.AvailabilityError('INVALID_DATE_RANGE', '日期范围必须是有效的 YYYY-MM-DD 且结束日期不早于开始日期', {
1821
+ dateRange: {
1822
+ startDate,
1823
+ endDate
1824
+ },
1872
1825
  timezone
1873
1826
  });
1874
1827
  }
1875
- const inclusiveDays = Math.trunc((endScalar - startScalar) / (24 * 60 * 60 * 1e3)) + 1;
1828
+ const inclusiveDays = Math.trunc((endScalar - startScalar) / (24 * 60 * 60 * 1000)) + 1;
1876
1829
  if (inclusiveDays > MAX_AVAILABILITY_RANGE_DAYS) {
1877
- throw new import_ResourcePlanner.AvailabilityError("RANGE_TOO_LARGE", "日期范围最多包含 90 个自然日", {
1878
- dateRange: { startDate, endDate },
1830
+ throw new _ResourcePlanner.AvailabilityError('RANGE_TOO_LARGE', '日期范围最多包含 90 个自然日', {
1831
+ dateRange: {
1832
+ startDate,
1833
+ endDate
1834
+ },
1879
1835
  inclusiveDays
1880
1836
  });
1881
1837
  }
1882
- return { startDate, endDate };
1838
+ return {
1839
+ startDate,
1840
+ endDate
1841
+ };
1883
1842
  }
1884
1843
  assertAvailabilityPrepareParams(params) {
1885
- var _a, _b;
1886
- assertAvailabilityCatalogProductIds(params.productIds, "prepare.productIds");
1844
+ assertAvailabilityCatalogProductIds(params.productIds, 'prepare.productIds');
1887
1845
  const hasProductAnchor = Array.isArray(params.productIds) && params.productIds.length > 0;
1888
1846
  const hasResourceAnchor = Array.isArray(params.resourceIds) && params.resourceIds.length > 0;
1889
- const hasDateAnchor = Boolean(((_a = params.dateRange) == null ? void 0 : _a.startDate) || ((_b = params.dateRange) == null ? void 0 : _b.endDate));
1847
+ const hasDateAnchor = Boolean(params.dateRange?.startDate || params.dateRange?.endDate);
1890
1848
  if (!hasProductAnchor && !hasResourceAnchor && !hasDateAnchor) {
1891
- throw new import_ResourcePlanner.AvailabilityError("MISSING_ANCHOR", "prepare 至少需要 productIds、resourceIds 或 dateRange 之一", {
1849
+ throw new _ResourcePlanner.AvailabilityError('MISSING_ANCHOR', 'prepare 至少需要 productIds、resourceIds 或 dateRange 之一', {
1892
1850
  params
1893
1851
  });
1894
1852
  }
1895
1853
  if (!hasProductAnchor && !params.catalogScope) {
1896
- throw new import_ResourcePlanner.AvailabilityError("MISSING_CATALOG_SCOPE", "缺少 productIds 时必须提供 catalogScope", {
1854
+ throw new _ResourcePlanner.AvailabilityError('MISSING_CATALOG_SCOPE', '缺少 productIds 时必须提供 catalogScope', {
1897
1855
  params
1898
1856
  });
1899
1857
  }
1900
- if (params.slotStepMinutes !== void 0) {
1858
+ if (params.slotStepMinutes !== undefined) {
1901
1859
  const step = Number(params.slotStepMinutes);
1902
1860
  if (!Number.isInteger(step) || step <= 0) {
1903
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "slotStepMinutes 必须是正整数", {
1861
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', 'slotStepMinutes 必须是正整数', {
1904
1862
  slotStepMinutes: params.slotStepMinutes
1905
1863
  });
1906
1864
  }
1907
1865
  }
1908
1866
  }
1909
1867
  captureAvailabilityScheduleCatalog() {
1910
- var _a, _b;
1911
1868
  if (!this.store.schedule) {
1912
- throw new Error("[UnifiedBookingSales] schedule 模块未初始化");
1869
+ throw new Error('[UnifiedBookingSales] schedule 模块未初始化');
1913
1870
  }
1914
- this.availabilityScheduleCatalog = (0, import_lodash_es.cloneDeep)(
1915
- ((_b = (_a = this.store.schedule).getScheduleList) == null ? void 0 : _b.call(_a)) || []
1916
- );
1871
+ this.availabilityScheduleCatalog = (0, _lodashEs.cloneDeep)(this.store.schedule.getScheduleList?.() || []);
1917
1872
  }
1873
+
1918
1874
  /** Returns the solution-lifetime schedule snapshot captured after initialization. */
1919
1875
  getAvailabilityScheduleCatalog() {
1920
1876
  if (this.availabilityScheduleCatalog === null) {
1921
- throw new Error("[UnifiedBookingSales] schedule 快照未初始化");
1877
+ throw new Error('[UnifiedBookingSales] schedule 快照未初始化');
1922
1878
  }
1923
1879
  return this.availabilityScheduleCatalog;
1924
1880
  }
1925
1881
  buildAvailabilityOperatingHoursSnapshot(params) {
1926
1882
  const descriptor = params.prepare._availabilityOperatingHours || {
1927
- source: params.prepare.businessHours ? "prepare_business_hours" : "default_business_hours",
1883
+ source: params.prepare.businessHours ? 'prepare_business_hours' : 'default_business_hours',
1928
1884
  scheduleIds: []
1929
1885
  };
1930
- if (descriptor.source !== "open_data_schedule") {
1931
- const windows2 = dateRangeDays(params.dateRange).flatMap((date) => {
1886
+ if (descriptor.source !== 'open_data_schedule') {
1887
+ const windows = dateRangeDays(params.dateRange).flatMap(date => {
1932
1888
  const range = normalizeAvailabilityLocalDateTimeRange({
1933
1889
  startAt: `${date}T${params.businessHours.startTime}:00`,
1934
1890
  endAt: `${date}T${params.businessHours.endTime}:00`,
@@ -1945,18 +1901,14 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1945
1901
  source: descriptor.source,
1946
1902
  scheduleIds: [],
1947
1903
  missingScheduleIds: [],
1948
- windows: windows2
1904
+ windows
1949
1905
  };
1950
1906
  }
1951
- const scheduleMap = new Map(
1952
- params.scheduleList.map((schedule) => [String(schedule.id), schedule])
1953
- );
1954
- const schedules = descriptor.scheduleIds.map((scheduleId) => scheduleMap.get(String(scheduleId))).filter((schedule) => Boolean(schedule));
1955
- const matchedScheduleIds = new Set(schedules.map((schedule) => String(schedule.id)));
1956
- const missingScheduleIds = descriptor.scheduleIds.filter(
1957
- (scheduleId) => !matchedScheduleIds.has(String(scheduleId))
1958
- );
1959
- const windows = dateRangeDays(params.dateRange).flatMap((date) => (0, import_getDateIsInSchedule.getScheduleStartEndTimePoints)(date, schedules).flatMap((slot) => {
1907
+ const scheduleMap = new Map(params.scheduleList.map(schedule => [String(schedule.id), schedule]));
1908
+ const schedules = descriptor.scheduleIds.map(scheduleId => scheduleMap.get(String(scheduleId))).filter(schedule => Boolean(schedule));
1909
+ const matchedScheduleIds = new Set(schedules.map(schedule => String(schedule.id)));
1910
+ const missingScheduleIds = descriptor.scheduleIds.filter(scheduleId => !matchedScheduleIds.has(String(scheduleId)));
1911
+ const windows = dateRangeDays(params.dateRange).flatMap(date => (0, _getDateIsInSchedule.getScheduleStartEndTimePoints)(date, schedules).flatMap(slot => {
1960
1912
  const range = normalizeAvailabilityLocalDateTimeRange({
1961
1913
  startAt: slot.start_at,
1962
1914
  endAt: slot.end_at,
@@ -1966,7 +1918,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1966
1918
  return range ? [{
1967
1919
  startAt: range.startAt,
1968
1920
  endAt: range.endAt,
1969
- source: `operating_schedule:${descriptor.scheduleIds.map(String).join(",")}`
1921
+ source: `operating_schedule:${descriptor.scheduleIds.map(String).join(',')}`
1970
1922
  }] : [];
1971
1923
  }));
1972
1924
  return {
@@ -1977,8 +1929,10 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1977
1929
  };
1978
1930
  }
1979
1931
  async loadAvailabilityProducts(params) {
1980
- var _a, _b, _c, _d, _e, _f, _g;
1981
- const { prepare, dateRange } = params;
1932
+ const {
1933
+ prepare,
1934
+ dateRange
1935
+ } = params;
1982
1936
  const explicitProductIds = prepare.productIds || [];
1983
1937
  let rawProducts = [];
1984
1938
  if (Array.isArray(prepare.rawProducts)) {
@@ -1989,21 +1943,18 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
1989
1943
  product_ids: explicitProductIds,
1990
1944
  schedule_date: dateRange.startDate
1991
1945
  });
1992
- } else if (((_a = prepare.catalogScope) == null ? void 0 : _a.type) === "schedule") {
1946
+ } else if (prepare.catalogScope?.type === 'schedule') {
1993
1947
  await this.loadScheduleAvailableDate({
1994
1948
  startDate: dateRange.startDate,
1995
1949
  endDate: dateRange.endDate,
1996
- custom_page_id: Number(prepare.catalogScope.customPageId) || void 0,
1950
+ custom_page_id: Number(prepare.catalogScope.customPageId) || undefined,
1997
1951
  channel: prepare.catalogScope.channel
1998
1952
  });
1999
1953
  const dateSet = new Set(dateRangeDays(dateRange));
2000
- const scheduleProductIds = (((_c = (_b = this.store.schedule).getAvailabilityScheduleDateList) == null ? void 0 : _c.call(_b)) || []).filter((item) => dateSet.has(item.date)).flatMap((item) => item.product_ids || []);
2001
- const productIds = uniqueAvailabilityIds([
2002
- ...scheduleProductIds,
2003
- ...((_e = (_d = this.store.schedule).getOtherProductsIds) == null ? void 0 : _e.call(_d)) || []
2004
- ]);
1954
+ const scheduleProductIds = (this.store.schedule.getAvailabilityScheduleDateList?.() || []).filter(item => dateSet.has(item.date)).flatMap(item => item.product_ids || []);
1955
+ const productIds = uniqueAvailabilityIds([...scheduleProductIds, ...(this.store.schedule.getOtherProductsIds?.() || [])]);
2005
1956
  if (productIds.length > 0) {
2006
- assertAvailabilityCatalogProductIds(productIds, "prepare.catalogScope.scheduleProductIds");
1957
+ assertAvailabilityCatalogProductIds(productIds, 'prepare.catalogScope.scheduleProductIds');
2007
1958
  rawProducts = await this.loadProducts({
2008
1959
  product_ids: productIds,
2009
1960
  schedule_date: dateRange.startDate
@@ -2011,36 +1962,27 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2011
1962
  } else {
2012
1963
  this.unifiedProductCatalog = [];
2013
1964
  }
2014
- } else if (((_f = prepare.catalogScope) == null ? void 0 : _f.type) === "productList") {
1965
+ } else if (prepare.catalogScope?.type === 'productList') {
2015
1966
  rawProducts = await this.loadProducts({
2016
1967
  ...prepare.catalogScope.params,
2017
1968
  schedule_date: prepare.catalogScope.params.schedule_date || dateRange.startDate
2018
1969
  });
2019
1970
  }
2020
- const normalized = rawProducts.map((product) => normalizeProductForAvailability(
2021
- product,
2022
- params.scheduleList,
2023
- this.getAvailabilityRuntimeOffsetMinutes()
2024
- ));
2025
- if (!explicitProductIds.length && ((_g = prepare.resourceIds) == null ? void 0 : _g.length)) {
2026
- return normalized.filter((product) => {
2027
- var _a2;
2028
- return (_a2 = product.requirementGroups) == null ? void 0 : _a2.some((group) => {
2029
- var _a3;
2030
- return (_a3 = group.resourceIds) == null ? void 0 : _a3.some((resourceId) => prepare.resourceIds.some((id) => sameAvailabilityId(id, resourceId)));
2031
- });
2032
- });
1971
+ const normalized = rawProducts.map(product => normalizeProductForAvailability(product, params.scheduleList, this.getAvailabilityRuntimeOffsetMinutes()));
1972
+ if (!explicitProductIds.length && prepare.resourceIds?.length) {
1973
+ return normalized.filter(product => product.requirementGroups?.some(group => group.resourceIds?.some(resourceId => prepare.resourceIds.some(id => sameAvailabilityId(id, resourceId)))));
2033
1974
  }
2034
1975
  const productIdSet = explicitProductIds.length ? new Set(explicitProductIds.map(String)) : null;
2035
- return productIdSet ? normalized.filter((product) => productIdSet.has(String(product.id))) : normalized;
1976
+ return productIdSet ? normalized.filter(product => productIdSet.has(String(product.id))) : normalized;
2036
1977
  }
1978
+
2037
1979
  /**
2038
1980
  * Fetches resource metadata plus flat occupied events. Work windows are intentionally derived
2039
1981
  * locally in buildAvailabilityResourcesFromV2 from /schedule, rather than requested from the legacy
2040
1982
  * resource dates endpoint.
2041
1983
  */
2042
1984
  async fetchAvailabilityResourcesV2(params) {
2043
- const response = await this.request.get("/schedule/resource/list/v2", {
1985
+ const response = await this.request.get('/schedule/resource/list/v2', {
2044
1986
  start_date: params.dateRange.startDate,
2045
1987
  end_date: params.dateRange.endDate,
2046
1988
  resource_ids: params.resourceIds,
@@ -2048,17 +1990,14 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2048
1990
  }, {
2049
1991
  useCache: false
2050
1992
  });
2051
- const data = response == null ? void 0 : response.data;
2052
- if (Array.isArray(data))
2053
- return data;
2054
- if (Array.isArray(data == null ? void 0 : data.list))
2055
- return data.list;
1993
+ const data = response?.data;
1994
+ if (Array.isArray(data)) return data;
1995
+ if (Array.isArray(data?.list)) return data.list;
2056
1996
  return [];
2057
1997
  }
2058
1998
  async fetchAndPublishAvailabilityResourcesV2(params) {
2059
1999
  const normalizedResourceIds = this.normalizeAvailabilityIdList(params.resourceIds) || [];
2060
- if (normalizedResourceIds.length === 0)
2061
- return [];
2000
+ if (normalizedResourceIds.length === 0) return [];
2062
2001
  const scopeKey = this.buildAvailabilityRemoteResourceScopeKey(params.timezone);
2063
2002
  const cacheParams = {
2064
2003
  scopeKey,
@@ -2072,8 +2011,8 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2072
2011
  timezone: params.timezone,
2073
2012
  dateRange: params.dateRange,
2074
2013
  resourceIds: normalizedResourceIds
2075
- }).catch((error) => {
2076
- console.warn("[UnifiedBookingSales] Remote occupancy background refresh failed", error);
2014
+ }).catch(error => {
2015
+ console.warn('[UnifiedBookingSales] Remote occupancy background refresh failed', error);
2077
2016
  });
2078
2017
  }
2079
2018
  return cachedRawResources;
@@ -2086,8 +2025,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2086
2025
  }
2087
2026
  async refreshAvailabilityRemoteResourceQuery(params) {
2088
2027
  const normalizedResourceIds = this.normalizeAvailabilityIdList(params.resourceIds) || [];
2089
- if (normalizedResourceIds.length === 0)
2090
- return [];
2028
+ if (normalizedResourceIds.length === 0) return [];
2091
2029
  const queryKey = this.buildAvailabilityRemoteResourceQueryKey({
2092
2030
  timezone: params.timezone,
2093
2031
  dateRange: params.dateRange,
@@ -2095,7 +2033,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2095
2033
  });
2096
2034
  const epoch = this.availabilityRemoteResourceEpoch;
2097
2035
  const existing = this.availabilityRemoteResourceQueryInFlight.get(queryKey);
2098
- if ((existing == null ? void 0 : existing.epoch) === epoch) {
2036
+ if (existing?.epoch === epoch) {
2099
2037
  return await existing.promise;
2100
2038
  }
2101
2039
  this.availabilityRemoteResourceQuerySequence += 1;
@@ -2123,7 +2061,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2123
2061
  return rawResources;
2124
2062
  } finally {
2125
2063
  const current = this.availabilityRemoteResourceQueryInFlight.get(queryKey);
2126
- if ((current == null ? void 0 : current.promise) === promise) {
2064
+ if (current?.promise === promise) {
2127
2065
  this.availabilityRemoteResourceQueryInFlight.delete(queryKey);
2128
2066
  }
2129
2067
  }
@@ -2144,7 +2082,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2144
2082
  fixedOffsetMinutes: this.getAvailabilityRuntimeOffsetMinutes()
2145
2083
  });
2146
2084
  }
2147
- if (params.fetchPolicy === "cache_only") {
2085
+ if (params.fetchPolicy === 'cache_only') {
2148
2086
  const cachedRawResources = this.availabilityRemoteOccupancyCache.read({
2149
2087
  scopeKey: this.buildAvailabilityRemoteResourceScopeKey(params.timezone),
2150
2088
  resourceIds,
@@ -2158,7 +2096,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2158
2096
  fixedOffsetMinutes: this.getAvailabilityRuntimeOffsetMinutes()
2159
2097
  });
2160
2098
  }
2161
- return params.fallbackResources ? (0, import_lodash_es.cloneDeep)(params.fallbackResources) : {
2099
+ return params.fallbackResources ? (0, _lodashEs.cloneDeep)(params.fallbackResources) : {
2162
2100
  resources: [],
2163
2101
  resourceOccupancies: []
2164
2102
  };
@@ -2177,44 +2115,46 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2177
2115
  });
2178
2116
  }
2179
2117
  resolveEditingOccupancyExclusions(tempOrder, productLineUids = []) {
2180
- const productUids = /* @__PURE__ */ new Set();
2181
- const bookingUids = /* @__PURE__ */ new Set();
2182
- const scheduleEventIds = /* @__PURE__ */ new Set();
2183
- if (!productLineUids.length)
2184
- return { productUids, bookingUids, scheduleEventIds };
2185
- const products = Array.isArray(tempOrder == null ? void 0 : tempOrder.products) ? tempOrder.products : [];
2186
- const bookings = Array.isArray(tempOrder == null ? void 0 : tempOrder.bookings) ? tempOrder.bookings : [];
2187
- productLineUids.forEach((requestedUid) => {
2188
- var _a;
2189
- const product = products.find((line) => getProductLineUid(line) === String(requestedUid));
2118
+ const productUids = new Set();
2119
+ const bookingUids = new Set();
2120
+ const scheduleEventIds = new Set();
2121
+ if (!productLineUids.length) return {
2122
+ productUids,
2123
+ bookingUids,
2124
+ scheduleEventIds
2125
+ };
2126
+ const products = Array.isArray(tempOrder?.products) ? tempOrder.products : [];
2127
+ const bookings = Array.isArray(tempOrder?.bookings) ? tempOrder.bookings : [];
2128
+ productLineUids.forEach(requestedUid => {
2129
+ const product = products.find(line => getProductLineUid(line) === String(requestedUid));
2190
2130
  if (!product) {
2191
- throw new import_ResourcePlanner.AvailabilityError(
2192
- "SELF_EXCLUSION_RESOLVE_FAILED",
2193
- "无法解析编辑商品行,不能安全排除自身占用",
2194
- { productLineUid: requestedUid }
2195
- );
2131
+ throw new _ResourcePlanner.AvailabilityError('SELF_EXCLUSION_RESOLVE_FAILED', '无法解析编辑商品行,不能安全排除自身占用', {
2132
+ productLineUid: requestedUid
2133
+ });
2196
2134
  }
2197
2135
  const productUid = getProductLineUid(product);
2198
- const linkedBookingUid = String(product.booking_uid ?? ((_a = product.metadata) == null ? void 0 : _a.booking_uid) ?? "");
2199
- const linkedBookings = bookings.filter((booking) => linkedBookingUid && getBookingUid(booking) === linkedBookingUid || productUid && String(booking.product_uid ?? "") === productUid);
2136
+ const linkedBookingUid = String(product.booking_uid ?? product.metadata?.booking_uid ?? '');
2137
+ const linkedBookings = bookings.filter(booking => linkedBookingUid && getBookingUid(booking) === linkedBookingUid || productUid && String(booking.product_uid ?? '') === productUid);
2200
2138
  if (!productUid || !linkedBookings.length) {
2201
- throw new import_ResourcePlanner.AvailabilityError(
2202
- "SELF_EXCLUSION_RESOLVE_FAILED",
2203
- "编辑商品行缺少可验证的 booking 关联",
2204
- { productLineUid: requestedUid, linkedBookingUid }
2205
- );
2139
+ throw new _ResourcePlanner.AvailabilityError('SELF_EXCLUSION_RESOLVE_FAILED', '编辑商品行缺少可验证的 booking 关联', {
2140
+ productLineUid: requestedUid,
2141
+ linkedBookingUid
2142
+ });
2206
2143
  }
2207
2144
  productUids.add(productUid);
2208
- linkedBookings.forEach((booking) => {
2145
+ linkedBookings.forEach(booking => {
2209
2146
  const bookingUid = getBookingUid(booking);
2210
- if (bookingUid)
2211
- bookingUids.add(bookingUid);
2147
+ if (bookingUid) bookingUids.add(bookingUid);
2212
2148
  if (booking.schedule_event_id != null) {
2213
2149
  scheduleEventIds.add(String(booking.schedule_event_id));
2214
2150
  }
2215
2151
  });
2216
2152
  });
2217
- return { productUids, bookingUids, scheduleEventIds };
2153
+ return {
2154
+ productUids,
2155
+ bookingUids,
2156
+ scheduleEventIds
2157
+ };
2218
2158
  }
2219
2159
  occupancyIsExcluded(occupancy, exclusions) {
2220
2160
  if (occupancy.scheduleEventId != null) {
@@ -2229,37 +2169,37 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2229
2169
  return false;
2230
2170
  }
2231
2171
  collectCartResourceOccupancies(tempOrder, exclusions) {
2232
- const bookings = Array.isArray(tempOrder == null ? void 0 : tempOrder.bookings) ? tempOrder.bookings : [];
2233
- return bookings.flatMap((booking) => {
2234
- var _a;
2172
+ const bookings = Array.isArray(tempOrder?.bookings) ? tempOrder.bookings : [];
2173
+ return bookings.flatMap(booking => {
2235
2174
  const bookingUid = getBookingUid(booking);
2236
- const productUid = String(booking.product_uid ?? ((_a = booking.metadata) == null ? void 0 : _a.product_uid) ?? "");
2175
+ const productUid = String(booking.product_uid ?? booking.metadata?.product_uid ?? '');
2237
2176
  const scheduleEventId = toNumberId(booking.schedule_event_id);
2238
- const startAt = booking.start_at || `${booking.start_date || ""} ${booking.start_time || ""}`.trim();
2239
- const endAt = booking.end_at || `${booking.end_date || booking.start_date || ""} ${booking.end_time || ""}`.trim();
2177
+ const startAt = booking.start_at || `${booking.start_date || ''} ${booking.start_time || ''}`.trim();
2178
+ const endAt = booking.end_at || `${booking.end_date || booking.start_date || ''} ${booking.end_time || ''}`.trim();
2240
2179
  const resources = Array.isArray(booking.resources) ? booking.resources : [];
2241
- return resources.flatMap((resource) => {
2180
+ return resources.flatMap(resource => {
2242
2181
  const resourceId = resource.resource_id ?? resource.relation_id ?? resource.id;
2243
- if (resourceId == null || !startAt || !endAt)
2244
- return [];
2182
+ if (resourceId == null || !startAt || !endAt) return [];
2245
2183
  const range = normalizeAvailabilityLocalDateTimeRange({
2246
2184
  startAt,
2247
2185
  endAt,
2248
2186
  fixedOffsetMinutes: this.getAvailabilityRuntimeOffsetMinutes(),
2249
2187
  rollOverEnd: false
2250
2188
  });
2251
- if (!range)
2252
- return [];
2189
+ if (!range) return [];
2253
2190
  const occupancy = {
2254
2191
  resourceId,
2255
2192
  startAt: range.startAt,
2256
2193
  endAt: range.endAt,
2257
2194
  pax: Math.max(1, Number(resource.capacity ?? booking.capacity ?? 1) || 1),
2258
- source: "cart",
2195
+ source: 'cart',
2259
2196
  scheduleEventId,
2260
- bookingUid: bookingUid || void 0,
2261
- productUid: productUid || void 0,
2262
- raw: { booking, resource }
2197
+ bookingUid: bookingUid || undefined,
2198
+ productUid: productUid || undefined,
2199
+ raw: {
2200
+ booking,
2201
+ resource
2202
+ }
2263
2203
  };
2264
2204
  return this.occupancyIsExcluded(occupancy, exclusions) ? [] : [occupancy];
2265
2205
  });
@@ -2271,30 +2211,22 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2271
2211
  getAvailabilityContextEntry(contextId) {
2272
2212
  const context = this.availabilityContextRegistry.get(contextId);
2273
2213
  if (!context) {
2274
- throw this.createAvailabilityFacadeError(
2275
- "AVAILABILITY_CONTEXT_NOT_FOUND",
2276
- "availability context 不存在或已失效,请重新 prepare",
2277
- {
2278
- contextId,
2279
- lifecycleGeneration: this.availabilityLifecycleGeneration
2280
- }
2281
- );
2214
+ throw this.createAvailabilityFacadeError('AVAILABILITY_CONTEXT_NOT_FOUND', 'availability context 不存在或已失效,请重新 prepare', {
2215
+ contextId,
2216
+ lifecycleGeneration: this.availabilityLifecycleGeneration
2217
+ });
2282
2218
  }
2283
2219
  this.touchAvailabilityContext(context);
2284
2220
  return context;
2285
2221
  }
2286
2222
  getAvailabilityProjectionByKey(projectionKey) {
2287
- var _a;
2288
- if (!projectionKey)
2289
- return null;
2290
- return ((_a = this.availabilityProjectionPool.get(projectionKey)) == null ? void 0 : _a.projection) || null;
2223
+ if (!projectionKey) return null;
2224
+ return this.availabilityProjectionPool.get(projectionKey)?.projection || null;
2291
2225
  }
2292
2226
  getActiveAvailabilityProjectionEntry(context) {
2293
- if (!context.activeProjectionKey)
2294
- return null;
2227
+ if (!context.activeProjectionKey) return null;
2295
2228
  const entry = this.availabilityProjectionPool.get(context.activeProjectionKey);
2296
- if (!entry)
2297
- return null;
2229
+ if (!entry) return null;
2298
2230
  return this.touchAvailabilityProjection(entry);
2299
2231
  }
2300
2232
  decorateAvailabilityCandidate(contextId, contextVersion, candidate) {
@@ -2306,38 +2238,30 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2306
2238
  }
2307
2239
  assertAvailabilityCandidateFreshness(context, candidate) {
2308
2240
  if (candidate.availabilityContextId !== context.contextId) {
2309
- throw this.createAvailabilityFacadeError(
2310
- "AVAILABILITY_SELECTION_STALE",
2311
- "候选与 availability context 不匹配,请重新获取候选",
2312
- {
2313
- candidateContextId: candidate.availabilityContextId,
2314
- contextId: context.contextId
2315
- }
2316
- );
2241
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', '候选与 availability context 不匹配,请重新获取候选', {
2242
+ candidateContextId: candidate.availabilityContextId,
2243
+ contextId: context.contextId
2244
+ });
2317
2245
  }
2318
2246
  const currentContextVersion = context.activeVersion;
2319
2247
  if (candidate.availabilityContextVersion !== currentContextVersion) {
2320
- throw this.createAvailabilityFacadeError(
2321
- "AVAILABILITY_SELECTION_STALE",
2322
- "候选已过期,请重新获取最新时间段",
2323
- {
2324
- contextId: context.contextId,
2325
- candidateContextVersion: candidate.availabilityContextVersion,
2326
- currentContextVersion,
2327
- snapshotId: context.lastSnapshotId
2328
- }
2329
- );
2248
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', '候选已过期,请重新获取最新时间段', {
2249
+ contextId: context.contextId,
2250
+ candidateContextVersion: candidate.availabilityContextVersion,
2251
+ currentContextVersion,
2252
+ snapshotId: context.lastSnapshotId
2253
+ });
2330
2254
  }
2331
2255
  }
2332
2256
  assertContextualQueryFreshness(context, request) {
2333
- if (request.target === "time") {
2334
- request.candidates.forEach((candidate) => {
2257
+ if (request.target === 'time') {
2258
+ request.candidates.forEach(candidate => {
2335
2259
  this.assertAvailabilityCandidateFreshness(context, candidate);
2336
2260
  });
2337
2261
  return;
2338
2262
  }
2339
- if (request.target === "resource") {
2340
- request.selectedRanges.forEach((candidate) => {
2263
+ if (request.target === 'resource') {
2264
+ request.selectedRanges.forEach(candidate => {
2341
2265
  this.assertAvailabilityCandidateFreshness(context, candidate);
2342
2266
  });
2343
2267
  }
@@ -2355,7 +2279,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2355
2279
  preparedAt: params.projection.meta.preparedAt,
2356
2280
  snapshotId: params.projection.meta.snapshotId
2357
2281
  };
2358
- if ((previousContext == null ? void 0 : previousContext.activeProjectionKey) && previousContext.activeProjectionKey !== projectionKey) {
2282
+ if (previousContext?.activeProjectionKey && previousContext.activeProjectionKey !== projectionKey) {
2359
2283
  this.removeAvailabilityProjection(previousContext.activeProjectionKey);
2360
2284
  }
2361
2285
  this.availabilityProjectionPool.set(projectionKey, entry);
@@ -2366,13 +2290,13 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2366
2290
  prepareKey: params.prepareKey,
2367
2291
  activeVersion: contextVersion,
2368
2292
  activeProjectionKey: projectionKey,
2369
- createdAt: (previousContext == null ? void 0 : previousContext.createdAt) ?? params.projection.meta.preparedAt,
2370
- lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString(),
2293
+ createdAt: previousContext?.createdAt ?? params.projection.meta.preparedAt,
2294
+ lastAccessedAt: new Date().toISOString(),
2371
2295
  lastKnownOrderRevision: params.orderRevision,
2372
2296
  lastPreparedAt: params.projection.meta.preparedAt,
2373
2297
  lastSnapshotId: params.projection.meta.snapshotId,
2374
- durationCandidateAnchorAt: (previousContext == null ? void 0 : previousContext.durationCandidateAnchorAt) ?? this.getAvailabilityDurationCandidateAnchorAt(params.projection),
2375
- refreshNonce: (previousContext == null ? void 0 : previousContext.refreshNonce) ?? 0,
2298
+ durationCandidateAnchorAt: previousContext?.durationCandidateAnchorAt ?? this.getAvailabilityDurationCandidateAnchorAt(params.projection),
2299
+ refreshNonce: previousContext?.refreshNonce ?? 0,
2376
2300
  lifecycleGeneration: this.availabilityLifecycleGeneration
2377
2301
  };
2378
2302
  this.touchAvailabilityContext(nextContext);
@@ -2385,7 +2309,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2385
2309
  const dateRange = normalizedPrepareParams.dateRange;
2386
2310
  const slotStepMinutes = normalizedPrepareParams.slotStepMinutes || DEFAULT_AVAILABILITY_SLOT_STEP_MINUTES;
2387
2311
  const businessHours = normalizedPrepareParams.businessHours || DEFAULT_AVAILABILITY_BUSINESS_HOURS;
2388
- const mode = normalizedPrepareParams.mode || "appointment";
2312
+ const mode = normalizedPrepareParams.mode || 'appointment';
2389
2313
  const scheduleList = this.getAvailabilityScheduleCatalog();
2390
2314
  const operatingHours = this.buildAvailabilityOperatingHoursSnapshot({
2391
2315
  prepare: normalizedPrepareParams,
@@ -2405,39 +2329,32 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2405
2329
  products,
2406
2330
  rawResources: normalizedPrepareParams.rawResources,
2407
2331
  scheduleList,
2408
- fetchPolicy: options.resourceFetchPolicy || "default",
2332
+ fetchPolicy: options.resourceFetchPolicy || 'default',
2409
2333
  fallbackResources: options.fallbackResources
2410
2334
  });
2411
2335
  const tempOrder = this.getTempOrder();
2412
- const exclusions = this.resolveEditingOccupancyExclusions(
2413
- tempOrder,
2414
- normalizedPrepareParams.editingProductLineUids
2415
- );
2416
- const injectedRawOccupancies = (normalizedPrepareParams.rawOccupancies || []).flatMap((occupancy) => {
2336
+ const exclusions = this.resolveEditingOccupancyExclusions(tempOrder, normalizedPrepareParams.editingProductLineUids);
2337
+ const injectedRawOccupancies = (normalizedPrepareParams.rawOccupancies || []).flatMap(occupancy => {
2417
2338
  const range = normalizeAvailabilityLocalDateTimeRange({
2418
2339
  startAt: occupancy.startAt,
2419
2340
  endAt: occupancy.endAt,
2420
2341
  fixedOffsetMinutes: this.getAvailabilityRuntimeOffsetMinutes(),
2421
2342
  rollOverEnd: false
2422
2343
  });
2423
- if (!range)
2424
- return [];
2344
+ if (!range) return [];
2425
2345
  return [{
2426
2346
  ...occupancy,
2427
2347
  startAt: range.startAt,
2428
2348
  endAt: range.endAt
2429
2349
  }];
2430
2350
  });
2431
- const remoteOccupancies = [
2432
- ...loadedResources.resourceOccupancies,
2433
- ...loadedResources.includesInjectedRawOccupancies ? [] : injectedRawOccupancies
2434
- ].filter((occupancy) => !this.occupancyIsExcluded(occupancy, exclusions));
2351
+ const remoteOccupancies = [...loadedResources.resourceOccupancies, ...(loadedResources.includesInjectedRawOccupancies ? [] : injectedRawOccupancies)].filter(occupancy => !this.occupancyIsExcluded(occupancy, exclusions));
2435
2352
  const cartOccupancies = this.collectCartResourceOccupancies(tempOrder, exclusions);
2436
2353
  const preparedAt = this.getAvailabilityRuntimeDateTime();
2437
2354
  const durationCandidateAnchorAt = options.durationCandidateAnchorAt || preparedAt;
2438
2355
  this.availabilityProjectionSequence += 1;
2439
2356
  const orderRevision = this.getCurrentOrderRevision();
2440
- const projection = (0, import_ResourcePlanner.createAvailabilityProjection)({
2357
+ const projection = (0, _ResourcePlanner.createAvailabilityProjection)({
2441
2358
  products,
2442
2359
  resources: loadedResources.resources,
2443
2360
  resourceOccupancies: [...remoteOccupancies, ...cartOccupancies],
@@ -2468,38 +2385,37 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2468
2385
  async getSharedPreparedAvailabilitySnapshot(params) {
2469
2386
  const lifecycleGeneration = this.availabilityLifecycleGeneration;
2470
2387
  const normalizedParams = this.normalizeAvailabilityPrepareDescriptor(params);
2471
- const hasRawInputs = params.rawProducts !== void 0 || params.rawResources !== void 0 || params.rawOccupancies !== void 0;
2388
+ const hasRawInputs = params.rawProducts !== undefined || params.rawResources !== undefined || params.rawOccupancies !== undefined;
2472
2389
  const prepareKey = hasRawInputs ? JSON.stringify(stableValue({
2473
2390
  scope: this.getAvailabilityScopeDescriptor(),
2474
2391
  prepare: {
2475
2392
  ...normalizedParams,
2476
- rawProducts: void 0,
2477
- rawResources: void 0,
2478
- rawOccupancies: void 0
2393
+ rawProducts: undefined,
2394
+ rawResources: undefined,
2395
+ rawOccupancies: undefined
2479
2396
  },
2480
2397
  rawInputs: {
2481
- products: params.rawProducts !== void 0,
2482
- resources: params.rawResources !== void 0,
2483
- occupancies: params.rawOccupancies !== void 0
2398
+ products: params.rawProducts !== undefined,
2399
+ resources: params.rawResources !== undefined,
2400
+ occupancies: params.rawOccupancies !== undefined
2484
2401
  }
2485
2402
  })) : this.buildAvailabilityPrepareKey(normalizedParams);
2486
2403
  if (hasRawInputs) {
2487
2404
  const snapshot = await this.buildAvailabilityProjectionSnapshot(normalizedParams);
2488
2405
  if (lifecycleGeneration !== this.availabilityLifecycleGeneration) {
2489
- throw this.createAvailabilityFacadeError(
2490
- "AVAILABILITY_CONTEXT_NOT_FOUND",
2491
- "prepare 期间业务作用域或实例生命周期已变化,请重新 prepare",
2492
- {
2493
- prepareKey,
2494
- expectedLifecycleGeneration: lifecycleGeneration,
2495
- currentLifecycleGeneration: this.availabilityLifecycleGeneration
2496
- }
2497
- );
2406
+ throw this.createAvailabilityFacadeError('AVAILABILITY_CONTEXT_NOT_FOUND', 'prepare 期间业务作用域或实例生命周期已变化,请重新 prepare', {
2407
+ prepareKey,
2408
+ expectedLifecycleGeneration: lifecycleGeneration,
2409
+ currentLifecycleGeneration: this.availabilityLifecycleGeneration
2410
+ });
2498
2411
  }
2499
- return { prepareKey, snapshot };
2412
+ return {
2413
+ prepareKey,
2414
+ snapshot
2415
+ };
2500
2416
  }
2501
2417
  const existing = this.availabilityPrepareInFlight.get(prepareKey);
2502
- const promise = (existing == null ? void 0 : existing.lifecycleGeneration) === lifecycleGeneration ? existing.promise : this.buildAvailabilityProjectionSnapshot(normalizedParams);
2418
+ const promise = existing?.lifecycleGeneration === lifecycleGeneration ? existing.promise : this.buildAvailabilityProjectionSnapshot(normalizedParams);
2503
2419
  if (!existing || existing.lifecycleGeneration !== lifecycleGeneration) {
2504
2420
  this.availabilityPrepareInFlight.set(prepareKey, {
2505
2421
  lifecycleGeneration,
@@ -2510,42 +2426,36 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2510
2426
  try {
2511
2427
  const snapshot = await promise;
2512
2428
  if (lifecycleGeneration !== this.availabilityLifecycleGeneration) {
2513
- throw this.createAvailabilityFacadeError(
2514
- "AVAILABILITY_CONTEXT_NOT_FOUND",
2515
- "prepare 期间业务作用域或实例生命周期已变化,请重新 prepare",
2516
- {
2517
- prepareKey,
2518
- expectedLifecycleGeneration: lifecycleGeneration,
2519
- currentLifecycleGeneration: this.availabilityLifecycleGeneration
2520
- }
2521
- );
2429
+ throw this.createAvailabilityFacadeError('AVAILABILITY_CONTEXT_NOT_FOUND', 'prepare 期间业务作用域或实例生命周期已变化,请重新 prepare', {
2430
+ prepareKey,
2431
+ expectedLifecycleGeneration: lifecycleGeneration,
2432
+ currentLifecycleGeneration: this.availabilityLifecycleGeneration
2433
+ });
2522
2434
  }
2523
- return { prepareKey, snapshot };
2435
+ return {
2436
+ prepareKey,
2437
+ snapshot
2438
+ };
2524
2439
  } finally {
2525
2440
  const current = this.availabilityPrepareInFlight.get(prepareKey);
2526
- if ((current == null ? void 0 : current.promise) === promise) {
2441
+ if (current?.promise === promise) {
2527
2442
  this.availabilityPrepareInFlight.delete(prepareKey);
2528
2443
  }
2529
2444
  }
2530
2445
  }
2531
2446
  async refreshAvailabilityContextProjection(params) {
2532
2447
  const existingInFlight = this.availabilityProjectionRefreshInFlight.get(params.contextId);
2533
- if (existingInFlight)
2534
- return await existingInFlight;
2448
+ if (existingInFlight) return await existingInFlight;
2535
2449
  const context = this.getAvailabilityContextEntry(params.contextId);
2536
2450
  const expectedVersion = context.activeVersion;
2537
2451
  const expectedRefreshNonce = context.refreshNonce;
2538
2452
  const expectedLifecycleGeneration = this.availabilityLifecycleGeneration;
2539
2453
  const refreshPromise = (async () => {
2540
- const snapshot = await this.buildAvailabilityProjectionSnapshot(
2541
- this.cloneAvailabilityPrepareParams(context.prepareParams),
2542
- {
2543
- durationCandidateAnchorAt: context.durationCandidateAnchorAt
2544
- }
2545
- );
2454
+ const snapshot = await this.buildAvailabilityProjectionSnapshot(this.cloneAvailabilityPrepareParams(context.prepareParams), {
2455
+ durationCandidateAnchorAt: context.durationCandidateAnchorAt
2456
+ });
2546
2457
  const currentContext = this.availabilityContextRegistry.get(params.contextId);
2547
- if (!currentContext)
2548
- return null;
2458
+ if (!currentContext) return null;
2549
2459
  if (expectedLifecycleGeneration !== this.availabilityLifecycleGeneration || currentContext.activeVersion !== expectedVersion || currentContext.refreshNonce !== expectedRefreshNonce || currentContext.lifecycleGeneration !== expectedLifecycleGeneration) {
2550
2460
  return null;
2551
2461
  }
@@ -2558,7 +2468,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2558
2468
  incrementVersion: true
2559
2469
  });
2560
2470
  await this.emitAvailabilityDiagnostic({
2561
- action: "refresh",
2471
+ action: 'refresh',
2562
2472
  contextId: currentContext.contextId,
2563
2473
  contextVersion: projectionEntry.contextVersion,
2564
2474
  projection: projectionEntry.projection,
@@ -2586,7 +2496,11 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2586
2496
  const currentOrderRevision = this.getCurrentOrderRevision();
2587
2497
  const projectionEntry = this.getActiveAvailabilityProjectionEntry(context);
2588
2498
  if (projectionEntry && projectionEntry.orderRevision === currentOrderRevision) {
2589
- return { context, projectionEntry, refreshed: false };
2499
+ return {
2500
+ context,
2501
+ projectionEntry,
2502
+ refreshed: false
2503
+ };
2590
2504
  }
2591
2505
  const refreshedProjectionEntry = await this.refreshAvailabilityContextProjection({
2592
2506
  contextId,
@@ -2607,7 +2521,7 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2607
2521
  refreshed: true
2608
2522
  };
2609
2523
  }
2610
- throw new import_ResourcePlanner.AvailabilityError("STALE_PROJECTION", "availability projection 刷新期间购物车持续变化,请重新 prepare", {
2524
+ throw new _ResourcePlanner.AvailabilityError('STALE_PROJECTION', 'availability projection 刷新期间购物车持续变化,请重新 prepare', {
2611
2525
  contextId,
2612
2526
  reason
2613
2527
  });
@@ -2616,50 +2530,52 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2616
2530
  if (this.availabilityCommitLocks.has(contextId)) {
2617
2531
  const waitingContext = this.availabilityContextRegistry.get(contextId);
2618
2532
  await this.emitAvailabilityDiagnostic({
2619
- action: "commit_lock_wait",
2533
+ action: 'commit_lock_wait',
2620
2534
  contextId,
2621
- contextVersion: (waitingContext == null ? void 0 : waitingContext.activeVersion) ?? null,
2622
- projection: this.getAvailabilityProjectionByKey(waitingContext == null ? void 0 : waitingContext.activeProjectionKey),
2623
- snapshotId: waitingContext == null ? void 0 : waitingContext.lastSnapshotId,
2624
- orderRevision: waitingContext == null ? void 0 : waitingContext.lastKnownOrderRevision,
2625
- reason: "AVAILABILITY_COMMIT_IN_PROGRESS"
2535
+ contextVersion: waitingContext?.activeVersion ?? null,
2536
+ projection: this.getAvailabilityProjectionByKey(waitingContext?.activeProjectionKey),
2537
+ snapshotId: waitingContext?.lastSnapshotId,
2538
+ orderRevision: waitingContext?.lastKnownOrderRevision,
2539
+ reason: 'AVAILABILITY_COMMIT_IN_PROGRESS'
2540
+ });
2541
+ throw this.createAvailabilityFacadeError('AVAILABILITY_COMMIT_IN_PROGRESS', '同一 availability context 已有 commit 正在进行中', {
2542
+ contextId
2626
2543
  });
2627
- throw this.createAvailabilityFacadeError(
2628
- "AVAILABILITY_COMMIT_IN_PROGRESS",
2629
- "同一 availability context 已有 commit 正在进行中",
2630
- { contextId }
2631
- );
2632
2544
  }
2633
2545
  this.availabilityCommitLocks.add(contextId);
2634
2546
  const currentContext = this.availabilityContextRegistry.get(contextId);
2635
2547
  await this.emitAvailabilityDiagnostic({
2636
- action: "commit_lock_acquired",
2548
+ action: 'commit_lock_acquired',
2637
2549
  contextId,
2638
- contextVersion: (currentContext == null ? void 0 : currentContext.activeVersion) ?? null,
2639
- projection: this.getAvailabilityProjectionByKey(currentContext == null ? void 0 : currentContext.activeProjectionKey),
2640
- snapshotId: currentContext == null ? void 0 : currentContext.lastSnapshotId,
2641
- orderRevision: currentContext == null ? void 0 : currentContext.lastKnownOrderRevision,
2642
- reason: "commit_start"
2550
+ contextVersion: currentContext?.activeVersion ?? null,
2551
+ projection: this.getAvailabilityProjectionByKey(currentContext?.activeProjectionKey),
2552
+ snapshotId: currentContext?.lastSnapshotId,
2553
+ orderRevision: currentContext?.lastKnownOrderRevision,
2554
+ reason: 'commit_start'
2643
2555
  });
2644
2556
  }
2645
2557
  async releaseAvailabilityCommitLock(contextId) {
2646
2558
  this.availabilityCommitLocks.delete(contextId);
2647
2559
  const releasedContext = this.availabilityContextRegistry.get(contextId);
2648
2560
  await this.emitAvailabilityDiagnostic({
2649
- action: "commit_lock_released",
2561
+ action: 'commit_lock_released',
2650
2562
  contextId,
2651
- contextVersion: (releasedContext == null ? void 0 : releasedContext.activeVersion) ?? null,
2652
- projection: this.getAvailabilityProjectionByKey(releasedContext == null ? void 0 : releasedContext.activeProjectionKey),
2653
- snapshotId: releasedContext == null ? void 0 : releasedContext.lastSnapshotId,
2654
- orderRevision: releasedContext == null ? void 0 : releasedContext.lastKnownOrderRevision,
2655
- reason: "commit_end"
2563
+ contextVersion: releasedContext?.activeVersion ?? null,
2564
+ projection: this.getAvailabilityProjectionByKey(releasedContext?.activeProjectionKey),
2565
+ snapshotId: releasedContext?.lastSnapshotId,
2566
+ orderRevision: releasedContext?.lastKnownOrderRevision,
2567
+ reason: 'commit_end'
2656
2568
  });
2657
2569
  }
2570
+
2658
2571
  /** IO boundary: loads catalog, schedules, resources, occupancies, and registers one context. */
2659
2572
  async prepareAvailabilityProjection(params) {
2660
2573
  this.assertAvailabilityPrepareParams(params);
2661
2574
  const paramsWithDefaults = await this.resolveAvailabilityPrepareDefaults(params);
2662
- const { prepareKey, snapshot } = await this.getSharedPreparedAvailabilitySnapshot(paramsWithDefaults);
2575
+ const {
2576
+ prepareKey,
2577
+ snapshot
2578
+ } = await this.getSharedPreparedAvailabilitySnapshot(paramsWithDefaults);
2663
2579
  const contextId = this.createAvailabilityContextId();
2664
2580
  const projectionEntry = this.storeAvailabilityProjectionEntry({
2665
2581
  contextId,
@@ -2676,62 +2592,59 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2676
2592
  contextVersion: context.activeVersion,
2677
2593
  projection: projectionEntry.projection,
2678
2594
  refreshed: false,
2679
- reason: "prepare"
2595
+ reason: 'prepare'
2680
2596
  };
2681
2597
  await this.emitAvailabilityDiagnostic({
2682
- action: "prepare",
2598
+ action: 'prepare',
2683
2599
  contextId,
2684
2600
  contextVersion: context.activeVersion,
2685
2601
  projection: projectionEntry.projection,
2686
2602
  snapshotId: context.lastSnapshotId,
2687
2603
  orderRevision: context.lastKnownOrderRevision,
2688
- reason: "prepare"
2604
+ reason: 'prepare'
2689
2605
  });
2690
- await this.core.effects.emit(
2691
- `${this.name}:${import_types.UnifiedBookingSalesHooks.onAvailabilityProjectionPrepared}`,
2692
- payload
2693
- );
2606
+ await this.core.effects.emit(`${this.name}:${_types.UnifiedBookingSalesHooks.onAvailabilityProjectionPrepared}`, payload);
2694
2607
  return handle;
2695
2608
  }
2609
+
2696
2610
  /** Pure configuration calculation over the current context projection. */
2697
2611
  async getProductTimeRanges(contextId, request = {}) {
2698
- const { context, projectionEntry } = await this.ensureAvailabilityContextProjection(
2699
- contextId,
2700
- "get_product_time_ranges"
2701
- );
2612
+ const {
2613
+ context,
2614
+ projectionEntry
2615
+ } = await this.ensureAvailabilityContextProjection(contextId, 'get_product_time_ranges');
2702
2616
  const contextVersion = context.activeVersion;
2703
- return (0, import_ResourcePlanner.getProductTimeRanges)(projectionEntry.projection, request).map((group) => ({
2617
+ return (0, _ResourcePlanner.getProductTimeRanges)(projectionEntry.projection, request).map(group => ({
2704
2618
  ...group,
2705
- ranges: group.ranges.map((candidate) => this.decorateAvailabilityCandidate(context.contextId, contextVersion, candidate))
2619
+ ranges: group.ranges.map(candidate => this.decorateAvailabilityCandidate(context.contextId, contextVersion, candidate))
2706
2620
  }));
2707
2621
  }
2622
+
2708
2623
  /** Thin facade: auto-refresh on cart drift, then delegate to the pure projection query. */
2709
2624
  async queryBookingAvailability(contextId, request) {
2710
- const { context, projectionEntry, refreshed } = await this.ensureAvailabilityContextProjection(
2711
- contextId,
2712
- "query_booking_availability"
2713
- );
2625
+ const {
2626
+ context,
2627
+ projectionEntry,
2628
+ refreshed
2629
+ } = await this.ensureAvailabilityContextProjection(contextId, 'query_booking_availability');
2714
2630
  this.assertContextualQueryFreshness(context, request);
2715
- const result = (0, import_ResourcePlanner.queryAvailabilityProjection)(
2716
- projectionEntry.projection,
2717
- request
2718
- );
2631
+ const result = (0, _ResourcePlanner.queryAvailabilityProjection)(projectionEntry.projection, request);
2719
2632
  const contextVersion = context.activeVersion;
2720
- const contextualResult = result.target === "time" ? {
2633
+ const contextualResult = result.target === 'time' ? {
2721
2634
  ...result,
2722
- data: result.data.map((group) => ({
2635
+ data: result.data.map(group => ({
2723
2636
  ...group,
2724
- times: group.times.map((item) => ({
2637
+ times: group.times.map(item => ({
2725
2638
  ...item,
2726
2639
  availabilityContextId: context.contextId,
2727
2640
  availabilityContextVersion: contextVersion
2728
2641
  }))
2729
2642
  }))
2730
- } : result.target === "resource" ? {
2643
+ } : result.target === 'resource' ? {
2731
2644
  ...result,
2732
- data: result.data.map((group) => ({
2645
+ data: result.data.map(group => ({
2733
2646
  ...group,
2734
- ranges: group.ranges.map((rangeGroup) => ({
2647
+ ranges: group.ranges.map(rangeGroup => ({
2735
2648
  ...rangeGroup,
2736
2649
  range: {
2737
2650
  ...rangeGroup.range,
@@ -2749,65 +2662,55 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2749
2662
  };
2750
2663
  }
2751
2664
  releaseAvailabilityContext(contextId) {
2752
- var _a;
2753
2665
  const context = this.availabilityContextRegistry.get(contextId);
2754
- if (!context)
2755
- return;
2666
+ if (!context) return;
2756
2667
  this.removeAvailabilityContext(contextId);
2757
2668
  void this.emitAvailabilityDiagnostic({
2758
- action: "release",
2669
+ action: 'release',
2759
2670
  contextId,
2760
2671
  contextVersion: context.activeVersion,
2761
- projection: ((_a = this.getActiveAvailabilityProjectionEntry(context)) == null ? void 0 : _a.projection) || null,
2672
+ projection: this.getActiveAvailabilityProjectionEntry(context)?.projection || null,
2762
2673
  snapshotId: context.lastSnapshotId,
2763
2674
  orderRevision: context.lastKnownOrderRevision,
2764
- reason: "explicit_release"
2675
+ reason: 'explicit_release'
2765
2676
  });
2766
2677
  }
2767
2678
  assertAvailabilityCommitWriteCAS(params) {
2768
2679
  const context = this.availabilityContextRegistry.get(params.contextId);
2769
2680
  if (!context) {
2770
- throw this.createAvailabilityFacadeError(
2771
- "AVAILABILITY_CONTEXT_NOT_FOUND",
2772
- "availability context 不存在或已失效,请重新 prepare",
2773
- { contextId: params.contextId }
2774
- );
2681
+ throw this.createAvailabilityFacadeError('AVAILABILITY_CONTEXT_NOT_FOUND', 'availability context 不存在或已失效,请重新 prepare', {
2682
+ contextId: params.contextId
2683
+ });
2775
2684
  }
2776
2685
  if (this.availabilityLifecycleGeneration !== params.expectedLifecycleGeneration || context.lifecycleGeneration !== params.expectedLifecycleGeneration || context.activeVersion !== params.expectedVersion || context.refreshNonce !== params.expectedRefreshNonce || this.getCurrentOrderRevision() !== params.expectedOrderRevision) {
2777
- throw this.createAvailabilityFacadeError(
2778
- "AVAILABILITY_SELECTION_STALE",
2779
- "availability context 已变化,当前选择已失效,请重新获取候选",
2780
- {
2781
- contextId: params.contextId,
2782
- expectedVersion: params.expectedVersion,
2783
- currentVersion: context.activeVersion,
2784
- expectedRefreshNonce: params.expectedRefreshNonce,
2785
- currentRefreshNonce: context.refreshNonce,
2786
- expectedLifecycleGeneration: params.expectedLifecycleGeneration,
2787
- currentLifecycleGeneration: this.availabilityLifecycleGeneration,
2788
- expectedOrderRevision: params.expectedOrderRevision,
2789
- currentOrderRevision: this.getCurrentOrderRevision()
2790
- }
2791
- );
2686
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', 'availability context 已变化,当前选择已失效,请重新获取候选', {
2687
+ contextId: params.contextId,
2688
+ expectedVersion: params.expectedVersion,
2689
+ currentVersion: context.activeVersion,
2690
+ expectedRefreshNonce: params.expectedRefreshNonce,
2691
+ currentRefreshNonce: context.refreshNonce,
2692
+ expectedLifecycleGeneration: params.expectedLifecycleGeneration,
2693
+ currentLifecycleGeneration: this.availabilityLifecycleGeneration,
2694
+ expectedOrderRevision: params.expectedOrderRevision,
2695
+ currentOrderRevision: this.getCurrentOrderRevision()
2696
+ });
2792
2697
  }
2793
2698
  return context;
2794
2699
  }
2795
2700
  findProductLineByUid(productLineUid) {
2796
- var _a;
2797
- return (((_a = this.getTempOrder()) == null ? void 0 : _a.products) || []).find((product) => getProductLineUid(product) === String(productLineUid));
2701
+ return (this.getTempOrder()?.products || []).find(product => getProductLineUid(product) === String(productLineUid));
2798
2702
  }
2799
2703
  findLinkedBooking(product) {
2800
- var _a, _b;
2801
2704
  const productUid = getProductLineUid(product);
2802
- const bookingUid = String(product.booking_uid ?? ((_a = product.metadata) == null ? void 0 : _a.booking_uid) ?? "");
2803
- return (((_b = this.getTempOrder()) == null ? void 0 : _b.bookings) || []).find((booking) => bookingUid && getBookingUid(booking) === bookingUid || productUid && String(booking.product_uid ?? "") === productUid);
2705
+ const bookingUid = String(product.booking_uid ?? product.metadata?.booking_uid ?? '');
2706
+ return (this.getTempOrder()?.bookings || []).find(booking => bookingUid && getBookingUid(booking) === bookingUid || productUid && String(booking.product_uid ?? '') === productUid);
2804
2707
  }
2708
+
2805
2709
  /** Revalidates against the latest landed occupancy cache, then mutates exactly one product line. */
2806
2710
  async commitAvailabilitySelection(contextId, params) {
2807
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2808
- const normalizedContextId = String(contextId || "").trim();
2711
+ const normalizedContextId = String(contextId || '').trim();
2809
2712
  if (!normalizedContextId) {
2810
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "commitAvailabilitySelection 缺少 contextId", {
2713
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', 'commitAvailabilitySelection 缺少 contextId', {
2811
2714
  candidate: params.candidate
2812
2715
  });
2813
2716
  }
@@ -2815,25 +2718,25 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2815
2718
  try {
2816
2719
  const bookingCount = Number(params.bookingCount ?? 1);
2817
2720
  if (!Number.isInteger(bookingCount) || bookingCount <= 0) {
2818
- throw new import_ResourcePlanner.AvailabilityError("INVALID_RESERVATION_QUANTITY", "bookingCount 必须是正整数", {
2721
+ throw new _ResourcePlanner.AvailabilityError('INVALID_RESERVATION_QUANTITY', 'bookingCount 必须是正整数', {
2819
2722
  bookingCount: params.bookingCount
2820
2723
  });
2821
2724
  }
2822
- if (params.mode === "edit" && bookingCount !== 1) {
2823
- throw new import_ResourcePlanner.AvailabilityError("INVALID_RESERVATION_QUANTITY", "编辑预约商品时 bookingCount 必须为 1", {
2725
+ if (params.mode === 'edit' && bookingCount !== 1) {
2726
+ throw new _ResourcePlanner.AvailabilityError('INVALID_RESERVATION_QUANTITY', '编辑预约商品时 bookingCount 必须为 1', {
2824
2727
  bookingCount
2825
2728
  });
2826
2729
  }
2827
- const orderProductQuantity = ((_a = params.orderProduct) == null ? void 0 : _a.num) ?? ((_b = params.orderProduct) == null ? void 0 : _b.quantity) ?? ((_d = (_c = params.orderProduct) == null ? void 0 : _c._extend) == null ? void 0 : _d.quantity);
2828
- if (orderProductQuantity !== void 0 && orderProductQuantity !== null && Number(orderProductQuantity) !== bookingCount) {
2829
- throw new import_ResourcePlanner.AvailabilityError("INVALID_RESERVATION_QUANTITY", "orderProduct 数量与 bookingCount 不一致", {
2730
+ const orderProductQuantity = params.orderProduct?.num ?? params.orderProduct?.quantity ?? params.orderProduct?._extend?.quantity;
2731
+ if (orderProductQuantity !== undefined && orderProductQuantity !== null && Number(orderProductQuantity) !== bookingCount) {
2732
+ throw new _ResourcePlanner.AvailabilityError('INVALID_RESERVATION_QUANTITY', 'orderProduct 数量与 bookingCount 不一致', {
2830
2733
  bookingCount,
2831
2734
  orderProductQuantity
2832
2735
  });
2833
2736
  }
2834
2737
  const partySize = Number(params.partySize);
2835
2738
  if (!Number.isInteger(partySize) || partySize <= 0) {
2836
- throw new import_ResourcePlanner.AvailabilityError("INVALID_RESERVATION_QUANTITY", "partySize 必须是正整数", {
2739
+ throw new _ResourcePlanner.AvailabilityError('INVALID_RESERVATION_QUANTITY', 'partySize 必须是正整数', {
2837
2740
  partySize: params.partySize
2838
2741
  });
2839
2742
  }
@@ -2841,104 +2744,77 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2841
2744
  context,
2842
2745
  projectionEntry,
2843
2746
  refreshed
2844
- } = await this.ensureAvailabilityContextProjection(
2845
- normalizedContextId,
2846
- "commit_precheck"
2847
- );
2747
+ } = await this.ensureAvailabilityContextProjection(normalizedContextId, 'commit_precheck');
2848
2748
  if (refreshed) {
2849
- throw this.createAvailabilityFacadeError(
2850
- "AVAILABILITY_SELECTION_STALE",
2851
- "availability context 已刷新,请重新获取候选",
2852
- {
2853
- contextId: normalizedContextId,
2854
- currentContextVersion: context.activeVersion,
2855
- candidateContextVersion: params.candidate.availabilityContextVersion
2856
- }
2857
- );
2749
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', 'availability context 已刷新,请重新获取候选', {
2750
+ contextId: normalizedContextId,
2751
+ currentContextVersion: context.activeVersion,
2752
+ candidateContextVersion: params.candidate.availabilityContextVersion
2753
+ });
2858
2754
  }
2859
2755
  const boundEditingUids = context.prepareParams.editingProductLineUids || [];
2860
- if (params.mode === "edit") {
2756
+ if (params.mode === 'edit') {
2861
2757
  if (!params.productLineUid || !boundEditingUids.includes(String(params.productLineUid))) {
2862
- throw this.createAvailabilityFacadeError(
2863
- "AVAILABILITY_SELECTION_STALE",
2864
- "edit context 与当前商品行不匹配,请重新 prepare 编辑上下文",
2865
- {
2866
- contextId: normalizedContextId,
2867
- productLineUid: params.productLineUid,
2868
- editingProductLineUids: boundEditingUids
2869
- }
2870
- );
2871
- }
2872
- } else if (boundEditingUids.length > 0) {
2873
- throw this.createAvailabilityFacadeError(
2874
- "AVAILABILITY_SELECTION_STALE",
2875
- "edit context 不能用于 add,请重新 prepare 新增上下文",
2876
- {
2758
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', 'edit context 与当前商品行不匹配,请重新 prepare 编辑上下文', {
2877
2759
  contextId: normalizedContextId,
2760
+ productLineUid: params.productLineUid,
2878
2761
  editingProductLineUids: boundEditingUids
2879
- }
2880
- );
2762
+ });
2763
+ }
2764
+ } else if (boundEditingUids.length > 0) {
2765
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', 'edit context 不能用于 add,请重新 prepare 新增上下文', {
2766
+ contextId: normalizedContextId,
2767
+ editingProductLineUids: boundEditingUids
2768
+ });
2881
2769
  }
2882
2770
  if (projectionEntry.contextVersion !== context.activeVersion) {
2883
- throw this.createAvailabilityFacadeError(
2884
- "AVAILABILITY_SELECTION_STALE",
2885
- "availability context 已刷新,请重新获取候选",
2886
- {
2887
- contextId: normalizedContextId,
2888
- currentContextVersion: context.activeVersion,
2889
- projectionContextVersion: projectionEntry.contextVersion
2890
- }
2891
- );
2771
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', 'availability context 已刷新,请重新获取候选', {
2772
+ contextId: normalizedContextId,
2773
+ currentContextVersion: context.activeVersion,
2774
+ projectionContextVersion: projectionEntry.contextVersion
2775
+ });
2892
2776
  }
2893
2777
  if (projectionEntry.orderRevision !== this.getCurrentOrderRevision()) {
2894
- throw this.createAvailabilityFacadeError(
2895
- "AVAILABILITY_SELECTION_STALE",
2896
- "购物车已变化,请重新获取候选",
2897
- {
2898
- contextId: normalizedContextId,
2899
- currentContextVersion: context.activeVersion,
2900
- projectionOrderRevision: projectionEntry.orderRevision,
2901
- currentOrderRevision: this.getCurrentOrderRevision()
2902
- }
2903
- );
2778
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', '购物车已变化,请重新获取候选', {
2779
+ contextId: normalizedContextId,
2780
+ currentContextVersion: context.activeVersion,
2781
+ projectionOrderRevision: projectionEntry.orderRevision,
2782
+ currentOrderRevision: this.getCurrentOrderRevision()
2783
+ });
2904
2784
  }
2905
2785
  if (projectionEntry.contextVersion !== params.candidate.availabilityContextVersion) {
2906
- throw this.createAvailabilityFacadeError(
2907
- "AVAILABILITY_SELECTION_STALE",
2908
- "候选已过期,请重新获取最新时间段",
2909
- {
2910
- contextId: normalizedContextId,
2911
- candidateContextVersion: params.candidate.availabilityContextVersion,
2912
- currentContextVersion: context.activeVersion
2913
- }
2914
- );
2786
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', '候选已过期,请重新获取最新时间段', {
2787
+ contextId: normalizedContextId,
2788
+ candidateContextVersion: params.candidate.availabilityContextVersion,
2789
+ currentContextVersion: context.activeVersion
2790
+ });
2915
2791
  }
2916
2792
  this.assertAvailabilityCandidateFreshness(context, params.candidate);
2917
- const orderProductId = ((_e = params.orderProduct) == null ? void 0 : _e.product_id) ?? ((_f = params.orderProduct) == null ? void 0 : _f.id);
2793
+ const orderProductId = params.orderProduct?.product_id ?? params.orderProduct?.id;
2918
2794
  if (!sameAvailabilityId(orderProductId, params.candidate.productId)) {
2919
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "orderProduct 与 candidate 商品不一致", {
2795
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', 'orderProduct 与 candidate 商品不一致', {
2920
2796
  orderProductId,
2921
2797
  candidateProductId: params.candidate.productId
2922
2798
  });
2923
2799
  }
2924
- if (params.mode === "edit" && !params.productLineUid) {
2925
- throw new import_ResourcePlanner.AvailabilityError("PRODUCT_LINE_NOT_FOUND", "edit 模式必须提供 productLineUid");
2800
+ if (params.mode === 'edit' && !params.productLineUid) {
2801
+ throw new _ResourcePlanner.AvailabilityError('PRODUCT_LINE_NOT_FOUND', 'edit 模式必须提供 productLineUid');
2926
2802
  }
2927
- const editingLine = params.mode === "edit" ? this.findProductLineByUid(String(params.productLineUid)) : void 0;
2928
- if (params.mode === "edit" && !editingLine) {
2929
- throw new import_ResourcePlanner.AvailabilityError("PRODUCT_LINE_NOT_FOUND", "找不到要编辑的预约商品行", {
2803
+ const editingLine = params.mode === 'edit' ? this.findProductLineByUid(String(params.productLineUid)) : undefined;
2804
+ if (params.mode === 'edit' && !editingLine) {
2805
+ throw new _ResourcePlanner.AvailabilityError('PRODUCT_LINE_NOT_FOUND', '找不到要编辑的预约商品行', {
2930
2806
  productLineUid: params.productLineUid
2931
2807
  });
2932
2808
  }
2933
2809
  if (editingLine && !sameAvailabilityId(editingLine.product_id ?? editingLine.id, params.candidate.productId)) {
2934
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "编辑商品行与 candidate 商品不一致", {
2810
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', '编辑商品行与 candidate 商品不一致', {
2935
2811
  productLineUid: params.productLineUid,
2936
2812
  productLineProductId: editingLine.product_id ?? editingLine.id,
2937
2813
  candidateProductId: params.candidate.productId
2938
2814
  });
2939
2815
  }
2940
2816
  if (!Array.isArray(params.requirementSelections)) {
2941
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "requirementSelections 必须是数组", {
2817
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', 'requirementSelections 必须是数组', {
2942
2818
  requirementSelections: params.requirementSelections
2943
2819
  });
2944
2820
  }
@@ -2948,82 +2824,75 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
2948
2824
  expectedVersion: context.activeVersion,
2949
2825
  expectedRefreshNonce: context.refreshNonce,
2950
2826
  expectedLifecycleGeneration: this.availabilityLifecycleGeneration,
2951
- expectedOrderRevision: String(baseProjection.meta.orderRevision ?? "")
2827
+ expectedOrderRevision: String(baseProjection.meta.orderRevision ?? '')
2952
2828
  };
2953
2829
  const prepareParams = baseProjection.meta.prepareParams;
2954
2830
  if (!prepareParams) {
2955
- throw new import_ResourcePlanner.AvailabilityError("REVALIDATION_FAILED", "projection 缺少 prepareParams,无法执行缓存重校验");
2831
+ throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', 'projection 缺少 prepareParams,无法执行缓存重校验');
2956
2832
  }
2957
2833
  const fallbackResources = {
2958
- resources: (0, import_lodash_es.cloneDeep)([...baseProjection.resources || []]),
2959
- resourceOccupancies: (0, import_lodash_es.cloneDeep)(
2960
- [...baseProjection.resourceOccupancies || []].filter((occupancy) => occupancy.source !== "cart")
2961
- ),
2834
+ resources: (0, _lodashEs.cloneDeep)([...(baseProjection.resources || [])]),
2835
+ resourceOccupancies: (0, _lodashEs.cloneDeep)([...(baseProjection.resourceOccupancies || [])].filter(occupancy => occupancy.source !== 'cart')),
2962
2836
  includesInjectedRawOccupancies: true
2963
2837
  };
2964
2838
  const commitSnapshot = await this.buildAvailabilityProjectionSnapshot({
2965
2839
  ...this.cloneAvailabilityPrepareParams(prepareParams),
2966
- editingProductLineUids: params.mode === "edit" && params.productLineUid ? [params.productLineUid] : []
2840
+ editingProductLineUids: params.mode === 'edit' && params.productLineUid ? [params.productLineUid] : []
2967
2841
  }, {
2968
- resourceFetchPolicy: "cache_only",
2842
+ resourceFetchPolicy: 'cache_only',
2969
2843
  fallbackResources,
2970
2844
  durationCandidateAnchorAt: this.getAvailabilityDurationCandidateAnchorAt(baseProjection) || context.durationCandidateAnchorAt
2971
2845
  });
2972
2846
  const refreshedProjection = commitSnapshot.projection;
2973
- if (String(refreshedProjection.meta.orderRevision ?? "") !== String(baseProjection.meta.orderRevision ?? "")) {
2847
+ if (String(refreshedProjection.meta.orderRevision ?? '') !== String(baseProjection.meta.orderRevision ?? '')) {
2974
2848
  await this.refreshAvailabilityContextProjection({
2975
2849
  contextId: normalizedContextId,
2976
- reason: "commit_order_revision_changed",
2977
- previousOrderRevision: String(baseProjection.meta.orderRevision ?? "")
2850
+ reason: 'commit_order_revision_changed',
2851
+ previousOrderRevision: String(baseProjection.meta.orderRevision ?? '')
2978
2852
  });
2979
2853
  const latestContext = this.getAvailabilityContextEntry(normalizedContextId);
2980
- throw this.createAvailabilityFacadeError(
2981
- "AVAILABILITY_SELECTION_STALE",
2982
- "最终缓存重校验期间购物车已变化,请重新获取候选",
2983
- {
2984
- contextId: normalizedContextId,
2985
- candidateContextVersion: params.candidate.availabilityContextVersion,
2986
- currentContextVersion: latestContext.activeVersion,
2987
- projectionOrderRevision: baseProjection.meta.orderRevision,
2988
- refreshedOrderRevision: refreshedProjection.meta.orderRevision,
2989
- snapshotId: baseProjection.meta.snapshotId,
2990
- refreshedSnapshotId: refreshedProjection.meta.snapshotId
2991
- }
2992
- );
2854
+ throw this.createAvailabilityFacadeError('AVAILABILITY_SELECTION_STALE', '最终缓存重校验期间购物车已变化,请重新获取候选', {
2855
+ contextId: normalizedContextId,
2856
+ candidateContextVersion: params.candidate.availabilityContextVersion,
2857
+ currentContextVersion: latestContext.activeVersion,
2858
+ projectionOrderRevision: baseProjection.meta.orderRevision,
2859
+ refreshedOrderRevision: refreshedProjection.meta.orderRevision,
2860
+ snapshotId: baseProjection.meta.snapshotId,
2861
+ refreshedSnapshotId: refreshedProjection.meta.snapshotId
2862
+ });
2993
2863
  }
2994
2864
  this.assertAvailabilityCommitWriteCAS(commitWriteGuard);
2995
- const refreshedRanges = (0, import_ResourcePlanner.getProductTimeRanges)(refreshedProjection, {
2865
+ const refreshedRanges = (0, _ResourcePlanner.getProductTimeRanges)(refreshedProjection, {
2996
2866
  productIds: [params.candidate.productId],
2997
2867
  dateRange: {
2998
2868
  startDate: params.candidate.startAt.slice(0, 10),
2999
2869
  endDate: params.candidate.startAt.slice(0, 10)
3000
2870
  }
3001
- }).flatMap((group) => group.ranges);
3002
- const refreshedCandidateBase = refreshedRanges.find((candidate) => candidate.startAt === params.candidate.startAt && candidate.endAt === params.candidate.endAt && candidate.bookingStartAt === params.candidate.bookingStartAt && candidate.bookingEndAt === params.candidate.bookingEndAt);
2871
+ }).flatMap(group => group.ranges);
2872
+ const refreshedCandidateBase = refreshedRanges.find(candidate => candidate.startAt === params.candidate.startAt && candidate.endAt === params.candidate.endAt && candidate.bookingStartAt === params.candidate.bookingStartAt && candidate.bookingEndAt === params.candidate.bookingEndAt);
3003
2873
  if (!refreshedCandidateBase) {
3004
- throw new import_ResourcePlanner.AvailabilityError("REVALIDATION_FAILED", "缓存重校验后候选时间已不在商品配置中", {
2874
+ throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', '缓存重校验后候选时间已不在商品配置中', {
3005
2875
  contextId: normalizedContextId,
3006
2876
  candidate: params.candidate,
3007
2877
  refreshedSnapshotId: refreshedProjection.meta.snapshotId
3008
2878
  });
3009
2879
  }
3010
- const validation = (0, import_ResourcePlanner.validateAvailabilitySelection)(refreshedProjection, {
2880
+ const validation = (0, _ResourcePlanner.validateAvailabilitySelection)(refreshedProjection, {
3011
2881
  candidate: refreshedCandidateBase,
3012
2882
  requirementSelections: params.requirementSelections,
3013
2883
  partySize,
3014
2884
  bookingCount
3015
2885
  });
3016
2886
  if (!validation.ok) {
3017
- const capacityConflict = validation.conflicts.find((conflict) => conflict.code === "resource_capacity_exceeded");
3018
- throw new import_ResourcePlanner.AvailabilityError(
3019
- "REVALIDATION_FAILED",
3020
- (capacityConflict == null ? void 0 : capacityConflict.message) || "缓存重校验后资源已不可提交",
3021
- {
3022
- validation,
3023
- refreshedSnapshotId: refreshedProjection.meta.snapshotId
3024
- }
3025
- );
2887
+ const capacityConflict = validation.conflicts.find(conflict => conflict.code === 'resource_capacity_exceeded');
2888
+ throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', capacityConflict?.message || '缓存重校验后资源已不可提交', {
2889
+ validation,
2890
+ refreshedSnapshotId: refreshedProjection.meta.snapshotId
2891
+ });
3026
2892
  }
2893
+ // Revalidation failure must leave the caller's candidate reusable. Only publish the
2894
+ // refreshed projection/version after candidate and resource validation has passed;
2895
+ // otherwise a second Confirm from the still-open modal would incorrectly become stale.
3027
2896
  const revalidationEntry = this.storeAvailabilityProjectionEntry({
3028
2897
  contextId: normalizedContextId,
3029
2898
  prepareParams: commitSnapshot.prepareParams,
@@ -3034,14 +2903,14 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
3034
2903
  });
3035
2904
  const revalidatedContext = this.getAvailabilityContextEntry(normalizedContextId);
3036
2905
  await this.emitAvailabilityDiagnostic({
3037
- action: "refresh",
2906
+ action: 'refresh',
3038
2907
  contextId: normalizedContextId,
3039
2908
  contextVersion: revalidatedContext.activeVersion,
3040
2909
  projection: refreshedProjection,
3041
2910
  snapshotId: revalidationEntry.snapshotId,
3042
2911
  orderRevision: revalidationEntry.orderRevision,
3043
2912
  previousOrderRevision: baseProjection.meta.orderRevision,
3044
- reason: "commit_cached_occupancy_revalidation"
2913
+ reason: 'commit_cached_occupancy_revalidation'
3045
2914
  });
3046
2915
  commitWriteGuard = {
3047
2916
  contextId: normalizedContextId,
@@ -3050,21 +2919,17 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
3050
2919
  expectedLifecycleGeneration: this.availabilityLifecycleGeneration,
3051
2920
  expectedOrderRevision: revalidationEntry.orderRevision
3052
2921
  };
3053
- const refreshedCandidate = this.decorateAvailabilityCandidate(
3054
- normalizedContextId,
3055
- revalidatedContext.activeVersion,
3056
- refreshedCandidateBase
3057
- );
3058
- const product = refreshedProjection.products.find((item) => sameAvailabilityId(item.id, refreshedCandidate.productId));
2922
+ const refreshedCandidate = this.decorateAvailabilityCandidate(normalizedContextId, revalidatedContext.activeVersion, refreshedCandidateBase);
2923
+ const product = refreshedProjection.products.find(item => sameAvailabilityId(item.id, refreshedCandidate.productId));
3059
2924
  if (!product) {
3060
- throw new import_ResourcePlanner.AvailabilityError("REVALIDATION_FAILED", "缓存重校验后商品不在 projection 中", {
2925
+ throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', '缓存重校验后商品不在 projection 中', {
3061
2926
  productId: refreshedCandidate.productId
3062
2927
  });
3063
2928
  }
3064
- const existingBooking = editingLine ? this.findLinkedBooking(editingLine) : void 0;
3065
- const existingBookingUid = existingBooking ? getBookingUid(existingBooking) : "";
3066
- if (params.mode === "edit" && !existingBookingUid) {
3067
- throw new import_ResourcePlanner.AvailabilityError("PRODUCT_LINE_NOT_FOUND", "编辑商品行缺少关联 booking", {
2929
+ const existingBooking = editingLine ? this.findLinkedBooking(editingLine) : undefined;
2930
+ const existingBookingUid = existingBooking ? getBookingUid(existingBooking) : '';
2931
+ if (params.mode === 'edit' && !existingBookingUid) {
2932
+ throw new _ResourcePlanner.AvailabilityError('PRODUCT_LINE_NOT_FOUND', '编辑商品行缺少关联 booking', {
3068
2933
  productLineUid: params.productLineUid
3069
2934
  });
3070
2935
  }
@@ -3074,37 +2939,37 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
3074
2939
  candidate: refreshedCandidate,
3075
2940
  product,
3076
2941
  resources: refreshedProjection.resources,
3077
- bookingUid: existingBookingUid || void 0
2942
+ bookingUid: existingBookingUid || undefined
3078
2943
  });
3079
2944
  const transformed = this.buildUnifiedOrderProduct({
3080
2945
  ...params.orderProduct,
3081
2946
  num: bookingCount,
3082
2947
  quantity: bookingCount
3083
- }, "unified_booking_sales", product);
2948
+ }, 'unified_booking_sales', product);
3084
2949
  if (!transformed) {
3085
- throw new import_ResourcePlanner.AvailabilityError("INVALID_TARGET_FILTER", "orderProduct 无法转换为订单行", {
2950
+ throw new _ResourcePlanner.AvailabilityError('INVALID_TARGET_FILTER', 'orderProduct 无法转换为订单行', {
3086
2951
  orderProduct: params.orderProduct
3087
2952
  });
3088
2953
  }
3089
2954
  transformed.num = bookingCount;
3090
2955
  transformed.metadata = {
3091
- ...transformed.metadata || {},
2956
+ ...(transformed.metadata || {}),
3092
2957
  unified_booking_sales: true,
3093
2958
  availability_candidate_key: refreshedCandidate.key,
3094
2959
  availability_context_id: normalizedContextId,
3095
2960
  availability_context_version: refreshedCandidate.availabilityContextVersion
3096
2961
  };
3097
- let productLineUid = "";
3098
- let bookingUid = "";
2962
+ let productLineUid = '';
2963
+ let bookingUid = '';
3099
2964
  let productLineUids = [];
3100
2965
  let bookingUids = [];
3101
- if (params.mode === "edit" && editingLine && params.productLineUid) {
2966
+ if (params.mode === 'edit' && editingLine && params.productLineUid) {
3102
2967
  transformed.product_sku = transformed.product_sku ?? editingLine.product_sku;
3103
2968
  transformed.product_bundle = transformed.product_bundle ?? editingLine.product_bundle;
3104
2969
  transformed.booking_uid = existingBookingUid;
3105
2970
  transformed.metadata = {
3106
- ...editingLine.metadata || {},
3107
- ...transformed.metadata || {},
2971
+ ...(editingLine.metadata || {}),
2972
+ ...(transformed.metadata || {}),
3108
2973
  unique_identification_number: params.productLineUid,
3109
2974
  booking_uid: existingBookingUid
3110
2975
  };
@@ -3120,33 +2985,18 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
3120
2985
  productLineUids = [productLineUid];
3121
2986
  bookingUids = [bookingUid];
3122
2987
  } else {
3123
- const beforeProductLineUids = new Set(
3124
- (((_g = this.getTempOrder()) == null ? void 0 : _g.products) || []).map((line) => getProductLineUid(line)).filter(Boolean)
3125
- );
3126
- const beforeBookingUids = new Set(
3127
- (((_h = this.getTempOrder()) == null ? void 0 : _h.bookings) || []).map((item) => getBookingUid(item)).filter(Boolean)
3128
- );
2988
+ const beforeProductLineUids = new Set((this.getTempOrder()?.products || []).map(line => getProductLineUid(line)).filter(Boolean));
2989
+ const beforeBookingUids = new Set((this.getTempOrder()?.bookings || []).map(item => getBookingUid(item)).filter(Boolean));
3129
2990
  const products = await this.addProductToOrder(transformed, booking);
3130
- const addedLines = products.filter((line) => {
3131
- var _a2;
3132
- return sameAvailabilityId(line.product_id ?? line.id, refreshedCandidate.productId) && ((_a2 = line.metadata) == null ? void 0 : _a2.availability_candidate_key) === refreshedCandidate.key && !beforeProductLineUids.has(getProductLineUid(line));
3133
- });
3134
- productLineUids = addedLines.map((line) => getProductLineUid(line)).filter(Boolean);
3135
- const addedBookings = (((_i = this.getTempOrder()) == null ? void 0 : _i.bookings) || []).filter((item) => {
3136
- var _a2;
3137
- return ((_a2 = item.metadata) == null ? void 0 : _a2.availability_candidate_key) === refreshedCandidate.key && !beforeBookingUids.has(getBookingUid(item));
3138
- });
3139
- bookingUids = addedBookings.map((item) => getBookingUid(item)).filter(Boolean);
2991
+ const addedLines = products.filter(line => sameAvailabilityId(line.product_id ?? line.id, refreshedCandidate.productId) && line.metadata?.availability_candidate_key === refreshedCandidate.key && !beforeProductLineUids.has(getProductLineUid(line)));
2992
+ productLineUids = addedLines.map(line => getProductLineUid(line)).filter(Boolean);
2993
+ const addedBookings = (this.getTempOrder()?.bookings || []).filter(item => item.metadata?.availability_candidate_key === refreshedCandidate.key && !beforeBookingUids.has(getBookingUid(item)));
2994
+ bookingUids = addedBookings.map(item => getBookingUid(item)).filter(Boolean);
3140
2995
  if (bookingUids.length === 0) {
3141
- bookingUids = addedLines.map((line) => {
3142
- var _a2;
3143
- return String(
3144
- line.booking_uid ?? ((_a2 = line.metadata) == null ? void 0 : _a2.booking_uid) ?? ""
3145
- );
3146
- }).filter(Boolean);
2996
+ bookingUids = addedLines.map(line => String(line.booking_uid ?? line.metadata?.booking_uid ?? '')).filter(Boolean);
3147
2997
  }
3148
- productLineUid = productLineUids[productLineUids.length - 1] || "";
3149
- bookingUid = bookingUids[bookingUids.length - 1] || "";
2998
+ productLineUid = productLineUids[productLineUids.length - 1] || '';
2999
+ bookingUid = bookingUids[bookingUids.length - 1] || '';
3150
3000
  }
3151
3001
  this.invalidateAvailabilityContextsAfterCommit();
3152
3002
  const nextContext = this.getAvailabilityContextEntry(normalizedContextId);
@@ -3161,28 +3011,12 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
3161
3011
  productLineUids,
3162
3012
  bookingUids
3163
3013
  };
3164
- await this.core.effects.emit(
3165
- `${this.name}:${import_types.UnifiedBookingSalesHooks.onAvailabilitySelectionCommitted}`,
3166
- result
3167
- );
3014
+ await this.core.effects.emit(`${this.name}:${_types.UnifiedBookingSalesHooks.onAvailabilitySelectionCommitted}`, result);
3168
3015
  return result;
3169
3016
  } finally {
3170
3017
  await this.releaseAvailabilityCommitLock(normalizedContextId);
3171
3018
  }
3172
3019
  }
3173
- };
3174
- var UnifiedBookingSales = UnifiedBookingSalesImpl;
3175
- // Annotate the CommonJS export names for ESM import in node:
3176
- 0 && (module.exports = {
3177
- AvailabilityError,
3178
- UnifiedBookingSales,
3179
- UnifiedBookingSalesImpl,
3180
- buildAvailabilityLineIdentity,
3181
- buildAvailabilityResourcesFromV2,
3182
- buildBookingFromAvailabilityAssignment,
3183
- buildBookingFromAvailabilityAssignments,
3184
- buildPlannerDiscountResult,
3185
- collectAvailabilityResourceIds,
3186
- normalizeProductForAvailability,
3187
- ...require("./types")
3188
- });
3020
+ }
3021
+ exports.UnifiedBookingSalesImpl = UnifiedBookingSalesImpl;
3022
+ const UnifiedBookingSales = exports.UnifiedBookingSales = UnifiedBookingSalesImpl;