@pisell/pisellos 2.1.77 → 2.1.79

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.
@@ -147,6 +147,9 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
147
147
  taxTitle?: string | undefined;
148
148
  totalTaxFee?: string | number | undefined;
149
149
  isPriceIncludeTax?: 0 | 1 | undefined;
150
+ surchargeAmount?: string | number | undefined;
151
+ surcharge?: any[] | undefined;
152
+ taxRate?: string | number | undefined;
150
153
  deposit?: {
151
154
  total?: string | number | undefined;
152
155
  policies?: import("../../modules/Summary/types").IProtocol[] | undefined;
@@ -307,7 +310,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
307
310
  date: string;
308
311
  status: string;
309
312
  week: string;
310
- weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
313
+ weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
311
314
  }[]>;
312
315
  submitTimeSlot(timeSlots: TimeSliceItem): void;
313
316
  private getScheduleDataByIds;
@@ -354,7 +357,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
354
357
  };
355
358
  setOtherData(key: string, value: any): void;
356
359
  getOtherData(key: string): any;
357
- getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
360
+ getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
358
361
  /**
359
362
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
360
363
  *
@@ -4216,7 +4216,7 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
4216
4216
  openResources = ((_tempProducts = tempProducts) === null || _tempProducts === void 0 || (_tempProducts = _tempProducts.product_resource) === null || _tempProducts === void 0 || (_tempProducts = _tempProducts.resources) === null || _tempProducts === void 0 ? void 0 : _tempProducts.filter(function (m) {
4217
4217
  return m.status === 1;
4218
4218
  })) || []; // res.data 返回的一定是启用商品的资源列表,不需要再过滤了
4219
- allProductResources = sortCombinedResources(res.data); // allProductResources 需要根据商品里的资源的单个预约多个预约补充resourceType
4219
+ allProductResources = cloneDeep(sortCombinedResources(res.data) || []); // allProductResources 需要根据商品里的资源的单个预约多个预约补充resourceType
4220
4220
  allProductResources.forEach(function (m) {
4221
4221
  var _tempProducts2;
4222
4222
  var resource = (_tempProducts2 = tempProducts) === null || _tempProducts2 === void 0 || (_tempProducts2 = _tempProducts2.product_resource) === null || _tempProducts2 === void 0 || (_tempProducts2 = _tempProducts2.resources) === null || _tempProducts2 === void 0 ? void 0 : _tempProducts2.find(function (n) {
@@ -115,7 +115,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
115
115
  * 获取当前的客户搜索条件
116
116
  * @returns 当前搜索条件
117
117
  */
118
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
118
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
119
119
  /**
120
120
  * 获取客户列表状态(包含滚动加载相关状态)
121
121
  * @returns 客户状态
@@ -146,6 +146,8 @@ export interface CartItem {
146
146
  _optionsOrigin?: any[];
147
147
  /** 操作系统提示 */
148
148
  osWarnTips?: string[];
149
+ /** 金额差值 */
150
+ totalDifference?: number;
149
151
  }
