@pisell/pisellos 2.2.291 → 2.2.293
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/core/index.d.ts +7 -0
- package/dist/core/index.js +108 -65
- package/dist/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
- package/dist/model/strategy/adapter/itemRule/adapter.js +135 -35
- package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
- package/dist/model/strategy/adapter/itemRule/evaluator.js +25 -1
- package/dist/model/strategy/adapter/itemRule/type.d.ts +44 -0
- package/dist/model/strategy/adapter/itemRule/type.js +19 -1
- package/dist/model/strategy/adapter/promotion/index.js +0 -9
- package/dist/modules/BookingContext/index.d.ts +3 -0
- package/dist/modules/BookingContext/index.js +42 -13
- package/dist/modules/BookingContext/types.d.ts +4 -4
- package/dist/modules/BookingContext/types.js +3 -3
- package/dist/modules/OpenData/types.d.ts +1 -0
- package/dist/modules/Order/index.d.ts +18 -3
- package/dist/modules/Order/index.js +885 -485
- package/dist/modules/Order/salesNotes.d.ts +31 -0
- package/dist/modules/Order/salesNotes.js +492 -0
- package/dist/modules/Order/types.d.ts +93 -5
- package/dist/modules/Order/types.js +5 -0
- package/dist/modules/Order/utils.d.ts +12 -0
- package/dist/modules/Order/utils.js +96 -31
- package/dist/modules/Product/types.d.ts +2 -0
- package/dist/modules/ProductList/clientDataVariants.d.ts +50 -0
- package/dist/modules/ProductList/clientDataVariants.js +216 -0
- package/dist/modules/ProductList/index.d.ts +18 -3
- package/dist/modules/ProductList/index.js +220 -38
- package/dist/modules/ProductList/types.d.ts +10 -0
- package/dist/modules/Quotation/index.d.ts +22 -0
- package/dist/modules/Quotation/index.js +293 -28
- package/dist/modules/ResourcePlanner/index.d.ts +0 -22
- package/dist/modules/ResourcePlanner/index.js +1 -180
- package/dist/modules/ResourcePlanner/localClock.d.ts +33 -0
- package/dist/modules/ResourcePlanner/localClock.js +183 -0
- package/dist/modules/ResourcePlanner/planner.d.ts +5 -14
- package/dist/modules/ResourcePlanner/planner.js +2111 -958
- package/dist/modules/ResourcePlanner/types.d.ts +359 -187
- package/dist/modules/ResourcePlanner/types.js +33 -1
- package/dist/plugins/request.d.ts +1 -0
- package/dist/server/index.d.ts +17 -2
- package/dist/server/index.js +1134 -932
- package/dist/server/modules/floor-plan/index.d.ts +4 -0
- package/dist/server/modules/floor-plan/index.js +240 -98
- package/dist/server/modules/menu/index.js +48 -23
- package/dist/server/modules/order/index.d.ts +17 -7
- package/dist/server/modules/order/index.js +419 -207
- package/dist/server/modules/products/index.d.ts +10 -4
- package/dist/server/modules/products/index.js +177 -84
- package/dist/server/modules/resource/index.js +21 -13
- package/dist/server/utils/product.d.ts +1 -1
- package/dist/server/utils/product.js +186 -22
- package/dist/server/utils/small-ticket.d.ts +9 -1
- package/dist/server/utils/small-ticket.js +131 -84
- package/dist/solution/BaseSales/index.d.ts +26 -3
- package/dist/solution/BaseSales/index.js +1384 -905
- package/dist/solution/BaseSales/types.d.ts +2 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +3 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +10 -3
- package/dist/solution/BaseSales/utils.js +6 -3
- package/dist/solution/BookingByStep/index.d.ts +4 -4
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +4 -2
- package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +2 -1
- package/dist/solution/BookingTicket/utils/addProductDecision.js +6 -3
- package/dist/solution/BookingTicket/utils/orderCustomer.js +3 -2
- package/dist/solution/RegisterAndLogin/config.d.ts +9 -3
- package/dist/solution/RegisterAndLogin/config.js +95 -40
- package/dist/solution/RegisterAndLogin/index.js +4 -1
- package/dist/solution/ScanOrder/index.d.ts +1 -0
- package/dist/solution/ScanOrder/index.js +31 -27
- package/dist/solution/ScanOrder/types.d.ts +2 -0
- package/dist/solution/ScanOrder/utils.d.ts +1 -0
- package/dist/solution/ScanOrder/utils.js +8 -3
- package/dist/solution/UnifiedBookingSales/index.d.ts +128 -74
- package/dist/solution/UnifiedBookingSales/index.js +3877 -963
- package/dist/solution/UnifiedBookingSales/remoteOccupancyCache.d.ts +49 -0
- package/dist/solution/UnifiedBookingSales/remoteOccupancyCache.js +430 -0
- package/dist/solution/UnifiedBookingSales/types.d.ts +161 -77
- package/dist/solution/UnifiedBookingSales/types.js +4 -9
- package/dist/solution/VenueBooking/index.d.ts +3 -0
- package/dist/solution/VenueBooking/index.js +549 -497
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.js +3 -1
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +2 -0
- package/dist/solution/VenueBooking/utils/slotMerge.js +3 -1
- package/dist/utils/platform.d.ts +8 -0
- package/dist/utils/platform.js +15 -0
- package/lib/core/index.d.ts +7 -0
- package/lib/core/index.js +20 -2
- package/lib/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
- package/lib/model/strategy/adapter/itemRule/adapter.js +73 -4
- package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
- package/lib/model/strategy/adapter/itemRule/evaluator.js +23 -1
- package/lib/model/strategy/adapter/itemRule/type.d.ts +44 -0
- package/lib/model/strategy/adapter/itemRule/type.js +19 -1
- package/lib/modules/BookingContext/index.d.ts +3 -0
- package/lib/modules/BookingContext/index.js +35 -8
- package/lib/modules/BookingContext/types.d.ts +4 -4
- package/lib/modules/BookingContext/types.js +3 -3
- package/lib/modules/OpenData/types.d.ts +1 -0
- package/lib/modules/Order/index.d.ts +18 -3
- package/lib/modules/Order/index.js +325 -28
- package/lib/modules/Order/salesNotes.d.ts +31 -0
- package/lib/modules/Order/salesNotes.js +382 -0
- package/lib/modules/Order/types.d.ts +93 -5
- package/lib/modules/Order/types.js +4 -0
- package/lib/modules/Order/utils.d.ts +12 -0
- package/lib/modules/Order/utils.js +85 -16
- package/lib/modules/Product/types.d.ts +2 -0
- package/lib/modules/ProductList/clientDataVariants.d.ts +50 -0
- package/lib/modules/ProductList/clientDataVariants.js +204 -0
- package/lib/modules/ProductList/index.d.ts +18 -3
- package/lib/modules/ProductList/index.js +137 -8
- package/lib/modules/ProductList/types.d.ts +10 -0
- package/lib/modules/Quotation/index.d.ts +22 -0
- package/lib/modules/Quotation/index.js +158 -11
- package/lib/modules/ResourcePlanner/index.d.ts +0 -22
- package/lib/modules/ResourcePlanner/index.js +9 -129
- package/lib/modules/ResourcePlanner/localClock.d.ts +33 -0
- package/lib/modules/ResourcePlanner/localClock.js +205 -0
- package/lib/modules/ResourcePlanner/planner.d.ts +5 -14
- package/lib/modules/ResourcePlanner/planner.js +1807 -783
- package/lib/modules/ResourcePlanner/types.d.ts +359 -187
- package/lib/modules/ResourcePlanner/types.js +13 -1
- package/lib/plugins/request.d.ts +1 -0
- package/lib/server/index.d.ts +17 -2
- package/lib/server/index.js +149 -21
- package/lib/server/modules/floor-plan/index.d.ts +4 -0
- package/lib/server/modules/floor-plan/index.js +60 -7
- package/lib/server/modules/menu/index.js +26 -4
- package/lib/server/modules/order/index.d.ts +17 -7
- package/lib/server/modules/order/index.js +194 -57
- package/lib/server/modules/products/index.d.ts +10 -4
- package/lib/server/modules/products/index.js +93 -23
- package/lib/server/modules/resource/index.js +12 -2
- package/lib/server/utils/product.d.ts +1 -1
- package/lib/server/utils/product.js +163 -3
- package/lib/server/utils/small-ticket.d.ts +9 -1
- package/lib/server/utils/small-ticket.js +123 -79
- package/lib/solution/BaseSales/index.d.ts +26 -3
- package/lib/solution/BaseSales/index.js +396 -70
- package/lib/solution/BaseSales/types.d.ts +2 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +3 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +9 -2
- package/lib/solution/BaseSales/utils.js +3 -0
- package/lib/solution/BookingByStep/index.d.ts +4 -4
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +2 -1
- package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +2 -1
- package/lib/solution/BookingTicket/utils/addProductDecision.js +5 -2
- package/lib/solution/BookingTicket/utils/orderCustomer.js +2 -1
- package/lib/solution/RegisterAndLogin/config.d.ts +9 -3
- package/lib/solution/RegisterAndLogin/config.js +49 -8
- package/lib/solution/RegisterAndLogin/index.js +4 -1
- package/lib/solution/ScanOrder/index.d.ts +1 -0
- package/lib/solution/ScanOrder/index.js +5 -1
- package/lib/solution/ScanOrder/types.d.ts +2 -0
- package/lib/solution/ScanOrder/utils.d.ts +1 -0
- package/lib/solution/ScanOrder/utils.js +4 -0
- package/lib/solution/UnifiedBookingSales/index.d.ts +128 -74
- package/lib/solution/UnifiedBookingSales/index.js +2592 -424
- package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.d.ts +49 -0
- package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +316 -0
- package/lib/solution/UnifiedBookingSales/types.d.ts +161 -77
- package/lib/solution/UnifiedBookingSales/types.js +4 -6
- package/lib/solution/VenueBooking/index.d.ts +3 -0
- package/lib/solution/VenueBooking/index.js +33 -9
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.js +3 -1
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +2 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +3 -1
- package/lib/utils/platform.d.ts +8 -0
- package/lib/utils/platform.js +22 -0
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { BaseModule } from '../BaseModule';
|
|
|
3
3
|
import { OrderModuleAPI, CommitOrderParams, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, CancelOrderParams, ChangeBookingStatusParams, CheckoutOrderParams } from './types';
|
|
4
4
|
import { CartItem } from '../Cart/types';
|
|
5
5
|
import { type SubmitPayloadEnhancer } from './utils';
|
|
6
|
-
import type { OrderAmountSnapshot, AddProductBookingInput, AddProductToOrderOptions, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions } from './types';
|
|
6
|
+
import type { OrderAmountSnapshot, AddProductBookingInput, AddProductToOrderOptions, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, SalesNote, SalesNotesMutationSnapshot, SetSalesNoteInput, PickupReferenceMode, ShopServiceData, ShopServiceType } from './types';
|
|
7
7
|
import type { ICustomer } from '../AccountList/types';
|
|
8
8
|
import type { Discount } from '../Discount/types';
|
|
9
9
|
import { UnavailableReason } from '../Rules/types';
|
|
@@ -301,9 +301,24 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
301
301
|
updateTempOrderNote(note: string, sync: boolean): string | Promise<string>;
|
|
302
302
|
syncTempOrderNoteToRemote(orderId: number | string, note: string): Promise<string>;
|
|
303
303
|
getTempOrderNote(): string;
|
|
304
|
+
private ensureSalesNotesRuntimeState;
|
|
305
|
+
private ensureSalesNotesLoadedForMutation;
|
|
306
|
+
private normalizeSalesNoteUuid;
|
|
307
|
+
private getSalesNotePrimaryRelation;
|
|
308
|
+
private removeSalesNotesForMissingProductLines;
|
|
309
|
+
private setSalesNoteOnTempOrder;
|
|
310
|
+
getSalesNotes(): SalesNote[];
|
|
311
|
+
createSalesNotesMutationSnapshot(): SalesNotesMutationSnapshot;
|
|
312
|
+
restoreSalesNotesMutationSnapshot(snapshot: SalesNotesMutationSnapshot): void;
|
|
313
|
+
setSalesNote(input: SetSalesNoteInput): Promise<SalesNote>;
|
|
314
|
+
removeSalesNote(uuid: string): Promise<void>;
|
|
315
|
+
clearSalesNotes(): Promise<void>;
|
|
304
316
|
updateTempOrderShopDiscount(amount: string | number): string;
|
|
305
317
|
updateTempOrderDepositAmount(amount: string | number): OrderSummary;
|
|
306
318
|
updateTempOrderBuzzer(buzzer: string): string;
|
|
319
|
+
private updateTempOrderShopServiceData;
|
|
320
|
+
updateTempOrderPickupReferenceMode(mode: PickupReferenceMode): ShopServiceData;
|
|
321
|
+
updateTempOrderServiceType(serviceType: ShopServiceType): ShopServiceData;
|
|
307
322
|
updateTempOrderContactsInfo(contactsInfo: Record<string, any> | null): Record<string, any> | null;
|
|
308
323
|
private buildTempOrderCustomer;
|
|
309
324
|
private isCustomerBoundDiscount;
|
|
@@ -454,7 +469,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
454
469
|
removeProductFromOrder(identity: OrderProductIdentity, options?: RemoveProductsFromOrderOptions): Promise<OrderProduct[]>;
|
|
455
470
|
/**
|
|
456
471
|
* 仅清空购物车行(products / bookings),不重置整单。
|
|
457
|
-
*
|
|
472
|
+
* 普通整单 note 保持不变;以商品行为主体的 Sales Notes 同步删除。
|
|
458
473
|
*/
|
|
459
474
|
clearOrderCartLines(): Promise<OrderTempOrder>;
|
|
460
475
|
buildCurrentSubmitPayloadForLocalPrint(params?: {
|
|
@@ -591,4 +606,4 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
591
606
|
getOrderInfo(order_id: number): Promise<any>;
|
|
592
607
|
getVouchers(): any[];
|
|
593
608
|
}
|
|
594
|
-
export type { AddProductToOrderOptions, RemoveProductsFromOrderOptions, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
|
|
609
|
+
export type { AddProductToOrderOptions, RemoveProductsFromOrderOptions, SalesNote, SalesNoteDraftInput, SalesNoteLocalizedSelection, SalesNoteLocalizedText, SalesNoteRelation, SalesNoteTextInput, SetSalesNoteInput, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
|
|
@@ -9,6 +9,7 @@ var _types = require("./types");
|
|
|
9
9
|
var _utils = require("./utils");
|
|
10
10
|
var _utils2 = require("../Product/utils");
|
|
11
11
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
12
|
+
var _salesNotes = require("./salesNotes");
|
|
12
13
|
var _paymentUtils = require("./payment-utils");
|
|
13
14
|
var _paymentNumber = require("../../utils/payment-number");
|
|
14
15
|
var _cartPromotion = require("../../solution/BaseSales/utils/cartPromotion");
|
|
@@ -904,6 +905,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
904
905
|
this.store.tempOrder = {
|
|
905
906
|
...this.store.tempOrder,
|
|
906
907
|
products: [...this.store.tempOrder.products],
|
|
908
|
+
notes: [...(this.store.tempOrder.notes || [])],
|
|
907
909
|
bookings: this.store.tempOrder.bookings ? [...this.store.tempOrder.bookings] : []
|
|
908
910
|
};
|
|
909
911
|
this.persistTempOrder();
|
|
@@ -2236,6 +2238,179 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2236
2238
|
getTempOrderNote() {
|
|
2237
2239
|
return this.store.tempOrder?.note || '';
|
|
2238
2240
|
}
|
|
2241
|
+
ensureSalesNotesRuntimeState(tempOrder) {
|
|
2242
|
+
const hadNotesSnapshot = Array.isArray(tempOrder.notes);
|
|
2243
|
+
if (!Array.isArray(tempOrder.notes)) tempOrder.notes = [];
|
|
2244
|
+
if (!tempOrder._extend || typeof tempOrder._extend !== 'object') {
|
|
2245
|
+
tempOrder._extend = {
|
|
2246
|
+
productsByUid: {}
|
|
2247
|
+
};
|
|
2248
|
+
}
|
|
2249
|
+
if (!tempOrder._extend.salesNotesState) {
|
|
2250
|
+
tempOrder._extend.salesNotesState = {
|
|
2251
|
+
loaded: hadNotesSnapshot,
|
|
2252
|
+
dirty: false
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
return tempOrder._extend.salesNotesState;
|
|
2256
|
+
}
|
|
2257
|
+
ensureSalesNotesLoadedForMutation(tempOrder) {
|
|
2258
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2259
|
+
if (state.loaded) return;
|
|
2260
|
+
if (tempOrder.order_id === null || tempOrder.order_id === undefined) {
|
|
2261
|
+
state.loaded = true;
|
|
2262
|
+
tempOrder.notes = [];
|
|
2263
|
+
return;
|
|
2264
|
+
}
|
|
2265
|
+
throw new Error('[Order Notes] 当前订单 Notes 尚未完整加载,禁止提交部分快照');
|
|
2266
|
+
}
|
|
2267
|
+
normalizeSalesNoteUuid(value, field) {
|
|
2268
|
+
const uuid = String(value ?? '').trim();
|
|
2269
|
+
if (!uuid) throw new Error(`[Order Notes] ${field} 不能为空`);
|
|
2270
|
+
if (uuid.length > 255) {
|
|
2271
|
+
throw new Error(`[Order Notes] ${field} 不能超过 255 个字符`);
|
|
2272
|
+
}
|
|
2273
|
+
return uuid;
|
|
2274
|
+
}
|
|
2275
|
+
getSalesNotePrimaryRelation(note) {
|
|
2276
|
+
return note.note_relations.find(relation => relation.is_primary === 1) || null;
|
|
2277
|
+
}
|
|
2278
|
+
removeSalesNotesForMissingProductLines(tempOrder) {
|
|
2279
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2280
|
+
if (!state.loaded || !Array.isArray(tempOrder.notes) || tempOrder.notes.length === 0) {
|
|
2281
|
+
return;
|
|
2282
|
+
}
|
|
2283
|
+
const remainingProductUids = new Set((tempOrder.products || []).map(product => product.metadata?.unique_identification_number || product.unique_identification_number).filter(uid => typeof uid === 'string' && uid.length > 0));
|
|
2284
|
+
const nextNotes = tempOrder.notes.filter(note => {
|
|
2285
|
+
const primary = this.getSalesNotePrimaryRelation(note);
|
|
2286
|
+
if (!primary || primary.target_type !== 'order_detail') return true;
|
|
2287
|
+
return remainingProductUids.has(primary.target_uuid);
|
|
2288
|
+
});
|
|
2289
|
+
if (nextNotes.length === tempOrder.notes.length) return;
|
|
2290
|
+
tempOrder.notes = nextNotes;
|
|
2291
|
+
state.dirty = true;
|
|
2292
|
+
}
|
|
2293
|
+
setSalesNoteOnTempOrder(tempOrder, input) {
|
|
2294
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
2295
|
+
const note_type = String(input.note_type || '').trim();
|
|
2296
|
+
const policy = (0, _salesNotes.getSalesNotePolicy)(note_type);
|
|
2297
|
+
if (!policy) {
|
|
2298
|
+
throw new Error(`[Order Notes] 当前未注册备注类型: ${note_type || '(empty)'}`);
|
|
2299
|
+
}
|
|
2300
|
+
if (input.target?.target_type !== 'order_detail') {
|
|
2301
|
+
throw new Error('[Order Notes] 本期只支持 order_detail 作为主体');
|
|
2302
|
+
}
|
|
2303
|
+
const target_uuid = this.normalizeSalesNoteUuid(input.target.target_uuid, 'target_uuid');
|
|
2304
|
+
const targetProductExists = (tempOrder.products || []).some(product => {
|
|
2305
|
+
const productLineUid = product.metadata?.unique_identification_number || product.unique_identification_number;
|
|
2306
|
+
return String(productLineUid ?? '') === target_uuid;
|
|
2307
|
+
});
|
|
2308
|
+
if (!targetProductExists) {
|
|
2309
|
+
throw new Error('[Order Notes] 目标商品行不存在');
|
|
2310
|
+
}
|
|
2311
|
+
const text = (0, _salesNotes.buildSalesNoteText)(input.text);
|
|
2312
|
+
const notes = tempOrder.notes || [];
|
|
2313
|
+
// 当前 allergy policy 固定同一商品行只保留一条;业务调用方不参与去重规则。
|
|
2314
|
+
const existingIndex = policy.uniquePerPrimaryTarget ? notes.findIndex(note => {
|
|
2315
|
+
const primary = this.getSalesNotePrimaryRelation(note);
|
|
2316
|
+
return note.note_type === note_type && primary?.target_type === 'order_detail' && primary.target_uuid === target_uuid;
|
|
2317
|
+
}) : -1;
|
|
2318
|
+
const existing = existingIndex >= 0 ? notes[existingIndex] : null;
|
|
2319
|
+
const existingPrimary = existing?.note_relations.find(relation => relation.is_primary === 1 && relation.target_type === 'order_detail');
|
|
2320
|
+
const existingOrderRelation = existing?.note_relations.find(relation => relation.is_primary === 0 && relation.target_type === 'order');
|
|
2321
|
+
const note = {
|
|
2322
|
+
uuid: existing?.uuid || (0, _utils.createUuidV4)(),
|
|
2323
|
+
note_type: policy.note_type,
|
|
2324
|
+
content: {
|
|
2325
|
+
text
|
|
2326
|
+
},
|
|
2327
|
+
importance: policy.importance,
|
|
2328
|
+
note_relations: [{
|
|
2329
|
+
uuid: existingPrimary?.uuid || (0, _utils.createUuidV4)(),
|
|
2330
|
+
relation_type: policy.primary_relation_type,
|
|
2331
|
+
target_type: 'order_detail',
|
|
2332
|
+
target_uuid,
|
|
2333
|
+
is_primary: 1
|
|
2334
|
+
}, {
|
|
2335
|
+
uuid: existingOrderRelation?.uuid || (0, _utils.createUuidV4)(),
|
|
2336
|
+
relation_type: policy.secondary_order_relation_type,
|
|
2337
|
+
target_type: 'order',
|
|
2338
|
+
target_uuid: String(tempOrder.shop_order_number ?? ''),
|
|
2339
|
+
is_primary: 0
|
|
2340
|
+
}]
|
|
2341
|
+
};
|
|
2342
|
+
const duplicateIndex = notes.findIndex((item, index) => item.uuid === note.uuid && index !== existingIndex);
|
|
2343
|
+
if (duplicateIndex >= 0) {
|
|
2344
|
+
throw new Error('[Order Notes] uuid 已被其他 Note 使用');
|
|
2345
|
+
}
|
|
2346
|
+
tempOrder.notes = existingIndex >= 0 ? notes.map((item, index) => index === existingIndex ? note : item) : [...notes, note];
|
|
2347
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2348
|
+
state.loaded = true;
|
|
2349
|
+
state.dirty = true;
|
|
2350
|
+
return note;
|
|
2351
|
+
}
|
|
2352
|
+
getSalesNotes() {
|
|
2353
|
+
const tempOrder = this.ensureTempOrder();
|
|
2354
|
+
this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2355
|
+
return (0, _lodashEs.cloneDeep)(tempOrder.notes || []);
|
|
2356
|
+
}
|
|
2357
|
+
createSalesNotesMutationSnapshot() {
|
|
2358
|
+
const tempOrder = this.ensureTempOrder();
|
|
2359
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2360
|
+
return {
|
|
2361
|
+
orderIdentity: {
|
|
2362
|
+
orderId: tempOrder.order_id ?? null,
|
|
2363
|
+
externalSaleNumber: String(tempOrder.external_sale_number || '')
|
|
2364
|
+
},
|
|
2365
|
+
notes: (0, _lodashEs.cloneDeep)(tempOrder.notes || []),
|
|
2366
|
+
state: (0, _lodashEs.cloneDeep)(state)
|
|
2367
|
+
};
|
|
2368
|
+
}
|
|
2369
|
+
restoreSalesNotesMutationSnapshot(snapshot) {
|
|
2370
|
+
if (!snapshot || !Array.isArray(snapshot.notes) || !snapshot.orderIdentity || typeof snapshot.orderIdentity.externalSaleNumber !== 'string' || typeof snapshot.state?.loaded !== 'boolean' || typeof snapshot.state?.dirty !== 'boolean') {
|
|
2371
|
+
throw new Error('[Order Notes] 无效的 mutation snapshot');
|
|
2372
|
+
}
|
|
2373
|
+
const tempOrder = this.store.tempOrder;
|
|
2374
|
+
if (!tempOrder) throw new Error('[Order Notes] 当前订单不存在');
|
|
2375
|
+
const snapshotOrderId = snapshot.orderIdentity.orderId;
|
|
2376
|
+
const currentOrderId = tempOrder.order_id;
|
|
2377
|
+
const hasSnapshotOrderId = snapshotOrderId !== null && snapshotOrderId !== undefined && String(snapshotOrderId).trim().length > 0;
|
|
2378
|
+
const hasCurrentOrderId = currentOrderId !== null && currentOrderId !== undefined && String(currentOrderId).trim().length > 0;
|
|
2379
|
+
const isSameOrder = hasSnapshotOrderId && hasCurrentOrderId ? String(snapshotOrderId) === String(currentOrderId) : Boolean(snapshot.orderIdentity.externalSaleNumber) && snapshot.orderIdentity.externalSaleNumber === String(tempOrder.external_sale_number || '');
|
|
2380
|
+
if (!isSameOrder) {
|
|
2381
|
+
throw new Error('[Order Notes] 当前订单已切换,拒绝恢复旧订单快照');
|
|
2382
|
+
}
|
|
2383
|
+
this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2384
|
+
tempOrder.notes = (0, _lodashEs.cloneDeep)(snapshot.notes);
|
|
2385
|
+
tempOrder._extend.salesNotesState = (0, _lodashEs.cloneDeep)(snapshot.state);
|
|
2386
|
+
this.notifyTempOrderChanged();
|
|
2387
|
+
}
|
|
2388
|
+
async setSalesNote(input) {
|
|
2389
|
+
const tempOrder = this.ensureTempOrder();
|
|
2390
|
+
const note = this.setSalesNoteOnTempOrder(tempOrder, input);
|
|
2391
|
+
this.notifyTempOrderChanged();
|
|
2392
|
+
return (0, _lodashEs.cloneDeep)(note);
|
|
2393
|
+
}
|
|
2394
|
+
async removeSalesNote(uuid) {
|
|
2395
|
+
const tempOrder = this.ensureTempOrder();
|
|
2396
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
2397
|
+
const normalizedUuid = this.normalizeSalesNoteUuid(uuid, 'uuid');
|
|
2398
|
+
const notes = tempOrder.notes || [];
|
|
2399
|
+
const nextNotes = notes.filter(note => note.uuid !== normalizedUuid);
|
|
2400
|
+
if (nextNotes.length === notes.length) return;
|
|
2401
|
+
tempOrder.notes = nextNotes;
|
|
2402
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2403
|
+
state.dirty = true;
|
|
2404
|
+
this.notifyTempOrderChanged();
|
|
2405
|
+
}
|
|
2406
|
+
async clearSalesNotes() {
|
|
2407
|
+
const tempOrder = this.ensureTempOrder();
|
|
2408
|
+
tempOrder.notes = [];
|
|
2409
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2410
|
+
state.loaded = true;
|
|
2411
|
+
state.dirty = true;
|
|
2412
|
+
this.notifyTempOrderChanged();
|
|
2413
|
+
}
|
|
2239
2414
|
updateTempOrderShopDiscount(amount) {
|
|
2240
2415
|
const tempOrder = this.ensureTempOrder();
|
|
2241
2416
|
const discount = _decimal.default.max(new _decimal.default(Number(amount) || 0), 0).toDecimalPlaces(2).toFixed(2);
|
|
@@ -2275,6 +2450,31 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2275
2450
|
this.persistTempOrder();
|
|
2276
2451
|
return tempOrder.buzzer;
|
|
2277
2452
|
}
|
|
2453
|
+
updateTempOrderShopServiceData(patch) {
|
|
2454
|
+
const tempOrder = this.ensureTempOrder();
|
|
2455
|
+
const metadata = tempOrder.metadata && typeof tempOrder.metadata === 'object' && !Array.isArray(tempOrder.metadata) ? tempOrder.metadata : {};
|
|
2456
|
+
const currentShopServiceData = metadata.shop_service_data && typeof metadata.shop_service_data === 'object' && !Array.isArray(metadata.shop_service_data) ? metadata.shop_service_data : {};
|
|
2457
|
+
const shopServiceData = {
|
|
2458
|
+
...currentShopServiceData,
|
|
2459
|
+
...patch
|
|
2460
|
+
};
|
|
2461
|
+
tempOrder.metadata = {
|
|
2462
|
+
...metadata,
|
|
2463
|
+
shop_service_data: shopServiceData
|
|
2464
|
+
};
|
|
2465
|
+
this.persistTempOrder();
|
|
2466
|
+
return shopServiceData;
|
|
2467
|
+
}
|
|
2468
|
+
updateTempOrderPickupReferenceMode(mode) {
|
|
2469
|
+
return this.updateTempOrderShopServiceData({
|
|
2470
|
+
pickup_reference_mode: mode
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
updateTempOrderServiceType(serviceType) {
|
|
2474
|
+
return this.updateTempOrderShopServiceData({
|
|
2475
|
+
service_type: serviceType
|
|
2476
|
+
});
|
|
2477
|
+
}
|
|
2278
2478
|
updateTempOrderContactsInfo(contactsInfo) {
|
|
2279
2479
|
const tempOrder = this.ensureTempOrder();
|
|
2280
2480
|
tempOrder.contacts_info = contactsInfo && typeof contactsInfo === 'object' && !Array.isArray(contactsInfo) ? contactsInfo : null;
|
|
@@ -2864,6 +3064,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2864
3064
|
const matchedProduct = matchedIndex === -1 ? null : tempOrder.products[matchedIndex];
|
|
2865
3065
|
const existedFingerprint = matchedProduct ? (0, _utils3.buildProductLineFingerprint)((0, _utils.getProductSkuOptions)(matchedProduct), matchedProduct.product_bundle) : '';
|
|
2866
3066
|
const commitProductLine = shouldMerge => {
|
|
3067
|
+
let committedProduct;
|
|
2867
3068
|
if (matchedIndex === -1 || !matchedProduct || !shouldMerge) {
|
|
2868
3069
|
this.captureProductRuntime(tempOrder, productToAdd, normalizedIncoming);
|
|
2869
3070
|
if (linked) {
|
|
@@ -2879,6 +3080,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2879
3080
|
} else {
|
|
2880
3081
|
tempOrder.products = [...tempOrder.products, normalizedIncoming];
|
|
2881
3082
|
}
|
|
3083
|
+
committedProduct = normalizedIncoming;
|
|
2882
3084
|
} else {
|
|
2883
3085
|
const targetProduct = matchedProduct;
|
|
2884
3086
|
const targetUid = targetProduct.metadata?.unique_identification_number;
|
|
@@ -2914,6 +3116,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2914
3116
|
num: nextNum
|
|
2915
3117
|
};
|
|
2916
3118
|
this.captureProductRuntime(tempOrder, productToAdd, tempOrder.products[matchedIndex], targetUid);
|
|
3119
|
+
committedProduct = tempOrder.products[matchedIndex];
|
|
2917
3120
|
if (matchedIndex !== tempOrder.products.length - 1) {
|
|
2918
3121
|
const mergedProduct = tempOrder.products[matchedIndex];
|
|
2919
3122
|
tempOrder.products = [...tempOrder.products.slice(0, matchedIndex), ...tempOrder.products.slice(matchedIndex + 1), mergedProduct];
|
|
@@ -2922,10 +3125,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2922
3125
|
if (linked) {
|
|
2923
3126
|
tempOrder.bookings = [...(tempOrder.bookings || []), linked.booking];
|
|
2924
3127
|
}
|
|
3128
|
+
return committedProduct;
|
|
2925
3129
|
};
|
|
2926
3130
|
if (!matchedProduct) {
|
|
2927
|
-
commitProductLine(false);
|
|
2928
|
-
return;
|
|
3131
|
+
return commitProductLine(false);
|
|
2929
3132
|
}
|
|
2930
3133
|
const shouldMerge = this.shouldMergeProductToOrder({
|
|
2931
3134
|
incomingProduct: productToAdd,
|
|
@@ -2940,7 +3143,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2940
3143
|
if (shouldMerge && typeof shouldMerge === 'object' && typeof shouldMerge.then === 'function') {
|
|
2941
3144
|
return Promise.resolve(shouldMerge).then(commitProductLine);
|
|
2942
3145
|
}
|
|
2943
|
-
commitProductLine(shouldMerge);
|
|
3146
|
+
return commitProductLine(shouldMerge);
|
|
2944
3147
|
}
|
|
2945
3148
|
|
|
2946
3149
|
/**
|
|
@@ -2952,36 +3155,102 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2952
3155
|
*/
|
|
2953
3156
|
async addProductToOrder(product, booking, options) {
|
|
2954
3157
|
const tempOrder = this.ensureTempOrder();
|
|
3158
|
+
const salesNoteDrafts = (options?.salesNotes || []).map(draft => ({
|
|
3159
|
+
note_type: String(draft.note_type || '').trim(),
|
|
3160
|
+
text: {
|
|
3161
|
+
kind: 'resolved',
|
|
3162
|
+
text: (0, _salesNotes.buildSalesNoteText)(draft.text)
|
|
3163
|
+
}
|
|
3164
|
+
}));
|
|
3165
|
+
const mutationSnapshot = salesNoteDrafts.length > 0 ? {
|
|
3166
|
+
products: (0, _lodashEs.cloneDeep)(tempOrder.products || []),
|
|
3167
|
+
bookings: (0, _lodashEs.cloneDeep)(tempOrder.bookings || []),
|
|
3168
|
+
notes: (0, _lodashEs.cloneDeep)(tempOrder.notes || []),
|
|
3169
|
+
extend: (0, _lodashEs.cloneDeep)(tempOrder._extend || {})
|
|
3170
|
+
} : null;
|
|
3171
|
+
const attachSalesNoteDrafts = orderProduct => {
|
|
3172
|
+
if (!salesNoteDrafts.length) return;
|
|
3173
|
+
const productLineUid = orderProduct.metadata?.unique_identification_number || orderProduct.unique_identification_number;
|
|
3174
|
+
if (!productLineUid) {
|
|
3175
|
+
throw new Error('[Order Notes] 商品行缺少 unique_identification_number');
|
|
3176
|
+
}
|
|
3177
|
+
salesNoteDrafts.forEach(draft => {
|
|
3178
|
+
this.setSalesNoteOnTempOrder(tempOrder, {
|
|
3179
|
+
note_type: draft.note_type,
|
|
3180
|
+
target: {
|
|
3181
|
+
target_type: 'order_detail',
|
|
3182
|
+
target_uuid: String(productLineUid)
|
|
3183
|
+
},
|
|
3184
|
+
text: draft.text
|
|
3185
|
+
});
|
|
3186
|
+
});
|
|
3187
|
+
};
|
|
3188
|
+
const rollbackProductAndNotesMutation = () => {
|
|
3189
|
+
if (!mutationSnapshot) return;
|
|
3190
|
+
tempOrder.products = mutationSnapshot.products;
|
|
3191
|
+
tempOrder.bookings = mutationSnapshot.bookings;
|
|
3192
|
+
tempOrder.notes = mutationSnapshot.notes;
|
|
3193
|
+
tempOrder._extend = mutationSnapshot.extend;
|
|
3194
|
+
};
|
|
2955
3195
|
const insertAfterProductUid = options?.insertAfterProductUid;
|
|
2956
3196
|
const anchorIndex = booking && insertAfterProductUid ? tempOrder.products.findIndex(line => {
|
|
2957
3197
|
const uid = line.metadata?.unique_identification_number || line.unique_identification_number;
|
|
2958
3198
|
return uid !== undefined && uid !== null && String(uid) === String(insertAfterProductUid);
|
|
2959
3199
|
}) : -1;
|
|
2960
3200
|
let insertAtIndex = anchorIndex >= 0 ? anchorIndex + 1 : undefined;
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
3201
|
+
try {
|
|
3202
|
+
if (booking) {
|
|
3203
|
+
const productRecord = product;
|
|
3204
|
+
const splitCount = (0, _utils3.getSafeProductNum)(productRecord.num ?? productRecord.product_quantity ?? 1);
|
|
3205
|
+
if (splitCount > 1) {
|
|
3206
|
+
for (let i = 0; i < splitCount; i += 1) {
|
|
3207
|
+
const singleLine = (0, _lodashEs.cloneDeep)(productRecord);
|
|
3208
|
+
const singleBooking = (0, _lodashEs.cloneDeep)(booking);
|
|
3209
|
+
singleLine.num = 1;
|
|
3210
|
+
delete singleLine.product_quantity;
|
|
3211
|
+
if (i > 0) {
|
|
3212
|
+
delete singleLine.unique_identification_number;
|
|
3213
|
+
delete singleLine.identity_key;
|
|
3214
|
+
if (singleLine.metadata) {
|
|
3215
|
+
singleLine.metadata = {
|
|
3216
|
+
...singleLine.metadata
|
|
3217
|
+
};
|
|
3218
|
+
delete singleLine.metadata.unique_identification_number;
|
|
3219
|
+
delete singleLine.metadata.identity_key;
|
|
3220
|
+
}
|
|
3221
|
+
delete singleBooking.booking_uid;
|
|
3222
|
+
if (singleBooking.metadata) {
|
|
3223
|
+
singleBooking.metadata = {
|
|
3224
|
+
...singleBooking.metadata
|
|
3225
|
+
};
|
|
3226
|
+
delete singleBooking.metadata.unique_identification_number;
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
const committedProduct = await this.appendProductLineToTempOrder(tempOrder, singleLine, singleBooking, {
|
|
3230
|
+
insertAtIndex,
|
|
3231
|
+
disableMerge: options?.disableMerge
|
|
3232
|
+
});
|
|
3233
|
+
attachSalesNoteDrafts(committedProduct);
|
|
3234
|
+
if (insertAtIndex !== undefined) insertAtIndex += 1;
|
|
3235
|
+
}
|
|
3236
|
+
} else {
|
|
3237
|
+
const committedProduct = await this.appendProductLineToTempOrder(tempOrder, product, (0, _lodashEs.cloneDeep)(booking), {
|
|
2970
3238
|
insertAtIndex,
|
|
2971
3239
|
disableMerge: options?.disableMerge
|
|
2972
3240
|
});
|
|
2973
|
-
|
|
2974
|
-
if (insertAtIndex !== undefined) insertAtIndex += 1;
|
|
3241
|
+
attachSalesNoteDrafts(committedProduct);
|
|
2975
3242
|
}
|
|
2976
|
-
|
|
2977
|
-
|
|
3243
|
+
} else {
|
|
3244
|
+
const committedProduct = await this.appendProductLineToTempOrder(tempOrder, product, undefined, {
|
|
3245
|
+
insertAtIndex,
|
|
3246
|
+
disableMerge: options?.disableMerge
|
|
3247
|
+
});
|
|
3248
|
+
attachSalesNoteDrafts(committedProduct);
|
|
2978
3249
|
}
|
|
3250
|
+
} catch (error) {
|
|
3251
|
+
rollbackProductAndNotesMutation();
|
|
3252
|
+
throw error;
|
|
2979
3253
|
}
|
|
2980
|
-
const appendResult = this.appendProductLineToTempOrder(tempOrder, product, booking, {
|
|
2981
|
-
insertAtIndex,
|
|
2982
|
-
disableMerge: options?.disableMerge
|
|
2983
|
-
});
|
|
2984
|
-
if (appendResult) await appendResult;
|
|
2985
3254
|
await this.finalizeProductOrderMutation(tempOrder);
|
|
2986
3255
|
this.logInfo('addProductToOrder success', {
|
|
2987
3256
|
product_id: product.product_id,
|
|
@@ -3426,10 +3695,12 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3426
3695
|
*/
|
|
3427
3696
|
async removeProductsFromOrder(identities, options) {
|
|
3428
3697
|
const tempOrder = this.ensureTempOrder();
|
|
3429
|
-
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
3430
3698
|
if (!identities.length) {
|
|
3431
3699
|
return tempOrder.products;
|
|
3432
3700
|
}
|
|
3701
|
+
// 商品删除会同步删除以商品行为主关系的 Notes;快照不完整时禁止产生孤儿 Relation。
|
|
3702
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
3703
|
+
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
3433
3704
|
const productsBeforeRemove = tempOrder.products || [];
|
|
3434
3705
|
const bookingsBeforeRemove = tempOrder.bookings || [];
|
|
3435
3706
|
const preserveDisplayPosition = options?.preserveDisplayPosition;
|
|
@@ -3489,6 +3760,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3489
3760
|
tempOrder.products = nextProductIndex >= 0 ? [...productsWithoutRemaining.slice(0, nextProductIndex), remainingProduct, ...productsWithoutRemaining.slice(nextProductIndex)] : [...productsWithoutRemaining, remainingProduct];
|
|
3490
3761
|
}
|
|
3491
3762
|
}
|
|
3763
|
+
this.removeSalesNotesForMissingProductLines(tempOrder);
|
|
3492
3764
|
await this.finalizeAfterProductsMutation(tempOrder);
|
|
3493
3765
|
this.logInfo('removeProductsFromOrder success', {
|
|
3494
3766
|
identities
|
|
@@ -3501,12 +3773,14 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3501
3773
|
|
|
3502
3774
|
/**
|
|
3503
3775
|
* 仅清空购物车行(products / bookings),不重置整单。
|
|
3504
|
-
*
|
|
3776
|
+
* 普通整单 note 保持不变;以商品行为主体的 Sales Notes 同步删除。
|
|
3505
3777
|
*/
|
|
3506
3778
|
async clearOrderCartLines() {
|
|
3507
3779
|
const tempOrder = this.ensureTempOrder();
|
|
3780
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
3508
3781
|
tempOrder.products = [];
|
|
3509
3782
|
tempOrder.bookings = [];
|
|
3783
|
+
this.removeSalesNotesForMissingProductLines(tempOrder);
|
|
3510
3784
|
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
3511
3785
|
if (tempOrder._extend && typeof tempOrder._extend === 'object') {
|
|
3512
3786
|
tempOrder._extend = {
|
|
@@ -3709,6 +3983,12 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3709
3983
|
this.logSubmitBackendRejected(result, payload);
|
|
3710
3984
|
return result;
|
|
3711
3985
|
}
|
|
3986
|
+
const isLocalPendingSubmit = this.isLocalPendingSubmitResult(result);
|
|
3987
|
+
// need_sync=1 仅表示已进入本地同步队列,不能视为远端已确认 Notes。
|
|
3988
|
+
if (Object.prototype.hasOwnProperty.call(payload, 'notes') && !isLocalPendingSubmit) {
|
|
3989
|
+
const salesNotesState = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
3990
|
+
salesNotesState.dirty = false;
|
|
3991
|
+
}
|
|
3712
3992
|
const submittedOrderId = this.extractOrderIdFromSubmitResult(result);
|
|
3713
3993
|
this.logInfo('runSubmitTempOrder: 提交成功', {
|
|
3714
3994
|
submittedOrderId,
|
|
@@ -3722,9 +4002,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3722
4002
|
tempOrder.order_id = submittedOrderId;
|
|
3723
4003
|
const resultRecord = result;
|
|
3724
4004
|
await this.markLocalOrderSynced(submittedOrderId, resultRecord?.data || resultRecord || {});
|
|
3725
|
-
}
|
|
4005
|
+
}
|
|
4006
|
+
if (isLocalPendingSubmit) {
|
|
3726
4007
|
this.store.syncState = 'local';
|
|
3727
|
-
} else {
|
|
4008
|
+
} else if (submittedOrderId === null || submittedOrderId === undefined) {
|
|
3728
4009
|
this.store.syncState = 'submitted';
|
|
3729
4010
|
}
|
|
3730
4011
|
return result;
|
|
@@ -4110,7 +4391,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4110
4391
|
params.forceRemote = false;
|
|
4111
4392
|
}
|
|
4112
4393
|
const res = await this.request.get(`/order/sales/${encodeURIComponent(lookup)}`, {
|
|
4113
|
-
with: ['products', 'bookings', 'payments', 'customer', 'summary', 'contacts_info', 'refunds'],
|
|
4394
|
+
with: ['products', 'bookings', 'payments', 'customer', 'summary', 'contacts_info', 'refunds', 'notes'],
|
|
4114
4395
|
...(params.forceRemote ? {
|
|
4115
4396
|
forceRemote: true
|
|
4116
4397
|
} : {})
|
|
@@ -4163,7 +4444,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4163
4444
|
const isMergedSalesDetailHydrate = options?.source === 'mergedSalesDetail';
|
|
4164
4445
|
const nextTempOrder = this.normalizeTempOrderForRuntime(raw, {
|
|
4165
4446
|
// merge 前已只给远端商品补标记;这里不能把本地未提交商品一并变成 saved item。
|
|
4166
|
-
makeEditMark: !isSessionStorageHydrate && !isMergedSalesDetailHydrate
|
|
4447
|
+
makeEditMark: !isSessionStorageHydrate && !isMergedSalesDetailHydrate,
|
|
4448
|
+
allowUnresolvedSalesNotes: isSessionStorageHydrate
|
|
4167
4449
|
});
|
|
4168
4450
|
this.store.tempOrder = nextTempOrder;
|
|
4169
4451
|
if (isSessionStorageHydrate) {
|
|
@@ -4385,6 +4667,17 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4385
4667
|
nextTempOrder.payments = Array.isArray(raw.payments) ? raw.payments.map(p => ({
|
|
4386
4668
|
...(p || {})
|
|
4387
4669
|
})) : [];
|
|
4670
|
+
const rawHasSalesNotes = Object.prototype.hasOwnProperty.call(raw, 'notes');
|
|
4671
|
+
const restoredSalesNotesState = raw._extend?.salesNotesState;
|
|
4672
|
+
const allowUnresolvedSalesNotes = options?.allowUnresolvedSalesNotes === true || restoredSalesNotesState?.dirty === true || Number(raw.is_draft_order || 0) === 1;
|
|
4673
|
+
const decodedSalesNotes = rawHasSalesNotes ? (0, _salesNotes.decodeSalesNotesSnapshot)(raw.notes, {
|
|
4674
|
+
allowUnresolvedOrderTarget: allowUnresolvedSalesNotes
|
|
4675
|
+
}) : {
|
|
4676
|
+
notes: [],
|
|
4677
|
+
complete: false
|
|
4678
|
+
};
|
|
4679
|
+
const hasUnresolvedSalesNoteOrderTarget = decodedSalesNotes.notes.some(note => note.note_relations.some(relation => relation.is_primary === 0 && relation.relation_type === 'related_to' && relation.target_type === 'order' && relation.target_uuid === ''));
|
|
4680
|
+
nextTempOrder.notes = decodedSalesNotes.notes;
|
|
4388
4681
|
nextTempOrder.surcharges = Array.isArray(raw.surcharges) ? raw.surcharges.map(s => ({
|
|
4389
4682
|
...(s || {})
|
|
4390
4683
|
})) : [];
|
|
@@ -4404,6 +4697,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4404
4697
|
productsByUid: {}
|
|
4405
4698
|
};
|
|
4406
4699
|
const tempOrderExtend = nextTempOrder._extend;
|
|
4700
|
+
tempOrderExtend.salesNotesState = {
|
|
4701
|
+
loaded: rawHasSalesNotes ? decodedSalesNotes.complete : restoredSalesNotesState?.loaded === true,
|
|
4702
|
+
dirty: decodedSalesNotes.complete && (restoredSalesNotesState?.dirty === true || allowUnresolvedSalesNotes && hasUnresolvedSalesNoteOrderTarget)
|
|
4703
|
+
};
|
|
4407
4704
|
const productsByUid = tempOrderExtend.productsByUid || {};
|
|
4408
4705
|
for (const [index, product] of nextTempOrder.products.entries()) {
|
|
4409
4706
|
const uid = product.metadata?.unique_identification_number;
|
|
@@ -4578,7 +4875,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4578
4875
|
}
|
|
4579
4876
|
async getOrderInfo(order_id) {
|
|
4580
4877
|
const res = await this.request.get(`/order/sales/${order_id}`, {
|
|
4581
|
-
with: ['products', 'bookings']
|
|
4878
|
+
with: ['products', 'bookings', 'notes']
|
|
4582
4879
|
}, {
|
|
4583
4880
|
osServer: true
|
|
4584
4881
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SalesNote, SalesNoteProtocol, SalesNoteTextInput } from './types';
|
|
2
|
+
export interface SalesNotePolicy {
|
|
3
|
+
note_type: string;
|
|
4
|
+
importance: string;
|
|
5
|
+
uniquePerPrimaryTarget: boolean;
|
|
6
|
+
primary_relation_type: 'about';
|
|
7
|
+
secondary_order_relation_type: 'related_to';
|
|
8
|
+
}
|
|
9
|
+
export declare function getSalesNotePolicy(note_type: string): SalesNotePolicy | null;
|
|
10
|
+
export declare function buildSalesNoteText(input: SalesNoteTextInput): Record<string, string>;
|
|
11
|
+
export interface SalesNoteValidationOptions {
|
|
12
|
+
allowUnresolvedOrderTarget?: boolean;
|
|
13
|
+
expectedOrderTargetUuid?: string;
|
|
14
|
+
productTargetUuids?: ReadonlySet<string>;
|
|
15
|
+
}
|
|
16
|
+
export type EncodeSalesNotesOptions = SalesNoteValidationOptions;
|
|
17
|
+
export declare function encodeSalesNotes(notes: SalesNote[], options?: EncodeSalesNotesOptions): SalesNoteProtocol[];
|
|
18
|
+
export interface DecodedSalesNotesSnapshot {
|
|
19
|
+
notes: SalesNote[];
|
|
20
|
+
complete: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface DecodeSalesNotesOptions {
|
|
23
|
+
allowUnresolvedOrderTarget?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function decodeSalesNotesSnapshot(value: unknown, options?: DecodeSalesNotesOptions): DecodedSalesNotesSnapshot;
|
|
26
|
+
export declare function decodeSalesNotes(value: unknown, options?: DecodeSalesNotesOptions): SalesNote[];
|
|
27
|
+
export declare function finalizeSalesNotesForCheckout(params: {
|
|
28
|
+
notes: unknown;
|
|
29
|
+
shopOrderNumber: unknown;
|
|
30
|
+
productTargetUuids: string[];
|
|
31
|
+
}): SalesNoteProtocol[];
|