@pisell/pisellos 2.3.101 → 2.3.103
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/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
- package/dist/model/strategy/adapter/dataVariant/evaluator.js +287 -101
- package/dist/model/strategy/adapter/dataVariant/type.d.ts +25 -0
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +10 -7
- package/dist/modules/Discount/index.d.ts +2 -0
- package/dist/modules/Discount/index.js +38 -5
- package/dist/modules/Discount/types.d.ts +11 -0
- package/dist/modules/Order/index.d.ts +29 -3
- package/dist/modules/Order/index.js +1105 -703
- package/dist/modules/Order/types.d.ts +14 -6
- package/dist/modules/Order/types.js +1 -1
- package/dist/modules/Order/utils/virtualSettlement.d.ts +63 -0
- package/dist/modules/Order/utils/virtualSettlement.js +284 -0
- package/dist/modules/Order/utils.d.ts +1 -0
- package/dist/modules/Order/utils.js +63 -24
- package/dist/modules/Product/types.d.ts +23 -0
- package/dist/modules/SalesSummary/index.d.ts +1 -0
- package/dist/modules/SalesSummary/index.js +4 -3
- package/dist/modules/SalesSummary/types.d.ts +1 -0
- package/dist/modules/SalesSummary/utils.d.ts +1 -0
- package/dist/modules/SalesSummary/utils.js +21 -1
- package/dist/solution/BaseSales/index.d.ts +10 -1
- package/dist/solution/BaseSales/index.js +1074 -746
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +72 -9
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/BookingTicket/utils/addProductDecision.js +2 -1
- package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +137 -6
- package/lib/model/strategy/adapter/dataVariant/type.d.ts +25 -0
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +4 -0
- package/lib/modules/Discount/index.d.ts +2 -0
- package/lib/modules/Discount/index.js +31 -2
- package/lib/modules/Discount/types.d.ts +11 -0
- package/lib/modules/Order/index.d.ts +29 -3
- package/lib/modules/Order/index.js +326 -51
- package/lib/modules/Order/types.d.ts +14 -6
- package/lib/modules/Order/types.js +1 -1
- package/lib/modules/Order/utils/virtualSettlement.d.ts +63 -0
- package/lib/modules/Order/utils/virtualSettlement.js +262 -0
- package/lib/modules/Order/utils.d.ts +1 -0
- package/lib/modules/Order/utils.js +57 -20
- package/lib/modules/Product/types.d.ts +23 -0
- package/lib/modules/SalesSummary/index.d.ts +1 -0
- package/lib/modules/SalesSummary/index.js +4 -2
- package/lib/modules/SalesSummary/types.d.ts +1 -0
- package/lib/modules/SalesSummary/utils.d.ts +1 -0
- package/lib/modules/SalesSummary/utils.js +17 -1
- package/lib/solution/BaseSales/index.d.ts +10 -1
- package/lib/solution/BaseSales/index.js +228 -20
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +38 -0
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -0
- package/package.json +1 -1
|
@@ -23,12 +23,25 @@ export interface ProductDataVariant {
|
|
|
23
23
|
module_data_id: number;
|
|
24
24
|
/** 关联 data_variant_rule.id */
|
|
25
25
|
data_variant_rule_id: number;
|
|
26
|
+
/** 多货币结算等业务类型 */
|
|
27
|
+
business_type?: 'multi_currency_settlement' | string;
|
|
28
|
+
/** 数据状态;多货币结算仅处理 enable 记录 */
|
|
29
|
+
status?: 'enable' | 'disable' | string;
|
|
26
30
|
/** 命中策略后覆盖到商品上的字段 */
|
|
27
31
|
data: Record<string, any>;
|
|
28
32
|
created_at: string | null;
|
|
29
33
|
updated_at: string | null;
|
|
30
34
|
deleted_at: string | null;
|
|
31
35
|
}
|
|
36
|
+
export interface ProductSettlementOption extends Record<string, any> {
|
|
37
|
+
settlement_type: 'legal_currency' | 'virtual_currency' | string;
|
|
38
|
+
currency_product_id?: number;
|
|
39
|
+
price: string;
|
|
40
|
+
data_variant_id?: number;
|
|
41
|
+
data_variant_rule_id: number | string;
|
|
42
|
+
available: boolean;
|
|
43
|
+
disabled_reason?: string;
|
|
44
|
+
}
|
|
32
45
|
/**
|
|
33
46
|
* 商品基本信息接口
|
|
34
47
|
*/
|
|
@@ -61,6 +74,8 @@ export interface ProductData {
|
|
|
61
74
|
sum_stock: number;
|
|
62
75
|
/** 商品价格 */
|
|
63
76
|
price: string;
|
|
77
|
+
/** 当前上下文解析出的可选结算货币 */
|
|
78
|
+
available_settlement_options?: ProductSettlementOption[];
|
|
64
79
|
/** 商品原价 */
|
|
65
80
|
original_price: string;
|
|
66
81
|
/** 商品成本价 */
|
|
@@ -239,6 +254,14 @@ export interface ProductData {
|
|
|
239
254
|
option_group_count: number;
|
|
240
255
|
/** 智能定价变体列表,/product/query with dataVariants 返回 */
|
|
241
256
|
data_variants?: ProductDataVariant[];
|
|
257
|
+
/**
|
|
258
|
+
* 商品接口规则计算结果;data_variant_ids 按优先级从高到低排列。
|
|
259
|
+
* 空数组表示规则已经计算完成但没有命中 Data Variant。
|
|
260
|
+
*/
|
|
261
|
+
metadata?: {
|
|
262
|
+
data_variant_ids?: Array<number | string>;
|
|
263
|
+
[key: string]: any;
|
|
264
|
+
};
|
|
242
265
|
/** 服务时长 */
|
|
243
266
|
service_times?: any;
|
|
244
267
|
}
|
|
@@ -30,6 +30,7 @@ export declare class SalesSummaryModule extends BaseModule implements Module, Sa
|
|
|
30
30
|
taxRate?: number;
|
|
31
31
|
shopDiscount?: string | number;
|
|
32
32
|
channel?: string;
|
|
33
|
+
virtualSettlementMode?: boolean;
|
|
33
34
|
}): Promise<{
|
|
34
35
|
tax_title: string;
|
|
35
36
|
tax_rate: number | undefined;
|
|
@@ -126,7 +126,8 @@ class SalesSummaryModule extends _BaseModule.BaseModule {
|
|
|
126
126
|
isPriceIncludeTax,
|
|
127
127
|
taxRate,
|
|
128
128
|
shopDiscount,
|
|
129
|
-
channel
|
|
129
|
+
channel,
|
|
130
|
+
virtualSettlementMode = false
|
|
130
131
|
} = params;
|
|
131
132
|
const summaryChannel = channel || this.resolveChannel();
|
|
132
133
|
if (summaryChannel !== this.surchargeListChannel) {
|
|
@@ -151,7 +152,8 @@ class SalesSummaryModule extends _BaseModule.BaseModule {
|
|
|
151
152
|
surchargeList: this.store.surchargeList,
|
|
152
153
|
scheduleById,
|
|
153
154
|
isInScheduleByDate: _Schedule.ScheduleModule.isInScheduleByDate,
|
|
154
|
-
shopDiscount
|
|
155
|
+
shopDiscount,
|
|
156
|
+
virtualSettlementMode
|
|
155
157
|
});
|
|
156
158
|
const summaryWithTaxMeta = {
|
|
157
159
|
...summary,
|
|
@@ -837,11 +837,27 @@ function calculateSalesSummary(params) {
|
|
|
837
837
|
surchargeList,
|
|
838
838
|
scheduleById = {},
|
|
839
839
|
isInScheduleByDate,
|
|
840
|
-
shopDiscount
|
|
840
|
+
shopDiscount,
|
|
841
|
+
virtualSettlementMode = false
|
|
841
842
|
} = params;
|
|
842
843
|
if (!products?.length) return createEmptySalesSummary();
|
|
843
844
|
const summaryProducts = products.filter(product => !isGeneratedVoucherProduct(product));
|
|
844
845
|
if (!summaryProducts.length) return createEmptySalesSummary();
|
|
846
|
+
if (virtualSettlementMode) {
|
|
847
|
+
const productQuantity = summaryProducts.reduce((sum, item) => sum + getSafeNum(item.num), 0);
|
|
848
|
+
const productAmount = summaryProducts.reduce((sum, item) => sum.plus(toDecimal(item.selling_price).times(getSafeNum(item.num))), new _decimal.default(0));
|
|
849
|
+
const amount = toFixed2(productAmount);
|
|
850
|
+
return {
|
|
851
|
+
...createEmptySalesSummary(),
|
|
852
|
+
product_quantity: productQuantity,
|
|
853
|
+
product_original_amount: amount,
|
|
854
|
+
product_amount: amount,
|
|
855
|
+
product_expect_amount: amount,
|
|
856
|
+
expect_amount: amount,
|
|
857
|
+
total_amount: amount,
|
|
858
|
+
is_price_include_tax: isPriceIncludeTax
|
|
859
|
+
};
|
|
860
|
+
}
|
|
845
861
|
const productQuantity = summaryProducts.reduce((sum, item) => sum + getSafeNum(item.num), 0);
|
|
846
862
|
const productOriginalAmount = summaryProducts.reduce((sum, item) => sum.plus(getUnitOriginalTotal(item).times(getSafeNum(item.num))), new _decimal.default(0));
|
|
847
863
|
const productAmount = summaryProducts.reduce((sum, item) => sum.plus(getUnitPaymentTotal(item).times(getSafeNum(item.num))), new _decimal.default(0));
|
|
@@ -4,7 +4,7 @@ import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentS
|
|
|
4
4
|
import { OrderModule } from '../../modules/Order';
|
|
5
5
|
import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions, SalesNote, SalesNotesMutationSnapshot, SetSalesNoteInput, PickupReferenceMode, ShopServiceData, ShopServiceType } from '../../modules/Order/types';
|
|
6
6
|
import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
|
|
7
|
-
import type { Discount } from '../../modules/Discount/types';
|
|
7
|
+
import type { Discount, VirtualCurrencyAsset } from '../../modules/Discount/types';
|
|
8
8
|
import { RequestPlugin, WindowPlugin } from '../../plugins';
|
|
9
9
|
export * from './types';
|
|
10
10
|
import { ProductList } from '../../modules/ProductList';
|
|
@@ -193,6 +193,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
193
193
|
protected setPaymentNumberDevicePrefix(prefix: unknown): void;
|
|
194
194
|
private getPaymentNumberDevicePrefixSync;
|
|
195
195
|
private getPaymentNumberDevicePrefixAsync;
|
|
196
|
+
private isMultiCurrencySettlementEnabled;
|
|
197
|
+
private isActiveVirtualSettlementOrder;
|
|
198
|
+
private isHistoricalVirtualSettlementOrder;
|
|
196
199
|
private syncAppDataToTempOrder;
|
|
197
200
|
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
198
201
|
destroy(): Promise<void>;
|
|
@@ -253,6 +256,8 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
253
256
|
* 同步清空内存中的 salesDetail 商品/预约视图,避免编辑态仍读到旧 bookings。
|
|
254
257
|
*/
|
|
255
258
|
clearOrderCartLines(): Promise<OrderTempOrder>;
|
|
259
|
+
/** 切换法币 / WalletPass 单位时清空商品、折扣与支付状态,保留客户。 */
|
|
260
|
+
clearOrderForSettlementSwitch(): Promise<OrderTempOrder>;
|
|
256
261
|
getOrderProducts(): import("../../modules/Order/types").OrderProduct[];
|
|
257
262
|
getSummary(): Promise<OrderSummary>;
|
|
258
263
|
private getHistoricalProductDiscountList;
|
|
@@ -263,12 +268,15 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
263
268
|
loadDiscountConfig(params?: {
|
|
264
269
|
customerId?: number;
|
|
265
270
|
action?: 'create' | 'edit';
|
|
271
|
+
force?: boolean;
|
|
266
272
|
}): Promise<{
|
|
267
273
|
productList: Record<string, any>[];
|
|
268
274
|
discountList: Discount[];
|
|
269
275
|
availableWalletIds: number[];
|
|
276
|
+
virtualCurrencyList: VirtualCurrencyAsset[];
|
|
270
277
|
}>;
|
|
271
278
|
getAvailableWalletIds(): number[];
|
|
279
|
+
getVirtualCurrencyList(): VirtualCurrencyAsset[];
|
|
272
280
|
bestDiscount(cb?: (result: any) => void): Promise<{
|
|
273
281
|
productList: Record<string, any>[];
|
|
274
282
|
discountList: Discount[];
|
|
@@ -300,6 +308,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
300
308
|
confirmPendingVoucherPayments?: boolean;
|
|
301
309
|
enhancePayload?: SubmitPayloadEnhancer;
|
|
302
310
|
}): Promise<T>;
|
|
311
|
+
private buildVirtualSettlementSubmitData;
|
|
303
312
|
/**
|
|
304
313
|
* 提交当前 Sales 订单。
|
|
305
314
|
*
|
|
@@ -25,6 +25,7 @@ var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
|
25
25
|
var _lodashEs = require("lodash-es");
|
|
26
26
|
var _types2 = require("../BookingByStep/types");
|
|
27
27
|
var _utils = require("../../modules/Order/utils");
|
|
28
|
+
var _virtualSettlement = require("../../modules/Order/utils/virtualSettlement");
|
|
28
29
|
var _paymentUtils = require("../../modules/Order/payment-utils");
|
|
29
30
|
var _paymentNumber = require("../../utils/payment-number");
|
|
30
31
|
var _orderCollectionIdentity = require("../../modules/Order/utils/orderCollectionIdentity");
|
|
@@ -1253,11 +1254,24 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1253
1254
|
}
|
|
1254
1255
|
return (0, _paymentNumber.resolvePaymentNumberDevicePrefix)(key => this.getAppData(key));
|
|
1255
1256
|
}
|
|
1257
|
+
isMultiCurrencySettlementEnabled() {
|
|
1258
|
+
return this.otherParams?.enableMultiCurrencySettlement === true;
|
|
1259
|
+
}
|
|
1260
|
+
isActiveVirtualSettlementOrder(tempOrder) {
|
|
1261
|
+
return this.isMultiCurrencySettlementEnabled() && (0, _virtualSettlement.isVirtualSettlementOrder)(tempOrder);
|
|
1262
|
+
}
|
|
1263
|
+
isHistoricalVirtualSettlementOrder(tempOrder) {
|
|
1264
|
+
return tempOrder?.metadata?.currency_settlement_config?.settlement_type === 'virtual_currency';
|
|
1265
|
+
}
|
|
1256
1266
|
syncAppDataToTempOrder(tempOrder) {
|
|
1257
1267
|
const isPriceIncludeTax = this.getAppData('is_price_include_tax');
|
|
1258
1268
|
const taxCountryCode = this.getAppData('tax_country_code');
|
|
1259
1269
|
const currencyCode = this.getAppData('shop_currency_code');
|
|
1260
1270
|
const currencySymbol = this.getAppData('shop_symbol');
|
|
1271
|
+
// 历史虚拟币订单不依赖交易开关;普通 POS 不从商品行残留快照推断订单币种。
|
|
1272
|
+
const isHistoricalVirtualSettlement = this.isHistoricalVirtualSettlementOrder(tempOrder);
|
|
1273
|
+
const isVirtualSettlement = this.isActiveVirtualSettlementOrder(tempOrder) || isHistoricalVirtualSettlement;
|
|
1274
|
+
const shouldManageLegalCurrencySnapshot = this.isMultiCurrencySettlementEnabled() || isHistoricalVirtualSettlement;
|
|
1261
1275
|
let isChanged = false;
|
|
1262
1276
|
if (isPriceIncludeTax !== undefined) {
|
|
1263
1277
|
const nextIsPriceIncludeTax = Number(isPriceIncludeTax);
|
|
@@ -1273,14 +1287,26 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1273
1287
|
isChanged = true;
|
|
1274
1288
|
}
|
|
1275
1289
|
}
|
|
1276
|
-
|
|
1290
|
+
tempOrder.metadata = tempOrder.metadata || {};
|
|
1291
|
+
if (shouldManageLegalCurrencySnapshot) {
|
|
1292
|
+
const legalCurrencySnapshot = {
|
|
1293
|
+
currency_code: String(currencyCode ?? tempOrder.metadata.legal_currency_snapshot?.currency_code ?? tempOrder.currency_code ?? ''),
|
|
1294
|
+
currency_symbol: String(currencySymbol ?? tempOrder.metadata.legal_currency_snapshot?.currency_symbol ?? tempOrder.currency_symbol ?? ''),
|
|
1295
|
+
currency_format: String(tempOrder.metadata.legal_currency_snapshot?.currency_format || (isVirtualSettlement ? 'symbol_first' : tempOrder.currency_format) || 'symbol_first')
|
|
1296
|
+
};
|
|
1297
|
+
if (JSON.stringify(tempOrder.metadata.legal_currency_snapshot || {}) !== JSON.stringify(legalCurrencySnapshot)) {
|
|
1298
|
+
tempOrder.metadata.legal_currency_snapshot = legalCurrencySnapshot;
|
|
1299
|
+
isChanged = true;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
if (!isVirtualSettlement && currencyCode !== undefined) {
|
|
1277
1303
|
const nextCurrencyCode = String(currencyCode || '');
|
|
1278
1304
|
if (tempOrder.currency_code !== nextCurrencyCode) {
|
|
1279
1305
|
tempOrder.currency_code = nextCurrencyCode;
|
|
1280
1306
|
isChanged = true;
|
|
1281
1307
|
}
|
|
1282
1308
|
}
|
|
1283
|
-
if (currencySymbol !== undefined) {
|
|
1309
|
+
if (!isVirtualSettlement && currencySymbol !== undefined) {
|
|
1284
1310
|
const nextCurrencySymbol = String(currencySymbol || '');
|
|
1285
1311
|
if (tempOrder.currency_symbol !== nextCurrencySymbol) {
|
|
1286
1312
|
tempOrder.currency_symbol = nextCurrencySymbol;
|
|
@@ -1654,6 +1680,24 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1654
1680
|
throw error;
|
|
1655
1681
|
}
|
|
1656
1682
|
}
|
|
1683
|
+
|
|
1684
|
+
/** 切换法币 / WalletPass 单位时清空商品、折扣与支付状态,保留客户。 */
|
|
1685
|
+
async clearOrderForSettlementSwitch() {
|
|
1686
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1687
|
+
const tempOrder = await this.store.order.clearOrderForSettlementSwitch();
|
|
1688
|
+
if (this.currentSalesDetail) {
|
|
1689
|
+
this.currentSalesDetail = {
|
|
1690
|
+
...this.currentSalesDetail,
|
|
1691
|
+
products: [],
|
|
1692
|
+
bookings: [],
|
|
1693
|
+
rootBooking: null,
|
|
1694
|
+
bookingsByProductUid: {},
|
|
1695
|
+
discount_list: [],
|
|
1696
|
+
payments: []
|
|
1697
|
+
};
|
|
1698
|
+
}
|
|
1699
|
+
return tempOrder;
|
|
1700
|
+
}
|
|
1657
1701
|
getOrderProducts() {
|
|
1658
1702
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1659
1703
|
const products = this.store.order.getOrderProducts();
|
|
@@ -1779,9 +1823,14 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1779
1823
|
const hasManualDiscountSelection = this.hasManualDiscountSelection || currentDiscountList.some(discount => discount.isManualSelect);
|
|
1780
1824
|
const discountAction = params?.action || (orderId ? 'edit' : 'create');
|
|
1781
1825
|
const discountConfigCacheKey = [customerId, discountAction, Number(orderId) || 0].join(':');
|
|
1782
|
-
|
|
1826
|
+
|
|
1827
|
+
// Walk-In 不请求 prepare config;当前搜索/扫码券必须继续参与本次重算。
|
|
1828
|
+
// current 优先于 original,保留搜索后的最新选择与可用状态。
|
|
1829
|
+
const searchedDiscountList = currentDiscountList.filter(discount => discount.isScan);
|
|
1830
|
+
const searchedDiscountIds = new Set(searchedDiscountList.map(discount => String(discount.id)));
|
|
1831
|
+
let preparedDiscountList = [...searchedDiscountList, ...originalDiscountList.filter(discount => !searchedDiscountIds.has(String(discount.id)))];
|
|
1783
1832
|
if (customerId && customerId !== 1) {
|
|
1784
|
-
if (this.discountConfigCacheKey === discountConfigCacheKey) {
|
|
1833
|
+
if (!params?.force && this.discountConfigCacheKey === discountConfigCacheKey) {
|
|
1785
1834
|
preparedDiscountList = originalDiscountList;
|
|
1786
1835
|
} else {
|
|
1787
1836
|
preparedDiscountList = await this.store.order.loadDiscountConfig({
|
|
@@ -1794,11 +1843,24 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1794
1843
|
await discountModule?.setOriginalDiscountList?.(preparedDiscountList);
|
|
1795
1844
|
}
|
|
1796
1845
|
}
|
|
1846
|
+
if (this.isActiveVirtualSettlementOrder(tempOrder)) {
|
|
1847
|
+
await discountModule?.setOriginalDiscountList?.([]);
|
|
1848
|
+
await discountModule?.setDiscountList?.([]);
|
|
1849
|
+
tempOrder.discount_list = [];
|
|
1850
|
+
tempOrder.shop_discount = '0.00';
|
|
1851
|
+
return {
|
|
1852
|
+
productList: tempOrder.products || [],
|
|
1853
|
+
discountList: [],
|
|
1854
|
+
availableWalletIds: this.getAvailableWalletIds(),
|
|
1855
|
+
virtualCurrencyList: this.store.order.getVirtualCurrencyList()
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1797
1858
|
if (hasManualDiscountSelection && currentDiscountList.length) {
|
|
1798
1859
|
return {
|
|
1799
1860
|
productList: tempOrder.products || [],
|
|
1800
1861
|
discountList: currentDiscountList,
|
|
1801
|
-
availableWalletIds: this.getAvailableWalletIds()
|
|
1862
|
+
availableWalletIds: this.getAvailableWalletIds(),
|
|
1863
|
+
virtualCurrencyList: this.store.order.getVirtualCurrencyList()
|
|
1802
1864
|
};
|
|
1803
1865
|
}
|
|
1804
1866
|
let nextDiscountList = this.mergeHistoricalDiscountList(preparedDiscountList || discountModule?.getDiscountList?.() || [], tempOrder.products || []);
|
|
@@ -1824,7 +1886,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1824
1886
|
return {
|
|
1825
1887
|
productList: tempOrder.products || [],
|
|
1826
1888
|
discountList: nextDiscountList,
|
|
1827
|
-
availableWalletIds: this.getAvailableWalletIds()
|
|
1889
|
+
availableWalletIds: this.getAvailableWalletIds(),
|
|
1890
|
+
virtualCurrencyList: this.store.order.getVirtualCurrencyList()
|
|
1828
1891
|
};
|
|
1829
1892
|
}
|
|
1830
1893
|
if (rulesModule) {
|
|
@@ -1880,16 +1943,29 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1880
1943
|
return {
|
|
1881
1944
|
productList: tempOrder.products || [],
|
|
1882
1945
|
discountList: nextDiscountList,
|
|
1883
|
-
availableWalletIds: this.getAvailableWalletIds()
|
|
1946
|
+
availableWalletIds: this.getAvailableWalletIds(),
|
|
1947
|
+
virtualCurrencyList: this.store.order.getVirtualCurrencyList()
|
|
1884
1948
|
};
|
|
1885
1949
|
}
|
|
1886
1950
|
getAvailableWalletIds() {
|
|
1887
1951
|
if (!this.store.order?.getAvailableWalletIds) return [];
|
|
1888
1952
|
return this.store.order.getAvailableWalletIds();
|
|
1889
1953
|
}
|
|
1954
|
+
getVirtualCurrencyList() {
|
|
1955
|
+
if (!this.store.order?.getVirtualCurrencyList) return [];
|
|
1956
|
+
return this.store.order.getVirtualCurrencyList();
|
|
1957
|
+
}
|
|
1890
1958
|
async bestDiscount(cb) {
|
|
1891
1959
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1892
1960
|
const tempOrder = this.store.order.ensureTempOrder();
|
|
1961
|
+
if (this.isActiveVirtualSettlementOrder(tempOrder)) {
|
|
1962
|
+
const result = {
|
|
1963
|
+
productList: tempOrder.products || [],
|
|
1964
|
+
discountList: []
|
|
1965
|
+
};
|
|
1966
|
+
cb?.(result);
|
|
1967
|
+
return result;
|
|
1968
|
+
}
|
|
1893
1969
|
const orderStore = this.store.order.store || {};
|
|
1894
1970
|
const discountModule = orderStore.discount;
|
|
1895
1971
|
const rulesModule = orderStore.rules;
|
|
@@ -1997,6 +2073,17 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1997
2073
|
async setDiscountSelected(params) {
|
|
1998
2074
|
try {
|
|
1999
2075
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
2076
|
+
const currentOrder = this.store.order.ensureTempOrder();
|
|
2077
|
+
if (this.isActiveVirtualSettlementOrder(currentOrder)) {
|
|
2078
|
+
currentOrder.discount_list = [];
|
|
2079
|
+
currentOrder.shop_discount = '0.00';
|
|
2080
|
+
await this.store.order.store?.discount?.setDiscountList?.([]);
|
|
2081
|
+
await this.store.order.recalculateSummary({
|
|
2082
|
+
createIfMissing: true
|
|
2083
|
+
});
|
|
2084
|
+
this.store.order.persistTempOrder();
|
|
2085
|
+
return;
|
|
2086
|
+
}
|
|
2000
2087
|
const list = this.store.order.getDiscountList();
|
|
2001
2088
|
const updated = list.map(d => d.id === params.discountId && !isBaseSalesHistoricalDiscountEntry(d) ? {
|
|
2002
2089
|
...d,
|
|
@@ -2135,6 +2222,101 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2135
2222
|
// Deprecated compatibility alias. New BaseSales callers should use submitSalesOrder.
|
|
2136
2223
|
return this.submitSalesOrder(params);
|
|
2137
2224
|
}
|
|
2225
|
+
async buildVirtualSettlementSubmitData() {
|
|
2226
|
+
if (!this.store.order) return null;
|
|
2227
|
+
const tempOrder = this.store.order.getTempOrder();
|
|
2228
|
+
if (!this.isActiveVirtualSettlementOrder(tempOrder)) return null;
|
|
2229
|
+
const snapshot = (0, _virtualSettlement.getTempOrderSettlementSnapshot)(tempOrder);
|
|
2230
|
+
const currencyProductId = Number(tempOrder?.metadata?.currency_settlement_config?.settlement_ids?.[0] ?? snapshot?.currency_product_id);
|
|
2231
|
+
if (!snapshot || !Number.isFinite(currencyProductId) || currencyProductId <= 0) {
|
|
2232
|
+
throw new Error('Virtual currency settlement configuration is invalid.');
|
|
2233
|
+
}
|
|
2234
|
+
const summary = await this.store.order.recalculateSummary({
|
|
2235
|
+
createIfMissing: true
|
|
2236
|
+
});
|
|
2237
|
+
const amount = new _decimal.default(summary?.total_amount || 0).toDecimalPlaces(2);
|
|
2238
|
+
const customerId = Number(tempOrder?.customer_id || 0);
|
|
2239
|
+
if (amount.gt(0) && customerId > 0 && customerId !== 1) {
|
|
2240
|
+
await this.store.order.loadDiscountConfig({
|
|
2241
|
+
customerId,
|
|
2242
|
+
action: tempOrder?.order_id ? 'edit' : 'create',
|
|
2243
|
+
orderId: Number(tempOrder?.order_id) || undefined,
|
|
2244
|
+
apply: false
|
|
2245
|
+
});
|
|
2246
|
+
}
|
|
2247
|
+
const asset = this.store.order.getVirtualCurrencyList().find(item => Number(item?.product_id) === currencyProductId);
|
|
2248
|
+
const currencyCode = String(tempOrder?.currency_code || '');
|
|
2249
|
+
const currencySymbol = String(tempOrder?.currency_symbol || '');
|
|
2250
|
+
const currencyFormat = String(tempOrder?.currency_format || 'symbol_first');
|
|
2251
|
+
if (amount.lte(0)) {
|
|
2252
|
+
return {
|
|
2253
|
+
payments: [],
|
|
2254
|
+
snapshot,
|
|
2255
|
+
currencyProductId,
|
|
2256
|
+
currencyCode,
|
|
2257
|
+
currencySymbol,
|
|
2258
|
+
currencyFormat
|
|
2259
|
+
};
|
|
2260
|
+
}
|
|
2261
|
+
if (!asset) {
|
|
2262
|
+
throw new Error('No matching virtual currency card is available.');
|
|
2263
|
+
}
|
|
2264
|
+
const balance = new _decimal.default(asset.balance || 0);
|
|
2265
|
+
if (balance.lt(amount)) {
|
|
2266
|
+
throw new Error('Insufficient virtual currency balance.');
|
|
2267
|
+
}
|
|
2268
|
+
const amountText = amount.toFixed(2);
|
|
2269
|
+
const paymentNumber = `LOCAL_${(0, _utils.createUuidV4)()}`;
|
|
2270
|
+
let payment;
|
|
2271
|
+
if (this.store.order.isOnlineStorePlatform()) {
|
|
2272
|
+
payment = {
|
|
2273
|
+
payment_number: paymentNumber,
|
|
2274
|
+
amount: amount.toNumber(),
|
|
2275
|
+
metadata: {
|
|
2276
|
+
unique_payment_number: (0, _utils.createUuidV4)()
|
|
2277
|
+
},
|
|
2278
|
+
tag: asset.tag,
|
|
2279
|
+
voucher_id: asset.id,
|
|
2280
|
+
wallet_pass_usage_unit: {
|
|
2281
|
+
price: 1,
|
|
2282
|
+
points: 1
|
|
2283
|
+
},
|
|
2284
|
+
wallet_pass_use_value: amountText
|
|
2285
|
+
};
|
|
2286
|
+
} else {
|
|
2287
|
+
const paymentMethods = await this.getPaymentMethodsAsync();
|
|
2288
|
+
const paymentMethod = paymentMethods.find(method => String(method.code || '').toUpperCase() === 'PRODUCTVOUCHER');
|
|
2289
|
+
if (!paymentMethod) {
|
|
2290
|
+
throw new Error('PRODUCTVOUCHER payment method is unavailable.');
|
|
2291
|
+
}
|
|
2292
|
+
payment = {
|
|
2293
|
+
payment_number: paymentNumber,
|
|
2294
|
+
amount: amountText,
|
|
2295
|
+
origin_amount: amountText,
|
|
2296
|
+
code: paymentMethod.code,
|
|
2297
|
+
custom_payment_id: paymentMethod.id,
|
|
2298
|
+
custom_payment_type: paymentMethod.custom_payment_type ?? paymentMethod.type,
|
|
2299
|
+
name: paymentMethod.name,
|
|
2300
|
+
type: 'normal',
|
|
2301
|
+
voucher_id: asset.id,
|
|
2302
|
+
order_payment_type: 'normal',
|
|
2303
|
+
wallet_pass_usage_unit: {
|
|
2304
|
+
price: 1,
|
|
2305
|
+
points: 1
|
|
2306
|
+
},
|
|
2307
|
+
wallet_pass_use_value: amountText,
|
|
2308
|
+
metadata: {}
|
|
2309
|
+
};
|
|
2310
|
+
}
|
|
2311
|
+
return {
|
|
2312
|
+
payments: [payment],
|
|
2313
|
+
snapshot,
|
|
2314
|
+
currencyProductId,
|
|
2315
|
+
currencyCode,
|
|
2316
|
+
currencySymbol,
|
|
2317
|
+
currencyFormat
|
|
2318
|
+
};
|
|
2319
|
+
}
|
|
2138
2320
|
|
|
2139
2321
|
/**
|
|
2140
2322
|
* 提交当前 Sales 订单。
|
|
@@ -2146,6 +2328,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2146
2328
|
if (!this.store.order) {
|
|
2147
2329
|
throw new Error('BaseSales 解决方案需要 order 模块支持');
|
|
2148
2330
|
}
|
|
2331
|
+
const virtualSettlement = await this.buildVirtualSettlementSubmitData();
|
|
2149
2332
|
// this.store.order.persistTempOrder();
|
|
2150
2333
|
const inferredPaymentStatus = this.getSubmitPaymentStatus(params?.paymentStatus);
|
|
2151
2334
|
const smallTicketDataFlag = params?.smallTicketDataFlag ?? this.getDefaultCheckoutSmallTicketDataFlag();
|
|
@@ -2157,7 +2340,9 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2157
2340
|
channel: this.getSubmitOrderSalesChannel(),
|
|
2158
2341
|
type: this.otherParams?.type,
|
|
2159
2342
|
request_unique_idempotency_token: this.store.order.generateIdempotencyToken(),
|
|
2160
|
-
...(
|
|
2343
|
+
...(virtualSettlement ? {
|
|
2344
|
+
payments: virtualSettlement.payments
|
|
2345
|
+
} : params?.payments !== undefined ? {
|
|
2161
2346
|
payments: params.payments
|
|
2162
2347
|
} : {}),
|
|
2163
2348
|
...(inferredPaymentStatus !== undefined ? {
|
|
@@ -2166,10 +2351,32 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2166
2351
|
...(smallTicketDataFlag !== undefined ? {
|
|
2167
2352
|
smallTicketDataFlag
|
|
2168
2353
|
} : {}),
|
|
2169
|
-
...(
|
|
2354
|
+
...(virtualSettlement ? {
|
|
2355
|
+
confirmPendingVoucherPayments: false
|
|
2356
|
+
} : params?.confirmPendingVoucherPayments !== undefined ? {
|
|
2170
2357
|
confirmPendingVoucherPayments: params.confirmPendingVoucherPayments
|
|
2171
2358
|
} : {}),
|
|
2172
|
-
...(
|
|
2359
|
+
...(virtualSettlement ? {
|
|
2360
|
+
enhancePayload: (payload, ctx) => {
|
|
2361
|
+
const callerPayload = enhancePayload ? enhancePayload(payload, ctx) : payload;
|
|
2362
|
+
const currencySettlementConfig = callerPayload.metadata?.currency_settlement_config || {};
|
|
2363
|
+
return {
|
|
2364
|
+
...callerPayload,
|
|
2365
|
+
metadata: {
|
|
2366
|
+
...(callerPayload.metadata || {}),
|
|
2367
|
+
currency_settlement_config: {
|
|
2368
|
+
...currencySettlementConfig,
|
|
2369
|
+
settlement_type: 'virtual_currency',
|
|
2370
|
+
settlement_ids: [virtualSettlement.currencyProductId],
|
|
2371
|
+
currency_display_snapshot: (0, _lodashEs.cloneDeep)(currencySettlementConfig.currency_display_snapshot ?? (0, _virtualSettlement.buildCurrencyDisplaySnapshot)(virtualSettlement.snapshot))
|
|
2372
|
+
}
|
|
2373
|
+
},
|
|
2374
|
+
currency_code: virtualSettlement.currencyCode,
|
|
2375
|
+
currency_symbol: virtualSettlement.currencySymbol,
|
|
2376
|
+
currency_format: virtualSettlement.currencyFormat
|
|
2377
|
+
};
|
|
2378
|
+
}
|
|
2379
|
+
} : enhancePayload !== undefined ? {
|
|
2173
2380
|
enhancePayload
|
|
2174
2381
|
} : {})
|
|
2175
2382
|
};
|
|
@@ -2581,7 +2788,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2581
2788
|
if (this.store.payment) {
|
|
2582
2789
|
const committed = this.getCommittedWalletAssets();
|
|
2583
2790
|
const state = this.store.payment.wallet.setCommittedWalletAssets(committed.ids, committed.assets);
|
|
2584
|
-
void this.publishWalletAssetsState(state);
|
|
2791
|
+
void this.publishWalletAssetsState(state, 'local');
|
|
2585
2792
|
}
|
|
2586
2793
|
return payments;
|
|
2587
2794
|
}
|
|
@@ -2727,9 +2934,10 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2727
2934
|
})
|
|
2728
2935
|
};
|
|
2729
2936
|
}
|
|
2730
|
-
async publishWalletAssetsState(state) {
|
|
2937
|
+
async publishWalletAssetsState(state, changeSource = 'derived') {
|
|
2731
2938
|
await this.effectsEmit(_types.BaseSalesHookNames.onWalletAssetsStateChanged, {
|
|
2732
|
-
state
|
|
2939
|
+
state,
|
|
2940
|
+
changeSource
|
|
2733
2941
|
});
|
|
2734
2942
|
return state;
|
|
2735
2943
|
}
|
|
@@ -2862,7 +3070,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2862
3070
|
source: params.source
|
|
2863
3071
|
});
|
|
2864
3072
|
await this.syncSelectedWalletAssets(state);
|
|
2865
|
-
return this.publishWalletAssetsState(state);
|
|
3073
|
+
return this.publishWalletAssetsState(state, 'local');
|
|
2866
3074
|
}
|
|
2867
3075
|
|
|
2868
3076
|
/** 更新已选钱包资产的手动使用金额,并同步 pending payment。 */
|
|
@@ -2870,7 +3078,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2870
3078
|
if (!this.store.payment) throw new Error('payment 模块未初始化');
|
|
2871
3079
|
const state = this.store.payment.wallet.updateWalletAssetAmount(params.assetId, params.amount);
|
|
2872
3080
|
await this.syncSelectedWalletAssets(state);
|
|
2873
|
-
return this.publishWalletAssetsState(state);
|
|
3081
|
+
return this.publishWalletAssetsState(state, 'local');
|
|
2874
3082
|
}
|
|
2875
3083
|
|
|
2876
3084
|
/** 扫码精确查券;仅可用资产会被自动选中。 */
|
|
@@ -2885,7 +3093,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2885
3093
|
const result = await wallet.scanWalletAssetAsync(code);
|
|
2886
3094
|
if (result.type === 'normalCode') {
|
|
2887
3095
|
await this.syncSelectedWalletAssets(result.state);
|
|
2888
|
-
await this.publishWalletAssetsState(result.state);
|
|
3096
|
+
await this.publishWalletAssetsState(result.state, 'local');
|
|
2889
3097
|
}
|
|
2890
3098
|
return result;
|
|
2891
3099
|
}
|
|
@@ -2895,7 +3103,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2895
3103
|
if (!this.store.payment) throw new Error('payment 模块未初始化');
|
|
2896
3104
|
const state = this.store.payment.wallet.clearWalletAssetSelection();
|
|
2897
3105
|
await this.syncSelectedWalletAssets(state);
|
|
2898
|
-
return this.publishWalletAssetsState(state);
|
|
3106
|
+
return this.publishWalletAssetsState(state, 'local');
|
|
2899
3107
|
}
|
|
2900
3108
|
|
|
2901
3109
|
/**
|
|
@@ -3025,7 +3233,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3025
3233
|
try {
|
|
3026
3234
|
const committed = this.getCommittedWalletAssets();
|
|
3027
3235
|
const walletState = this.store.payment.wallet.setCommittedWalletAssets(committed.ids, committed.assets);
|
|
3028
|
-
await this.publishWalletAssetsState(walletState);
|
|
3236
|
+
await this.publishWalletAssetsState(walletState, 'local');
|
|
3029
3237
|
} catch (error) {
|
|
3030
3238
|
this.logWarning('confirmWalletPayment: Wallet committed 状态同步失败', {
|
|
3031
3239
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -3109,7 +3317,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3109
3317
|
if (this.store.payment) {
|
|
3110
3318
|
const committed = this.getCommittedWalletAssets();
|
|
3111
3319
|
const walletState = this.store.payment.wallet.setCommittedWalletAssets(committed.ids, committed.assets);
|
|
3112
|
-
await this.publishWalletAssetsState(walletState);
|
|
3320
|
+
await this.publishWalletAssetsState(walletState, 'local');
|
|
3113
3321
|
}
|
|
3114
3322
|
return {
|
|
3115
3323
|
payment: payment || {},
|
|
@@ -3215,7 +3423,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3215
3423
|
if (this.store.payment) {
|
|
3216
3424
|
const committed = this.getCommittedWalletAssets();
|
|
3217
3425
|
const walletState = this.store.payment.wallet.setCommittedWalletAssets(committed.ids, committed.assets);
|
|
3218
|
-
await this.publishWalletAssetsState(walletState);
|
|
3426
|
+
await this.publishWalletAssetsState(walletState, 'local');
|
|
3219
3427
|
}
|
|
3220
3428
|
return {
|
|
3221
3429
|
payment: payment || {},
|
|
@@ -37,6 +37,34 @@ function isBlankValue(value) {
|
|
|
37
37
|
function firstNonBlank(...values) {
|
|
38
38
|
return values.find(value => !isBlankValue(value));
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 取第一份接口权威 Data Variant 命中结果并复制数组。
|
|
43
|
+
* 空数组表示规则已计算但无命中,必须与字段缺失区分。
|
|
44
|
+
*/
|
|
45
|
+
function cloneFirstDataVariantIds(...values) {
|
|
46
|
+
const ids = values.find(value => Array.isArray(value));
|
|
47
|
+
return Array.isArray(ids) ? [...ids] : undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 在接口权威命中结果后追加本地应用及最终选中的 Data Variant ID。
|
|
52
|
+
* 以字符串身份去重,同时将新增 ID 归一为正整数。
|
|
53
|
+
*/
|
|
54
|
+
function appendDataVariantIds(base, ...values) {
|
|
55
|
+
const result = Array.isArray(base) ? [...base] : [];
|
|
56
|
+
const seen = new Set(result.map(id => String(id)));
|
|
57
|
+
for (const value of values) {
|
|
58
|
+
const candidates = Array.isArray(value) ? value : [value];
|
|
59
|
+
for (const candidate of candidates) {
|
|
60
|
+
const id = Number(candidate);
|
|
61
|
+
if (!Number.isFinite(id) || id <= 0 || seen.has(String(id))) continue;
|
|
62
|
+
result.push(id);
|
|
63
|
+
seen.add(String(id));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return Array.isArray(base) || result.length ? result : undefined;
|
|
67
|
+
}
|
|
40
68
|
function normalizeOptionItems(optionItems) {
|
|
41
69
|
if (!Array.isArray(optionItems)) return [];
|
|
42
70
|
return optionItems.map(optionItem => {
|
|
@@ -111,6 +139,10 @@ function transformBaseProductToOrderProduct(params) {
|
|
|
111
139
|
...(sourceProduct || {}),
|
|
112
140
|
...(callbackOrigin || {})
|
|
113
141
|
};
|
|
142
|
+
const authoritativeDataVariantIds = cloneFirstDataVariantIds(payload.metadata?.data_variant_ids, sourceProduct?.metadata?.data_variant_ids, callbackOrigin?.metadata?.data_variant_ids, origin?.metadata?.data_variant_ids);
|
|
143
|
+
const selectedSettlementSnapshot = firstNonBlank(payload.selected_settlement_snapshot, payload.metadata?.selected_settlement_snapshot, payload._extend?.metadata?.selected_settlement_snapshot, sourceProduct?.metadata?.selected_settlement_snapshot, sourceProduct?._extend?.metadata?.selected_settlement_snapshot, callbackOrigin?.metadata?.selected_settlement_snapshot, callbackOrigin?._extend?.metadata?.selected_settlement_snapshot);
|
|
144
|
+
const locallyAppliedVariantIds = authoritativeDataVariantIds === undefined ? cloneFirstDataVariantIds(payload._dataVariant?.appliedVariantIds, sourceProduct?._dataVariant?.appliedVariantIds, callbackOrigin?._dataVariant?.appliedVariantIds, origin?._dataVariant?.appliedVariantIds) : undefined;
|
|
145
|
+
const dataVariantIds = appendDataVariantIds(authoritativeDataVariantIds, locallyAppliedVariantIds, selectedSettlementSnapshot?.data_variant_id);
|
|
114
146
|
const matchedVariant = findVariantById(callbackOrigin, productVariantId) ?? findVariantById(sourceProduct, productVariantId) ?? findVariantById(origin, productVariantId);
|
|
115
147
|
const productionCode = normalizeProductionCode(Object.prototype.hasOwnProperty.call(payload, 'production_code') ? payload.production_code : productVariantId > 0 ? matchedVariant?.production_code : origin?.production_code ?? sourceProduct?.production_code);
|
|
116
148
|
const hasPriceOverride = payload.price_override !== undefined && payload.price_override !== null && payload.price_override !== '';
|
|
@@ -179,6 +211,12 @@ function transformBaseProductToOrderProduct(params) {
|
|
|
179
211
|
main_product_original_price: mainProductOriginalPrice,
|
|
180
212
|
price_schema_version: 2,
|
|
181
213
|
holder_config: sourceProduct?.holder_config,
|
|
214
|
+
...(dataVariantIds !== undefined ? {
|
|
215
|
+
data_variant_ids: dataVariantIds
|
|
216
|
+
} : {}),
|
|
217
|
+
...(selectedSettlementSnapshot ? {
|
|
218
|
+
selected_settlement_snapshot: selectedSettlementSnapshot
|
|
219
|
+
} : {}),
|
|
182
220
|
...(hasPriceOverride ? {
|
|
183
221
|
price_override: String(payload.price_override),
|
|
184
222
|
is_manual_discount: 1
|