@pisell/pisellos 2.3.164 → 2.3.166
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/promotion/evaluator.js +89 -104
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +28 -4
- package/dist/modules/Holder/utils.d.ts +2 -0
- package/dist/modules/Holder/utils.js +32 -2
- package/dist/modules/OpenData/contactInfo.d.ts +20 -0
- package/dist/modules/OpenData/contactInfo.js +70 -0
- package/dist/modules/OpenData/index.d.ts +1 -0
- package/dist/modules/OpenData/index.js +1 -0
- package/dist/modules/OpenData/types.d.ts +9 -0
- package/dist/modules/Order/holderRelations.d.ts +14 -0
- package/dist/modules/Order/holderRelations.js +154 -0
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Order/index.js +89 -44
- package/dist/modules/Order/types.d.ts +19 -1
- package/dist/modules/Order/types.js +2 -0
- package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
- package/dist/modules/Order/utils/discountProductLineIdentity.js +142 -7
- package/dist/modules/Order/utils/orderCollectionIdentity.js +24 -10
- package/dist/modules/Order/utils.d.ts +1 -1
- package/dist/modules/Order/utils.js +35 -9
- package/dist/modules/Rules/index.js +62 -61
- package/dist/server/index.js +18 -12
- package/dist/server/modules/order/index.d.ts +4 -0
- package/dist/server/modules/order/index.js +255 -190
- package/dist/server/modules/order/types.d.ts +3 -0
- package/dist/server/modules/products/index.js +3 -2
- package/dist/shared/receipt/small-ticket.js +17 -6
- package/dist/shared/sales/loadSalesOrderSnapshot.js +1 -1
- package/dist/solution/BaseSales/index.d.ts +4 -0
- package/dist/solution/BaseSales/index.js +1116 -935
- package/dist/solution/BaseSales/types.d.ts +2 -1
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
- package/dist/solution/BaseSales/utils/parseSalesResponse.js +7 -3
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -4
- package/dist/solution/BookingTicket/index.d.ts +15 -1
- package/dist/solution/BookingTicket/index.js +784 -501
- package/dist/solution/UnifiedBookingSales/index.js +1 -1
- package/lib/model/strategy/adapter/promotion/evaluator.js +9 -14
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +17 -1
- package/lib/modules/Holder/utils.d.ts +2 -0
- package/lib/modules/Holder/utils.js +27 -1
- package/lib/modules/OpenData/contactInfo.d.ts +20 -0
- package/lib/modules/OpenData/contactInfo.js +56 -0
- package/lib/modules/OpenData/index.d.ts +1 -0
- package/lib/modules/OpenData/index.js +12 -0
- package/lib/modules/OpenData/types.d.ts +9 -0
- package/lib/modules/Order/holderRelations.d.ts +14 -0
- package/lib/modules/Order/holderRelations.js +98 -0
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Order/index.js +44 -12
- package/lib/modules/Order/types.d.ts +19 -1
- package/lib/modules/Order/types.js +1 -0
- package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
- package/lib/modules/Order/utils/discountProductLineIdentity.js +51 -2
- package/lib/modules/Order/utils/orderCollectionIdentity.js +5 -0
- package/lib/modules/Order/utils.d.ts +1 -1
- package/lib/modules/Order/utils.js +27 -6
- package/lib/modules/Rules/index.js +2 -1
- package/lib/server/index.js +6 -0
- package/lib/server/modules/order/index.d.ts +4 -0
- package/lib/server/modules/order/index.js +46 -4
- package/lib/server/modules/order/types.d.ts +3 -0
- package/lib/server/modules/products/index.js +2 -1
- package/lib/shared/receipt/small-ticket.js +15 -7
- package/lib/shared/sales/loadSalesOrderSnapshot.js +1 -1
- package/lib/solution/BaseSales/index.d.ts +4 -0
- package/lib/solution/BaseSales/index.js +68 -2
- package/lib/solution/BaseSales/types.d.ts +2 -1
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +16 -8
- package/lib/solution/BookingTicket/index.d.ts +15 -1
- package/lib/solution/BookingTicket/index.js +132 -3
- package/lib/solution/UnifiedBookingSales/index.js +1 -1
- package/package.json +1 -1
|
@@ -2421,7 +2421,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
2421
2421
|
(_this$store$customer = this.store.customer) === null || _this$store$customer === void 0 || (_this$store$customer$ = _this$store$customer.setSelectedCustomer) === null || _this$store$customer$ === void 0 || _this$store$customer$.call(_this$store$customer, authenticatedCustomer);
|
|
2422
2422
|
this.setOrderCustomer(authenticatedCustomer);
|
|
2423
2423
|
_context10.next = 15;
|
|
2424
|
-
return Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh()]);
|
|
2424
|
+
return Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh(), this.waitForOrderCustomerContactInfo()]);
|
|
2425
2425
|
case 15:
|
|
2426
2426
|
return _context10.abrupt("return", true);
|
|
2427
2427
|
case 16:
|
|
@@ -227,10 +227,13 @@ class PromotionEvaluator {
|
|
|
227
227
|
const productResults = this.evaluateProducts(input);
|
|
228
228
|
|
|
229
229
|
// 2. 收集所有适用的促销(去重)
|
|
230
|
+
// strategyId is metadata and is not guaranteed to be unique. Use the actual
|
|
231
|
+
// configuration as the key so one strategy cannot overwrite another strategy's
|
|
232
|
+
// label/action when their IDs happen to be the same.
|
|
230
233
|
const promotionMap = new Map();
|
|
231
234
|
for (const productResult of productResults) {
|
|
232
235
|
for (const promo of productResult.applicablePromotions) {
|
|
233
|
-
const existing = promotionMap.get(promo.
|
|
236
|
+
const existing = promotionMap.get(promo.strategyConfig);
|
|
234
237
|
const product = productResult.product;
|
|
235
238
|
|
|
236
239
|
// 计算促销数量:如果是 bundle 子商品匹配,数量 = 主商品数量 × 子商品数量
|
|
@@ -253,7 +256,7 @@ class PromotionEvaluator {
|
|
|
253
256
|
// 新促销
|
|
254
257
|
const productMatchedBundleIndexMap = new Map();
|
|
255
258
|
productMatchedBundleIndexMap.set(product.id, promo.matchedBundleIndex);
|
|
256
|
-
promotionMap.set(promo.
|
|
259
|
+
promotionMap.set(promo.strategyConfig, {
|
|
257
260
|
...promo,
|
|
258
261
|
applicableProducts: [product],
|
|
259
262
|
totalQuantity: promoQuantity,
|
|
@@ -305,7 +308,7 @@ class PromotionEvaluator {
|
|
|
305
308
|
const cartResult = this.evaluateCart(input);
|
|
306
309
|
|
|
307
310
|
// 2. 按 action priority 排序促销组(从 strategyConfig 获取 priority)
|
|
308
|
-
const sortedGroups = this.sortPromotionGroupsByPriority(cartResult.promotionGroups
|
|
311
|
+
const sortedGroups = this.sortPromotionGroupsByPriority(cartResult.promotionGroups);
|
|
309
312
|
|
|
310
313
|
// 3. 追踪已处理的商品(避免重复处理)
|
|
311
314
|
// key: `${product_id}_${product_variant_id}`
|
|
@@ -544,19 +547,11 @@ class PromotionEvaluator {
|
|
|
544
547
|
* 按优先级排序促销组
|
|
545
548
|
* 优先级从 strategyConfig.actions[0].priority 获取,数值越小优先级越高
|
|
546
549
|
*/
|
|
547
|
-
sortPromotionGroupsByPriority(groups
|
|
548
|
-
// 创建策略ID到优先级的映射
|
|
549
|
-
const priorityMap = new Map();
|
|
550
|
-
for (const promo of promotions) {
|
|
551
|
-
const actions = promo.strategyConfig?.actions || [];
|
|
552
|
-
const priority = actions[0]?.priority ?? 999;
|
|
553
|
-
priorityMap.set(promo.strategyId, priority);
|
|
554
|
-
}
|
|
555
|
-
|
|
550
|
+
sortPromotionGroupsByPriority(groups) {
|
|
556
551
|
// 按优先级排序(数值越小优先级越高)
|
|
557
552
|
return [...groups].sort((a, b) => {
|
|
558
|
-
const priorityA =
|
|
559
|
-
const priorityB =
|
|
553
|
+
const priorityA = a.strategyConfig?.actions?.[0]?.priority ?? 999;
|
|
554
|
+
const priorityB = b.strategyConfig?.actions?.[0]?.priority ?? 999;
|
|
560
555
|
return priorityA - priorityB;
|
|
561
556
|
});
|
|
562
557
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { OrderProduct } from '../../Order/types';
|
|
1
|
+
import type { OrderHolderRelation, OrderProduct } from '../../Order/types';
|
|
2
2
|
export interface BuildNormalProductCacheItemFromOrderLineInput {
|
|
3
3
|
/** tempOrder.products 中的一行(普通商品,无关联 booking) */
|
|
4
4
|
product: OrderProduct;
|
|
5
5
|
/** 商品 catalog / 详情,用于 variant / option / bundle 模板字段 */
|
|
6
6
|
sourceProduct?: Record<string, any> | null;
|
|
7
|
+
/** 整单关系集合,按商品行 UID 回填。 */
|
|
8
|
+
holder_relations?: OrderHolderRelation[];
|
|
7
9
|
}
|
|
8
10
|
export declare function buildNormalProductCacheItemFromOrderLine(input: BuildNormalProductCacheItemFromOrderLineInput): Record<string, any>;
|
|
@@ -4,13 +4,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.buildNormalProductCacheItemFromOrderLine = buildNormalProductCacheItemFromOrderLine;
|
|
7
|
+
var _lodashEs = require("lodash-es");
|
|
8
|
+
var _holderRelations = require("../../Order/holderRelations");
|
|
7
9
|
var _utils = require("../../Order/utils");
|
|
8
10
|
var _entitlementPass = require("../../Discount/entitlementPass");
|
|
11
|
+
var _utils2 = require("../../Holder/utils");
|
|
9
12
|
var _orderLineDisplay = require("./orderLineDisplay");
|
|
10
13
|
/**
|
|
11
14
|
* 从已加车的普通商品 order line 反查 SkuDetailModal edit 所需的 cacheItem。
|
|
12
15
|
*
|
|
13
|
-
* 与 `buildCacheItemFromOrderLine`(预约行 + booking
|
|
16
|
+
* 与 `buildCacheItemFromOrderLine`(预约行 + booking)并列;Holder 从订单关系回填,不生成预约字段。
|
|
14
17
|
*/
|
|
15
18
|
/**
|
|
16
19
|
* 解析 v2 主商品 source 价(不含 option、不含 bundle),供 SkuDetailModal / transform 使用。
|
|
@@ -84,6 +87,15 @@ function buildNormalProductCacheItemFromOrderLine(input) {
|
|
|
84
87
|
const original = Number(product.original_price ?? selling);
|
|
85
88
|
const uid = product.metadata?.unique_identification_number;
|
|
86
89
|
const originExtend = product.metadata?.origin?._extend;
|
|
90
|
+
const holderRelations = (0, _lodashEs.cloneDeep)((0, _holderRelations.getProductHolderRelations)(input, product));
|
|
91
|
+
const formRelations = holderRelations.filter(relation => relation.holder_type === 'form');
|
|
92
|
+
const holderIds = formRelations.map(relation => relation.holder_id);
|
|
93
|
+
const holderNames = formRelations.map(relation => relation.metadata?.name).filter(name => typeof name === 'string' && name.length > 0);
|
|
94
|
+
const holder = formRelations.length > 0 ? {
|
|
95
|
+
...(formRelations[0].metadata || {}),
|
|
96
|
+
form_record: holderIds,
|
|
97
|
+
name: holderNames.join(',')
|
|
98
|
+
} : null;
|
|
87
99
|
const shouldPreserveEntitlementPriceOverride = hasEntitlementPassDiscount(product) && (originExtend?.priceOverride !== undefined || product.metadata?.price_override != null);
|
|
88
100
|
const hasPriceOverride = originExtend?.priceOverride !== undefined || shouldPreserveEntitlementPriceOverride;
|
|
89
101
|
const option = (0, _utils.getProductSkuOptions)(product);
|
|
@@ -115,6 +127,9 @@ function buildNormalProductCacheItemFromOrderLine(input) {
|
|
|
115
127
|
skuValue: JSON.parse(JSON.stringify(skuValue)),
|
|
116
128
|
_skuValue: JSON.parse(JSON.stringify(skuValue)),
|
|
117
129
|
isNormalProduct: true,
|
|
130
|
+
holder_relations: holderRelations,
|
|
131
|
+
holder,
|
|
132
|
+
holder_id: holderIds,
|
|
118
133
|
metadata: {
|
|
119
134
|
product_add_schedule_time: product.metadata?.product_add_schedule_time
|
|
120
135
|
},
|
|
@@ -134,6 +149,7 @@ function buildNormalProductCacheItemFromOrderLine(input) {
|
|
|
134
149
|
}
|
|
135
150
|
return {
|
|
136
151
|
...(sourceProduct || {}),
|
|
152
|
+
holder_config: (0, _utils2.resolveProductHolderConfig)(sourceProduct) ?? (0, _utils2.resolveProductHolderConfig)(product) ?? undefined,
|
|
137
153
|
id: resolvedId,
|
|
138
154
|
product_id: resolvedId,
|
|
139
155
|
_id: uid,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ProductData } from '../Product/types';
|
|
2
2
|
import { IFormItemData, IHolderConfig } from './types';
|
|
3
|
+
/** 保留显式禁用配置;仅在新配置缺失时兼容商品旧 holder 定义。 */
|
|
4
|
+
export declare function resolveProductHolderConfig(product?: ProductData | Record<string, any> | null): Record<string, any> | null;
|
|
3
5
|
export declare function getProductHolderConfig(product?: ProductData | Record<string, any> | null): IHolderConfig | null;
|
|
4
6
|
export declare function getFormIdFromHolderConfig(config: IHolderConfig): number;
|
|
5
7
|
export declare function normalizeFormId(formId: number | string): number;
|
|
@@ -8,9 +8,35 @@ exports.getFormIdFromHolderConfig = getFormIdFromHolderConfig;
|
|
|
8
8
|
exports.getProductHolderConfig = getProductHolderConfig;
|
|
9
9
|
exports.normalizeFormId = normalizeFormId;
|
|
10
10
|
exports.resolveFormMetaFromHolderItem = resolveFormMetaFromHolderItem;
|
|
11
|
+
exports.resolveProductHolderConfig = resolveProductHolderConfig;
|
|
12
|
+
/** 保留显式禁用配置;仅在新配置缺失时兼容商品旧 holder 定义。 */
|
|
13
|
+
function resolveProductHolderConfig(product) {
|
|
14
|
+
if (!product || typeof product !== 'object') return null;
|
|
15
|
+
const source = product;
|
|
16
|
+
const configSources = [source.holder_config, source.metadata?.holder_config, source.origin?.holder_config, source.metadata?.origin?.holder_config, source._origin?.holder_config, source._extend?.holder_config, source._extend?.product?.holder_config, source._extend?.product?.origin?.holder_config, source._extend?.product?.metadata?.holder_config, source._extend?.product?.metadata?.origin?.holder_config, source._extend?.product?._origin?.holder_config, source._extend?.product?._extend?.holder_config];
|
|
17
|
+
const config = configSources.find(value => value !== null && typeof value === 'object');
|
|
18
|
+
if (config) return config;
|
|
19
|
+
|
|
20
|
+
// metadata.holder / _extend.holder 是选择结果,不能作为商品配置读取。
|
|
21
|
+
const legacySources = [source.holder, source.origin?.holder, source.metadata?.origin?.holder, source._origin?.holder, source._extend?.product?.holder, source._extend?.product?.origin?.holder, source._extend?.product?.metadata?.origin?.holder, source._extend?.product?._origin?.holder];
|
|
22
|
+
const legacy = legacySources.find(value => value && typeof value === 'object' && !Array.isArray(value) && typeof value.type === 'string');
|
|
23
|
+
if (!legacy) return null;
|
|
24
|
+
const formId = legacy.custom?.custom_id;
|
|
25
|
+
if (legacy.type === 'custom' && legacy.custom?.type === 'form' && (typeof formId === 'number' || typeof formId === 'string') && Number.isInteger(Number(formId)) && Number(formId) > 0) {
|
|
26
|
+
return {
|
|
27
|
+
status: 'enable',
|
|
28
|
+
required: 0,
|
|
29
|
+
resource_id: formId
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
status: 'disable',
|
|
34
|
+
required: 0
|
|
35
|
+
};
|
|
36
|
+
}
|
|
11
37
|
function getProductHolderConfig(product) {
|
|
12
38
|
if (!product) return null;
|
|
13
|
-
const config = product
|
|
39
|
+
const config = resolveProductHolderConfig(product);
|
|
14
40
|
if (config?.status && config?.status !== 'enable') return null;
|
|
15
41
|
if (!config?.resource_id) return null;
|
|
16
42
|
return config;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OpenDataConfig } from './types';
|
|
2
|
+
export declare const CONTACT_INFO_FIELDS: readonly ["first_name", "last_name", "phone", "email"];
|
|
3
|
+
export type ContactInfoField = typeof CONTACT_INFO_FIELDS[number];
|
|
4
|
+
export interface ContactInfoConfig {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
fields: Record<ContactInfoField, {
|
|
7
|
+
visible: boolean;
|
|
8
|
+
required: boolean;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export declare function resolveContactInfoConfig(data?: OpenDataConfig | null): ContactInfoConfig;
|
|
12
|
+
export declare function getMissingContactInfoFields(config: ContactInfoConfig, value: unknown): ContactInfoField[];
|
|
13
|
+
export declare function isContactRecord(value: unknown): value is Record<string, any>;
|
|
14
|
+
/** Customer relations wrap the contact in value; sales orders store the object itself. */
|
|
15
|
+
export declare function extractCustomerContactInfo(customer: unknown): Record<string, any> | null;
|
|
16
|
+
export declare class ContactInfoRequiredError extends Error {
|
|
17
|
+
readonly fields: ContactInfoField[];
|
|
18
|
+
readonly code = "CONTACT_INFO_REQUIRED";
|
|
19
|
+
constructor(fields: ContactInfoField[]);
|
|
20
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ContactInfoRequiredError = exports.CONTACT_INFO_FIELDS = void 0;
|
|
7
|
+
exports.extractCustomerContactInfo = extractCustomerContactInfo;
|
|
8
|
+
exports.getMissingContactInfoFields = getMissingContactInfoFields;
|
|
9
|
+
exports.isContactRecord = isContactRecord;
|
|
10
|
+
exports.resolveContactInfoConfig = resolveContactInfoConfig;
|
|
11
|
+
const CONTACT_INFO_FIELDS = exports.CONTACT_INFO_FIELDS = ['first_name', 'last_name', 'phone', 'email'];
|
|
12
|
+
function resolveContactInfoConfig(data) {
|
|
13
|
+
const enabled = data?.['sale.enable_contact_info'] === true;
|
|
14
|
+
const fields = CONTACT_INFO_FIELDS.reduce((result, field) => {
|
|
15
|
+
const visible = data?.[`sale.${field}.visible`] !== false;
|
|
16
|
+
result[field] = {
|
|
17
|
+
visible,
|
|
18
|
+
required: enabled && visible && data?.[`sale.${field}.required`] === true
|
|
19
|
+
};
|
|
20
|
+
return result;
|
|
21
|
+
}, {});
|
|
22
|
+
return {
|
|
23
|
+
enabled: enabled && CONTACT_INFO_FIELDS.some(field => fields[field].visible),
|
|
24
|
+
fields
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function getMissingContactInfoFields(config, value) {
|
|
28
|
+
if (!config.enabled) return [];
|
|
29
|
+
const contact = isContactRecord(value) ? value : {};
|
|
30
|
+
return CONTACT_INFO_FIELDS.filter(field => {
|
|
31
|
+
if (!config.fields[field].visible || !config.fields[field].required) return false;
|
|
32
|
+
const fieldValue = field === 'phone' ? isContactRecord(contact.phone) ? contact.phone.phone : undefined : contact[field];
|
|
33
|
+
return typeof fieldValue !== 'string' || !fieldValue.trim();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function isContactRecord(value) {
|
|
37
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Customer relations wrap the contact in value; sales orders store the object itself. */
|
|
41
|
+
function extractCustomerContactInfo(customer) {
|
|
42
|
+
if (!isContactRecord(customer)) return null;
|
|
43
|
+
const contact = customer.contacts_info;
|
|
44
|
+
if (!isContactRecord(contact)) return null;
|
|
45
|
+
const value = Object.prototype.hasOwnProperty.call(contact, 'value') ? contact.value : contact;
|
|
46
|
+
return isContactRecord(value) ? value : null;
|
|
47
|
+
}
|
|
48
|
+
class ContactInfoRequiredError extends Error {
|
|
49
|
+
code = 'CONTACT_INFO_REQUIRED';
|
|
50
|
+
constructor(fields) {
|
|
51
|
+
super(`Contact information is required: ${fields.join(', ')}`);
|
|
52
|
+
this.fields = fields;
|
|
53
|
+
this.name = 'ContactInfoRequiredError';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.ContactInfoRequiredError = ContactInfoRequiredError;
|
|
@@ -3,6 +3,7 @@ import { BaseModule } from '../BaseModule';
|
|
|
3
3
|
import type { ScheduleModule } from '../Schedule';
|
|
4
4
|
import type { OpenDataConfig, OpenDataFetchParams, OpenDataAvailabilityResult, InvoiceLayoutConfig, InvoiceTemplateSettings } from './types';
|
|
5
5
|
export * from './types';
|
|
6
|
+
export * from './contactInfo';
|
|
6
7
|
export { computeAvailability, getDefaultInvoiceLayoutConfig, getDefaultInvoiceTemplateSettings, normalizeInvoiceLayoutConfig, normalizeInvoiceLayoutFromTemplateSettings, normalizeInvoiceTemplateSettings, normalizeRawInvoiceTemplateSettings, resolveInvoiceReceiptLocales, } from './utils';
|
|
7
8
|
export declare class OpenDataModule extends BaseModule implements Module {
|
|
8
9
|
protected defaultName: string;
|
|
@@ -77,6 +77,18 @@ Object.keys(_types).forEach(function (key) {
|
|
|
77
77
|
}
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
|
+
var _contactInfo = require("./contactInfo");
|
|
81
|
+
Object.keys(_contactInfo).forEach(function (key) {
|
|
82
|
+
if (key === "default" || key === "__esModule") return;
|
|
83
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
84
|
+
if (key in exports && exports[key] === _contactInfo[key]) return;
|
|
85
|
+
Object.defineProperty(exports, key, {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
get: function () {
|
|
88
|
+
return _contactInfo[key];
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
80
92
|
function isRecord(value) {
|
|
81
93
|
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
82
94
|
}
|
|
@@ -69,6 +69,15 @@ export interface OpenDataConfig {
|
|
|
69
69
|
'reservation.time_slice'?: number | string;
|
|
70
70
|
'sale.allow_item_notes'?: boolean;
|
|
71
71
|
'sale.allow_order_notes'?: boolean;
|
|
72
|
+
'sale.enable_contact_info'?: boolean;
|
|
73
|
+
'sale.first_name.visible'?: boolean;
|
|
74
|
+
'sale.first_name.required'?: boolean;
|
|
75
|
+
'sale.last_name.visible'?: boolean;
|
|
76
|
+
'sale.last_name.required'?: boolean;
|
|
77
|
+
'sale.phone.visible'?: boolean;
|
|
78
|
+
'sale.phone.required'?: boolean;
|
|
79
|
+
'sale.email.visible'?: boolean;
|
|
80
|
+
'sale.email.required'?: boolean;
|
|
72
81
|
/** False submits an order without starting or confirming payment. */
|
|
73
82
|
'sale.require_payment_on_submit'?: boolean | null;
|
|
74
83
|
'sale.enable_item_rules'?: boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { OrderHolderRelation, OrderTempOrder } from './types';
|
|
2
|
+
/** 在原订单上补齐关系身份,让缓存、提交和重试共用同一个 UUID。 */
|
|
3
|
+
export declare function ensureHolderRelationUuids(order: {
|
|
4
|
+
holder_relations?: OrderHolderRelation[];
|
|
5
|
+
}): void;
|
|
6
|
+
export declare function hasProductBooking(product: Record<string, any>): boolean;
|
|
7
|
+
export declare function getProductHolderRelations(order: {
|
|
8
|
+
holder_relations?: OrderHolderRelation[];
|
|
9
|
+
}, product: Record<string, any>): OrderHolderRelation[];
|
|
10
|
+
export declare function replaceProductHolderRelations(order: OrderTempOrder, product: Record<string, any>, patch: OrderHolderRelation[] | undefined): void;
|
|
11
|
+
/** 只删除明确被用户删除的行,不从稀疏远端快照推断删除。 */
|
|
12
|
+
export declare function removeProductHolderRelations(order: OrderTempOrder, products: Array<Record<string, any>>): void;
|
|
13
|
+
/** 仅兼容尚无新字段的旧测试草稿;显式 [] 永远不恢复旧 product 数据。 */
|
|
14
|
+
export declare function restoreLegacyHolderRelations(order: Record<string, any>): OrderHolderRelation[] | undefined;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ensureHolderRelationUuids = ensureHolderRelationUuids;
|
|
7
|
+
exports.getProductHolderRelations = getProductHolderRelations;
|
|
8
|
+
exports.hasProductBooking = hasProductBooking;
|
|
9
|
+
exports.removeProductHolderRelations = removeProductHolderRelations;
|
|
10
|
+
exports.replaceProductHolderRelations = replaceProductHolderRelations;
|
|
11
|
+
exports.restoreLegacyHolderRelations = restoreLegacyHolderRelations;
|
|
12
|
+
var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
|
|
13
|
+
function getHolderRelationUuid(relation) {
|
|
14
|
+
return typeof relation?.uuid === 'string' && relation.uuid.trim() ? relation.uuid : undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** 在原订单上补齐关系身份,让缓存、提交和重试共用同一个 UUID。 */
|
|
18
|
+
function ensureHolderRelationUuids(order) {
|
|
19
|
+
if (!Array.isArray(order.holder_relations)) return;
|
|
20
|
+
for (const relation of order.holder_relations) {
|
|
21
|
+
if (relation && typeof relation === 'object' && !getHolderRelationUuid(relation)) {
|
|
22
|
+
relation.uuid = (0, _orderCollectionIdentity.createUuidV4)();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function hasProductBooking(product) {
|
|
27
|
+
const bookingIds = [product.booking_id, product.metadata?.booking_id, product.schedule_event_id];
|
|
28
|
+
return Boolean(product.booking_uid || product.metadata?.booking_uid) || bookingIds.some(id => id !== undefined && id !== null && String(id) !== '' && String(id) !== '0');
|
|
29
|
+
}
|
|
30
|
+
function getProductHolderRelations(order, product) {
|
|
31
|
+
const uid = product.metadata?.unique_identification_number ?? product.unique_identification_number;
|
|
32
|
+
if (uid === undefined || uid === null || uid === '') return [];
|
|
33
|
+
return (order.holder_relations || []).filter(relation => relation.relation_model === 'order_detail' && String(relation.relation_uuid) === String(uid));
|
|
34
|
+
}
|
|
35
|
+
function replaceProductHolderRelations(order, product, patch) {
|
|
36
|
+
if (patch === undefined || hasProductBooking(product)) return;
|
|
37
|
+
const uid = product.metadata?.unique_identification_number ?? product.unique_identification_number;
|
|
38
|
+
if (uid === undefined || uid === null || uid === '') return;
|
|
39
|
+
const existing = getProductHolderRelations(order, product);
|
|
40
|
+
const next = new Map();
|
|
41
|
+
for (const relation of patch) {
|
|
42
|
+
const key = `${relation.holder_type}:${relation.holder_id}`;
|
|
43
|
+
const previous = existing.find(item => item.holder_type === relation.holder_type && String(item.holder_id) === String(relation.holder_id));
|
|
44
|
+
next.set(key, {
|
|
45
|
+
...previous,
|
|
46
|
+
...relation,
|
|
47
|
+
uuid: getHolderRelationUuid(previous) || getHolderRelationUuid(relation) || (0, _orderCollectionIdentity.createUuidV4)(),
|
|
48
|
+
relation_model: 'order_detail',
|
|
49
|
+
relation_uuid: String(uid),
|
|
50
|
+
...(previous?.metadata || relation.metadata ? {
|
|
51
|
+
metadata: {
|
|
52
|
+
...previous?.metadata,
|
|
53
|
+
...relation.metadata
|
|
54
|
+
}
|
|
55
|
+
} : {})
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
order.holder_relations = [...(order.holder_relations || []).filter(relation => relation.relation_model !== 'order_detail' || String(relation.relation_uuid) !== String(uid)), ...next.values()];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** 只删除明确被用户删除的行,不从稀疏远端快照推断删除。 */
|
|
62
|
+
function removeProductHolderRelations(order, products) {
|
|
63
|
+
if (!Array.isArray(order.holder_relations)) return;
|
|
64
|
+
const removedUids = new Set(products.map(product => String(product.metadata?.unique_identification_number ?? product.unique_identification_number ?? '')));
|
|
65
|
+
order.holder_relations = order.holder_relations.filter(relation => relation.relation_model !== 'order_detail' || !removedUids.has(String(relation.relation_uuid)));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** 仅兼容尚无新字段的旧测试草稿;显式 [] 永远不恢复旧 product 数据。 */
|
|
69
|
+
function restoreLegacyHolderRelations(order) {
|
|
70
|
+
if (Object.prototype.hasOwnProperty.call(order, 'holder_relations')) {
|
|
71
|
+
return Array.isArray(order.holder_relations) ? order.holder_relations : undefined;
|
|
72
|
+
}
|
|
73
|
+
const relations = [];
|
|
74
|
+
const bookingProductUids = new Set((order.bookings || []).map(booking => String(booking.product_uid ?? booking.metadata?.product_uid ?? '')));
|
|
75
|
+
for (const product of order.products || []) {
|
|
76
|
+
if (hasProductBooking(product)) continue;
|
|
77
|
+
const uid = product.metadata?.unique_identification_number ?? product.unique_identification_number;
|
|
78
|
+
if (uid === undefined || uid === null || uid === '' || bookingProductUids.has(String(uid))) continue;
|
|
79
|
+
const holder = product.metadata?.holder || {};
|
|
80
|
+
const rawIds = product.metadata?.holder_id ?? holder.form_record;
|
|
81
|
+
const ids = (Array.isArray(rawIds) ? rawIds : [rawIds]).filter(id => id !== undefined && id !== null && id !== '' && Number.isInteger(Number(id)) && Number(id) >= 0);
|
|
82
|
+
for (const id of ids) {
|
|
83
|
+
const metadata = {
|
|
84
|
+
...holder,
|
|
85
|
+
form_record: [Number(id)]
|
|
86
|
+
};
|
|
87
|
+
if (ids.length !== 1) delete metadata.name;
|
|
88
|
+
relations.push({
|
|
89
|
+
relation_model: 'order_detail',
|
|
90
|
+
relation_uuid: String(uid),
|
|
91
|
+
holder_type: 'form',
|
|
92
|
+
holder_id: Number(id),
|
|
93
|
+
metadata
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return relations.length ? relations : undefined;
|
|
98
|
+
}
|
|
@@ -673,6 +673,6 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
673
673
|
getOrderInfo(order_id: number): Promise<any>;
|
|
674
674
|
getVouchers(): any[];
|
|
675
675
|
}
|
|
676
|
-
export type { AddProductToOrderOptions, OrderMetaList, PointCardSnapshotItem, VirtualCurrencySnapshotItem, RemoveProductsFromOrderOptions, SalesNote, SalesNoteDraftInput, SalesNoteLocalizedSelection, SalesNoteLocalizedText, SalesNoteRelation, SalesNoteTextInput, SetSalesNoteInput, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
|
|
676
|
+
export type { OrderHolderRelation, AddProductToOrderOptions, OrderMetaList, PointCardSnapshotItem, VirtualCurrencySnapshotItem, RemoveProductsFromOrderOptions, SalesNote, SalesNoteDraftInput, SalesNoteLocalizedSelection, SalesNoteLocalizedText, SalesNoteRelation, SalesNoteTextInput, SetSalesNoteInput, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
|
|
677
677
|
export { isFulfillmentTimingBooking } from './pickupTiming';
|
|
678
678
|
export type { PickupTimingBooking, PickupTimingBookingInput, PickupTimingBookingMetadata, PickupTimingSelectionMode, PickupTimingSource, } from './pickupTiming';
|
|
@@ -16,6 +16,7 @@ var _BaseModule = require("../BaseModule");
|
|
|
16
16
|
var _types = require("./types");
|
|
17
17
|
var _utils = require("./utils");
|
|
18
18
|
var _utils2 = require("../Product/utils");
|
|
19
|
+
var _holderRelations = require("./holderRelations");
|
|
19
20
|
var _weighedProduct = require("./utils/weighedProduct");
|
|
20
21
|
var _pickupTiming = require("./pickupTiming");
|
|
21
22
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
@@ -543,7 +544,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
543
544
|
this.store.rules = rules;
|
|
544
545
|
}
|
|
545
546
|
createDefaultRulesHooks() {
|
|
546
|
-
return (0, _utils.createDefaultOrderRulesHooks)(() => this.store.tempOrder?.bookings || []);
|
|
547
|
+
return (0, _utils.createDefaultOrderRulesHooks)(() => this.store.tempOrder?.bookings || [], () => this.store.tempOrder?.holder_relations);
|
|
547
548
|
}
|
|
548
549
|
|
|
549
550
|
/**
|
|
@@ -857,7 +858,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
857
858
|
discount_list: (0, _utils.normalizeOrderProductDiscountList)((0, _manualProductDiscount.syncManualProductDiscountProductNum)(mergedProduct.discount_list, mergedProduct.num))
|
|
858
859
|
};
|
|
859
860
|
}));
|
|
860
|
-
(0, _discountProductLineIdentity.ensureUniqueProductLineUids)(tempOrder);
|
|
861
|
+
(0, _discountProductLineIdentity.ensureUniqueProductLineUids)(tempOrder, discountList);
|
|
861
862
|
(0, _discountProductLineIdentity.consolidateDiscountFreeProductLines)(tempOrder);
|
|
862
863
|
}
|
|
863
864
|
if (result?.discountList) {
|
|
@@ -1118,7 +1119,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1118
1119
|
* sessionStorage 的 cacheId 分桶。写入失败由 BaseModule 静默降级。
|
|
1119
1120
|
*/
|
|
1120
1121
|
persistTempOrder() {
|
|
1121
|
-
if (!this.
|
|
1122
|
+
if (!this.store.tempOrder) return;
|
|
1123
|
+
(0, _holderRelations.ensureHolderRelationUuids)(this.store.tempOrder);
|
|
1124
|
+
if (!this.sessionStoragePersistEnabled) return;
|
|
1122
1125
|
this.checkSaveCache({
|
|
1123
1126
|
cacheId: this.cacheId,
|
|
1124
1127
|
fatherModule: this.fatherModule,
|
|
@@ -1827,7 +1830,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1827
1830
|
source_product_price: this.normalizeFingerprintMoney(metadata.source_product_price),
|
|
1828
1831
|
main_product_selling_price: this.normalizeFingerprintMoney(metadata.main_product_selling_price),
|
|
1829
1832
|
main_product_original_price: this.normalizeFingerprintMoney(metadata.main_product_original_price),
|
|
1830
|
-
product_discount_difference: this.normalizeFingerprintMoney(metadata.product_discount_difference)
|
|
1833
|
+
product_discount_difference: this.normalizeFingerprintMoney(metadata.product_discount_difference),
|
|
1834
|
+
...(!(0, _holderRelations.hasProductBooking)(product) ? {
|
|
1835
|
+
holder_relations: this.normalizeFingerprintValue((0, _holderRelations.getProductHolderRelations)(this.store.tempOrder || {}, product))
|
|
1836
|
+
} : {})
|
|
1831
1837
|
},
|
|
1832
1838
|
product_sku: this.normalizeFingerprintValue({
|
|
1833
1839
|
code: sku.code ?? '',
|
|
@@ -1863,7 +1869,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1863
1869
|
items.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
|
1864
1870
|
return JSON.stringify(items);
|
|
1865
1871
|
}
|
|
1866
|
-
buildProductStructuralFingerprintItem(product) {
|
|
1872
|
+
buildProductStructuralFingerprintItem(product, order = this.store.tempOrder || {}) {
|
|
1867
1873
|
const sku = product?.product_sku || {};
|
|
1868
1874
|
const metadata = product?.metadata || {};
|
|
1869
1875
|
const discountTypes = (product?.discount_list || []).map(discount => discount?.type ?? discount?.tag);
|
|
@@ -1878,7 +1884,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1878
1884
|
unique_identification_number: metadata.unique_identification_number ?? product?.unique_identification_number ?? '',
|
|
1879
1885
|
price_override: metadata.price_override ?? '',
|
|
1880
1886
|
is_manual_discount: metadata.is_manual_discount ?? '',
|
|
1881
|
-
product_discount_reason: metadata.product_discount_reason ?? ''
|
|
1887
|
+
product_discount_reason: metadata.product_discount_reason ?? '',
|
|
1888
|
+
...(!(0, _holderRelations.hasProductBooking)(product) ? {
|
|
1889
|
+
holder_relations: this.normalizeFingerprintValue((0, _holderRelations.getProductHolderRelations)(order, product))
|
|
1890
|
+
} : {})
|
|
1882
1891
|
},
|
|
1883
1892
|
product_sku: this.normalizeFingerprintValue({
|
|
1884
1893
|
code: sku.code ?? '',
|
|
@@ -1916,8 +1925,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1916
1925
|
})))
|
|
1917
1926
|
};
|
|
1918
1927
|
}
|
|
1919
|
-
buildOrderProductsStructuralFingerprint(products) {
|
|
1920
|
-
const items = (products || []).map(product => this.buildProductStructuralFingerprintItem(product));
|
|
1928
|
+
buildOrderProductsStructuralFingerprint(products, order = this.store.tempOrder || {}) {
|
|
1929
|
+
const items = (products || []).map(product => this.buildProductStructuralFingerprintItem(product, order));
|
|
1921
1930
|
items.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
|
1922
1931
|
return JSON.stringify(items);
|
|
1923
1932
|
}
|
|
@@ -1984,7 +1993,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1984
1993
|
const manualDepositOverride = this.getManualDepositOverride(tempOrder);
|
|
1985
1994
|
if (currentFingerprint !== snapshot.productFingerprint) {
|
|
1986
1995
|
const currentStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(tempOrder.products);
|
|
1987
|
-
const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(Array.isArray(snapshot.products) ? snapshot.products : []);
|
|
1996
|
+
const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(Array.isArray(snapshot.products) ? snapshot.products : [], snapshot);
|
|
1988
1997
|
if (currentStructuralFingerprint !== snapshotStructuralFingerprint) return null;
|
|
1989
1998
|
}
|
|
1990
1999
|
let summary = {
|
|
@@ -2205,9 +2214,16 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2205
2214
|
product.metadata = metadata;
|
|
2206
2215
|
return String(uid);
|
|
2207
2216
|
}
|
|
2208
|
-
sanitizeOrderProductForTempOrder(product) {
|
|
2217
|
+
sanitizeOrderProductForTempOrder(product, deferHolderCleanup = false) {
|
|
2209
2218
|
if (product.metadata && typeof product.metadata === 'object') {
|
|
2210
2219
|
delete product.metadata.origin;
|
|
2220
|
+
if (!deferHolderCleanup && !(0, _holderRelations.hasProductBooking)(product)) {
|
|
2221
|
+
delete product.metadata.holder;
|
|
2222
|
+
delete product.metadata.holder_id;
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
if (product._extend?.holder_relations !== undefined) {
|
|
2226
|
+
delete product._extend.holder_relations;
|
|
2211
2227
|
}
|
|
2212
2228
|
return product;
|
|
2213
2229
|
}
|
|
@@ -3006,6 +3022,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3006
3022
|
const nextCustomerId = tempOrder.customer_id ?? null;
|
|
3007
3023
|
if (String(previousCustomerId ?? '') !== String(nextCustomerId ?? '')) {
|
|
3008
3024
|
this.clearCustomerWalletState(tempOrder);
|
|
3025
|
+
(0, _holderRelations.removeProductHolderRelations)(tempOrder, tempOrder.products.filter(product => !(0, _holderRelations.hasProductBooking)(product)));
|
|
3009
3026
|
}
|
|
3010
3027
|
this.persistTempOrder();
|
|
3011
3028
|
return {
|
|
@@ -3569,10 +3586,13 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3569
3586
|
const hasIncomingProductNote = this.hasOrderProductLineNote(normalizedIncoming);
|
|
3570
3587
|
const hasIncomingManualProductDiscount = isManualProductDiscountProduct(normalizedIncoming);
|
|
3571
3588
|
const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
|
|
3589
|
+
const holderRelationsPatch = !hasIncomingBookingUid ? productToAdd._extend?.holder_relations : undefined;
|
|
3590
|
+
const hasIncomingHolder = Array.isArray(holderRelationsPatch) && holderRelationsPatch.length > 0;
|
|
3572
3591
|
const isIncomingCustomItem = productToAdd.metadata?.origin?.isCustomItem === true || productToAdd._origin?.isCustomItem === true;
|
|
3573
|
-
const shouldForceNewLine = disableMerge || !!booking || hasIncomingGoodPass || isIncomingPersistedEntitlementPass || hasIncomingBookingUid || isIncomingCustomItem || isWeighingProduct;
|
|
3592
|
+
const shouldForceNewLine = disableMerge || !!booking || hasIncomingGoodPass || isIncomingPersistedEntitlementPass || hasIncomingBookingUid || hasIncomingHolder || isIncomingCustomItem || isWeighingProduct;
|
|
3574
3593
|
const matchedIndex = shouldForceNewLine ? -1 : tempOrder.products.findIndex(item => {
|
|
3575
3594
|
if (this.hasGoodPassDiscount(item)) return false;
|
|
3595
|
+
if ((0, _holderRelations.getProductHolderRelations)(tempOrder, item).length > 0 || (0, _utils.hasAssignedHolderId)(item.metadata?.holder_id)) return false;
|
|
3576
3596
|
const isRuntimeEntitlementPass = this.isRuntimeEntitlementAppend(item, tempOrder);
|
|
3577
3597
|
if (isIncomingEntitlementAppend !== isRuntimeEntitlementPass) {
|
|
3578
3598
|
return false;
|
|
@@ -3663,6 +3683,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3663
3683
|
if (linked) {
|
|
3664
3684
|
tempOrder.bookings = [...(tempOrder.bookings || []), linked.booking];
|
|
3665
3685
|
}
|
|
3686
|
+
(0, _holderRelations.replaceProductHolderRelations)(tempOrder, committedProduct, holderRelationsPatch);
|
|
3666
3687
|
return committedProduct;
|
|
3667
3688
|
};
|
|
3668
3689
|
if (!matchedProduct) {
|
|
@@ -3772,6 +3793,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3772
3793
|
}));
|
|
3773
3794
|
const mutationSnapshot = salesNoteDrafts.length > 0 ? {
|
|
3774
3795
|
products: (0, _lodashEs.cloneDeep)(tempOrder.products || []),
|
|
3796
|
+
holder_relations: (0, _lodashEs.cloneDeep)(tempOrder.holder_relations),
|
|
3775
3797
|
bookings: (0, _lodashEs.cloneDeep)(tempOrder.bookings || []),
|
|
3776
3798
|
notes: (0, _lodashEs.cloneDeep)(tempOrder.notes || []),
|
|
3777
3799
|
extend: (0, _lodashEs.cloneDeep)(tempOrder._extend || {})
|
|
@@ -3796,6 +3818,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3796
3818
|
const rollbackProductAndNotesMutation = () => {
|
|
3797
3819
|
if (!mutationSnapshot) return;
|
|
3798
3820
|
tempOrder.products = mutationSnapshot.products;
|
|
3821
|
+
if (mutationSnapshot.holder_relations === undefined) delete tempOrder.holder_relations;else tempOrder.holder_relations = mutationSnapshot.holder_relations;
|
|
3799
3822
|
tempOrder.bookings = mutationSnapshot.bookings;
|
|
3800
3823
|
tempOrder.notes = mutationSnapshot.notes;
|
|
3801
3824
|
tempOrder._extend = mutationSnapshot.extend;
|
|
@@ -4280,6 +4303,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4280
4303
|
if (uid) reapplyWeighedDiscountProductUids?.push(String(uid));
|
|
4281
4304
|
}
|
|
4282
4305
|
tempOrder.products[productIndex] = normalizedProduct;
|
|
4306
|
+
(0, _holderRelations.replaceProductHolderRelations)(tempOrder, normalizedProduct, updates._extend?.holder_relations);
|
|
4283
4307
|
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
4284
4308
|
this.captureProductRuntime(tempOrder, updates, tempOrder.products[productIndex], tempOrder.products[productIndex].metadata?.unique_identification_number);
|
|
4285
4309
|
return tempOrder.products[productIndex].metadata?.unique_identification_number;
|
|
@@ -4557,6 +4581,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4557
4581
|
tempOrder.products = nextProductIndex >= 0 ? [...productsWithoutRemaining.slice(0, nextProductIndex), remainingProduct, ...productsWithoutRemaining.slice(nextProductIndex)] : [...productsWithoutRemaining, remainingProduct];
|
|
4558
4582
|
}
|
|
4559
4583
|
}
|
|
4584
|
+
(0, _holderRelations.removeProductHolderRelations)(tempOrder, productsBeforeRemove.filter(product => !tempOrder.products.includes(product)));
|
|
4560
4585
|
this.removeSalesNotesForMissingProductLines(tempOrder);
|
|
4561
4586
|
if (isCurrentOrder) {
|
|
4562
4587
|
await this.finalizeProductOrderMutation(tempOrder, {
|
|
@@ -4582,6 +4607,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4582
4607
|
async clearOrderCartLines() {
|
|
4583
4608
|
const tempOrder = this.ensureTempOrder();
|
|
4584
4609
|
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
4610
|
+
(0, _holderRelations.removeProductHolderRelations)(tempOrder, tempOrder.products);
|
|
4585
4611
|
tempOrder.products = [];
|
|
4586
4612
|
tempOrder.bookings = [];
|
|
4587
4613
|
(0, _virtualSettlement.releaseTempOrderSettlementState)(tempOrder);
|
|
@@ -4611,6 +4637,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4611
4637
|
async clearOrderForSettlementSwitch() {
|
|
4612
4638
|
const tempOrder = this.ensureTempOrder();
|
|
4613
4639
|
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
4640
|
+
(0, _holderRelations.removeProductHolderRelations)(tempOrder, tempOrder.products);
|
|
4614
4641
|
tempOrder.products = [];
|
|
4615
4642
|
tempOrder.bookings = [];
|
|
4616
4643
|
this.removeSalesNotesForMissingProductLines(tempOrder);
|
|
@@ -5354,6 +5381,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
5354
5381
|
originalSalesSnapshot: {
|
|
5355
5382
|
summary: (0, _lodashEs.cloneDeep)(this.store.summary),
|
|
5356
5383
|
products: (0, _lodashEs.cloneDeep)(nextTempOrder.products || []),
|
|
5384
|
+
holder_relations: (0, _lodashEs.cloneDeep)(nextTempOrder.holder_relations),
|
|
5357
5385
|
bookings: (0, _lodashEs.cloneDeep)(nextTempOrder.bookings || []),
|
|
5358
5386
|
payments: (0, _lodashEs.cloneDeep)(nextTempOrder.payments || []),
|
|
5359
5387
|
surcharges: (0, _lodashEs.cloneDeep)(nextTempOrder.surcharges || []),
|
|
@@ -5506,6 +5534,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
5506
5534
|
nextTempOrder.metadata = raw.metadata && typeof raw.metadata === 'object' ? {
|
|
5507
5535
|
...raw.metadata
|
|
5508
5536
|
} : {};
|
|
5537
|
+
const holderRelations = (0, _holderRelations.restoreLegacyHolderRelations)(raw);
|
|
5538
|
+
if (holderRelations === undefined) delete nextTempOrder.holder_relations;else nextTempOrder.holder_relations = (0, _lodashEs.cloneDeep)(holderRelations);
|
|
5539
|
+
(0, _holderRelations.ensureHolderRelationUuids)(nextTempOrder);
|
|
5509
5540
|
nextTempOrder.holder = raw.holder && typeof raw.holder === 'object' ? {
|
|
5510
5541
|
...raw.holder
|
|
5511
5542
|
} : null;
|
|
@@ -5583,6 +5614,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
5583
5614
|
}
|
|
5584
5615
|
tempOrderExtend.productsByUid = productsByUid;
|
|
5585
5616
|
this.hydrateLinkedBookingIdentity(nextTempOrder);
|
|
5617
|
+
nextTempOrder.products.forEach(product => this.sanitizeOrderProductForTempOrder(product));
|
|
5586
5618
|
if (options?.ensureIdentity !== false) {
|
|
5587
5619
|
this.ensureExternalSaleNumber(nextTempOrder);
|
|
5588
5620
|
}
|
|
@@ -5743,7 +5775,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
5743
5775
|
};
|
|
5744
5776
|
if (result.metadata) delete result.metadata.price_schema_version;
|
|
5745
5777
|
const restored = (0, _bundleDiscountHydration.restoreHydratedBundleDiscounts)(result, _utils.normalizeOrderProductDiscountList);
|
|
5746
|
-
return this.sanitizeOrderProductForTempOrder(this.normalizeVirtualSettlementProductIfEnabled(restored));
|
|
5778
|
+
return this.sanitizeOrderProductForTempOrder(this.normalizeVirtualSettlementProductIfEnabled(restored), true);
|
|
5747
5779
|
}
|
|
5748
5780
|
getLastOrderInfo() {
|
|
5749
5781
|
return this.store?.lastOrderInfo;
|