@pisell/pisellos 2.3.1 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/modules/Order/index.d.ts +9 -0
  2. package/dist/modules/Order/index.js +448 -369
  3. package/dist/modules/Order/types.d.ts +2 -0
  4. package/dist/modules/Quotation/index.d.ts +16 -2
  5. package/dist/modules/Quotation/index.js +71 -38
  6. package/dist/modules/Quotation/types.d.ts +14 -0
  7. package/dist/modules/SalesSummary/index.d.ts +1 -0
  8. package/dist/modules/SalesSummary/index.js +7 -4
  9. package/dist/modules/Schedule/index.d.ts +4 -0
  10. package/dist/modules/Schedule/index.js +31 -1
  11. package/dist/modules/Schedule/types.d.ts +2 -0
  12. package/dist/server/index.js +13 -12
  13. package/dist/server/modules/products/index.d.ts +4 -0
  14. package/dist/server/modules/products/index.js +76 -45
  15. package/dist/server/modules/quotation/index.d.ts +39 -0
  16. package/dist/server/modules/quotation/index.js +278 -66
  17. package/dist/server/modules/schedule/index.d.ts +2 -0
  18. package/dist/server/modules/schedule/index.js +10 -2
  19. package/dist/solution/BaseSales/index.d.ts +10 -1
  20. package/dist/solution/BaseSales/index.js +825 -528
  21. package/dist/solution/BaseSales/types.d.ts +7 -0
  22. package/dist/solution/BaseSales/utils/quotationPrice.d.ts +12 -1
  23. package/dist/solution/BaseSales/utils/quotationPrice.js +16 -3
  24. package/dist/solution/BookingByStep/index.d.ts +1 -1
  25. package/lib/modules/Order/index.d.ts +9 -0
  26. package/lib/modules/Order/index.js +48 -7
  27. package/lib/modules/Order/types.d.ts +2 -0
  28. package/lib/modules/Quotation/index.d.ts +16 -2
  29. package/lib/modules/Quotation/index.js +49 -13
  30. package/lib/modules/Quotation/types.d.ts +14 -0
  31. package/lib/modules/SalesSummary/index.d.ts +1 -0
  32. package/lib/modules/SalesSummary/index.js +4 -3
  33. package/lib/modules/Schedule/index.d.ts +4 -0
  34. package/lib/modules/Schedule/index.js +21 -0
  35. package/lib/modules/Schedule/types.d.ts +2 -0
  36. package/lib/server/index.js +1 -1
  37. package/lib/server/modules/products/index.d.ts +4 -0
  38. package/lib/server/modules/products/index.js +43 -19
  39. package/lib/server/modules/quotation/index.d.ts +39 -0
  40. package/lib/server/modules/quotation/index.js +179 -1
  41. package/lib/server/modules/schedule/index.d.ts +2 -0
  42. package/lib/server/modules/schedule/index.js +8 -1
  43. package/lib/solution/BaseSales/index.d.ts +10 -1
  44. package/lib/solution/BaseSales/index.js +218 -19
  45. package/lib/solution/BaseSales/types.d.ts +7 -0
  46. package/lib/solution/BaseSales/utils/quotationPrice.d.ts +12 -1
  47. package/lib/solution/BaseSales/utils/quotationPrice.js +15 -3
  48. package/lib/solution/BookingByStep/index.d.ts +1 -1
  49. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
1
  import { OrderModule, ProductList, QuotationModule, SalesSummaryModule, ScanOrderLoggerModule as BaseSalesLoggerModule, ScheduleModule } from '../../modules';
2
2
  import type { ScanOrderLogInput as BaseSalesLogInput, ScanOrderLoggerProviderConfig as BaseSalesLoggerProviderConfig, ScanOrderLoggerProviderType as BaseSalesLoggerProviderType } from '../../modules/ScanOrderLogger/types';
