@pisell/pisellos 2.3.39 → 2.3.41

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 (226) hide show
  1. package/dist/core/index.d.ts +2 -0
  2. package/dist/core/index.js +7 -0
  3. package/dist/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  4. package/dist/model/strategy/adapter/promotion/adapter.js +23 -0
  5. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  6. package/dist/model/strategy/adapter/promotion/evaluator.js +279 -6
  7. package/dist/model/strategy/adapter/promotion/examples.d.ts +86 -0
  8. package/dist/model/strategy/adapter/promotion/examples.js +99 -0
  9. package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
  10. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  11. package/dist/model/strategy/adapter/promotion/type.d.ts +90 -2
  12. package/dist/model/strategy/adapter/promotion/type.js +45 -0
  13. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -3
  14. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +6 -3
  15. package/dist/modules/Discount/index.d.ts +0 -1
  16. package/dist/modules/Discount/index.js +11 -40
  17. package/dist/modules/Discount/types.d.ts +0 -1
  18. package/dist/modules/OpenData/index.d.ts +2 -0
  19. package/dist/modules/OpenData/index.js +10 -2
  20. package/dist/modules/Order/index.d.ts +29 -12
  21. package/dist/modules/Order/index.js +750 -509
  22. package/dist/modules/Order/payment-utils.d.ts +26 -0
  23. package/dist/modules/Order/payment-utils.js +225 -0
  24. package/dist/modules/Order/types.d.ts +33 -10
  25. package/dist/modules/Order/utils/orderCollectionIdentity.js +7 -2
  26. package/dist/modules/Order/utils.d.ts +0 -10
  27. package/dist/modules/Order/utils.js +13 -41
  28. package/dist/modules/Payment/index.d.ts +2 -0
  29. package/dist/modules/Payment/index.js +79 -50
  30. package/dist/modules/Payment/types.d.ts +99 -28
  31. package/dist/modules/Payment/types.js +20 -3
  32. package/dist/modules/Payment/walletpass.d.ts +25 -1
  33. package/dist/modules/Payment/walletpass.js +707 -157
  34. package/dist/modules/Product/types.d.ts +0 -1
  35. package/dist/modules/ProductList/index.js +14 -33
  36. package/dist/modules/Quotation/index.d.ts +1 -1
  37. package/dist/modules/Quotation/index.js +2 -2
  38. package/dist/modules/Rules/index.d.ts +1 -0
  39. package/dist/modules/Rules/index.js +89 -96
  40. package/dist/modules/SalesSummary/index.js +13 -12
  41. package/dist/modules/ScanOrderLogger/index.d.ts +0 -2
  42. package/dist/modules/ScanOrderLogger/index.js +2 -15
  43. package/dist/modules/ScanOrderLogger/providers/feishu.js +27 -45
  44. package/dist/modules/ScanOrderLogger/types.d.ts +0 -1
  45. package/dist/modules/Schedule/index.d.ts +1 -3
  46. package/dist/modules/Schedule/index.js +16 -21
  47. package/dist/modules/Summary/utils.js +13 -38
  48. package/dist/modules/index.d.ts +0 -2
  49. package/dist/modules/index.js +1 -3
  50. package/dist/plugins/window.d.ts +0 -1
  51. package/dist/server/index.d.ts +16 -14
  52. package/dist/server/index.js +1925 -1143
  53. package/dist/server/modules/order/index.d.ts +54 -4
  54. package/dist/server/modules/order/index.js +1600 -700
  55. package/dist/server/modules/order/types.d.ts +11 -3
  56. package/dist/server/modules/order/types.js +1 -1
  57. package/dist/solution/BaseSales/index.d.ts +109 -20
  58. package/dist/solution/BaseSales/index.js +1800 -480
  59. package/dist/solution/BaseSales/types.d.ts +52 -0
  60. package/dist/solution/BaseSales/types.js +2 -1
  61. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  62. package/dist/solution/BaseSales/utils/cartPromotion.js +90 -31
  63. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  64. package/dist/solution/BookingByStep/index.d.ts +2 -17
  65. package/dist/solution/BookingByStep/index.js +215 -294
  66. package/dist/solution/BookingByStep/types.d.ts +1 -2
  67. package/dist/solution/BookingByStep/types.js +1 -3
  68. package/dist/solution/BookingByStep/utils/capacity.js +1 -17
  69. package/dist/solution/BookingByStep/utils/timeslots.d.ts +1 -3
  70. package/dist/solution/BookingByStep/utils/timeslots.js +12 -19
  71. package/dist/solution/BookingTicket/index.d.ts +7 -3
  72. package/dist/solution/BookingTicket/index.js +132 -49
  73. package/dist/solution/BookingTicket/utils/addProductDecision.js +6 -0
  74. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  75. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +172 -82
  76. package/dist/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  77. package/dist/solution/BookingTicket/utils/weighingProductSku.js +45 -0
  78. package/dist/solution/Sales/index.d.ts +1 -0
  79. package/dist/solution/Sales/index.js +10 -2
  80. package/dist/solution/ScanOrder/index.d.ts +14 -26
  81. package/dist/solution/ScanOrder/index.js +756 -1148
  82. package/dist/solution/ScanOrder/types.d.ts +1 -21
  83. package/dist/solution/ScanOrder/utils.d.ts +0 -8
  84. package/dist/solution/ScanOrder/utils.js +25 -66
  85. package/dist/solution/ShopDiscount/index.d.ts +0 -1
  86. package/dist/solution/ShopDiscount/index.js +87 -125
  87. package/dist/solution/VenueBooking/index.d.ts +11 -39
  88. package/dist/solution/VenueBooking/index.js +860 -1176
  89. package/dist/solution/VenueBooking/types.d.ts +0 -3
  90. package/dist/solution/VenueBooking/utils/resource.js +0 -1
  91. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  92. package/dist/solution/VenueBooking/utils/slotMerge.js +5 -10
  93. package/dist/solution/index.d.ts +0 -1
  94. package/dist/solution/index.js +1 -2
  95. package/dist/types/index.d.ts +1 -1
  96. package/dist/utils/payment-number.d.ts +9 -0
  97. package/dist/utils/payment-number.js +69 -0
  98. package/lib/core/index.d.ts +2 -0
  99. package/lib/core/index.js +4 -0
  100. package/lib/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  101. package/lib/model/strategy/adapter/promotion/adapter.js +20 -0
  102. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  103. package/lib/model/strategy/adapter/promotion/evaluator.js +235 -0
  104. package/lib/model/strategy/adapter/promotion/examples.d.ts +86 -0
  105. package/lib/model/strategy/adapter/promotion/examples.js +91 -0
  106. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  107. package/lib/model/strategy/adapter/promotion/index.js +51 -0
  108. package/lib/model/strategy/adapter/promotion/type.d.ts +90 -2
  109. package/lib/model/strategy/adapter/promotion/type.js +2 -0
  110. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +2 -1
  111. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  112. package/lib/modules/Discount/index.d.ts +0 -1
  113. package/lib/modules/Discount/index.js +0 -9
  114. package/lib/modules/Discount/types.d.ts +0 -1
  115. package/lib/modules/OpenData/index.d.ts +2 -0
  116. package/lib/modules/OpenData/index.js +6 -1
  117. package/lib/modules/Order/index.d.ts +29 -12
  118. package/lib/modules/Order/index.js +196 -86
  119. package/lib/modules/Order/payment-utils.d.ts +26 -0
  120. package/lib/modules/Order/payment-utils.js +224 -0
  121. package/lib/modules/Order/types.d.ts +33 -10
  122. package/lib/modules/Order/utils/orderCollectionIdentity.js +3 -0
  123. package/lib/modules/Order/utils.d.ts +0 -10
  124. package/lib/modules/Order/utils.js +16 -40
  125. package/lib/modules/Payment/index.d.ts +2 -0
  126. package/lib/modules/Payment/index.js +34 -13
  127. package/lib/modules/Payment/types.d.ts +99 -28
  128. package/lib/modules/Payment/types.js +4 -3
  129. package/lib/modules/Payment/walletpass.d.ts +25 -1
  130. package/lib/modules/Payment/walletpass.js +470 -21
  131. package/lib/modules/Product/types.d.ts +0 -1
  132. package/lib/modules/ProductList/index.js +31 -40
  133. package/lib/modules/Quotation/index.d.ts +1 -1
  134. package/lib/modules/Quotation/index.js +2 -2
  135. package/lib/modules/Rules/index.d.ts +1 -0
  136. package/lib/modules/Rules/index.js +47 -40
  137. package/lib/modules/SalesSummary/index.js +7 -6
  138. package/lib/modules/ScanOrderLogger/index.d.ts +0 -2
  139. package/lib/modules/ScanOrderLogger/index.js +1 -13
  140. package/lib/modules/ScanOrderLogger/providers/feishu.js +6 -15
  141. package/lib/modules/ScanOrderLogger/types.d.ts +0 -1
  142. package/lib/modules/Schedule/index.d.ts +1 -3
  143. package/lib/modules/Schedule/index.js +8 -10
  144. package/lib/modules/Summary/utils.js +1 -21
  145. package/lib/modules/index.d.ts +0 -2
  146. package/lib/modules/index.js +1 -5
  147. package/lib/plugins/window.d.ts +0 -1
  148. package/lib/server/index.d.ts +16 -14
  149. package/lib/server/index.js +675 -83
  150. package/lib/server/modules/order/index.d.ts +54 -4
  151. package/lib/server/modules/order/index.js +679 -66
  152. package/lib/server/modules/order/types.d.ts +11 -3
  153. package/lib/solution/BaseSales/index.d.ts +109 -20
  154. package/lib/solution/BaseSales/index.js +883 -70
  155. package/lib/solution/BaseSales/types.d.ts +52 -0
  156. package/lib/solution/BaseSales/types.js +2 -1
  157. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  158. package/lib/solution/BaseSales/utils/cartPromotion.js +63 -12
  159. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  160. package/lib/solution/BookingByStep/index.d.ts +2 -17
  161. package/lib/solution/BookingByStep/index.js +18 -60
  162. package/lib/solution/BookingByStep/types.d.ts +1 -2
  163. package/lib/solution/BookingByStep/types.js +0 -5
  164. package/lib/solution/BookingByStep/utils/capacity.js +1 -20
  165. package/lib/solution/BookingByStep/utils/timeslots.d.ts +1 -3
  166. package/lib/solution/BookingByStep/utils/timeslots.js +11 -19
  167. package/lib/solution/BookingTicket/index.d.ts +7 -3
  168. package/lib/solution/BookingTicket/index.js +62 -9
  169. package/lib/solution/BookingTicket/utils/addProductDecision.js +4 -0
  170. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  171. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +36 -4
  172. package/lib/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  173. package/lib/solution/BookingTicket/utils/weighingProductSku.js +63 -0
  174. package/lib/solution/Sales/index.d.ts +1 -0
  175. package/lib/solution/Sales/index.js +5 -3
  176. package/lib/solution/ScanOrder/index.d.ts +14 -26
  177. package/lib/solution/ScanOrder/index.js +190 -449
  178. package/lib/solution/ScanOrder/types.d.ts +1 -21
  179. package/lib/solution/ScanOrder/utils.d.ts +0 -8
  180. package/lib/solution/ScanOrder/utils.js +0 -31
  181. package/lib/solution/ShopDiscount/index.d.ts +0 -1
  182. package/lib/solution/ShopDiscount/index.js +0 -14
  183. package/lib/solution/VenueBooking/index.d.ts +11 -39
  184. package/lib/solution/VenueBooking/index.js +123 -328
  185. package/lib/solution/VenueBooking/types.d.ts +0 -3
  186. package/lib/solution/VenueBooking/utils/resource.js +0 -1
  187. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  188. package/lib/solution/VenueBooking/utils/slotMerge.js +4 -6
  189. package/lib/solution/index.d.ts +0 -1
  190. package/lib/solution/index.js +1 -3
  191. package/lib/types/index.d.ts +1 -1
  192. package/lib/utils/payment-number.d.ts +9 -0
  193. package/lib/utils/payment-number.js +64 -0
  194. package/package.json +1 -1
  195. package/dist/modules/Holder/index.d.ts +0 -48
  196. package/dist/modules/Holder/index.js +0 -640
  197. package/dist/modules/Holder/types.d.ts +0 -123
  198. package/dist/modules/Holder/types.js +0 -1
  199. package/dist/modules/Holder/utils.d.ts +0 -13
  200. package/dist/modules/Holder/utils.js +0 -34
  201. package/dist/modules/ResourcePlanner/index.d.ts +0 -24
  202. package/dist/modules/ResourcePlanner/index.js +0 -181
  203. package/dist/modules/ResourcePlanner/planner.d.ts +0 -14
  204. package/dist/modules/ResourcePlanner/planner.js +0 -1069
  205. package/dist/modules/ResourcePlanner/types.d.ts +0 -227
  206. package/dist/modules/ResourcePlanner/types.js +0 -1
  207. package/dist/solution/UnifiedBookingSales/index.d.ts +0 -183
  208. package/dist/solution/UnifiedBookingSales/index.js +0 -1871
  209. package/dist/solution/UnifiedBookingSales/types.d.ts +0 -143
  210. package/dist/solution/UnifiedBookingSales/types.js +0 -11
  211. package/lib/modules/Holder/index.d.ts +0 -48
  212. package/lib/modules/Holder/index.js +0 -402
  213. package/lib/modules/Holder/types.d.ts +0 -123
  214. package/lib/modules/Holder/types.js +0 -17
  215. package/lib/modules/Holder/utils.d.ts +0 -13
  216. package/lib/modules/Holder/utils.js +0 -71
  217. package/lib/modules/ResourcePlanner/index.d.ts +0 -24
  218. package/lib/modules/ResourcePlanner/index.js +0 -148
  219. package/lib/modules/ResourcePlanner/planner.d.ts +0 -14
  220. package/lib/modules/ResourcePlanner/planner.js +0 -933
  221. package/lib/modules/ResourcePlanner/types.d.ts +0 -227
  222. package/lib/modules/ResourcePlanner/types.js +0 -17
  223. package/lib/solution/UnifiedBookingSales/index.d.ts +0 -183
  224. package/lib/solution/UnifiedBookingSales/index.js +0 -1076
  225. package/lib/solution/UnifiedBookingSales/types.d.ts +0 -143
  226. package/lib/solution/UnifiedBookingSales/types.js +0 -33
