@pisell/pisellos 2.3.51 → 2.3.54
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/BookingContext/utils/buildCacheItemFromOrderLine.js +12 -10
- package/dist/modules/Order/index.d.ts +6 -6
- package/dist/modules/Order/index.js +140 -86
- package/dist/modules/Order/types.d.ts +21 -3
- package/dist/modules/Order/types.js +11 -0
- package/dist/modules/ProductList/index.js +1 -1
- package/dist/modules/Rules/index.js +19 -9
- package/dist/modules/SalesSummary/utils.js +7 -1
- package/dist/solution/BaseSales/index.d.ts +15 -5
- package/dist/solution/BaseSales/index.js +173 -135
- package/dist/solution/BaseSales/utils/cartPromotion.js +5 -3
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/types.d.ts +3 -0
- package/dist/solution/BookingTicket/utils/cartView.js +44 -32
- package/dist/solution/Sales/index.d.ts +1 -0
- package/dist/solution/Sales/index.js +16 -2
- package/dist/solution/UnifiedBookingSales/index.d.ts +0 -4
- package/dist/solution/UnifiedBookingSales/index.js +27 -26
- package/lib/model/strategy/adapter/promotion/index.js +0 -51
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -1
- package/lib/modules/Order/index.d.ts +6 -6
- package/lib/modules/Order/index.js +79 -12
- package/lib/modules/Order/types.d.ts +21 -3
- package/lib/modules/ProductList/index.js +9 -1
- package/lib/modules/Rules/index.js +16 -11
- package/lib/modules/SalesSummary/utils.js +5 -1
- package/lib/solution/BaseSales/index.d.ts +15 -5
- package/lib/solution/BaseSales/index.js +44 -11
- package/lib/solution/BaseSales/utils/cartPromotion.js +5 -2
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/types.d.ts +3 -0
- package/lib/solution/BookingTicket/utils/cartView.js +43 -30
- package/lib/solution/Sales/index.d.ts +1 -0
- package/lib/solution/Sales/index.js +15 -3
- package/lib/solution/UnifiedBookingSales/index.d.ts +0 -4
- package/lib/solution/UnifiedBookingSales/index.js +27 -26
- package/package.json +1 -1
|
@@ -243,7 +243,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
243
243
|
const discountType = selectedDiscount.tag || selectedDiscount.type;
|
|
244
244
|
return selectedDiscount.isEditMode === true && selectedDiscount.isSelected === true && ["good_pass", "discount_card", "product_discount_card"].includes(discountType);
|
|
245
245
|
};
|
|
246
|
-
const
|
|
246
|
+
const resolveReapplyBookingDiscountPercent = (originProduct, selectedDiscount) => {
|
|
247
247
|
var _a2;
|
|
248
248
|
if (!shouldReapplyBookingDiscount(originProduct, selectedDiscount))
|
|
249
249
|
return void 0;
|
|
@@ -318,6 +318,9 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
318
318
|
bundleIndex,
|
|
319
319
|
// 虚拟商品属性
|
|
320
320
|
price: Number(bundleItem.price || 0),
|
|
321
|
+
// 新增商品运行态通常带 _bundle_product_id;订单 hydrate 后只有
|
|
322
|
+
// bundle_product_id。Change time 必须兼容两种结构,否则 bundle
|
|
323
|
+
// 子项无法命中折扣卡的 limited_relation_product_data.product_ids。
|
|
321
324
|
id: bundleItem.bundle_product_id ?? bundleItem._bundle_product_id ?? bundleItem.product_id,
|
|
322
325
|
_id: `${product._id}_bundle_${bundleIndex}`,
|
|
323
326
|
parentId: product._id,
|
|
@@ -779,13 +782,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
779
782
|
if (isPersistedProduct && hasExistingWalletDiscount) {
|
|
780
783
|
if (flatItem.type === "main") {
|
|
781
784
|
processedProductsMap.set(product._id, [originProduct]);
|
|
782
|
-
} else {
|
|
783
|
-
processedFlatItemsMap.set(flatItem._id, [
|
|
784
|
-
{
|
|
785
|
-
...flatItem,
|
|
786
|
-
processed: true
|
|
787
|
-
}
|
|
788
|
-
]);
|
|
789
785
|
}
|
|
790
786
|
return;
|
|
791
787
|
}
|
|
@@ -1091,8 +1087,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1091
1087
|
amount = productAllocation.discountAmount;
|
|
1092
1088
|
productDiscountDifference = productAllocation.difference;
|
|
1093
1089
|
mainProductSellingPrice = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
|
|
1094
|
-
} else if (
|
|
1095
|
-
const percent =
|
|
1090
|
+
} else if (resolveReapplyBookingDiscountPercent(originProduct, selectedDiscount2) !== void 0) {
|
|
1091
|
+
const percent = resolveReapplyBookingDiscountPercent(originProduct, selectedDiscount2);
|
|
1096
1092
|
reapplyDiscountPercent = new import_decimal.default(percent).toFixed(2);
|
|
1097
1093
|
mainProductSellingPrice = new import_decimal.default(product.price || 0).mul(new import_decimal.default(100).minus(percent)).div(100).toDecimalPlaces(2).toNumber();
|
|
1098
1094
|
amount = new import_decimal.default(product.price).minus(mainProductSellingPrice).toNumber();
|
|
@@ -1267,10 +1263,19 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1267
1263
|
let targetProductTotal;
|
|
1268
1264
|
let fixedAmountPerItem;
|
|
1269
1265
|
let productDiscountDifference;
|
|
1266
|
+
let reapplyDiscountPercent;
|
|
1270
1267
|
if (isOrderLevel && productAllocation) {
|
|
1271
1268
|
fixedAmountPerItem = productAllocation.discountAmount;
|
|
1272
1269
|
productDiscountDifference = productAllocation.difference;
|
|
1273
1270
|
targetProductTotal = Math.max(new import_decimal.default(productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
|
|
1271
|
+
} else if (resolveReapplyBookingDiscountPercent(originProduct, selectedDiscount2) !== void 0) {
|
|
1272
|
+
const percent = resolveReapplyBookingDiscountPercent(
|
|
1273
|
+
originProduct,
|
|
1274
|
+
selectedDiscount2
|
|
1275
|
+
);
|
|
1276
|
+
reapplyDiscountPercent = new import_decimal.default(percent).toFixed(2);
|
|
1277
|
+
targetProductTotal = new import_decimal.default(productOriginTotal).mul(new import_decimal.default(100).minus(percent)).div(100).toDecimalPlaces(2).toNumber();
|
|
1278
|
+
fixedAmountPerItem = new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
|
|
1274
1279
|
} else {
|
|
1275
1280
|
targetProductTotal = (0, import_utils.getDiscountAmount)(
|
|
1276
1281
|
selectedDiscount2,
|
|
@@ -1292,7 +1297,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1292
1297
|
title: selectedDiscount2.format_title,
|
|
1293
1298
|
original_amount: product.original_price,
|
|
1294
1299
|
product_id: product.id || product.product_id,
|
|
1295
|
-
percent: selectedDiscount2.par_value,
|
|
1300
|
+
percent: reapplyDiscountPercent ?? selectedDiscount2.par_value,
|
|
1296
1301
|
discount_product_id: selectedDiscount2.product_id
|
|
1297
1302
|
},
|
|
1298
1303
|
metadata: {
|
|
@@ -99,7 +99,11 @@ function getUnitOriginalTotal(product) {
|
|
|
99
99
|
function isGeneratedVoucherProduct(product) {
|
|
100
100
|
const record = product;
|
|
101
101
|
const metadata = (record == null ? void 0 : record.metadata) || {};
|
|
102
|
-
|
|
102
|
+
const isGeneratedChild = metadata.parent_order_detail_id !== void 0 || metadata.gift_card_type !== void 0;
|
|
103
|
+
if (isGeneratedChild)
|
|
104
|
+
return true;
|
|
105
|
+
const isPersisted = (record == null ? void 0 : record.order_detail_id) !== void 0 && (record == null ? void 0 : record.order_detail_id) !== null;
|
|
106
|
+
return (record == null ? void 0 : record.extension_type) === "product_voucher" && !isPersisted;
|
|
103
107
|
}
|
|
104
108
|
function buildSurchargeServiceItems(products) {
|
|
105
109
|
return products.map((product) => {
|
|
@@ -2,7 +2,7 @@ import { Module, ModuleOptions, PisellCore } from '../../types';
|
|
|
2
2
|
import { BaseModule } from '../../modules/BaseModule';
|
|
3
3
|
import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
|
|
4
4
|
import { OrderModule } from '../../modules/Order';
|
|
5
|
-
import type { AddProductBookingInput, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions } from '../../modules/Order/types';
|
|
5
|
+
import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions } from '../../modules/Order/types';
|
|
6
6
|
import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
|
|
7
7
|
import type { Discount } from '../../modules/Discount/types';
|
|
8
8
|
import { RequestPlugin, WindowPlugin } from '../../plugins';
|
|
@@ -109,6 +109,16 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
109
109
|
private applyQuotationScheduleResolver;
|
|
110
110
|
private loadQuotationForPriceQuery;
|
|
111
111
|
private getPriceQueryProductId;
|
|
112
|
+
/**
|
|
113
|
+
* Change Time / customer reprice 必须沿用商品列表的渠道口径。
|
|
114
|
+
* SalesSdk Provider 通常将渠道存为 platform,因此不能只读取 otherParams.channel。
|
|
115
|
+
*/
|
|
116
|
+
private getPriceQueryChannel;
|
|
117
|
+
/**
|
|
118
|
+
* /product/query 的智能定价评估只读取 strategy_context;
|
|
119
|
+
* application_code 仅作为接口兼容字段,不能替代 channel / business_code。
|
|
120
|
+
*/
|
|
121
|
+
private getPriceQueryStrategyContext;
|
|
112
122
|
private getPriceQuerySchedule;
|
|
113
123
|
private loadProductsForPriceQuery;
|
|
114
124
|
private loadProductForPriceQuery;
|
|
@@ -180,7 +190,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
180
190
|
/** 获取附加费用(运费/服务费/税费等)。 */
|
|
181
191
|
getSurcharges(): ISalesSurcharge[];
|
|
182
192
|
getTempOrder(): OrderTempOrder | null;
|
|
183
|
-
replaceTempOrder(tempOrder: OrderTempOrder): Promise<OrderTempOrder>;
|
|
193
|
+
replaceTempOrder(tempOrder: OrderTempOrder, options?: ReplaceTempOrderOptions): Promise<OrderTempOrder>;
|
|
184
194
|
getOrderIdentity(): import("../../modules/Order/types").OrderIdentitySnapshot | null;
|
|
185
195
|
getOrderSnapshot(): import("../../modules/Order/types").OrderSnapshot | null;
|
|
186
196
|
getOrderSyncState(): import("../../modules/Order/types").OrderSyncState;
|
|
@@ -421,7 +431,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
421
431
|
getQuotationCustomerScopeInfo(): BaseSalesQuotationCustomerScopeInfo;
|
|
422
432
|
shouldRecalculateProductBookingPricesForContextChange(params: BaseSalesPriceRecalculationContextChange): boolean;
|
|
423
433
|
calculateProductBookingPrices(paramsList: BaseSalesCalculateProductBookingPriceParams[]): Promise<BaseSalesProductBookingPriceResult[]>;
|
|
424
|
-
addProductToOrder(product: Partial<BaseSalesOrderProduct> & BaseSalesOrderProductIdentity, booking?: AddProductBookingInput): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
434
|
+
addProductToOrder(product: Partial<BaseSalesOrderProduct> & BaseSalesOrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
425
435
|
updateOrderProduct(params: UpdateOrderProductParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
426
436
|
updateOrderProducts(paramsList: UpdateOrderProductParams[]): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
427
437
|
updateOrderProductQuantity(params: BaseSalesUpdateOrderProductQuantityParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
@@ -437,8 +447,8 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
437
447
|
* @example
|
|
438
448
|
* await baseSales.removeProductsFromOrder([identityA, identityB]);
|
|
439
449
|
*/
|
|
440
|
-
removeProductsFromOrder(identities: BaseSalesOrderProductIdentity[]): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
441
|
-
removeProductFromOrder(identity: BaseSalesOrderProductIdentity): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
450
|
+
removeProductsFromOrder(identities: BaseSalesOrderProductIdentity[], options?: RemoveProductsFromOrderOptions): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
451
|
+
removeProductFromOrder(identity: BaseSalesOrderProductIdentity, options?: RemoveProductsFromOrderOptions): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
442
452
|
/**
|
|
443
453
|
* 注入促销评估器到底层 OrderModule。
|
|
444
454
|
*
|
|
@@ -702,6 +702,36 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
702
702
|
return null;
|
|
703
703
|
return productId;
|
|
704
704
|
}
|
|
705
|
+
/**
|
|
706
|
+
* Change Time / customer reprice 必须沿用商品列表的渠道口径。
|
|
707
|
+
* SalesSdk Provider 通常将渠道存为 platform,因此不能只读取 otherParams.channel。
|
|
708
|
+
*/
|
|
709
|
+
getPriceQueryChannel(channel) {
|
|
710
|
+
var _a, _b, _c;
|
|
711
|
+
const strategyContext = ((_a = this.otherParams) == null ? void 0 : _a.strategy_context) && typeof this.otherParams.strategy_context === "object" ? this.otherParams.strategy_context : {};
|
|
712
|
+
const value = channel ?? strategyContext.channel ?? ((_b = this.otherParams) == null ? void 0 : _b.channel) ?? ((_c = this.otherParams) == null ? void 0 : _c.platform);
|
|
713
|
+
if (value === void 0 || value === null || String(value).trim() === "") {
|
|
714
|
+
return void 0;
|
|
715
|
+
}
|
|
716
|
+
return String(value).trim();
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* /product/query 的智能定价评估只读取 strategy_context;
|
|
720
|
+
* application_code 仅作为接口兼容字段,不能替代 channel / business_code。
|
|
721
|
+
*/
|
|
722
|
+
getPriceQueryStrategyContext(channel) {
|
|
723
|
+
var _a, _b, _c;
|
|
724
|
+
const inherited = ((_a = this.otherParams) == null ? void 0 : _a.strategy_context) && typeof this.otherParams.strategy_context === "object" ? this.otherParams.strategy_context : {};
|
|
725
|
+
const strategyContext = { ...inherited };
|
|
726
|
+
const resolvedChannel = this.getPriceQueryChannel(channel);
|
|
727
|
+
const businessCode = strategyContext.business_code ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code);
|
|
728
|
+
if (resolvedChannel)
|
|
729
|
+
strategyContext.channel = resolvedChannel;
|
|
730
|
+
if (businessCode !== void 0 && businessCode !== null && String(businessCode).trim() !== "") {
|
|
731
|
+
strategyContext.business_code = String(businessCode).trim();
|
|
732
|
+
}
|
|
733
|
+
return strategyContext;
|
|
734
|
+
}
|
|
705
735
|
getPriceQuerySchedule(params) {
|
|
706
736
|
const booking = params.booking || {};
|
|
707
737
|
if (typeof booking.start_date === "string" && booking.start_date.trim()) {
|
|
@@ -729,13 +759,15 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
729
759
|
};
|
|
730
760
|
}
|
|
731
761
|
async loadProductsForPriceQuery(params) {
|
|
732
|
-
var _a
|
|
762
|
+
var _a;
|
|
733
763
|
const ids = Array.from(new Set(
|
|
734
764
|
params.ids.filter((id) => Number.isFinite(id))
|
|
735
765
|
));
|
|
736
766
|
const productsById = /* @__PURE__ */ new Map();
|
|
737
767
|
if (!ids.length || !this.request)
|
|
738
768
|
return productsById;
|
|
769
|
+
const channel = this.getPriceQueryChannel(params.channel);
|
|
770
|
+
const strategyContext = this.getPriceQueryStrategyContext(channel);
|
|
739
771
|
try {
|
|
740
772
|
const response = await this.request.post("/product/query", {
|
|
741
773
|
ids,
|
|
@@ -747,13 +779,14 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
747
779
|
customer_id: params.customerId,
|
|
748
780
|
schedule_date: params.schedule.schedule_date,
|
|
749
781
|
schedule_datetime: params.schedule.schedule_datetime,
|
|
750
|
-
application_code:
|
|
782
|
+
application_code: channel,
|
|
783
|
+
...Object.keys(strategyContext).length ? { strategy_context: strategyContext } : {}
|
|
751
784
|
}, {
|
|
752
785
|
osServer: true,
|
|
753
786
|
customToast: () => {
|
|
754
787
|
}
|
|
755
788
|
});
|
|
756
|
-
const list = ((
|
|
789
|
+
const list = ((_a = response == null ? void 0 : response.data) == null ? void 0 : _a.list) || (response == null ? void 0 : response.list) || [];
|
|
757
790
|
if (!Array.isArray(list))
|
|
758
791
|
return productsById;
|
|
759
792
|
list.forEach((item) => {
|
|
@@ -1190,10 +1223,10 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1190
1223
|
const result = ((_a = this.store.order) == null ? void 0 : _a.getTempOrder()) || null;
|
|
1191
1224
|
return result;
|
|
1192
1225
|
}
|
|
1193
|
-
async replaceTempOrder(tempOrder) {
|
|
1226
|
+
async replaceTempOrder(tempOrder, options) {
|
|
1194
1227
|
if (!this.store.order)
|
|
1195
1228
|
throw new Error("order 模块未初始化");
|
|
1196
|
-
const nextTempOrder = await this.store.order.replaceTempOrder(tempOrder);
|
|
1229
|
+
const nextTempOrder = await this.store.order.replaceTempOrder(tempOrder, options);
|
|
1197
1230
|
await this.effectsEmit("onTempOrderReplaced", { tempOrder: nextTempOrder });
|
|
1198
1231
|
return nextTempOrder;
|
|
1199
1232
|
}
|
|
@@ -3187,11 +3220,11 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
3187
3220
|
});
|
|
3188
3221
|
});
|
|
3189
3222
|
}
|
|
3190
|
-
async addProductToOrder(product, booking) {
|
|
3223
|
+
async addProductToOrder(product, booking, options) {
|
|
3191
3224
|
try {
|
|
3192
3225
|
if (!this.store.order)
|
|
3193
3226
|
throw new Error("order 模块未初始化");
|
|
3194
|
-
const products = await this.store.order.addProductToOrder(product, booking);
|
|
3227
|
+
const products = await this.store.order.addProductToOrder(product, booking, options);
|
|
3195
3228
|
return products;
|
|
3196
3229
|
} catch (error) {
|
|
3197
3230
|
throw error;
|
|
@@ -3267,17 +3300,17 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
3267
3300
|
* @example
|
|
3268
3301
|
* await baseSales.removeProductsFromOrder([identityA, identityB]);
|
|
3269
3302
|
*/
|
|
3270
|
-
async removeProductsFromOrder(identities) {
|
|
3303
|
+
async removeProductsFromOrder(identities, options) {
|
|
3271
3304
|
try {
|
|
3272
3305
|
if (!this.store.order)
|
|
3273
3306
|
throw new Error("order 模块未初始化");
|
|
3274
|
-
return await this.store.order.removeProductsFromOrder(identities);
|
|
3307
|
+
return await this.store.order.removeProductsFromOrder(identities, options);
|
|
3275
3308
|
} catch (error) {
|
|
3276
3309
|
throw error;
|
|
3277
3310
|
}
|
|
3278
3311
|
}
|
|
3279
|
-
async removeProductFromOrder(identity) {
|
|
3280
|
-
return this.removeProductsFromOrder([identity]);
|
|
3312
|
+
async removeProductFromOrder(identity, options) {
|
|
3313
|
+
return this.removeProductsFromOrder([identity], options);
|
|
3281
3314
|
}
|
|
3282
3315
|
// ─── 促销/赠品 透传(迁移自 booking usePromotion) ────────────────
|
|
3283
3316
|
/**
|
|
@@ -367,8 +367,11 @@ function getProductLineNoteSignature(product) {
|
|
|
367
367
|
return uid ? `note:${uid}` : `note:${normalizedNote}`;
|
|
368
368
|
}
|
|
369
369
|
function getPromotionLineMergeBoundary(product) {
|
|
370
|
-
var _a;
|
|
371
|
-
if (((_a = product == null ? void 0 : product.
|
|
370
|
+
var _a, _b;
|
|
371
|
+
if (Number(((_a = product == null ? void 0 : product.product_sku) == null ? void 0 : _a.open_sold_weight) || 0) === 1) {
|
|
372
|
+
return `weighing:${getOrderProductUid(product)}`;
|
|
373
|
+
}
|
|
374
|
+
if (((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.is_edit_for_runtime) !== true)
|
|
372
375
|
return "";
|
|
373
376
|
return `edit:${getOrderProductUid(product)}`;
|
|
374
377
|
}
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 |
|
|
329
|
+
weekNum: 0 | 5 | 2 | 1 | 6 | 4 | 3;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -118,12 +118,15 @@ export interface BookingTicketCartBookingView extends ISalesBooking {
|
|
|
118
118
|
canAddTime: boolean;
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
|
+
export type BookingTicketCartLineView = BookingTicketCartBookingView | BookingTicketCartItemView;
|
|
121
122
|
/**
|
|
122
123
|
* BookingTicket 面向 UI 的购物车视图。
|
|
123
124
|
*/
|
|
124
125
|
export interface BookingTicketCartView {
|
|
125
126
|
bookings: BookingTicketCartBookingView[];
|
|
126
127
|
items: BookingTicketCartItemView[];
|
|
128
|
+
/** 以 tempOrder.products 为唯一顺序真源的统一购物车行(旧到新)。 */
|
|
129
|
+
lines: BookingTicketCartLineView[];
|
|
127
130
|
}
|
|
128
131
|
/**
|
|
129
132
|
* BookingTicket 面向 UI 的客户展示视图。
|
|
@@ -86,29 +86,27 @@ function isGiftProductLine(line) {
|
|
|
86
86
|
function buildCartView(lines, bookings, options = {}) {
|
|
87
87
|
const productLines = Array.isArray(lines) ? lines : [];
|
|
88
88
|
const bookingList = Array.isArray(bookings) ? bookings : [];
|
|
89
|
+
const childBookings = bookingList.filter((booking) => booking.parent_id !== 0);
|
|
90
|
+
const bookingsByProductUid = indexBookingsByProductUid(childBookings);
|
|
89
91
|
const linesByUid = indexProductsByUid(productLines);
|
|
90
92
|
const addTimeLinesByBookingUid = indexAddTimeProductsByBookingUid(productLines);
|
|
91
|
-
const claimedUids = /* @__PURE__ */ new Set();
|
|
92
93
|
const claimedAddTimeLines = /* @__PURE__ */ new Set();
|
|
93
|
-
|
|
94
|
-
const
|
|
94
|
+
childBookings.forEach((booking) => {
|
|
95
|
+
const bookingUid = getBookingUid(booking);
|
|
96
|
+
if (!bookingUid)
|
|
97
|
+
return;
|
|
98
|
+
(addTimeLinesByBookingUid[bookingUid] || []).forEach((line) => {
|
|
99
|
+
claimedAddTimeLines.add(line);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
const claimedBookings = /* @__PURE__ */ new Set();
|
|
103
|
+
const cartBookings = [];
|
|
104
|
+
const items = [];
|
|
105
|
+
const orderedLines = [];
|
|
106
|
+
const buildBookingView = (booking, product) => {
|
|
95
107
|
const bookingUid = getBookingUid(booking);
|
|
96
|
-
let product = null;
|
|
97
|
-
if (uid !== void 0 && uid !== null && uid !== "") {
|
|
98
|
-
const key = String(uid);
|
|
99
|
-
if (!claimedUids.has(key)) {
|
|
100
|
-
const line = linesByUid[key];
|
|
101
|
-
if (isGiftProductLine(line))
|
|
102
|
-
return acc;
|
|
103
|
-
if (line) {
|
|
104
|
-
claimedUids.add(key);
|
|
105
|
-
product = line;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
108
|
const addTimeProduct = bookingUid ? addTimeLinesByBookingUid[bookingUid] || [] : [];
|
|
110
|
-
|
|
111
|
-
acc.push({
|
|
109
|
+
return {
|
|
112
110
|
...booking,
|
|
113
111
|
_extend: {
|
|
114
112
|
product,
|
|
@@ -122,21 +120,36 @@ function buildCartView(lines, bookings, options = {}) {
|
|
|
122
120
|
shopOpeningHours: options.shopOpeningHours
|
|
123
121
|
})
|
|
124
122
|
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const items = productLines.filter((line) => {
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
productLines.forEach((line) => {
|
|
129
126
|
var _a;
|
|
130
|
-
if (isGiftProductLine(line))
|
|
131
|
-
return
|
|
132
|
-
if (claimedAddTimeLines.has(line))
|
|
133
|
-
return false;
|
|
127
|
+
if (isGiftProductLine(line) || claimedAddTimeLines.has(line))
|
|
128
|
+
return;
|
|
134
129
|
const uid = (_a = line.metadata) == null ? void 0 : _a.unique_identification_number;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
130
|
+
const matchedBooking = uid === void 0 || uid === null || uid === "" ? void 0 : (bookingsByProductUid[String(uid)] || []).find(
|
|
131
|
+
(booking) => !claimedBookings.has(booking)
|
|
132
|
+
);
|
|
133
|
+
if (matchedBooking) {
|
|
134
|
+
claimedBookings.add(matchedBooking);
|
|
135
|
+
const bookingView = buildBookingView(matchedBooking, line);
|
|
136
|
+
cartBookings.push(bookingView);
|
|
137
|
+
orderedLines.push(bookingView);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
items.push(line);
|
|
141
|
+
orderedLines.push(line);
|
|
142
|
+
});
|
|
143
|
+
childBookings.forEach((booking) => {
|
|
144
|
+
if (claimedBookings.has(booking))
|
|
145
|
+
return;
|
|
146
|
+
const uid = booking == null ? void 0 : booking.product_uid;
|
|
147
|
+
const linkedProduct = uid === void 0 || uid === null || uid === "" ? null : linesByUid[String(uid)] || null;
|
|
148
|
+
if (isGiftProductLine(linkedProduct))
|
|
149
|
+
return;
|
|
150
|
+
cartBookings.push(buildBookingView(booking, null));
|
|
138
151
|
});
|
|
139
|
-
return { bookings: cartBookings, items };
|
|
152
|
+
return { bookings: cartBookings, items, lines: orderedLines };
|
|
140
153
|
}
|
|
141
154
|
function isWalkInCustomer(customer) {
|
|
142
155
|
if (!customer)
|
|
@@ -95,6 +95,7 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
95
95
|
* 2) 若无 active,返回已超时且仍占用中的预约(允许并发多条)
|
|
96
96
|
* 3) 若仍无,返回最近一组未来预约(同 start_time 的并发预约全部返回)
|
|
97
97
|
* 4) 最后兜底返回一条(避免资源有历史预约时完全无反馈)
|
|
98
|
+
* - includeAllFuture 时,保留选中预约并返回当天全部后续预约;仅详情接口启用。
|
|
98
99
|
*/
|
|
99
100
|
private pickBookingsForCurrentPoint;
|
|
100
101
|
/**
|
|
@@ -316,8 +316,9 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
316
316
|
* 2) 若无 active,返回已超时且仍占用中的预约(允许并发多条)
|
|
317
317
|
* 3) 若仍无,返回最近一组未来预约(同 start_time 的并发预约全部返回)
|
|
318
318
|
* 4) 最后兜底返回一条(避免资源有历史预约时完全无反馈)
|
|
319
|
+
* - includeAllFuture 时,保留选中预约并返回当天全部后续预约;仅详情接口启用。
|
|
319
320
|
*/
|
|
320
|
-
pickBookingsForCurrentPoint(current, bookings) {
|
|
321
|
+
pickBookingsForCurrentPoint(current, bookings, options = {}) {
|
|
321
322
|
if (bookings.length === 0)
|
|
322
323
|
return [];
|
|
323
324
|
const currentDayStart = current.startOf("day");
|
|
@@ -334,6 +335,13 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
334
335
|
const appendNextStartGroupIfNeeded = (selectedBookings) => {
|
|
335
336
|
if (selectedBookings.length === 0)
|
|
336
337
|
return selectedBookings;
|
|
338
|
+
if (options.includeAllFuture) {
|
|
339
|
+
const allFutureBookings = dayScopedBookings.filter((booking) => {
|
|
340
|
+
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
341
|
+
return startAt.isValid() && startAt.isAfter(current);
|
|
342
|
+
});
|
|
343
|
+
return [...selectedBookings, ...allFutureBookings];
|
|
344
|
+
}
|
|
337
345
|
const shouldAppendNextGroup = selectedBookings.some(
|
|
338
346
|
(booking) => booking.status === "reserved" || booking.status === "occupied"
|
|
339
347
|
);
|
|
@@ -384,6 +392,8 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
384
392
|
return startAt.isValid() && startAt.isAfter(current) && startAt.isSame(current, "day");
|
|
385
393
|
});
|
|
386
394
|
if (upcoming.length > 0) {
|
|
395
|
+
if (options.includeAllFuture)
|
|
396
|
+
return upcoming;
|
|
387
397
|
const firstStartAt = this.toBookingDateTime(upcoming[0].start_date, upcoming[0].start_time).valueOf();
|
|
388
398
|
const upcomingStartGroup = upcoming.filter((booking) => {
|
|
389
399
|
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
@@ -638,7 +648,8 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
638
648
|
const unpaidBookingList = matchedBookingList.filter((booking) => this.isUnpaidBooking(booking));
|
|
639
649
|
const bookings = this.pickBookingsForCurrentPoint(
|
|
640
650
|
current,
|
|
641
|
-
this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList)
|
|
651
|
+
this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList),
|
|
652
|
+
{ includeAllFuture: true }
|
|
642
653
|
);
|
|
643
654
|
const completedBookings = completedBookingList.map((booking) => {
|
|
644
655
|
return {
|
|
@@ -654,7 +665,8 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
654
665
|
});
|
|
655
666
|
const unpaidBookings = this.pickBookingsForCurrentPoint(
|
|
656
667
|
current,
|
|
657
|
-
this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList)
|
|
668
|
+
this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList),
|
|
669
|
+
{ includeAllFuture: true }
|
|
658
670
|
);
|
|
659
671
|
const orderCount = this.countBookingOrders(statsBookingList);
|
|
660
672
|
const bookingCount = statsBookingList.length;
|
|
@@ -102,10 +102,6 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
102
102
|
* Read-only compatibility view for salesSdk skins. It reconnects a booking to its product but
|
|
103
103
|
* must not be used to mutate tempOrder; all writes go through BaseSales / planner APIs.
|
|
104
104
|
*/
|
|
105
|
-
getCart(): {
|
|
106
|
-
items: any[];
|
|
107
|
-
bookings: any[];
|
|
108
|
-
};
|
|
109
105
|
/**
|
|
110
106
|
* Loads the current customer's product coupons and discount cards after planner lines exist,
|
|
111
107
|
* then optionally lets the existing Rules engine select the best valid combination. This is a
|
|
@@ -626,32 +626,33 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
|
|
|
626
626
|
* Read-only compatibility view for salesSdk skins. It reconnects a booking to its product but
|
|
627
627
|
* must not be used to mutate tempOrder; all writes go through BaseSales / planner APIs.
|
|
628
628
|
*/
|
|
629
|
-
getCart() {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}
|
|
629
|
+
// getCart(): BookingTicketCartView {
|
|
630
|
+
// const tempOrder = this.getTempOrder();
|
|
631
|
+
// const salesDetail = this.getSalesOrder();
|
|
632
|
+
// const items = tempOrder?.products || [];
|
|
633
|
+
// const bookings = salesDetail?.bookings || tempOrder?.bookings || [];
|
|
634
|
+
// return {
|
|
635
|
+
// items,
|
|
636
|
+
// bookings: bookings.map((booking: any) => {
|
|
637
|
+
// const productUid = booking?.product_uid;
|
|
638
|
+
// const product = productUid
|
|
639
|
+
// ? items.find((item: any) => {
|
|
640
|
+
// const uid = item?.metadata?.unique_identification_number || item?.unique_identification_number;
|
|
641
|
+
// return String(uid || '') === String(productUid);
|
|
642
|
+
// }) || null
|
|
643
|
+
// : null;
|
|
644
|
+
// return {
|
|
645
|
+
// ...booking,
|
|
646
|
+
// _extend: {
|
|
647
|
+
// ...(booking?._extend || {}),
|
|
648
|
+
// product,
|
|
649
|
+
// addTimeProduct: [],
|
|
650
|
+
// canAddTime: false,
|
|
651
|
+
// },
|
|
652
|
+
// };
|
|
653
|
+
// }),
|
|
654
|
+
// };
|
|
655
|
+
// }
|
|
655
656
|
/**
|
|
656
657
|
* Loads the current customer's product coupons and discount cards after planner lines exist,
|
|
657
658
|
* then optionally lets the existing Rules engine select the best valid combination. This is a
|