@pisell/pisellos 2.2.314 → 2.2.315

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 (214) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +3 -1
  3. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
  4. package/dist/model/strategy/adapter/itemRule/adapter.js +74 -7
  5. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
  6. package/dist/model/strategy/adapter/itemRule/evaluator.js +13 -0
  7. package/dist/model/strategy/adapter/itemRule/type.d.ts +40 -1
  8. package/dist/model/strategy/adapter/itemRule/type.js +10 -0
  9. package/dist/modules/BookingContext/utils/productExtend.d.ts +7 -0
  10. package/dist/modules/BookingContext/utils/productExtend.js +62 -18
  11. package/dist/modules/BookingContext/utils/resources.js +1 -1
  12. package/dist/modules/BusinessAvailability/index.d.ts +30 -0
  13. package/dist/modules/BusinessAvailability/index.js +204 -0
  14. package/dist/modules/Cart/index.js +4 -3
  15. package/dist/modules/Cart/types.d.ts +2 -0
  16. package/dist/modules/Cart/utils/cartProduct.d.ts +3 -1
  17. package/dist/modules/Cart/utils/cartProduct.js +59 -32
  18. package/dist/modules/FulfillmentTiming/index.d.ts +11 -0
  19. package/dist/modules/FulfillmentTiming/index.js +407 -0
  20. package/dist/modules/FulfillmentTiming/types.d.ts +67 -0
  21. package/dist/modules/FulfillmentTiming/types.js +1 -0
  22. package/dist/modules/OpenData/types.d.ts +14 -0
  23. package/dist/modules/Order/index.d.ts +14 -2
  24. package/dist/modules/Order/index.js +856 -486
  25. package/dist/modules/Order/localEftposState.d.ts +13 -0
  26. package/dist/modules/Order/localEftposState.js +39 -0
  27. package/dist/modules/Order/pickupTiming.d.ts +46 -0
  28. package/dist/modules/Order/pickupTiming.js +53 -0
  29. package/dist/modules/Order/types.d.ts +30 -2
  30. package/dist/modules/Order/utils.js +25 -7
  31. package/dist/modules/Payment/index.js +9 -10
  32. package/dist/modules/Product/types.d.ts +11 -0
  33. package/dist/modules/ProductList/index.js +1 -1
  34. package/dist/modules/ResourcePlanner/planner.d.ts +2 -0
  35. package/dist/modules/ResourcePlanner/planner.js +332 -23
  36. package/dist/modules/ResourcePlanner/types.d.ts +29 -0
  37. package/dist/modules/Schedule/index.d.ts +8 -0
  38. package/dist/modules/Schedule/index.js +141 -39
  39. package/dist/modules/index.d.ts +1 -0
  40. package/dist/modules/index.js +1 -0
  41. package/dist/plugins/request.d.ts +7 -0
  42. package/dist/server/index.d.ts +1 -0
  43. package/dist/server/index.js +1536 -1309
  44. package/dist/server/modules/form/index.d.ts +19 -0
  45. package/dist/server/modules/form/index.js +205 -0
  46. package/dist/server/modules/form/types.d.ts +13 -0
  47. package/dist/server/modules/form/types.js +3 -0
  48. package/dist/server/modules/index.d.ts +3 -0
  49. package/dist/server/modules/index.js +4 -0
  50. package/dist/server/modules/order/index.d.ts +15 -0
  51. package/dist/server/modules/order/index.js +920 -688
  52. package/dist/server/modules/order/types.d.ts +1 -0
  53. package/dist/server/test.json +1 -1
  54. package/dist/server/utils/small-ticket.d.ts +1 -85
  55. package/dist/server/utils/small-ticket.js +2 -2542
  56. package/dist/shared/payment/loadPaymentMethods.d.ts +9 -0
  57. package/dist/shared/payment/loadPaymentMethods.js +66 -0
  58. package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  59. package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
  60. package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
  61. package/dist/shared/receipt/loadCustomerInvoiceLayout.js +184 -0
  62. package/dist/shared/receipt/small-ticket.d.ts +96 -0
  63. package/dist/shared/receipt/small-ticket.js +2751 -0
  64. package/dist/shared/receipt/templateVisibility.d.ts +23 -0
  65. package/dist/shared/receipt/templateVisibility.js +64 -0
  66. package/dist/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  67. package/dist/shared/sales/loadSalesOrderSnapshot.js +21 -0
  68. package/dist/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
  69. package/dist/solution/BaseSales/fulfillmentItemRules.js +750 -0
  70. package/dist/solution/BaseSales/index.d.ts +39 -16
  71. package/dist/solution/BaseSales/index.js +1754 -1154
  72. package/dist/solution/BaseSales/pickupTiming.d.ts +47 -0
  73. package/dist/solution/BaseSales/pickupTiming.js +616 -0
  74. package/dist/solution/BaseSales/types.d.ts +11 -0
  75. package/dist/solution/BaseSales/utils/parseSalesResponse.js +3 -0
  76. package/dist/solution/BookingByStep/index.d.ts +3 -1
  77. package/dist/solution/BookingByStep/index.js +8 -3
  78. package/dist/solution/BookingTicket/index.d.ts +8 -2
  79. package/dist/solution/BookingTicket/index.js +513 -436
  80. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
  81. package/dist/solution/BookingTicket/utils/addProductDecision.js +1 -1
  82. package/dist/solution/BookingTicket/utils/cartView.js +3 -1
  83. package/dist/solution/OrderInvoicePreview/index.d.ts +66 -0
  84. package/dist/solution/OrderInvoicePreview/index.js +340 -0
  85. package/dist/solution/RegisterAndLogin/config.js +54 -11
  86. package/dist/solution/RegisterAndLogin/index.d.ts +2 -0
  87. package/dist/solution/RegisterAndLogin/index.js +1 -1
  88. package/dist/solution/RegisterAndLogin/utils.d.ts +12 -4
  89. package/dist/solution/RegisterAndLogin/utils.js +36 -16
  90. package/dist/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  91. package/dist/solution/UnifiedBookingSales/businessAvailability.js +292 -0
  92. package/dist/solution/UnifiedBookingSales/index.d.ts +36 -4
  93. package/dist/solution/UnifiedBookingSales/index.js +1714 -905
  94. package/dist/solution/UnifiedBookingSales/types.d.ts +16 -2
  95. package/dist/solution/VenueBooking/index.d.ts +15 -2
  96. package/dist/solution/VenueBooking/index.js +1062 -785
  97. package/dist/solution/VenueBooking/types.d.ts +2 -1
  98. package/dist/solution/VenueBooking/types.js +1 -0
  99. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  100. package/dist/solution/VenueBooking/utils/dateSummary.js +7 -4
  101. package/dist/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
  102. package/dist/solution/VenueBooking/utils/smartPricing.js +273 -0
  103. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
  104. package/dist/solution/VenueBooking/utils/timeSlot.js +6 -3
  105. package/dist/solution/index.d.ts +1 -0
  106. package/dist/solution/index.js +2 -1
  107. package/lib/index.d.ts +2 -0
  108. package/lib/index.js +21 -1
  109. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
  110. package/lib/model/strategy/adapter/itemRule/adapter.js +54 -4
  111. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
  112. package/lib/model/strategy/adapter/itemRule/evaluator.js +9 -0
  113. package/lib/model/strategy/adapter/itemRule/type.d.ts +40 -1
  114. package/lib/model/strategy/adapter/itemRule/type.js +10 -0
  115. package/lib/model/strategy/adapter/promotion/index.js +46 -1
  116. package/lib/modules/BookingContext/utils/productExtend.d.ts +7 -0
  117. package/lib/modules/BookingContext/utils/productExtend.js +45 -2
  118. package/lib/modules/BookingContext/utils/resources.js +1 -1
  119. package/lib/modules/BusinessAvailability/index.d.ts +30 -0
  120. package/lib/modules/BusinessAvailability/index.js +146 -0
  121. package/lib/modules/Cart/index.js +4 -2
  122. package/lib/modules/Cart/types.d.ts +2 -0
  123. package/lib/modules/Cart/utils/cartProduct.d.ts +3 -1
  124. package/lib/modules/Cart/utils/cartProduct.js +39 -20
  125. package/lib/modules/FulfillmentTiming/index.d.ts +11 -0
  126. package/lib/modules/FulfillmentTiming/index.js +359 -0
  127. package/lib/modules/FulfillmentTiming/types.d.ts +67 -0
  128. package/lib/modules/FulfillmentTiming/types.js +5 -0
  129. package/lib/modules/OpenData/types.d.ts +14 -0
  130. package/lib/modules/Order/index.d.ts +14 -2
  131. package/lib/modules/Order/index.js +240 -38
  132. package/lib/modules/Order/localEftposState.d.ts +13 -0
  133. package/lib/modules/Order/localEftposState.js +44 -0
  134. package/lib/modules/Order/pickupTiming.d.ts +46 -0
  135. package/lib/modules/Order/pickupTiming.js +61 -0
  136. package/lib/modules/Order/types.d.ts +30 -2
  137. package/lib/modules/Order/utils.js +21 -5
  138. package/lib/modules/Payment/index.js +3 -4
  139. package/lib/modules/Product/types.d.ts +11 -0
  140. package/lib/modules/ProductList/index.js +1 -1
  141. package/lib/modules/ResourcePlanner/planner.d.ts +2 -0
  142. package/lib/modules/ResourcePlanner/planner.js +252 -8
  143. package/lib/modules/ResourcePlanner/types.d.ts +29 -0
  144. package/lib/modules/Schedule/index.d.ts +8 -0
  145. package/lib/modules/Schedule/index.js +68 -12
  146. package/lib/modules/index.d.ts +1 -0
  147. package/lib/modules/index.js +11 -0
  148. package/lib/plugins/request.d.ts +7 -0
  149. package/lib/server/index.d.ts +1 -0
  150. package/lib/server/index.js +158 -37
  151. package/lib/server/modules/form/index.d.ts +19 -0
  152. package/lib/server/modules/form/index.js +73 -0
  153. package/lib/server/modules/form/types.d.ts +13 -0
  154. package/lib/server/modules/form/types.js +9 -0
  155. package/lib/server/modules/index.d.ts +3 -0
  156. package/lib/server/modules/index.js +15 -1
  157. package/lib/server/modules/order/index.d.ts +15 -0
  158. package/lib/server/modules/order/index.js +114 -3
  159. package/lib/server/modules/order/types.d.ts +1 -0
  160. package/lib/server/test.json +1 -1
  161. package/lib/server/utils/small-ticket.d.ts +1 -85
  162. package/lib/server/utils/small-ticket.js +9 -2305
  163. package/lib/shared/payment/loadPaymentMethods.d.ts +9 -0
  164. package/lib/shared/payment/loadPaymentMethods.js +40 -0
  165. package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  166. package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
  167. package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
  168. package/lib/shared/receipt/loadCustomerInvoiceLayout.js +124 -0
  169. package/lib/shared/receipt/small-ticket.d.ts +96 -0
  170. package/lib/shared/receipt/small-ticket.js +2546 -0
  171. package/lib/shared/receipt/templateVisibility.d.ts +23 -0
  172. package/lib/shared/receipt/templateVisibility.js +63 -0
  173. package/lib/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  174. package/lib/shared/sales/loadSalesOrderSnapshot.js +22 -0
  175. package/lib/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
  176. package/lib/solution/BaseSales/fulfillmentItemRules.js +259 -0
  177. package/lib/solution/BaseSales/index.d.ts +39 -16
  178. package/lib/solution/BaseSales/index.js +333 -31
  179. package/lib/solution/BaseSales/pickupTiming.d.ts +47 -0
  180. package/lib/solution/BaseSales/pickupTiming.js +290 -0
  181. package/lib/solution/BaseSales/types.d.ts +11 -0
  182. package/lib/solution/BaseSales/utils/parseSalesResponse.js +3 -0
  183. package/lib/solution/BookingByStep/index.d.ts +3 -1
  184. package/lib/solution/BookingByStep/index.js +7 -3
  185. package/lib/solution/BookingTicket/index.d.ts +8 -2
  186. package/lib/solution/BookingTicket/index.js +65 -6
  187. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
  188. package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -1
  189. package/lib/solution/BookingTicket/utils/cartView.js +3 -1
  190. package/lib/solution/OrderInvoicePreview/index.d.ts +66 -0
  191. package/lib/solution/OrderInvoicePreview/index.js +246 -0
  192. package/lib/solution/RegisterAndLogin/config.js +57 -11
  193. package/lib/solution/RegisterAndLogin/index.d.ts +2 -0
  194. package/lib/solution/RegisterAndLogin/index.js +9 -1
  195. package/lib/solution/RegisterAndLogin/utils.d.ts +12 -4
  196. package/lib/solution/RegisterAndLogin/utils.js +24 -17
  197. package/lib/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  198. package/lib/solution/UnifiedBookingSales/businessAvailability.js +138 -0
  199. package/lib/solution/UnifiedBookingSales/index.d.ts +36 -4
  200. package/lib/solution/UnifiedBookingSales/index.js +561 -74
  201. package/lib/solution/UnifiedBookingSales/types.d.ts +16 -2
  202. package/lib/solution/VenueBooking/index.d.ts +15 -2
  203. package/lib/solution/VenueBooking/index.js +243 -96
  204. package/lib/solution/VenueBooking/types.d.ts +2 -1
  205. package/lib/solution/VenueBooking/types.js +1 -0
  206. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  207. package/lib/solution/VenueBooking/utils/dateSummary.js +7 -4
  208. package/lib/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
  209. package/lib/solution/VenueBooking/utils/smartPricing.js +224 -0
  210. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
  211. package/lib/solution/VenueBooking/utils/timeSlot.js +5 -2
  212. package/lib/solution/index.d.ts +1 -0
  213. package/lib/solution/index.js +11 -0
  214. package/package.json +1 -1
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.OrderInvoicePreviewImpl = void 0;
7
+ var _BaseModule = require("../../modules/BaseModule");
8
+ var _loadCustomerInvoiceLayout = require("../../shared/receipt/loadCustomerInvoiceLayout");
9
+ var _customerInvoiceLanguages = require("../../shared/receipt/customerInvoiceLanguages");
10
+ var _smallTicket = require("../../shared/receipt/small-ticket");
11
+ var _loadSalesOrderSnapshot = require("../../shared/sales/loadSalesOrderSnapshot");
12
+ var _loadPaymentMethods = require("../../shared/payment/loadPaymentMethods");
13
+ // Page-runtime cache shared by preview instances, scoped to host, shop and identity.
14
+ const contextCaches = new WeakMap();
15
+ /** Read-only, page-owned solution. No Order, Schedule, quotation or payment modules. */
16
+ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
17
+ isSolution = true;
18
+ request;
19
+ state = {
20
+ status: 'idle',
21
+ result: null,
22
+ error: null
23
+ };
24
+ listeners = new Set();
25
+ generation = 0;
26
+ disposed = false;
27
+ input;
28
+ activeKey = '';
29
+ // Hosts retain this readonly instance while the same order modal is closed.
30
+ languageSelection;
31
+ pending;
32
+ snapshotCache = new Map();
33
+ constructor(name = 'orderInvoicePreview') {
34
+ super(name);
35
+ }
36
+ initialize(core, _options) {
37
+ this.core = core;
38
+ const request = core.getPlugin('request');
39
+ if (!request) throw new Error('OrderInvoicePreview requires request plugin');
40
+ this.request = request;
41
+ }
42
+ getState = () => this.state;
43
+ subscribe = listener => {
44
+ this.listeners.add(listener);
45
+ return () => {
46
+ this.listeners.delete(listener);
47
+ };
48
+ };
49
+ publish(state) {
50
+ this.state = state;
51
+ this.listeners.forEach(listener => listener());
52
+ }
53
+ getScope(input) {
54
+ return JSON.stringify([input.tenantId, input.shopId, input.identity, input.businessCode, input.channel]);
55
+ }
56
+ loadContext(input) {
57
+ let cache = contextCaches.get(this.request);
58
+ if (!cache) {
59
+ cache = new Map();
60
+ contextCaches.set(this.request, cache);
61
+ }
62
+ const key = JSON.stringify([input.tenantId, input.shopId, input.identity]);
63
+ const cached = cache.get(key);
64
+ if (cached) return cached;
65
+ const task = Promise.all([this.request.get('/shop/show', {}, {
66
+ manualErrorHandling: true,
67
+ skipErrorHandler: true
68
+ }), (0, _loadPaymentMethods.loadPaymentMethods)(this.request, {
69
+ transport: 'remote',
70
+ filterPaymentMethods: false
71
+ })]).then(([response, methods]) => {
72
+ const shop = response?.data;
73
+ if (!shop || typeof shop !== 'object' || Array.isArray(shop)) throw new Error('Invoice shop information is unavailable');
74
+ if (String(shop.id) !== String(input.shopId)) throw new Error('Invoice shop identity mismatch');
75
+ return {
76
+ shop,
77
+ methods
78
+ };
79
+ }).catch(error => {
80
+ if (cache.get(key) === task) cache.delete(key);
81
+ throw error;
82
+ });
83
+ cache.set(key, task);
84
+ return task;
85
+ }
86
+ loadSource(input) {
87
+ const key = JSON.stringify([this.getScope(input), input.orderId, input.sourceRevision]);
88
+ const cached = this.snapshotCache.get(key);
89
+ if (cached) return cached;
90
+ const task = (0, _loadSalesOrderSnapshot.loadSalesOrderSnapshot)(this.request, {
91
+ lookup: input.orderId,
92
+ transport: 'remote'
93
+ }).then(response => {
94
+ if (response?.code !== 200 || !response.data || typeof response.data !== 'object' || Array.isArray(response.data)) {
95
+ throw new Error(response?.message || 'Invoice order is unavailable');
96
+ }
97
+ const source = response.data;
98
+ if (source.order_id != null && String(source.order_id) !== String(input.orderId)) {
99
+ throw new Error('Invoice order identity mismatch');
100
+ }
101
+ return source;
102
+ }).catch(error => {
103
+ if (this.snapshotCache.get(key) === task) this.snapshotCache.delete(key);
104
+ throw error;
105
+ });
106
+ this.snapshotCache.set(key, task);
107
+ return task;
108
+ }
109
+ prepare(input) {
110
+ if (this.disposed) return Promise.reject(new Error('Invoice preview disposed'));
111
+ const currentShop = this.core.getPlugin('app')?.getData?.()?.('shop_id');
112
+ if (currentShop != null && String(currentShop) !== String(input.shopId)) {
113
+ return Promise.reject(new Error('Invoice shop changed'));
114
+ }
115
+ const key = JSON.stringify([this.getScope(input), input.orderId, input.sourceRevision, input.locale]);
116
+ if (key === this.activeKey) {
117
+ if (this.pending) return this.pending;
118
+ if (this.state.status === 'ready' && this.state.result) return Promise.resolve(this.state.result);
119
+ }
120
+ if (this.input && this.getScope(this.input) !== this.getScope(input)) this.snapshotCache.clear();
121
+ if (this.languageSelection?.scope !== this.getSelectionScope(input)) this.languageSelection = undefined;
122
+ this.input = input;
123
+ this.activeKey = key;
124
+ const generation = ++this.generation;
125
+ this.publish({
126
+ status: 'loading',
127
+ result: null,
128
+ error: null
129
+ });
130
+ const task = (async () => {
131
+ const [snapshot, context, template] = await Promise.all([this.loadSource(input), this.loadContext(input), (0, _loadCustomerInvoiceLayout.loadCustomerInvoiceTemplate)(this.request, input)]);
132
+ const source = (0, _loadPaymentMethods.withPaymentMethodNames)(snapshot, context.methods);
133
+ const getData = this.core.getPlugin('app')?.getData?.();
134
+ if (getData?.('shop_id') != null && String(getData('shop_id')) !== String(input.shopId)) throw new Error('Invoice shop changed');
135
+ const coreData = getData?.('core');
136
+ const shop = {
137
+ ...(coreData?.core?.shop || coreData?.shop || {}),
138
+ ...(getData?.('shop_info') || {}),
139
+ ...input.shop,
140
+ ...context.shop,
141
+ ...(getData?.('tax_country_code') ? {
142
+ tax_country_code: getData('tax_country_code')
143
+ } : {})
144
+ };
145
+ if (generation !== this.generation || this.disposed) throw new Error('Invoice request superseded');
146
+ const languageOptions = (0, _customerInvoiceLanguages.resolveCustomerInvoiceLanguages)(template.language, input.locale);
147
+ const remembered = this.languageSelection?.code;
148
+ const selected = languageOptions.find(option => option.code === remembered) || languageOptions[0];
149
+ const locale = selected.locales[0];
150
+ const result = {
151
+ identity: this.documentIdentity(key, selected.code),
152
+ languageOptions,
153
+ selectedLanguage: selected.code,
154
+ ...(selected.locales[1] ? {
155
+ secondaryLocale: selected.locales[1]
156
+ } : {}),
157
+ orderId: input.orderId,
158
+ sourceRevision: input.sourceRevision,
159
+ generatedAt: new Date().toISOString(),
160
+ locale,
161
+ source,
162
+ shop,
163
+ layout: template.layout,
164
+ smallTicketData: (0, _smallTicket.buildSmallTicketData)({
165
+ order: source,
166
+ shopInfo: shop,
167
+ locales: [...new Set(languageOptions.flatMap(option => option.locales))],
168
+ includeReceiptKeys: true,
169
+ templateSettings: template.layout
170
+ })
171
+ };
172
+ this.publish({
173
+ status: 'ready',
174
+ result,
175
+ error: null
176
+ });
177
+ return result;
178
+ })().catch(error => {
179
+ if (generation === this.generation && !this.disposed) {
180
+ this.publish({
181
+ status: 'error',
182
+ result: null,
183
+ error: error instanceof Error ? error.message : String(error)
184
+ });
185
+ }
186
+ throw error;
187
+ }).finally(() => {
188
+ if (this.pending === task) this.pending = undefined;
189
+ });
190
+ this.pending = task;
191
+ return task;
192
+ }
193
+ getSelectionScope(input) {
194
+ return JSON.stringify([this.getScope(input), input.orderId]);
195
+ }
196
+ documentIdentity(key, language) {
197
+ return JSON.stringify([key, language]);
198
+ }
199
+
200
+ /** Switch only the ready receipt projection; no fetching or rebuilding data. */
201
+ selectLanguage(code) {
202
+ if (this.disposed) throw new Error('Invoice preview disposed');
203
+ const current = this.state.result;
204
+ if (this.state.status !== 'ready' || !current || !this.input) throw new Error('Invoice preview is not ready');
205
+ const currentShop = this.core.getPlugin('app')?.getData?.()?.('shop_id');
206
+ if (currentShop != null && String(currentShop) !== String(this.input.shopId)) throw new Error('Invoice shop changed');
207
+ const selected = current.languageOptions.find(option => option.code === code);
208
+ if (!selected) throw new Error('Invoice language is unavailable');
209
+ this.languageSelection = {
210
+ scope: this.getSelectionScope(this.input),
211
+ code: selected.code
212
+ };
213
+ if (selected.code === current.selectedLanguage) return current;
214
+ const {
215
+ secondaryLocale: _previousSecondary,
216
+ ...rest
217
+ } = current;
218
+ const result = {
219
+ ...rest,
220
+ identity: this.documentIdentity(this.activeKey, selected.code),
221
+ selectedLanguage: selected.code,
222
+ locale: selected.locales[0],
223
+ ...(selected.locales[1] ? {
224
+ secondaryLocale: selected.locales[1]
225
+ } : {})
226
+ };
227
+ this.publish({
228
+ status: 'ready',
229
+ result,
230
+ error: null
231
+ });
232
+ return result;
233
+ }
234
+ retry() {
235
+ if (!this.input) return Promise.reject(new Error('Invoice input is missing'));
236
+ return this.prepare(this.input);
237
+ }
238
+ destroy() {
239
+ this.disposed = true;
240
+ this.generation++;
241
+ this.listeners.clear();
242
+ this.snapshotCache.clear();
243
+ if (this.core.getModule(this.name) === this) super.destroy();
244
+ }
245
+ }
246
+ exports.OrderInvoicePreviewImpl = OrderInvoicePreviewImpl;
@@ -305,6 +305,30 @@ function withH5AuthPrefix(config) {
305
305
  return nextConfig;
306
306
  }