3
3
  import type { QuantityCheckResult, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
4
+ import type { QuotationCustomerScopeInfo } from '../../modules/Quotation/types';
4
5
  /**
5
6
  * BaseSales 流程 hook 后缀。
6
7
  * 完整事件名应由当前模块名动态拼接,避免多个实例共享固定事件 key。
@@ -278,6 +279,12 @@ export interface BaseSalesProductBookingPriceResult {
278
279
  segments: BaseSalesProductBookingPriceSegment[];
279
280
  product_bundle?: BaseSalesBundleProductBookingPriceResult[];
280
281
  }
282
+ export type BaseSalesQuotationCustomerScopeInfo = QuotationCustomerScopeInfo;
283
+ export interface BaseSalesPriceRecalculationContextChange {
284
+ previousCustomerId?: number | string | null;
285
+ nextCustomerId?: number | string | null;
286
+ [key: string]: any;
287
+ }
281
288
  export type BaseSalesAvailabilityMode = 'idle' | 'shop_closed' | 'submit_disabled' | 'resource_busy' | 'additional_order_with_code' | 'additional_order';
282
289
  export interface BaseSalesTableFormRecord {
283
290
  policy?: string | null;
@@ -1,7 +1,18 @@
1
1
  import type { QuotationModule } from '../../../modules/Quotation';
2
2
  import type { BaseSalesCalculateProductBookingPriceParams, BaseSalesProductBookingPriceResult } from '../types';
3
3
  interface BuildBaseSalesQuotationPriceParams extends BaseSalesCalculateProductBookingPriceParams {
4
- quotation?: Pick<QuotationModule, 'getPriceForProduct' | 'getQuotationShelfId'> | null;
4
+ quotation?: (Pick<QuotationModule, 'getPriceForProduct' | 'getQuotationShelfId'> & {
5
+ getQuotationMatchForProduct?: (params: {
6
+ productId: number;
7
+ variantId?: number;
8
+ datetime: string;
9
+ channel?: string;
10
+ customer_id?: number | string;
11
+ }) => {
12
+ price: string | null;
13
+ quotationShelfId: number;
14
+ } | null;
15
+ }) | null;
5
16
  }
6
17
  export declare function calculateBaseSalesProductBookingPrice(params: BuildBaseSalesQuotationPriceParams): BaseSalesProductBookingPriceResult;
7
18
  export {};
@@ -118,20 +118,30 @@ function formatTimePoint(datetime) {
118
118
  return datetime.format('YYYY-MM-DD HH:mm:ss');
119
119
  }
120
120
  function buildPriceSegment(params) {
121
+ var _match$quotationShelf;
121
122
  var timePoint = formatTimePoint(params.segment.start);
122
- var quotedPrice = params.quotation && params.productId !== null ? params.quotation.getPriceForProduct({
123
+ var match = params.quotation && params.productId !== null && params.quotation.getQuotationMatchForProduct ? params.quotation.getQuotationMatchForProduct({
123
124
  productId: params.productId,
124
125
  variantId: params.variantId,
125
126
  datetime: timePoint,
127
+ channel: params.channel,
128
+ customer_id: params.customerId
129
+ }) : null;
130
+ var quotedPrice = match ? match.price : params.quotation && params.productId !== null ? params.quotation.getPriceForProduct({
131
+ productId: params.productId,
132
+ variantId: params.variantId,
133
+ datetime: timePoint,
134
+ channel: params.channel,
126
135
  customer_id: params.customerId
127
136
  }) : null;
128
137
  var unitPrice = toPriceString(quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : params.fallbackPrice);
129
- var quotationShelfId = quotedPrice !== null && params.quotation && params.productId !== null ? params.quotation.getQuotationShelfId({
138
+ var quotationShelfId = quotedPrice !== null ? (_match$quotationShelf = match === null || match === void 0 ? void 0 : match.quotationShelfId) !== null && _match$quotationShelf !== void 0 ? _match$quotationShelf : params.quotation && params.productId !== null ? params.quotation.getQuotationShelfId({
130
139
  productId: params.productId,
131
140
  variantId: params.variantId,
132
141
  datetime: timePoint,
142
+ channel: params.channel,
133
143
  customer_id: params.customerId
134
- }) : 0;
144
+ }) : 0 : 0;
135
145
  return {
136
146
  start_datetime: timePoint,
137
147
  end_datetime: params.segment.end ? formatTimePoint(params.segment.end) : undefined,
@@ -151,6 +161,7 @@ function calculatePriceForProduct(params) {
151
161
  productId: params.productId,
152
162
  variantId: params.variantId,
153
163
  customerId: params.customerId,
164
+ channel: params.channel,
154
165
  fallbackPrice: params.fallbackPrice,
155
166
  segment: segment
156
167
  });
@@ -183,6 +194,7 @@ function calculateBundlePrices(params, segments) {
183
194
  productId: productId,
184
195
  variantId: variantId,
185
196
  customerId: params.customer_id,
197
+ channel: params.channel,
186
198
  quantity: quantity,
187
199
  fallbackPrice: getBundleFallbackPrice(bundle),
188
200
  segments: segments
@@ -216,6 +228,7 @@ export function calculateBaseSalesProductBookingPrice(params) {
216
228
  productId: productId,
217
229
  variantId: variantId,
218
230
  customerId: params.customer_id,
231
+ channel: params.channel,
219
232
  quantity: productQuantity,
220
233
  fallbackPrice: fallbackPrice,
221
234
  segments: timeSegments
@@ -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 | 1 | 2 | 6 | 3 | 4 | 5;
314
+ weekNum: 0 | 2 | 1 | 6 | 3 | 4 | 5;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -358,7 +358,9 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
358
358
  private hasGoodPassDiscount;
359
359
  private getBundleRuntimeIdentity;
360
360
  private preservePersistedBundlePriceFields;
361
+ private applyOrderProductUpdateToTempOrder;
361
362
  updateOrderProduct(params: UpdateOrderProductParams): Promise<OrderProduct[]>;
363
+ updateOrderProducts(paramsList: UpdateOrderProductParams[]): Promise<OrderProduct[]>;
362
364
  updateOrderProductQuantity(params: UpdateOrderProductQuantityParams): Promise<OrderProduct[]>;
363
365
  updateOrderBooking(params: UpdateOrderBookingParams): any[];
364
366
  /**
@@ -479,6 +481,13 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
479
481
  hydrateTempOrderFromRecord(record: Record<string, any>, options?: {
480
482
  recalcOnHydrate?: boolean;
481
483
  }): Promise<OrderTempOrder>;
484
+ /**
485
+ * 兼容后端详情将 holder 放在 metadata.holder 的历史形态,统一补到运行时展示路径。
486
+ *
487
+ * @example
488
+ * this.normalizeHydratedBookingHolder({ metadata: { holder: { form_record: [1] } } });
489
+ */
490
+ private normalizeHydratedBookingHolder;
482
491
  private normalizeTempOrderForRuntime;
483
492
  private hydrateLinkedBookingIdentity;
484
493
  private pickHydratedDisplayText;
@@ -2683,7 +2683,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2683
2683
  };
