@pisell/pisellos 2.3.28 → 2.3.30
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.
- package/dist/modules/Order/index.d.ts +32 -8
- package/dist/modules/Order/index.js +883 -521
- package/dist/modules/Order/payment-utils.d.ts +23 -0
- package/dist/modules/Order/payment-utils.js +203 -0
- package/dist/modules/Order/types.d.ts +33 -1
- package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
- package/dist/modules/Order/utils.d.ts +2 -1
- package/dist/modules/Order/utils.js +6 -12
- package/dist/modules/Payment/index.d.ts +2 -0
- package/dist/modules/Payment/index.js +78 -49
- package/dist/modules/Payment/types.d.ts +26 -24
- package/dist/modules/Payment/types.js +2 -0
- package/dist/modules/Product/index.d.ts +1 -1
- package/dist/server/index.d.ts +14 -0
- package/dist/server/index.js +1826 -1000
- package/dist/server/modules/order/index.d.ts +47 -4
- package/dist/server/modules/order/index.js +1415 -711
- package/dist/server/modules/order/types.d.ts +11 -3
- package/dist/server/modules/order/types.js +1 -1
- package/dist/solution/BaseSales/index.d.ts +40 -4
- package/dist/solution/BaseSales/index.js +1268 -749
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +9 -4
- package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +13 -1
- package/dist/solution/BookingTicket/index.js +2 -1
- package/dist/utils/payment-number.d.ts +9 -0
- package/dist/utils/payment-number.js +69 -0
- package/lib/modules/Order/index.d.ts +32 -8
- package/lib/modules/Order/index.js +270 -64
- package/lib/modules/Order/payment-utils.d.ts +23 -0
- package/lib/modules/Order/payment-utils.js +193 -0
- package/lib/modules/Order/types.d.ts +33 -1
- package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +415 -0
- package/lib/modules/Order/utils.d.ts +2 -1
- package/lib/modules/Order/utils.js +6 -14
- package/lib/modules/Payment/index.d.ts +2 -0
- package/lib/modules/Payment/index.js +33 -12
- package/lib/modules/Payment/types.d.ts +26 -24
- package/lib/modules/Product/index.d.ts +1 -1
- package/lib/server/index.d.ts +14 -0
- package/lib/server/index.js +604 -8
- package/lib/server/modules/order/index.d.ts +47 -4
- package/lib/server/modules/order/index.js +578 -116
- package/lib/server/modules/order/types.d.ts +11 -3
- package/lib/solution/BaseSales/index.d.ts +40 -4
- package/lib/solution/BaseSales/index.js +363 -37
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +9 -4
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +13 -1
- package/lib/solution/BookingTicket/index.js +2 -1
- package/lib/utils/payment-number.d.ts +9 -0
- package/lib/utils/payment-number.js +64 -0
- package/package.json +1 -1
|
@@ -40,6 +40,9 @@ var import_decimal = __toESM(require("decimal.js"));
|
|
|
40
40
|
var import_lodash_es = require("lodash-es");
|
|
41
41
|
var import_types2 = require("../BookingByStep/types");
|
|
42
42
|
var import_utils = require("../../modules/Order/utils");
|
|
43
|
+
var import_payment_utils = require("../../modules/Order/payment-utils");
|
|
44
|
+
var import_payment_number = require("../../utils/payment-number");
|
|
45
|
+
var import_orderCollectionIdentity = require("../../modules/Order/utils/orderCollectionIdentity");
|
|
43
46
|
var import_dayjs = __toESM(require("dayjs"));
|
|
44
47
|
__reExport(BaseSales_exports, require("./types"), module.exports);
|
|
45
48
|
var import_Quotation = require("../../modules/Quotation");
|
|
@@ -79,8 +82,20 @@ function isBaseSalesHistoricalDiscountEntry(discount) {
|
|
|
79
82
|
function getBaseSalesUniqueArrayMetadataKey(key) {
|
|
80
83
|
if (key === "products" || key === "bookings")
|
|
81
84
|
return "unique_identification_number";
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
var BASE_SALES_PERSISTENT_ID_FIELD_BY_KIND = {
|
|
88
|
+
product: "order_detail_id",
|
|
89
|
+
booking: "schedule_event_id",
|
|
90
|
+
payment: "order_payment_id"
|
|
91
|
+
};
|
|
92
|
+
function getBaseSalesOrderCollectionKind(key) {
|
|
93
|
+
if (key === "products")
|
|
94
|
+
return "product";
|
|
95
|
+
if (key === "bookings")
|
|
96
|
+
return "booking";
|
|
82
97
|
if (key === "payments" || key === "payment")
|
|
83
|
-
return "
|
|
98
|
+
return "payment";
|
|
84
99
|
return null;
|
|
85
100
|
}
|
|
86
101
|
function isSameBaseSalesOrderRecord(left, right) {
|
|
@@ -95,13 +110,6 @@ function isSameBaseSalesOrderRecord(left, right) {
|
|
|
95
110
|
(value) => value !== void 0 && value !== null && value !== "" && leftIdentities.has(String(value))
|
|
96
111
|
);
|
|
97
112
|
}
|
|
98
|
-
function getBaseSalesMetadataUid(item, metadataKey) {
|
|
99
|
-
var _a;
|
|
100
|
-
const uid = ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a[metadataKey]) ?? (item == null ? void 0 : item[metadataKey]);
|
|
101
|
-
if (uid === void 0 || uid === null || uid === "")
|
|
102
|
-
return null;
|
|
103
|
-
return String(uid);
|
|
104
|
-
}
|
|
105
113
|
function isBaseSalesBlankValue(value) {
|
|
106
114
|
return value === void 0 || value === null || value === "";
|
|
107
115
|
}
|
|
@@ -120,7 +128,102 @@ function mergeBaseSalesProductSnapshotFields(currentItem, loadedItem) {
|
|
|
120
128
|
}
|
|
121
129
|
return mergedItem;
|
|
122
130
|
}
|
|
123
|
-
function
|
|
131
|
+
function mergeBaseSalesCollectionItem(kind, currentItem, incomingItem, uidRemaps) {
|
|
132
|
+
const currentReferenceUid = (0, import_orderCollectionIdentity.getOrderCollectionReferenceUid)(kind, currentItem);
|
|
133
|
+
const incomingReferenceUid = (0, import_orderCollectionIdentity.getOrderCollectionReferenceUid)(kind, incomingItem);
|
|
134
|
+
const identityMergedItem = (0, import_orderCollectionIdentity.mergeOrderCollectionItems)(
|
|
135
|
+
kind,
|
|
136
|
+
currentItem,
|
|
137
|
+
incomingItem
|
|
138
|
+
);
|
|
139
|
+
const mergedUid = (0, import_orderCollectionIdentity.getOrderCollectionUid)(kind, identityMergedItem);
|
|
140
|
+
if (mergedUid) {
|
|
141
|
+
for (const from of /* @__PURE__ */ new Set([currentReferenceUid, incomingReferenceUid])) {
|
|
142
|
+
if (!from || from === mergedUid)
|
|
143
|
+
continue;
|
|
144
|
+
uidRemaps.push({
|
|
145
|
+
kind,
|
|
146
|
+
from,
|
|
147
|
+
to: mergedUid,
|
|
148
|
+
persistentId: (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, incomingItem) || (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, currentItem)
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const mergedItem = mergedUid ? (0, import_orderCollectionIdentity.setOrderCollectionUid)(kind, incomingItem, mergedUid) : (0, import_lodash_es.cloneDeep)(incomingItem);
|
|
153
|
+
const persistentIdField = BASE_SALES_PERSISTENT_ID_FIELD_BY_KIND[kind];
|
|
154
|
+
if (isBaseSalesBlankValue(mergedItem[persistentIdField]) && !isBaseSalesBlankValue(identityMergedItem[persistentIdField])) {
|
|
155
|
+
mergedItem[persistentIdField] = identityMergedItem[persistentIdField];
|
|
156
|
+
}
|
|
157
|
+
return kind === "product" ? mergeBaseSalesProductSnapshotFields(currentItem, mergedItem) : mergedItem;
|
|
158
|
+
}
|
|
159
|
+
function mergeBaseSalesOrderCollection(kind, currentValue, incomingValue, strategy, uidRemaps) {
|
|
160
|
+
const currentItems = (0, import_orderCollectionIdentity.normalizeOrderCollection)(kind, currentValue, {
|
|
161
|
+
ensureUid: false
|
|
162
|
+
}).items;
|
|
163
|
+
const incomingItems = (0, import_orderCollectionIdentity.normalizeOrderCollection)(kind, incomingValue, {
|
|
164
|
+
ensureUid: false
|
|
165
|
+
}).items;
|
|
166
|
+
if (strategy === "authoritative-incoming") {
|
|
167
|
+
const result2 = (0, import_lodash_es.cloneDeep)(incomingItems);
|
|
168
|
+
currentItems.forEach((currentItem) => {
|
|
169
|
+
const incomingIndex = result2.findIndex(
|
|
170
|
+
(incomingItem) => (0, import_orderCollectionIdentity.isSameOrderCollectionItem)(kind, currentItem, incomingItem)
|
|
171
|
+
);
|
|
172
|
+
if (incomingIndex !== -1) {
|
|
173
|
+
result2[incomingIndex] = mergeBaseSalesCollectionItem(
|
|
174
|
+
kind,
|
|
175
|
+
currentItem,
|
|
176
|
+
result2[incomingIndex],
|
|
177
|
+
uidRemaps
|
|
178
|
+
);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (!(0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, currentItem)) {
|
|
182
|
+
result2.push((0, import_lodash_es.cloneDeep)(currentItem));
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
return result2;
|
|
186
|
+
}
|
|
187
|
+
const result = (0, import_lodash_es.cloneDeep)(currentItems);
|
|
188
|
+
incomingItems.forEach((incomingItem) => {
|
|
189
|
+
const currentIndex = result.findIndex(
|
|
190
|
+
(currentItem) => (0, import_orderCollectionIdentity.isSameOrderCollectionItem)(kind, currentItem, incomingItem)
|
|
191
|
+
);
|
|
192
|
+
if (currentIndex !== -1) {
|
|
193
|
+
result[currentIndex] = mergeBaseSalesCollectionItem(
|
|
194
|
+
kind,
|
|
195
|
+
result[currentIndex],
|
|
196
|
+
incomingItem,
|
|
197
|
+
uidRemaps
|
|
198
|
+
);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
result.push((0, import_lodash_es.cloneDeep)(incomingItem));
|
|
202
|
+
});
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
function normalizeBaseSalesRecordCollections(sourceRecord, options) {
|
|
206
|
+
const normalizedRecord = (0, import_orderCollectionIdentity.normalizeOrderCollections)(
|
|
207
|
+
(0, import_lodash_es.cloneDeep)(sourceRecord || {}),
|
|
208
|
+
options
|
|
209
|
+
).order;
|
|
210
|
+
if (Array.isArray(normalizedRecord.payment)) {
|
|
211
|
+
normalizedRecord.payment = (0, import_orderCollectionIdentity.normalizeOrderCollection)(
|
|
212
|
+
"payment",
|
|
213
|
+
normalizedRecord.payment,
|
|
214
|
+
options
|
|
215
|
+
).items;
|
|
216
|
+
}
|
|
217
|
+
return normalizedRecord;
|
|
218
|
+
}
|
|
219
|
+
function getBaseSalesMetadataUid(item, metadataKey) {
|
|
220
|
+
var _a;
|
|
221
|
+
const uid = ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a[metadataKey]) ?? (item == null ? void 0 : item[metadataKey]);
|
|
222
|
+
if (uid === void 0 || uid === null || uid === "")
|
|
223
|
+
return null;
|
|
224
|
+
return String(uid);
|
|
225
|
+
}
|
|
226
|
+
function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey) {
|
|
124
227
|
const result = [];
|
|
125
228
|
const indexByUid = /* @__PURE__ */ new Map();
|
|
126
229
|
const appendOrReplaceByUid = (item) => {
|
|
@@ -132,7 +235,7 @@ function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey, array
|
|
|
132
235
|
}
|
|
133
236
|
const existingIndex = indexByUid.get(uid);
|
|
134
237
|
if (existingIndex !== void 0) {
|
|
135
|
-
result[existingIndex] =
|
|
238
|
+
result[existingIndex] = clonedItem;
|
|
136
239
|
return;
|
|
137
240
|
}
|
|
138
241
|
indexByUid.set(uid, result.length);
|
|
@@ -142,17 +245,42 @@ function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey, array
|
|
|
142
245
|
loadedValue.forEach(appendOrReplaceByUid);
|
|
143
246
|
return result;
|
|
144
247
|
}
|
|
145
|
-
function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord) {
|
|
146
|
-
|
|
147
|
-
|
|
248
|
+
function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, strategy) {
|
|
249
|
+
const normalizedLoadedRecord = normalizeBaseSalesRecordCollections(
|
|
250
|
+
loadedRecord || {},
|
|
251
|
+
{ ensureUid: false }
|
|
252
|
+
);
|
|
253
|
+
if (!currentTempOrder) {
|
|
254
|
+
return normalizeBaseSalesRecordCollections(normalizedLoadedRecord);
|
|
255
|
+
}
|
|
256
|
+
const normalizedCurrentTempOrder = normalizeBaseSalesRecordCollections(
|
|
257
|
+
currentTempOrder,
|
|
258
|
+
{ ensureUid: false }
|
|
259
|
+
);
|
|
260
|
+
const uidRemaps = [];
|
|
148
261
|
const mergedRecord = (0, import_lodash_es.mergeWith)(
|
|
149
|
-
|
|
150
|
-
|
|
262
|
+
normalizedCurrentTempOrder,
|
|
263
|
+
normalizedLoadedRecord,
|
|
151
264
|
(currentValue, loadedValue, key) => {
|
|
265
|
+
const collectionKind = getBaseSalesOrderCollectionKind(key);
|
|
266
|
+
if (collectionKind && Array.isArray(loadedValue)) {
|
|
267
|
+
return mergeBaseSalesOrderCollection(
|
|
268
|
+
collectionKind,
|
|
269
|
+
Array.isArray(currentValue) ? currentValue : [],
|
|
270
|
+
loadedValue,
|
|
271
|
+
strategy,
|
|
272
|
+
uidRemaps
|
|
273
|
+
);
|
|
274
|
+
}
|
|
152
275
|
if (Array.isArray(currentValue) && Array.isArray(loadedValue)) {
|
|
276
|
+
if (key === "payments" || key === "payment") {
|
|
277
|
+
return (0, import_payment_utils.mergeOrderPaymentListsByIdentity)(currentValue, loadedValue, {
|
|
278
|
+
preserveUnmatchedExisting: true
|
|
279
|
+
});
|
|
280
|
+
}
|
|
153
281
|
const metadataKey = getBaseSalesUniqueArrayMetadataKey(key);
|
|
154
282
|
if (metadataKey) {
|
|
155
|
-
return mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey
|
|
283
|
+
return mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey);
|
|
156
284
|
}
|
|
157
285
|
return [
|
|
158
286
|
...(0, import_lodash_es.cloneDeep)(currentValue),
|
|
@@ -168,7 +296,9 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord) {
|
|
|
168
296
|
}
|
|
169
297
|
);
|
|
170
298
|
delete mergedRecord.request_unique_idempotency_token;
|
|
171
|
-
return
|
|
299
|
+
return normalizeBaseSalesRecordCollections(
|
|
300
|
+
(0, import_orderCollectionIdentity.applyOrderCollectionUidRemaps)(mergedRecord, uidRemaps)
|
|
301
|
+
);
|
|
172
302
|
}
|
|
173
303
|
var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
174
304
|
constructor(name, version) {
|
|
@@ -190,9 +320,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
190
320
|
this.queuedAutoPaymentSync = false;
|
|
191
321
|
this.autoPaymentSyncFlushing = false;
|
|
192
322
|
this.autoPaymentSyncTimer = null;
|
|
193
|
-
this.
|
|
323
|
+
this.salesDetailLoadInFlightCount = 0;
|
|
324
|
+
this.salesDetailLoadSequence = 0;
|
|
325
|
+
this.salesDetailHydrateQueue = Promise.resolve();
|
|
194
326
|
this.serverOrderChangeUnsubscribe = null;
|
|
195
327
|
this.serverOrderChangeHydrateInFlight = null;
|
|
328
|
+
this.queuedServerOrderChanges = [];
|
|
196
329
|
this.serverOrderChangeSyncEnabled = false;
|
|
197
330
|
}
|
|
198
331
|
/**
|
|
@@ -269,22 +402,56 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
269
402
|
}
|
|
270
403
|
setServerOrderChangeSyncEnabled(enabled) {
|
|
271
404
|
this.serverOrderChangeSyncEnabled = enabled;
|
|
405
|
+
if (!enabled)
|
|
406
|
+
this.queuedServerOrderChanges = [];
|
|
407
|
+
}
|
|
408
|
+
queueLatestServerOrderChange(order) {
|
|
409
|
+
const snapshot = (0, import_lodash_es.cloneDeep)(order);
|
|
410
|
+
const existingIndex = this.queuedServerOrderChanges.findIndex(
|
|
411
|
+
(queued) => isSameBaseSalesOrderRecord(queued, snapshot)
|
|
412
|
+
);
|
|
413
|
+
if (existingIndex >= 0) {
|
|
414
|
+
this.queuedServerOrderChanges[existingIndex] = snapshot;
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
this.queuedServerOrderChanges.push(snapshot);
|
|
418
|
+
}
|
|
419
|
+
async drainQueuedServerOrderChanges() {
|
|
420
|
+
if (!this.serverOrderChangeSyncEnabled || this.salesDetailLoadInFlightCount > 0 || this.serverOrderChangeHydrateInFlight || this.queuedServerOrderChanges.length === 0)
|
|
421
|
+
return;
|
|
422
|
+
const changedOrders = this.queuedServerOrderChanges;
|
|
423
|
+
this.queuedServerOrderChanges = [];
|
|
424
|
+
await this.syncCurrentSalesDetailFromServerOrderChange({ changedOrders });
|
|
272
425
|
}
|
|
273
426
|
async syncCurrentSalesDetailFromServerOrderChange(payload) {
|
|
274
427
|
const changedOrders = Array.isArray(payload) ? payload : Array.isArray(payload == null ? void 0 : payload.changedOrders) ? payload.changedOrders : (payload == null ? void 0 : payload.data) && typeof payload.data === "object" ? [payload.data] : [];
|
|
275
|
-
if (!this.serverOrderChangeSyncEnabled
|
|
428
|
+
if (!this.serverOrderChangeSyncEnabled)
|
|
429
|
+
return;
|
|
430
|
+
if (this.salesDetailLoadInFlightCount > 0) {
|
|
431
|
+
changedOrders.forEach(
|
|
432
|
+
(order) => this.queueLatestServerOrderChange(order)
|
|
433
|
+
);
|
|
276
434
|
return;
|
|
435
|
+
}
|
|
277
436
|
const changedOrder = changedOrders.find(
|
|
278
437
|
(order) => this.isCurrentSalesOrderRecord(order)
|
|
279
438
|
);
|
|
280
439
|
if (!changedOrder)
|
|
281
440
|
return;
|
|
441
|
+
if (this.serverOrderChangeHydrateInFlight) {
|
|
442
|
+
this.queueLatestServerOrderChange(changedOrder);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
282
445
|
if (!this.store.order)
|
|
283
446
|
return;
|
|
284
447
|
this.serverOrderChangeHydrateInFlight = (async () => {
|
|
285
448
|
var _a, _b;
|
|
286
449
|
const currentTempOrder = (_b = (_a = this.store.order).getTempOrder) == null ? void 0 : _b.call(_a);
|
|
287
|
-
const record = mergeSalesDetailRecordWithTempOrder(
|
|
450
|
+
const record = mergeSalesDetailRecordWithTempOrder(
|
|
451
|
+
currentTempOrder,
|
|
452
|
+
changedOrder,
|
|
453
|
+
"authoritative-incoming"
|
|
454
|
+
);
|
|
288
455
|
const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
|
|
289
456
|
recalcOnHydrate: false
|
|
290
457
|
});
|
|
@@ -295,6 +462,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
295
462
|
await this.serverOrderChangeHydrateInFlight;
|
|
296
463
|
} finally {
|
|
297
464
|
this.serverOrderChangeHydrateInFlight = null;
|
|
465
|
+
await this.drainQueuedServerOrderChanges();
|
|
298
466
|
}
|
|
299
467
|
}
|
|
300
468
|
registerServerOrderChangeSync() {
|
|
@@ -304,13 +472,42 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
304
472
|
if (!effects || typeof effects.on !== "function")
|
|
305
473
|
return;
|
|
306
474
|
this.serverOrderChangeUnsubscribe = effects.on(SERVER_ORDER_CHANGED_EVENT, (payload) => {
|
|
307
|
-
|
|
475
|
+
return this.syncCurrentSalesDetailFromServerOrderChange(payload).catch((error) => {
|
|
308
476
|
this.logError("sync sales detail from server order change failed", {
|
|
309
477
|
error: error instanceof Error ? error.message : String(error)
|
|
310
478
|
});
|
|
311
479
|
});
|
|
312
480
|
});
|
|
313
481
|
}
|
|
482
|
+
async hydrateLatestLoadedSalesDetail(record, loadSequence) {
|
|
483
|
+
let hydratedSales = null;
|
|
484
|
+
let skippedBeforeHydrate = false;
|
|
485
|
+
const hydrateTask = async () => {
|
|
486
|
+
if (loadSequence !== this.salesDetailLoadSequence) {
|
|
487
|
+
skippedBeforeHydrate = true;
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
if (!this.store.order)
|
|
491
|
+
throw new Error("order 模块未初始化");
|
|
492
|
+
const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
|
|
493
|
+
recalcOnHydrate: false
|
|
494
|
+
});
|
|
495
|
+
hydratedSales = sales;
|
|
496
|
+
if (loadSequence !== this.salesDetailLoadSequence)
|
|
497
|
+
return;
|
|
498
|
+
this.currentSalesDetail = sales;
|
|
499
|
+
await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
|
|
500
|
+
};
|
|
501
|
+
const queuedTask = this.salesDetailHydrateQueue.then(hydrateTask, hydrateTask);
|
|
502
|
+
this.salesDetailHydrateQueue = queuedTask.then(
|
|
503
|
+
() => void 0,
|
|
504
|
+
() => void 0
|
|
505
|
+
);
|
|
506
|
+
await queuedTask;
|
|
507
|
+
if (skippedBeforeHydrate)
|
|
508
|
+
return record;
|
|
509
|
+
return hydratedSales || this.currentSalesDetail || record;
|
|
510
|
+
}
|
|
314
511
|
hydrateOrderPaymentNames(payments) {
|
|
315
512
|
if (!payments.length)
|
|
316
513
|
return [];
|
|
@@ -644,6 +841,16 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
644
841
|
const coreData = (_f = (_d = (_c = app == null ? void 0 : app.models) == null ? void 0 : _c.getStore) == null ? void 0 : (_e = _d.call(_c)).getDataByModel) == null ? void 0 : _f.call(_e, "core", "core");
|
|
645
842
|
return coreData == null ? void 0 : coreData[key];
|
|
646
843
|
}
|
|
844
|
+
getPaymentNumberDevicePrefixSync() {
|
|
845
|
+
if (!this.appPlugin)
|
|
846
|
+
return "LOCAL";
|
|
847
|
+
return (0, import_payment_number.resolvePaymentNumberDevicePrefixFromDeviceId)((key) => this.getAppData(key));
|
|
848
|
+
}
|
|
849
|
+
getPaymentNumberDevicePrefixAsync() {
|
|
850
|
+
if (!this.appPlugin)
|
|
851
|
+
return Promise.resolve("LOCAL");
|
|
852
|
+
return (0, import_payment_number.resolvePaymentNumberDevicePrefix)((key) => this.getAppData(key));
|
|
853
|
+
}
|
|
647
854
|
syncAppDataToTempOrder(tempOrder) {
|
|
648
855
|
const isPriceIncludeTax = this.getAppData("is_price_include_tax");
|
|
649
856
|
const taxCountryCode = this.getAppData("tax_country_code");
|
|
@@ -745,6 +952,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
745
952
|
}
|
|
746
953
|
});
|
|
747
954
|
this.currentSalesDetail = null;
|
|
955
|
+
this.queuedServerOrderChanges = [];
|
|
956
|
+
this.salesDetailLoadSequence += 1;
|
|
748
957
|
await this.core.effects.emit(`${this.name}:onDestroy`, {});
|
|
749
958
|
super.destroy();
|
|
750
959
|
}
|
|
@@ -758,7 +967,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
758
967
|
async loadSalesDetail(orderIdOrParams) {
|
|
759
968
|
if (!this.store.order)
|
|
760
969
|
throw new Error("order 模块未初始化");
|
|
761
|
-
|
|
970
|
+
const loadSequence = ++this.salesDetailLoadSequence;
|
|
971
|
+
this.salesDetailLoadInFlightCount += 1;
|
|
762
972
|
try {
|
|
763
973
|
const params = typeof orderIdOrParams === "object" ? orderIdOrParams : { orderId: orderIdOrParams };
|
|
764
974
|
const externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
|
|
@@ -777,15 +987,26 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
777
987
|
}
|
|
778
988
|
const remoteRecord = preloadedSalesDetail ?? loadedRecord.data;
|
|
779
989
|
const currentTempOrder = params.merge ? this.store.order.getTempOrder() : null;
|
|
780
|
-
const record = params.merge ? mergeSalesDetailRecordWithTempOrder(
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
await this.
|
|
786
|
-
return sales;
|
|
990
|
+
const record = params.merge ? mergeSalesDetailRecordWithTempOrder(
|
|
991
|
+
currentTempOrder,
|
|
992
|
+
remoteRecord,
|
|
993
|
+
"preserve-local"
|
|
994
|
+
) : remoteRecord;
|
|
995
|
+
return await this.hydrateLatestLoadedSalesDetail(record, loadSequence);
|
|
787
996
|
} finally {
|
|
788
|
-
this.
|
|
997
|
+
this.salesDetailLoadInFlightCount = Math.max(
|
|
998
|
+
0,
|
|
999
|
+
this.salesDetailLoadInFlightCount - 1
|
|
1000
|
+
);
|
|
1001
|
+
if (this.salesDetailLoadInFlightCount === 0) {
|
|
1002
|
+
try {
|
|
1003
|
+
await this.drainQueuedServerOrderChanges();
|
|
1004
|
+
} catch (error) {
|
|
1005
|
+
this.logError("drain queued server order changes failed", {
|
|
1006
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
789
1010
|
}
|
|
790
1011
|
}
|
|
791
1012
|
/** 获取当前已加载的销售详情(只读快照)。未加载过则返回 null。 */
|
|
@@ -1552,6 +1773,20 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1552
1773
|
};
|
|
1553
1774
|
return this.store.order.submitTempOrder(submitParams);
|
|
1554
1775
|
}
|
|
1776
|
+
async saveSalesOrderDraft(params) {
|
|
1777
|
+
var _a, _b, _c, _d;
|
|
1778
|
+
if (!this.store.order) {
|
|
1779
|
+
throw new Error("BaseSales 解决方案需要 order 模块支持");
|
|
1780
|
+
}
|
|
1781
|
+
return this.store.order.saveTempOrderAsDraft({
|
|
1782
|
+
cacheId: this.cacheId,
|
|
1783
|
+
platform: (params == null ? void 0 : params.platform) ?? ((_a = this.otherParams) == null ? void 0 : _a.platform),
|
|
1784
|
+
businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
|
|
1785
|
+
channel: (params == null ? void 0 : params.channel) ?? this.getSubmitOrderSalesChannel(),
|
|
1786
|
+
type: (params == null ? void 0 : params.type) ?? ((_d = this.otherParams) == null ? void 0 : _d.type),
|
|
1787
|
+
...(params == null ? void 0 : params.enhancePayload) !== void 0 ? { enhancePayload: params.enhancePayload } : {}
|
|
1788
|
+
});
|
|
1789
|
+
}
|
|
1555
1790
|
async submitTempOrderAsync(params) {
|
|
1556
1791
|
var _a, _b, _c, _d;
|
|
1557
1792
|
if (!this.store.order) {
|
|
@@ -1752,8 +1987,26 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1752
1987
|
}
|
|
1753
1988
|
}
|
|
1754
1989
|
}
|
|
1755
|
-
/**
|
|
1990
|
+
/**
|
|
1991
|
+
* 同步兼容入口。无法等待 IoT 短号时,按调用当下的 device_id 或 LOCAL 生成。
|
|
1992
|
+
*/
|
|
1756
1993
|
addOrderPayment(payment) {
|
|
1994
|
+
const hasPaymentNumber = String(
|
|
1995
|
+
payment.payment_number || ""
|
|
1996
|
+
).trim() !== "";
|
|
1997
|
+
return this.addOrderPaymentWithDevicePrefix(
|
|
1998
|
+
payment,
|
|
1999
|
+
hasPaymentNumber ? "LOCAL" : this.getPaymentNumberDevicePrefixSync()
|
|
2000
|
+
);
|
|
2001
|
+
}
|
|
2002
|
+
/** 创建新支付项时读取最新设备短号,不缓存运行时设备信息。 */
|
|
2003
|
+
async addOrderPaymentAsync(payment) {
|
|
2004
|
+
const paymentRecord = payment;
|
|
2005
|
+
const hasPaymentNumber = String(paymentRecord.payment_number || "").trim() !== "";
|
|
2006
|
+
const devicePrefix = hasPaymentNumber ? "LOCAL" : await this.getPaymentNumberDevicePrefixAsync();
|
|
2007
|
+
return this.addOrderPaymentWithDevicePrefix(payment, devicePrefix);
|
|
2008
|
+
}
|
|
2009
|
+
addOrderPaymentWithDevicePrefix(payment, devicePrefix) {
|
|
1757
2010
|
var _a;
|
|
1758
2011
|
if (!this.store.order)
|
|
1759
2012
|
throw new Error("order 模块未初始化");
|
|
@@ -1770,21 +2023,26 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1770
2023
|
if (shopWalletPassId !== void 0 && shopWalletPassId !== null) {
|
|
1771
2024
|
metadata.shop_wallet_pass_id = shopWalletPassId;
|
|
1772
2025
|
}
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
2026
|
+
const normalizedPaymentRecord = (0, import_payment_utils.ensureOrderPaymentNumber)(
|
|
2027
|
+
paymentRecord,
|
|
2028
|
+
devicePrefix,
|
|
2029
|
+
import_utils.createUuidV4
|
|
2030
|
+
);
|
|
1776
2031
|
const paymentTimestamp = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
1777
2032
|
const paymentTime = paymentRecord.payment_time ?? paymentTimestamp;
|
|
1778
2033
|
const createdAt = paymentRecord.created_at ?? paymentTimestamp;
|
|
1779
2034
|
const serviceCharge = paymentRecord.service_charge && typeof paymentRecord.service_charge === "object" ? paymentRecord.service_charge : null;
|
|
1780
2035
|
const calculatedServiceFee = serviceCharge ? new import_decimal.default(paymentRecord.origin_amount ?? paymentRecord.amount ?? 0).times(serviceCharge.percentage || 0).plus(serviceCharge.amount || 0).toDecimalPlaces(2).toFixed(2) : void 0;
|
|
1781
2036
|
const payments = this.store.order.addOrderPayment({
|
|
1782
|
-
...
|
|
2037
|
+
...normalizedPaymentRecord,
|
|
1783
2038
|
...calculatedServiceFee !== void 0 ? { service_fee: calculatedServiceFee } : {},
|
|
1784
2039
|
metadata,
|
|
1785
2040
|
payment_time: paymentTime,
|
|
1786
2041
|
created_at: createdAt
|
|
1787
2042
|
});
|
|
2043
|
+
if (paymentRecord.status === "payment_pending") {
|
|
2044
|
+
return payments;
|
|
2045
|
+
}
|
|
1788
2046
|
const amountSnapshot = this.store.order.getOrderAmountSnapshot();
|
|
1789
2047
|
const syncState = this.store.order.getOrderSyncState();
|
|
1790
2048
|
if (amountSnapshot) {
|
|
@@ -1806,10 +2064,73 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1806
2064
|
return payments;
|
|
1807
2065
|
}
|
|
1808
2066
|
/** 更新当前订单中的指定支付项。 */
|
|
1809
|
-
updateOrderPayment(paymentIdentity, updates) {
|
|
2067
|
+
async updateOrderPayment(paymentIdentity, updates, options = {}) {
|
|
2068
|
+
var _a, _b, _c;
|
|
1810
2069
|
if (!this.store.order)
|
|
1811
2070
|
throw new Error("order 模块未初始化");
|
|
1812
|
-
|
|
2071
|
+
const matchMode = options.matchBy === "compat" || options.matchBy === "legacy" ? "compat" : "payment_number";
|
|
2072
|
+
const previousMatch = (0, import_payment_utils.resolveOrderPaymentIdentity)(
|
|
2073
|
+
this.store.order.getOrderPayments(),
|
|
2074
|
+
paymentIdentity,
|
|
2075
|
+
matchMode
|
|
2076
|
+
);
|
|
2077
|
+
const previousPayment = previousMatch == null ? void 0 : previousMatch.payment;
|
|
2078
|
+
if ((previousPayment == null ? void 0 : previousPayment.status) === "paid" && !options.applyUpdatesWhenPaid) {
|
|
2079
|
+
const currentPayments = this.store.order.getOrderPayments();
|
|
2080
|
+
let syncResult2;
|
|
2081
|
+
if (options.submitWhenPaid && options.forceSubmitIfPaid) {
|
|
2082
|
+
syncResult2 = await this.syncPaymentsToOrder({
|
|
2083
|
+
payments: currentPayments,
|
|
2084
|
+
paymentStatus: this.getPaymentStatusForSync(currentPayments),
|
|
2085
|
+
submitWhenPaid: true,
|
|
2086
|
+
smallTicketDataFlag: options.smallTicketDataFlag ?? 1
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
return {
|
|
2090
|
+
updated: false,
|
|
2091
|
+
payment: previousPayment,
|
|
2092
|
+
payments: currentPayments,
|
|
2093
|
+
summary: ((_a = this.store.order.getOrderAmountSnapshot()) == null ? void 0 : _a.summary) || null,
|
|
2094
|
+
...syncResult2 !== void 0 ? { syncResult: syncResult2 } : {}
|
|
2095
|
+
};
|
|
2096
|
+
}
|
|
2097
|
+
const result = await this.store.order.updateOrderPayment(paymentIdentity, updates, {
|
|
2098
|
+
matchBy: matchMode
|
|
2099
|
+
});
|
|
2100
|
+
let draftResult;
|
|
2101
|
+
let draftError;
|
|
2102
|
+
if (options.persistDraft !== false) {
|
|
2103
|
+
try {
|
|
2104
|
+
draftResult = await this.saveSalesOrderDraft();
|
|
2105
|
+
} catch (error) {
|
|
2106
|
+
draftError = error;
|
|
2107
|
+
this.logError("updateOrderPayment: 保存支付草稿失败", {
|
|
2108
|
+
paymentIdentity,
|
|
2109
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2110
|
+
});
|
|
2111
|
+
if (!options.submitWhenPaid)
|
|
2112
|
+
throw error;
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
const becamePaid = (previousPayment == null ? void 0 : previousPayment.status) !== "paid" && ((_b = result.payment) == null ? void 0 : _b.status) === "paid";
|
|
2116
|
+
const shouldSubmit = Boolean(
|
|
2117
|
+
options.submitWhenPaid && ((_c = result.payment) == null ? void 0 : _c.status) === "paid" && (becamePaid || options.forceSubmitIfPaid)
|
|
2118
|
+
);
|
|
2119
|
+
let syncResult;
|
|
2120
|
+
if (shouldSubmit) {
|
|
2121
|
+
syncResult = await this.syncPaymentsToOrder({
|
|
2122
|
+
payments: result.payments,
|
|
2123
|
+
paymentStatus: this.getPaymentStatusForSync(result.payments),
|
|
2124
|
+
submitWhenPaid: true,
|
|
2125
|
+
smallTicketDataFlag: options.smallTicketDataFlag ?? 1
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
return {
|
|
2129
|
+
...result,
|
|
2130
|
+
...draftResult !== void 0 ? { draftResult } : {},
|
|
2131
|
+
...draftError !== void 0 ? { draftError } : {},
|
|
2132
|
+
...syncResult !== void 0 ? { syncResult } : {}
|
|
2133
|
+
};
|
|
1813
2134
|
}
|
|
1814
2135
|
/** 删除当前订单中的指定支付项。 */
|
|
1815
2136
|
deleteOrderPayment(paymentIdentity) {
|
|
@@ -1823,6 +2144,11 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1823
2144
|
throw new Error("order 模块未初始化");
|
|
1824
2145
|
return this.store.order.updateVoucherOrderPayments(payments, options);
|
|
1825
2146
|
}
|
|
2147
|
+
async updateVoucherOrderPaymentsAsync(payments, options) {
|
|
2148
|
+
if (!this.store.order)
|
|
2149
|
+
throw new Error("order 模块未初始化");
|
|
2150
|
+
return this.store.order.updateVoucherOrderPaymentsAsync(payments, options);
|
|
2151
|
+
}
|
|
1826
2152
|
confirmPendingVoucherPayments() {
|
|
1827
2153
|
if (!this.store.order)
|
|
1828
2154
|
throw new Error("order 模块未初始化");
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 把 `/order/sales/{id}` 响应(OrderData)解析为 ISalesDetail。
|
|
3
3
|
*
|
|
4
4
|
* - 纯函数:不依赖任何运行时模块/插件,便于单测与 view-model 适配
|
|
5
|
-
* - products 保留 tempOrder /
|
|
5
|
+
* - products 保留 tempOrder / 后端详情原字段,仅规范化集合身份并浅拷贝,避免丢失 product_sku 等协议字段
|
|
6
6
|
* - bookings 平铺保留服务端原顺序,同时输出 byProductUid 反查表与 rootBooking
|
|
7
7
|
* - header 收敛"非数组顶层字段",便于 ticketBooking view-model 直接消费
|
|
8
8
|
*
|
|
@@ -82,8 +82,13 @@ export interface ISalesBooking {
|
|
|
82
82
|
metadata?: Record<string, any> | null;
|
|
83
83
|
[key: string]: any;
|
|
84
84
|
}
|
|
85
|
+
export interface ISalesPaymentMetadata extends Record<string, any> {
|
|
86
|
+
/** 刷卡机设备快照;OS 不解析内部字段 */
|
|
87
|
+
card_reader_snapshot?: Record<string, unknown>;
|
|
88
|
+
}
|
|
85
89
|
export interface ISalesPayment {
|
|
86
90
|
order_payment_id?: number | null;
|
|
91
|
+
payment_number?: string;
|
|
87
92
|
custom_payment_id?: number;
|
|
88
93
|
code?: string;
|
|
89
94
|
name?: string;
|
|
@@ -95,7 +100,7 @@ export interface ISalesPayment {
|
|
|
95
100
|
status?: string;
|
|
96
101
|
payment_time?: string | null;
|
|
97
102
|
service_charge?: Record<string, any> | null;
|
|
98
|
-
metadata?:
|
|
103
|
+
metadata?: ISalesPaymentMetadata | null;
|
|
99
104
|
[key: string]: any;
|
|
100
105
|
}
|
|
101
106
|
export interface ISalesSurcharge {
|
|
@@ -130,7 +135,7 @@ export interface ISalesDetail {
|
|
|
130
135
|
customer: ISalesDetailCustomer | null;
|
|
131
136
|
/** 服务端 summary(仅输出) */
|
|
132
137
|
summary: Record<string, any>;
|
|
133
|
-
/**
|
|
138
|
+
/** 规范化后的响应快照,方便 UI 兜底使用 */
|
|
134
139
|
raw: Record<string, any>;
|
|
135
140
|
}
|
|
136
141
|
/**
|
|
@@ -138,7 +143,7 @@ export interface ISalesDetail {
|
|
|
138
143
|
*
|
|
139
144
|
* 注意:
|
|
140
145
|
* - 入参允许是 `{ data: OrderData }` 或直接 `OrderData`,自动识别。
|
|
141
|
-
* - products
|
|
146
|
+
* - products/bookings/payments 在此补齐集合身份;其余 runtime 字段由 OrderModule hydrate 负责。
|
|
142
147
|
* - 不做远程请求;不修改入参;返回新对象。
|
|
143
148
|
*/
|
|
144
149
|
export declare function parseSalesResponse(input: Record<string, any> | null | undefined): ISalesDetail;
|
|
@@ -22,6 +22,7 @@ __export(parseSalesResponse_exports, {
|
|
|
22
22
|
parseSalesResponse: () => parseSalesResponse
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(parseSalesResponse_exports);
|
|
25
|
+
var import_orderCollectionIdentity = require("../../../modules/Order/utils/orderCollectionIdentity");
|
|
25
26
|
var HEADER_KEYS = [
|
|
26
27
|
"order_id",
|
|
27
28
|
"order_number",
|
|
@@ -121,14 +122,12 @@ function indexBookingsByProductUid(bookings) {
|
|
|
121
122
|
return result;
|
|
122
123
|
}
|
|
123
124
|
function parseSalesResponse(input) {
|
|
124
|
-
const
|
|
125
|
+
const sourceRaw = input && typeof input === "object" && input.data && input.order_id == null ? input.data : input || {};
|
|
126
|
+
const raw = (0, import_orderCollectionIdentity.normalizeOrderCollections)(sourceRaw).order;
|
|
125
127
|
const productsRaw = Array.isArray(raw == null ? void 0 : raw.products) ? raw.products : [];
|
|
126
|
-
const products = productsRaw.map((p
|
|
128
|
+
const products = productsRaw.map((p) => {
|
|
127
129
|
const row = { ...p || {} };
|
|
128
130
|
const metadata = row.metadata && typeof row.metadata === "object" ? { ...row.metadata } : {};
|
|
129
|
-
if (!metadata.unique_identification_number) {
|
|
130
|
-
metadata.unique_identification_number = `sales-product-${row.product_id ?? "unknown"}-${row.product_variant_id ?? 0}-${index}`;
|
|
131
|
-
}
|
|
132
131
|
delete metadata.price_schema_version;
|
|
133
132
|
delete row.identity_key;
|
|
134
133
|
return { ...row, metadata };
|
|
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
311
311
|
date: string;
|
|
312
312
|
status: string;
|
|
313
313
|
week: string;
|
|
314
|
-
weekNum: 0 | 2 | 1 | 6 |
|
|
314
|
+
weekNum: 0 | 2 | 1 | 6 | 4 | 3 | 5;
|
|
315
315
|
}[]>;
|
|
316
316
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
317
317
|
private getScheduleDataByIds;
|