@pisell/pisellos 2.2.163 → 2.2.165

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 (124) hide show
  1. package/dist/modules/BookingContext/index.d.ts +37 -0
  2. package/dist/modules/BookingContext/index.js +436 -0
  3. package/dist/modules/BookingContext/types.d.ts +102 -0
  4. package/dist/modules/BookingContext/types.js +51 -0
  5. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  6. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +157 -0
  7. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  8. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +137 -0
  9. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +65 -0
  10. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +191 -0
  11. package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
  12. package/dist/modules/BookingContext/utils/flexible.js +56 -0
  13. package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  14. package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
  15. package/dist/modules/BookingContext/utils/index.d.ts +11 -0
  16. package/dist/modules/BookingContext/utils/index.js +11 -0
  17. package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
  18. package/dist/modules/BookingContext/utils/noResource.js +77 -0
  19. package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
  20. package/dist/modules/BookingContext/utils/productExtend.js +339 -0
  21. package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  22. package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
  23. package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  24. package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
  25. package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
  26. package/dist/modules/BookingContext/utils/resources.js +486 -0
  27. package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  28. package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
  29. package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  30. package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
  31. package/dist/modules/Customer/index.js +23 -22
  32. package/dist/modules/Discount/index.js +4 -3
  33. package/dist/modules/Order/index.d.ts +25 -7
  34. package/dist/modules/Order/index.js +608 -291
  35. package/dist/modules/Order/types.d.ts +46 -14
  36. package/dist/modules/Order/types.js +2 -0
  37. package/dist/modules/Order/utils.d.ts +10 -0
  38. package/dist/modules/Order/utils.js +76 -23
  39. package/dist/modules/SalesSummary/index.js +4 -2
  40. package/dist/modules/index.d.ts +1 -0
  41. package/dist/modules/index.js +2 -1
  42. package/dist/solution/BaseSales/index.d.ts +46 -7
  43. package/dist/solution/BaseSales/index.js +928 -312
  44. package/dist/solution/BaseSales/types.d.ts +51 -1
  45. package/dist/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
  46. package/dist/solution/BaseSales/utils/quotationPrice.js +159 -0
  47. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +33 -14
  48. package/dist/solution/BaseSales/utils.js +36 -7
  49. package/dist/solution/BookingByStep/index.d.ts +1 -1
  50. package/dist/solution/BookingTicket/index.d.ts +124 -1
  51. package/dist/solution/BookingTicket/index.js +488 -90
  52. package/dist/solution/BookingTicket/types.d.ts +2 -0
  53. package/dist/solution/BookingTicket/types.js +3 -0
  54. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +111 -0
  55. package/dist/solution/BookingTicket/utils/addProductDecision.js +334 -0
  56. package/dist/solution/ScanOrder/index.d.ts +9 -3
  57. package/dist/solution/ScanOrder/index.js +231 -128
  58. package/dist/solution/ScanOrder/utils.js +36 -7
  59. package/dist/solution/VenueBooking/index.d.ts +4 -2
  60. package/dist/solution/VenueBooking/index.js +103 -55
  61. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
  62. package/dist/solution/VenueBooking/utils/slotMerge.js +10 -0
  63. package/lib/modules/BookingContext/index.d.ts +37 -0
  64. package/lib/modules/BookingContext/index.js +297 -0
  65. package/lib/modules/BookingContext/types.d.ts +102 -0
  66. package/lib/modules/BookingContext/types.js +34 -0
  67. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  68. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +174 -0
  69. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  70. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +141 -0
  71. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +65 -0
  72. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +177 -0
  73. package/lib/modules/BookingContext/utils/flexible.d.ts +28 -0
  74. package/lib/modules/BookingContext/utils/flexible.js +80 -0
  75. package/lib/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  76. package/lib/modules/BookingContext/utils/formatResourceList.js +50 -0
  77. package/lib/modules/BookingContext/utils/index.d.ts +11 -0
  78. package/lib/modules/BookingContext/utils/index.js +43 -0
  79. package/lib/modules/BookingContext/utils/noResource.d.ts +13 -0
  80. package/lib/modules/BookingContext/utils/noResource.js +90 -0
  81. package/lib/modules/BookingContext/utils/productExtend.d.ts +72 -0
  82. package/lib/modules/BookingContext/utils/productExtend.js +283 -0
  83. package/lib/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  84. package/lib/modules/BookingContext/utils/resourceErrors.js +80 -0
  85. package/lib/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  86. package/lib/modules/BookingContext/utils/resourceSelection.js +46 -0
  87. package/lib/modules/BookingContext/utils/resources.d.ts +80 -0
  88. package/lib/modules/BookingContext/utils/resources.js +377 -0
  89. package/lib/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  90. package/lib/modules/BookingContext/utils/serviceTimes.js +162 -0
  91. package/lib/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  92. package/lib/modules/BookingContext/utils/timeSlices.js +124 -0
  93. package/lib/modules/Customer/index.js +8 -8
  94. package/lib/modules/Discount/index.js +5 -1
  95. package/lib/modules/Order/index.d.ts +25 -7
  96. package/lib/modules/Order/index.js +268 -72
  97. package/lib/modules/Order/types.d.ts +46 -14
  98. package/lib/modules/Order/utils.d.ts +10 -0
  99. package/lib/modules/Order/utils.js +66 -15
  100. package/lib/modules/SalesSummary/index.js +4 -2
  101. package/lib/modules/index.d.ts +1 -0
  102. package/lib/modules/index.js +3 -1
  103. package/lib/solution/BaseSales/index.d.ts +46 -7
  104. package/lib/solution/BaseSales/index.js +369 -17
  105. package/lib/solution/BaseSales/types.d.ts +51 -1
  106. package/lib/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
  107. package/lib/solution/BaseSales/utils/quotationPrice.js +201 -0
  108. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +31 -10
  109. package/lib/solution/BaseSales/utils.js +37 -5
  110. package/lib/solution/BookingByStep/index.d.ts +1 -1
  111. package/lib/solution/BookingTicket/index.d.ts +124 -1
  112. package/lib/solution/BookingTicket/index.js +255 -8
  113. package/lib/solution/BookingTicket/types.d.ts +2 -0
  114. package/lib/solution/BookingTicket/types.js +6 -0
  115. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +111 -0
  116. package/lib/solution/BookingTicket/utils/addProductDecision.js +308 -0
  117. package/lib/solution/ScanOrder/index.d.ts +9 -3
  118. package/lib/solution/ScanOrder/index.js +147 -66
  119. package/lib/solution/ScanOrder/utils.js +37 -5
  120. package/lib/solution/VenueBooking/index.d.ts +4 -2
  121. package/lib/solution/VenueBooking/index.js +50 -14
  122. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
  123. package/lib/solution/VenueBooking/utils/slotMerge.js +10 -0
  124. package/package.json +1 -1
