@pisell/pisellos 2.2.309 → 2.2.310
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/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.js +4 -2
- package/dist/modules/BookingContext/index.js +4 -4
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +58 -19
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +24 -12
- package/dist/modules/Customer/index.js +6 -3
- package/dist/modules/Customer/types.d.ts +2 -0
- package/dist/modules/Discount/availability.d.ts +7 -0
- package/dist/modules/Discount/availability.js +49 -0
- package/dist/modules/Discount/entitlementPass.d.ts +34 -0
- package/dist/modules/Discount/entitlementPass.js +147 -0
- package/dist/modules/Discount/index.d.ts +2 -2
- package/dist/modules/Discount/index.js +37 -151
- package/dist/modules/Discount/types.d.ts +36 -5
- package/dist/modules/OpenData/index.d.ts +1 -1
- package/dist/modules/OpenData/index.js +21 -12
- package/dist/modules/Order/index.d.ts +32 -4
- package/dist/modules/Order/index.js +733 -373
- package/dist/modules/Order/types.d.ts +17 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +16 -12
- package/dist/modules/Order/utils.d.ts +14 -2
- package/dist/modules/Order/utils.js +275 -76
- package/dist/modules/Payment/index.d.ts +0 -5
- package/dist/modules/Payment/index.js +35 -85
- package/dist/modules/Payment/types.d.ts +21 -1
- package/dist/modules/Payment/types.js +2 -0
- package/dist/modules/Payment/walletpass.d.ts +1 -1
- package/dist/modules/Payment/walletpass.js +80 -47
- package/dist/modules/ProductList/index.js +18 -5
- package/dist/modules/Rules/index.d.ts +2 -2
- package/dist/modules/Rules/index.js +480 -186
- package/dist/modules/Rules/types.d.ts +4 -0
- package/dist/server/index.js +8 -5
- package/dist/server/modules/order/index.js +6 -0
- package/dist/server/modules/order/types.d.ts +12 -0
- package/dist/server/modules/payment/index.d.ts +25 -6
- package/dist/server/modules/payment/index.js +660 -133
- package/dist/server/utils/small-ticket.d.ts +8 -5
- package/dist/server/utils/small-ticket.js +1269 -199
- package/dist/solution/BaseSales/index.d.ts +11 -2
- package/dist/solution/BaseSales/index.js +1463 -1173
- package/dist/solution/BaseSales/types.d.ts +7 -3
- package/dist/solution/BaseSales/utils/cartPromotion.js +141 -126
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +12 -3
- package/dist/solution/BookingTicket/index.js +663 -542
- package/dist/solution/BookingTicket/types.d.ts +5 -1
- package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +2 -0
- package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +338 -147
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +8 -4
- package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +6 -0
- package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +19 -6
- package/dist/solution/ShopDiscount/index.d.ts +2 -0
- package/dist/solution/ShopDiscount/index.js +99 -42
- package/dist/solution/ShopDiscount/utils.d.ts +4 -2
- package/dist/solution/ShopDiscount/utils.js +43 -23
- package/dist/solution/UnifiedBookingSales/index.d.ts +2 -2
- package/dist/solution/UnifiedBookingSales/index.js +5 -5
- package/dist/utils/os-private-payload.d.ts +5 -0
- package/dist/utils/os-private-payload.js +17 -0
- package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
- package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -0
- package/lib/modules/BookingContext/index.js +3 -3
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +35 -6
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +13 -6
- package/lib/modules/Customer/index.js +5 -1
- package/lib/modules/Customer/types.d.ts +2 -0
- package/lib/modules/Discount/availability.d.ts +7 -0
- package/lib/modules/Discount/availability.js +43 -0
- package/lib/modules/Discount/entitlementPass.d.ts +34 -0
- package/lib/modules/Discount/entitlementPass.js +141 -0
- package/lib/modules/Discount/index.d.ts +2 -2
- package/lib/modules/Discount/index.js +23 -129
- package/lib/modules/Discount/types.d.ts +36 -5
- package/lib/modules/OpenData/index.d.ts +1 -1
- package/lib/modules/OpenData/index.js +11 -2
- package/lib/modules/Order/index.d.ts +32 -4
- package/lib/modules/Order/index.js +341 -71
- package/lib/modules/Order/types.d.ts +17 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +14 -11
- package/lib/modules/Order/utils.d.ts +14 -2
- package/lib/modules/Order/utils.js +186 -3
- package/lib/modules/Payment/index.d.ts +0 -5
- package/lib/modules/Payment/index.js +3 -28
- package/lib/modules/Payment/types.d.ts +21 -1
- package/lib/modules/Payment/types.js +1 -0
- package/lib/modules/Payment/walletpass.d.ts +1 -1
- package/lib/modules/Payment/walletpass.js +29 -9
- package/lib/modules/ProductList/index.js +14 -1
- package/lib/modules/Rules/index.d.ts +2 -2
- package/lib/modules/Rules/index.js +357 -110
- package/lib/modules/Rules/types.d.ts +4 -0
- package/lib/server/index.js +8 -5
- package/lib/server/modules/order/index.js +6 -0
- package/lib/server/modules/order/types.d.ts +12 -0
- package/lib/server/modules/payment/index.d.ts +25 -6
- package/lib/server/modules/payment/index.js +350 -78
- package/lib/server/utils/small-ticket.d.ts +8 -5
- package/lib/server/utils/small-ticket.js +1009 -121
- package/lib/solution/BaseSales/index.d.ts +11 -2
- package/lib/solution/BaseSales/index.js +164 -30
- package/lib/solution/BaseSales/types.d.ts +7 -3
- package/lib/solution/BaseSales/utils/cartPromotion.js +12 -4
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +12 -3
- package/lib/solution/BookingTicket/index.js +103 -41
- package/lib/solution/BookingTicket/types.d.ts +5 -1
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +2 -0
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +174 -42
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +8 -4
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +6 -0
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +11 -3
- package/lib/solution/ShopDiscount/index.d.ts +2 -0
- package/lib/solution/ShopDiscount/index.js +55 -9
- package/lib/solution/ShopDiscount/utils.d.ts +4 -2
- package/lib/solution/ShopDiscount/utils.js +42 -25
- package/lib/solution/UnifiedBookingSales/index.d.ts +2 -2
- package/lib/solution/UnifiedBookingSales/index.js +5 -5
- package/lib/utils/os-private-payload.d.ts +5 -0
- package/lib/utils/os-private-payload.js +22 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Module, ModuleOptions, PisellCore } from '../../types';
|
|
2
2
|
import { BaseModule } from '../../modules/BaseModule';
|
|
3
|
-
import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
|
|
3
|
+
import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentOptions, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
|
|
4
4
|
import { OrderModule } from '../../modules/Order';
|
|
5
5
|
import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions, SalesNote, SalesNotesMutationSnapshot, SetSalesNoteInput, PickupReferenceMode, ShopServiceData, ShopServiceType } from '../../modules/Order/types';
|
|
6
6
|
import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
|
|
@@ -72,6 +72,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
72
72
|
private walletAssetsRefreshSequence;
|
|
73
73
|
private salesDetailHydrateQueue;
|
|
74
74
|
private serverOrderChangeUnsubscribe;
|
|
75
|
+
private paymentMethodsChangedUnsubscribe;
|
|
75
76
|
private serverOrderChangeHydrateInFlight;
|
|
76
77
|
private queuedServerOrderChanges;
|
|
77
78
|
private serverOrderChangeSyncEnabled;
|
|
@@ -101,6 +102,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
101
102
|
private drainQueuedServerOrderChanges;
|
|
102
103
|
private syncCurrentSalesDetailFromServerOrderChange;
|
|
103
104
|
private registerServerOrderChangeSync;
|
|
105
|
+
private registerPaymentMethodsChangeSync;
|
|
104
106
|
private hydrateLatestLoadedSalesDetail;
|
|
105
107
|
private hydrateOrderPaymentNames;
|
|
106
108
|
get payment(): PaymentModule | undefined;
|
|
@@ -271,6 +273,12 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
271
273
|
private mergeHistoricalDiscountList;
|
|
272
274
|
private shouldSkipAutoApplyFetchedDiscountsInEditMode;
|
|
273
275
|
private mergeCurrentDiscountSelectionState;
|
|
276
|
+
private resolveDiscountConfigCustomerId;
|
|
277
|
+
/**
|
|
278
|
+
* Stable across notifyTempOrderChanged's immutable object replacement, while
|
|
279
|
+
* still distinguishing two local orders for the same customer.
|
|
280
|
+
*/
|
|
281
|
+
private getDiscountConfigOrderIdentityKey;
|
|
274
282
|
loadDiscountConfig(params?: {
|
|
275
283
|
customerId?: number;
|
|
276
284
|
action?: 'create' | 'edit';
|
|
@@ -407,6 +415,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
407
415
|
refreshWalletAssets(params?: {
|
|
408
416
|
order_wait_pay_amount?: number;
|
|
409
417
|
preserveSelection?: boolean;
|
|
418
|
+
retainSearchResultCodes?: string[];
|
|
410
419
|
}): Promise<WalletAssetsState>;
|
|
411
420
|
/** 选择或取消单张钱包资产,并立即同步 pending wallet payments。 */
|
|
412
421
|
selectWalletAsset(params: {
|
|
@@ -442,7 +451,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
442
451
|
private findCashPaymentMethod;
|
|
443
452
|
private getPendingWalletPaymentAmount;
|
|
444
453
|
/** 读取现金 action 所需的支付方式、待付金额和快捷金额。 */
|
|
445
|
-
getCashPaymentConfig(): Promise<BaseSalesCashPaymentConfig>;
|
|
454
|
+
getCashPaymentConfig(options?: BaseSalesCashPaymentOptions): Promise<BaseSalesCashPaymentConfig>;
|
|
446
455
|
/**
|
|
447
456
|
* 确认足额覆盖订单的 pending Wallet 支付并提交订单。
|
|
448
457
|
*
|
|
@@ -37,6 +37,7 @@ var _transformBaseProductToOrderProduct = require("./utils/transformBaseProductT
|
|
|
37
37
|
var _quotationPrice = require("./utils/quotationPrice");
|
|
38
38
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
39
39
|
const SERVER_ORDER_CHANGED_EVENT = 'order:onOrdersChanged';
|
|
40
|
+
const PAYMENT_METHODS_CHANGED_EVENT = 'payment:onPaymentMethodsChanged';
|
|
40
41
|
const OS_FULFILLMENT_REF_MODE_FIELD = '_os_fulfillment_ref_mode';
|
|
41
42
|
const OS_INVOICE_LAYOUT_CONFIG_FIELD = '_os_invoice_layout_config';
|
|
42
43
|
const OS_INVOICE_TEMPLATE_SETTINGS_FIELD = '_os_invoice_template_settings';
|
|
@@ -345,6 +346,7 @@ function areBaseSalesNotesEquivalent(currentValue, loadedValue, options) {
|
|
|
345
346
|
return currentNotes !== null && loadedNotes !== null && (0, _lodashEs.isEqual)(currentNotes, loadedNotes);
|
|
346
347
|
}
|
|
347
348
|
function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, strategy) {
|
|
349
|
+
const loadedHasOrderMetaList = Object.prototype.hasOwnProperty.call(loadedRecord || {}, 'order_meta_list');
|
|
348
350
|
const loadedHasSalesNotes = Object.prototype.hasOwnProperty.call(loadedRecord || {}, 'notes');
|
|
349
351
|
const hasDirtyLocalSalesNotes = currentTempOrder?._extend?.salesNotesState?.dirty === true;
|
|
350
352
|
const incomingSalesNotesMatchLocal = loadedHasSalesNotes && areBaseSalesNotesEquivalent(currentTempOrder?.notes, loadedRecord.notes, {
|
|
@@ -363,6 +365,12 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, str
|
|
|
363
365
|
});
|
|
364
366
|
const uidRemaps = [];
|
|
365
367
|
const mergedRecord = (0, _lodashEs.mergeWith)(normalizedCurrentTempOrder, normalizedLoadedRecord, (currentValue, loadedValue, key) => {
|
|
368
|
+
// order_meta_list 是服务端/本地订单携带的完整业务快照。若 incoming
|
|
369
|
+
// 明确提供它,必须整体替换;若省略,则保留当前值,避免 snapshot
|
|
370
|
+
// 数组递归拼接后出现同 ID 的旧数据。
|
|
371
|
+
if (key === 'order_meta_list') {
|
|
372
|
+
return (0, _lodashEs.cloneDeep)(loadedHasOrderMetaList ? loadedValue : currentValue);
|
|
373
|
+
}
|
|
366
374
|
if (key === 'notes') {
|
|
367
375
|
if (preserveDirtyLocalSalesNotes && Array.isArray(currentValue)) {
|
|
368
376
|
return (0, _lodashEs.cloneDeep)(currentValue);
|
|
@@ -487,6 +495,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
487
495
|
walletAssetsRefreshSequence = 0;
|
|
488
496
|
salesDetailHydrateQueue = Promise.resolve();
|
|
489
497
|
serverOrderChangeUnsubscribe = null;
|
|
498
|
+
paymentMethodsChangedUnsubscribe = null;
|
|
490
499
|
serverOrderChangeHydrateInFlight = null;
|
|
491
500
|
queuedServerOrderChanges = [];
|
|
492
501
|
serverOrderChangeSyncEnabled = false;
|
|
@@ -630,6 +639,15 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
630
639
|
});
|
|
631
640
|
});
|
|
632
641
|
}
|
|
642
|
+
registerPaymentMethodsChangeSync() {
|
|
643
|
+
this.paymentMethodsChangedUnsubscribe?.();
|
|
644
|
+
const effects = this.core?.effects;
|
|
645
|
+
if (!effects || typeof effects.on !== 'function') return;
|
|
646
|
+
this.paymentMethodsChangedUnsubscribe = effects.on(PAYMENT_METHODS_CHANGED_EVENT, async payload => {
|
|
647
|
+
if (!Array.isArray(payload?.newMethods)) return;
|
|
648
|
+
await this.getPaymentMethodsAsync();
|
|
649
|
+
});
|
|
650
|
+
}
|
|
633
651
|
async hydrateLatestLoadedSalesDetail(record, loadSequence, options) {
|
|
634
652
|
let hydratedSales = null;
|
|
635
653
|
let skippedBeforeHydrate = false;
|
|
@@ -1331,9 +1349,22 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1331
1349
|
}
|
|
1332
1350
|
syncAppDataToTempOrder(tempOrder) {
|
|
1333
1351
|
const isPriceIncludeTax = this.getAppData('is_price_include_tax');
|
|
1334
|
-
const
|
|
1335
|
-
const
|
|
1336
|
-
const
|
|
1352
|
+
const rawTaxCountryCode = this.getAppData('tax_country_code');
|
|
1353
|
+
const rawCurrencyCode = this.getAppData('shop_currency_code');
|
|
1354
|
+
const rawCurrencySymbol = this.getAppData('shop_symbol');
|
|
1355
|
+
const normalizeNonBlankValue = value => {
|
|
1356
|
+
if (value === undefined || value === null) return undefined;
|
|
1357
|
+
const normalizedValue = String(value).trim();
|
|
1358
|
+
return normalizedValue || undefined;
|
|
1359
|
+
};
|
|
1360
|
+
const taxCountryCode = normalizeNonBlankValue(rawTaxCountryCode);
|
|
1361
|
+
const currencyCode = normalizeNonBlankValue(rawCurrencyCode);
|
|
1362
|
+
const currencySymbol = normalizeNonBlankValue(rawCurrencySymbol);
|
|
1363
|
+
const before = {
|
|
1364
|
+
tax_country_code: tempOrder.tax_country_code,
|
|
1365
|
+
currency_code: tempOrder.currency_code,
|
|
1366
|
+
currency_symbol: tempOrder.currency_symbol
|
|
1367
|
+
};
|
|
1337
1368
|
// 历史虚拟币订单不依赖交易开关;普通 POS 不从商品行残留快照推断订单币种。
|
|
1338
1369
|
const isHistoricalVirtualSettlement = this.isHistoricalVirtualSettlementOrder(tempOrder);
|
|
1339
1370
|
const isVirtualSettlement = this.isActiveVirtualSettlementOrder(tempOrder) || isHistoricalVirtualSettlement;
|
|
@@ -1347,9 +1378,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1347
1378
|
}
|
|
1348
1379
|
}
|
|
1349
1380
|
if (taxCountryCode !== undefined) {
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
tempOrder.tax_country_code = nextTaxCountryCode;
|
|
1381
|
+
if (tempOrder.tax_country_code !== taxCountryCode) {
|
|
1382
|
+
tempOrder.tax_country_code = taxCountryCode;
|
|
1353
1383
|
isChanged = true;
|
|
1354
1384
|
}
|
|
1355
1385
|
}
|
|
@@ -1366,19 +1396,45 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1366
1396
|
}
|
|
1367
1397
|
}
|
|
1368
1398
|
if (!isVirtualSettlement && currencyCode !== undefined) {
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
tempOrder.currency_code = nextCurrencyCode;
|
|
1399
|
+
if (tempOrder.currency_code !== currencyCode) {
|
|
1400
|
+
tempOrder.currency_code = currencyCode;
|
|
1372
1401
|
isChanged = true;
|
|
1373
1402
|
}
|
|
1374
1403
|
}
|
|
1375
1404
|
if (!isVirtualSettlement && currencySymbol !== undefined) {
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
tempOrder.currency_symbol = nextCurrencySymbol;
|
|
1405
|
+
if (tempOrder.currency_symbol !== currencySymbol) {
|
|
1406
|
+
tempOrder.currency_symbol = currencySymbol;
|
|
1379
1407
|
isChanged = true;
|
|
1380
1408
|
}
|
|
1381
1409
|
}
|
|
1410
|
+
try {
|
|
1411
|
+
const orderIdentity = this.store.order?.getOrderIdentity?.();
|
|
1412
|
+
this.logger?.addLog?.({
|
|
1413
|
+
type: 'info',
|
|
1414
|
+
title: 'syncAppDataToTempOrder',
|
|
1415
|
+
metadata: {
|
|
1416
|
+
moduleName: this.name,
|
|
1417
|
+
cacheId: this.cacheId,
|
|
1418
|
+
orderId: orderIdentity?.orderId ?? tempOrder.order_id,
|
|
1419
|
+
externalSaleNumber: orderIdentity?.externalSaleNumber ?? tempOrder.external_sale_number,
|
|
1420
|
+
shopOrderNumber: orderIdentity?.shopOrderNumber ?? tempOrder.shop_order_number,
|
|
1421
|
+
readValues: {
|
|
1422
|
+
tax_country_code: rawTaxCountryCode,
|
|
1423
|
+
shop_currency_code: rawCurrencyCode,
|
|
1424
|
+
shop_symbol: rawCurrencySymbol
|
|
1425
|
+
},
|
|
1426
|
+
before,
|
|
1427
|
+
after: {
|
|
1428
|
+
tax_country_code: tempOrder.tax_country_code,
|
|
1429
|
+
currency_code: tempOrder.currency_code,
|
|
1430
|
+
currency_symbol: tempOrder.currency_symbol
|
|
1431
|
+
},
|
|
1432
|
+
isChanged
|
|
1433
|
+
}
|
|
1434
|
+
});
|
|
1435
|
+
} catch {
|
|
1436
|
+
// 诊断日志不能影响订单字段同步。
|
|
1437
|
+
}
|
|
1382
1438
|
return isChanged;
|
|
1383
1439
|
}
|
|
1384
1440
|
async initialize(core, options = {}) {
|
|
@@ -1429,12 +1485,15 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1429
1485
|
this.store.order.setEnableTempOrderPersist(this.otherParams.enableTempOrderPersist);
|
|
1430
1486
|
}
|
|
1431
1487
|
await this.getPaymentMethodsAsync();
|
|
1488
|
+
this.registerPaymentMethodsChangeSync();
|
|
1432
1489
|
this.registerServerOrderChangeSync();
|
|
1433
1490
|
this.core.effects.emit(`${this.name}:onInited`, {});
|
|
1434
1491
|
}
|
|
1435
1492
|
async destroy() {
|
|
1436
1493
|
this.serverOrderChangeUnsubscribe?.();
|
|
1437
1494
|
this.serverOrderChangeUnsubscribe = null;
|
|
1495
|
+
this.paymentMethodsChangedUnsubscribe?.();
|
|
1496
|
+
this.paymentMethodsChangedUnsubscribe = null;
|
|
1438
1497
|
Object.keys(this.store).forEach(key => {
|
|
1439
1498
|
if (this.reusedSharedSubModuleNames.has(key)) return;
|
|
1440
1499
|
const sub = this.store[key];
|
|
@@ -1790,7 +1849,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1790
1849
|
if (!this.isPersistedOrderProduct(item)) return;
|
|
1791
1850
|
(item.discount_list || []).forEach(discount => {
|
|
1792
1851
|
const discountId = discount.discount?.resource_id || discount.id;
|
|
1793
|
-
if (!discountId || !['good_pass', 'discount_card'].includes(discount.type)) return;
|
|
1852
|
+
if (!discountId || !['entitlement_pass', 'good_pass', 'discount_card'].includes(discount.type)) return;
|
|
1794
1853
|
const quantity = item.quantity || item.num || item.product_quantity || 1;
|
|
1795
1854
|
const savedAmount = new _decimal.default(discount.amount || 0).times(quantity).plus(discount?.metadata?.product_discount_difference || 0);
|
|
1796
1855
|
const index = historyDiscountList.findIndex(n => n.id === discountId);
|
|
@@ -1882,19 +1941,46 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1882
1941
|
return discount;
|
|
1883
1942
|
});
|
|
1884
1943
|
}
|
|
1944
|
+
resolveDiscountConfigCustomerId(tempOrder) {
|
|
1945
|
+
return Number(tempOrder?.customer_id || tempOrder?.customer?.id || tempOrder?._extend?.customerSnapshot?.id || tempOrder?._extend?.customerSnapshot?.customer_id || 0);
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
/**
|
|
1949
|
+
* Stable across notifyTempOrderChanged's immutable object replacement, while
|
|
1950
|
+
* still distinguishing two local orders for the same customer.
|
|
1951
|
+
*/
|
|
1952
|
+
getDiscountConfigOrderIdentityKey(tempOrder) {
|
|
1953
|
+
const identity = this.store.order?.getOrderIdentity?.();
|
|
1954
|
+
return JSON.stringify([identity?.orderId ?? tempOrder?.order_id ?? '', tempOrder?.request_unique_idempotency_token ?? '', identity?.externalSaleNumber ?? tempOrder?.external_sale_number ?? '', identity?.localId ?? tempOrder?._extend?.localId ?? this.cacheId ?? '']);
|
|
1955
|
+
}
|
|
1885
1956
|
async loadDiscountConfig(params) {
|
|
1886
1957
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1887
1958
|
const tempOrder = this.store.order.ensureTempOrder();
|
|
1888
1959
|
const orderStore = this.store.order.store || {};
|
|
1889
1960
|
const discountModule = orderStore.discount;
|
|
1890
1961
|
const rulesModule = orderStore.rules;
|
|
1891
|
-
const orderId = tempOrder.order_id || this.getOrderIdentity?.()?.orderId;
|
|
1962
|
+
const orderId = tempOrder.order_id || this.store.order.getOrderIdentity?.()?.orderId;
|
|
1892
1963
|
const customerId = Number(params?.customerId || tempOrder.customer_id || tempOrder.customer?.id || tempOrder._extend?.customerSnapshot?.id || tempOrder._extend?.customerSnapshot?.customer_id || 0);
|
|
1893
1964
|
const currentDiscountList = discountModule?.getDiscountList?.() || [];
|
|
1894
1965
|
const originalDiscountList = discountModule?.getOriginalDiscountList?.() || [];
|
|
1895
1966
|
const hasManualDiscountSelection = this.hasManualDiscountSelection || currentDiscountList.some(discount => discount.isManualSelect);
|
|
1896
1967
|
const discountAction = params?.action || (orderId ? 'edit' : 'create');
|
|
1897
|
-
const
|
|
1968
|
+
const requestOrderIdentityKey = this.getDiscountConfigOrderIdentityKey(tempOrder);
|
|
1969
|
+
const discountConfigCacheKey = JSON.stringify([customerId, discountAction, Number(orderId) || 0, requestOrderIdentityKey]);
|
|
1970
|
+
let requestEpoch = this.store.order.getCustomerWalletPrepareConfigEpoch?.();
|
|
1971
|
+
const isCurrentRequest = () => {
|
|
1972
|
+
const currentTempOrder = this.store.order?.getTempOrder?.();
|
|
1973
|
+
return Boolean(currentTempOrder && (requestEpoch === undefined || this.store.order?.getCustomerWalletPrepareConfigEpoch?.() === requestEpoch) && this.resolveDiscountConfigCustomerId(currentTempOrder) === customerId && this.getDiscountConfigOrderIdentityKey(currentTempOrder) === requestOrderIdentityKey);
|
|
1974
|
+
};
|
|
1975
|
+
const getCurrentResult = () => {
|
|
1976
|
+
const currentTempOrder = this.store.order?.getTempOrder?.();
|
|
1977
|
+
return {
|
|
1978
|
+
productList: currentTempOrder?.products || [],
|
|
1979
|
+
discountList: discountModule?.getDiscountList?.() || [],
|
|
1980
|
+
availableWalletIds: this.getAvailableWalletIds(),
|
|
1981
|
+
virtualCurrencyList: this.getVirtualCurrencyList()
|
|
1982
|
+
};
|
|
1983
|
+
};
|
|
1898
1984
|
|
|
1899
1985
|
// Walk-In 不请求 prepare config;当前搜索/扫码券必须继续参与本次重算。
|
|
1900
1986
|
// current 优先于 original,保留搜索后的最新选择与可用状态。
|
|
@@ -1905,26 +1991,34 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1905
1991
|
if (!params?.force && this.discountConfigCacheKey === discountConfigCacheKey) {
|
|
1906
1992
|
preparedDiscountList = originalDiscountList;
|
|
1907
1993
|
} else {
|
|
1908
|
-
|
|
1994
|
+
const prepareConfigPromise = this.store.order.loadDiscountConfig({
|
|
1909
1995
|
customerId,
|
|
1910
1996
|
action: discountAction,
|
|
1911
1997
|
orderId: Number(orderId) || undefined,
|
|
1912
1998
|
apply: false
|
|
1913
1999
|
});
|
|
1914
|
-
this
|
|
2000
|
+
// OrderModule increments this epoch synchronously before its first await.
|
|
2001
|
+
requestEpoch = this.store.order.getCustomerWalletPrepareConfigEpoch?.();
|
|
2002
|
+
preparedDiscountList = await prepareConfigPromise;
|
|
2003
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1915
2004
|
await discountModule?.setOriginalDiscountList?.(preparedDiscountList);
|
|
2005
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
2006
|
+
this.discountConfigCacheKey = discountConfigCacheKey;
|
|
1916
2007
|
}
|
|
1917
2008
|
}
|
|
1918
2009
|
if (this.isActiveVirtualSettlementOrder(tempOrder)) {
|
|
2010
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1919
2011
|
await discountModule?.setOriginalDiscountList?.([]);
|
|
2012
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1920
2013
|
await discountModule?.setDiscountList?.([]);
|
|
2014
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1921
2015
|
tempOrder.discount_list = [];
|
|
1922
2016
|
tempOrder.shop_discount = '0.00';
|
|
1923
2017
|
return {
|
|
1924
2018
|
productList: tempOrder.products || [],
|
|
1925
2019
|
discountList: [],
|
|
1926
2020
|
availableWalletIds: this.getAvailableWalletIds(),
|
|
1927
|
-
virtualCurrencyList: this.
|
|
2021
|
+
virtualCurrencyList: this.getVirtualCurrencyList()
|
|
1928
2022
|
};
|
|
1929
2023
|
}
|
|
1930
2024
|
if (hasManualDiscountSelection && currentDiscountList.length) {
|
|
@@ -1932,12 +2026,14 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1932
2026
|
productList: tempOrder.products || [],
|
|
1933
2027
|
discountList: currentDiscountList,
|
|
1934
2028
|
availableWalletIds: this.getAvailableWalletIds(),
|
|
1935
|
-
virtualCurrencyList: this.
|
|
2029
|
+
virtualCurrencyList: this.getVirtualCurrencyList()
|
|
1936
2030
|
};
|
|
1937
2031
|
}
|
|
1938
2032
|
let nextDiscountList = this.mergeHistoricalDiscountList(preparedDiscountList || discountModule?.getDiscountList?.() || [], tempOrder.products || []);
|
|
1939
2033
|
nextDiscountList = this.mergeCurrentDiscountSelectionState(nextDiscountList, currentDiscountList);
|
|
2034
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1940
2035
|
await discountModule?.setDiscountList(nextDiscountList);
|
|
2036
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1941
2037
|
const shouldSkipAutoApplyFetchedDiscounts = this.shouldSkipAutoApplyFetchedDiscountsInEditMode({
|
|
1942
2038
|
discountAction,
|
|
1943
2039
|
products: tempOrder.products || [],
|
|
@@ -1945,24 +2041,28 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1945
2041
|
nextDiscountList
|
|
1946
2042
|
});
|
|
1947
2043
|
if (shouldSkipAutoApplyFetchedDiscounts) {
|
|
1948
|
-
|
|
2044
|
+
await this.store.order.recalculateSummary({
|
|
1949
2045
|
createIfMissing: true
|
|
1950
2046
|
});
|
|
2047
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1951
2048
|
this.store.order.persistTempOrder();
|
|
2049
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1952
2050
|
await this.effectsEmit('onDiscountApplied', {
|
|
1953
2051
|
productList: tempOrder.products || [],
|
|
1954
2052
|
discountList: nextDiscountList,
|
|
1955
2053
|
selectedDiscountList: tempOrder.discount_list || [],
|
|
1956
2054
|
tempOrder
|
|
1957
2055
|
});
|
|
2056
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1958
2057
|
return {
|
|
1959
2058
|
productList: tempOrder.products || [],
|
|
1960
2059
|
discountList: nextDiscountList,
|
|
1961
2060
|
availableWalletIds: this.getAvailableWalletIds(),
|
|
1962
|
-
virtualCurrencyList: this.
|
|
2061
|
+
virtualCurrencyList: this.getVirtualCurrencyList()
|
|
1963
2062
|
};
|
|
1964
2063
|
}
|
|
1965
2064
|
if (rulesModule) {
|
|
2065
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
1966
2066
|
const orderTotalAmount = Number(orderStore.summary?.total_amount || 0);
|
|
1967
2067
|
const result = rulesModule.calcDiscount({
|
|
1968
2068
|
productList: tempOrder.products,
|
|
@@ -1998,25 +2098,31 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1998
2098
|
if (result.discountList) {
|
|
1999
2099
|
nextDiscountList = this.mergeHistoricalDiscountList(result.discountList, tempOrder.products || []);
|
|
2000
2100
|
_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
|
|
2101
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
2001
2102
|
await discountModule?.setDiscountList(nextDiscountList);
|
|
2103
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
2002
2104
|
tempOrder.discount_list = nextDiscountList.filter(discount => discount.isSelected);
|
|
2003
2105
|
}
|
|
2004
2106
|
}
|
|
2005
|
-
|
|
2107
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
2108
|
+
await this.store.order.recalculateSummary({
|
|
2006
2109
|
createIfMissing: true
|
|
2007
2110
|
});
|
|
2111
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
2008
2112
|
this.store.order.persistTempOrder();
|
|
2113
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
2009
2114
|
await this.effectsEmit('onDiscountApplied', {
|
|
2010
2115
|
productList: tempOrder.products || [],
|
|
2011
2116
|
discountList: nextDiscountList,
|
|
2012
2117
|
selectedDiscountList: tempOrder.discount_list || [],
|
|
2013
2118
|
tempOrder
|
|
2014
2119
|
});
|
|
2120
|
+
if (!isCurrentRequest()) return getCurrentResult();
|
|
2015
2121
|
return {
|
|
2016
2122
|
productList: tempOrder.products || [],
|
|
2017
2123
|
discountList: nextDiscountList,
|
|
2018
2124
|
availableWalletIds: this.getAvailableWalletIds(),
|
|
2019
|
-
virtualCurrencyList: this.
|
|
2125
|
+
virtualCurrencyList: this.getVirtualCurrencyList()
|
|
2020
2126
|
};
|
|
2021
2127
|
}
|
|
2022
2128
|
getAvailableWalletIds() {
|
|
@@ -2057,6 +2163,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2057
2163
|
holders: [],
|
|
2058
2164
|
isFormSubject: product => (0, _utils.resolveIsFormSubject)(tempOrder, product),
|
|
2059
2165
|
orderTotalAmount
|
|
2166
|
+
}, {
|
|
2167
|
+
preserveEntitlementSelection: false
|
|
2060
2168
|
}) || result;
|
|
2061
2169
|
if (result.productList) {
|
|
2062
2170
|
tempOrder.products = preserveManualProductDiscountProducts(tempOrder.products, result.productList);
|
|
@@ -2972,6 +3080,10 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2972
3080
|
};
|
|
2973
3081
|
}
|
|
2974
3082
|
const result = await this.store.payment.wallet.initializeWalletDataFromBusinessAsync(walletBusinessData);
|
|
3083
|
+
this.store.order.mergePointCardSnapshotCodes?.(result.userIdentificationCodes, {
|
|
3084
|
+
customerId: walletBusinessData.customer_id,
|
|
3085
|
+
orderIdentity: snapshot?.identity
|
|
3086
|
+
});
|
|
2975
3087
|
await this.core.effects.emit(`${this.name}:onWalletDataInitialized`, {
|
|
2976
3088
|
orderId: snapshot?.identity?.orderId,
|
|
2977
3089
|
customerId: walletBusinessData.customer_id,
|
|
@@ -3098,6 +3210,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3098
3210
|
async importWalletAssetsSnapshot(snapshot) {
|
|
3099
3211
|
if (!this.store.payment) throw new Error('payment 模块未初始化');
|
|
3100
3212
|
const state = this.store.payment.wallet.importWalletAssetsSnapshot(snapshot);
|
|
3213
|
+
this.store.order?.mergePointCardSnapshotCodes?.(state.items);
|
|
3101
3214
|
await this.syncSelectedWalletAssets(state);
|
|
3102
3215
|
return this.publishWalletAssetsState(state);
|
|
3103
3216
|
}
|
|
@@ -3119,6 +3232,10 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3119
3232
|
});
|
|
3120
3233
|
return this.publishWalletAssetsState(emptyState);
|
|
3121
3234
|
}
|
|
3235
|
+
const pointCardSnapshotMergeContext = {
|
|
3236
|
+
customerId: businessData.customer_id,
|
|
3237
|
+
orderIdentity: this.store.order.getOrderSnapshot()?.identity
|
|
3238
|
+
};
|
|
3122
3239
|
const previousState = wallet.getWalletAssetsState();
|
|
3123
3240
|
const hasPreviousWalletContext = previousState.status !== 'idle' || previousState.items.length > 0 || previousState.selectedIds.length > 0 || previousState.customerId !== undefined;
|
|
3124
3241
|
const customerChanged = hasPreviousWalletContext && String(previousState.customerId ?? '') !== String(businessData.customer_id ?? '');
|
|
@@ -3130,7 +3247,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3130
3247
|
await this.publishWalletAssetsState(clearedState);
|
|
3131
3248
|
}
|
|
3132
3249
|
const refreshTask = wallet.refreshWalletAssetsFromBusinessAsync(businessData, {
|
|
3133
|
-
preserveSelection: params?.preserveSelection !== false && !customerChanged
|
|
3250
|
+
preserveSelection: params?.preserveSelection !== false && !customerChanged,
|
|
3251
|
+
retainSearchResultCodes: params?.retainSearchResultCodes
|
|
3134
3252
|
});
|
|
3135
3253
|
await this.publishWalletAssetsState(wallet.getWalletAssetsState());
|
|
3136
3254
|
let state = await refreshTask;
|
|
@@ -3140,6 +3258,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3140
3258
|
if (state.status !== 'error') {
|
|
3141
3259
|
const committed = this.getCommittedWalletAssets();
|
|
3142
3260
|
state = wallet.setCommittedWalletAssets(committed.ids, committed.assets);
|
|
3261
|
+
this.store.order.mergePointCardSnapshotCodes?.(wallet.getUserIdentificationCodes?.() || [], pointCardSnapshotMergeContext);
|
|
3143
3262
|
}
|
|
3144
3263
|
await this.syncSelectedWalletAssets(state);
|
|
3145
3264
|
return this.publishWalletAssetsState(state);
|
|
@@ -3197,7 +3316,13 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3197
3316
|
*/
|
|
3198
3317
|
updateOrderCustomer(customer) {
|
|
3199
3318
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
3319
|
+
const previousCustomerId = this.resolveDiscountConfigCustomerId(this.store.order.getTempOrder?.());
|
|
3200
3320
|
const result = this.store.order.updateTempOrderCustomer(customer);
|
|
3321
|
+
const nextCustomerId = this.resolveDiscountConfigCustomerId(this.store.order.getTempOrder?.());
|
|
3322
|
+
if (String(previousCustomerId) !== String(nextCustomerId)) {
|
|
3323
|
+
this.discountConfigCacheKey = null;
|
|
3324
|
+
this.hasManualDiscountSelection = false;
|
|
3325
|
+
}
|
|
3201
3326
|
this.store.order.recalculateSummary({
|
|
3202
3327
|
createIfMissing: true
|
|
3203
3328
|
});
|
|
@@ -3231,10 +3356,14 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3231
3356
|
getPaymentMethods() {
|
|
3232
3357
|
return [...this.paymentMethodsCache];
|
|
3233
3358
|
}
|
|
3234
|
-
findCashPaymentMethod(paymentMethods) {
|
|
3359
|
+
findCashPaymentMethod(paymentMethods, paymentMethodId) {
|
|
3235
3360
|
return paymentMethods.find(method => {
|
|
3361
|
+
if (method?.enabled === false || method?.enable === false) return false;
|
|
3236
3362
|
const identifiers = [method?.code, method?.type, method?.tag].map(value => String(value || '').toUpperCase());
|
|
3237
|
-
|
|
3363
|
+
const isDefaultCash = identifiers.includes('CASHMANUAL');
|
|
3364
|
+
if (paymentMethodId === undefined) return isDefaultCash;
|
|
3365
|
+
const isCustomCash = String(method?.type || '').trim().toLowerCase() === 'custom' && [method?.name, method?.nameEn].some(name => typeof name === 'string' && /现金|現金|cash/i.test(name));
|
|
3366
|
+
return String(method?.id) === String(paymentMethodId) && (isDefaultCash || isCustomCash);
|
|
3238
3367
|
});
|
|
3239
3368
|
}
|
|
3240
3369
|
getPendingWalletPaymentAmount(payments = this.store.order?.getOrderPayments?.() || []) {
|
|
@@ -3251,13 +3380,16 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3251
3380
|
}
|
|
3252
3381
|
|
|
3253
3382
|
/** 读取现金 action 所需的支付方式、待付金额和快捷金额。 */
|
|
3254
|
-
async getCashPaymentConfig() {
|
|
3383
|
+
async getCashPaymentConfig(options = {}) {
|
|
3255
3384
|
if (!this.store.payment) throw new Error('payment 模块未初始化');
|
|
3256
3385
|
let paymentMethods = this.getPaymentMethods();
|
|
3257
|
-
let paymentMethod = this.findCashPaymentMethod(paymentMethods);
|
|
3386
|
+
let paymentMethod = this.findCashPaymentMethod(paymentMethods, options.paymentMethodId);
|
|
3258
3387
|
if (!paymentMethod) {
|
|
3259
3388
|
paymentMethods = await this.getPaymentMethodsAsync();
|
|
3260
|
-
paymentMethod = this.findCashPaymentMethod(paymentMethods);
|
|
3389
|
+
paymentMethod = this.findCashPaymentMethod(paymentMethods, options.paymentMethodId);
|
|
3390
|
+
}
|
|
3391
|
+
if (!paymentMethod && options.paymentMethodId !== undefined) {
|
|
3392
|
+
throw new Error(`未找到可用的现金支付方式:${options.paymentMethodId}`);
|
|
3261
3393
|
}
|
|
3262
3394
|
const amountSnapshot = this.store.order?.getOrderAmountSnapshot?.();
|
|
3263
3395
|
const pendingWalletAmount = this.getPendingWalletPaymentAmount();
|
|
@@ -3355,7 +3487,9 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3355
3487
|
if (!Number.isFinite(amount) || amount <= 0) {
|
|
3356
3488
|
throw new Error('现金支付金额必须大于 0');
|
|
3357
3489
|
}
|
|
3358
|
-
const config = await this.getCashPaymentConfig()
|
|
3490
|
+
const config = params.paymentMethodId === undefined ? await this.getCashPaymentConfig() : await this.getCashPaymentConfig({
|
|
3491
|
+
paymentMethodId: params.paymentMethodId
|
|
3492
|
+
});
|
|
3359
3493
|
const paymentMethod = config.paymentMethod;
|
|
3360
3494
|
if (!paymentMethod) throw new Error('未找到可用的 CASHMANUAL 支付方式');
|
|
3361
3495
|
if (config.amountDue <= 0) throw new Error('当前订单没有待支付金额');
|
|
@@ -23,13 +23,17 @@ export type BaseSalesHookName = typeof BaseSalesHookNames[keyof typeof BaseSales
|
|
|
23
23
|
export declare function createBaseSalesHook(moduleName: string, hookName: BaseSalesHookName): string;
|
|
24
24
|
export type BaseSalesStatus = 'idle' | 'initializing' | 'ready' | 'error';
|
|
25
25
|
export type BaseSalesPaymentStatus = 'paid' | 'partially_paid' | 'unpaid' | 'payment_processing' | string;
|
|
26
|
+
export interface BaseSalesCashPaymentOptions {
|
|
27
|
+
/** 指定现金支付方式;省略时使用默认 CASHMANUAL。 */
|
|
28
|
+
paymentMethodId?: number | string;
|
|
29
|
+
}
|
|
26
30
|
export interface BaseSalesCashPaymentConfig {
|
|
27
31
|
available: boolean;
|
|
28
32
|
paymentMethod?: PaymentMethod;
|
|
29
33
|
amountDue: number;
|
|
30
34
|
recommendedAmounts: number[];
|
|
31
35
|
}
|
|
32
|
-
export interface BaseSalesPayCashParams {
|
|
36
|
+
export interface BaseSalesPayCashParams extends BaseSalesCashPaymentOptions {
|
|
33
37
|
/** 实际计入订单的现金支付金额(部分支付时小于待付金额)。 */
|
|
34
38
|
amount: number;
|
|
35
39
|
/** 顾客实际交付现金;可大于 amount。 */
|
|
@@ -441,10 +445,10 @@ export interface BaseSalesAddLogParams extends BaseSalesLogInput {
|
|
|
441
445
|
/** BaseSales.scanPromotionCode 对外的轻量结果(UI 可用 getDiscountList 或 scannedDiscountList 补 Holder) */
|
|
442
446
|
export interface BaseSalesScanCodeResult {
|
|
443
447
|
isAvailable: boolean;
|
|
444
|
-
/** 卡券已加入 Promotion
|
|
448
|
+
/** 卡券已加入 Promotion;可能因次数、时间或当前订单条件而暂时无法应用。 */
|
|
445
449
|
isAccepted?: boolean;
|
|
446
450
|
type?: 'server' | string;
|
|
447
451
|
unavailableReason?: 'time_limit' | string;
|
|
448
|
-
/**
|
|
452
|
+
/** 扫码卡券资料及最新可用状态,供 Holder 补全等流程使用。 */
|
|
449
453
|
scannedDiscountList?: Discount[];
|
|
450
454
|
}
|
|
@@ -17,6 +17,7 @@ exports.resolveStrategyEligibleProducts = resolveStrategyEligibleProducts;
|
|
|
17
17
|
exports.resolveStrategyRequiredQuantity = resolveStrategyRequiredQuantity;
|
|
18
18
|
var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
19
19
|
var _lodashEs = require("lodash-es");
|
|
20
|
+
var _entitlementPass = require("../../../modules/Discount/entitlementPass");
|
|
20
21
|
var _utils = require("../../../modules/Order/utils");
|
|
21
22
|
var _utils2 = require("../../ScanOrder/utils");
|
|
22
23
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -395,11 +396,16 @@ function getProductLineNoteSignature(product) {
|
|
|
395
396
|
const uid = getOrderProductUid(product);
|
|
396
397
|
return uid ? `note:${uid}` : `note:${normalizedNote}`;
|
|
397
398
|
}
|
|
398
|
-
function
|
|
399
|
+
function getFullCoveragePassDiscountType(product) {
|
|
399
400
|
const productBundle = Array.isArray(product?.product_bundle) ? product.product_bundle : [];
|
|
400
401
|
const extendedBundle = Array.isArray(product?._extend?.other?.bundle) ? product._extend.other.bundle : [];
|
|
401
402
|
const discountLists = [product?.discount_list, ...productBundle.map(item => item?.discount_list), ...extendedBundle.map(item => item?.discount_list)];
|
|
402
|
-
|
|
403
|
+
for (const discountList of discountLists) {
|
|
404
|
+
if (!Array.isArray(discountList)) continue;
|
|
405
|
+
const pass = discountList.find(item => (0, _entitlementPass.isFullCoveragePass)(item));
|
|
406
|
+
if (pass) return String(pass.type || pass.tag);
|
|
407
|
+
}
|
|
408
|
+
return null;
|
|
403
409
|
}
|
|
404
410
|
|
|
405
411
|
/**
|
|
@@ -412,8 +418,10 @@ function getPromotionLineMergeBoundary(product) {
|
|
|
412
418
|
if (product?.product_id === undefined || product?.product_id === null) {
|
|
413
419
|
return `custom:${getOrderProductUid(product)}`;
|
|
414
420
|
}
|
|
415
|
-
|
|
416
|
-
|
|
421
|
+
const fullCoveragePassType = getFullCoveragePassDiscountType(product);
|
|
422
|
+
if (fullCoveragePassType) {
|
|
423
|
+
const boundary = fullCoveragePassType === 'good_pass' ? 'good-pass' : 'entitlement-pass';
|
|
424
|
+
return `${boundary}:${getOrderProductUid(product)}`;
|
|
417
425
|
}
|
|
418
426
|
if (Number(product?.product_sku?.open_sold_weight || 0) === 1) {
|
|
419
427
|
return `weighing:${getOrderProductUid(product)}`;
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 | 2 | 1 |
|
|
329
|
+
weekNum: 0 | 2 | 1 | 6 | 4 | 5 | 3;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -8,6 +8,7 @@ import { BaseSalesImpl } from '../BaseSales';
|
|
|
8
8
|
import type { BaseSalesScanCodeResult } from '../BaseSales/types';
|
|
9
9
|
import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
|
|
10
10
|
import type { LoadSalesDetailParams } from '../../modules/Order/types';
|
|
11
|
+
import type { GlobalScanSearchType } from './utils/scan/formatGlobalScan';
|
|
11
12
|
import type { AddAddTimeProductToBookingInput, AddAddTimeProductsToBookingInput, GlobalScanHandleResult, GlobalScanHostBridge } from './types';
|
|
12
13
|
import { AddProductDecideContext, AddProductRequiresDetailPayload } from './utils/addProductDecision';
|
|
13
14
|
import { type BuildCacheItemFromOrderLineInput } from '../../modules/BookingContext/utils/buildCacheItemFromOrderLine';
|
|
@@ -29,7 +30,9 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
29
30
|
private addTimeProductsCatalog;
|
|
30
31
|
private orderCustomerDiscountRefreshInFlight;
|
|
31
32
|
private orderCustomerDiscountRefreshCustomerId;
|
|
33
|
+
private orderCustomerDiscountRefreshTarget;
|
|
32
34
|
private orderCustomerPromotionRefreshInFlight;
|
|
35
|
+
private readonly customerResolveRequests;
|
|
33
36
|
protected loadOpenDataInFlight: Promise<OpenDataConfig> | null;
|
|
34
37
|
protected loadOpenDataInFlightTarget: string | null;
|
|
35
38
|
protected openDataTarget: string | null;
|
|
@@ -45,6 +48,12 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
45
48
|
*/
|
|
46
49
|
protected createSubModule(moduleName: string): Module | null;
|
|
47
50
|
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
51
|
+
private getInjectedOpenDataConfig;
|
|
52
|
+
/**
|
|
53
|
+
* 在解决方案对外 ready 前准备 Invoice Document;失败只降级模板,不阻断销售。
|
|
54
|
+
* 已由页面取得的 OpenData 直接交给模块接管,没有注入数据时再走 target-scoped 加载。
|
|
55
|
+
*/
|
|
56
|
+
private prepareInvoiceTemplateAtSolutionReady;
|
|
48
57
|
protected getBookingTicketBusinessCode(): string | null;
|
|
49
58
|
private getIdGeneratorPlugin;
|
|
50
59
|
private loadOpenDataConfig;
|
|
@@ -72,10 +81,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
72
81
|
resolveCustomerById(customerId: string | number): Promise<ICustomer | null>;
|
|
73
82
|
/** 兼容既有优惠码扫码逻辑。 */
|
|
74
83
|
private resolveCustomerByDiscountCustomerId;
|
|
75
|
-
private findCustomerById;
|
|
76
84
|
private normalizeCustomer;
|
|
77
85
|
private getRawCustomerId;
|
|
78
|
-
private hasUsableCustomerDetails;
|
|
79
86
|
/**
|
|
80
87
|
* 更新当前预约的 appointment_status。
|
|
81
88
|
*
|
|
@@ -339,7 +346,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
339
346
|
* 获取当前的客户搜索条件
|
|
340
347
|
* @returns 当前搜索条件
|
|
341
348
|
*/
|
|
342
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
349
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
|
|
343
350
|
/**
|
|
344
351
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
345
352
|
* @returns 客户状态
|
|
@@ -531,6 +538,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
531
538
|
* ```
|
|
532
539
|
*/
|
|
533
540
|
handleGlobalScanCode(code: string, bridge?: GlobalScanHostBridge): Promise<GlobalScanHandleResult>;
|
|
541
|
+
/** 查询码类型;复用原有识别和缓存,不写订单、不打开选择 UI。 */
|
|
542
|
+
getGlobalScanCodeType(code: string): Promise<GlobalScanSearchType | null>;
|
|
534
543
|
resolveBestAddTimePlan(addTimeProducts: any[], targetMinutes: number): any;
|
|
535
544
|
/**
|
|
536
545
|
* 构造一条绑定到已有 booking 的加时商品行。
|