@pisell/pisellos 0.10.53 → 0.10.55

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 (68) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +3 -1
  3. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  4. package/dist/modules/BusinessAvailability/index.d.ts +30 -0
  5. package/dist/modules/BusinessAvailability/index.js +204 -0
  6. package/dist/modules/OpenData/index.js +1 -1
  7. package/dist/modules/OpenData/types.d.ts +2 -0
  8. package/dist/modules/Order/index.d.ts +5 -2
  9. package/dist/modules/Order/index.js +320 -247
  10. package/dist/modules/Order/types.d.ts +8 -0
  11. package/dist/modules/Payment/index.js +9 -10
  12. package/dist/plugins/request.d.ts +3 -0
  13. package/dist/server/utils/small-ticket.d.ts +1 -85
  14. package/dist/server/utils/small-ticket.js +2 -2576
  15. package/dist/shared/payment/loadPaymentMethods.d.ts +9 -0
  16. package/dist/shared/payment/loadPaymentMethods.js +66 -0
  17. package/dist/shared/receipt/small-ticket.d.ts +85 -0
  18. package/dist/shared/receipt/small-ticket.js +2576 -0
  19. package/dist/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  20. package/dist/shared/sales/loadSalesOrderSnapshot.js +21 -0
  21. package/dist/solution/BaseSales/index.d.ts +4 -15
  22. package/dist/solution/BaseSales/index.js +131 -86
  23. package/dist/solution/BaseSales/types.d.ts +11 -0
  24. package/dist/solution/BookingByStep/index.d.ts +1 -1
  25. package/dist/solution/BookingTicket/index.js +41 -13
  26. package/dist/solution/OrderInvoicePreview/index.d.ts +56 -0
  27. package/dist/solution/OrderInvoicePreview/index.js +269 -0
  28. package/dist/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  29. package/dist/solution/UnifiedBookingSales/businessAvailability.js +292 -0
  30. package/dist/solution/UnifiedBookingSales/index.d.ts +11 -0
  31. package/dist/solution/UnifiedBookingSales/index.js +154 -75
  32. package/dist/solution/UnifiedBookingSales/types.d.ts +2 -0
  33. package/dist/solution/index.d.ts +1 -0
  34. package/dist/solution/index.js +2 -1
  35. package/lib/index.d.ts +2 -0
  36. package/lib/index.js +21 -1
  37. package/lib/modules/BusinessAvailability/index.d.ts +30 -0
  38. package/lib/modules/BusinessAvailability/index.js +146 -0
  39. package/lib/modules/OpenData/index.js +1 -1
  40. package/lib/modules/OpenData/types.d.ts +2 -0
  41. package/lib/modules/Order/index.d.ts +5 -2
  42. package/lib/modules/Order/index.js +67 -13
  43. package/lib/modules/Order/types.d.ts +8 -0
  44. package/lib/modules/Payment/index.js +3 -4
  45. package/lib/plugins/request.d.ts +3 -0
  46. package/lib/server/utils/small-ticket.d.ts +1 -85
  47. package/lib/server/utils/small-ticket.js +9 -2335
  48. package/lib/shared/payment/loadPaymentMethods.d.ts +9 -0
  49. package/lib/shared/payment/loadPaymentMethods.js +40 -0
  50. package/lib/shared/receipt/small-ticket.d.ts +85 -0
  51. package/lib/shared/receipt/small-ticket.js +2342 -0
  52. package/lib/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  53. package/lib/shared/sales/loadSalesOrderSnapshot.js +22 -0
  54. package/lib/solution/BaseSales/index.d.ts +4 -15
  55. package/lib/solution/BaseSales/index.js +45 -24
  56. package/lib/solution/BaseSales/types.d.ts +11 -0
  57. package/lib/solution/BookingByStep/index.d.ts +1 -1
  58. package/lib/solution/BookingTicket/index.js +37 -4
  59. package/lib/solution/OrderInvoicePreview/index.d.ts +56 -0
  60. package/lib/solution/OrderInvoicePreview/index.js +194 -0
  61. package/lib/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  62. package/lib/solution/UnifiedBookingSales/businessAvailability.js +138 -0
  63. package/lib/solution/UnifiedBookingSales/index.d.ts +11 -0
  64. package/lib/solution/UnifiedBookingSales/index.js +54 -0
  65. package/lib/solution/UnifiedBookingSales/types.d.ts +2 -0
  66. package/lib/solution/index.d.ts +1 -0
  67. package/lib/solution/index.js +11 -0
  68. package/package.json +1 -1