@@ -0,0 +1,201 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
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
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/solution/BaseSales/utils/quotationPrice.ts
30
+ var quotationPrice_exports = {};
31
+ __export(quotationPrice_exports, {
32
+ calculateBaseSalesProductBookingPrice: () => calculateBaseSalesProductBookingPrice
33
+ });
34
+ module.exports = __toCommonJS(quotationPrice_exports);
35
+ var import_dayjs = __toESM(require("dayjs"));
36
+ var import_decimal = __toESM(require("decimal.js"));
37
+ function toFiniteNumber(value, fallback = 0) {
38
+ const parsedValue = Number(value);
39
+ if (!Number.isFinite(parsedValue))
40
+ return fallback;
41
+ return parsedValue;
42
+ }
43
+ function toPositiveInt(value, fallback = 1) {
44
+ const parsedValue = Math.floor(Number(value));
45
+ if (!Number.isFinite(parsedValue) || parsedValue < 1)
46
+ return fallback;
47
+ return parsedValue;
48
+ }
49
+ function toPriceString(value) {
50
+ return new import_decimal.default(Number(value) || 0).toDecimalPlaces(2).toFixed(2);
51
+ }
52
+ function normalizeDateTime(value) {
53
+ if (typeof value !== "string" || !value.trim())
54
+ return null;
55
+ const normalized = value.includes(":") ? value : `${value} 00:00:00`;
56
+ const datetime = (0, import_dayjs.default)(normalized);
57
+ if (!datetime.isValid())
58
+ return null;
59
+ return datetime;
60
+ }
61
+ function buildBookingDateTime(date, time) {
62
+ if (typeof date !== "string" || !date.trim())
63
+ return null;
64
+ const timeText = typeof time === "string" && time.trim() ? time.trim() : "00:00";
65
+ const datetime = (0, import_dayjs.default)(`${date.trim()} ${timeText}`);
66
+ if (!datetime.isValid())
67
+ return null;
68
+ return datetime;
69
+ }
70
+ function getDurationUnit(type) {
71
+ const normalizedType = String(type || "").toLowerCase();
72
+ if (normalizedType === "day" || normalizedType === "days")
73
+ return "day";
74
+ if (normalizedType === "minute" || normalizedType === "minutes")
75
+ return "minute";
76
+ return null;
77
+ }
78
+ function getProductId(product) {
79
+ const productId = toFiniteNumber(product.product_id ?? product.id, NaN);
80
+ if (!Number.isFinite(productId))
81
+ return null;
82
+ return productId;
83
+ }
84
+ function getProductVariantId(product) {
85
+ const variantId = toFiniteNumber(
86
+ product.product_variant_id ?? product.variant_id,
87
+ 0
88
+ );
89
+ if (!Number.isFinite(variantId) || variantId <= 0)
90
+ return void 0;
91
+ return variantId;
92
+ }
93
+ function getFallbackPrice(params) {
94
+ const product = params.product || {};
95
+ return toPriceString(
96
+ params.fallback_price ?? product.price ?? product.selling_price ?? product.original_price ?? 0
97
+ );
98
+ }
99
+ function getProductQuantity(product) {
100
+ return toPositiveInt(product.num ?? product.quantity, 1);
101
+ }
102
+ function shouldSplitByDuration(duration, start, end) {
103
+ if (!duration)
104
+ return false;
105
+ if (!start || !end || !end.isAfter(start))
106
+ return false;
107
+ const unit = getDurationUnit(duration.type);
108
+ const value = toFiniteNumber(duration.value);
109
+ return !!unit && value > 0;
110
+ }
111
+ function buildTimeSegments(params) {
112
+ const booking = params.booking || {};
113
+ const explicitDatetime = normalizeDateTime(params.datetime);
114
+ const bookingStart = buildBookingDateTime(booking.start_date, booking.start_time);
115
+ const start = bookingStart || explicitDatetime || (0, import_dayjs.default)();
116
+ const bookingEnd = buildBookingDateTime(booking.end_date, booking.end_time);
117
+ if (!shouldSplitByDuration(params.duration, start, bookingEnd)) {
118
+ return [{ start }];
119
+ }
120
+ const unit = getDurationUnit(params.duration.type);
121
+ const value = toFiniteNumber(params.duration.value);
122
+ const segments = [];
123
+ let cursor = start;
124
+ let guard = 0;
125
+ while (cursor.isBefore(bookingEnd) && guard < 1e4) {
126
+ const next = cursor.add(value, unit);
127
+ segments.push({
128
+ start: cursor,
129
+ end: next.isBefore(bookingEnd) ? next : bookingEnd ?? void 0
130
+ });
131
+ cursor = next;
132
+ guard += 1;
133
+ }
134
+ return segments.length ? segments : [{ start }];
135
+ }
136
+ function formatTimePoint(datetime) {
137
+ return datetime.format("YYYY-MM-DD HH:mm:ss");
138
+ }
139
+ function buildPriceSegment(params) {
140
+ const timePoint = formatTimePoint(params.segment.start);
141
+ const quotedPrice = params.quotation && params.productId !== null ? params.quotation.getPriceForProduct({
142
+ productId: params.productId,
143
+ variantId: params.variantId,
144
+ datetime: timePoint,
145
+ customer_id: params.customerId
146
+ }) : null;
147
+ const unitPrice = toPriceString(quotedPrice ?? params.fallbackPrice);
148
+ const quotationShelfId = quotedPrice !== null && params.quotation && params.productId !== null ? params.quotation.getQuotationShelfId({
149
+ productId: params.productId,
150
+ variantId: params.variantId,
151
+ datetime: timePoint,
152
+ customer_id: params.customerId
153
+ }) : 0;
154
+ return {
155
+ start_datetime: timePoint,
156
+ end_datetime: params.segment.end ? formatTimePoint(params.segment.end) : void 0,
157
+ time_point: timePoint,
158
+ unit_price: unitPrice,
159
+ quantity: 1,
160
+ total_price: unitPrice,
161
+ quotation_shelf_id: quotationShelfId,
162
+ source: quotedPrice !== null ? "quotation" : "fallback"
163
+ };
164
+ }
165
+ function calculateBaseSalesProductBookingPrice(params) {
166
+ var _a;
167
+ const product = params.product || {};
168
+ const productId = getProductId(product);
169
+ const variantId = getProductVariantId(product);
170
+ const productQuantity = getProductQuantity(product);
171
+ const fallbackPrice = getFallbackPrice(params);
172
+ const segments = buildTimeSegments(params).map((segment) => buildPriceSegment({
173
+ quotation: params.quotation,
174
+ productId,
175
+ variantId,
176
+ customerId: params.customer_id,
177
+ fallbackPrice,
178
+ segment
179
+ }));
180
+ const unitPrice = segments.reduce(
181
+ (total, segment) => total.plus(segment.total_price),
182
+ new import_decimal.default(0)
183
+ );
184
+ const totalPrice = unitPrice.times(productQuantity);
185
+ const quotationShelfId = ((_a = segments.find((segment) => segment.quotation_shelf_id)) == null ? void 0 : _a.quotation_shelf_id) || 0;
186
+ return {
187
+ product_id: productId,
188
+ product_variant_id: variantId ?? 0,
189
+ customer_id: params.customer_id,
190
+ unit_price: unitPrice.toDecimalPlaces(2).toFixed(2),
191
+ total_price: totalPrice.toDecimalPlaces(2).toFixed(2),
192
+ quantity: productQuantity,
193
+ duration: params.duration,
194
+ quotation_shelf_id: quotationShelfId,
195
+ segments
196
+ };
197
+ }
198
+ // Annotate the CommonJS export names for ESM import in node:
199
+ 0 && (module.exports = {
200
+ calculateBaseSalesProductBookingPrice
201
+ });
@@ -62,13 +62,23 @@ function normalizeOptionItems(optionItems) {
62
62
  };