307
307
  const h5OnlineStoreConfig = withH5AuthPrefix(onlineStoreConfig);
308
+ function withKioskSalesChannel(config) {
309
+ return {
310
+ ...config,
311
+ options: params => {
312
+ const options = (typeof config.options === 'function' ? config.options(params) : config.options) || {};
313
+ const headers = typeof options.headers === 'function' ? options.headers(params) : options.headers;
314
+ return {
315
+ ...options,
316
+ headers: {
317
+ ...headers,
318
+ 'Sales-Channel': 'kiosk'
319
+ }
320
+ };
321
+ }
322
+ };
323
+ }
324
+
325
+ // Kiosk 复用网店顾客认证接口,通过注册(含验证码登录自动注册)请求头标识会员归属渠道。
326
+ const kioskConfig = {
327
+ ...h5OnlineStoreConfig,
328
+ emailCodeRegister: withKioskSalesChannel(h5OnlineStoreConfig.emailCodeRegister),
329
+ phoneCodeRegister: withKioskSalesChannel(h5OnlineStoreConfig.phoneCodeRegister),
330
+ phoneCodeLogin: withKioskSalesChannel(h5OnlineStoreConfig.phoneCodeLogin)
331
+ };
308
332
 
309
333
  /**
310
334
  * 默认配置(通用配置)
@@ -564,6 +588,16 @@ const defaultConfig = {
564
588
  /**
565
589
  * webpos 渠道配置
566
590
  */