@@ -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;
@@ -5,9 +5,11 @@ import type { LoadScheduleAvailableDateParams, ScheduleItem } from '../../module
5
5
  import type { ProductListLoadProductsParams, ProductListStoreQueryParams } from '../../modules/ProductList';
6
6
  import type { AvailabilityDateRange, AvailabilityOccupancy, AvailabilityProduct, AvailabilityResource, GetProductTimeRangesRequest } from '../../modules/ResourcePlanner';
7
7
  import type { AvailabilityContextRef, ContextualAvailabilityQuery, ContextualAvailabilityQueryResult, ContextualCommitAvailabilitySelectionParams, ContextualProductTimeRangeGroup, UnifiedBookingSalesAddRetailProductParams, UnifiedBookingSalesApplyPlannerDiscountsParams, UnifiedBookingSalesCommitAvailabilitySelectionResult, UnifiedBookingSalesDiscountResult, UnifiedBookingSalesLoadProductsByScheduleDateParams, UnifiedBookingSalesLoadOpenDataParams, UnifiedBookingSalesPrepareAvailabilityProjectionParams, UnifiedBookingSalesPolicyResponse, UnifiedBookingSalesResolveProductAllergyRequirementParams, UnifiedBookingSalesStageRetailProductsParams, UnifiedBookingSalesState } from './types';
8
+ import type { BusinessAvailability } from '../../modules/BusinessAvailability';
8
9
  import { BookingTicket } from '../BookingTicket';
9
10
  import type { AllergyRequirement } from '../../model/strategy/adapter/itemRule';
10
11
  export * from './types';
12
+ export type { BusinessAvailability, BusinessClosedBehavior } from '../../modules/BusinessAvailability';
11
13
  export { AvailabilityError } from '../../modules/ResourcePlanner';
12
14
  /**
13
15
  * Converts Rules/Order discount internals into a small UI-facing diagnostic. The result keeps
@@ -60,6 +62,7 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
60
62
  protected defaultVersion: string;
61
63
  protected store: UnifiedBookingSalesState;
62
64
  protected pickupTimingEnabled: boolean;
65
+ private businessAvailabilityController?;
63
66
  private runtimeOpenDataScope;
64
67
  private runtimeOpenDataSnapshot;
65
68
  private runtimeOpenDataModule;
@@ -86,6 +89,14 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
86
89
  private allergyItemRuleConfigsPromise;
87
90
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
88
91
  protected getSubmitOrderSalesChannel(): string;
92
+ /** Only the explicit Kiosk Sales consumer entry enables this policy; POS stays unchanged. */
93
+ protected isBusinessAvailabilityEnabled(): boolean;
94
+ protected getBusinessAvailabilityScope(): string;
95
+ private getBusinessAvailabilityController;
96
+ getBusinessAvailability(): Promise<BusinessAvailability>;
97
+ /** Internal final-write assertion; does not fetch OpenData or Schedule. */
98
+ assertBusinessAvailability(): void;
99
+ protected getSubModuleHooks(moduleName: string): any;
89
100
  private createAvailabilityFacadeError;
90
101
  private getAvailabilityScopeDescriptor;
91
102
  private normalizeAvailabilityIdList;
@@ -49,6 +49,7 @@ Object.keys(_types).forEach(function (key) {
49
49
  });
50
50
  });
51
51
  var _remoteOccupancyCache = require("./remoteOccupancyCache");
52
+ var _businessAvailability = require("./businessAvailability");
52
53
  var _BookingTicket = require("../BookingTicket");
53
54
  var _localClock = require("../../modules/ResourcePlanner/localClock");
54
55
  var _platform = require("../../utils/platform");
@@ -1199,6 +1200,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1199
1200
  defaultVersion = '1.0.0';
1200
1201
  store = {};
1201
1202
  pickupTimingEnabled = true;
1203
+ businessAvailabilityController;
1202
1204
  runtimeOpenDataScope = null;
1203
1205
  runtimeOpenDataSnapshot = null;
1204
1206
  runtimeOpenDataModule = null;
@@ -1241,6 +1243,57 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1241
1243
  const channel = String(this.otherParams?.channel ?? '').trim();
1242
1244
  return channel || super.getSubmitOrderSalesChannel();
1243
1245
  }