150
152
  /**
151
153
  * 购物车状态接口
@@ -45,6 +45,7 @@ module.exports = __toCommonJS(cartProduct_exports);
45
45
  var import_decimal = __toESM(require("decimal.js"));
46
46
  var import_utils = require("../../Product/utils");
47
47
  var import_utils2 = require("../../../solution/ShopDiscount/utils");
48
+ var import_utils3 = require("../../Summary/utils");
48
49
  var handleVariantProduct = (product) => {
49
50
  var _a;
50
51
  if (product == null ? void 0 : product.product_variant_id) {
@@ -80,6 +81,7 @@ var formatProductToCartItem = (params) => {
80
81
  cartItem.price = product == null ? void 0 : product.price;
81
82
  cartItem.num = num;
82
83
  cartItem.total = getProductTotalPrice({ product, bundle, options, num, discounts });
84
+ cartItem.totalDifference = getTotalDifference({ product, bundle, discounts });
83
85
  cartItem.summaryTotal = cartItem.total * (num || 1);
84
86
  cartItem.origin_total = getProductOriginTotalPrice({
85
87
  product,
@@ -207,6 +209,18 @@ var getProductTotalPrice = (params) => {
207
209
  }
208
210
  return Math.max(0, price);
209
211
  };
212
+ var getTotalDifference = (params) => {
213
+ const { bundle, discounts } = params;
214
+ const bundleDiscountList = [];
215
+ if (bundle == null ? void 0 : bundle.length) {
216
+ bundle.forEach((currentValue) => {
217
+ bundleDiscountList.push(...(currentValue == null ? void 0 : currentValue.discount_list) || []);
218
+ });
219
+ }
220
+ const allDiscounts = [...discounts || [], ...bundleDiscountList];
221
+ const productDiscountProductDiscountDifference = (0, import_utils3.calcDiscountListDifference)(allDiscounts);
222
+ return productDiscountProductDiscountDifference || 0;
223
+ };
210
224
  var getProductOriginTotalPrice = (params) => {
211
225
  const { product, bundle, options, discounts } = params;
212
226
  const num = (params == null ? void 0 : params.num) || 1;
@@ -271,7 +285,8 @@ var formatBundle = (bundle) => {
271
285
  options: formatOptions(item == null ? void 0 : item.option),
272
286
  _bundle_product_id: item._bundle_product_id,
273
287
  discount_list: item.discount_list,
274
- originBundleItem: item.originBundleItem || item
288
+ originBundleItem: item.originBundleItem || item,
289
+ is_charge_tax: item == null ? void 0 : item.is_charge_tax
275
290
  };
276
291
  });
277
292
  };
@@ -37,5 +37,5 @@ export declare class DateModule extends BaseModule implements Module, DateModule
37
37
  getResourceAvailableTimeList(params: IGetAvailableTimeListParams): Promise<ITime[]>;
38
38
  clearDateRange(): void;
39
39
  storeChange(): void;
40
- getResourcesListByDate(date: string): any[] | undefined;
40
+ getResourcesListByDate(date: string): any[];
41
41
  }
@@ -258,7 +258,7 @@ var DateModule = class extends import_BaseModule.BaseModule {
258
258
  getResourcesListByDate(date) {
259
259
  var _a;
260
260
  const dateList = this.store.dateList;
261
- const resourcesList = (_a = dateList.find((item) => item.date === date)) == null ? void 0 : _a.resource;
261
+ const resourcesList = ((_a = dateList == null ? void 0 : dateList.find((item) => item.date === date)) == null ? void 0 : _a.resource) || [];
262
262
  return resourcesList;
263
263
  }
264
264
  };
@@ -451,7 +451,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
451
451
  }
452
452
  const applicableProducts = [];
453
453
  sortedFlattenedList.forEach((flatItem) => {
454
- var _a, _b;
454
+ var _a, _b, _c;
455
455
  const occupyingDiscountId = occupiedItems.get(flatItem._id);
456
456
  if (occupyingDiscountId !== void 0 && occupyingDiscountId !== discount.id) {
457
457
  return;
@@ -471,7 +471,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
471
471
  num: flatItem.num
472
472
  };
473
473
  }
474
- const quantity = flatItem.type === "main" ? product.quantity || 1 : (product.num || 1) * (((_a = flatItem.parentProduct) == null ? void 0 : _a.quantity) || 1);
474
+ const quantity = flatItem.type === "main" ? product.num || product.quantity || 1 : (product.num || product.quantity || 1) * (((_a = flatItem.parentProduct) == null ? void 0 : _a.num) || ((_b = flatItem.parentProduct) == null ? void 0 : _b.quantity) || 1);
475
475
  const originalAmount = flatItem.type === "main" ? Number(product.price ?? 0) : Number(flatItem.original_price ?? flatItem.price ?? 0);
476
476
  const productData = {
477
477
  productId: flatItem._id,
@@ -479,7 +479,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
479
479
  quantity
480
480
  };
481
481
  if (flatItem.type === "bundle") {
482
- productData.parentQuantity = ((_b = flatItem.parentProduct) == null ? void 0 : _b.quantity) || 1;
482
+ productData.parentQuantity = ((_c = flatItem.parentProduct) == null ? void 0 : _c.quantity) || 1;
483
483
  }
484
484
  applicableProducts.push(productData);
485
485
  });
@@ -13,6 +13,7 @@ export declare class SummaryModule extends BaseModule implements Module, ISummar
13
13
  private fatherModule;
14
14
  constructor(name?: string, version?: string);
15
15
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
16
+ getSurchargeList(): Promise<void>;
16
17
  getSummary(cartItems: CartItem[]): Promise<ISummaryState['summary']>;
17
18
  /**
18
19
  * 获取协议
@@ -21,4 +22,6 @@ export declare class SummaryModule extends BaseModule implements Module, ISummar
21
22
  */