591
+ const webposPasswordResetOptions = {
592
+ prefix: false,
593
+ isDefaultSaasDomain: true,
594
+ cache: false,
595
+ noToast: true,
596
+ headers: {
597
+ Accept: 'application/json',
598
+ 'Content-Type': 'application/json'
599
+ }
600
+ };
567
601
  const webposConfig = {
568
602
  sendEmailVerificationCode: {
569
603
  url: '/auth/email/register-code',
@@ -686,13 +720,20 @@ const webposConfig = {
686
720
  })
687
721
  },
688
722
  checkEmailCode: {
689
- url: '/auth/email/check-email-code',
690
- method: 'GET',
723
+ url: '/tenant/account/reset-password/email-code/verify',
724
+ method: 'POST',
691
725
  transformParams: params => ({
692
726
  email: params.email,
693
- code: params.code,
694
- action: params.action
695
- })
727
+ code: params.code
728
+ }),
729
+ // SaaS 成功时 data 为 null,统一为既有验证码校验返回结构。
730
+ transformResponse: response => response?.status === true ? {
731
+ ...response,
732
+ data: {
733
+ valid: true
734
+ }
735
+ } : response,
736
+ options: webposPasswordResetOptions
696
737
  },
697
738
  checkMobileCode: {
698
739
  url: '/auth/mobile/check-mobile-code',
@@ -714,11 +755,12 @@ const webposConfig = {
714
755
  })