1246
+
1247
+ /** Only the explicit Kiosk Sales consumer entry enables this policy; POS stays unchanged. */
1248
+ isBusinessAvailabilityEnabled() {
1249
+ return this.otherParams?.enableBusinessAvailability === true && ['pc', 'h5', 'kiosk'].includes((0, _platform.normalizeRuntimePlatform)(this.otherParams?.platform));
1250
+ }
1251
+ getBusinessAvailabilityScope() {
1252
+ return `${this.getRuntimeOpenDataScope()}:${this.runtimeOpenDataGeneration}`;
1253
+ }
1254
+ getBusinessAvailabilityController() {
1255
+ if (!this.businessAvailabilityController) {
1256
+ this.businessAvailabilityController = new _businessAvailability.BusinessAvailabilityController({
1257
+ loadOpenData: () => this.loadOpenDataConfig(),
1258
+ getSchedule: () => this.store.schedule,
1259
+ getTimezone: () => String(this.otherParams?.businessTimezone || this.getPickupTimingContextData('timezone') || ''),
1260
+ getScope: () => this.getBusinessAvailabilityScope()
1261
+ });
1262
+ }
1263
+ return this.businessAvailabilityController;
1264
+ }
1265
+ getBusinessAvailability() {
1266
+ return this.getBusinessAvailabilityController().getAvailability();
1267
+ }
1268
+
1269
+ /** Internal final-write assertion; does not fetch OpenData or Schedule. */
1270
+ assertBusinessAvailability() {
1271
+ if (this.isBusinessAvailabilityEnabled()) this.getBusinessAvailabilityController().assertAvailable();
1272
+ }
1273
+ getSubModuleHooks(moduleName) {
1274
+ const hooks = super.getSubModuleHooks(moduleName);
1275
+ if (moduleName !== 'order' || !this.isBusinessAvailabilityEnabled()) return hooks;
1276
+ let lastScope;
1277
+ let lastExistingScope;
1278
+ let scopeToken = {};
1279
+ return {
1280
+ ...hooks,
1281
+ getCartIntentScope: () => {
1282
+ const scope = this.getBusinessAvailabilityScope();
1283
+ const existingScope = hooks?.getCartIntentScope?.();
1284
+ if (scope !== lastScope || !Object.is(existingScope, lastExistingScope)) {
1285
+ lastScope = scope;
1286
+ lastExistingScope = existingScope;
1287
+ scopeToken = {};
1288
+ }
1289
+ return scopeToken;
1290
+ },
1291
+ beforeCartIntentCommit: context => {
1292
+ this.assertBusinessAvailability();
1293
+ hooks?.beforeCartIntentCommit?.(context);
1294
+ }
1295
+ };
1296
+ }
1244
1297
  createAvailabilityFacadeError(code, message, details) {
1245
1298
  return new _ResourcePlanner.AvailabilityError(code, message, details);
1246
1299
  }
@@ -1714,6 +1767,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1714
1767
  });
1715
1768
  }
1716
1769
  resetRuntimeOpenData() {
1770
+ this.businessAvailabilityController?.invalidate();
1717
1771
  this.runtimeOpenDataGeneration += 1;
1718
1772
  this.runtimeOpenDataScope = null;
1719
1773
  this.runtimeOpenDataSnapshot = null;
@@ -216,6 +216,8 @@ export interface UnifiedBookingSalesDiscountResult {
216
216
  summaryAfter?: unknown;
217
217
  }
218
218
  export interface UnifiedBookingSalesApi {
219
+ /** Uses cached business settings and evaluates the current store-local clock. */
220
+ getBusinessAvailability: () => Promise<import('../../modules/BusinessAvailability').BusinessAvailability>;
219
221
  loadOpenData: (params: UnifiedBookingSalesLoadOpenDataParams) => Promise<OpenDataConfig>;
220
222
  /** Returns the latest OpenData payload cached by this solution instance. */
221
223
  getOpenData: () => Promise<OpenDataConfig | null>;
@@ -9,3 +9,4 @@ export * from './ScanOrder';
9
9
  export * from './BaseSales';
10
10
  export * from './VenueBooking';
11
11
  export * from './UnifiedBookingSales';
12
+ export * from './OrderInvoicePreview';
@@ -123,4 +123,15 @@ Object.keys(_UnifiedBookingSales).forEach(function (key) {
123
123
  return _UnifiedBookingSales[key];
124
124
  }
125
125
  });
126
+ });
127
+ var _OrderInvoicePreview = require("./OrderInvoicePreview");
128
+ Object.keys(_OrderInvoicePreview).forEach(function (key) {
129
+ if (key === "default" || key === "__esModule") return;
130
+ if (key in exports && exports[key] === _OrderInvoicePreview[key]) return;
131
+ Object.defineProperty(exports, key, {
132
+ enumerable: true,
133
+ get: function () {
134
+ return _OrderInvoicePreview[key];
135
+ }
136
+ });
126
137
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.10.53",
4
+ "version": "0.10.55",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",