22
23
  getProtocol(protocolId: string): Promise<any>;
23
24
  storeChange(): void;
25
+ private getTaxforUtils;
26
+ private getSurchargeforUtils;
24
27
  }
@@ -1,6 +1,8 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __export = (target, all) => {
6
8
  for (var name in all)
@@ -14,6 +16,14 @@ var __copyProps = (to, from, except, desc) => {
14
16
  }
15
17
  return to;
16
18
  };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
17
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
28
 
19
29
  // src/modules/Summary/index.ts
@@ -22,7 +32,9 @@ __export(Summary_exports, {
22
32
  SummaryModule: () => SummaryModule
23
33
  });
24
34
  module.exports = __toCommonJS(Summary_exports);
35
+ var import_decimal = __toESM(require("decimal.js"));
25
36
  var import_BaseModule = require("../BaseModule");
37
+ var import_Schedule = require("../Schedule");
26
38
  var import_utils = require("./utils");
27
39
  var SummaryModule = class extends import_BaseModule.BaseModule {
28
40
  constructor(name, version) {
@@ -50,11 +62,27 @@ var SummaryModule = class extends import_BaseModule.BaseModule {
50
62
  if (!this.shopStore) {
51
63
  throw new Error("SummaryModule 需要 shopStore 插件支持");
52
64
  }
65
+ this.getSurchargeList();
66
+ }
67
+ async getSurchargeList() {
68
+ const surchargeList = await this.request.get("/order/custom-surcharge/available", {
69
+ channel: "online-store",
70
+ is_assemble_product_data: 1,
71
+ is_assemble_schedule_data: 1,
72
+ with: ["relationSchedule"]
73
+ });
74
+ this.store.surchargeList = (surchargeList == null ? void 0 : surchargeList.data) || [];
53
75
  }
54
76
  async getSummary(cartItems) {
55
77
  var _a, _b;
56
78
  const shopInfo = ((_b = (_a = this.shopStore.get("core")) == null ? void 0 : _a.core) == null ? void 0 : _b.shop) || {};
57
- const summary = (0, import_utils.calculatePriceDetails)(shopInfo, cartItems);
79
+ this.core.getModule("appointmentBooking_schedule");
80
+ const summary = (0, import_utils.calculatePriceDetails)(
81
+ shopInfo,
82
+ cartItems,
83
+ import_Schedule.ScheduleModule.isInScheduleByDate,
84
+ this.store.surchargeList
85
+ );
58
86
  this.store.summary = summary;
59
87
  return this.store.summary;
60
88
  }
@@ -76,6 +104,25 @@ var SummaryModule = class extends import_BaseModule.BaseModule {
76
104
  });
77
105
  }
78
106
  }
107
+ getTaxforUtils(items, shopInfo, subtotal) {
108
+ return (0, import_utils.getTax)({ service: items, bookingDetail: null, bookingId: void 0 }, {
109
+ computed: {
110
+ productExpectAmount: subtotal,
111
+ shopDiscount: 0
112
+ },
113
+ isEdit: false,
114
+ tax_rate: shopInfo == null ? void 0 : shopInfo.tax_rate,
115
+ is_price_include_tax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax
116
+ });
117
+ }
118
+ getSurchargeforUtils(items) {
119
+ const surchargeList = (0, import_utils.getSurcharge)({ service: items, addons: [], bookingDetail: null, bookingId: void 0 }, { isEdit: false, isInScheduleByDate: import_Schedule.ScheduleModule.isInScheduleByDate, surcharge_list: this.store.surchargeList, scheduleById: {} });
120
+ const surchargeAmount = new import_decimal.default((0, import_utils.getSurchargeAmount)({ bookingDetail: null, bookingId: void 0 }, surchargeList, { isEdit: false }));
121
+ return {
122
+ surchargeList,
123
+ surchargeAmount: surchargeAmount.toFixed(2)
124
+ };
125
+ }
79
126
  };
80
127
  // Annotate the CommonJS export names for ESM import in node:
81
128
  0 && (module.exports = {
@@ -1,5 +1,6 @@
1
1
  import { CartItem } from '../Cart/types';
2
2
  export interface ISummaryState {
3
+ surchargeList: any[];
3
4
  summary: {
4
5
  /** 商品总价 */
5
6
  subtotal: string | number;
@@ -11,6 +12,12 @@ export interface ISummaryState {
11
12
  totalTaxFee?: string | number;
12
13
  /** 商品价格是否包含费率 */
13
14
  isPriceIncludeTax?: 0 | 1;
15
+ /** 附加费金额 */
16
+ surchargeAmount?: string | number;
17
+ /** 附加费列表 */
18
+ surcharge?: any[];
19
+ /** 税率 */
20
+ taxRate?: string | number;
14
21
  /** 定金 */
15
22
  deposit?: {
16
23
  /** 定金总价 */
@@ -1,12 +1,57 @@
1
1
  import Decimal from 'decimal.js';
2
2
  import { CartItem } from '../Cart/types';
3
3
  import { ISummaryState } from './types';
4
- export declare const calculatePriceDetails: (shopInfo: any, items: CartItem[]) => ISummaryState['summary'];
4
+ export declare const calculatePriceDetails: (shopInfo: any, items: CartItem[], isInScheduleByDate: any, surchargeList: any[]) => ISummaryState['summary'];
5
5
  /**
6
6
  * 获取子商品折扣信息
7
7
  * @param item
8
8
  */
9
9
  export declare const getBundleDiscountList: (bundle: any[]) => any[];
10
+ export declare const calcDiscountListDifference: (discountList: any[]) => any;
11
+ export declare const getProductDiscountProductDiscountDifference: (item: CartItem) => any;
12
+ /**
13
+ * 计算订单税费(折扣前/折扣后),并把单品税费信息回写到商品数据上(用于明细展示/后续计算)。
14
+ *
15
+ * - **折扣前税费**:`originTax`
16
+ * - **折扣后税费**:`tax`(会考虑 `computed.shopDiscount` 对每个商品的分摊影响)
17
+ * - **税率/是否含税**:优先取 `bookingDetail.tax_rate` / `bookingDetail.is_price_include_tax`,取不到再回退到 `options.tax_rate` / `options.is_price_include_tax`
18
+ *
19
+ * **副作用(会修改入参商品对象)**:
20
+ * - 主商品:写入 `item.original_tax_fee` / `item.tax_fee`(四舍五入保留两位)
21
+ * - bundle 原价子商品:写入 `bundleItem.original_tax_fee` / `bundleItem.tax_fee`
22
+ * - 加时商品(`relation_details`):写入 `atItem.tax_fee`
23
+ * - 税费舍入差值:追加到最后一个“含税商品”的 `tax_fee_rounding_remainder` / `original_tax_fee_rounding_remainder`
24
+ *
25
+ * @param params 入参集合(RORO)
26
+ * @param params.service 服务商品数组(主商品)。通常是购物车商品结构(可能包含 `bundle` / `relation_details`)
27
+ * @param params.addons 附加商品数组(可选)。结构同商品数组
28
+ * @param params.bookingDetail 订单详情(编辑/详情场景用于读取后端税率配置),可选
29
+ * @param params.bookingId 订单/预约 ID(编辑/详情场景识别用),可选
30
+ * @param options 计算选项
31
+ * @param options.isEdit 是否处于“编辑中”。当前实现不强依赖该值(历史逻辑保留),但建议按真实状态传入
32
+ * @param options.computed 预计算结果(用于折扣分摊)
33
+ * @param options.computed.productExpectAmount 商品期望总金额(用于按比例分摊折扣)
34
+ * @param options.computed.shopDiscount 店铺折扣总额(用于按比例分摊到商品)
35
+ * @param options.tax_rate 管理端税率(百分比,如 5 表示 5%)。仅当 `bookingDetail.tax_rate` 不存在时生效
36
+ * @param options.is_price_include_tax 是否含税:`0` 不含税、`1` 含税。仅当 `bookingDetail.is_price_include_tax` 不存在时生效
37
+ * @returns 税费汇总(number,金额单位与商品价格一致,四舍五入保留两位)
38
+ * @returns.originTax 折扣前税费合计
39
+ * @returns.tax 折扣后税费合计
40
+ */
41
+ export declare const getTax: ({ service, addons, bookingDetail, bookingId }: {
42
+ service?: any;
43
+ addons?: any;
44
+ bookingDetail?: any;
45
+ bookingId?: number | undefined;
46
+ }, options: {
47
+ isEdit: boolean;
48
+ computed: Record<string, number | string>;
49
+ tax_rate?: number;
50
+ is_price_include_tax?: number;
51
+ } & Record<string, any>) => {
52
+ originTax: number;
53
+ tax: number;
54
+ };
10
55
  /**
11
56
  * 计算商品小计(不含其他费用)
12
57
  * @param items - 购物车商品数组
@@ -32,3 +77,61 @@ export declare const calculateDeposit: (items: CartItem[]) => {
32
77
  protocols: any[];
33
78
  hasDeposit: never;
34
79
  } | undefined;
80
+ /**
81
+ * 计算订单附加费金额(订单级别合计)。
82
+ *
83
+ * - **详情未编辑**(`!options.isEdit && bookingId`)且存在后端详情时:直接返回 `bookingDetail.surcharge_fee`
84
+ * - **新增/编辑**时:对 `surcharge`(通常为 `getSurcharge` 的返回值)按 `item.value` 求和
85
+ *
86
+ * @param params 入参集合(RORO)
87
+ * @param params.bookingDetail 订单详情(详情未编辑时用于读取后端的 `surcharge_fee`),可选
88
+ * @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
89
+ * @param surcharge 附加费列表(通常来自 `getSurcharge`),元素结构至少包含 `value: number`
90
+ * @param options 计算选项
91
+ * @param options.isEdit 是否处于“编辑中”。`false` 时会优先走后端金额直取逻辑(若存在)
92
+ * @returns 订单附加费金额(number,金额单位与商品价格一致)
93
+ */
94
+ export declare const getSurchargeAmount: ({ bookingDetail, bookingId }: {
95
+ bookingDetail?: any;
96
+ bookingId?: number | undefined;
97
+ }, surcharge: any[], options: any) => any;
98
+ /**
99
+ * 订单附加费各项信息
100
+ *
101
+ * - **详情未编辑**(`!options.isEdit && bookingId`)时:直接返回 `bookingDetail.surcharge`(后端计算结果)
102
+ * - **新增/编辑**时:按 `options.surcharge_list` 逐条配置计算本次订单的附加费
103
+ *
104
+ * 规则要点:
105
+ * - 匹配范围包含:主商品(`service`)、原价 bundle 子商品(`item.bundle`)、加时商品(`item.relation_details`)、以及 addons(`addons.value`)
106
+ * - 固定附加费 `fixed`:只加一次,再按商品数量分摊(向下取整保留两位),剩余小数会以 `surcharge_rounding_remainder` 形式抹平到最后一个商品
107
+ * - 百分比附加费 `percentage`:按每个商品(价格 * 数量)分别计算再累加
108
+ * - 当 `open_product === 0`:不回写到商品,只在订单级别累加;否则会把单品附加费回写到商品
109
+ *
110
+ * **副作用(可能修改入参商品对象)**:
111
+ * - 当 `open_product !== 0` 时:写入 `item.surcharge_fee`(单品单数量附加费,保留两位、向下取整)
112
+ * - 写入 `item.relation_surcharge_ids`(关联到的 surcharge 配置 id 列表)
113
+ * - 写入 `item.surcharge_rounding_remainder`(用于抹平固定附加费/总额舍入差)
114
+ *
115
+ * @param params 入参集合(RORO)
116
+ * @param params.service 服务商品数组(主商品)。元素可能包含 `bundle` / `relation_details`
117
+ * @param params.addons 附加商品容器。当前实现读取 `addons.value` 作为商品数组(所以通常传 `{ value: CartItem[] }`)
118
+ * @param params.bookingDetail 订单详情(详情未编辑时用于直接取后端的 surcharge 列表),可选
119
+ * @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
120
+ * @param options 计算选项
121
+ * @param options.isEdit 是否处于“编辑中”。`false` 且存在 `bookingId` 时会走详情直取逻辑
122
+ * @param options.surcharge_list 附加费配置列表(后端下发)。缺失/为空则返回空数组
123
+ * @param options.isInScheduleByDate 判断日期是否落在某个 schedule 内的方法(通常来自 ScheduleModule)
124
+ * @param options.scheduleById schedule 映射表:`{ [scheduleId]: schedule }`(用于根据配置的 `available_schedule_ids` 做日程匹配)
125
+ * @returns 附加费列表(仅返回金额 > 0 的项)
126
+ */
127
+ export declare const getSurcharge: ({ service, addons, bookingDetail, bookingId }: {
128
+ service: any;
129
+ addons: any;
130
+ bookingDetail?: any;
131
+ bookingId?: number | undefined;
132
+ }, options: {
133
+ isEdit: boolean;
134
+ isInScheduleByDate: any;
135
+ surcharge_list?: any[];
136
+ scheduleById?: Record<string, any>;
137
+ } & Record<string, any>) => any;