715
756
  },
716
757
  sendPasswordResetEmail: {
717
- url: '/auth/email/reset-password-code',
718
- method: 'GET',
758
+ url: '/tenant/account/reset-password/email-code/send',
759
+ method: 'POST',
719
760
  transformParams: params => ({
720
761
  email: params.email
721
- })
762
+ }),
763
+ options: webposPasswordResetOptions
722
764
  },
723
765
  sendPasswordResetSms: {
724
766
  url: '/auth/mobile/sms-forget',
@@ -751,13 +793,16 @@ const webposConfig = {
751
793
  })
752
794
  },
753
795
  resetPasswordByEmail: {
754
- url: '/auth/email/reset-password',
796
+ url: '/tenant/account/reset-password/email-code',
755
797
  method: 'POST',
756
798
  transformParams: params => ({
757
799
  email: params.email,
758
800
  password: params.password,
759
- code: params.code
760
- })
801
+ code: params.code,
802
+ // 页面先校验两次输入完全一致,SDK 保持原有重置参数。
803
+ password_confirmation: params.password
804
+ }),
805
+ options: webposPasswordResetOptions
761
806
  },
762
807
  resetPasswordByPhone: {
763
808
  url: '/auth/mobile/reset-password',
@@ -1094,6 +1139,7 @@ const shopWebposConfig = {
1094
1139
  const channelConfigMap = exports.channelConfigMap = {
1095
1140
  'online-store': onlineStoreConfig,
1096
1141
  'online-store-h5': h5OnlineStoreConfig,
1142
+ 'kiosk': kioskConfig,
1097
1143
  'default': defaultConfig,
1098
1144
  'webpos': webposConfig,
1099
1145
  'shop.webpos': shopWebposConfig
@@ -4,6 +4,8 @@ import { RegisterParams, LoginParams, OAuthLoginParams, SendVerificationCodePara
4
4
  import { ApiCaller } from './config';
5
5
  export * from './types';
6
6
  export * from './config';
7
+ export { validatePassword } from './utils';
8
+ export type { PasswordValidationOptions } from './utils';
7
9
  /**
8
10
  * 注册登录解决方案实现
9
11
  */
@@ -4,9 +4,16 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  var _exportNames = {
7
- RegisterAndLoginImpl: true
7
+ RegisterAndLoginImpl: true,
8
+ validatePassword: true
8
9
  };
9
10
  exports.RegisterAndLoginImpl = void 0;
11
+ Object.defineProperty(exports, "validatePassword", {
12
+ enumerable: true,
13
+ get: function () {
14
+ return _utils.validatePassword;
15
+ }
16
+ });
10
17
  var _BaseModule = require("../../modules/BaseModule");
11
18
  var _types = require("./types");
12
19
  Object.keys(_types).forEach(function (key) {
@@ -32,6 +39,7 @@ Object.keys(_config).forEach(function (key) {
32
39
  }
33
40
  });
34
41
  });
42
+ var _utils = require("./utils");
35
43
  /**
36
44
  * 注册登录解决方案实现
37
45
  */
@@ -10,10 +10,18 @@ export declare function validateEmail(email: string): boolean;
10
10
  * 验证手机号格式(支持多种国际格式)
11
11
  */
12
12
  export declare function validatePhone(phone: string): boolean;
13
- /**
14
- * 验证密码强度
15
- */
16
- export declare function validatePassword(password: string): {
13
+ export interface PasswordValidationOptions {
14
+ minLength?: number;
15
+ maxLength?: number;
16
+ requireLowercase?: boolean;
17
+ requireUppercase?: boolean;
18
+ requireNumber?: boolean;
19
+ requireSpecialCharacters?: boolean;
20
+ specialCharactersPattern?: RegExp;
21
+ messages?: Partial<Record<'minLength' | 'maxLength' | 'requireLowercase' | 'requireUppercase' | 'requireNumber' | 'requireSpecialCharacters', string>>;
22
+ }
23
+ /** 验证密码强度;不传 options 时保持原有规则与返回格式。 */
24
+ export declare function validatePassword(password: string, options?: PasswordValidationOptions): {
17
25
  isValid: boolean;
18
26
  errors: string[];
19
27
  };
@@ -49,29 +49,36 @@ function validatePhone(phone) {
49
49
  const phoneRegex = /^(\+\d{1,3}[- ]?)?\d{10,14}$/;
50
50
  return phoneRegex.test(cleanPhone);
51
51
  }
52
-
53
- /**
54
- * 验证密码强度
55
- */
56
- function validatePassword(password) {
52
+ /** 验证密码强度;不传 options 时保持原有规则与返回格式。 */
53
+ function validatePassword(password, options = {}) {
57
54
  const errors = [];
58
- if (password.length < 8) {
59
- errors.push('密码长度至少为8位');
55
+ const {
56
+ minLength = 8,
57
+ maxLength = 128,
58
+ requireLowercase = true,
59
+ requireUppercase = true,
60
+ requireNumber = true,
61
+ requireSpecialCharacters = true,
62
+ specialCharactersPattern = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/,
63
+ messages = {}
64
+ } = options;
65
+ if (password.length < minLength) {
66
+ errors.push(messages.minLength ?? `密码长度至少为${minLength}位`);
60
67
  }
61
- if (password.length > 128) {
62
- errors.push('密码长度不能超过128位');
68
+ if (password.length > maxLength) {
69
+ errors.push(messages.maxLength ?? `密码长度不能超过${maxLength}位`);
63
70
  }
64
- if (!/[a-z]/.test(password)) {
65
- errors.push('密码必须包含至少一个小写字母');
71
+ if (requireLowercase && !/[a-z]/.test(password)) {
72
+ errors.push(messages.requireLowercase ?? '密码必须包含至少一个小写字母');
66
73
  }
67
- if (!/[A-Z]/.test(password)) {
68
- errors.push('密码必须包含至少一个大写字母');
74
+ if (requireUppercase && !/[A-Z]/.test(password)) {
75
+ errors.push(messages.requireUppercase ?? '密码必须包含至少一个大写字母');
69
76
  }
70
- if (!/\d/.test(password)) {
71
- errors.push('密码必须包含至少一个数字');
77
+ if (requireNumber && !/\d/.test(password)) {
78
+ errors.push(messages.requireNumber ?? '密码必须包含至少一个数字');
72
79
  }
73
- if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) {
74
- errors.push('密码必须包含至少一个特殊字符');
80
+ if (requireSpecialCharacters && !specialCharactersPattern.test(password)) {
81
+ errors.push(messages.requireSpecialCharacters ?? '密码必须包含至少一个特殊字符');
75
82
  }
76
83
  return {
77
84
  isValid: errors.length === 0,
@@ -0,0 +1,27 @@
1
+ import { type BusinessAvailability } from '../../modules/BusinessAvailability';
2
+ import type { ScheduleModule } from '../../modules/Schedule';
3
+ interface BusinessAvailabilityHost {
4
+ loadOpenData: () => Promise<Record<string, unknown> | null>;
5
+ getSchedule: () => ScheduleModule | undefined;
6
+ getTimezone: () => string;
7
+ getScope: () => string;
8
+ now?: () => Date;
9
+ }
10
+ /** Read successful configuration once per business runtime; evaluate the clock on demand. */
11
+ export declare class BusinessAvailabilityController {
12
+ private readonly host;
13
+ private runtime?;
14
+ constructor(host: BusinessAvailabilityHost);
15
+ invalidate(): void;
16
+ private now;
17
+ private getRuntime;
18
+ private assertCurrent;
19
+ private loadConfig;
20
+ private loadSchedules;
21
+ private error;
22
+ /** Synchronous final cart-commit check; deliberately never starts a load. */
23
+ getCachedAvailability(): BusinessAvailability;
24
+ getAvailability(): Promise<BusinessAvailability>;
25
+ assertAvailable(): void;
26
+ }
27
+ export {};
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BusinessAvailabilityController = void 0;
7
+ var _lodashEs = require("lodash-es");
8
+ var _BusinessAvailability = require("../../modules/BusinessAvailability");
9
+ async function withTimeout(request) {
10
+ let timer;
11
+ try {
12
+ return await Promise.race([request, new Promise((_, reject) => {
13
+ timer = setTimeout(() => reject(new Error('Unable to load business settings. Please try again.')), 30_000);
14
+ })]);
15
+ } finally {
16
+ if (timer !== undefined) clearTimeout(timer);
17
+ }
18
+ }
19
+
20
+ /** Read successful configuration once per business runtime; evaluate the clock on demand. */
21
+ class BusinessAvailabilityController {
22
+ runtime;
23
+ constructor(host) {
24
+ this.host = host;
25
+ }
26
+ invalidate() {
27
+ this.runtime = undefined;
28
+ }
29
+ now() {
30
+ return this.host.now?.() ?? new Date();
31
+ }
32
+ getRuntime() {
33
+ const scope = this.host.getScope();
34
+ if (this.runtime?.scope !== scope) this.runtime = {
35
+ scope
36
+ };
37
+ return this.runtime;
38
+ }
39
+ assertCurrent(runtime) {
40
+ if (this.runtime !== runtime || runtime.scope !== this.host.getScope()) {
41
+ throw new Error('Store settings changed. Please try again.');
42
+ }
43
+ }
44
+ async loadConfig(runtime) {
45
+ if (runtime.config) return runtime.config;
46
+ if (!runtime.configRequest) {
47
+ runtime.configRequest = (async () => {
48
+ const data = await withTimeout(this.host.loadOpenData());
49
+ this.assertCurrent(runtime);
50
+ if (!data) throw new Error('Business settings are unavailable. Please try again.');
51
+ const config = (0, _lodashEs.cloneDeep)((0, _BusinessAvailability.normalizeBusinessAvailabilityConfig)(data));
52
+ runtime.config = config;
53
+ return config;
54
+ })();
55
+ }
56
+ const request = runtime.configRequest;
57
+ try {
58
+ return await request;
59
+ } finally {
60
+ if (runtime.configRequest === request) runtime.configRequest = undefined;
61
+ }
62
+ }
63
+ async loadSchedules(runtime) {
64
+ if (runtime.schedules) return runtime.schedules;
65
+ if (!runtime.scheduleRequest) {
66
+ runtime.scheduleRequest = (async () => {
67
+ const schedule = this.host.getSchedule();
68
+ if (!schedule) throw new Error('Business operating-hours schedule is unavailable. Please try again.');
69
+ await withTimeout(schedule.loadAllSchedule({
70
+ useCache: true
71
+ }));
72
+ this.assertCurrent(runtime);
73
+ const schedules = (0, _lodashEs.cloneDeep)(schedule.getScheduleListByIds(runtime.config.scheduleIds) || []);
74
+ runtime.schedules = schedules;
75
+ return schedules;
76
+ })();
77
+ }
78
+ const request = runtime.scheduleRequest;
79
+ try {
80
+ return await request;
81
+ } finally {
82
+ if (runtime.scheduleRequest === request) runtime.scheduleRequest = undefined;
83
+ }
84
+ }
85
+ error(reason, runtime) {
86
+ return {
87
+ status: 'error',
88
+ behavior: 'hide_all',
89
+ message: null,
90
+ nextChangeAt: this.now().getTime() + 60_000,
91
+ requirePaymentOnSubmit: runtime?.config?.requirePaymentOnSubmit ?? true,
92
+ error: reason instanceof Error ? reason.message : 'Business settings are unavailable. Please try again.'
93
+ };
94
+ }
95
+
96
+ /** Synchronous final cart-commit check; deliberately never starts a load. */
97
+ getCachedAvailability() {
98
+ const runtime = this.getRuntime();
99
+ try {
100
+ this.assertCurrent(runtime);
101
+ if (!runtime.config) throw new Error('Business settings are still loading. Please try again.');
102
+ return (0, _BusinessAvailability.computeBusinessAvailability)({
103
+ config: runtime.config,
104
+ schedules: runtime.schedules || [],
105
+ timezone: this.host.getTimezone(),
106
+ now: this.now()
107
+ });
108
+ } catch (reason) {
109
+ return this.error(reason, runtime);
110
+ }
111
+ }
112
+ async getAvailability() {
113
+ const runtime = this.getRuntime();
114
+ try {
115
+ const config = await this.loadConfig(runtime);
116
+ this.assertCurrent(runtime);
117
+ if (!config.paused && !config.invalidScheduleIds && config.scheduleIds.length) {
118
+ await this.loadSchedules(runtime);
119
+ }
120
+ this.assertCurrent(runtime);
121
+ return this.getCachedAvailability();
122
+ } catch (reason) {
123
+ return this.error(reason, runtime);
124
+ }
125
+ }
126
+ assertAvailable() {
127
+ const availability = this.getCachedAvailability();
128
+ if (availability.status !== 'open') {
129
+ const error = new Error(availability.error || (availability.status === 'paused' ? 'Ordering is temporarily paused.' : 'Ordering is currently closed.'));
130
+ Object.assign(error, {
131
+ code: 'BUSINESS_UNAVAILABLE',
132
+ businessAvailability: availability
133
+ });
134
+ throw error;
135
+ }
136
+ }
137
+ }
138
+ exports.BusinessAvailabilityController = BusinessAvailabilityController;