@pisell/pisellos 2.2.315 → 2.2.317
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 +791 -795
- package/dist/modules/Order/types.d.ts +21 -3
- package/dist/modules/Order/types.js +4 -2
- 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 +2 -1
- package/dist/modules/Order/utils.js +36 -10
- package/dist/modules/Rules/index.js +62 -61
- package/dist/server/index.js +36 -28
- 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.d.ts +28 -7
- package/dist/server/modules/products/index.js +1297 -770
- package/dist/server/modules/products/replication.d.ts +8 -0
- package/dist/server/modules/products/replication.js +69 -0
- package/dist/server/modules/products/types.d.ts +12 -1
- package/dist/server/modules/products/types.js +4 -0
- package/dist/shared/receipt/small-ticket.js +24 -12
- package/dist/shared/receipt/templateVisibility.d.ts +3 -0
- package/dist/shared/receipt/templateVisibility.js +6 -2
- 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/BookingByStep/index.d.ts +2 -2
- package/dist/solution/BookingTicket/index.d.ts +15 -1
- package/dist/solution/BookingTicket/index.js +784 -501
- package/dist/solution/ScanOrder/index.js +65 -31
- package/dist/solution/ScanOrder/types.d.ts +3 -0
- 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 +46 -20
- package/lib/modules/Order/types.d.ts +21 -3
- package/lib/modules/Order/types.js +3 -2
- 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 +2 -1
- package/lib/modules/Order/utils.js +28 -6
- package/lib/modules/Rules/index.js +2 -1
- package/lib/server/index.js +8 -2
- 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.d.ts +28 -7
- package/lib/server/modules/products/index.js +226 -63
- package/lib/server/modules/products/replication.d.ts +8 -0
- package/lib/server/modules/products/replication.js +30 -0
- package/lib/server/modules/products/types.d.ts +12 -1
- package/lib/server/modules/products/types.js +3 -0
- package/lib/shared/receipt/small-ticket.js +22 -13
- package/lib/shared/receipt/templateVisibility.d.ts +3 -0
- package/lib/shared/receipt/templateVisibility.js +6 -2
- 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/BookingByStep/index.d.ts +2 -2
- package/lib/solution/BookingTicket/index.d.ts +15 -1
- package/lib/solution/BookingTicket/index.js +132 -3
- package/lib/solution/ScanOrder/index.js +59 -20
- package/lib/solution/ScanOrder/types.d.ts +3 -0
- package/lib/solution/UnifiedBookingSales/index.js +1 -1
- package/package.json +1 -1
|
@@ -39,6 +39,9 @@ var _orderLineDisplay = require("../../modules/BookingContext/utils/orderLineDis
|
|
|
39
39
|
var _bookingStatus = require("./utils/bookingStatus");
|
|
40
40
|
var _resolveBestAddTimePlan = require("./utils/resolveBestAddTimePlan");
|
|
41
41
|
var _utils = require("../../modules/Order/utils");
|
|
42
|
+
var _contactInfo = require("../../modules/OpenData/contactInfo");
|
|
43
|
+
var _platform = require("../../utils/platform");
|
|
44
|
+
var _lodashEs = require("lodash-es");
|
|
42
45
|
var _types2 = require("../../server/modules/form/types");
|
|
43
46
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
44
47
|
const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'documents'];
|
|
@@ -163,6 +166,7 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
163
166
|
orderCustomerDiscountRefreshCustomerId = null;
|
|
164
167
|
orderCustomerDiscountRefreshTarget = null;
|
|
165
168
|
orderCustomerPromotionRefreshInFlight = null;
|
|
169
|
+
orderCustomerContactRequest = null;
|
|
166
170
|
customerResolveRequests = new Map();
|
|
167
171
|
loadOpenDataInFlight = null;
|
|
168
172
|
loadOpenDataInFlightTarget = null;
|
|
@@ -300,6 +304,9 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
300
304
|
async getOpenData() {
|
|
301
305
|
return this.loadOpenDataConfig();
|
|
302
306
|
}
|
|
307
|
+
async loadContactInfoOpenData() {
|
|
308
|
+
return this.store.openData ? this.getOpenData() : super.loadContactInfoOpenData();
|
|
309
|
+
}
|
|
303
310
|
async loadFulfillmentItemRuleOpenData() {
|
|
304
311
|
return this.store.openData ? this.getOpenData() : super.loadFulfillmentItemRuleOpenData();
|
|
305
312
|
}
|
|
@@ -1035,7 +1042,9 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1035
1042
|
*/
|
|
1036
1043
|
setOrderCustomer(customer, options) {
|
|
1037
1044
|
if (!customer) {
|
|
1038
|
-
this.clearOrderCustomer(
|
|
1045
|
+
this.clearOrderCustomer({
|
|
1046
|
+
preserveContactInfo: options?.source === 'detailHydrate'
|
|
1047
|
+
});
|
|
1039
1048
|
return;
|
|
1040
1049
|
}
|
|
1041
1050
|
const previousCustomerId = this.store.order.getOrderCustomer()?.customer_id;
|
|
@@ -1046,7 +1055,16 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1046
1055
|
this.discountConfigCacheKey = null;
|
|
1047
1056
|
this.hasManualDiscountSelection = false;
|
|
1048
1057
|
}
|
|
1058
|
+
if (!customerUnchanged && options?.source !== 'detailHydrate') {
|
|
1059
|
+
this.resetOrderCustomerContactInfo();
|
|
1060
|
+
this.store.order.updateTempOrderContactsInfo((0, _lodashEs.cloneDeep)((0, _contactInfo.extractCustomerContactInfo)(customer)));
|
|
1061
|
+
}
|
|
1049
1062
|
this.store.order.setOrderCustomer(patch, customer);
|
|
1063
|
+
if (options?.source === 'detailHydrate') {
|
|
1064
|
+
this.orderCustomerContactRequest = null;
|
|
1065
|
+
} else {
|
|
1066
|
+
this.prefillOrderCustomerContactInfo(customer, !customerUnchanged);
|
|
1067
|
+
}
|
|
1050
1068
|
const snapshotAfterOrderSet = this.store.order.getOrderCustomerSnapshot();
|
|
1051
1069
|
if (customerUnchanged) {
|
|
1052
1070
|
// hydrate 后 customer_id 已存在但 _extend.customerSnapshot 仍为空时,
|
|
@@ -1079,6 +1097,105 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1079
1097
|
this.orderCustomerPromotionRefreshInFlight = null;
|
|
1080
1098
|
});
|
|
1081
1099
|
}
|
|
1100
|
+
resetOrderCustomerContactInfo() {
|
|
1101
|
+
this.orderCustomerContactRequest = null;
|
|
1102
|
+
const order = this.getTempOrder();
|
|
1103
|
+
if (order?._extend) delete order._extend.contactInfoEdited;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/** Explicit edits, including clearing the contact, must win over a pending default. */
|
|
1107
|
+
updateTempOrderContactsInfo(contact) {
|
|
1108
|
+
const order = this.store.order.ensureTempOrder();
|
|
1109
|
+
order._extend || (order._extend = {});
|
|
1110
|
+
order._extend.contactInfoEdited = true;
|
|
1111
|
+
this.orderCustomerContactRequest = null;
|
|
1112
|
+
return super.updateTempOrderContactsInfo(contact);
|
|
1113
|
+
}
|
|
1114
|
+
getCustomerContactScope() {
|
|
1115
|
+
return JSON.stringify([this.getPickupTimingScope(), this.otherParams?.channel, this.otherParams?.shop_id, this.otherParams?.tenantId]);
|
|
1116
|
+
}
|
|
1117
|
+
getCustomerContactOrderKey() {
|
|
1118
|
+
const order = this.getTempOrder();
|
|
1119
|
+
// Cart mutations can replace the object without changing the order.
|
|
1120
|
+
const identity = order?.external_sale_number || order?.request_unique_idempotency_token || order?._extend?.localId || order?.order_id;
|
|
1121
|
+
return identity ? JSON.stringify([identity, order?.order_id]) : order;
|
|
1122
|
+
}
|
|
1123
|
+
async replaceTempOrder(...args) {
|
|
1124
|
+
this.orderCustomerContactRequest = null;
|
|
1125
|
+
return super.replaceTempOrder(...args);
|
|
1126
|
+
}
|
|
1127
|
+
async applyDefaultOrderCustomerContactInfo(contact) {
|
|
1128
|
+
this.store.order.updateTempOrderContactsInfo((0, _lodashEs.cloneDeep)(contact));
|
|
1129
|
+
// Metadata may finish after promotion/discount refresh; publish the updated cart explicitly.
|
|
1130
|
+
await this.effectsEmit('onTempOrderReplaced', {
|
|
1131
|
+
tempOrder: this.getTempOrder()
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
prefillOrderCustomerContactInfo(customer, customerChanged) {
|
|
1135
|
+
const order = this.getTempOrder();
|
|
1136
|
+
const customerId = Number(order?.customer_id);
|
|
1137
|
+
if (!order || !Number.isInteger(customerId) || customerId <= 1 || order.contacts_info != null || order._extend?.contactInfoEdited) return;
|
|
1138
|
+
// A restored new cart may already have its customer ID. Existing sales keep their snapshot,
|
|
1139
|
+
// even when it is empty; only an explicit customer switch replaces it.
|
|
1140
|
+
if (!customerChanged && order.order_id && !String(order.order_id).startsWith('local_order')) return;
|
|
1141
|
+
const contact = (0, _contactInfo.extractCustomerContactInfo)(customer);
|
|
1142
|
+
if (contact) {
|
|
1143
|
+
this.orderCustomerContactRequest = null;
|
|
1144
|
+
void this.applyDefaultOrderCustomerContactInfo(contact);
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
// A relation explicitly returned as null is authoritative. Only a missing relation needs fetching.
|
|
1148
|
+
if (customer.contacts_info !== undefined) return;
|
|
1149
|
+
const userPlatform = (0, _platform.isCustomerUserPlatform)(this.otherParams?.platform);
|
|
1150
|
+
const getAuthenticatedCustomerId = () => Number(this.core?.getPlugin?.('user')?.get?.()?.id);
|
|
1151
|
+
if (userPlatform && getAuthenticatedCustomerId() !== customerId) return;
|
|
1152
|
+
const scope = this.getCustomerContactScope();
|
|
1153
|
+
const orderKey = this.getCustomerContactOrderKey();
|
|
1154
|
+
const previous = this.orderCustomerContactRequest;
|
|
1155
|
+
if (previous?.orderKey === orderKey && previous.customerId === customerId && previous.scope === scope) return;
|
|
1156
|
+
const pending = {
|
|
1157
|
+
orderKey,
|
|
1158
|
+
customerId,
|
|
1159
|
+
scope,
|
|
1160
|
+
promise: Promise.resolve()
|
|
1161
|
+
};
|
|
1162
|
+
this.orderCustomerContactRequest = pending;
|
|
1163
|
+
const loadContact = async () => {
|
|
1164
|
+
if (userPlatform) {
|
|
1165
|
+
// Same endpoint as BookingByStep.getContactInfo; the PC/H5 host adds /h5 and login headers.
|
|
1166
|
+
const result = await this.request.get('/customer/metadata', {
|
|
1167
|
+
key: 'contacts_info'
|
|
1168
|
+
});
|
|
1169
|
+
if (result?.code !== 200 || result?.status === false) throw new Error('Customer contact lookup failed');
|
|
1170
|
+
return (0, _contactInfo.isContactRecord)(result.data) ? result.data : null;
|
|
1171
|
+
}
|
|
1172
|
+
// POS and physical Kiosk share the /shop request plugin and current-shop customer resolver.
|
|
1173
|
+
const resolved = await this.resolveCustomerById(customerId);
|
|
1174
|
+
return Number(resolved?.id) === customerId ? (0, _contactInfo.extractCustomerContactInfo)(resolved) : null;
|
|
1175
|
+
};
|
|
1176
|
+
pending.promise = loadContact().then(async value => {
|
|
1177
|
+
const current = this.getTempOrder();
|
|
1178
|
+
if (this.orderCustomerContactRequest !== pending || this.getCustomerContactOrderKey() !== orderKey || Number(current?.customer_id) !== customerId || scope !== this.getCustomerContactScope() || current?._extend?.contactInfoEdited || current?.contacts_info != null || userPlatform && getAuthenticatedCustomerId() !== customerId) return;
|
|
1179
|
+
if (value) await this.applyDefaultOrderCustomerContactInfo(value);
|
|
1180
|
+
}).catch(() => {
|
|
1181
|
+
// A failed default does not prevent manual entry; a subsequent sync can retry.
|
|
1182
|
+
if (this.orderCustomerContactRequest === pending) this.orderCustomerContactRequest = null;
|
|
1183
|
+
console.warn('[BookingTicket] Failed to load saved customer contact information');
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
waitForOrderCustomerContactInfo() {
|
|
1187
|
+
return this.orderCustomerContactRequest?.promise ?? Promise.resolve();
|
|
1188
|
+
}
|
|
1189
|
+
async validateContactInfo() {
|
|
1190
|
+
const orderKey = this.getCustomerContactOrderKey();
|
|
1191
|
+
const customerId = this.getTempOrder()?.customer_id;
|
|
1192
|
+
const scope = this.getCustomerContactScope();
|
|
1193
|
+
await this.waitForOrderCustomerContactInfo();
|
|
1194
|
+
if (this.getCustomerContactOrderKey() !== orderKey || this.getTempOrder()?.customer_id !== customerId || this.getCustomerContactScope() !== scope) {
|
|
1195
|
+
throw new Error('The order changed. Please try again.');
|
|
1196
|
+
}
|
|
1197
|
+
await super.validateContactInfo();
|
|
1198
|
+
}
|
|
1082
1199
|
|
|
1083
1200
|
/**
|
|
1084
1201
|
* 读取 tempOrder 上的下单客户协议字段;customer_id 缺失时返回 null。
|
|
@@ -1097,7 +1214,10 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1097
1214
|
/**
|
|
1098
1215
|
* 清空下单客户(协议字段 + snapshot)。
|
|
1099
1216
|
*/
|
|
1100
|
-
clearOrderCustomer() {
|
|
1217
|
+
clearOrderCustomer(options) {
|
|
1218
|
+
this.orderCustomerContactRequest = null;
|
|
1219
|
+
if (!options?.preserveContactInfo) this.resetOrderCustomerContactInfo();
|
|
1220
|
+
if (!options?.preserveContactInfo) this.store.order.updateTempOrderContactsInfo(null);
|
|
1101
1221
|
this.store.order.clearOrderCustomer();
|
|
1102
1222
|
this.discountConfigCacheKey = null;
|
|
1103
1223
|
this.hasManualDiscountSelection = false;
|
|
@@ -1667,7 +1787,10 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1667
1787
|
* 从已加车的普通商品 order line 反查 SkuDetailModal edit 所需的 cacheItem。
|
|
1668
1788
|
*/
|
|
1669
1789
|
buildNormalProductCacheItemFromOrderLine(input) {
|
|
1670
|
-
return (0, _buildNormalProductCacheItemFromOrderLine.buildNormalProductCacheItemFromOrderLine)(
|
|
1790
|
+
return (0, _buildNormalProductCacheItemFromOrderLine.buildNormalProductCacheItemFromOrderLine)({
|
|
1791
|
+
...input,
|
|
1792
|
+
holder_relations: input.holder_relations ?? this.store.order?.getTempOrder()?.holder_relations
|
|
1793
|
+
});
|
|
1671
1794
|
}
|
|
1672
1795
|
|
|
1673
1796
|
/** 文档别名:与 OrderModule.updateOrderProduct 一致。 */
|
|
@@ -1900,6 +2023,11 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1900
2023
|
async setOtherParams(params, {
|
|
1901
2024
|
cover = false
|
|
1902
2025
|
} = {}) {
|
|
2026
|
+
const nextParams = cover ? params : {
|
|
2027
|
+
...this.otherParams,
|
|
2028
|
+
...params
|
|
2029
|
+
};
|
|
2030
|
+
if (['businessCode', 'business_code', 'channel', 'platform', 'shop_id', 'tenantId', 'cacheId'].some(key => nextParams?.[key] !== this.otherParams?.[key])) this.orderCustomerContactRequest = null;
|
|
1903
2031
|
await super.setOtherParams(params, {
|
|
1904
2032
|
cover
|
|
1905
2033
|
});
|
|
@@ -2015,6 +2143,7 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
2015
2143
|
* 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。
|
|
2016
2144
|
*/
|
|
2017
2145
|
async destroy() {
|
|
2146
|
+
this.orderCustomerContactRequest = null;
|
|
2018
2147
|
await super.destroy();
|
|
2019
2148
|
try {
|
|
2020
2149
|
this.scan?.removeAllListeners();
|
|
@@ -797,6 +797,7 @@ class ScanOrderImpl extends _BaseSales.BaseSalesImpl {
|
|
|
797
797
|
}
|
|
798
798
|
|
|
799
799
|
// ScanOrder 提交 payload enhancer:
|
|
800
|
+
// - 新单有桌台上下文但无 booking 时,补建基础预约(通用 Order 已不再自动生成)
|
|
800
801
|
// - 给所有 booking 注入 appointment_status: 'started'(扫码点餐语义)
|
|
801
802
|
// - 给所有 booking 的 metadata 注入 resource_select_type(来自预约规则商品的 resource.type)
|
|
802
803
|
// - 给第一条 booking 补 resources 与 product_uid(仅当存在 resource / rule product)
|
|
@@ -818,7 +819,8 @@ class ScanOrderImpl extends _BaseSales.BaseSalesImpl {
|
|
|
818
819
|
};
|
|
819
820
|
return (payload, {
|
|
820
821
|
bookingUuid,
|
|
821
|
-
tempOrder
|
|
822
|
+
tempOrder,
|
|
823
|
+
now
|
|
822
824
|
}) => {
|
|
823
825
|
const resourceId = String(resourceState?.relationId ?? '').trim();
|
|
824
826
|
const hasReservationBookingContext = Boolean(ruleProduct && resourceState && resourceId && resourceState.relationId && resourceState.tableFormId);
|
|
@@ -855,7 +857,31 @@ class ScanOrderImpl extends _BaseSales.BaseSalesImpl {
|
|
|
855
857
|
} : undefined;
|
|
856
858
|
const ruleProductUid = ruleProduct ? (0, _utils2.createUuidV4)() : undefined;
|
|
857
859
|
const bookingCapacityDimensionId = (0, _utils.pickFirstCustomCapacityDimensionId)(this.enabledReservationRuleProducts) ?? 0;
|
|
858
|
-
|
|
860
|
+
let bookings = payload.bookings || [];
|
|
861
|
+
if (!tempOrder.order_id && bookings.length === 0) {
|
|
862
|
+
const bookingStart = (0, _dayjs.default)(now);
|
|
863
|
+
const bookingDuration = (0, _utils2.resolveTableOccupancyDuration)(tempOrder);
|
|
864
|
+
const bookingEnd = bookingStart.add(bookingDuration, 'minute');
|
|
865
|
+
bookings = [(0, _utils2.normalizeSubmitBooking)({
|
|
866
|
+
relation_id: 0,
|
|
867
|
+
form_id: 0,
|
|
868
|
+
start_time: bookingStart.format('HH:mm'),
|
|
869
|
+
start_date: bookingStart.format('YYYY-MM-DD'),
|
|
870
|
+
end_time: bookingEnd.format('HH:mm'),
|
|
871
|
+
end_date: bookingEnd.format('YYYY-MM-DD'),
|
|
872
|
+
duration: bookingDuration,
|
|
873
|
+
metadata: {
|
|
874
|
+
unique_identification_number: bookingUuid
|
|
875
|
+
},
|
|
876
|
+
select_date: bookingStart.format('YYYY-MM-DD'),
|
|
877
|
+
is_all: false,
|
|
878
|
+
like_status: 'common',
|
|
879
|
+
schedule_id: 0,
|
|
880
|
+
relation_type: '',
|
|
881
|
+
number: 1
|
|
882
|
+
})];
|
|
883
|
+
}
|
|
884
|
+
const nextBookings = bookings.map((booking, idx) => {
|
|
859
885
|
const metadata = {
|
|
860
886
|
...(booking.metadata || {})
|
|
861
887
|
};
|
|
@@ -1273,29 +1299,40 @@ class ScanOrderImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1273
1299
|
if (!Number.isFinite(productId) || targetQuantity <= 0) continue;
|
|
1274
1300
|
if (Number.isNaN(productVariantId)) continue;
|
|
1275
1301
|
const sourceItem = productSourceMap.get((0, _utils.buildProductKey)(productId, productVariantId)) || productSourceMap.get((0, _utils.buildProductKey)(productId, 0)) || null;
|
|
1302
|
+
const sourceTitle = sourceItem?.product_title || sourceItem?.title || sourceItem?.name;
|
|
1303
|
+
const productTitle = typeof sourceTitle === 'string' ? {
|
|
1304
|
+
auto: sourceTitle
|
|
1305
|
+
} : sourceTitle;
|
|
1306
|
+
// 标准标题在归一化后补入,供购物车展示,并由 Order 在折扣重算时保留。
|
|
1307
|
+
const displayFields = productTitle ? {
|
|
1308
|
+
product_title: productTitle
|
|
1309
|
+
} : {};
|
|
1276
1310
|
const productIndex = (0, _utils.getProductIdentityIndex)(tempOrder.products, {
|
|
1277
1311
|
product_id: productId,
|
|
1278
1312
|
product_variant_id: productVariantId
|
|
1279
1313
|
});
|
|
1280
1314
|
if (productIndex === -1) {
|
|
1281
1315
|
const sellingPrice = (0, _utils.toPriceString)(sourceItem?.price ?? sourceItem?.selling_price, '0.00');
|
|
1282
|
-
tempOrder.products.push(
|
|
1283
|
-
...
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1316
|
+
tempOrder.products.push({
|
|
1317
|
+
...(0, _utils.normalizeOrderProduct)({
|
|
1318
|
+
...sourceItem,
|
|
1319
|
+
product_id: productId,
|
|
1320
|
+
product_variant_id: productVariantId,
|
|
1321
|
+
num: targetQuantity,
|
|
1322
|
+
selling_price: sellingPrice,
|
|
1323
|
+
original_price: sellingPrice,
|
|
1324
|
+
metadata: {
|
|
1325
|
+
item_rule_prefill: true,
|
|
1326
|
+
item_rule_id: prefillItem.ruleId
|
|
1327
|
+
},
|
|
1328
|
+
_origin: {
|
|
1329
|
+
...(sourceItem || {}),
|
|
1330
|
+
item_rule_prefill: true,
|
|
1331
|
+
item_rule_id: prefillItem.ruleId
|
|
1332
|
+
}
|
|
1333
|
+
}),
|
|
1334
|
+
...displayFields
|
|
1335
|
+
});
|
|
1299
1336
|
hasChanges = true;
|
|
1300
1337
|
continue;
|
|
1301
1338
|
}
|
|
@@ -1304,6 +1341,7 @@ class ScanOrderImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1304
1341
|
const delta = targetQuantity - existedQuantity;
|
|
1305
1342
|
const nextProduct = {
|
|
1306
1343
|
...targetProduct,
|
|
1344
|
+
...displayFields,
|
|
1307
1345
|
...(delta > 0 ? {
|
|
1308
1346
|
num: (0, _utils.getSafeProductNum)(existedQuantity + delta)
|
|
1309
1347
|
} : {}),
|
|
@@ -1318,8 +1356,9 @@ class ScanOrderImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1318
1356
|
} : targetProduct._origin
|
|
1319
1357
|
};
|
|
1320
1358
|
const hasQuantityChanged = delta > 0;
|
|
1359
|
+
const hasTitleChanged = Boolean(productTitle && JSON.stringify(targetProduct.product_title) !== JSON.stringify(productTitle));
|
|
1321
1360
|
const hasOriginChanged = Boolean(sourceItem && (!targetProduct._origin || targetProduct._origin?.name !== sourceItem?.name || targetProduct._origin?.title !== sourceItem?.title || targetProduct._origin?.price !== sourceItem?.price));
|
|
1322
|
-
if (hasQuantityChanged || hasOriginChanged) {
|
|
1361
|
+
if (hasQuantityChanged || hasTitleChanged || hasOriginChanged) {
|
|
1323
1362
|
tempOrder.products[productIndex] = nextProduct;
|
|
1324
1363
|
hasChanges = true;
|
|
1325
1364
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OrderModule, ProductList, SalesSummaryModule, ScanOrderLogInput, ScanOrderLoggerModule, ScanOrderLoggerProviderConfig, ScanOrderLoggerProviderType, ScheduleModule } from '../../modules';
|
|
2
2
|
import type { QuantityCheckResult, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
|
|
3
|
+
import type { OrderLocalizedText } from '../../modules/Order/types';
|
|
3
4
|
/**
|
|
4
5
|
* 扫码下单流程 hook
|
|
5
6
|
*/
|
|
@@ -43,6 +44,8 @@ export interface ScanOrderProductSku {
|
|
|
43
44
|
}
|
|
44
45
|
export interface ScanOrderOrderProduct extends ScanOrderOrderProductIdentity {
|
|
45
46
|
order_detail_id: number | null;
|
|
47
|
+
/** 与 Order 一致的商品展示名称。 */
|
|
48
|
+
product_title?: OrderLocalizedText;
|
|
46
49
|
num: number;
|
|
47
50
|
/** Product 或当前 Variant 的生产编码 */
|
|
48
51
|
production_code?: string;
|
|
@@ -1877,7 +1877,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
1877
1877
|
}
|
|
1878
1878
|
this.store.customer?.setSelectedCustomer?.(authenticatedCustomer);
|
|
1879
1879
|
this.setOrderCustomer(authenticatedCustomer);
|
|
1880
|
-
await Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh()]);
|
|
1880
|
+
await Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh(), this.waitForOrderCustomerContactInfo()]);
|
|
1881
1881
|
return true;
|
|
1882
1882
|
}
|
|
1883
1883
|
isAuthenticatedCustomerUserPlatform() {
|