63
63
  });
64
64
  }
65
- function normalizeBundleItems(bundleItems) {
65
+ function normalizeBundleItems(bundleItems, preferPriceField = false) {
66
66
  if (!Array.isArray(bundleItems))
67
67
  return [];
68
- return bundleItems.map((bundleItem) => ({
69
- ...bundleItem,
70
- option: normalizeOptionItems(bundleItem == null ? void 0 : bundleItem.option)
71
- }));
68
+ return bundleItems.map((bundleItem) => {
69
+ const unitSelling = preferPriceField ? bundleItem.price ?? bundleItem.bundle_selling_price ?? bundleItem.custom_price ?? bundleItem.product_price ?? "0" : bundleItem.bundle_selling_price ?? bundleItem.price ?? bundleItem.custom_price ?? bundleItem.product_price ?? "0";
70
+ const unitStr = toPriceString(unitSelling, "0.00");
71
+ const num = toSafePositiveInt((bundleItem == null ? void 0 : bundleItem.num) ?? (bundleItem == null ? void 0 : bundleItem.quantity), 1);
72
+ return {
73
+ ...bundleItem,
74
+ num,
75
+ quantity: (bundleItem == null ? void 0 : bundleItem.quantity) ?? num,
76
+ price: bundleItem.price ?? unitStr,
77
+ bundle_selling_price: unitStr,
78
+ original_price: bundleItem.original_price ?? bundleItem.product_price ?? bundleItem.price ?? unitStr,
79
+ option: normalizeOptionItems(bundleItem == null ? void 0 : bundleItem.option)
80
+ };
81
+ });
72
82
  }
73
83
  function findVariantById(origin, variantId) {
74
84
  if (!origin || !variantId || variantId <= 0)
@@ -77,7 +87,7 @@ function findVariantById(origin, variantId) {
77
87
  return variants.find((variant) => Number(variant == null ? void 0 : variant.id) === variantId) || null;
78
88
  }
79
89
  function transformBaseProductToOrderProduct(params) {
80
- var _a, _b;
90
+ var _a, _b, _c;
81
91
  const { payload, fallbackProductId = null } = params;
82
92
  if (!payload || typeof payload !== "object")
83
93
  return null;
@@ -101,11 +111,17 @@ function transformBaseProductToOrderProduct(params) {
101
111
  payload.price ?? payload.selling_price ?? (matchedVariant == null ? void 0 : matchedVariant.price) ?? (matchedVariant == null ? void 0 : matchedVariant.base_price) ?? (origin == null ? void 0 : origin.price) ?? (origin == null ? void 0 : origin.base_price) ?? (sourceProduct == null ? void 0 : sourceProduct.price) ?? (sourceProduct == null ? void 0 : sourceProduct.selling_price) ?? (sourceProduct == null ? void 0 : sourceProduct.base_price),
102
112
  "0.00"
103
113
  );
114
+ const lineCompositeTotal = toPriceString(
115
+ payload.line_total ?? payload.total ?? ((_c = payload._extend) == null ? void 0 : _c.total),
116
+ sourceProductPrice
117
+ );
118
+ const hasPriceOverride = payload.price_override !== void 0 && payload.price_override !== null && payload.price_override !== "";
104
119
  const productOptionItem = normalizeOptionItems(
105
120
  payload.option ?? payload.options ?? payload.product_option_item
106
121
  );
107
122
  const productBundle = normalizeBundleItems(
108
- payload.bundle ?? payload.product_bundle
123
+ payload.bundle ?? payload.product_bundle,
124
+ hasPriceOverride
109
125
  );
110
126
  const uniqueIdentificationNumber = payload.unique_identification_number ?? payload.unique;
111
127
  const metadata = {
@@ -119,7 +135,11 @@ function transformBaseProductToOrderProduct(params) {
119
135
  policy_id: payload.policy_id,
120
136
  source_shop_id: payload.source_shop_id,
121
137
  origin,
122
- source_product_price: sourceProductPrice
138
+ source_product_price: sourceProductPrice,
139
+ main_product_selling_price: sourceProductPrice,
140
+ main_product_original_price: sourceProductPrice,
141
+ ...hasPriceOverride ? { price_override: String(payload.price_override) } : {},
142
+ ...payload.bundle_edit !== void 0 ? { bundle_edit: payload.bundle_edit } : {}
123
143
  };
124
144
  if (uniqueIdentificationNumber) {
125
145
  metadata.unique_identification_number = String(uniqueIdentificationNumber);
@@ -131,8 +151,9 @@ function transformBaseProductToOrderProduct(params) {
131
151
  num: toSafePositiveInt(payload.quantity ?? payload.num, 1),
132
152
  product_option_item: productOptionItem,
133
153
  product_bundle: productBundle,
134
- selling_price: sourceProductPrice,
135
- original_price: sourceProductPrice,
154
+ // 折后行价由 normalizeOrderProduct 按 main + bundle 合成;手动改价时 bundle 已为分摊后单价
155
+ selling_price: lineCompositeTotal,
156
+ original_price: lineCompositeTotal,
136
157
  tax_fee: toPriceString(
137
158
  payload.tax_fee ?? (matchedVariant == null ? void 0 : matchedVariant.tax_fee) ?? (origin == null ? void 0 : origin.tax_fee) ?? (sourceProduct == null ? void 0 : sourceProduct.tax_fee),
138
159
  "0.00"
@@ -102,12 +102,40 @@ function isSkuOnlyDeleteIdentity(x) {
102
102
  return !("product_option_item" in x) && !("product_bundle" in x);
103
103
  }
104
104
  function normalizeOrderProduct(product) {
105
- var _a, _b, _c;
105
+ var _a, _b, _c, _d, _e, _f;
106
106
  const metadata = { ...product.metadata || {} };
107
107
  const resolvedIdentityKey = ((_a = product.metadata) == null ? void 0 : _a.unique_identification_number) ? String(product.metadata.unique_identification_number) : product.unique_identification_number && String(product.unique_identification_number).length > 0 ? String(product.unique_identification_number) : product.identity_key && String(product.identity_key).length > 0 ? String(product.identity_key) : (0, import_utils.createUuidV4)();
108
108
  metadata.unique_identification_number = resolvedIdentityKey;
109
- const normalizedBundle = (product.product_bundle || []).map((item) => ({
109
+ const priceOverride = metadata.price_override;
110
+ const originOtherBundle = (_d = (_c = (_b = metadata.origin) == null ? void 0 : _b._extend) == null ? void 0 : _c.other) == null ? void 0 : _d.bundle;
111
+ let bundleInput = product.product_bundle || [];
112
+ if (priceOverride !== void 0 && priceOverride !== null && priceOverride !== "" && Array.isArray(originOtherBundle) && originOtherBundle.length > 0) {
113
+ const priceById = /* @__PURE__ */ new Map();
114
+ originOtherBundle.forEach((item) => {
115
+ if ((item == null ? void 0 : item.id) == null)
116
+ return;
117
+ const unit = item.price ?? item.bundle_selling_price;
118
+ if (unit === void 0 || unit === null)
119
+ return;
120
+ priceById.set(String(item.id), String(unit));
121
+ });
122
+ const base = Array.isArray(bundleInput) && bundleInput.length > 0 ? bundleInput : originOtherBundle;
123
+ bundleInput = base.map((item) => {
124
+ const unit = priceById.get(String(item == null ? void 0 : item.id));
125
+ if (unit === void 0)
126
+ return item;
127
+ return {
128
+ ...item,
129
+ price: unit,
130
+ bundle_selling_price: unit
131
+ };
132
+ });
133
+ }
134
+ const normalizedBundle = bundleInput.map((item) => ({
110
135
  ...item,
136
+ bundle_id: item.bundle_id ?? item.id,
137
+ bundle_product_id: item.bundle_product_id ?? item._bundle_product_id,
138
+ bundle_group_id: item.bundle_group_id ?? item.group_id,
111
139
  bundle_selling_price: item.bundle_selling_price ?? item.price ?? "0.00",
112
140
  price: item.price ?? item.custom_price ?? item.bundle_selling_price ?? "0.00",
113
141
  price_type: item.price_type ?? item.custom_price_type ?? "",
@@ -117,8 +145,8 @@ function normalizeOrderProduct(product) {
117
145
  const optionSum = (0, import_utils.sumOptionUnitPrice)(normalizedOptions);
118
146
  const isV2 = metadata.price_schema_version === 2 || metadata.price_schema_version === "2";
119
147
  const variantId = Number(product.product_variant_id || 0);
120
- const variantList = variantId ? (_b = metadata == null ? void 0 : metadata.origin) == null ? void 0 : _b.variant : null;
121
- const variantPrice = Array.isArray(variantList) ? (_c = variantList.find((v) => Number(v == null ? void 0 : v.id) === variantId)) == null ? void 0 : _c.price : void 0;
148
+ const variantList = variantId ? (_e = metadata == null ? void 0 : metadata.origin) == null ? void 0 : _e.variant : null;
149
+ const variantPrice = Array.isArray(variantList) ? (_f = variantList.find((v) => Number(v == null ? void 0 : v.id) === variantId)) == null ? void 0 : _f.price : void 0;
122
150
  const resolvedSource = (() => {
123
151
  var _a2, _b2;
124
152
  if (metadata.source_product_price !== void 0) {
@@ -174,6 +202,10 @@ function normalizeOrderProduct(product) {
174
202
  bundle: normalizedBundle,
175
203
  useOriginalBundle: true
176
204
  });
205
+ const finalOriginalPrice = (0, import_utils.resolveManualOverrideLineOriginalPrice)(
206
+ { num: product.num, metadata },
207
+ composedOriginalPrice
208
+ );
177
209
  return {
178
210
  order_detail_id: product.order_detail_id || null,
179
211
  product_id: product.product_id,
@@ -181,7 +213,7 @@ function normalizeOrderProduct(product) {
181
213
  product_variant_id: product.product_variant_id,
182
214
  product_option_item: normalizedOptions,
183
215
  selling_price: composedSellingPrice,
184
- original_price: composedOriginalPrice,
216
+ original_price: finalOriginalPrice,
185
217
  tax_fee: product.tax_fee || "0.00",
186
218
  is_charge_tax: product.is_charge_tax ?? 0,
187
219
  discount_list: product.discount_list || [],
@@ -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 | 5 | 4;
314
+ weekNum: 0 | 2 | 1 | 5 | 3 | 4 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -1,10 +1,15 @@
1
1
  import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BookingTicketCartView, BookingTicketProductCatalogView, BookingTicketState, IGetCustomerListParams, ICustomer, ILoadProductsParams, ILoadProductDetailParams, IScanResult } from './types';
3
3
  import type { ProductData } from '../../modules';
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';
4
5
  import type { OrderCustomerView } from '../../modules/Order/types';
5
6
  import { BaseSalesImpl } from '../BaseSales';
6
7
  import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
7
8
  import type { LoadSalesDetailParams } from '../../modules/Order/types';
9
+ import { AddProductDecideContext, AddProductRequiresDetailPayload } from './utils/addProductDecision';
10
+ import { type BuildCacheItemFromOrderLineInput } from '../../modules/BookingContext/utils/buildCacheItemFromOrderLine';
11
+ import { type BuildNormalProductCacheItemFromOrderLineInput } from '../../modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine';
12
+ import type { AddProductBookingInput, OrderProduct, OrderProductIdentity, UpdateOrderProductParams } from '../../modules/Order/types';
8
13
  export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
9
14
  protected defaultName: string;
10
15
  protected defaultVersion: string;
@@ -16,10 +21,14 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
16
21
  private platform;
17
22
  private scan;
18
23
  private productCatalog;
24
+ private orderCustomerDiscountRefreshInFlight;
25
+ private orderCustomerDiscountRefreshCustomerId;
19
26
  /**
20
- * 在 BaseSales 默认模块清单(products/order/salesSummary/schedule)基础上追加 customer。
27
+ * 在 BaseSales 默认模块清单(products/order/salesSummary/schedule)基础上追加 customer + bookingContext
28
+ * bookingContext 是 SalesSdk 加车下沉所需的「预约 UI 上下文」(bookingConfig / resourcesOrigin / date)。
21
29
  */
22
30
  protected getRegisteredModuleNames(): readonly string[];
31
+ protected getSubmitOrderSalesChannel(): string;
23
32
  /**
24
33
  * 业务侧子模块工厂:BookingTicket 自带的 createBookingTicketModule 优先匹配;
25
34
  * 未识别的模块名(如 BookingByStep 公共类型)回退到父类工厂。
@@ -186,8 +195,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
186
195
  * 清空下单客户(协议字段 + snapshot)。
187
196
  */
188
197
  clearOrderCustomer(): void;
198
+ /**
199
+ * 重置 tempOrder,并同步清空下单客户运行态。
200
+ *
201
+ * OrderModule.restoreOrder 会重建空单(customer_id 已为 null),但不会:
202
+ * - emit BookingTicket `onOrderCustomerChange`
203
+ * - 重置 CustomerModule.selectedCustomer(老路 getActiveCustomer)
204
+ *
205
+ * 因此在 super.restoreOrder 之后显式清客户,保证 SalesSdk / ticketBooking 订阅方与 tempOrder 一致。
206
+ */
207
+ restoreOrder(): Promise<import("../../modules/Order/types").OrderTempOrder>;
189
208
  /** 内部:基于 OrderModule 当前状态构造一份 OrderCustomerChangePayload。 */
190
209
  private buildOrderCustomerPayload;
210
+ private refreshDiscountConfigAfterOrderCustomerChange;
191
211
  /**
192
212
  * 获取客户分页信息
193
213
  * @returns 分页信息
@@ -291,6 +311,109 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
291
311
  * @returns 其他参数
292
312
  */
293
313
  getOtherParams(): Promise<Record<string, any>>;
314
+ /** 拉取 board config 并写入 BookingContext。 */
315
+ loadBookingConfig(params?: LoadBookingConfigParams): Promise<BookingContextConfig | null>;
316
+ /** 拉取资源全集并写入 BookingContext。 */
317
+ loadBookingResources(params?: LoadBookingResourcesParams): Promise<BookingContextResource[]>;
318
+ /** 初始化 BookingContext(date + config + resources)。 */
319
+ initBookingContext(params?: InitBookingContextParams): Promise<BookingContextState>;
320
+ /** 当前 store 是否已具备与入参等价的 config / resources(无需再请求接口)。 */
321
+ isBookingContextReady(params?: InitBookingContextParams): boolean;
322
+ /** 写入 booking config(来源:`/core/board/management/config`)。 */
323
+ setBookingConfig(config: BookingContextConfig | null): void;
324
+ /** 读取当前 booking config。 */
325
+ getBookingConfig(): BookingContextConfig | null;
326
+ /** 写入资源全集(来源:`/form/schedule`),同步派生 resourcesOriginMap。 */
327
+ setResources(resources: BookingContextResource[] | null | undefined): void;
328
+ /** 读取资源全集(浅克隆)。 */
329
+ getResourcesOrigin(): BookingContextResource[];
330
+ /** 读取资源全集 map(id → resource)。 */
331
+ getResourcesOriginMap(): BookingContextResourceMap;
332
+ /** 写入当前选择的日期;支持 dayjs / Date / string。 */
333
+ setBookingDate(date: BookingContextDateInput): void;
334
+ /** 读取当前选择的日期(统一 string)。 */
335
+ getBookingDate(): string | null;
336
+ /** 读取 BookingContext 完整 store(调试 / 测试 / 透传给 SDK 使用)。 */
337
+ getBookingContextState(): BookingContextState;
338
+ /** 清空 BookingContext(切租户 / destroy 场景)。 */
339
+ clearBookingContext(): void;
340
+ /**
341
+ * 构造 BookingContext 计算上下文(供 getProductExtend / getResourceByIds 等读 API 复用)。
342
+ */
343
+ private buildBookingCalcContext;
344
+ /**
345
+ * 取商品当前可选资源列表(透传 OS BookingContext utils#getResourceByIds)。
346
+ * `extraResources` 用于把拖入未绑定的资源也展示出来。
347
+ */
348
+ getResourcesForProduct(product: any, options?: {
349
+ extraResources?: Array<{
350
+ form_id: number | string;
351
+ id: number;
352
+ }>;
353
+ }): any[];
354
+ /**
355
+ * 拼装 cacheItem 的 _extend / _data(资源 / 容量 / timeObj),与 info2 `getProductExtend` 等价。
356
+ */
357
+ getProductExtend(cacheItem: any, extra?: Partial<BookingCalcContext>): any;
358
+ /**
359
+ * 取资源不可用原因列表(结构化 enum + params,i18n 文案由 UI 渲染)。
360
+ */
361
+ getResourceErrors(resource: any, cacheItem: any): ResourceError[];
362
+ /**
363
+ * 拼装 addProductDecision 通用上下文(从 store 自取)。
364
+ */
365
+ private buildAddProductCtx;
366
+ /**
367
+ * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
368
+ * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
369
+ */
370
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
371
+ /** 规格弹窗 callback 后的第二段决策。 */
372
+ decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
373
+ /**
374
+ * @deprecated 请用 `decideAddProduct`;`autoClose=true` 仅当 action=add。
375
+ */
376
+ decideAutoClose(item: any, options?: Partial<AddProductDecideContext>): {
377
+ autoClose: boolean;
378
+ cacheItem?: any;
379
+ };
380
+ /** 替代 info2 `getIsEject`:商品是否需要弹窗(0/1)。 */
381
+ getIsEject(item: any, type?: 'select' | 'detail'): 0 | 1;
382
+ /** 仅 session 商品(无 variant/option/package)→ true。 */
383
+ getIsOnlySession(item: any): boolean;
384
+ /**
385
+ * 拼装 requiresDetail payload(给 SDK 直接 return 给 UI 用)。
386
+ */
387
+ buildRequiresDetailPayload(item: any, options?: Partial<AddProductDecideContext>): AddProductRequiresDetailPayload;
388
+ /**
389
+ * 把 detail 弹窗回调结果(e, extension_type, detail)转换为 `(product, booking)` 入参。
390
+ * 内部会先拼 cacheItem,再走 cacheItemToBookingInput 严格协议对齐。
391
+ */
392
+ transformDetailToProductAndBooking(input: {
393
+ item: any;
394
+ cacheItem?: any;
395
+ detailResult?: {
396
+ e: any;
397
+ extension_type?: any;
398
+ detail?: any;
399
+ };
400
+ options?: Partial<AddProductDecideContext>;
401
+ }): {
402
+ product: Partial<OrderProduct> & OrderProductIdentity;
403
+ booking?: AddProductBookingInput;
404
+ cacheItem: any;
405
+ };
406
+ /**
407
+ * 从已加车的 order line + booking 反查资源编辑抽屉所需的 cacheItem。
408
+ * 供 SalesSdk「编辑资源」等场景使用;字段语义与 buildCacheItemFromDetail 产出对齐。
409
+ */
410
+ buildCacheItemFromOrderLine(input: BuildCacheItemFromOrderLineInput): Record<string, any>;
411
+ /**
412
+ * 从已加车的普通商品 order line 反查 SkuDetailModal edit 所需的 cacheItem。
413
+ */
414
+ buildNormalProductCacheItemFromOrderLine(input: BuildNormalProductCacheItemFromOrderLineInput): Record<string, any>;
415
+ /** 文档别名:与 OrderModule.updateOrderProduct 一致。 */
416
+ updateProductInOrder(params: UpdateOrderProductParams): Promise<OrderProduct[]>;
294
417
  /**
295
418
  * 销毁模块:先调用父类(销毁所有 store 内子模块 + emit destroy + super.destroy()),
296
419
  * 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。