@pisell/pisellos 2.3.138 → 2.3.139

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.
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.OrderInvoicePreviewImpl = void 0;
7
7
  var _BaseModule = require("../../modules/BaseModule");
8
8
  var _loadCustomerInvoiceLayout = require("../../shared/receipt/loadCustomerInvoiceLayout");
9
+ var _customerInvoiceLanguages = require("../../shared/receipt/customerInvoiceLanguages");
9
10
  var _smallTicket = require("../../shared/receipt/small-ticket");
10
11
  var _loadSalesOrderSnapshot = require("../../shared/sales/loadSalesOrderSnapshot");
11
12
  var _loadPaymentMethods = require("../../shared/payment/loadPaymentMethods");
@@ -25,6 +26,8 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
25
26
  disposed = false;
26
27
  input;
27
28
  activeKey = '';
29
+ // Hosts retain this readonly instance while the same order modal is closed.
30
+ languageSelection;
28
31
  pending;
29
32
  snapshotCache = new Map();
30
33
  constructor(name = 'orderInvoicePreview') {
@@ -56,7 +59,7 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
56
59
  cache = new Map();
57
60
  contextCaches.set(this.request, cache);
58
61
  }
59
- const key = JSON.stringify([input.tenantId, input.shopId, input.identity, input.locale]);
62
+ const key = JSON.stringify([input.tenantId, input.shopId, input.identity]);
60
63
  const cached = cache.get(key);
61
64
  if (cached) return cached;
62
65
  const task = Promise.all([this.request.get('/shop/show', {}, {
@@ -115,6 +118,7 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
115
118
  if (this.state.status === 'ready' && this.state.result) return Promise.resolve(this.state.result);
116
119
  }
117
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;
118
122
  this.input = input;
119
123
  this.activeKey = key;
120
124
  const generation = ++this.generation;
@@ -124,7 +128,7 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
124
128
  error: null
125
129
  });
126
130
  const task = (async () => {
127
- const [snapshot, context, layout] = await Promise.all([this.loadSource(input), this.loadContext(input), (0, _loadCustomerInvoiceLayout.loadCustomerInvoiceLayout)(this.request, input)]);
131
+ const [snapshot, context, template] = await Promise.all([this.loadSource(input), this.loadContext(input), (0, _loadCustomerInvoiceLayout.loadCustomerInvoiceTemplate)(this.request, input)]);
128
132
  const source = (0, _loadPaymentMethods.withPaymentMethodNames)(snapshot, context.methods);
129
133
  const getData = this.core.getPlugin('app')?.getData?.();
130
134
  if (getData?.('shop_id') != null && String(getData('shop_id')) !== String(input.shopId)) throw new Error('Invoice shop changed');
@@ -139,21 +143,29 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
139
143
  } : {})
140
144
  };
141
145
  if (generation !== this.generation || this.disposed) throw new Error('Invoice request superseded');
142
- const requestedLocale = input.locale.toLowerCase().replace(/_/g, '-');
143
- const locale = requestedLocale.startsWith('zh-tw') || requestedLocale.startsWith('zh-hk') ? 'zh_HK' : requestedLocale.startsWith('zh') ? 'zh_CN' : requestedLocale.startsWith('ja') ? 'ja' : requestedLocale.startsWith('pt') ? 'pt' : 'en';
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];
144
150
  const result = {
145
- identity: key,
151
+ identity: this.documentIdentity(key, selected.code),
152
+ languageOptions,
153
+ selectedLanguage: selected.code,
154
+ ...(selected.locales[1] ? {
155
+ secondaryLocale: selected.locales[1]
156
+ } : {}),
146
157
  orderId: input.orderId,
147
158
  sourceRevision: input.sourceRevision,
148
159
  generatedAt: new Date().toISOString(),
149
160
  locale,
150
161
  source,
151
162
  shop,
152
- layout,
163
+ layout: template.layout,
153
164
  smallTicketData: (0, _smallTicket.buildSmallTicketData)({
154
165
  order: source,
155
166
  shopInfo: shop,
156
- locales: [locale]
167
+ locales: [...new Set(languageOptions.flatMap(option => option.locales))],
168
+ includeReceiptKeys: true
157
169
  })
158
170
  };
159
171
  this.publish({
@@ -177,6 +189,47 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
177
189
  this.pending = task;
178
190
  return task;
179
191
  }
192
+ getSelectionScope(input) {
193
+ return JSON.stringify([this.getScope(input), input.orderId]);
194
+ }
195
+ documentIdentity(key, language) {
196
+ return JSON.stringify([key, language]);
197
+ }
198
+
199
+ /** Switch only the ready receipt projection; no fetching or rebuilding data. */
200
+ selectLanguage(code) {
201
+ if (this.disposed) throw new Error('Invoice preview disposed');
202
+ const current = this.state.result;
203
+ if (this.state.status !== 'ready' || !current || !this.input) throw new Error('Invoice preview is not ready');
204
+ const currentShop = this.core.getPlugin('app')?.getData?.()?.('shop_id');
205
+ if (currentShop != null && String(currentShop) !== String(this.input.shopId)) throw new Error('Invoice shop changed');
206
+ const selected = current.languageOptions.find(option => option.code === code);
207
+ if (!selected) throw new Error('Invoice language is unavailable');
208
+ this.languageSelection = {
209
+ scope: this.getSelectionScope(this.input),
210
+ code: selected.code
211
+ };
212
+ if (selected.code === current.selectedLanguage) return current;
213
+ const {
214
+ secondaryLocale: _previousSecondary,
215
+ ...rest
216
+ } = current;
217
+ const result = {
218
+ ...rest,
219
+ identity: this.documentIdentity(this.activeKey, selected.code),
220
+ selectedLanguage: selected.code,
221
+ locale: selected.locales[0],
222
+ ...(selected.locales[1] ? {
223
+ secondaryLocale: selected.locales[1]
224
+ } : {})
225
+ };
226
+ this.publish({
227
+ status: 'ready',
228
+ result,
229
+ error: null
230
+ });
231
+ return result;
232
+ }
180
233
  retry() {
181
234
  if (!this.input) return Promise.reject(new Error('Invoice input is missing'));
182
235
  return this.prepare(this.input);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.138",
4
+ "version": "2.3.139",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",