@@ -1,1069 +0,0 @@
1
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
5
- function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
7
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
8
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
9
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
10
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
11
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
12
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
13
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
14
- import dayjs from 'dayjs';
15
- export var DEFAULT_RESOURCE_PLANNER_CONTEXT = {
16
- products: [],
17
- resources: [],
18
- externalEvents: [],
19
- slotDurationMinutes: 30,
20
- businessStartTime: '09:00',
21
- businessEndTime: '18:00'
22
- };
23
- export var DEFAULT_RESOURCE_PLANNER_SELECTION = {
24
- productIds: [],
25
- resourceIds: [],
26
- assignments: []
27
- };
28
- export function normalizePlannerContext() {
29
- var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
30
- return {
31
- products: Array.isArray(input.products) ? input.products : [],
32
- resources: Array.isArray(input.resources) ? input.resources : [],
33
- externalEvents: Array.isArray(input.externalEvents) ? input.externalEvents : [],
34
- slotDurationMinutes: input.slotDurationMinutes || DEFAULT_RESOURCE_PLANNER_CONTEXT.slotDurationMinutes,
35
- businessStartTime: input.businessStartTime || DEFAULT_RESOURCE_PLANNER_CONTEXT.businessStartTime,
36
- businessEndTime: input.businessEndTime || DEFAULT_RESOURCE_PLANNER_CONTEXT.businessEndTime
37
- };
38
- }
39
- function sameId(left, right) {
40
- return String(left) === String(right);
41
- }
42
- function dateOf(value) {
43
- return dayjs(value).format('YYYY-MM-DD');
44
- }
45
- function timeOf(value) {
46
- return dayjs(value).format('HH:mm');
47
- }
48
- function toDateTime(date, time) {
49
- if (/^\d{4}-\d{2}-\d{2}/.test(time)) return dayjs(time);
50
- return dayjs("".concat(date, " ").concat(time.length === 5 ? "".concat(time, ":00") : time));
51
- }
52
- function overlaps(startA, endA, startB, endB) {
53
- return startA.isBefore(endB) && endA.isAfter(startB);
54
- }
55
- function containsRange(outerStart, outerEnd, innerStart, innerEnd) {
56
- return !innerStart.isBefore(outerStart) && !innerEnd.isAfter(outerEnd);
57
- }
58
- function maxDayjs(left, right) {
59
- return left.isAfter(right) ? left : right;
60
- }
61
- function minDayjs(left, right) {
62
- return left.isBefore(right) ? left : right;
63
- }
64
- function addDays(start, end) {
65
- var result = [];
66
- var cursor = dayjs(start);
67
- var finalDay = dayjs(end);
68
- while (!cursor.isAfter(finalDay, 'day')) {
69
- result.push(cursor.format('YYYY-MM-DD'));
70
- cursor = cursor.add(1, 'day');
71
- }
72
- return result;
73
- }
74
- function getQueryProducts(products, query) {
75
- var _query$productIds;
76
- if (!((_query$productIds = query.productIds) !== null && _query$productIds !== void 0 && _query$productIds.length)) return products;
77
- return products.filter(function (product) {
78
- return query.productIds.some(function (id) {
79
- return sameId(id, product.id);
80
- });
81
- });
82
- }
83
- function getQueryResources(resources, query) {
84
- var _query$resourceIds;
85
- if (!((_query$resourceIds = query.resourceIds) !== null && _query$resourceIds !== void 0 && _query$resourceIds.length)) return resources;
86
- return resources.filter(function (resource) {
87
- return query.resourceIds.some(function (id) {
88
- return sameId(id, resource.id);
89
- });
90
- });
91
- }
92
- function matchesResourceRequirement(resource, requirement) {
93
- var _requirement$resource;
94
- var isFormlessCandidate = resource.formId == null;
95
- var formMatches = requirement.formId == null || isFormlessCandidate || sameId(requirement.formId, resource.formId);
96
- var resourceMatches = !((_requirement$resource = requirement.resourceIds) !== null && _requirement$resource !== void 0 && _requirement$resource.length) || isFormlessCandidate || requirement.resourceIds.some(function (id) {
97
- return sameId(id, resource.id);
98
- });
99
- return formMatches && resourceMatches;
100
- }
101
- function resolveProductTitle(product) {
102
- var _product$raw, _product$raw2, _product$raw3;
103
- var rawTitle = ((_product$raw = product.raw) === null || _product$raw === void 0 ? void 0 : _product$raw.title) || ((_product$raw2 = product.raw) === null || _product$raw2 === void 0 ? void 0 : _product$raw2.name) || ((_product$raw3 = product.raw) === null || _product$raw3 === void 0 ? void 0 : _product$raw3.product_title);
104
- if (typeof product.title === 'string') return product.title;
105
- if (typeof rawTitle === 'string') return rawTitle;
106
- if (rawTitle && _typeof(rawTitle) === 'object') {
107
- return rawTitle.en || rawTitle.zh || rawTitle.default || Object.values(rawTitle)[0];
108
- }
109
- return undefined;
110
- }
111
- export function buildDemandIntervals(products, query, context) {
112
- var dates = query.date ? [query.date] : query.dateRange ? addDays(query.dateRange.start, query.dateRange.end) : [];
113
- var selectedProducts = getQueryProducts(products, query);
114
- var intervals = [];
115
- var _iterator = _createForOfIteratorHelper(selectedProducts),
116
- _step;
117
- try {
118
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
119
- var product = _step.value;
120
- var quantity = Math.max(1, Number(product.quantity || 1));
121
- var capacityRequired = Math.max(1, Number(query.pax || product.capacityRequired || 1));
122
- var requirements = product.resourceRequirements || [];
123
- if (product.kind === 'session' || product.kind === 'venue_slot') {
124
- var schedules = product.schedule || [];
125
- var _iterator2 = _createForOfIteratorHelper(schedules),
126
- _step2;
127
- try {
128
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
129
- var schedule = _step2.value;
130
- var scheduleDate = dateOf(schedule.start_at);
131
- if (dates.length > 0 && !dates.includes(scheduleDate)) continue;
132
- var start = dayjs(schedule.start_at);
133
- var end = dayjs(schedule.end_at);
134
- intervals.push({
135
- id: "".concat(product.id, ":").concat(start.toISOString(), ":").concat(end.toISOString()),
136
- productId: product.id,
137
- source: product.kind,
138
- date: dateOf(schedule.start_at),
139
- start_at: start.toISOString(),
140
- end_at: end.toISOString(),
141
- durationMinutes: Math.max(1, end.diff(start, 'minute')),
142
- quantity: quantity,
143
- capacityRequired: capacityRequired,
144
- resourceRequirements: requirements
145
- });
146
- }
147
- } catch (err) {
148
- _iterator2.e(err);
149
- } finally {
150
- _iterator2.f();
151
- }
152
- continue;
153
- }
154
- if (product.kind === 'duration') {
155
- var duration = Math.max(1, Number(product.durationMinutes || 30));
156
- var _iterator3 = _createForOfIteratorHelper(dates),
157
- _step3;
158
- try {
159
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
160
- var currentDate = _step3.value;
161
- var _start = query.startTime ? toDateTime(currentDate, query.startTime) : toDateTime(currentDate, (context === null || context === void 0 ? void 0 : context.businessStartTime) || DEFAULT_RESOURCE_PLANNER_CONTEXT.businessStartTime);
162
- var _end = query.startTime && query.endTime ? toDateTime(currentDate, query.endTime) : query.startTime ? _start.add(duration, 'minute') : toDateTime(currentDate, (context === null || context === void 0 ? void 0 : context.businessEndTime) || DEFAULT_RESOURCE_PLANNER_CONTEXT.businessEndTime);
163
- if (!_end.isAfter(_start)) _end = _end.add(1, 'day');
164
- intervals.push({
165
- id: "".concat(product.id, ":").concat(currentDate, ":").concat(query.startTime || 'range'),
166
- productId: product.id,
167
- source: 'duration',
168
- date: currentDate,
169
- start_at: _start.toISOString(),
170
- end_at: _end.toISOString(),
171
- durationMinutes: duration,
172
- quantity: quantity,
173
- capacityRequired: capacityRequired,
174
- resourceRequirements: requirements
175
- });
176
- }
177
- } catch (err) {
178
- _iterator3.e(err);
179
- } finally {
180
- _iterator3.f();
181
- }
182
- }
183
- }
184
- } catch (err) {
185
- _iterator.e(err);
186
- } finally {
187
- _iterator.f();
188
- }
189
- return intervals;
190
- }
191
- function getEventsForResource(resource, contextEvents) {
192
- var embeddedEvents = resource.times.flatMap(function (time) {
193
- return time.event_list || [];
194
- });
195
- return [].concat(_toConsumableArray(embeddedEvents), _toConsumableArray(contextEvents.filter(function (event) {
196
- var _event$resourceId;
197
- return sameId((_event$resourceId = event.resourceId) !== null && _event$resourceId !== void 0 ? _event$resourceId : event.resource_id, resource.id);
198
- }))).filter(Boolean);
199
- }
200
- function collectEventsByResource(resources, contextEvents) {
201
- var eventsByResource = new Map();
202
- resources.forEach(function (resource) {
203
- eventsByResource.set(String(resource.id), getEventsForResource(resource, contextEvents));
204
- });
205
- return eventsByResource;
206
- }
207
- function getWorkingSegmentsForInterval(resource, interval) {
208
- var intervalStart = dayjs(interval.start_at);
209
- var intervalEnd = dayjs(interval.end_at);
210
- return resource.times.map(function (time) {
211
- var start = maxDayjs(dayjs(time.start_at), intervalStart);
212
- var end = minDayjs(dayjs(time.end_at), intervalEnd);
213
- return {
214
- start: start,
215
- end: end
216
- };
217
- }).filter(function (segment) {
218
- return segment.end.isAfter(segment.start);
219
- });
220
- }
221
- function mergeBusySegments(segments) {
222
- var sorted = _toConsumableArray(segments).filter(function (segment) {
223
- return segment.end.isAfter(segment.start);
224
- }).sort(function (left, right) {
225
- return left.start.valueOf() - right.start.valueOf();
226
- });
227
- var merged = [];
228
- sorted.forEach(function (segment) {
229
- var previous = merged[merged.length - 1];
230
- if (previous && !segment.start.isAfter(previous.end)) {
231
- previous.end = maxDayjs(previous.end, segment.end);
232
- } else {
233
- merged.push(_objectSpread({}, segment));
234
- }
235
- });
236
- return merged;
237
- }
238
- function subtractBusyIntervals(workingSegments, events) {
239
- var available = [];
240
- workingSegments.forEach(function (working) {
241
- var busySegments = mergeBusySegments(events.filter(function (event) {
242
- return overlaps(working.start, working.end, dayjs(event.start_at), dayjs(event.end_at));
243
- }).map(function (event) {
244
- return {
245
- start: maxDayjs(dayjs(event.start_at), working.start),
246
- end: minDayjs(dayjs(event.end_at), working.end)
247
- };
248
- }));
249
- var cursor = working.start;
250
- busySegments.forEach(function (busy) {
251
- if (busy.start.isAfter(cursor)) {
252
- available.push({
253
- start: cursor,
254
- end: busy.start
255
- });
256
- }
257
- if (busy.end.isAfter(cursor)) cursor = busy.end;
258
- });
259
- if (working.end.isAfter(cursor)) {
260
- available.push({
261
- start: cursor,
262
- end: working.end
263
- });
264
- }
265
- });
266
- return available;
267
- }
268
- function buildCapacityRanges(params) {
269
- var workingSegments = params.workingSegments,
270
- events = params.events,
271
- maxCapacity = params.maxCapacity,
272
- requiredCapacity = params.requiredCapacity;
273
- var ranges = [];
274
- workingSegments.forEach(function (working) {
275
- var boundaries = new Map([[working.start.valueOf(), working.start], [working.end.valueOf(), working.end]]);
276
- events.forEach(function (event) {
277
- var eventStart = dayjs(event.start_at);
278
- var eventEnd = dayjs(event.end_at);
279
- if (!overlaps(working.start, working.end, eventStart, eventEnd)) return;
280
- var clippedStart = maxDayjs(eventStart, working.start);
281
- var clippedEnd = minDayjs(eventEnd, working.end);
282
- boundaries.set(clippedStart.valueOf(), clippedStart);
283
- boundaries.set(clippedEnd.valueOf(), clippedEnd);
284
- });
285
- var points = Array.from(boundaries.values()).sort(function (left, right) {
286
- return left.valueOf() - right.valueOf();
287
- });
288
- var _loop = function _loop() {
289
- var start = points[index];
290
- var end = points[index + 1];
291
- if (!end.isAfter(start)) return 0; // continue
292
- var usedCapacity = events.filter(function (event) {
293
- return overlaps(start, end, dayjs(event.start_at), dayjs(event.end_at));
294
- }).reduce(function (sum, event) {
295
- return sum + Math.max(1, Number(event.pax || 1));
296
- }, 0);
297
- var remainingCapacity = Math.max(0, maxCapacity - usedCapacity);
298
- if (remainingCapacity < requiredCapacity) return 0; // continue
299
- var status = remainingCapacity < maxCapacity ? 'limited' : 'available';
300
- var previous = ranges[ranges.length - 1];
301
- if (previous && previous.end.isSame(start) && previous.remainingCapacity === remainingCapacity && previous.maxCapacity === maxCapacity && previous.status === status) {
302
- previous.end = end;
303
- } else {
304
- ranges.push({
305
- start: start,
306
- end: end,
307
- remainingCapacity: remainingCapacity,
308
- maxCapacity: maxCapacity,
309
- status: status
310
- });
311
- }
312
- },
313
- _ret;
314
- for (var index = 0; index < points.length - 1; index += 1) {
315
- _ret = _loop();
316
- if (_ret === 0) continue;
317
- }
318
- });
319
- return ranges;
320
- }
321
- function rangeFitsDuration(segment, durationMinutes) {
322
- return segment.end.diff(segment.start, 'minute') >= durationMinutes;
323
- }
324
- function makeAvailabilityRangeCell(params) {
325
- var _segment$remainingCap;
326
- var interval = params.interval,
327
- resource = params.resource,
328
- segment = params.segment;
329
- var maxCapacity = Math.max(1, Number(segment.maxCapacity || resource.capacity || 1));
330
- var remainingCapacity = resource.resourceType === 'single' ? 1 : Math.max(0, Number((_segment$remainingCap = segment.remainingCapacity) !== null && _segment$remainingCap !== void 0 ? _segment$remainingCap : maxCapacity));
331
- var status = resource.resourceType === 'single' ? 'available' : segment.status || (remainingCapacity < maxCapacity ? 'limited' : 'available');
332
- return {
333
- key: "".concat(interval.productId, ":").concat(resource.id, ":").concat(segment.start.toISOString(), ":").concat(segment.end.toISOString()),
334
- productId: interval.productId,
335
- resourceId: resource.id,
336
- date: interval.date,
337
- start_at: segment.start.toISOString(),
338
- end_at: segment.end.toISOString(),
339
- startTime: segment.start.format('HH:mm'),
340
- endTime: segment.end.format('HH:mm'),
341
- durationMinutes: interval.durationMinutes,
342
- cellType: 'availability_range',
343
- status: status,
344
- remainingCapacity: remainingCapacity,
345
- maxCapacity: maxCapacity,
346
- reasonCodes: [],
347
- conflicts: []
348
- };
349
- }
350
- function buildAvailabilityCellsForResource(params) {
351
- var resource = params.resource,
352
- interval = params.interval,
353
- events = params.events;
354
- var requiredCapacity = Math.max(1, Number(interval.capacityRequired || 1));
355
- var durationMinutes = Math.max(1, Number(interval.durationMinutes || 1));
356
- var maxCapacity = Math.max(1, Number(resource.capacity || 1));
357
- var workingSegments = getWorkingSegmentsForInterval(resource, interval);
358
- var now = dayjs();
359
- workingSegments = workingSegments.map(function (segment) {
360
- return {
361
- start: segment.end.isAfter(now) ? maxDayjs(segment.start, now) : segment.start,
362
- end: segment.end
363
- };
364
- }).filter(function (segment) {
365
- return segment.end.isAfter(segment.start);
366
- });
367
- var availableSegments = resource.resourceType === 'single' ? subtractBusyIntervals(workingSegments, events).map(function (segment) {
368
- return _objectSpread(_objectSpread({}, segment), {}, {
369
- remainingCapacity: 1,
370
- maxCapacity: 1,
371
- status: 'available'
372
- });
373
- }) : buildCapacityRanges({
374
- workingSegments: workingSegments,
375
- events: events,
376
- maxCapacity: maxCapacity,
377
- requiredCapacity: requiredCapacity
378
- });
379
- return availableSegments.filter(function (segment) {
380
- return rangeFitsDuration(segment, durationMinutes);
381
- }).map(function (segment) {
382
- return makeAvailabilityRangeCell({
383
- interval: interval,
384
- resource: resource,
385
- segment: segment
386
- });
387
- });
388
- }
389
- export function evaluateResourceForInterval(params) {
390
- var resource = params.resource,
391
- interval = params.interval,
392
- context = params.context;
393
- var start = dayjs(interval.start_at);
394
- var end = dayjs(interval.end_at);
395
- var conflicts = [];
396
- var reasonCodes = [];
397
- var maxCapacity = Math.max(1, Number(resource.capacity || 1));
398
- var requiredCapacity = Math.max(1, Number(interval.capacityRequired || 1));
399
- if (start.isBefore(dayjs())) {
400
- reasonCodes.push('past');
401
- conflicts.push({
402
- type: 'past',
403
- message: '时间已过期',
404
- resourceId: resource.id,
405
- productId: interval.productId
406
- });
407
- }
408
- var insideResourceTime = resource.times.some(function (time) {
409
- return containsRange(dayjs(time.start_at), dayjs(time.end_at), start, end);
410
- });
411
- if (!insideResourceTime) {
412
- reasonCodes.push('outside_resource_time');
413
- conflicts.push({
414
- type: 'outside_resource_time',
415
- message: '所选时间不在资源可用时间内',
416
- resourceId: resource.id,
417
- productId: interval.productId
418
- });
419
- }
420
- var events = getEventsForResource(resource, context.externalEvents);
421
- var overlapping = events.filter(function (event) {
422
- return overlaps(start, end, dayjs(event.start_at), dayjs(event.end_at));
423
- });
424
- var usedCapacity = resource.resourceType === 'single' ? overlapping.length : overlapping.reduce(function (sum, event) {
425
- return sum + Math.max(1, Number(event.pax || 1));
426
- }, 0);
427
- var remainingCapacity = resource.resourceType === 'single' ? overlapping.length > 0 ? 0 : 1 : Math.max(0, maxCapacity - usedCapacity);
428
- if (overlapping.length > 0 && resource.resourceType === 'single') {
429
- reasonCodes.push('remote_event_overlap');
430
- conflicts.push.apply(conflicts, _toConsumableArray(overlapping.map(function (event) {
431
- return {
432
- type: 'remote_event_overlap',
433
- message: '资源时间被已有预约占用',
434
- event: event,
435
- resourceId: resource.id,
436
- productId: interval.productId
437
- };
438
- })));
439
- }
440
- if (resource.resourceType !== 'single' && remainingCapacity < requiredCapacity) {
441
- reasonCodes.push('capacity_full');
442
- conflicts.push({
443
- type: 'capacity_full',
444
- message: '资源剩余容量不足',
445
- resourceId: resource.id,
446
- productId: interval.productId
447
- });
448
- }
449
- var status = 'available';
450
- if (reasonCodes.includes('past')) status = 'past';else if (reasonCodes.includes('outside_resource_time')) status = 'unavailable';else if (reasonCodes.includes('remote_event_overlap') || reasonCodes.includes('capacity_full')) {
451
- status = 'full';
452
- } else if (remainingCapacity < maxCapacity) {
453
- status = 'limited';
454
- }
455
- return {
456
- key: "".concat(interval.productId, ":").concat(resource.id, ":").concat(interval.start_at, ":").concat(interval.end_at),
457
- productId: interval.productId,
458
- resourceId: resource.id,
459
- date: interval.date,
460
- start_at: interval.start_at,
461
- end_at: interval.end_at,
462
- startTime: timeOf(interval.start_at),
463
- endTime: timeOf(interval.end_at),
464
- durationMinutes: interval.durationMinutes,
465
- cellType: status === 'available' || status === 'limited' ? 'fixed_interval' : 'unavailable',
466
- status: status,
467
- remainingCapacity: remainingCapacity,
468
- maxCapacity: maxCapacity,
469
- reasonCodes: reasonCodes,
470
- conflicts: conflicts
471
- };
472
- }
473
- function aggregateStatus(cells) {
474
- if (!cells.length) return 'unavailable';
475
- if (cells.some(function (cell) {
476
- return cell.status === 'available';
477
- })) return 'available';
478
- if (cells.some(function (cell) {
479
- return cell.status === 'limited';
480
- })) return 'limited';
481
- if (cells.some(function (cell) {
482
- return cell.status === 'past';
483
- })) return 'past';
484
- if (cells.some(function (cell) {
485
- return cell.status === 'full';
486
- })) return 'full';
487
- if (cells.some(function (cell) {
488
- return cell.status === 'conflict';
489
- })) return 'conflict';
490
- return 'unavailable';
491
- }
492
- function uniqueReasonCodes(cells) {
493
- return Array.from(new Set(cells.flatMap(function (cell) {
494
- return cell.reasonCodes || [];
495
- })));
496
- }
497
- function buildProductOptions(products, cells, query) {
498
- var queryProducts = getQueryProducts(products, query);
499
- return queryProducts.map(function (product) {
500
- var productCells = cells.filter(function (cell) {
501
- return sameId(cell.productId, product.id);
502
- });
503
- var status = product.kind === 'normal' ? 'available' : aggregateStatus(productCells);
504
- return {
505
- productId: product.id,
506
- title: resolveProductTitle(product),
507
- status: status,
508
- reasonCodes: uniqueReasonCodes(productCells)
509
- };
510
- });
511
- }
512
- function buildResourceOptions(resources, cells, query) {
513
- var queryResources = getQueryResources(resources, query);
514
- return queryResources.map(function (resource) {
515
- var resourceCells = cells.filter(function (cell) {
516
- return cell.resourceId !== undefined && sameId(cell.resourceId, resource.id);
517
- });
518
- var bestCell = resourceCells.find(function (cell) {
519
- return cell.status === 'available';
520
- }) || resourceCells.find(function (cell) {
521
- return cell.status === 'limited';
522
- }) || resourceCells[0];
523
- return {
524
- resourceId: resource.id,
525
- resourceName: resource.name,
526
- resourceFormId: resource.formId,
527
- resourceType: resource.resourceType,
528
- status: resourceCells.length ? aggregateStatus(resourceCells) : 'unavailable',
529
- remainingCapacity: bestCell === null || bestCell === void 0 ? void 0 : bestCell.remainingCapacity,
530
- maxCapacity: (bestCell === null || bestCell === void 0 ? void 0 : bestCell.maxCapacity) || resource.capacity,
531
- reasonCodes: uniqueReasonCodes(resourceCells)
532
- };
533
- });
534
- }
535
- function buildDateSummary(cells, query) {
536
- var dates = query.date ? [query.date] : query.dateRange ? addDays(query.dateRange.start, query.dateRange.end) : Array.from(new Set(cells.map(function (cell) {
537
- return cell.date;
538
- }).filter(Boolean)));
539
- return dates.map(function (date) {
540
- var dateCells = cells.filter(function (cell) {
541
- return cell.date === date;
542
- });
543
- var availableCount = dateCells.filter(function (cell) {
544
- return cell.status === 'available' || cell.status === 'limited';
545
- }).length;
546
- return {
547
- date: date,
548
- status: dateCells.length ? aggregateStatus(dateCells) : 'unavailable',
549
- availableCount: availableCount,
550
- totalCount: dateCells.length
551
- };
552
- });
553
- }
554
- function buildTimeLabels(date, context, query) {
555
- if (!date) return [];
556
- var slotMinutes = query.slotDurationMinutes || context.slotDurationMinutes;
557
- var labels = [];
558
- var cursor = toDateTime(date, context.businessStartTime);
559
- var end = toDateTime(date, context.businessEndTime);
560
- if (!end.isAfter(cursor)) end = end.add(1, 'day');
561
- while (cursor.isBefore(end)) {
562
- labels.push(cursor.format('HH:mm'));
563
- cursor = cursor.add(slotMinutes, 'minute');
564
- }
565
- return labels;
566
- }
567
- function buildGridSlotInterval(product, date, label, context, query) {
568
- var slotMinutes = product.kind === 'duration' ? Math.max(1, Number(product.durationMinutes || query.slotDurationMinutes || context.slotDurationMinutes)) : query.slotDurationMinutes || context.slotDurationMinutes;
569
- var start = toDateTime(date, label);
570
- var end = start.add(slotMinutes, 'minute');
571
- return {
572
- id: "".concat(product.id, ":").concat(date, ":").concat(label),
573
- productId: product.id,
574
- source: product.kind === 'session' ? 'session' : product.kind === 'venue_slot' ? 'venue_slot' : 'duration',
575
- date: date,
576
- start_at: start.toISOString(),
577
- end_at: end.toISOString(),
578
- durationMinutes: slotMinutes,
579
- quantity: Math.max(1, Number(product.quantity || 1)),
580
- capacityRequired: Math.max(1, Number(query.pax || product.capacityRequired || 1)),
581
- resourceRequirements: product.resourceRequirements || []
582
- };
583
- }
584
- function buildTimeGrid(context, query, cells) {
585
- var _query$dateRange;
586
- var date = query.date || ((_query$dateRange = query.dateRange) === null || _query$dateRange === void 0 ? void 0 : _query$dateRange.start);
587
- var products = getQueryProducts(context.products, query).filter(function (product) {
588
- return product.kind !== 'normal';
589
- });
590
- var resources = getQueryResources(context.resources, query);
591
- var timeLabels = buildTimeLabels(date, context, query);
592
- if (!date || !products.length || !resources.length) {
593
- return {
594
- date: date,
595
- timeLabels: timeLabels,
596
- resources: []
597
- };
598
- }
599
- var rows = resources.map(function (resource) {
600
- var slots = timeLabels.map(function (label) {
601
- var product = products[0];
602
- var interval = buildGridSlotInterval(product, date, label, context, query);
603
- var start = dayjs(interval.start_at);
604
- var end = dayjs(interval.end_at);
605
- var cell = cells.find(function (item) {
606
- return sameId(item.productId, product.id) && sameId(item.resourceId, resource.id) && item.date === date && (item.status === 'available' || item.status === 'limited') && containsRange(dayjs(item.start_at), dayjs(item.end_at), start, end);
607
- });
608
- return {
609
- startTime: label,
610
- endTime: dayjs(interval.end_at).format('HH:mm'),
611
- status: (cell === null || cell === void 0 ? void 0 : cell.status) || 'unavailable',
612
- resourceId: resource.id,
613
- productId: product.id,
614
- remainingCapacity: cell === null || cell === void 0 ? void 0 : cell.remainingCapacity,
615
- maxCapacity: (cell === null || cell === void 0 ? void 0 : cell.maxCapacity) || resource.capacity,
616
- reasonCodes: (cell === null || cell === void 0 ? void 0 : cell.reasonCodes) || ['outside_available_range']
617
- };
618
- });
619
- return {
620
- resourceId: resource.id,
621
- resourceName: resource.name,
622
- resourceFormId: resource.formId,
623
- slots: slots
624
- };
625
- });
626
- return {
627
- date: date,
628
- timeLabels: timeLabels,
629
- resources: rows
630
- };
631
- }
632
- export function queryPlannerAvailability(contextInput) {
633
- var query = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
634
- var context = normalizePlannerContext(contextInput);
635
- var intervals = buildDemandIntervals(context.products, query, context);
636
- var resources = getQueryResources(context.resources, query);
637
- var eventsByResource = collectEventsByResource(resources, context.externalEvents);
638
- var cells = [];
639
- var _iterator4 = _createForOfIteratorHelper(intervals),
640
- _step4;
641
- try {
642
- var _loop2 = function _loop2() {
643
- var interval = _step4.value;
644
- var candidateResources = resources.filter(function (resource) {
645
- var requirements = interval.resourceRequirements || [];
646
- if (!requirements.length) return true;
647
- return requirements.some(function (requirement) {
648
- return matchesResourceRequirement(resource, requirement);
649
- });
650
- });
651
- if (!candidateResources.length) {
652
- cells.push({
653
- key: "".concat(interval.productId, ":missing-resource:").concat(interval.start_at),
654
- productId: interval.productId,
655
- date: interval.date,
656
- start_at: interval.start_at,
657
- end_at: interval.end_at,
658
- startTime: timeOf(interval.start_at),
659
- endTime: timeOf(interval.end_at),
660
- durationMinutes: interval.durationMinutes,
661
- cellType: 'unavailable',
662
- status: 'unavailable',
663
- reasonCodes: ['missing_resource'],
664
- conflicts: [{
665
- type: 'missing_resource',
666
- message: '没有匹配商品需求的资源',
667
- productId: interval.productId
668
- }]
669
- });
670
- return 1; // continue
671
- }
672
- candidateResources.forEach(function (resource) {
673
- if (interval.source === 'duration' && !query.startTime) {
674
- cells.push.apply(cells, _toConsumableArray(buildAvailabilityCellsForResource({
675
- resource: resource,
676
- interval: interval,
677
- events: eventsByResource.get(String(resource.id)) || []
678
- })));
679
- return;
680
- }
681
- cells.push(evaluateResourceForInterval({
682
- resource: resource,
683
- interval: interval,
684
- context: context
685
- }));
686
- });
687
- };
688
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
689
- if (_loop2()) continue;
690
- }
691
- } catch (err) {
692
- _iterator4.e(err);
693
- } finally {
694
- _iterator4.f();
695
- }
696
- return {
697
- query: query,
698
- demandIntervals: intervals,
699
- productOptions: buildProductOptions(context.products, cells, query),
700
- resourceOptions: buildResourceOptions(context.resources, cells, query),
701
- dateSummary: buildDateSummary(cells, query),
702
- timeGrid: buildTimeGrid(context, query, cells),
703
- cells: cells
704
- };
705
- }
706
- function getIntervalRequirements(interval) {
707
- return interval.resourceRequirements.length ? interval.resourceRequirements : [{
708
- capacityRequired: interval.capacityRequired,
709
- required: true
710
- }];
711
- }
712
- function buildAssignableCandidateGroups(params) {
713
- var interval = params.interval,
714
- cells = params.cells,
715
- resources = params.resources;
716
- var conflicts = [];
717
- var groups = getIntervalRequirements(interval).map(function (requirement) {
718
- var candidateCells = cells.filter(function (cell) {
719
- if (!sameId(cell.productId, interval.productId)) return false;
720
- if (cell.date !== interval.date) return false;
721
- if (cell.resourceId === undefined) return false;
722
- if (cell.status !== 'available' && cell.status !== 'limited') return false;
723
- var cellStart = dayjs(cell.start_at);
724
- var cellEnd = dayjs(cell.end_at);
725
- var intervalStart = dayjs(interval.start_at);
726
- var intervalEnd = dayjs(interval.end_at);
727
- return containsRange(cellStart, cellEnd, intervalStart, intervalEnd) || interval.source === 'duration';
728
- });
729
- return candidateCells.flatMap(function (cell) {
730
- var resource = resources.find(function (item) {
731
- return sameId(item.id, cell.resourceId);
732
- });
733
- if (!resource || !matchesResourceRequirement(resource, requirement)) return [];
734
- return [{
735
- requirement: requirement,
736
- resource: resource,
737
- cell: cell
738
- }];
739
- });
740
- });
741
- groups.forEach(function (group, index) {
742
- var _interval$resourceReq;
743
- if (group.length) return;
744
- conflicts.push({
745
- type: 'missing_resource',
746
- message: '没有匹配商品需求的可用资源',
747
- productId: interval.productId,
748
- resourceId: (_interval$resourceReq = interval.resourceRequirements[index]) === null || _interval$resourceReq === void 0 || (_interval$resourceReq = _interval$resourceReq.resourceIds) === null || _interval$resourceReq === void 0 ? void 0 : _interval$resourceReq[0]
749
- });
750
- });
751
- return {
752
- groups: groups,
753
- conflicts: conflicts
754
- };
755
- }
756
- function combineCandidateGroups(groups) {
757
- if (!groups.length || groups.some(function (group) {
758
- return group.length === 0;
759
- })) return [];
760
- return groups.reduce(function (combinations, group) {
761
- return combinations.flatMap(function (combination) {
762
- return group.map(function (candidate) {
763
- return [].concat(_toConsumableArray(combination), [candidate]);
764
- });
765
- });
766
- }, [[]]);
767
- }
768
- function buildSlotFromCandidates(params) {
769
- var interval = params.interval,
770
- candidates = params.candidates,
771
- start = params.start,
772
- end = params.end;
773
- if (!end.isAfter(start)) return null;
774
- var status = candidates.some(function (candidate) {
775
- return candidate.cell.status === 'limited';
776
- }) ? 'limited' : 'available';
777
- var assignments = candidates.map(function (candidate) {
778
- return {
779
- productId: interval.productId,
780
- resourceId: candidate.resource.id,
781
- start_at: start.toISOString(),
782
- end_at: end.toISOString(),
783
- capacityRequired: Math.max(1, Number(candidate.requirement.capacityRequired || interval.capacityRequired || 1))
784
- };
785
- });
786
- return {
787
- key: [interval.productId, start.toISOString(), end.toISOString()].concat(_toConsumableArray(candidates.map(function (candidate) {
788
- return candidate.resource.id;
789
- }))).join(':'),
790
- productId: interval.productId,
791
- date: interval.date,
792
- start_at: start.toISOString(),
793
- end_at: end.toISOString(),
794
- startTime: start.format('HH:mm'),
795
- endTime: end.format('HH:mm'),
796
- durationMinutes: Math.max(1, end.diff(start, 'minute')),
797
- status: status,
798
- resources: candidates.map(function (candidate) {
799
- return {
800
- resourceId: candidate.resource.id,
801
- resourceName: candidate.resource.name,
802
- resourceFormId: candidate.resource.formId,
803
- resourceType: candidate.resource.resourceType,
804
- capacityRequired: Math.max(1, Number(candidate.requirement.capacityRequired || interval.capacityRequired || 1)),
805
- remainingCapacity: candidate.cell.remainingCapacity,
806
- maxCapacity: candidate.cell.maxCapacity
807
- };
808
- }),
809
- assignments: assignments,
810
- conflicts: []
811
- };
812
- }
813
- function buildSlotsForInterval(params) {
814
- var interval = params.interval,
815
- candidates = params.candidates,
816
- query = params.query,
817
- context = params.context;
818
- var start = candidates.reduce(function (current, candidate) {
819
- return maxDayjs(current, dayjs(candidate.cell.start_at));
820
- }, dayjs(interval.start_at));
821
- var end = candidates.reduce(function (current, candidate) {
822
- return minDayjs(current, dayjs(candidate.cell.end_at));
823
- }, dayjs(interval.end_at));
824
- var durationMinutes = Math.max(1, Number(interval.durationMinutes || 1));
825
- if (interval.source !== 'duration' || query.startTime) {
826
- var fixedStart = dayjs(interval.start_at);
827
- var fixedEnd = dayjs(interval.end_at);
828
- if (containsRange(start, end, fixedStart, fixedEnd) || candidates.every(function (candidate) {
829
- return candidate.cell.cellType === 'fixed_interval';
830
- })) {
831
- var slot = buildSlotFromCandidates({
832
- interval: interval,
833
- candidates: candidates,
834
- start: fixedStart,
835
- end: fixedEnd
836
- });
837
- return slot ? [slot] : [];
838
- }
839
- return [];
840
- }
841
- var stepMinutes = Math.max(1, Number(query.slotDurationMinutes || context.slotDurationMinutes || 30));
842
- var slots = [];
843
- var cursor = start;
844
- while (!cursor.add(durationMinutes, 'minute').isAfter(end)) {
845
- var slotEnd = cursor.add(durationMinutes, 'minute');
846
- var _slot = buildSlotFromCandidates({
847
- interval: interval,
848
- candidates: candidates,
849
- start: cursor,
850
- end: slotEnd
851
- });
852
- if (_slot) slots.push(_slot);
853
- cursor = cursor.add(stepMinutes, 'minute');
854
- }
855
- return slots;
856
- }
857
- export function resolveAssignableSlots(contextInput) {
858
- var query = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
859
- var context = normalizePlannerContext(contextInput);
860
- var projection = queryPlannerAvailability(context, query);
861
- var resources = getQueryResources(context.resources, query);
862
- var slotsByKey = new Map();
863
- var conflicts = [];
864
- projection.demandIntervals.forEach(function (interval) {
865
- var _buildAssignableCandi = buildAssignableCandidateGroups({
866
- interval: interval,
867
- cells: projection.cells,
868
- resources: resources
869
- }),
870
- groups = _buildAssignableCandi.groups,
871
- groupConflicts = _buildAssignableCandi.conflicts;
872
- conflicts.push.apply(conflicts, _toConsumableArray(groupConflicts));
873
- combineCandidateGroups(groups).forEach(function (candidates) {
874
- buildSlotsForInterval({
875
- interval: interval,
876
- candidates: candidates,
877
- query: query,
878
- context: context
879
- }).forEach(function (slot) {
880
- if (!slotsByKey.has(slot.key)) slotsByKey.set(slot.key, slot);
881
- });
882
- });
883
- });
884
- return {
885
- projection: projection,
886
- slots: Array.from(slotsByKey.values()),
887
- conflicts: conflicts
888
- };
889
- }
890
- export function autoAssignResources(contextInput) {
891
- var query = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
892
- var baseContext = normalizePlannerContext(contextInput);
893
- var projection = queryPlannerAvailability(baseContext, query);
894
- var assignments = [];
895
- var conflicts = [];
896
- var missingTimeProductIds = new Set();
897
- var _iterator5 = _createForOfIteratorHelper(projection.demandIntervals),
898
- _step5;
899
- try {
900
- var _loop3 = function _loop3() {
901
- var interval = _step5.value;
902
- if (interval.source === 'duration' && !query.startTime) {
903
- var productKey = String(interval.productId);
904
- if (!missingTimeProductIds.has(productKey)) {
905
- missingTimeProductIds.add(productKey);
906
- conflicts.push({
907
- type: 'missing_time',
908
- message: 'duration 商品需要先确定开始时间后才能自动分配资源',
909
- productId: interval.productId
910
- });
911
- }
912
- return 0; // continue
913
- }
914
- var contextWithAssignments = withAssignmentEvents(baseContext, assignments);
915
- var candidateResources = getQueryResources(contextWithAssignments.resources, query).filter(function (resource) {
916
- var requirements = interval.resourceRequirements || [];
917
- if (!requirements.length) return true;
918
- return requirements.some(function (requirement) {
919
- return matchesResourceRequirement(resource, requirement);
920
- });
921
- });
922
- var availableCell = candidateResources.map(function (resource) {
923
- return evaluateResourceForInterval({
924
- resource: resource,
925
- interval: interval,
926
- context: contextWithAssignments
927
- });
928
- }).find(function (cell) {
929
- return cell.status === 'available' || cell.status === 'limited';
930
- });
931
- if (!(availableCell !== null && availableCell !== void 0 && availableCell.resourceId)) {
932
- conflicts.push({
933
- type: 'missing_resource',
934
- message: '无法为商品自动分配可用资源',
935
- productId: interval.productId
936
- });
937
- return 0; // continue
938
- }
939
- assignments.push({
940
- productId: interval.productId,
941
- resourceId: availableCell.resourceId,
942
- start_at: interval.start_at,
943
- end_at: interval.end_at,
944
- capacityRequired: interval.capacityRequired
945
- });
946
- },
947
- _ret2;
948
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
949
- _ret2 = _loop3();
950
- if (_ret2 === 0) continue;
951
- }
952
- } catch (err) {
953
- _iterator5.e(err);
954
- } finally {
955
- _iterator5.f();
956
- }
957
- return {
958
- assignments: assignments,
959
- conflicts: conflicts
960
- };
961
- }
962
- function withAssignmentEvents(context, assignments) {
963
- if (!assignments.length) return context;
964
- return _objectSpread(_objectSpread({}, context), {}, {
965
- externalEvents: [].concat(_toConsumableArray(context.externalEvents), _toConsumableArray(assignments.map(function (assignment) {
966
- return {
967
- resourceId: assignment.resourceId,
968
- start_at: assignment.start_at,
969
- end_at: assignment.end_at,
970
- pax: assignment.capacityRequired || 1,
971
- source: 'selection'
972
- };
973
- })))
974
- });
975
- }
976
- export function validateAssignments(contextInput, selection) {
977
- if (selection.assignments.length > 0) {
978
- var context = normalizePlannerContext(contextInput);
979
- var _conflicts = [];
980
- var _loop4 = function _loop4() {
981
- var assignment = selection.assignments[index];
982
- var product = context.products.find(function (item) {
983
- return sameId(item.id, assignment.productId);
984
- });
985
- var resource = context.resources.find(function (item) {
986
- return sameId(item.id, assignment.resourceId);
987
- });
988
- if (!product) {
989
- _conflicts.push({
990
- type: 'missing_resource',
991
- message: 'assignment 对应的商品不存在',
992
- productId: assignment.productId
993
- });
994
- return 0; // continue
995
- }
996
- if (!resource) {
997
- _conflicts.push({
998
- type: 'missing_resource',
999
- message: 'assignment 对应的资源不存在',
1000
- productId: assignment.productId,
1001
- resourceId: assignment.resourceId
1002
- });
1003
- return 0; // continue
1004
- }
1005
- var start = dayjs(assignment.start_at);
1006
- var end = dayjs(assignment.end_at);
1007
- var interval = {
1008
- id: "".concat(assignment.productId, ":").concat(assignment.resourceId, ":").concat(assignment.start_at, ":").concat(assignment.end_at),
1009
- productId: assignment.productId,
1010
- source: product.kind === 'session' ? 'session' : product.kind === 'venue_slot' ? 'venue_slot' : 'duration',
1011
- date: start.format('YYYY-MM-DD'),
1012
- start_at: assignment.start_at,
1013
- end_at: assignment.end_at,
1014
- durationMinutes: Math.max(1, end.diff(start, 'minute')),
1015
- quantity: Math.max(1, Number(product.quantity || 1)),
1016
- capacityRequired: Math.max(1, Number(assignment.capacityRequired || product.capacityRequired || 1)),
1017
- resourceRequirements: product.resourceRequirements || []
1018
- };
1019
- var cell = evaluateResourceForInterval({
1020
- resource: resource,
1021
- interval: interval,
1022
- context: context
1023
- });
1024
- if (cell.status !== 'available' && cell.status !== 'limited') {
1025
- _conflicts.push.apply(_conflicts, _toConsumableArray(cell.conflicts));
1026
- }
1027
- var priorContext = withAssignmentEvents(context, selection.assignments.slice(0, index));
1028
- var selfConflictCell = evaluateResourceForInterval({
1029
- resource: resource,
1030
- interval: interval,
1031
- context: priorContext
1032
- });
1033
- if (selfConflictCell.status !== 'available' && selfConflictCell.status !== 'limited') {
1034
- _conflicts.push.apply(_conflicts, _toConsumableArray(selfConflictCell.conflicts.map(function (conflict) {
1035
- return _objectSpread(_objectSpread({}, conflict), {}, {
1036
- type: 'cart_overlap',
1037
- message: '本次选择中存在资源时间冲突'
1038
- });
1039
- })));
1040
- }
1041
- },
1042
- _ret3;
1043
- for (var index = 0; index < selection.assignments.length; index += 1) {
1044
- _ret3 = _loop4();
1045
- if (_ret3 === 0) continue;
1046
- }
1047
- return {
1048
- ok: _conflicts.length === 0,
1049
- conflicts: _conflicts
1050
- };
1051
- }
1052
- var projection = queryPlannerAvailability(contextInput, {
1053
- productIds: selection.productIds,
1054
- date: selection.date,
1055
- startTime: selection.startTime,
1056
- endTime: selection.endTime,
1057
- resourceIds: selection.resourceIds,
1058
- mode: selection.mode
1059
- });
1060
- var conflicts = projection.cells.filter(function (cell) {
1061
- return cell.status !== 'available' && cell.status !== 'limited';
1062
- }).flatMap(function (cell) {
1063
- return cell.conflicts;
1064
- });
1065
- return {
1066
- ok: conflicts.length === 0,
1067
- conflicts: conflicts
1068
- };
1069
- }