2684
2684
  });
2685
2685
  }
2686
- async updateOrderProduct(params) {
2686
+ applyOrderProductUpdateToTempOrder(tempOrder, params) {
2687
2687
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
2688
2688
  const {
2689
2689
  product_id,
@@ -2695,7 +2695,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2695
2695
  product_bundle,
2696
2696
  booking
2697
2697
  } = params;
2698
- const tempOrder = this.ensureTempOrder();
2699
2698
  const identityLookup = {
2700
2699
  product_id,
2701
2700
  product_variant_id
@@ -2839,6 +2838,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2839
2838
  tempOrder.products[productIndex],
2840
2839
  (_q = tempOrder.products[productIndex].metadata) == null ? void 0 : _q.unique_identification_number
2841
2840
  );
2841
+ }
2842
+ async updateOrderProduct(params) {
2843
+ const tempOrder = this.ensureTempOrder();
2844
+ this.applyOrderProductUpdateToTempOrder(tempOrder, params);
2842
2845
  await this.applyPromotion();
2843
2846
  this.applyDiscount();
2844
2847
  this.sanitizeTempOrderProducts(tempOrder);
@@ -2846,6 +2849,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2846
2849
  this.persistTempOrder();
2847
2850
  return tempOrder.products;
2848
2851
  }
2852
+ async updateOrderProducts(paramsList) {
2853
+ const tempOrder = this.ensureTempOrder();
2854
+ if (!paramsList.length) {
2855
+ return tempOrder.products;
2856
+ }
2857
+ paramsList.forEach((params) => {
2858
+ this.applyOrderProductUpdateToTempOrder(tempOrder, params);
2859
+ });
2860
+ await this.finalizeAfterProductsMutation(tempOrder);
2861
+ return tempOrder.products;
2862
+ }
2849
2863
  async updateOrderProductQuantity(params) {
2850
2864
  var _a;
2851
2865
  const {
@@ -3634,6 +3648,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3634
3648
  this.persistTempOrder();
3635
3649
  return nextTempOrder;
3636
3650
  }
3651
+ /**
3652
+ * 兼容后端详情将 holder 放在 metadata.holder 的历史形态,统一补到运行时展示路径。
3653
+ *
3654
+ * @example
3655
+ * this.normalizeHydratedBookingHolder({ metadata: { holder: { form_record: [1] } } });
3656
+ */
3657
+ normalizeHydratedBookingHolder(booking) {
3658
+ const next = { ...booking || {} };
3659
+ const metadata = next.metadata && typeof next.metadata === "object" && !Array.isArray(next.metadata) ? { ...next.metadata } : {};
3660
+ const metadataHolder = metadata.holder && typeof metadata.holder === "object" && !Array.isArray(metadata.holder) ? metadata.holder : null;
3661
+ if (!next.holder && metadataHolder) {
3662
+ next.holder = { ...metadataHolder };
3663
+ }
3664
+ const holder = next.holder && typeof next.holder === "object" && !Array.isArray(next.holder) ? next.holder : null;
3665
+ const holderRecords = Array.isArray(holder == null ? void 0 : holder.form_record) ? holder.form_record.filter((id) => id !== void 0 && id !== null && id !== "") : [];
3666
+ const hasMetadataHolderId = metadata.holder_id !== void 0 && metadata.holder_id !== null && metadata.holder_id !== "" && (!Array.isArray(metadata.holder_id) || metadata.holder_id.length > 0);
3667
+ if (!hasMetadataHolderId && holderRecords.length > 0) {
3668
+ metadata.holder_id = holderRecords;
3669
+ }
3670
+ if (Object.keys(metadata).length > 0) {
3671
+ next.metadata = metadata;
3672
+ }
3673
+ return next;
3674
+ }
3637
3675
  normalizeTempOrderForRuntime(raw, options) {
3638
3676
  var _a, _b;
3639
3677
  const nextTempOrder = {
@@ -3660,11 +3698,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3660
3698
  nextTempOrder.holder = raw.holder && typeof raw.holder === "object" ? { ...raw.holder } : null;
3661
3699
  const rawProducts = Array.isArray(raw.products) ? raw.products : [];
3662
3700
  nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p)) : [];
3663
- nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map((b) => ({
3664
- ...b || {},
3665
- is_all: (0, import_utils.normalizeBookingIsAll)(b || {}),
3666
- sub_type: (0, import_utils.normalizeBookingSubType)(b || {})
3667
- })) : [];
3701
+ nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map((b) => {
3702
+ const booking = this.normalizeHydratedBookingHolder(b || {});
3703
+ return {
3704
+ ...booking,
3705
+ is_all: (0, import_utils.normalizeBookingIsAll)(booking),
3706
+ sub_type: (0, import_utils.normalizeBookingSubType)(booking)
3707
+ };
3708
+ }) : [];
3668
3709
  nextTempOrder.payments = Array.isArray(raw.payments) ? raw.payments.map((p) => ({ ...p || {} })) : [];
3669
3710
  nextTempOrder.surcharges = Array.isArray(raw.surcharges) ? raw.surcharges.map((s) => ({ ...s || {} })) : [];
3670
3711
  nextTempOrder.relation_forms = Array.isArray(raw.relation_forms) ? raw.relation_forms.map((f) => ({ ...f || {} })) : [];
@@ -666,6 +666,8 @@ export interface OrderModuleAPI {
666
666
  updateTempOrderContactsInfo: (contactsInfo: Record<string, any> | null) => Record<string, any> | null;
667
667
  addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput) => Promise<OrderProduct[]>;
668
668
  updateOrderProduct: (params: UpdateOrderProductParams) => Promise<OrderProduct[]>;
669
+ /** 批量更新购物车行,末尾仅触发一次促销重算与 summary 刷新 */
670
+ updateOrderProducts: (paramsList: UpdateOrderProductParams[]) => Promise<OrderProduct[]>;
669
671
  updateOrderProductQuantity: (params: UpdateOrderProductQuantityParams) => Promise<OrderProduct[]>;
670
672
  updateOrderBooking: (params: UpdateOrderBookingParams) => any[];
671
673
  removeProductFromOrder: (identity: OrderProductIdentity) => Promise<OrderProduct[]>;
@@ -1,8 +1,8 @@
1
1
  import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
3
  import type { ScheduleItem } from '../Schedule/types';
4
- import type { QuotationItem } from './types';
5
- export type { QuotationItem, QuotationProductData, QuotationSchedule, QuotationState, QuotationCustomer } from './types';
4
+ import type { QuotationItem, QuotationCustomerScopeInfo } from './types';
5
+ export type { QuotationItem, QuotationProductData, QuotationSchedule, QuotationState, QuotationCustomer, QuotationCustomerScope, QuotationCustomerScopeInfo, } from './types';
6
6
  export declare class QuotationModule extends BaseModule implements Module {
7
7
  protected defaultName: string;
8
8
  protected defaultVersion: string;
@@ -16,6 +16,7 @@ export declare class QuotationModule extends BaseModule implements Module {
16
16
  customer_id?: number | string;
17
17
  }): Promise<void>;
18
18
  getQuotationList(): QuotationItem[];
19
+ getQuotationCustomerScopeInfo(): QuotationCustomerScopeInfo;
19
20
  /**
20
21
  * Look up the quotation price for a specific product (+ optional variant) at a given datetime.
21
22
  * Returns the price as a string (e.g. "300.00"), or null if no quotation applies.
@@ -28,12 +29,24 @@ export declare class QuotationModule extends BaseModule implements Module {
28
29
  productId: number;
29
30
  variantId?: number;
30
31
  datetime: string;
32
+ channel?: string;
31
33
  customer_id?: number | string;
32
34
  }): string | null;
35
+ getQuotationMatchForProduct(params: {
36
+ productId: number;
37
+ variantId?: number;
38
+ datetime: string;
39
+ channel?: string;
40
+ customer_id?: number | string;
41
+ }): {
42
+ price: string | null;
43
+ quotationShelfId: number;
44
+ } | null;
33
45
  getQuotationShelfId(params: {
34
46
  productId: number;
35
47
  variantId?: number;
36
48
  datetime: string;
49
+ channel?: string;
37
50
  customer_id?: number | string;
38
51
  }): number;
39
52
  /**
@@ -49,6 +62,7 @@ export declare class QuotationModule extends BaseModule implements Module {
49
62
  setScheduleResolver(resolver: (id: number) => ScheduleItem | undefined): void;
50
63
  private isQuotationVisibleForCustomer;
51
64
  private hasValidCustomerId;
65
+ private normalizeCustomerId;
52
66
  private isQuotationActiveAt;
53
67
  private findProductData;
54
68
  }
@@ -58,6 +58,40 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
58
58
  getQuotationList() {
59
59
  return this.store.list;
60
60
  }
61
+ getQuotationCustomerScopeInfo() {
62
+ const customerById = /* @__PURE__ */ new Map();
63
+ const quotationScopes = this.store.list.filter((quotation) => Array.isArray(quotation.customer) && quotation.customer.length > 0).map((quotation) => {
64
+ const customerIds = [];
65
+ const customers = [];
66
+ const localSeen = /* @__PURE__ */ new Set();
67
+ const quotationCustomers = quotation.customer || [];
68
+ quotationCustomers.forEach((customer) => {
69
+ const customerId = this.normalizeCustomerId(customer == null ? void 0 : customer.id);
70
+ if (!customerId || localSeen.has(customerId))
71
+ return;
72
+ localSeen.add(customerId);
73
+ customerIds.push(customerId);
74
+ customers.push(customer);
75
+ if (!customerById.has(customerId))
76
+ customerById.set(customerId, customer);
77
+ });
78
+ return {
79
+ quotationId: quotation.id,
80
+ quotationName: quotation.name,
81
+ customerIds,
82
+ customers
83
+ };
84
+ });
85
+ const result = {
86
+ quotationCount: this.store.list.length,
87
+ hasCustomerScopedQuotations: quotationScopes.length > 0,
88
+ allQuotationsCustomerScoped: this.store.list.length > 0 && quotationScopes.length === this.store.list.length,
89
+ customerIds: Array.from(customerById.keys()),
90
+ customers: Array.from(customerById.values()),
91
+ quotationScopes
92
+ };
93
+ return result;
94
+ }
61
95
  /**
62
96
  * Look up the quotation price for a specific product (+ optional variant) at a given datetime.
63
97
  * Returns the price as a string (e.g. "300.00"), or null if no quotation applies.
@@ -67,6 +101,10 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
67
101
  * the requested productId wins.
68
102
  */
69
103
  getPriceForProduct(params) {
104
+ var _a;
105
+ return ((_a = this.getQuotationMatchForProduct(params)) == null ? void 0 : _a.price) ?? null;
106
+ }
107
+ getQuotationMatchForProduct(params) {
70
108
  const { productId, variantId, datetime, customer_id } = params;
71
109
  for (const quotation of this.store.list) {
72
110
  const visible = this.isQuotationVisibleForCustomer(quotation, customer_id);
@@ -80,23 +118,16 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
80
118
  continue;
81
119
  if (match.value === 0)
82
120
  continue;
83
- return String(match.value);
121
+ return {
122
+ price: String(match.value),
123
+ quotationShelfId: quotation.id
124
+ };
84
125
  }
85
126
  return null;
86
127
  }
87
128
  getQuotationShelfId(params) {
88
- const { productId, variantId, datetime, customer_id } = params;
89
- for (const quotation of this.store.list) {
90
- if (!this.isQuotationVisibleForCustomer(quotation, customer_id))
91
- continue;
92
- if (!this.isQuotationActiveAt(quotation, datetime))
93
- continue;
94
- const match = this.findProductData(quotation.product_data, productId, variantId);
95
- if (!match || match.value === 0)
96
- continue;
97
- return quotation.id;
98
- }
99
- return 0;
129
+ var _a;
130
+ return ((_a = this.getQuotationMatchForProduct(params)) == null ? void 0 : _a.quotationShelfId) ?? 0;
100
131
  }
101
132
  /**
102
133
  * Batch pre-compute quotation prices for a set of products across multiple time points.
@@ -138,6 +169,11 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
138
169
  return false;
139
170
  return Number(customerId) > 0;
140
171
  }
172
+ normalizeCustomerId(customerId) {
173
+ if (customerId === void 0 || customerId === null || customerId === "")
174
+ return null;
175
+ return String(customerId);
176
+ }
141
177
  isQuotationActiveAt(quotation, datetime) {
142
178
  var _a;
143
179
  if (!((_a = quotation.schedule) == null ? void 0 : _a.length))
@@ -45,3 +45,17 @@ export interface QuotationItem {
45
45
  export interface QuotationState {
46
46
  list: QuotationItem[];
47
47
  }
48
+ export interface QuotationCustomerScope {
49
+ quotationId: number;
50
+ quotationName: string;
51
+ customerIds: string[];
52
+ customers: QuotationCustomer[];
53
+ }
54
+ export interface QuotationCustomerScopeInfo {
55
+ quotationCount: number;
56
+ hasCustomerScopedQuotations: boolean;
57
+ allQuotationsCustomerScoped: boolean;
58
+ customerIds: string[];
59
+ customers: QuotationCustomer[];
60
+ quotationScopes: QuotationCustomerScope[];
61
+ }
@@ -29,6 +29,7 @@ export declare class SalesSummaryModule extends BaseModule implements Module, Sa
29
29
  }): Promise<{
30
30
  tax_title: string;
31
31
  tax_rate: number | undefined;
32
+ tax_country_code: string;
32
33
  product_quantity: number;
33
34
  product_original_amount: string;
34
35
  product_amount: string;
@@ -119,8 +119,8 @@ var SalesSummaryModule = class extends import_BaseModule.BaseModule {
119
119
  const summarySchedule = this.core.getModule(
120
120
  `${this.name.split("_")[0]}_schedule`
121
121
  );
122
- const needScheduleIds = (_b = (_a = this.store.surchargeList) == null ? void 0 : _a.map((item) => item.available_schedule_ids)) == null ? void 0 : _b.flat();
123
- const scheduleList = summarySchedule == null ? void 0 : summarySchedule.getScheduleListByIds(needScheduleIds);
122
+ const needScheduleIds = (((_b = (_a = this.store.surchargeList) == null ? void 0 : _a.map((item) => item.available_schedule_ids)) == null ? void 0 : _b.flat()) || []).filter((id) => id !== void 0 && id !== null && id !== "");
123
+ const scheduleList = needScheduleIds.length > 0 ? summarySchedule == null ? void 0 : summarySchedule.getScheduleListByIds(needScheduleIds) : [];
124
124
  const scheduleById = {};
125
125
  if (Array.isArray(scheduleList)) {
126
126
  for (const item of scheduleList) {
@@ -139,7 +139,8 @@ var SalesSummaryModule = class extends import_BaseModule.BaseModule {
139
139
  const summaryWithTaxMeta = {
140
140
  ...summary,
141
141
  tax_title: taxConfig.taxTitle || "",
142
- tax_rate: taxRate ?? taxConfig.taxRate
142
+ tax_rate: taxRate ?? taxConfig.taxRate,
143
+ tax_country_code: taxConfig.taxCountryCode || ""
143
144
  };
144
145
  this.store.summary = summaryWithTaxMeta;
145
146
  return summaryWithTaxMeta;
@@ -9,6 +9,7 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
9
9
  private cacheId;
10
10
  private openCache;
11
11
  private fatherModule;
12
+ private hasLoadedScheduleList;
12
13
  constructor(name?: string, version?: string);
13
14
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
14
15
  /**
@@ -25,6 +26,9 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
25
26
  */
26
27
  loadAllSchedule(): Promise<void>;
27
28
  setScheduleList(list: ScheduleItem[]): void;
29
+ private syncScheduleMap;
30
+ getScheduleList(): ScheduleItem[];
31
+ isScheduleListLoaded(): boolean;
28
32
  loadScheduleAvailableDate({ startDate, endDate, custom_page_id, channel, }: LoadScheduleAvailableDateParams): Promise<import("../Date/types").ITime[]>;
29
33
  getScheduleListByIds(ids: number[]): ScheduleItem[];
30
34
  setAvailabilityScheduleDateList(list: ScheduleAvailabilityDateItem[]): void;
@@ -49,6 +49,7 @@ var ScheduleModule = class extends import_BaseModule.BaseModule {
49
49
  this.defaultVersion = "1.0.0";
50
50
  this.store = {};
51
51
  this.openCache = false;
52
+ this.hasLoadedScheduleList = false;
52
53
  }
53
54
  async initialize(core, options) {
54
55
  var _a, _b;
@@ -60,10 +61,14 @@ var ScheduleModule = class extends import_BaseModule.BaseModule {
60
61
  this.store = options == null ? void 0 : options.store;
61
62
  if (options.initialState) {
62
63
  this.store.scheduleList = options.initialState.scheduleList;
64
+ this.syncScheduleMap();
63
65
  this.store.availabilityDateList = options.initialState.availabilityDateList;
66
+ this.hasLoadedScheduleList = Array.isArray(options.initialState.scheduleList);
64
67
  } else {
65
68
  this.store.scheduleList = [];
69
+ this.store.map = /* @__PURE__ */ new Map();
66
70
  this.store.availabilityDateList = [];
71
+ this.hasLoadedScheduleList = false;
67
72
  }
68
73
  if ((_a = options.otherParams) == null ? void 0 : _a.cacheId) {
69
74
  this.openCache = options.otherParams.openCache;
@@ -101,6 +106,19 @@ var ScheduleModule = class extends import_BaseModule.BaseModule {
101
106
  }
102
107
  setScheduleList(list) {
103
108
  this.store.scheduleList = list;
109
+ this.syncScheduleMap();
110
+ this.hasLoadedScheduleList = true;
111
+ }
112
+ syncScheduleMap() {
113
+ this.store.map = new Map(
114
+ (this.store.scheduleList || []).map((schedule) => [Number(schedule.id), schedule])
115
+ );
116
+ }
117
+ getScheduleList() {
118
+ return this.store.scheduleList || [];
119
+ }
120
+ isScheduleListLoaded() {
121
+ return this.hasLoadedScheduleList;
104
122
  }
105
123
  async loadScheduleAvailableDate({
106
124
  startDate,
@@ -150,6 +168,9 @@ var ScheduleModule = class extends import_BaseModule.BaseModule {
150
168
  var _a;
151
169
  const idSet = new Set(ids.map((id) => String(id)));
152
170
  console.log("getScheduleListByIds", this.store.scheduleList);
171
+ if (this.store.map instanceof Map && this.store.map.size > 0) {
172
+ return ids.map((id) => this.store.map.get(Number(id))).filter(Boolean);
173
+ }
153
174
  const list = (_a = this.store.scheduleList) == null ? void 0 : _a.filter((n) => idSet.has(String(n.id)));
154
175
  return list;
155
176
  }
@@ -25,6 +25,8 @@ export interface LoadScheduleAvailableDateParams {
25
25
  channel?: string;
26
26
  }
27
27
  export interface ScheduleModuleAPI {
28
+ getScheduleList: () => ScheduleItem[];
29
+ isScheduleListLoaded: () => boolean;
28
30
  }
29
31
  export type ScheduleItem = {
30
32
  /** 颜色 */
@@ -2486,6 +2486,7 @@ var Server = class {
2486
2486
  const shouldClearLocalOrderId = this.isLocalCheckoutOrderId(next.order_id);
2487
2487
  if (shouldClearLocalOrderId)
2488
2488
  next.order_id = null;
2489
+ delete next.vouchers;
2489
2490
  const hasCheckoutOrderNumbers = !this.isBlankCheckoutValue(next.shop_order_number) && !this.isBlankCheckoutValue(next.shop_full_order_number);
2490
2491
  if (hasCheckoutOrderNumbers) {
2491
2492
  this.logInfo(`${title}: checkout 已携带订单号,跳过查重`, {
@@ -2541,7 +2542,6 @@ var Server = class {
2541
2542
  shop_order_number: next.shop_order_number,
2542
2543
  shop_full_order_number: next.shop_full_order_number
2543
2544
  });
2544
- delete next.vouchers;
2545
2545
  return next;
2546
2546
  } catch (error) {
2547
2547
  this.logWarning(`${title}: checkout 查找本地订单失败`, {
@@ -24,6 +24,9 @@ export declare class ProductsModule extends BaseModule implements Module {
24
24
  private quotationBridgeLoadedKey?;
25
25
  private quotationBridgeRefreshPromise?;
26
26
  private quotationBridgeRefreshKey?;
27
+ private quotationScheduleCache;
28
+ private quotationScheduleCacheSource;
29
+ private quotationScheduleCacheLoaded;
27
30
  private productDataSource;
28
31
  private pendingSyncMessages;
29
32
  private syncTimer?;
@@ -75,6 +78,7 @@ export declare class ProductsModule extends BaseModule implements Module {
75
78
  }): Promise<void>;
76
79
  private ensureQuotationBridgeReady;
77
80
  private getQuotationBridgeScopeKey;
81
+ private getQuotedPrice;
78
82
  private buildPriceDataFromQuotation;
79
83
  private buildVariantPriceData;
80
84
  private buildBundleGroupPriceData;