@pisell/pisellos 2.2.166 → 2.2.168
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/Discount/types.d.ts +1 -0
- package/dist/modules/Order/index.d.ts +2 -8
- package/dist/modules/Order/index.js +34 -16
- package/dist/modules/Order/types.d.ts +8 -0
- package/dist/modules/Order/utils.js +1 -1
- package/dist/server/modules/order/utils/filterOrders.js +20 -6
- package/dist/solution/BaseSales/index.js +81 -11
- package/dist/solution/BaseSales/types.d.ts +2 -0
- package/dist/solution/BaseSales/types.js +3 -1
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +10 -1
- package/dist/solution/BookingTicket/index.js +369 -189
- package/dist/solution/VenueBooking/index.d.ts +1 -6
- package/lib/modules/Discount/types.d.ts +1 -0
- package/lib/modules/Order/index.d.ts +2 -8
- package/lib/modules/Order/index.js +21 -9
- package/lib/modules/Order/types.d.ts +8 -0
- package/lib/modules/Order/utils.js +1 -1
- package/lib/server/modules/order/utils/filterOrders.js +12 -4
- package/lib/solution/BaseSales/index.js +60 -4
- package/lib/solution/BaseSales/types.d.ts +2 -0
- package/lib/solution/BaseSales/types.js +3 -1
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +10 -1
- package/lib/solution/BookingTicket/index.js +77 -0
- package/lib/solution/VenueBooking/index.d.ts +1 -6
- package/package.json +1 -1
|
@@ -150,12 +150,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
|
|
|
150
150
|
customerId: number;
|
|
151
151
|
}): Promise<void>;
|
|
152
152
|
private recalculateOrderPricesFromQuotation;
|
|
153
|
-
scanCode(code: string, customerId?: number): Promise<
|
|
154
|
-
isAvailable: boolean;
|
|
155
|
-
discountList: import("../../modules/Discount").Discount[];
|
|
156
|
-
type: "server" | "clientCalc";
|
|
157
|
-
unavailableReason?: import("../../modules/Rules/types").UnavailableReason | undefined;
|
|
158
|
-
}>;
|
|
153
|
+
scanCode(code: string, customerId?: number): Promise<import("../../modules/Order/types").OrderScanCodeResult>;
|
|
159
154
|
/** 获取当前折扣列表(包装 order.getDiscountList) */
|
|
160
155
|
getDiscountList(): import("../../modules/Discount").Discount[];
|
|
161
156
|
/** 勾选/取消勾选某张折扣券,重新计算折扣并持久化 */
|
|
@@ -135,6 +135,7 @@ export interface Discount {
|
|
|
135
135
|
appliedProductDetails: ApplicableProductDetails[];
|
|
136
136
|
isDisabledForProductUsed?: boolean;
|
|
137
137
|
amount?: number;
|
|
138
|
+
customer_id?: number | string | null;
|
|
138
139
|
extension_data?: ExtensionData[];
|
|
139
140
|
total_order_behavior_count?: number;
|
|
140
141
|
today_order_behavior_count?: number;
|
|
@@ -3,10 +3,9 @@ import { BaseModule } from '../BaseModule';
|
|
|
3
3
|
import { OrderModuleAPI, CommitOrderParams, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, CheckoutOrderParams, CancelOrderParams, ChangeBookingStatusParams } from './types';
|
|
4
4
|
import { CartItem } from '../Cart/types';
|
|
5
5
|
import { type SubmitPayloadEnhancer } from './utils';
|
|
6
|
-
import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions } from './types';
|
|
6
|
+
import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, OrderScanCodeResult, ReplaceTempOrderOptions } from './types';
|
|
7
7
|
import type { ICustomer } from '../AccountList/types';
|
|
8
8
|
import type { Discount } from '../Discount/types';
|
|
9
|
-
import { UnavailableReason } from '../Rules/types';
|
|
10
9
|
export declare class OrderModule extends BaseModule implements Module, OrderModuleAPI {
|
|
11
10
|
protected defaultName: string;
|
|
12
11
|
protected defaultVersion: string;
|
|
@@ -48,12 +47,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
48
47
|
apply?: boolean;
|
|
49
48
|
}): Promise<Discount[]>;
|
|
50
49
|
getDiscountList(): Discount[];
|
|
51
|
-
scanCode(code: string, customerId?: number): Promise<
|
|
52
|
-
isAvailable: boolean;
|
|
53
|
-
discountList: Discount[];
|
|
54
|
-
type: 'server' | 'clientCalc';
|
|
55
|
-
unavailableReason?: UnavailableReason;
|
|
56
|
-
}>;
|
|
50
|
+
scanCode(code: string, customerId?: number): Promise<OrderScanCodeResult>;
|
|
57
51
|
applyDiscount(): void;
|
|
58
52
|
initTempOrder(params: {
|
|
59
53
|
cacheId?: string;
|
|
@@ -207,6 +207,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
207
207
|
type: "clientCalc",
|
|
208
208
|
isAvailable: false,
|
|
209
209
|
discountList: this.getDiscountList(),
|
|
210
|
+
scannedDiscountList: resultDiscountList,
|
|
210
211
|
unavailableReason: import_types2.UnavailableReason.Unknown
|
|
211
212
|
};
|
|
212
213
|
}
|
|
@@ -214,7 +215,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
214
215
|
return {
|
|
215
216
|
type: "server",
|
|
216
217
|
isAvailable: false,
|
|
217
|
-
discountList: this.getDiscountList()
|
|
218
|
+
discountList: this.getDiscountList(),
|
|
219
|
+
scannedDiscountList: resultDiscountList
|
|
218
220
|
};
|
|
219
221
|
}
|
|
220
222
|
const withScanList = resultDiscountList.map((item) => ({
|
|
@@ -226,7 +228,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
226
228
|
return {
|
|
227
229
|
type: "clientCalc",
|
|
228
230
|
isAvailable: true,
|
|
229
|
-
discountList: this.getDiscountList()
|
|
231
|
+
discountList: this.getDiscountList(),
|
|
232
|
+
scannedDiscountList: resultDiscountList
|
|
230
233
|
};
|
|
231
234
|
}
|
|
232
235
|
const tempOrder = this.store.tempOrder;
|
|
@@ -247,6 +250,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
247
250
|
type: "clientCalc",
|
|
248
251
|
isAvailable: isAvailable || false,
|
|
249
252
|
discountList: newDiscountList || this.getDiscountList(),
|
|
253
|
+
scannedDiscountList: resultDiscountList,
|
|
250
254
|
unavailableReason
|
|
251
255
|
};
|
|
252
256
|
}
|
|
@@ -570,6 +574,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
570
574
|
this.store.tempOrder = freshTempOrder;
|
|
571
575
|
this.store.summary = (0, import_utils.createEmptySummary)();
|
|
572
576
|
this.store.lastOrderInfo = void 0;
|
|
577
|
+
this.store.syncState = void 0;
|
|
573
578
|
void ((_a = this.store.discount) == null ? void 0 : _a.setOriginalDiscountList([]));
|
|
574
579
|
void ((_b = this.store.discount) == null ? void 0 : _b.setDiscountList([]));
|
|
575
580
|
this.persistTempOrder();
|
|
@@ -988,6 +993,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
988
993
|
}
|
|
989
994
|
/** 追加单个支付项,并立即持久化当前 tempOrder。 */
|
|
990
995
|
addOrderPayment(payment) {
|
|
996
|
+
this.logInfo("addOrderPayment", {
|
|
997
|
+
payment
|
|
998
|
+
});
|
|
991
999
|
const tempOrder = this.ensureTempOrder();
|
|
992
1000
|
const mapped = (0, import_utils.mapPaymentItemsToOrderPayments)([payment]);
|
|
993
1001
|
tempOrder.payments = [...tempOrder.payments || [], ...mapped];
|
|
@@ -1556,20 +1564,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1556
1564
|
const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
|
|
1557
1565
|
params.payments || []
|
|
1558
1566
|
);
|
|
1559
|
-
tempOrder.payments = mappedPayments;
|
|
1560
|
-
if (params.paymentStatus)
|
|
1561
|
-
tempOrder.payment_status = params.paymentStatus;
|
|
1562
|
-
this.persistTempOrder();
|
|
1563
|
-
await this.saveDraft();
|
|
1564
1567
|
const paymentTotal = this.calculatePaymentTotal(mappedPayments);
|
|
1565
1568
|
const targetAmount = this.getPaymentTargetAmount();
|
|
1566
1569
|
const isFullyPaid = targetAmount.lte(0) ? false : paymentTotal.gte(targetAmount);
|
|
1567
|
-
|
|
1570
|
+
const paymentStatus = isFullyPaid ? params.paymentStatus || "paid" : "partially_paid";
|
|
1571
|
+
tempOrder.payments = mappedPayments;
|
|
1572
|
+
tempOrder.payment_status = paymentStatus;
|
|
1573
|
+
this.persistTempOrder();
|
|
1574
|
+
await this.saveDraft();
|
|
1575
|
+
if (!params.submitWhenPaid) {
|
|
1576
|
+
return { isFullyPaid };
|
|
1577
|
+
}
|
|
1578
|
+
if (this.store.syncState === "submitting") {
|
|
1568
1579
|
return { isFullyPaid };
|
|
1569
1580
|
}
|
|
1581
|
+
this.store.syncState = "submitting";
|
|
1570
1582
|
const submitResult = await this.submitTempOrder({
|
|
1571
1583
|
payments: mappedPayments,
|
|
1572
|
-
paymentStatus
|
|
1584
|
+
paymentStatus,
|
|
1573
1585
|
smallTicketDataFlag: params.smallTicketDataFlag,
|
|
1574
1586
|
channel: params.channel
|
|
1575
1587
|
});
|
|
@@ -2,6 +2,7 @@ import { CartItem } from '../Cart/types';
|
|
|
2
2
|
import type { DiscountModule } from '../Discount';
|
|
3
3
|
import type { RulesModule } from '../Rules';
|
|
4
4
|
import type { Discount } from '../Discount/types';
|
|
5
|
+
import type { UnavailableReason } from '../Rules/types';
|
|
5
6
|
import type { SubmitPayloadEnhancer } from './utils';
|
|
6
7
|
import type { PaymentItem } from '../Payment/types';
|
|
7
8
|
import type { ICustomer } from '../AccountList/types';
|
|
@@ -48,6 +49,13 @@ export interface OrderCustomerChangePayload {
|
|
|
48
49
|
patch: OrderCustomerView;
|
|
49
50
|
snapshot: ICustomer | null;
|
|
50
51
|
}
|
|
52
|
+
export interface OrderScanCodeResult {
|
|
53
|
+
isAvailable: boolean;
|
|
54
|
+
discountList: Discount[];
|
|
55
|
+
scannedDiscountList: Discount[];
|
|
56
|
+
type: 'server' | 'clientCalc';
|
|
57
|
+
unavailableReason?: UnavailableReason;
|
|
58
|
+
}
|
|
51
59
|
export interface OrderProductIdentity {
|
|
52
60
|
product_id: number | null;
|
|
53
61
|
product_variant_id: number;
|
|
@@ -572,7 +572,7 @@ function buildSubmitPayload(params) {
|
|
|
572
572
|
note: tempOrder.note || "",
|
|
573
573
|
delivery_type: tempOrder.delivery_type || "nil",
|
|
574
574
|
schedule_date: scheduleDate,
|
|
575
|
-
created_at: tempOrder.created_at || formatDateTime(now),
|
|
575
|
+
// created_at: tempOrder.created_at || formatDateTime(now), 和后端协定这个字段先不提交到接口
|
|
576
576
|
bookings: (tempOrder.bookings || []).filter(
|
|
577
577
|
(booking) => Number(booking.parent_id) !== 0
|
|
578
578
|
).map((booking) => normalizeSubmitBooking(booking)),
|
|
@@ -33,6 +33,13 @@ __export(filterOrders_exports, {
|
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(filterOrders_exports);
|
|
35
35
|
var import_dayjs = __toESM(require("dayjs"));
|
|
36
|
+
function getOrderPaymentCodes(order) {
|
|
37
|
+
const payments = order.payments;
|
|
38
|
+
if (!Array.isArray(payments) || payments.length === 0) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
return payments.map((item) => item == null ? void 0 : item.code).filter((code) => typeof code === "string" && code.length > 0);
|
|
42
|
+
}
|
|
36
43
|
function filterOrders(orders, filters) {
|
|
37
44
|
const safeFilters = filters || {};
|
|
38
45
|
if (!orders || !Array.isArray(orders)) {
|
|
@@ -133,26 +140,27 @@ function filterOrders(orders, filters) {
|
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
if (safeFilters.payment_methods && safeFilters.payment_methods.length > 0) {
|
|
136
|
-
|
|
143
|
+
const orderPaymentCodes = getOrderPaymentCodes(order);
|
|
144
|
+
if (orderPaymentCodes.length === 0) {
|
|
137
145
|
rejected.push({
|
|
138
146
|
order_id: order.order_id,
|
|
139
147
|
order_number: order.order_number,
|
|
140
148
|
reason: {
|
|
141
149
|
field: "payment_methods",
|
|
142
|
-
actual: order.
|
|
150
|
+
actual: order.payments,
|
|
143
151
|
expected: safeFilters.payment_methods
|
|
144
152
|
}
|
|
145
153
|
});
|
|
146
154
|
return false;
|
|
147
155
|
}
|
|
148
|
-
const hasMatch =
|
|
156
|
+
const hasMatch = orderPaymentCodes.some((code) => safeFilters.payment_methods.includes(code));
|
|
149
157
|
if (!hasMatch) {
|
|
150
158
|
rejected.push({
|
|
151
159
|
order_id: order.order_id,
|
|
152
160
|
order_number: order.order_number,
|
|
153
161
|
reason: {
|
|
154
162
|
field: "payment_methods",
|
|
155
|
-
actual:
|
|
163
|
+
actual: orderPaymentCodes,
|
|
156
164
|
expected: safeFilters.payment_methods
|
|
157
165
|
}
|
|
158
166
|
});
|
|
@@ -34,9 +34,10 @@ __export(BaseSales_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(BaseSales_exports);
|
|
36
36
|
var import_BaseModule = require("../../modules/BaseModule");
|
|
37
|
+
var import_types = require("./types");
|
|
37
38
|
var import_Order = require("../../modules/Order");
|
|
38
39
|
var import_decimal = __toESM(require("decimal.js"));
|
|
39
|
-
var
|
|
40
|
+
var import_types2 = require("../BookingByStep/types");
|
|
40
41
|
var import_utils = require("../../modules/Order/utils");
|
|
41
42
|
var import_dayjs = __toESM(require("dayjs"));
|
|
42
43
|
__reExport(BaseSales_exports, require("./types"), module.exports);
|
|
@@ -147,7 +148,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
147
148
|
if (moduleName === "quotation") {
|
|
148
149
|
return new import_Quotation.QuotationModule(`${this.name}_quotation`);
|
|
149
150
|
}
|
|
150
|
-
return (0,
|
|
151
|
+
return (0, import_types2.createModule)(moduleName, this.name);
|
|
151
152
|
}
|
|
152
153
|
getSubModuleHooks(moduleName) {
|
|
153
154
|
var _a, _b;
|
|
@@ -779,6 +780,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
779
780
|
tempOrder.discount_list = (nextDiscountList || []).filter((d) => d.isSelected);
|
|
780
781
|
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
781
782
|
this.store.order.persistTempOrder();
|
|
783
|
+
this.effectsEmit("onDiscountApplied", {
|
|
784
|
+
productList: tempOrder.products,
|
|
785
|
+
discountList: nextDiscountList,
|
|
786
|
+
selectedDiscountList: tempOrder.discount_list,
|
|
787
|
+
tempOrder
|
|
788
|
+
});
|
|
782
789
|
} catch (error) {
|
|
783
790
|
throw error;
|
|
784
791
|
}
|
|
@@ -844,10 +851,43 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
844
851
|
if (!this.store.order)
|
|
845
852
|
throw new Error("order 模块未初始化");
|
|
846
853
|
const channel = params.channel ?? this.getSubmitOrderSalesChannel();
|
|
847
|
-
|
|
854
|
+
const syncParams = {
|
|
848
855
|
...params,
|
|
849
856
|
...channel !== void 0 ? { channel } : {}
|
|
857
|
+
};
|
|
858
|
+
const syncState = this.store.order.getOrderSyncState();
|
|
859
|
+
if (params.submitWhenPaid && syncState === "submitting") {
|
|
860
|
+
return this.store.order.syncPaymentsToOrder(syncParams);
|
|
861
|
+
}
|
|
862
|
+
const payments = params.payments || [];
|
|
863
|
+
await this.effectsEmit(import_types.BaseSalesHookNames.onPaymentSyncStart, {
|
|
864
|
+
payments,
|
|
865
|
+
params: syncParams,
|
|
866
|
+
amountSnapshot: this.store.order.getOrderAmountSnapshot(),
|
|
867
|
+
orderSnapshot: this.store.order.getOrderSnapshot()
|
|
850
868
|
});
|
|
869
|
+
try {
|
|
870
|
+
const syncResult = await this.store.order.syncPaymentsToOrder(syncParams);
|
|
871
|
+
await this.effectsEmit(import_types.BaseSalesHookNames.onPaymentSyncEnd, {
|
|
872
|
+
ok: true,
|
|
873
|
+
syncResult,
|
|
874
|
+
payments: this.store.order.getOrderPayments(),
|
|
875
|
+
params: syncParams,
|
|
876
|
+
amountSnapshot: this.store.order.getOrderAmountSnapshot(),
|
|
877
|
+
orderSnapshot: this.store.order.getOrderSnapshot()
|
|
878
|
+
});
|
|
879
|
+
return syncResult;
|
|
880
|
+
} catch (error) {
|
|
881
|
+
await this.effectsEmit(import_types.BaseSalesHookNames.onPaymentSyncEnd, {
|
|
882
|
+
ok: false,
|
|
883
|
+
error,
|
|
884
|
+
payments: this.store.order.getOrderPayments(),
|
|
885
|
+
params: syncParams,
|
|
886
|
+
amountSnapshot: this.store.order.getOrderAmountSnapshot(),
|
|
887
|
+
orderSnapshot: this.store.order.getOrderSnapshot()
|
|
888
|
+
});
|
|
889
|
+
throw error;
|
|
890
|
+
}
|
|
851
891
|
}
|
|
852
892
|
/** 读取当前 BaseSales 订单上下文中的 Sales 协议支付项。 */
|
|
853
893
|
getOrderPayments() {
|
|
@@ -865,7 +905,23 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
865
905
|
addOrderPayment(payment) {
|
|
866
906
|
if (!this.store.order)
|
|
867
907
|
throw new Error("order 模块未初始化");
|
|
868
|
-
|
|
908
|
+
const payments = this.store.order.addOrderPayment(payment);
|
|
909
|
+
const amountSnapshot = this.store.order.getOrderAmountSnapshot();
|
|
910
|
+
const syncState = this.store.order.getOrderSyncState();
|
|
911
|
+
if (amountSnapshot && syncState !== "submitting") {
|
|
912
|
+
const paymentStatus = Number(amountSnapshot.amountGap || 0) <= 0 ? "paid" : "partially_paid";
|
|
913
|
+
void this.syncPaymentsToOrder({
|
|
914
|
+
payments,
|
|
915
|
+
paymentStatus,
|
|
916
|
+
submitWhenPaid: true,
|
|
917
|
+
smallTicketDataFlag: 1
|
|
918
|
+
}).catch((error) => {
|
|
919
|
+
this.logError("auto sync payments failed", {
|
|
920
|
+
error: error instanceof Error ? error.message : String(error)
|
|
921
|
+
});
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
return payments;
|
|
869
925
|
}
|
|
870
926
|
/** 更新当前订单中的指定支付项。 */
|
|
871
927
|
updateOrderPayment(paymentIdentity, updates) {
|
|
@@ -11,6 +11,8 @@ export declare const BaseSalesHookNames: {
|
|
|
11
11
|
readonly onRetryInit: "onRetryInit";
|
|
12
12
|
readonly onRefresh: "onRefresh";
|
|
13
13
|
readonly onCartValidationChanged: "onCartValidationChanged";
|
|
14
|
+
readonly onPaymentSyncStart: "onPaymentSyncStart";
|
|
15
|
+
readonly onPaymentSyncEnd: "onPaymentSyncEnd";
|
|
14
16
|
};
|
|
15
17
|
export type BaseSalesHookName = typeof BaseSalesHookNames[keyof typeof BaseSalesHookNames];
|
|
16
18
|
export declare function createBaseSalesHook(moduleName: string, hookName: BaseSalesHookName): string;
|
|
@@ -28,7 +28,9 @@ var BaseSalesHookNames = {
|
|
|
28
28
|
onDestroy: "onDestroy",
|
|
29
29
|
onRetryInit: "onRetryInit",
|
|
30
30
|
onRefresh: "onRefresh",
|
|
31
|
-
onCartValidationChanged: "onCartValidationChanged"
|
|
31
|
+
onCartValidationChanged: "onCartValidationChanged",
|
|
32
|
+
onPaymentSyncStart: "onPaymentSyncStart",
|
|
33
|
+
onPaymentSyncEnd: "onPaymentSyncEnd"
|
|
32
34
|
};
|
|
33
35
|
function createBaseSalesHook(moduleName, hookName) {
|
|
34
36
|
return `${moduleName}:${hookName}`;
|
|
@@ -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 |
|
|
314
|
+
weekNum: 0 | 1 | 2 | 6 | 3 | 5 | 4;
|
|
315
315
|
}[]>;
|
|
316
316
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
317
317
|
private getScheduleDataByIds;
|
|
@@ -4,6 +4,7 @@ import type { ProductData } from '../../modules';
|
|
|
4
4
|
import { type BookingContextConfig, type BookingContextDateInput, type BookingContextResource, type BookingContextResourceMap, type BookingContextState, type InitBookingContextParams, type LoadBookingConfigParams, type LoadBookingResourcesParams, type ResourceError, type BookingCalcContext } from '../../modules/BookingContext';
|
|
5
5
|
import type { OrderCustomerView } from '../../modules/Order/types';
|
|
6
6
|
import { BaseSalesImpl } from '../BaseSales';
|
|
7
|
+
import type { BaseSalesScanCodeResult } from '../BaseSales/types';
|
|
7
8
|
import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
|
|
8
9
|
import type { LoadSalesDetailParams } from '../../modules/Order/types';
|
|
9
10
|
import { AddProductDecideContext, AddProductRequiresDetailPayload } from './utils/addProductDecision';
|
|
@@ -43,6 +44,14 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
43
44
|
* 让现有 setActiveCustomer / getActiveCustomer 调用方零成本拿到详情态客户。
|
|
44
45
|
*/
|
|
45
46
|
loadSalesDetail(orderIdOrParams: number | string | LoadSalesDetailParams): Promise<ISalesDetail>;
|
|
47
|
+
scanPromotionCode(code: string, customerId?: number): Promise<BaseSalesScanCodeResult>;
|
|
48
|
+
private hydrateOrderCustomerFromScanDiscounts;
|
|
49
|
+
private getDiscountCustomerId;
|
|
50
|
+
private resolveCustomerByDiscountCustomerId;
|
|
51
|
+
private findCustomerById;
|
|
52
|
+
private normalizeCustomer;
|
|
53
|
+
private getRawCustomerId;
|
|
54
|
+
private hasUsableCustomerDetails;
|
|
46
55
|
/**
|
|
47
56
|
* 更新当前预约的 appointment_status。
|
|
48
57
|
*
|
|
@@ -251,7 +260,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
251
260
|
* 获取当前的客户搜索条件
|
|
252
261
|
* @returns 当前搜索条件
|
|
253
262
|
*/
|
|
254
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
263
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
|
|
255
264
|
/**
|
|
256
265
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
257
266
|
* @returns 客户状态
|
|
@@ -133,6 +133,83 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
|
|
|
133
133
|
}
|
|
134
134
|
return sales;
|
|
135
135
|
}
|
|
136
|
+
async scanPromotionCode(code, customerId) {
|
|
137
|
+
if (!this.store.order)
|
|
138
|
+
throw new Error("order 模块未初始化");
|
|
139
|
+
const raw = await this.store.order.scanCode(code, customerId);
|
|
140
|
+
if (raw.isAvailable) {
|
|
141
|
+
await this.hydrateOrderCustomerFromScanDiscounts(raw.scannedDiscountList);
|
|
142
|
+
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
143
|
+
this.store.order.persistTempOrder();
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
isAvailable: raw.isAvailable,
|
|
147
|
+
type: raw.type,
|
|
148
|
+
unavailableReason: raw.unavailableReason
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
async hydrateOrderCustomerFromScanDiscounts(discounts) {
|
|
152
|
+
const currentOrderCustomer = this.store.order.getOrderCustomer();
|
|
153
|
+
if (currentOrderCustomer)
|
|
154
|
+
return;
|
|
155
|
+
const customerId = this.getDiscountCustomerId(discounts);
|
|
156
|
+
if (!customerId)
|
|
157
|
+
return;
|
|
158
|
+
const customer = await this.resolveCustomerByDiscountCustomerId(customerId);
|
|
159
|
+
if (!customer)
|
|
160
|
+
return;
|
|
161
|
+
this.store.customer.setSelectedCustomer(customer);
|
|
162
|
+
this.setOrderCustomer(customer);
|
|
163
|
+
}
|
|
164
|
+
getDiscountCustomerId(discounts) {
|
|
165
|
+
const discount = discounts.find((item) => item.customer_id != null);
|
|
166
|
+
const customerId = Number(discount == null ? void 0 : discount.customer_id);
|
|
167
|
+
if (!Number.isFinite(customerId) || customerId <= 0)
|
|
168
|
+
return null;
|
|
169
|
+
return customerId;
|
|
170
|
+
}
|
|
171
|
+
async resolveCustomerByDiscountCustomerId(customerId) {
|
|
172
|
+
var _a;
|
|
173
|
+
const localCustomers = this.store.customer.getCustomers();
|
|
174
|
+
const localCustomer = this.findCustomerById(localCustomers, customerId);
|
|
175
|
+
const normalizedLocalCustomer = localCustomer ? this.normalizeCustomer(localCustomer) : null;
|
|
176
|
+
if (normalizedLocalCustomer && this.hasUsableCustomerDetails(normalizedLocalCustomer)) {
|
|
177
|
+
return normalizedLocalCustomer;
|
|
178
|
+
}
|
|
179
|
+
const result = await this.store.customer.getCustomerList({
|
|
180
|
+
ids: [customerId],
|
|
181
|
+
skip: 1,
|
|
182
|
+
num: 1
|
|
183
|
+
});
|
|
184
|
+
const remoteCustomer = this.findCustomerById((result == null ? void 0 : result.list) || [], customerId) || ((_a = result == null ? void 0 : result.list) == null ? void 0 : _a[0]) || null;
|
|
185
|
+
return remoteCustomer ? this.normalizeCustomer(remoteCustomer) : null;
|
|
186
|
+
}
|
|
187
|
+
findCustomerById(customers = [], customerId) {
|
|
188
|
+
return customers.find((customer) => {
|
|
189
|
+
const rawId = this.getRawCustomerId(customer);
|
|
190
|
+
return rawId !== null && String(rawId) === String(customerId);
|
|
191
|
+
}) || null;
|
|
192
|
+
}
|
|
193
|
+
normalizeCustomer(customer) {
|
|
194
|
+
const raw = customer;
|
|
195
|
+
const rawId = this.getRawCustomerId(customer);
|
|
196
|
+
const name = customer.name || raw.display_name || raw.nickname || raw.customer_name || [raw.first_name, raw.last_name].filter(Boolean).join(" ") || "";
|
|
197
|
+
return {
|
|
198
|
+
...customer,
|
|
199
|
+
id: rawId ?? customer.id,
|
|
200
|
+
name,
|
|
201
|
+
phone: customer.phone ?? raw.phone ?? raw.mobile ?? "",
|
|
202
|
+
email: customer.email ?? raw.email ?? "",
|
|
203
|
+
country_calling_code: customer.country_calling_code ?? raw.country_calling_code ?? ""
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
getRawCustomerId(customer) {
|
|
207
|
+
const raw = customer;
|
|
208
|
+
return customer.id ?? raw.customer_id ?? raw.customerId ?? null;
|
|
209
|
+
}
|
|
210
|
+
hasUsableCustomerDetails(customer) {
|
|
211
|
+
return !!(customer.name || customer.phone || customer.email || customer.display_name || customer.customer_name);
|
|
212
|
+
}
|
|
136
213
|
/**
|
|
137
214
|
* 更新当前预约的 appointment_status。
|
|
138
215
|
*
|
|
@@ -150,12 +150,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
|
|
|
150
150
|
customerId: number;
|
|
151
151
|
}): Promise<void>;
|
|
152
152
|
private recalculateOrderPricesFromQuotation;
|
|
153
|
-
scanCode(code: string, customerId?: number): Promise<
|
|
154
|
-
isAvailable: boolean;
|
|
155
|
-
discountList: import("../../modules/Discount").Discount[];
|
|
156
|
-
type: "server" | "clientCalc";
|
|
157
|
-
unavailableReason?: import("../../modules/Rules/types").UnavailableReason | undefined;
|
|
158
|
-
}>;
|
|
153
|
+
scanCode(code: string, customerId?: number): Promise<import("../../modules/Order/types").OrderScanCodeResult>;
|
|
159
154
|
/** 获取当前折扣列表(包装 order.getDiscountList) */
|
|
160
155
|
getDiscountList(): import("../../modules/Discount").Discount[];
|
|
161
156
|
/** 勾选/取消勾选某张折扣券,重新计算折扣并持久化 */
|