@pisell/pisellos 0.10.43 → 0.10.45
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/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 +9 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.js +4 -2
- package/dist/modules/Customer/index.js +2 -1
- package/dist/modules/Discount/availability.d.ts +7 -0
- package/dist/modules/Discount/availability.js +49 -0
- package/dist/modules/Discount/index.d.ts +1 -3
- package/dist/modules/Discount/index.js +12 -151
- package/dist/modules/Discount/types.d.ts +6 -0
- package/dist/modules/Order/index.d.ts +41 -9
- package/dist/modules/Order/index.js +1457 -872
- package/dist/modules/Order/salesNotes.d.ts +31 -0
- package/dist/modules/Order/salesNotes.js +492 -0
- package/dist/modules/Order/types.d.ts +105 -8
- package/dist/modules/Order/types.js +6 -1
- package/dist/modules/Order/utils.d.ts +4 -2
- package/dist/modules/Order/utils.js +224 -79
- package/dist/modules/Payment/cashRecommendationAlgorithm.d.ts +4 -5
- package/dist/modules/Payment/cashRecommendationAlgorithm.js +17 -367
- package/dist/modules/Product/index.d.ts +1 -1
- package/dist/modules/ProductList/index.d.ts +2 -1
- package/dist/modules/ProductList/index.js +100 -20
- package/dist/modules/ProductList/types.d.ts +10 -0
- package/dist/modules/Rules/index.js +50 -16
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +45 -3
- package/dist/server/modules/order/index.js +6 -0
- package/dist/server/modules/order/types.d.ts +9 -0
- package/dist/server/utils/small-ticket.d.ts +1 -0
- package/dist/server/utils/small-ticket.js +142 -14
- package/dist/solution/BaseSales/index.d.ts +15 -1
- package/dist/solution/BaseSales/index.js +1240 -877
- package/dist/solution/BaseSales/types.d.ts +2 -2
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +1 -0
- package/dist/solution/BookingTicket/index.js +37 -16
- 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/utils.d.ts +1 -0
- package/dist/solution/ScanOrder/utils.js +2 -0
- package/dist/solution/ShopDiscount/index.d.ts +1 -0
- package/dist/solution/ShopDiscount/index.js +59 -22
- package/dist/solution/ShopDiscount/utils.d.ts +4 -2
- package/dist/solution/ShopDiscount/utils.js +40 -21
- package/dist/solution/UnifiedBookingSales/index.d.ts +15 -2
- package/dist/solution/UnifiedBookingSales/index.js +777 -510
- package/dist/solution/UnifiedBookingSales/types.d.ts +14 -1
- package/dist/solution/VenueBooking/index.d.ts +1 -0
- package/dist/solution/VenueBooking/index.js +8 -4
- 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/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
- package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -0
- package/lib/modules/Customer/index.js +1 -0
- package/lib/modules/Discount/availability.d.ts +7 -0
- package/lib/modules/Discount/availability.js +43 -0
- package/lib/modules/Discount/index.d.ts +1 -3
- package/lib/modules/Discount/index.js +10 -131
- package/lib/modules/Discount/types.d.ts +6 -0
- package/lib/modules/Order/index.d.ts +41 -9
- package/lib/modules/Order/index.js +456 -69
- package/lib/modules/Order/salesNotes.d.ts +31 -0
- package/lib/modules/Order/salesNotes.js +382 -0
- package/lib/modules/Order/types.d.ts +105 -8
- package/lib/modules/Order/types.js +5 -1
- package/lib/modules/Order/utils.d.ts +4 -2
- package/lib/modules/Order/utils.js +134 -3
- package/lib/modules/Payment/cashRecommendationAlgorithm.d.ts +4 -5
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +9 -354
- package/lib/modules/Product/index.d.ts +1 -1
- package/lib/modules/ProductList/index.d.ts +2 -1
- package/lib/modules/ProductList/index.js +47 -2
- package/lib/modules/ProductList/types.d.ts +10 -0
- package/lib/modules/Rules/index.js +42 -5
- package/lib/server/index.d.ts +7 -0
- package/lib/server/index.js +39 -3
- package/lib/server/modules/order/index.js +6 -0
- package/lib/server/modules/order/types.d.ts +9 -0
- package/lib/server/utils/small-ticket.d.ts +1 -0
- package/lib/server/utils/small-ticket.js +136 -12
- package/lib/solution/BaseSales/index.d.ts +15 -1
- package/lib/solution/BaseSales/index.js +192 -22
- package/lib/solution/BaseSales/types.d.ts +2 -2
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +1 -0
- package/lib/solution/BookingTicket/index.js +23 -5
- 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/utils.d.ts +1 -0
- package/lib/solution/ScanOrder/utils.js +1 -0
- package/lib/solution/ShopDiscount/index.d.ts +1 -0
- package/lib/solution/ShopDiscount/index.js +29 -3
- package/lib/solution/ShopDiscount/utils.d.ts +4 -2
- package/lib/solution/ShopDiscount/utils.js +39 -23
- package/lib/solution/UnifiedBookingSales/index.d.ts +15 -2
- package/lib/solution/UnifiedBookingSales/index.js +125 -1
- package/lib/solution/UnifiedBookingSales/types.d.ts +14 -1
- package/lib/solution/VenueBooking/index.d.ts +1 -0
- package/lib/solution/VenueBooking/index.js +5 -1
- package/package.json +1 -1
|
@@ -9,7 +9,9 @@ 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 _availability = require("../Discount/availability");
|
|
12
13
|
var _osPrivatePayload = require("../../utils/os-private-payload");
|
|
14
|
+
var _salesNotes = require("./salesNotes");
|
|
13
15
|
var _paymentUtils = require("./payment-utils");
|
|
14
16
|
var _paymentNumber = require("../../utils/payment-number");
|
|
15
17
|
var _cartPromotion = require("../../solution/BaseSales/utils/cartPromotion");
|
|
@@ -126,6 +128,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
126
128
|
openCache = false;
|
|
127
129
|
sessionStoragePersistEnabled = false;
|
|
128
130
|
sessionStorageRestoreRecord = null;
|
|
131
|
+
/** 只允许当前订单最新的 prepare/config 请求回写客户资产态。 */
|
|
132
|
+
customerWalletPrepareConfigEpoch = 0;
|
|
129
133
|
salesSummaryModuleName;
|
|
130
134
|
rulesHooksOverride;
|
|
131
135
|
moduleHooksOverride;
|
|
@@ -136,8 +140,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
136
140
|
promotionEvaluator = null;
|
|
137
141
|
/** 赠品选择 resolver;由 SDK host bridge 注入 */
|
|
138
142
|
giftSelectResolver = null;
|
|
139
|
-
/**
|
|
143
|
+
/** 促销评估递归保护 flag(写路径同步评估促销,禁止重入) */
|
|
140
144
|
isApplyingPromotion = false;
|
|
145
|
+
/** 保持旧事件语义:同步事件监听器内触发的订单写入不得递归评估促销。 */
|
|
146
|
+
isEmittingPromotionApplied = false;
|
|
141
147
|
/** 商品曾应用过客户券卡,客户变更剥离后需强制跑一次 calcDiscount 复位价格 */
|
|
142
148
|
hasActiveCustomerBoundDiscount = false;
|
|
143
149
|
/** 最近一次 applyPromotion 的未满足促销提示 */
|
|
@@ -491,13 +497,24 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
491
497
|
this.store.rules = rules;
|
|
492
498
|
}
|
|
493
499
|
createDefaultRulesHooks() {
|
|
494
|
-
return (0, _utils.createDefaultOrderRulesHooks)();
|
|
500
|
+
return (0, _utils.createDefaultOrderRulesHooks)(() => this.store.tempOrder?.bookings || []);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Stable across notifyTempOrderChanged's immutable copy, but changes when a
|
|
505
|
+
* different local/server order becomes current.
|
|
506
|
+
*/
|
|
507
|
+
getDiscountConfigOrderIdentityKey(tempOrder) {
|
|
508
|
+
const identity = this.getOrderIdentity();
|
|
509
|
+
return JSON.stringify([identity?.orderId ?? tempOrder?.order_id ?? '', tempOrder?.request_unique_idempotency_token ?? '', identity?.externalSaleNumber ?? tempOrder?.external_sale_number ?? '', identity?.localId ?? tempOrder?._extend?.localId ?? this.cacheId ?? '']);
|
|
495
510
|
}
|
|
496
511
|
|
|
497
512
|
// ─── Discount: 公共 API ───
|
|
498
513
|
|
|
499
514
|
async loadDiscountConfig(params) {
|
|
500
515
|
const orderId = params.orderId || this.store.tempOrder?.order_id || undefined;
|
|
516
|
+
const requestEpoch = ++this.customerWalletPrepareConfigEpoch;
|
|
517
|
+
const requestOrderIdentityKey = this.getDiscountConfigOrderIdentityKey(this.store.tempOrder);
|
|
501
518
|
const prepareConfigResult = await this.store.discount?.loadPrepareConfig({
|
|
502
519
|
customer_id: params.customerId,
|
|
503
520
|
action: params.action || (orderId ? 'edit' : 'create'),
|
|
@@ -508,18 +525,23 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
508
525
|
with_available_wallet_pass_flag: 1,
|
|
509
526
|
with_virtual_currency: 1,
|
|
510
527
|
with_entitlement_pass: 1,
|
|
528
|
+
filter_order_wallet_pass_usage: 0,
|
|
511
529
|
request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
512
530
|
...(orderId ? {
|
|
513
531
|
order_id: orderId
|
|
514
532
|
} : {})
|
|
515
533
|
});
|
|
534
|
+
const isCurrentRequest = () => requestEpoch === this.customerWalletPrepareConfigEpoch && this.getDiscountConfigOrderIdentityKey(this.store.tempOrder) === requestOrderIdentityKey && String(this.store.tempOrder?.customer_id ?? '') === String(params.customerId);
|
|
535
|
+
if (!isCurrentRequest()) {
|
|
536
|
+
return this.getDiscountList();
|
|
537
|
+
}
|
|
516
538
|
const discountList = prepareConfigResult?.discountList;
|
|
517
|
-
this.store.availableWalletIds = prepareConfigResult?.availableWalletIds || [];
|
|
518
|
-
this.store.virtualCurrencyList = prepareConfigResult?.virtualCurrencyList || [];
|
|
519
539
|
if (prepareConfigResult) {
|
|
520
|
-
this.
|
|
540
|
+
this.writeCustomerWalletSnapshotsFromPrepareConfig({
|
|
521
541
|
customerId: params.customerId,
|
|
522
|
-
|
|
542
|
+
availableWalletIds: prepareConfigResult.availableWalletIds || [],
|
|
543
|
+
availableWalletPassList: prepareConfigResult.availableWalletPassList || [],
|
|
544
|
+
virtualCurrencyList: prepareConfigResult.virtualCurrencyList || []
|
|
523
545
|
});
|
|
524
546
|
}
|
|
525
547
|
if (discountList) {
|
|
@@ -579,9 +601,12 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
579
601
|
return id === null || !refreshedScanDiscountIds.has(id);
|
|
580
602
|
});
|
|
581
603
|
const mergedDiscountList = [...retainedCommittedDiscounts, ...retainedScanDiscounts, ...runtimeDiscounts];
|
|
604
|
+
if (!isCurrentRequest()) return this.getDiscountList();
|
|
582
605
|
await this.store.discount?.setOriginalDiscountList(mergedDiscountList);
|
|
606
|
+
if (!isCurrentRequest()) return this.getDiscountList();
|
|
583
607
|
await this.store.discount?.setDiscountList(mergedDiscountList);
|
|
584
608
|
}
|
|
609
|
+
if (!isCurrentRequest()) return this.getDiscountList();
|
|
585
610
|
if (params.apply !== false && this.store.tempOrder?.products?.length) {
|
|
586
611
|
this.applyDiscount();
|
|
587
612
|
}
|
|
@@ -596,6 +621,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
596
621
|
getVirtualCurrencyList() {
|
|
597
622
|
return (0, _lodashEs.cloneDeep)(this.store.virtualCurrencyList || []);
|
|
598
623
|
}
|
|
624
|
+
getCustomerWalletPrepareConfigEpoch() {
|
|
625
|
+
return this.customerWalletPrepareConfigEpoch;
|
|
626
|
+
}
|
|
599
627
|
async syncScannedDiscountsToOriginalDiscountList(discountList) {
|
|
600
628
|
const scanDiscounts = (discountList || []).filter(discount => discount?.isScan);
|
|
601
629
|
if (!scanDiscounts.length) return;
|
|
@@ -693,19 +721,31 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
693
721
|
isAvailable: false,
|
|
694
722
|
discountList: this.getDiscountList()
|
|
695
723
|
};
|
|
696
|
-
const
|
|
724
|
+
const scannedIds = new Set(withScanList.map(discount => String(discount.id)));
|
|
725
|
+
const evaluatedScannedDiscounts = (evaluatedDiscountList || withScanList).filter(discount => scannedIds.has(String(discount.id)) && isCustomerPromotionDiscount(discount) && !(0, _availability.getDiscountLifecycleReason)(discount));
|
|
726
|
+
const shouldRetainForLater = !isAvailable && evaluatedScannedDiscounts.length > 0;
|
|
697
727
|
const normalizedNewDiscountList = newDiscountList ? markScannedDiscounts(newDiscountList, withScanList) : undefined;
|
|
698
|
-
const retainedDiscountList = evaluatedDiscountList ? markScannedDiscounts(evaluatedDiscountList, withScanList) : normalizedNewDiscountList;
|
|
699
728
|
let resolvedDiscountList = normalizedNewDiscountList || this.getDiscountList();
|
|
700
729
|
if (isAvailable && normalizedNewDiscountList) {
|
|
701
730
|
await this.store.discount?.setDiscountList(normalizedNewDiscountList);
|
|
702
731
|
this.applyDiscount();
|
|
703
732
|
await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
|
|
704
733
|
resolvedDiscountList = this.getDiscountList();
|
|
705
|
-
} else if (shouldRetainForLater
|
|
706
|
-
//
|
|
707
|
-
|
|
708
|
-
|
|
734
|
+
} else if (shouldRetainForLater) {
|
|
735
|
+
// 只合并本次识别的卡券;不把试算产生的其他选券状态写回订单。
|
|
736
|
+
const retainedDiscounts = new Map(this.getDiscountList().map(discount => [String(discount.id), discount]));
|
|
737
|
+
evaluatedScannedDiscounts.forEach(discount => {
|
|
738
|
+
retainedDiscounts.set(String(discount.id), {
|
|
739
|
+
...discount,
|
|
740
|
+
isScan: true,
|
|
741
|
+
isAvailable: false,
|
|
742
|
+
isSelected: false,
|
|
743
|
+
reasonCode: discount.reasonCode || 'product_not_applicable',
|
|
744
|
+
appliedProductDetails: [],
|
|
745
|
+
savedAmount: 0
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
await this.store.discount?.setDiscountList([...retainedDiscounts.values()]);
|
|
709
749
|
await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
|
|
710
750
|
resolvedDiscountList = this.getDiscountList();
|
|
711
751
|
}
|
|
@@ -714,7 +754,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
714
754
|
isAvailable: isAvailable || false,
|
|
715
755
|
isAccepted: Boolean(isAvailable || shouldRetainForLater),
|
|
716
756
|
discountList: resolvedDiscountList,
|
|
717
|
-
scannedDiscountList:
|
|
757
|
+
scannedDiscountList: evaluatedScannedDiscounts,
|
|
718
758
|
unavailableReason
|
|
719
759
|
};
|
|
720
760
|
}
|
|
@@ -808,7 +848,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
808
848
|
}
|
|
809
849
|
|
|
810
850
|
/**
|
|
811
|
-
*
|
|
851
|
+
* 只执行购物车促销评估与赠品写回,不发布稳定态事件。
|
|
812
852
|
*
|
|
813
853
|
* 调用时机:写路径(add/update/remove/clear/setCustomer)末尾自动触发;外部一般无需手动调。
|
|
814
854
|
*
|
|
@@ -816,26 +856,27 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
816
856
|
* - 不调用任何公开 CRUD API(如 removeProductFromOrder),全部内部 mutate tempOrder.products,避免事件风暴;
|
|
817
857
|
* - 用 `isApplyingPromotion` 防递归;
|
|
818
858
|
* - 多选项赠品依赖 giftSelectResolver,未注入则跳过且 console.warn;
|
|
819
|
-
* - 不主动调用 applyDiscount / recalculateSummary
|
|
859
|
+
* - 不主动调用 applyDiscount / recalculateSummary,调用方负责跟进;
|
|
860
|
+
* - 返回的 payload 只能在 applyDiscount(商品写路径还需 summary/persist)完成后发布。
|
|
820
861
|
*/
|
|
821
|
-
async
|
|
822
|
-
if (this.isApplyingPromotion) {
|
|
823
|
-
return;
|
|
862
|
+
async evaluatePromotion() {
|
|
863
|
+
if (this.isApplyingPromotion || this.isEmittingPromotionApplied) {
|
|
864
|
+
return null;
|
|
824
865
|
}
|
|
825
866
|
if (!this.promotionEvaluator) {
|
|
826
|
-
return;
|
|
867
|
+
return null;
|
|
827
868
|
}
|
|
828
869
|
const tempOrder = this.store.tempOrder;
|
|
829
870
|
if (!tempOrder) {
|
|
830
|
-
return;
|
|
871
|
+
return null;
|
|
831
872
|
}
|
|
832
873
|
if (this.isActiveVirtualSettlementOrder(tempOrder)) {
|
|
833
874
|
tempOrder.products = (0, _virtualSettlement.normalizeVirtualSettlementProducts)(tempOrder.products);
|
|
834
|
-
return;
|
|
875
|
+
return null;
|
|
835
876
|
}
|
|
836
877
|
const strategyConfigs = this.promotionEvaluator.getStrategyConfigs?.();
|
|
837
878
|
if (Array.isArray(strategyConfigs) && strategyConfigs.length === 0) {
|
|
838
|
-
return;
|
|
879
|
+
return null;
|
|
839
880
|
}
|
|
840
881
|
this.isApplyingPromotion = true;
|
|
841
882
|
try {
|
|
@@ -927,14 +968,46 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
927
968
|
})),
|
|
928
969
|
products: tempOrder.products
|
|
929
970
|
};
|
|
930
|
-
|
|
971
|
+
return payload;
|
|
931
972
|
} catch (error) {
|
|
932
973
|
console.error('[OrderModule] applyPromotion failed', error);
|
|
974
|
+
return null;
|
|
933
975
|
} finally {
|
|
934
976
|
this.isApplyingPromotion = false;
|
|
935
977
|
}
|
|
936
978
|
}
|
|
937
979
|
|
|
980
|
+
/** 发布促销稳定态;products 必须读取折扣计算后的当前数组。 */
|
|
981
|
+
emitPromotionApplied(payload) {
|
|
982
|
+
if (!payload) return;
|
|
983
|
+
const products = this.store.tempOrder?.products || payload.products;
|
|
984
|
+
this.isEmittingPromotionApplied = true;
|
|
985
|
+
try {
|
|
986
|
+
void this.effectsEmit('onPromotionApplied', {
|
|
987
|
+
...payload,
|
|
988
|
+
products
|
|
989
|
+
});
|
|
990
|
+
} finally {
|
|
991
|
+
// effectsEmit 同步调用监听器后返回 Promise;保持既有的非阻塞事件行为。
|
|
992
|
+
this.isEmittingPromotionApplied = false;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
/** 公开入口:促销、折扣、summary 与持久化完成后发布稳定态事件。 */
|
|
997
|
+
async applyPromotion() {
|
|
998
|
+
const payload = await this.evaluatePromotion();
|
|
999
|
+
if (!payload) return;
|
|
1000
|
+
const tempOrder = this.store.tempOrder;
|
|
1001
|
+
if (!tempOrder) return;
|
|
1002
|
+
this.applyDiscount();
|
|
1003
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
1004
|
+
await this.recalculateSummary({
|
|
1005
|
+
createIfMissing: true
|
|
1006
|
+
});
|
|
1007
|
+
this.persistTempOrder();
|
|
1008
|
+
this.emitPromotionApplied(payload);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
938
1011
|
/** 最近一次 applyPromotion 输出的未满足促销列表 */
|
|
939
1012
|
getUnfulfilledPromotions() {
|
|
940
1013
|
return this.lastUnfulfilledPromotions;
|
|
@@ -1038,6 +1111,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1038
1111
|
this.store.tempOrder = {
|
|
1039
1112
|
...this.store.tempOrder,
|
|
1040
1113
|
products: [...this.store.tempOrder.products],
|
|
1114
|
+
notes: [...(this.store.tempOrder.notes || [])],
|
|
1041
1115
|
bookings: this.store.tempOrder.bookings ? [...this.store.tempOrder.bookings] : []
|
|
1042
1116
|
};
|
|
1043
1117
|
this.persistTempOrder();
|
|
@@ -1050,27 +1124,41 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1050
1124
|
now: (0, _utils.formatDateTime)(new Date())
|
|
1051
1125
|
});
|
|
1052
1126
|
}
|
|
1053
|
-
|
|
1127
|
+
clearTempOrderCustomerWalletSnapshots(tempOrder) {
|
|
1054
1128
|
const orderMetaList = (0, _utils.normalizeOrderMetaList)(tempOrder.order_meta_list);
|
|
1055
1129
|
if (!orderMetaList) return;
|
|
1056
1130
|
const nextOrderMetaList = {
|
|
1057
1131
|
...orderMetaList
|
|
1058
1132
|
};
|
|
1059
1133
|
delete nextOrderMetaList.point_cards_snapshot;
|
|
1134
|
+
delete nextOrderMetaList.virtual_currency_snapshot;
|
|
1060
1135
|
if (Object.keys(nextOrderMetaList).length === 0) {
|
|
1061
1136
|
delete tempOrder.order_meta_list;
|
|
1062
1137
|
return;
|
|
1063
1138
|
}
|
|
1064
1139
|
tempOrder.order_meta_list = nextOrderMetaList;
|
|
1065
1140
|
}
|
|
1066
|
-
|
|
1141
|
+
clearCustomerWalletState(tempOrder) {
|
|
1142
|
+
this.clearCustomerWalletRuntimeState();
|
|
1143
|
+
this.clearTempOrderCustomerWalletSnapshots(tempOrder);
|
|
1144
|
+
}
|
|
1145
|
+
clearCustomerWalletRuntimeState() {
|
|
1146
|
+
this.customerWalletPrepareConfigEpoch += 1;
|
|
1147
|
+
this.store.availableWalletIds = [];
|
|
1148
|
+
this.store.virtualCurrencyList = [];
|
|
1149
|
+
}
|
|
1150
|
+
writeCustomerWalletSnapshotsFromPrepareConfig(params) {
|
|
1067
1151
|
const tempOrder = this.store.tempOrder;
|
|
1068
1152
|
if (!tempOrder) return;
|
|
1069
1153
|
if (String(tempOrder.customer_id ?? '') !== String(params.customerId)) return;
|
|
1154
|
+
const virtualCurrencyList = Array.isArray(params.virtualCurrencyList) ? params.virtualCurrencyList : [];
|
|
1070
1155
|
tempOrder.order_meta_list = {
|
|
1071
1156
|
...((0, _utils.normalizeOrderMetaList)(tempOrder.order_meta_list) || {}),
|
|
1072
|
-
point_cards_snapshot: (0, _utils.buildPointCardSnapshotFromWalletPassList)(params.availableWalletPassList)
|
|
1157
|
+
point_cards_snapshot: (0, _utils.buildPointCardSnapshotFromWalletPassList)(params.availableWalletPassList),
|
|
1158
|
+
virtual_currency_snapshot: (0, _utils.buildVirtualCurrencySnapshotFromList)(virtualCurrencyList)
|
|
1073
1159
|
};
|
|
1160
|
+
this.store.availableWalletIds = [...params.availableWalletIds];
|
|
1161
|
+
this.store.virtualCurrencyList = (0, _lodashEs.cloneDeep)(virtualCurrencyList);
|
|
1074
1162
|
this.persistTempOrder();
|
|
1075
1163
|
this.saveDraftInBackground();
|
|
1076
1164
|
}
|
|
@@ -1855,6 +1943,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1855
1943
|
const freshTempOrder = this.createDefaultTempOrderInstance();
|
|
1856
1944
|
this.ensureExternalSaleNumber(freshTempOrder);
|
|
1857
1945
|
this.store.tempOrder = freshTempOrder;
|
|
1946
|
+
this.clearCustomerWalletRuntimeState();
|
|
1858
1947
|
this.store.summary = (0, _utils.createEmptySummary)();
|
|
1859
1948
|
this.store.lastOrderInfo = undefined;
|
|
1860
1949
|
this.store.syncState = undefined;
|
|
@@ -1875,6 +1964,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1875
1964
|
ensureIdentity: false
|
|
1876
1965
|
});
|
|
1877
1966
|
this.store.tempOrder = nextTempOrder;
|
|
1967
|
+
this.clearCustomerWalletRuntimeState();
|
|
1878
1968
|
if (options?.recalculateSummary !== false) {
|
|
1879
1969
|
await this.recalculateSummary({
|
|
1880
1970
|
createIfMissing: false
|
|
@@ -2398,6 +2488,179 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2398
2488
|
getTempOrderNote() {
|
|
2399
2489
|
return this.store.tempOrder?.note || '';
|
|
2400
2490
|
}
|
|
2491
|
+
ensureSalesNotesRuntimeState(tempOrder) {
|
|
2492
|
+
const hadNotesSnapshot = Array.isArray(tempOrder.notes);
|
|
2493
|
+
if (!Array.isArray(tempOrder.notes)) tempOrder.notes = [];
|
|
2494
|
+
if (!tempOrder._extend || typeof tempOrder._extend !== 'object') {
|
|
2495
|
+
tempOrder._extend = {
|
|
2496
|
+
productsByUid: {}
|
|
2497
|
+
};
|
|
2498
|
+
}
|
|
2499
|
+
if (!tempOrder._extend.salesNotesState) {
|
|
2500
|
+
tempOrder._extend.salesNotesState = {
|
|
2501
|
+
loaded: hadNotesSnapshot,
|
|
2502
|
+
dirty: false
|
|
2503
|
+
};
|
|
2504
|
+
}
|
|
2505
|
+
return tempOrder._extend.salesNotesState;
|
|
2506
|
+
}
|
|
2507
|
+
ensureSalesNotesLoadedForMutation(tempOrder) {
|
|
2508
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2509
|
+
if (state.loaded) return;
|
|
2510
|
+
if (tempOrder.order_id === null || tempOrder.order_id === undefined) {
|
|
2511
|
+
state.loaded = true;
|
|
2512
|
+
tempOrder.notes = [];
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
throw new Error('[Order Notes] 当前订单 Notes 尚未完整加载,禁止提交部分快照');
|
|
2516
|
+
}
|
|
2517
|
+
normalizeSalesNoteUuid(value, field) {
|
|
2518
|
+
const uuid = String(value ?? '').trim();
|
|
2519
|
+
if (!uuid) throw new Error(`[Order Notes] ${field} 不能为空`);
|
|
2520
|
+
if (uuid.length > 255) {
|
|
2521
|
+
throw new Error(`[Order Notes] ${field} 不能超过 255 个字符`);
|
|
2522
|
+
}
|
|
2523
|
+
return uuid;
|
|
2524
|
+
}
|
|
2525
|
+
getSalesNotePrimaryRelation(note) {
|
|
2526
|
+
return note.note_relations.find(relation => relation.is_primary === 1) || null;
|
|
2527
|
+
}
|
|
2528
|
+
removeSalesNotesForMissingProductLines(tempOrder) {
|
|
2529
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2530
|
+
if (!state.loaded || !Array.isArray(tempOrder.notes) || tempOrder.notes.length === 0) {
|
|
2531
|
+
return;
|
|
2532
|
+
}
|
|
2533
|
+
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));
|
|
2534
|
+
const nextNotes = tempOrder.notes.filter(note => {
|
|
2535
|
+
const primary = this.getSalesNotePrimaryRelation(note);
|
|
2536
|
+
if (!primary || primary.target_type !== 'order_detail') return true;
|
|
2537
|
+
return remainingProductUids.has(primary.target_uuid);
|
|
2538
|
+
});
|
|
2539
|
+
if (nextNotes.length === tempOrder.notes.length) return;
|
|
2540
|
+
tempOrder.notes = nextNotes;
|
|
2541
|
+
state.dirty = true;
|
|
2542
|
+
}
|
|
2543
|
+
setSalesNoteOnTempOrder(tempOrder, input) {
|
|
2544
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
2545
|
+
const note_type = String(input.note_type || '').trim();
|
|
2546
|
+
const policy = (0, _salesNotes.getSalesNotePolicy)(note_type);
|
|
2547
|
+
if (!policy) {
|
|
2548
|
+
throw new Error(`[Order Notes] 当前未注册备注类型: ${note_type || '(empty)'}`);
|
|
2549
|
+
}
|
|
2550
|
+
if (input.target?.target_type !== 'order_detail') {
|
|
2551
|
+
throw new Error('[Order Notes] 本期只支持 order_detail 作为主体');
|
|
2552
|
+
}
|
|
2553
|
+
const target_uuid = this.normalizeSalesNoteUuid(input.target.target_uuid, 'target_uuid');
|
|
2554
|
+
const targetProductExists = (tempOrder.products || []).some(product => {
|
|
2555
|
+
const productLineUid = product.metadata?.unique_identification_number || product.unique_identification_number;
|
|
2556
|
+
return String(productLineUid ?? '') === target_uuid;
|
|
2557
|
+
});
|
|
2558
|
+
if (!targetProductExists) {
|
|
2559
|
+
throw new Error('[Order Notes] 目标商品行不存在');
|
|
2560
|
+
}
|
|
2561
|
+
const text = (0, _salesNotes.buildSalesNoteText)(input.text);
|
|
2562
|
+
const notes = tempOrder.notes || [];
|
|
2563
|
+
// 当前 allergy policy 固定同一商品行只保留一条;业务调用方不参与去重规则。
|
|
2564
|
+
const existingIndex = policy.uniquePerPrimaryTarget ? notes.findIndex(note => {
|
|
2565
|
+
const primary = this.getSalesNotePrimaryRelation(note);
|
|
2566
|
+
return note.note_type === note_type && primary?.target_type === 'order_detail' && primary.target_uuid === target_uuid;
|
|
2567
|
+
}) : -1;
|
|
2568
|
+
const existing = existingIndex >= 0 ? notes[existingIndex] : null;
|
|
2569
|
+
const existingPrimary = existing?.note_relations.find(relation => relation.is_primary === 1 && relation.target_type === 'order_detail');
|
|
2570
|
+
const existingOrderRelation = existing?.note_relations.find(relation => relation.is_primary === 0 && relation.target_type === 'order');
|
|
2571
|
+
const note = {
|
|
2572
|
+
uuid: existing?.uuid || (0, _utils.createUuidV4)(),
|
|
2573
|
+
note_type: policy.note_type,
|
|
2574
|
+
content: {
|
|
2575
|
+
text
|
|
2576
|
+
},
|
|
2577
|
+
importance: policy.importance,
|
|
2578
|
+
note_relations: [{
|
|
2579
|
+
uuid: existingPrimary?.uuid || (0, _utils.createUuidV4)(),
|
|
2580
|
+
relation_type: policy.primary_relation_type,
|
|
2581
|
+
target_type: 'order_detail',
|
|
2582
|
+
target_uuid,
|
|
2583
|
+
is_primary: 1
|
|
2584
|
+
}, {
|
|
2585
|
+
uuid: existingOrderRelation?.uuid || (0, _utils.createUuidV4)(),
|
|
2586
|
+
relation_type: policy.secondary_order_relation_type,
|
|
2587
|
+
target_type: 'order',
|
|
2588
|
+
target_uuid: String(tempOrder.shop_order_number ?? ''),
|
|
2589
|
+
is_primary: 0
|
|
2590
|
+
}]
|
|
2591
|
+
};
|
|
2592
|
+
const duplicateIndex = notes.findIndex((item, index) => item.uuid === note.uuid && index !== existingIndex);
|
|
2593
|
+
if (duplicateIndex >= 0) {
|
|
2594
|
+
throw new Error('[Order Notes] uuid 已被其他 Note 使用');
|
|
2595
|
+
}
|
|
2596
|
+
tempOrder.notes = existingIndex >= 0 ? notes.map((item, index) => index === existingIndex ? note : item) : [...notes, note];
|
|
2597
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2598
|
+
state.loaded = true;
|
|
2599
|
+
state.dirty = true;
|
|
2600
|
+
return note;
|
|
2601
|
+
}
|
|
2602
|
+
getSalesNotes() {
|
|
2603
|
+
const tempOrder = this.ensureTempOrder();
|
|
2604
|
+
this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2605
|
+
return (0, _lodashEs.cloneDeep)(tempOrder.notes || []);
|
|
2606
|
+
}
|
|
2607
|
+
createSalesNotesMutationSnapshot() {
|
|
2608
|
+
const tempOrder = this.ensureTempOrder();
|
|
2609
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2610
|
+
return {
|
|
2611
|
+
orderIdentity: {
|
|
2612
|
+
orderId: tempOrder.order_id ?? null,
|
|
2613
|
+
externalSaleNumber: String(tempOrder.external_sale_number || '')
|
|
2614
|
+
},
|
|
2615
|
+
notes: (0, _lodashEs.cloneDeep)(tempOrder.notes || []),
|
|
2616
|
+
state: (0, _lodashEs.cloneDeep)(state)
|
|
2617
|
+
};
|
|
2618
|
+
}
|
|
2619
|
+
restoreSalesNotesMutationSnapshot(snapshot) {
|
|
2620
|
+
if (!snapshot || !Array.isArray(snapshot.notes) || !snapshot.orderIdentity || typeof snapshot.orderIdentity.externalSaleNumber !== 'string' || typeof snapshot.state?.loaded !== 'boolean' || typeof snapshot.state?.dirty !== 'boolean') {
|
|
2621
|
+
throw new Error('[Order Notes] 无效的 mutation snapshot');
|
|
2622
|
+
}
|
|
2623
|
+
const tempOrder = this.store.tempOrder;
|
|
2624
|
+
if (!tempOrder) throw new Error('[Order Notes] 当前订单不存在');
|
|
2625
|
+
const snapshotOrderId = snapshot.orderIdentity.orderId;
|
|
2626
|
+
const currentOrderId = tempOrder.order_id;
|
|
2627
|
+
const hasSnapshotOrderId = snapshotOrderId !== null && snapshotOrderId !== undefined && String(snapshotOrderId).trim().length > 0;
|
|
2628
|
+
const hasCurrentOrderId = currentOrderId !== null && currentOrderId !== undefined && String(currentOrderId).trim().length > 0;
|
|
2629
|
+
const isSameOrder = hasSnapshotOrderId && hasCurrentOrderId ? String(snapshotOrderId) === String(currentOrderId) : Boolean(snapshot.orderIdentity.externalSaleNumber) && snapshot.orderIdentity.externalSaleNumber === String(tempOrder.external_sale_number || '');
|
|
2630
|
+
if (!isSameOrder) {
|
|
2631
|
+
throw new Error('[Order Notes] 当前订单已切换,拒绝恢复旧订单快照');
|
|
2632
|
+
}
|
|
2633
|
+
this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2634
|
+
tempOrder.notes = (0, _lodashEs.cloneDeep)(snapshot.notes);
|
|
2635
|
+
tempOrder._extend.salesNotesState = (0, _lodashEs.cloneDeep)(snapshot.state);
|
|
2636
|
+
this.notifyTempOrderChanged();
|
|
2637
|
+
}
|
|
2638
|
+
async setSalesNote(input) {
|
|
2639
|
+
const tempOrder = this.ensureTempOrder();
|
|
2640
|
+
const note = this.setSalesNoteOnTempOrder(tempOrder, input);
|
|
2641
|
+
this.notifyTempOrderChanged();
|
|
2642
|
+
return (0, _lodashEs.cloneDeep)(note);
|
|
2643
|
+
}
|
|
2644
|
+
async removeSalesNote(uuid) {
|
|
2645
|
+
const tempOrder = this.ensureTempOrder();
|
|
2646
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
2647
|
+
const normalizedUuid = this.normalizeSalesNoteUuid(uuid, 'uuid');
|
|
2648
|
+
const notes = tempOrder.notes || [];
|
|
2649
|
+
const nextNotes = notes.filter(note => note.uuid !== normalizedUuid);
|
|
2650
|
+
if (nextNotes.length === notes.length) return;
|
|
2651
|
+
tempOrder.notes = nextNotes;
|
|
2652
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2653
|
+
state.dirty = true;
|
|
2654
|
+
this.notifyTempOrderChanged();
|
|
2655
|
+
}
|
|
2656
|
+
async clearSalesNotes() {
|
|
2657
|
+
const tempOrder = this.ensureTempOrder();
|
|
2658
|
+
tempOrder.notes = [];
|
|
2659
|
+
const state = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
2660
|
+
state.loaded = true;
|
|
2661
|
+
state.dirty = true;
|
|
2662
|
+
this.notifyTempOrderChanged();
|
|
2663
|
+
}
|
|
2401
2664
|
updateTempOrderShopDiscount(amount) {
|
|
2402
2665
|
const tempOrder = this.ensureTempOrder();
|
|
2403
2666
|
const discount = _decimal.default.max(new _decimal.default(Number(amount) || 0), 0).toDecimalPlaces(2).toFixed(2);
|
|
@@ -2437,6 +2700,31 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2437
2700
|
this.persistTempOrder();
|
|
2438
2701
|
return tempOrder.buzzer;
|
|
2439
2702
|
}
|
|
2703
|
+
updateTempOrderShopServiceData(patch) {
|
|
2704
|
+
const tempOrder = this.ensureTempOrder();
|
|
2705
|
+
const metadata = tempOrder.metadata && typeof tempOrder.metadata === 'object' && !Array.isArray(tempOrder.metadata) ? tempOrder.metadata : {};
|
|
2706
|
+
const currentShopServiceData = metadata.shop_service_data && typeof metadata.shop_service_data === 'object' && !Array.isArray(metadata.shop_service_data) ? metadata.shop_service_data : {};
|
|
2707
|
+
const shopServiceData = {
|
|
2708
|
+
...currentShopServiceData,
|
|
2709
|
+
...patch
|
|
2710
|
+
};
|
|
2711
|
+
tempOrder.metadata = {
|
|
2712
|
+
...metadata,
|
|
2713
|
+
shop_service_data: shopServiceData
|
|
2714
|
+
};
|
|
2715
|
+
this.persistTempOrder();
|
|
2716
|
+
return shopServiceData;
|
|
2717
|
+
}
|
|
2718
|
+
updateTempOrderPickupReferenceMode(mode) {
|
|
2719
|
+
return this.updateTempOrderShopServiceData({
|
|
2720
|
+
pickup_reference_mode: mode
|
|
2721
|
+
});
|
|
2722
|
+
}
|
|
2723
|
+
updateTempOrderServiceType(serviceType) {
|
|
2724
|
+
return this.updateTempOrderShopServiceData({
|
|
2725
|
+
service_type: serviceType
|
|
2726
|
+
});
|
|
2727
|
+
}
|
|
2440
2728
|
updateTempOrderContactsInfo(contactsInfo) {
|
|
2441
2729
|
const tempOrder = this.ensureTempOrder();
|
|
2442
2730
|
tempOrder.contacts_info = contactsInfo && typeof contactsInfo === 'object' && !Array.isArray(contactsInfo) ? contactsInfo : null;
|
|
@@ -2547,8 +2835,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2547
2835
|
});
|
|
2548
2836
|
const nextCustomerId = tempOrder.customer_id ?? null;
|
|
2549
2837
|
if (String(previousCustomerId ?? '') !== String(nextCustomerId ?? '')) {
|
|
2550
|
-
this.
|
|
2551
|
-
this.clearTempOrderPointCardSnapshot(tempOrder);
|
|
2838
|
+
this.clearCustomerWalletState(tempOrder);
|
|
2552
2839
|
}
|
|
2553
2840
|
this.persistTempOrder();
|
|
2554
2841
|
return {
|
|
@@ -2584,9 +2871,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2584
2871
|
}
|
|
2585
2872
|
const nextCustomerId = tempOrder.customer_id ?? null;
|
|
2586
2873
|
if (String(previousCustomerId ?? '') !== String(nextCustomerId ?? '')) {
|
|
2587
|
-
this.
|
|
2588
|
-
this.store.virtualCurrencyList = [];
|
|
2589
|
-
this.clearTempOrderPointCardSnapshot(tempOrder);
|
|
2874
|
+
this.clearCustomerWalletState(tempOrder);
|
|
2590
2875
|
(0, _utils.clearTempOrderHolderAssignments)(tempOrder);
|
|
2591
2876
|
this.clearCustomerBoundDiscounts(tempOrder);
|
|
2592
2877
|
this.applyDiscount();
|
|
@@ -2624,9 +2909,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2624
2909
|
tempOrder.email = '';
|
|
2625
2910
|
tempOrder.customer = null;
|
|
2626
2911
|
if (tempOrder._extend) delete tempOrder._extend.customerSnapshot;
|
|
2627
|
-
this.
|
|
2628
|
-
this.store.virtualCurrencyList = [];
|
|
2629
|
-
this.clearTempOrderPointCardSnapshot(tempOrder);
|
|
2912
|
+
this.clearCustomerWalletState(tempOrder);
|
|
2630
2913
|
this.clearCustomerBoundDiscounts(tempOrder);
|
|
2631
2914
|
this.applyDiscount();
|
|
2632
2915
|
this.persistTempOrder();
|
|
@@ -3034,9 +3317,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3034
3317
|
if (!options?.skipEditDiscountConfigRefresh && !isVirtualSettlement) {
|
|
3035
3318
|
await this.ensureEditDiscountConfigForProductChange(tempOrder);
|
|
3036
3319
|
}
|
|
3037
|
-
|
|
3038
|
-
await this.applyPromotion();
|
|
3039
|
-
}
|
|
3320
|
+
const promotionPayload = !options?.skipDiscountRecalculation && !isVirtualSettlement ? await this.evaluatePromotion() : null;
|
|
3040
3321
|
if (!options?.skipDiscountRecalculation && !isVirtualSettlement) {
|
|
3041
3322
|
this.applyDiscount();
|
|
3042
3323
|
}
|
|
@@ -3045,6 +3326,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3045
3326
|
createIfMissing: true
|
|
3046
3327
|
});
|
|
3047
3328
|
this.persistTempOrder();
|
|
3329
|
+
this.emitPromotionApplied(promotionPayload);
|
|
3048
3330
|
}
|
|
3049
3331
|
|
|
3050
3332
|
/**
|
|
@@ -3127,6 +3409,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3127
3409
|
const matchedProduct = matchedIndex === -1 ? null : tempOrder.products[matchedIndex];
|
|
3128
3410
|
const existedFingerprint = matchedProduct ? (0, _utils3.buildProductLineFingerprint)((0, _utils.getProductSkuOptions)(matchedProduct), matchedProduct.product_bundle) : '';
|
|
3129
3411
|
const commitProductLine = shouldMerge => {
|
|
3412
|
+
let committedProduct;
|
|
3130
3413
|
if (matchedIndex === -1 || !matchedProduct || !shouldMerge) {
|
|
3131
3414
|
this.captureProductRuntime(tempOrder, productToAdd, normalizedIncoming);
|
|
3132
3415
|
if (linked) {
|
|
@@ -3142,6 +3425,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3142
3425
|
} else {
|
|
3143
3426
|
tempOrder.products = [...tempOrder.products, normalizedIncoming];
|
|
3144
3427
|
}
|
|
3428
|
+
committedProduct = normalizedIncoming;
|
|
3145
3429
|
} else {
|
|
3146
3430
|
const targetProduct = matchedProduct;
|
|
3147
3431
|
const targetUid = targetProduct.metadata?.unique_identification_number;
|
|
@@ -3177,6 +3461,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3177
3461
|
num: nextNum
|
|
3178
3462
|
};
|
|
3179
3463
|
this.captureProductRuntime(tempOrder, productToAdd, tempOrder.products[matchedIndex], targetUid);
|
|
3464
|
+
committedProduct = tempOrder.products[matchedIndex];
|
|
3180
3465
|
if (matchedIndex !== tempOrder.products.length - 1) {
|
|
3181
3466
|
const mergedProduct = tempOrder.products[matchedIndex];
|
|
3182
3467
|
tempOrder.products = [...tempOrder.products.slice(0, matchedIndex), ...tempOrder.products.slice(matchedIndex + 1), mergedProduct];
|
|
@@ -3185,10 +3470,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3185
3470
|
if (linked) {
|
|
3186
3471
|
tempOrder.bookings = [...(tempOrder.bookings || []), linked.booking];
|
|
3187
3472
|
}
|
|
3473
|
+
return committedProduct;
|
|
3188
3474
|
};
|
|
3189
3475
|
if (!matchedProduct) {
|
|
3190
|
-
commitProductLine(false);
|
|
3191
|
-
return;
|
|
3476
|
+
return commitProductLine(false);
|
|
3192
3477
|
}
|
|
3193
3478
|
const shouldMerge = this.shouldMergeProductToOrder({
|
|
3194
3479
|
incomingProduct: productToAdd,
|
|
@@ -3203,7 +3488,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3203
3488
|
if (shouldMerge && typeof shouldMerge === 'object' && typeof shouldMerge.then === 'function') {
|
|
3204
3489
|
return Promise.resolve(shouldMerge).then(commitProductLine);
|
|
3205
3490
|
}
|
|
3206
|
-
commitProductLine(shouldMerge);
|
|
3491
|
+
return commitProductLine(shouldMerge);
|
|
3207
3492
|
}
|
|
3208
3493
|
|
|
3209
3494
|
/**
|
|
@@ -3276,34 +3561,99 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3276
3561
|
*/
|
|
3277
3562
|
async addProductToOrder(product, booking, options) {
|
|
3278
3563
|
const tempOrder = this.ensureTempOrder();
|
|
3564
|
+
const salesNoteDrafts = (options?.salesNotes || []).map(draft => ({
|
|
3565
|
+
note_type: String(draft.note_type || '').trim(),
|
|
3566
|
+
text: {
|
|
3567
|
+
kind: 'resolved',
|
|
3568
|
+
text: (0, _salesNotes.buildSalesNoteText)(draft.text)
|
|
3569
|
+
}
|
|
3570
|
+
}));
|
|
3571
|
+
const mutationSnapshot = salesNoteDrafts.length > 0 ? {
|
|
3572
|
+
products: (0, _lodashEs.cloneDeep)(tempOrder.products || []),
|
|
3573
|
+
bookings: (0, _lodashEs.cloneDeep)(tempOrder.bookings || []),
|
|
3574
|
+
notes: (0, _lodashEs.cloneDeep)(tempOrder.notes || []),
|
|
3575
|
+
extend: (0, _lodashEs.cloneDeep)(tempOrder._extend || {})
|
|
3576
|
+
} : null;
|
|
3577
|
+
const attachSalesNoteDrafts = orderProduct => {
|
|
3578
|
+
if (!salesNoteDrafts.length) return;
|
|
3579
|
+
const productLineUid = orderProduct.metadata?.unique_identification_number || orderProduct.unique_identification_number;
|
|
3580
|
+
if (!productLineUid) {
|
|
3581
|
+
throw new Error('[Order Notes] 商品行缺少 unique_identification_number');
|
|
3582
|
+
}
|
|
3583
|
+
salesNoteDrafts.forEach(draft => {
|
|
3584
|
+
this.setSalesNoteOnTempOrder(tempOrder, {
|
|
3585
|
+
note_type: draft.note_type,
|
|
3586
|
+
target: {
|
|
3587
|
+
target_type: 'order_detail',
|
|
3588
|
+
target_uuid: String(productLineUid)
|
|
3589
|
+
},
|
|
3590
|
+
text: draft.text
|
|
3591
|
+
});
|
|
3592
|
+
});
|
|
3593
|
+
};
|
|
3594
|
+
const rollbackProductAndNotesMutation = () => {
|
|
3595
|
+
if (!mutationSnapshot) return;
|
|
3596
|
+
tempOrder.products = mutationSnapshot.products;
|
|
3597
|
+
tempOrder.bookings = mutationSnapshot.bookings;
|
|
3598
|
+
tempOrder.notes = mutationSnapshot.notes;
|
|
3599
|
+
tempOrder._extend = mutationSnapshot.extend;
|
|
3600
|
+
};
|
|
3279
3601
|
const insertAfterProductUid = options?.insertAfterProductUid;
|
|
3280
3602
|
const anchorIndex = booking && insertAfterProductUid ? tempOrder.products.findIndex(line => {
|
|
3281
3603
|
const uid = line.metadata?.unique_identification_number || line.unique_identification_number;
|
|
3282
3604
|
return uid !== undefined && uid !== null && String(uid) === String(insertAfterProductUid);
|
|
3283
3605
|
}) : -1;
|
|
3284
3606
|
let insertAtIndex = anchorIndex >= 0 ? anchorIndex + 1 : undefined;
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3607
|
+
try {
|
|
3608
|
+
if (booking) {
|
|
3609
|
+
const productRecord = product;
|
|
3610
|
+
const splitCount = (0, _utils3.getSafeProductNum)(productRecord.num ?? productRecord.product_quantity ?? 1);
|
|
3611
|
+
if (splitCount > 1) {
|
|
3612
|
+
for (let i = 0; i < splitCount; i += 1) {
|
|
3613
|
+
const splitLine = this.createSplitBookingLine(productRecord, booking, i, splitCount);
|
|
3614
|
+
if (i > 0) {
|
|
3615
|
+
delete splitLine.product.unique_identification_number;
|
|
3616
|
+
delete splitLine.product.identity_key;
|
|
3617
|
+
if (splitLine.product.metadata) {
|
|
3618
|
+
splitLine.product.metadata = {
|
|
3619
|
+
...splitLine.product.metadata
|
|
3620
|
+
};
|
|
3621
|
+
delete splitLine.product.metadata.unique_identification_number;
|
|
3622
|
+
delete splitLine.product.metadata.identity_key;
|
|
3623
|
+
}
|
|
3624
|
+
delete splitLine.booking.booking_uid;
|
|
3625
|
+
if (splitLine.booking.metadata) {
|
|
3626
|
+
splitLine.booking.metadata = {
|
|
3627
|
+
...splitLine.booking.metadata
|
|
3628
|
+
};
|
|
3629
|
+
delete splitLine.booking.metadata.unique_identification_number;
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
const committedProduct = await this.appendProductLineToTempOrder(tempOrder, splitLine.product, splitLine.booking, {
|
|
3633
|
+
insertAtIndex,
|
|
3634
|
+
disableMerge: options?.disableMerge
|
|
3635
|
+
});
|
|
3636
|
+
attachSalesNoteDrafts(committedProduct);
|
|
3637
|
+
if (insertAtIndex !== undefined) insertAtIndex += 1;
|
|
3638
|
+
}
|
|
3639
|
+
} else {
|
|
3640
|
+
const committedProduct = await this.appendProductLineToTempOrder(tempOrder, product, (0, _lodashEs.cloneDeep)(booking), {
|
|
3292
3641
|
insertAtIndex,
|
|
3293
3642
|
disableMerge: options?.disableMerge
|
|
3294
3643
|
});
|
|
3295
|
-
|
|
3296
|
-
if (insertAtIndex !== undefined) insertAtIndex += 1;
|
|
3644
|
+
attachSalesNoteDrafts(committedProduct);
|
|
3297
3645
|
}
|
|
3298
|
-
|
|
3299
|
-
|
|
3646
|
+
} else {
|
|
3647
|
+
const committedProduct = await this.appendProductLineToTempOrder(tempOrder, product, undefined, {
|
|
3648
|
+
insertAtIndex,
|
|
3649
|
+
disableMerge: options?.disableMerge
|
|
3650
|
+
});
|
|
3651
|
+
attachSalesNoteDrafts(committedProduct);
|
|
3300
3652
|
}
|
|
3653
|
+
} catch (error) {
|
|
3654
|
+
rollbackProductAndNotesMutation();
|
|
3655
|
+
throw error;
|
|
3301
3656
|
}
|
|
3302
|
-
const appendResult = this.appendProductLineToTempOrder(tempOrder, product, booking, {
|
|
3303
|
-
insertAtIndex,
|
|
3304
|
-
disableMerge: options?.disableMerge
|
|
3305
|
-
});
|
|
3306
|
-
if (appendResult) await appendResult;
|
|
3307
3657
|
await this.finalizeProductOrderMutation(tempOrder);
|
|
3308
3658
|
this.logInfo('addProductToOrder success', {
|
|
3309
3659
|
product_id: product.product_id,
|
|
@@ -3626,7 +3976,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3626
3976
|
async updateOrderProduct(params) {
|
|
3627
3977
|
const tempOrder = this.ensureTempOrder();
|
|
3628
3978
|
const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params);
|
|
3629
|
-
await this.
|
|
3979
|
+
const promotionPayload = await this.evaluatePromotion();
|
|
3630
3980
|
this.applyDiscount({
|
|
3631
3981
|
reapplyBookingDiscountProductUids: params.allow_booking_discount_reapply && updatedProductUid ? [String(updatedProductUid)] : undefined
|
|
3632
3982
|
});
|
|
@@ -3635,6 +3985,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3635
3985
|
createIfMissing: true
|
|
3636
3986
|
});
|
|
3637
3987
|
this.persistTempOrder();
|
|
3988
|
+
this.emitPromotionApplied(promotionPayload);
|
|
3638
3989
|
this.logInfo('updateOrderProduct success', {
|
|
3639
3990
|
params
|
|
3640
3991
|
});
|
|
@@ -3729,8 +4080,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3729
4080
|
}
|
|
3730
4081
|
tempOrder.products[productIndex] = normalizedProduct;
|
|
3731
4082
|
this.prepareVirtualSettlementTempOrder(tempOrder);
|
|
3732
|
-
|
|
3733
|
-
|
|
4083
|
+
const isVirtualSettlement = this.isActiveVirtualSettlementOrder(tempOrder);
|
|
4084
|
+
const promotionPayload = !isVirtualSettlement ? await this.evaluatePromotion() : null;
|
|
4085
|
+
if (!isVirtualSettlement) {
|
|
3734
4086
|
this.applyDiscount();
|
|
3735
4087
|
}
|
|
3736
4088
|
this.sanitizeTempOrderProducts(tempOrder);
|
|
@@ -3738,6 +4090,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3738
4090
|
createIfMissing: true
|
|
3739
4091
|
});
|
|
3740
4092
|
this.persistTempOrder();
|
|
4093
|
+
this.emitPromotionApplied(promotionPayload);
|
|
3741
4094
|
this.logInfo('updateOrderProductQuantity success', {
|
|
3742
4095
|
params
|
|
3743
4096
|
});
|
|
@@ -3782,7 +4135,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3782
4135
|
*/
|
|
3783
4136
|
async finalizeAfterProductsMutation(tempOrder, options) {
|
|
3784
4137
|
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
3785
|
-
await this.
|
|
4138
|
+
const promotionPayload = await this.evaluatePromotion();
|
|
3786
4139
|
this.applyDiscount({
|
|
3787
4140
|
reapplyBookingDiscountProductUids: options?.reapplyBookingDiscountProductUids
|
|
3788
4141
|
});
|
|
@@ -3791,6 +4144,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3791
4144
|
createIfMissing: true
|
|
3792
4145
|
});
|
|
3793
4146
|
this.persistTempOrder();
|
|
4147
|
+
this.emitPromotionApplied(promotionPayload);
|
|
3794
4148
|
}
|
|
3795
4149
|
|
|
3796
4150
|
/**
|
|
@@ -3801,10 +4155,12 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3801
4155
|
*/
|
|
3802
4156
|
async removeProductsFromOrder(identities, options) {
|
|
3803
4157
|
const tempOrder = this.ensureTempOrder();
|
|
3804
|
-
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
3805
4158
|
if (!identities.length) {
|
|
3806
4159
|
return tempOrder.products;
|
|
3807
4160
|
}
|
|
4161
|
+
// 商品删除会同步删除以商品行为主关系的 Notes;快照不完整时禁止产生孤儿 Relation。
|
|
4162
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
4163
|
+
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
3808
4164
|
const productsBeforeRemove = tempOrder.products || [];
|
|
3809
4165
|
const bookingsBeforeRemove = tempOrder.bookings || [];
|
|
3810
4166
|
const preserveDisplayPosition = options?.preserveDisplayPosition;
|
|
@@ -3864,6 +4220,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3864
4220
|
tempOrder.products = nextProductIndex >= 0 ? [...productsWithoutRemaining.slice(0, nextProductIndex), remainingProduct, ...productsWithoutRemaining.slice(nextProductIndex)] : [...productsWithoutRemaining, remainingProduct];
|
|
3865
4221
|
}
|
|
3866
4222
|
}
|
|
4223
|
+
this.removeSalesNotesForMissingProductLines(tempOrder);
|
|
3867
4224
|
await this.finalizeAfterProductsMutation(tempOrder);
|
|
3868
4225
|
this.logInfo('removeProductsFromOrder success', {
|
|
3869
4226
|
identities
|
|
@@ -3876,13 +4233,15 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3876
4233
|
|
|
3877
4234
|
/**
|
|
3878
4235
|
* 仅清空购物车行(products / bookings),不重置整单。
|
|
3879
|
-
*
|
|
4236
|
+
* 普通整单 note 保持不变;以商品行为主体的 Sales Notes 同步删除。
|
|
3880
4237
|
*/
|
|
3881
4238
|
async clearOrderCartLines() {
|
|
3882
4239
|
const tempOrder = this.ensureTempOrder();
|
|
4240
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
3883
4241
|
tempOrder.products = [];
|
|
3884
4242
|
tempOrder.bookings = [];
|
|
3885
4243
|
(0, _virtualSettlement.releaseTempOrderSettlementState)(tempOrder);
|
|
4244
|
+
this.removeSalesNotesForMissingProductLines(tempOrder);
|
|
3886
4245
|
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
3887
4246
|
if (tempOrder._extend && typeof tempOrder._extend === 'object') {
|
|
3888
4247
|
tempOrder._extend = {
|
|
@@ -3890,13 +4249,14 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3890
4249
|
productsByUid: {}
|
|
3891
4250
|
};
|
|
3892
4251
|
}
|
|
3893
|
-
await this.
|
|
4252
|
+
const promotionPayload = await this.evaluatePromotion();
|
|
3894
4253
|
this.applyDiscount();
|
|
3895
4254
|
this.sanitizeTempOrderProducts(tempOrder);
|
|
3896
4255
|
await this.recalculateSummary({
|
|
3897
4256
|
createIfMissing: true
|
|
3898
4257
|
});
|
|
3899
4258
|
this.persistTempOrder();
|
|
4259
|
+
this.emitPromotionApplied(promotionPayload);
|
|
3900
4260
|
this.logInfo('clearOrderCartLines success', {});
|
|
3901
4261
|
return tempOrder;
|
|
3902
4262
|
}
|
|
@@ -3906,8 +4266,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3906
4266
|
*/
|
|
3907
4267
|
async clearOrderForSettlementSwitch() {
|
|
3908
4268
|
const tempOrder = this.ensureTempOrder();
|
|
4269
|
+
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
3909
4270
|
tempOrder.products = [];
|
|
3910
4271
|
tempOrder.bookings = [];
|
|
4272
|
+
this.removeSalesNotesForMissingProductLines(tempOrder);
|
|
3911
4273
|
tempOrder.discount_list = [];
|
|
3912
4274
|
tempOrder.payments = [];
|
|
3913
4275
|
tempOrder.refunds = [];
|
|
@@ -4050,6 +4412,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4050
4412
|
})) || this.store.summary || (0, _utils.createEmptySummary)();
|
|
4051
4413
|
const effectiveCacheId = params?.cacheId ?? this.cacheId;
|
|
4052
4414
|
const hasPaymentStatusOverride = params?.paymentStatus !== undefined;
|
|
4415
|
+
const shouldOverridePaymentStatus = hasPaymentStatusOverride && !isOnlineStorePlatform && !shouldConfirmPendingVoucherPayments;
|
|
4053
4416
|
const hasSmallTicketDataFlagOverride = params?.smallTicketDataFlag !== undefined;
|
|
4054
4417
|
const enhancePayload = hasPaymentOverride || hasPaymentStatusOverride || hasSmallTicketDataFlagOverride || params?.enhancePayload ? (payload, ctx) => {
|
|
4055
4418
|
const nextPayload = {
|
|
@@ -4057,7 +4420,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4057
4420
|
...(hasPaymentOverride ? {
|
|
4058
4421
|
payments: preparedPaymentOverride || []
|
|
4059
4422
|
} : {}),
|
|
4060
|
-
...(
|
|
4423
|
+
...(shouldOverridePaymentStatus ? {
|
|
4061
4424
|
payment_status: params?.paymentStatus
|
|
4062
4425
|
} : {}),
|
|
4063
4426
|
...(hasSmallTicketDataFlagOverride ? {
|
|
@@ -4124,6 +4487,12 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4124
4487
|
this.logSubmitBackendRejected(result, payload);
|
|
4125
4488
|
return result;
|
|
4126
4489
|
}
|
|
4490
|
+
const isLocalPendingSubmit = this.isLocalPendingSubmitResult(result);
|
|
4491
|
+
// need_sync=1 仅表示已进入本地同步队列,不能视为远端已确认 Notes。
|
|
4492
|
+
if (Object.prototype.hasOwnProperty.call(payload, 'notes') && !isLocalPendingSubmit) {
|
|
4493
|
+
const salesNotesState = this.ensureSalesNotesRuntimeState(tempOrder);
|
|
4494
|
+
salesNotesState.dirty = false;
|
|
4495
|
+
}
|
|
4127
4496
|
const submittedOrderId = this.extractOrderIdFromSubmitResult(result);
|
|
4128
4497
|
this.logInfo('runSubmitTempOrder: 提交成功', {
|
|
4129
4498
|
submittedOrderId,
|
|
@@ -4137,9 +4506,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4137
4506
|
tempOrder.order_id = submittedOrderId;
|
|
4138
4507
|
const resultRecord = result;
|
|
4139
4508
|
await this.markLocalOrderSynced(submittedOrderId, resultRecord?.data || resultRecord || {});
|
|
4140
|
-
}
|
|
4509
|
+
}
|
|
4510
|
+
if (isLocalPendingSubmit) {
|
|
4141
4511
|
this.store.syncState = 'local';
|
|
4142
|
-
} else {
|
|
4512
|
+
} else if (submittedOrderId === null || submittedOrderId === undefined) {
|
|
4143
4513
|
this.store.syncState = 'submitted';
|
|
4144
4514
|
}
|
|
4145
4515
|
return result;
|
|
@@ -4535,7 +4905,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4535
4905
|
params.forceRemote = false;
|
|
4536
4906
|
}
|
|
4537
4907
|
const res = await this.request.get(`/order/sales/${encodeURIComponent(lookup)}`, {
|
|
4538
|
-
with: ['products', 'bookings', 'payments', 'customer', 'summary', 'contacts_info', 'order_meta_list', 'refunds'],
|
|
4908
|
+
with: ['products', 'bookings', 'payments', 'customer', 'summary', 'contacts_info', 'order_meta_list', 'refunds', 'notes'],
|
|
4539
4909
|
...(params.forceRemote ? {
|
|
4540
4910
|
forceRemote: true
|
|
4541
4911
|
} : {})
|
|
@@ -4588,9 +4958,11 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4588
4958
|
const isMergedSalesDetailHydrate = options?.source === 'mergedSalesDetail';
|
|
4589
4959
|
const nextTempOrder = this.normalizeTempOrderForRuntime(raw, {
|
|
4590
4960
|
// merge 前已只给远端商品补标记;这里不能把本地未提交商品一并变成 saved item。
|
|
4591
|
-
makeEditMark: !isSessionStorageHydrate && !isMergedSalesDetailHydrate
|
|
4961
|
+
makeEditMark: !isSessionStorageHydrate && !isMergedSalesDetailHydrate,
|
|
4962
|
+
allowUnresolvedSalesNotes: isSessionStorageHydrate
|
|
4592
4963
|
});
|
|
4593
4964
|
this.store.tempOrder = nextTempOrder;
|
|
4965
|
+
this.clearCustomerWalletRuntimeState();
|
|
4594
4966
|
if (isSessionStorageHydrate) {
|
|
4595
4967
|
// 会话快照是未提交购物车,不应获得编辑订单的 saved/edit 标记与服务端基线。
|
|
4596
4968
|
const restoredSessionDiscounts = Array.isArray(raw.discount_list) ? (0, _lodashEs.cloneDeep)(raw.discount_list) : [];
|
|
@@ -4810,6 +5182,17 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4810
5182
|
nextTempOrder.payments = Array.isArray(raw.payments) ? raw.payments.map(p => ({
|
|
4811
5183
|
...(p || {})
|
|
4812
5184
|
})) : [];
|
|
5185
|
+
const rawHasSalesNotes = Object.prototype.hasOwnProperty.call(raw, 'notes');
|
|
5186
|
+
const restoredSalesNotesState = raw._extend?.salesNotesState;
|
|
5187
|
+
const allowUnresolvedSalesNotes = options?.allowUnresolvedSalesNotes === true || restoredSalesNotesState?.dirty === true || Number(raw.is_draft_order || 0) === 1;
|
|
5188
|
+
const decodedSalesNotes = rawHasSalesNotes ? (0, _salesNotes.decodeSalesNotesSnapshot)(raw.notes, {
|
|
5189
|
+
allowUnresolvedOrderTarget: allowUnresolvedSalesNotes
|
|
5190
|
+
}) : {
|
|
5191
|
+
notes: [],
|
|
5192
|
+
complete: false
|
|
5193
|
+
};
|
|
5194
|
+
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 === ''));
|
|
5195
|
+
nextTempOrder.notes = decodedSalesNotes.notes;
|
|
4813
5196
|
nextTempOrder.surcharges = Array.isArray(raw.surcharges) ? raw.surcharges.map(s => ({
|
|
4814
5197
|
...(s || {})
|
|
4815
5198
|
})) : [];
|
|
@@ -4830,6 +5213,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4830
5213
|
productsByUid: {}
|
|
4831
5214
|
};
|
|
4832
5215
|
const tempOrderExtend = nextTempOrder._extend;
|
|
5216
|
+
tempOrderExtend.salesNotesState = {
|
|
5217
|
+
loaded: rawHasSalesNotes ? decodedSalesNotes.complete : restoredSalesNotesState?.loaded === true,
|
|
5218
|
+
dirty: decodedSalesNotes.complete && (restoredSalesNotesState?.dirty === true || allowUnresolvedSalesNotes && hasUnresolvedSalesNoteOrderTarget)
|
|
5219
|
+
};
|
|
4833
5220
|
const productsByUid = tempOrderExtend.productsByUid || {};
|
|
4834
5221
|
for (const [index, product] of nextTempOrder.products.entries()) {
|
|
4835
5222
|
const uid = product.metadata?.unique_identification_number;
|
|
@@ -5021,7 +5408,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
5021
5408
|
}
|
|
5022
5409
|
async getOrderInfo(order_id) {
|
|
5023
5410
|
const res = await this.request.get(`/order/sales/${order_id}`, {
|
|
5024
|
-
with: ['products', 'bookings']
|
|
5411
|
+
with: ['products', 'bookings', 'notes']
|
|
5025
5412
|
}, {
|
|
5026
5413
|
osServer: true
|
|
5027
5414
|
});
|