@pisell/pisellos 0.10.41 → 0.10.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +58 -19
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +24 -12
- package/dist/modules/Discount/entitlementPass.d.ts +34 -0
- package/dist/modules/Discount/entitlementPass.js +147 -0
- package/dist/modules/Discount/index.d.ts +2 -0
- package/dist/modules/Discount/index.js +39 -13
- package/dist/modules/Discount/types.d.ts +26 -5
- package/dist/modules/Order/index.d.ts +6 -1
- package/dist/modules/Order/index.js +283 -118
- package/dist/modules/Order/utils/orderCollectionIdentity.js +16 -12
- package/dist/modules/Order/utils.js +17 -1
- package/dist/modules/ResourcePlanner/planner.d.ts +2 -2
- package/dist/modules/ResourcePlanner/planner.js +163 -46
- package/dist/modules/ResourcePlanner/types.d.ts +17 -0
- package/dist/modules/Rules/index.js +310 -134
- package/dist/solution/BaseSales/index.d.ts +2 -0
- package/dist/solution/BaseSales/index.js +9 -1
- package/dist/solution/BaseSales/utils/cartPromotion.js +141 -126
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +2 -0
- package/dist/solution/ShopDiscount/index.d.ts +1 -0
- package/dist/solution/ShopDiscount/index.js +41 -21
- package/dist/solution/ShopDiscount/utils.js +3 -2
- package/dist/solution/UnifiedBookingSales/index.js +94 -21
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +35 -6
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +13 -6
- package/lib/modules/Discount/entitlementPass.d.ts +34 -0
- package/lib/modules/Discount/entitlementPass.js +141 -0
- package/lib/modules/Discount/index.d.ts +2 -0
- package/lib/modules/Discount/index.js +25 -9
- package/lib/modules/Discount/types.d.ts +26 -5
- package/lib/modules/Order/index.d.ts +6 -1
- package/lib/modules/Order/index.js +172 -28
- package/lib/modules/Order/utils/orderCollectionIdentity.js +14 -11
- package/lib/modules/Order/utils.js +19 -1
- package/lib/modules/ResourcePlanner/planner.d.ts +2 -2
- package/lib/modules/ResourcePlanner/planner.js +137 -35
- package/lib/modules/ResourcePlanner/types.d.ts +17 -0
- package/lib/modules/Rules/index.js +230 -96
- package/lib/solution/BaseSales/index.d.ts +2 -0
- package/lib/solution/BaseSales/index.js +7 -1
- package/lib/solution/BaseSales/utils/cartPromotion.js +12 -4
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +2 -0
- package/lib/solution/ShopDiscount/index.d.ts +1 -0
- package/lib/solution/ShopDiscount/index.js +26 -6
- package/lib/solution/ShopDiscount/utils.js +3 -2
- package/lib/solution/UnifiedBookingSales/index.js +86 -22
- package/package.json +1 -1
|
@@ -27,6 +27,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
27
27
|
import { BaseModule } from "../../modules/BaseModule";
|
|
28
28
|
import { DiscountModule } from "../../modules/Discount";
|
|
29
29
|
import { RulesModule } from "../../modules/Rules";
|
|
30
|
+
import { isEntitlementPass } from "../../modules/Discount/entitlementPass";
|
|
30
31
|
import { filterDiscountListByBookingTime as _filterDiscountListByBookingTime, isAllNormalProduct } from "./utils";
|
|
31
32
|
import { UnavailableReason } from "../../modules/Rules/types";
|
|
32
33
|
import Decimal from 'decimal.js';
|
|
@@ -203,7 +204,8 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
203
204
|
customerId: customer.id,
|
|
204
205
|
action: 'create',
|
|
205
206
|
with_good_pass: 1,
|
|
206
|
-
with_discount_card: 1
|
|
207
|
+
with_discount_card: 1,
|
|
208
|
+
with_entitlement_pass: 1
|
|
207
209
|
});
|
|
208
210
|
});
|
|
209
211
|
}
|
|
@@ -622,7 +624,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
622
624
|
var _this3$hooks;
|
|
623
625
|
var product = (_this3$hooks = _this3.hooks) === null || _this3$hooks === void 0 ? void 0 : _this3$hooks.getProduct(item);
|
|
624
626
|
(item.discount_list || []).forEach(function (discount) {
|
|
625
|
-
if (discount.id && ['good_pass', 'discount_card'].includes(discount.type)) {
|
|
627
|
+
if (discount.id && ['entitlement_pass', 'good_pass', 'discount_card'].includes(discount.type)) {
|
|
626
628
|
var index = editModeDiscountList.findIndex(function (n) {
|
|
627
629
|
var _discount$discount;
|
|
628
630
|
return n.id === (((_discount$discount = discount.discount) === null || _discount$discount === void 0 ? void 0 : _discount$discount.resource_id) || discount.id);
|
|
@@ -789,7 +791,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
789
791
|
key: "loadPrepareConfig",
|
|
790
792
|
value: function () {
|
|
791
793
|
var _loadPrepareConfig = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(params) {
|
|
792
|
-
var _this$getCustomer2, _this$store$discount8, _this$getDiscountList, _this$store$discount9, _this$store$productLi2, orderId, customerId, prepareConfigResult, goodPassList, scanDiscount,
|
|
794
|
+
var _this$getCustomer2, _this$store$discount8, _this$getDiscountList, _this$store$discount9, _this$store$productLi2, orderId, customerId, prepareConfigResult, goodPassList, scanDiscount, scanDiscountById, refreshedScanEntitlementIds, newGoodPassList, retainedScanDiscounts, newDiscountList, filteredDiscountList, _result3;
|
|
793
795
|
return _regeneratorRuntime().wrap(function _callee10$(_context10) {
|
|
794
796
|
while (1) switch (_context10.prev = _context10.next) {
|
|
795
797
|
case 0:
|
|
@@ -805,6 +807,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
805
807
|
with_good_pass: 1,
|
|
806
808
|
with_discount_card: 1,
|
|
807
809
|
with_wallet_pass_holder: 1,
|
|
810
|
+
with_entitlement_pass: 1,
|
|
808
811
|
request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
809
812
|
}, orderId ? {
|
|
810
813
|
order_id: orderId
|
|
@@ -814,44 +817,61 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
814
817
|
goodPassList = (prepareConfigResult === null || prepareConfigResult === void 0 ? void 0 : prepareConfigResult.discountList) || [];
|
|
815
818
|
scanDiscount = (_this$getDiscountList = this.getDiscountList()) === null || _this$getDiscountList === void 0 ? void 0 : _this$getDiscountList.filter(function (item) {
|
|
816
819
|
return item.isScan;
|
|
817
|
-
}); //
|
|
818
|
-
|
|
819
|
-
|
|
820
|
+
}); // 扫码 Entitlement Pass 与客户列表重复时保留扫码选择状态,但刷新实时余额。
|
|
821
|
+
// 其他券继续沿用原来的“保留扫码结果、剔除列表重复项”行为。
|
|
822
|
+
scanDiscountById = new Map(scanDiscount.map(function (discount) {
|
|
823
|
+
return [String(discount.id), discount];
|
|
824
|
+
}));
|
|
825
|
+
refreshedScanEntitlementIds = new Set();
|
|
826
|
+
newGoodPassList = goodPassList.flatMap(function (discount) {
|
|
827
|
+
var key = String(discount.id);
|
|
828
|
+
var scannedDiscount = scanDiscountById.get(key);
|
|
829
|
+
if (!scannedDiscount) return [discount];
|
|
830
|
+
if (isEntitlementPass(scannedDiscount) && isEntitlementPass(discount)) {
|
|
831
|
+
var _scannedDiscount$isSe, _scannedDiscount$isMa;
|
|
832
|
+
refreshedScanEntitlementIds.add(key);
|
|
833
|
+
return [_objectSpread(_objectSpread({}, discount), {}, {
|
|
834
|
+
isScan: true,
|
|
835
|
+
isSelected: (_scannedDiscount$isSe = scannedDiscount.isSelected) !== null && _scannedDiscount$isSe !== void 0 ? _scannedDiscount$isSe : discount.isSelected,
|
|
836
|
+
isManualSelect: (_scannedDiscount$isMa = scannedDiscount.isManualSelect) !== null && _scannedDiscount$isMa !== void 0 ? _scannedDiscount$isMa : discount.isManualSelect
|
|
837
|
+
})];
|
|
838
|
+
}
|
|
839
|
+
return [];
|
|
820
840
|
});
|
|
821
|
-
|
|
822
|
-
return !
|
|
841
|
+
retainedScanDiscounts = scanDiscount.filter(function (discount) {
|
|
842
|
+
return !refreshedScanEntitlementIds.has(String(discount.id));
|
|
823
843
|
});
|
|
824
|
-
newDiscountList = [].concat(_toConsumableArray(
|
|
844
|
+
newDiscountList = [].concat(_toConsumableArray(retainedScanDiscounts), _toConsumableArray(newGoodPassList)); // 存储原始优惠券列表
|
|
825
845
|
this.store.originalDiscountList = newDiscountList;
|
|
826
|
-
_context10.next =
|
|
846
|
+
_context10.next = 16;
|
|
827
847
|
return (_this$store$discount9 = this.store.discount) === null || _this$store$discount9 === void 0 ? void 0 : _this$store$discount9.setOriginalDiscountList(newDiscountList);
|
|
828
|
-
case
|
|
848
|
+
case 16:
|
|
829
849
|
// 根据当前预约时间过滤优惠券列表
|
|
830
850
|
filteredDiscountList = this.filterDiscountListByBookingTime(newDiscountList, this.store.currentBookingTime);
|
|
831
851
|
this.store.filteredDiscountList = filteredDiscountList;
|
|
832
852
|
this.setDiscountList(filteredDiscountList || []);
|
|
833
853
|
if (!((_this$store$productLi2 = this.store.productList) !== null && _this$store$productLi2 !== void 0 && _this$store$productLi2.length)) {
|
|
834
|
-
_context10.next =
|
|
854
|
+
_context10.next = 23;
|
|
835
855
|
break;
|
|
836
856
|
}
|
|
837
857
|
_result3 = this.calcDiscount(this.store.productList);
|
|
838
|
-
_context10.next = 21;
|
|
839
|
-
return this.core.effects.emit("".concat(this.name, ":onLoadPrepareCalcResult"), _result3);
|
|
840
|
-
case 21:
|
|
841
858
|
_context10.next = 23;
|
|
842
|
-
return this.core.effects.emit("".concat(this.name, ":
|
|
859
|
+
return this.core.effects.emit("".concat(this.name, ":onLoadPrepareCalcResult"), _result3);
|
|
843
860
|
case 23:
|
|
844
|
-
_context10.next =
|
|
845
|
-
|
|
861
|
+
_context10.next = 25;
|
|
862
|
+
return this.core.effects.emit("".concat(this.name, ":onLoadDiscountList"), filteredDiscountList);
|
|
846
863
|
case 25:
|
|
847
|
-
_context10.
|
|
864
|
+
_context10.next = 30;
|
|
865
|
+
break;
|
|
866
|
+
case 27:
|
|
867
|
+
_context10.prev = 27;
|
|
848
868
|
_context10.t0 = _context10["catch"](0);
|
|
849
869
|
console.error('[ShopDiscount] 加载准备配置出错:', _context10.t0);
|
|
850
|
-
case
|
|
870
|
+
case 30:
|
|
851
871
|
case "end":
|
|
852
872
|
return _context10.stop();
|
|
853
873
|
}
|
|
854
|
-
}, _callee10, this, [[0,
|
|
874
|
+
}, _callee10, this, [[0, 27]]);
|
|
855
875
|
}));
|
|
856
876
|
function loadPrepareConfig(_x10) {
|
|
857
877
|
return _loadPrepareConfig.apply(this, arguments);
|
|
@@ -9,6 +9,7 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
|
|
|
9
9
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
10
10
|
import Decimal from "decimal.js";
|
|
11
11
|
import dayjs from "dayjs";
|
|
12
|
+
import { isFullCoveragePass } from "../../modules/Discount/entitlementPass";
|
|
12
13
|
export var uniqueById = function uniqueById(arr) {
|
|
13
14
|
var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'id';
|
|
14
15
|
var seen = new Set();
|
|
@@ -41,8 +42,8 @@ export var isAllNormalProduct = function isAllNormalProduct(items) {
|
|
|
41
42
|
*/
|
|
42
43
|
export var getDiscountAmount = function getDiscountAmount(discount, total, price) {
|
|
43
44
|
var _discount$metadata;
|
|
44
|
-
//
|
|
45
|
-
if (discount
|
|
45
|
+
// 商品券和 Entitlement Pass 都是全额抵扣。
|
|
46
|
+
if (isFullCoveragePass(discount)) {
|
|
46
47
|
return new Decimal(price).minus(new Decimal(price || 0)).toNumber();
|
|
47
48
|
}
|
|
48
49
|
|
|
@@ -142,7 +142,7 @@ export function buildPlannerDiscountResult(params) {
|
|
|
142
142
|
productDiscounts.forEach(function (discount) {
|
|
143
143
|
var _product$product_id, _product$metadata;
|
|
144
144
|
var type = discount.tag || discount.type;
|
|
145
|
-
if (!['good_pass', 'discount_card', 'product_discount_card'].includes(type)) return;
|
|
145
|
+
if (!['entitlement_pass', 'good_pass', 'discount_card', 'product_discount_card'].includes(type)) return;
|
|
146
146
|
var discountId = resolvePlannerDiscountId(discount);
|
|
147
147
|
applications.push({
|
|
148
148
|
discountId: discountId,
|
|
@@ -194,7 +194,7 @@ function isLocalOrderId(orderId) {
|
|
|
194
194
|
function isCustomerBoundDiscount(discount) {
|
|
195
195
|
var _discount$type;
|
|
196
196
|
var type = (_discount$type = discount === null || discount === void 0 ? void 0 : discount.type) !== null && _discount$type !== void 0 ? _discount$type : discount === null || discount === void 0 ? void 0 : discount.tag;
|
|
197
|
-
return type === 'good_pass' || type === 'discount_card' || type === 'product_discount_card';
|
|
197
|
+
return type === 'entitlement_pass' || type === 'good_pass' || type === 'discount_card' || type === 'product_discount_card';
|
|
198
198
|
}
|
|
199
199
|
function filterCustomerBoundDiscounts(discountList) {
|
|
200
200
|
if (!Array.isArray(discountList)) return [];
|
|
@@ -674,14 +674,9 @@ function normalizeResource(raw) {
|
|
|
674
674
|
var id = (_ref5 = (_raw$resourceId = raw.resourceId) !== null && _raw$resourceId !== void 0 ? _raw$resourceId : raw.resource_id) !== null && _ref5 !== void 0 ? _ref5 : raw.id;
|
|
675
675
|
if (id === undefined || id === null || id === '') return null;
|
|
676
676
|
var rawWindows = raw.windows || raw.times || [];
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
name: raw.resourceName || raw.main_field || raw.name || raw.title,
|
|
681
|
-
code: raw.code,
|
|
682
|
-
resourceType: normalizeResourceType(raw.type || raw.resourceType),
|
|
683
|
-
capacity: Math.max(1, Number(raw.capacity || raw.max_capacity || 1) || 1),
|
|
684
|
-
windows: (Array.isArray(rawWindows) ? rawWindows : []).flatMap(function (window) {
|
|
677
|
+
var rawExcludedWindows = raw.excludedWindows || raw.excluded_windows || [];
|
|
678
|
+
var normalizeWindows = function normalizeWindows(windows) {
|
|
679
|
+
return (Array.isArray(windows) ? windows : []).flatMap(function (window) {
|
|
685
680
|
var range = normalizeAvailabilityLocalDateTimeRange({
|
|
686
681
|
startAt: window.startAt || window.start_at || window.start,
|
|
687
682
|
endAt: window.endAt || window.end_at || window.end,
|
|
@@ -695,7 +690,17 @@ function normalizeResource(raw) {
|
|
|
695
690
|
source: window.source,
|
|
696
691
|
raw: window
|
|
697
692
|
}];
|
|
698
|
-
})
|
|
693
|
+
});
|
|
694
|
+
};
|
|
695
|
+
return {
|
|
696
|
+
id: id,
|
|
697
|
+
formId: (_ref6 = (_raw$formId = raw.formId) !== null && _raw$formId !== void 0 ? _raw$formId : raw.form_id) !== null && _ref6 !== void 0 ? _ref6 : raw.resource_form_id,
|
|
698
|
+
name: raw.resourceName || raw.main_field || raw.name || raw.title,
|
|
699
|
+
code: raw.code,
|
|
700
|
+
resourceType: normalizeResourceType(raw.type || raw.resourceType),
|
|
701
|
+
capacity: Math.max(1, Number(raw.capacity || raw.max_capacity || 1) || 1),
|
|
702
|
+
windows: normalizeWindows(rawWindows),
|
|
703
|
+
excludedWindows: normalizeWindows(rawExcludedWindows),
|
|
699
704
|
raw: raw
|
|
700
705
|
};
|
|
701
706
|
}
|
|
@@ -719,6 +724,16 @@ function dateRangeDays(dateRange) {
|
|
|
719
724
|
}
|
|
720
725
|
return dates;
|
|
721
726
|
}
|
|
727
|
+
function getExcludedScheduleDateOverrideTimePoints(date, schedule) {
|
|
728
|
+
var _schedule$repeat_rule;
|
|
729
|
+
if (!((_schedule$repeat_rule = schedule.repeat_rule) !== null && _schedule$repeat_rule !== void 0 && (_schedule$repeat_rule = _schedule$repeat_rule.excluded_date) !== null && _schedule$repeat_rule !== void 0 && _schedule$repeat_rule.length)) return [];
|
|
730
|
+
if (getScheduleStartEndTimePoints(date, [schedule]).length > 0) return [];
|
|
731
|
+
return getScheduleStartEndTimePoints(date, [_objectSpread(_objectSpread({}, schedule), {}, {
|
|
732
|
+
repeat_rule: _objectSpread(_objectSpread({}, schedule.repeat_rule), {}, {
|
|
733
|
+
excluded_date: []
|
|
734
|
+
})
|
|
735
|
+
})]);
|
|
736
|
+
}
|
|
722
737
|
function normalizeResourceOccupancy(rawEvent, resourceId) {
|
|
723
738
|
var _ref9, _ref10, _rawEvent$start_at, _ref11, _ref12, _rawEvent$end_at, _ref13, _ref14, _rawEvent$pax, _rawEvent$schedule_ev, _ref15, _rawEvent$schedule_ev2, _ref16, _rawEvent$booking_uid, _rawEvent$metadata, _ref17, _rawEvent$product_uid, _rawEvent$metadata2;
|
|
724
739
|
var source = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'remote';
|
|
@@ -825,7 +840,30 @@ export function buildAvailabilityResourcesFromV2(params) {
|
|
|
825
840
|
});
|
|
826
841
|
});
|
|
827
842
|
});
|
|
843
|
+
var excludedWindows = dates.flatMap(function (date) {
|
|
844
|
+
return schedules.flatMap(function (schedule) {
|
|
845
|
+
return getExcludedScheduleDateOverrideTimePoints(date, schedule).flatMap(function (slot) {
|
|
846
|
+
var range = normalizeAvailabilityLocalDateTimeRange({
|
|
847
|
+
startAt: slot.start_at,
|
|
848
|
+
endAt: slot.end_at,
|
|
849
|
+
fixedOffsetMinutes: fixedOffsetMinutes,
|
|
850
|
+
rollOverEnd: true
|
|
851
|
+
});
|
|
852
|
+
if (!range) return [];
|
|
853
|
+
return [{
|
|
854
|
+
startAt: range.startAt,
|
|
855
|
+
endAt: range.endAt,
|
|
856
|
+
source: "resource_schedule_excluded:".concat(schedule.id),
|
|
857
|
+
raw: {
|
|
858
|
+
scheduleId: schedule.id,
|
|
859
|
+
excludedDate: date
|
|
860
|
+
}
|
|
861
|
+
}];
|
|
862
|
+
});
|
|
863
|
+
});
|
|
864
|
+
});
|
|
828
865
|
resource.windows = materializedWindows.length > 0 ? materializedWindows : explicitWindows;
|
|
866
|
+
resource.excludedWindows = [].concat(_toConsumableArray(resource.excludedWindows || []), _toConsumableArray(excludedWindows));
|
|
829
867
|
if (resource.windows.length === 0 && missingScheduleIds.length > 0) {
|
|
830
868
|
resource.windows = buildResourceWindowFallbackTimes({
|
|
831
869
|
raw: raw,
|
|
@@ -1093,7 +1131,7 @@ function buildBookingFromAvailabilitySelection(params) {
|
|
|
1093
1131
|
} : {})
|
|
1094
1132
|
});
|
|
1095
1133
|
}
|
|
1096
|
-
var POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cutoff', 'resource_full', 'resource_unavailable', 'resource_capacity_exceeded',
|
|
1134
|
+
var POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cutoff', 'schedule_excluded_date', 'resource_full', 'resource_unavailable', 'resource_capacity_exceeded',
|
|
1097
1135
|
// A required group whose selected resource is outside its window is surfaced
|
|
1098
1136
|
// as missing_resource at group level. Structural validation below still
|
|
1099
1137
|
// rejects a genuinely missing selection.
|
|
@@ -3133,12 +3171,35 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
3133
3171
|
}] : [];
|
|
3134
3172
|
});
|
|
3135
3173
|
});
|
|
3136
|
-
|
|
3174
|
+
var excludedWindows = dateRangeDays(params.dateRange).flatMap(function (date) {
|
|
3175
|
+
return schedules.flatMap(function (schedule) {
|
|
3176
|
+
return getExcludedScheduleDateOverrideTimePoints(date, schedule).flatMap(function (slot) {
|
|
3177
|
+
var range = normalizeAvailabilityLocalDateTimeRange({
|
|
3178
|
+
startAt: slot.start_at,
|
|
3179
|
+
endAt: slot.end_at,
|
|
3180
|
+
fixedOffsetMinutes: _this3.getAvailabilityRuntimeOffsetMinutes(),
|
|
3181
|
+
rollOverEnd: true
|
|
3182
|
+
});
|
|
3183
|
+
return range ? [{
|
|
3184
|
+
startAt: range.startAt,
|
|
3185
|
+
endAt: range.endAt,
|
|
3186
|
+
source: "operating_schedule_excluded:".concat(schedule.id),
|
|
3187
|
+
raw: {
|
|
3188
|
+
scheduleId: schedule.id,
|
|
3189
|
+
excludedDate: date
|
|
3190
|
+
}
|
|
3191
|
+
}] : [];
|
|
3192
|
+
});
|
|
3193
|
+
});
|
|
3194
|
+
});
|
|
3195
|
+
return _objectSpread({
|
|
3137
3196
|
source: descriptor.source,
|
|
3138
3197
|
scheduleIds: _toConsumableArray(descriptor.scheduleIds),
|
|
3139
3198
|
missingScheduleIds: missingScheduleIds,
|
|
3140
3199
|
windows: windows
|
|
3141
|
-
}
|
|
3200
|
+
}, excludedWindows.length > 0 ? {
|
|
3201
|
+
excludedWindows: excludedWindows
|
|
3202
|
+
} : {});
|
|
3142
3203
|
}
|
|
3143
3204
|
}, {
|
|
3144
3205
|
key: "loadAvailabilityProducts",
|
|
@@ -4312,7 +4373,9 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4312
4373
|
allowOutsideOperatingHoursForRequestedStartTimes: true
|
|
4313
4374
|
} : {}), {
|
|
4314
4375
|
evaluatedAt: this.getAvailabilityRuntimeDateTime(),
|
|
4315
|
-
|
|
4376
|
+
useExactDurationCandidateMinute: isPosAvailabilityRequest,
|
|
4377
|
+
allowSessionCustomRanges: isPosAvailabilityRequest,
|
|
4378
|
+
allowExcludedScheduleDateOverride: isPosAvailabilityRequest
|
|
4316
4379
|
}).map(function (group) {
|
|
4317
4380
|
return _objectSpread(_objectSpread({}, group), {}, {
|
|
4318
4381
|
ranges: group.ranges.map(function (candidate) {
|
|
@@ -4335,7 +4398,8 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4335
4398
|
key: "queryBookingAvailability",
|
|
4336
4399
|
value: (function () {
|
|
4337
4400
|
var _queryBookingAvailability = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee38(contextId, request) {
|
|
4338
|
-
var
|
|
4401
|
+
var _this$otherParams$pla3, _this$otherParams21;
|
|
4402
|
+
var _yield$this$ensureAva2, context, projectionEntry, refreshed, isPosAvailabilityRequest, result, contextVersion, contextualResult;
|
|
4339
4403
|
return _regeneratorRuntime().wrap(function _callee38$(_context38) {
|
|
4340
4404
|
while (1) switch (_context38.prev = _context38.next) {
|
|
4341
4405
|
case 0:
|
|
@@ -4347,7 +4411,11 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4347
4411
|
projectionEntry = _yield$this$ensureAva2.projectionEntry;
|
|
4348
4412
|
refreshed = _yield$this$ensureAva2.refreshed;
|
|
4349
4413
|
this.assertContextualQueryFreshness(context, request);
|
|
4350
|
-
|
|
4414
|
+
isPosAvailabilityRequest = String((_this$otherParams$pla3 = (_this$otherParams21 = this.otherParams) === null || _this$otherParams21 === void 0 ? void 0 : _this$otherParams21.platform) !== null && _this$otherParams$pla3 !== void 0 ? _this$otherParams$pla3 : '').trim().toLowerCase() === 'pos';
|
|
4415
|
+
result = queryAvailabilityProjection(projectionEntry.projection, request, {
|
|
4416
|
+
useExactDurationCandidateMinute: isPosAvailabilityRequest,
|
|
4417
|
+
allowExcludedScheduleDateOverride: isPosAvailabilityRequest
|
|
4418
|
+
});
|
|
4351
4419
|
contextVersion = context.activeVersion;
|
|
4352
4420
|
contextualResult = result.target === 'time' ? _objectSpread(_objectSpread({}, result), {}, {
|
|
4353
4421
|
data: result.data.map(function (group) {
|
|
@@ -4379,7 +4447,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4379
4447
|
contextVersion: contextVersion,
|
|
4380
4448
|
refreshed: refreshed
|
|
4381
4449
|
}));
|
|
4382
|
-
case
|
|
4450
|
+
case 12:
|
|
4383
4451
|
case "end":
|
|
4384
4452
|
return _context38.stop();
|
|
4385
4453
|
}
|
|
@@ -4456,7 +4524,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4456
4524
|
key: "commitAvailabilitySelection",
|
|
4457
4525
|
value: (function () {
|
|
4458
4526
|
var _commitAvailabilitySelection = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee39(contextId, params) {
|
|
4459
|
-
var normalizedContextId, _params$bookingCount, _ref46, _params$orderProduct$, _params$orderProduct, _params$orderProduct2, _params$orderProduct3, _params$orderProduct$2, _params$orderProduct4, _params$orderProduct5, _editingLine$product_, _baseProjection$meta$, _refreshedProjection$, _baseProjection$meta$2, _this$otherParams$
|
|
4527
|
+
var normalizedContextId, _params$bookingCount, _ref46, _params$orderProduct$, _params$orderProduct, _params$orderProduct2, _params$orderProduct3, _params$orderProduct$2, _params$orderProduct4, _params$orderProduct5, _editingLine$product_, _baseProjection$meta$, _refreshedProjection$, _baseProjection$meta$2, _this$otherParams$pla4, _this$otherParams22, _ref47, _params$orderProduct$3, _params$orderProduct6, _existingBooking$meta, _ref48, _ref49, _params$orderProduct$4, _params$orderProduct7, _params$orderProduct8, _existingBooking$meta2, _existingBooking$hold, bookingCount, orderProductQuantity, partySize, _yield$this$ensureAva3, context, projectionEntry, refreshed, boundEditingUids, orderProductId, editingLine, _editingLine$product_2, baseProjection, commitWriteGuard, prepareParams, fallbackResources, commitSnapshot, refreshedProjection, _baseProjection$meta$3, latestContext, candidateDurationMinutes, candidateStartTime, allowPosAvailabilityOverride, refreshedRanges, refreshedCandidateBase, product, validation, forced, capacityConflict, revalidationEntry, revalidatedContext, refreshedCandidate, existingBooking, existingBookingUid, booking, transformed, productLineUid, bookingUid, productLineUids, bookingUids, _transformed$product_, _transformed$product_2, _transformed$product_3, _ref50, _transformed$product_4, _this$getTempOrder4, _this$getTempOrder5, _this$getTempOrder6, beforeProductLineUids, beforeBookingUids, products, addedLines, addedBookings, nextContext, result;
|
|
4460
4528
|
return _regeneratorRuntime().wrap(function _callee39$(_context39) {
|
|
4461
4529
|
while (1) switch (_context39.prev = _context39.next) {
|
|
4462
4530
|
case 0:
|
|
@@ -4686,7 +4754,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4686
4754
|
this.assertAvailabilityCommitWriteCAS(commitWriteGuard);
|
|
4687
4755
|
candidateDurationMinutes = getCandidateDurationMinutes(params.candidate);
|
|
4688
4756
|
candidateStartTime = getCandidateStartTime(params.candidate);
|
|
4689
|
-
allowPosAvailabilityOverride = String((_this$otherParams$
|
|
4757
|
+
allowPosAvailabilityOverride = String((_this$otherParams$pla4 = (_this$otherParams22 = this.otherParams) === null || _this$otherParams22 === void 0 ? void 0 : _this$otherParams22.platform) !== null && _this$otherParams$pla4 !== void 0 ? _this$otherParams$pla4 : '').trim().toLowerCase() === 'pos';
|
|
4690
4758
|
refreshedRanges = getProjectionProductTimeRanges(refreshedProjection, _objectSpread({
|
|
4691
4759
|
productIds: [params.candidate.productId],
|
|
4692
4760
|
dateRange: {
|
|
@@ -4700,7 +4768,9 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4700
4768
|
}, allowPosAvailabilityOverride ? {
|
|
4701
4769
|
allowOutsideOperatingHoursForRequestedStartTimes: true
|
|
4702
4770
|
} : {}) : {}) : {}), {
|
|
4703
|
-
|
|
4771
|
+
useExactDurationCandidateMinute: allowPosAvailabilityOverride,
|
|
4772
|
+
allowSessionCustomRanges: allowPosAvailabilityOverride,
|
|
4773
|
+
allowExcludedScheduleDateOverride: allowPosAvailabilityOverride
|
|
4704
4774
|
}).flatMap(function (group) {
|
|
4705
4775
|
return group.ranges;
|
|
4706
4776
|
});
|
|
@@ -4733,6 +4803,9 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4733
4803
|
requirementSelections: params.requirementSelections,
|
|
4734
4804
|
partySize: partySize,
|
|
4735
4805
|
bookingCount: bookingCount
|
|
4806
|
+
}, {
|
|
4807
|
+
useExactDurationCandidateMinute: allowPosAvailabilityOverride,
|
|
4808
|
+
allowExcludedScheduleDateOverride: allowPosAvailabilityOverride
|
|
4736
4809
|
});
|
|
4737
4810
|
if (allowPosAvailabilityOverride && !validation.ok && validation.conflicts.every(function (conflict) {
|
|
4738
4811
|
return POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES.has(conflict.code);
|
|
@@ -7,6 +7,7 @@ exports.buildCacheItemFromOrderLine = buildCacheItemFromOrderLine;
|
|
|
7
7
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
8
8
|
var _utils = require("../../Order/utils");
|
|
9
9
|
var _manualProductDiscount = require("../../Order/utils/manualProductDiscount");
|
|
10
|
+
var _entitlementPass = require("../../Discount/entitlementPass");
|
|
10
11
|
var _orderLineDisplay = require("./orderLineDisplay");
|
|
11
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
13
|
function safeFormat(value, fmt) {
|
|
@@ -116,11 +117,38 @@ function resolveProductTitle(product, booking, sourceProduct) {
|
|
|
116
117
|
function resolveProductCover(product, booking, sourceProduct) {
|
|
117
118
|
return sourceProduct?.cover ?? product.product_cover ?? '';
|
|
118
119
|
}
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
const value = metadata.main_product_original_price ?? metadata.source_product_price;
|
|
120
|
+
function toFinitePrice(value) {
|
|
121
|
+
if (value === undefined || value === null || value === '') return null;
|
|
122
122
|
const parsed = Number(value);
|
|
123
|
-
return Number.isFinite(parsed) ? parsed :
|
|
123
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
124
|
+
}
|
|
125
|
+
function hasEntitlementPassDiscount(product) {
|
|
126
|
+
const hasEntitlementDiscount = discountList => Array.isArray(discountList) && discountList.some(_entitlementPass.isEntitlementPass);
|
|
127
|
+
return hasEntitlementDiscount(product.discount_list) || Array.isArray(product.product_bundle) && product.product_bundle.some(bundle => hasEntitlementDiscount(bundle?.discount_list));
|
|
128
|
+
}
|
|
129
|
+
function resolveMainProductPrice(product, fallback, sourceProduct, restoreEntitlementPrice = false) {
|
|
130
|
+
const metadata = product.metadata || {};
|
|
131
|
+
if (!restoreEntitlementPrice) {
|
|
132
|
+
const value = metadata.main_product_original_price ?? metadata.source_product_price;
|
|
133
|
+
const parsed = Number(value);
|
|
134
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
135
|
+
}
|
|
136
|
+
const sourcePrice = toFinitePrice(metadata.source_product_price);
|
|
137
|
+
if (sourcePrice !== null) return sourcePrice;
|
|
138
|
+
const variantId = Number(product.product_variant_id || 0);
|
|
139
|
+
const variantList = sourceProduct?.variant ?? metadata.origin?.variant;
|
|
140
|
+
if (variantId > 0 && Array.isArray(variantList)) {
|
|
141
|
+
const matched = variantList.find(variant => Number(variant?.id) === variantId);
|
|
142
|
+
const variantPrice = toFinitePrice(matched?.price ?? matched?.base_price);
|
|
143
|
+
if (variantPrice !== null) return variantPrice;
|
|
144
|
+
}
|
|
145
|
+
const catalogPrice = toFinitePrice(sourceProduct?.price ?? sourceProduct?.base_price ?? metadata.origin?.price ?? metadata.origin?.base_price);
|
|
146
|
+
if (catalogPrice !== null) return catalogPrice;
|
|
147
|
+
|
|
148
|
+
// legacy 数据没有 source_product_price 时,main_product_original_price
|
|
149
|
+
// 仍比已被月卡改写为 0 的 selling_price 更可靠。
|
|
150
|
+
const legacyMainPrice = toFinitePrice(metadata.main_product_original_price);
|
|
151
|
+
return legacyMainPrice ?? fallback;
|
|
124
152
|
}
|
|
125
153
|
function mapOrderBundleToOtherBundle(bundle) {
|
|
126
154
|
return bundle.map(item => {
|
|
@@ -185,7 +213,8 @@ function buildCacheItemFromOrderLine(input) {
|
|
|
185
213
|
const resolvedId = product.product_id ?? sourceProduct?.id;
|
|
186
214
|
const selling = Number(product.selling_price ?? 0);
|
|
187
215
|
const original = Number(product.original_price ?? selling);
|
|
188
|
-
const
|
|
216
|
+
const shouldRestoreEntitlementPrice = hasEntitlementPassDiscount(product);
|
|
217
|
+
const mainProductPrice = resolveMainProductPrice(product, selling, sourceProduct, shouldRestoreEntitlementPrice);
|
|
189
218
|
const startDate = safeFormat(booking.start_date, 'YYYY-MM-DD');
|
|
190
219
|
const endDate = safeFormat(booking.end_date, 'YYYY-MM-DD');
|
|
191
220
|
const startTime = normalizeTimeString(booking.start_time);
|
|
@@ -240,7 +269,7 @@ function buildCacheItemFromOrderLine(input) {
|
|
|
240
269
|
}
|
|
241
270
|
}
|
|
242
271
|
if (product.metadata?.price_override != null || manualDiscount) {
|
|
243
|
-
extend.priceOverride = selling;
|
|
272
|
+
extend.priceOverride = shouldRestoreEntitlementPrice ? product.metadata?.price_override ?? selling : selling;
|
|
244
273
|
}
|
|
245
274
|
if (booking.holder !== undefined) {
|
|
246
275
|
extend.holder = booking.holder;
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.buildNormalProductCacheItemFromOrderLine = buildNormalProductCacheItemFromOrderLine;
|
|
7
7
|
var _utils = require("../../Order/utils");
|
|
8
|
+
var _entitlementPass = require("../../Discount/entitlementPass");
|
|
8
9
|
var _orderLineDisplay = require("./orderLineDisplay");
|
|
9
10
|
/**
|
|
10
11
|
* 从已加车的普通商品 order line 反查 SkuDetailModal edit 所需的 cacheItem。
|
|
@@ -44,12 +45,16 @@ function resolveSourceProductPrice(product, sourceProduct) {
|
|
|
44
45
|
}
|
|
45
46
|
return Number(product.selling_price ?? 0);
|
|
46
47
|
}
|
|
48
|
+
function hasEntitlementPassDiscount(product) {
|
|
49
|
+
const hasEntitlementDiscount = discountList => Array.isArray(discountList) && discountList.some(_entitlementPass.isEntitlementPass);
|
|
50
|
+
return hasEntitlementDiscount(product.discount_list) || Array.isArray(product.product_bundle) && product.product_bundle.some(bundle => hasEntitlementDiscount(bundle?.discount_list));
|
|
51
|
+
}
|
|
47
52
|
|
|
48
53
|
/** 订单行 bundle → booking other.bundle(保留 original_price 供 setProductPrice 按比例分摊) */
|
|
49
|
-
function mapOrderBundleToOtherBundle(bundle) {
|
|
54
|
+
function mapOrderBundleToOtherBundle(bundle, preferManualPrice = false) {
|
|
50
55
|
return bundle.map(item => {
|
|
51
56
|
const catalogOriginal = item.original_price ?? item.product_price ?? item.price ?? item.bundle_selling_price;
|
|
52
|
-
const selling = item.bundle_selling_price ?? item.price ?? catalogOriginal;
|
|
57
|
+
const selling = preferManualPrice ? item.price ?? item.bundle_selling_price ?? catalogOriginal : item.bundle_selling_price ?? item.price ?? catalogOriginal;
|
|
53
58
|
const {
|
|
54
59
|
bundle_selling_price: _omitBundleSelling,
|
|
55
60
|
...rest
|
|
@@ -78,9 +83,11 @@ function buildNormalProductCacheItemFromOrderLine(input) {
|
|
|
78
83
|
const selling = Number(product.selling_price ?? 0);
|
|
79
84
|
const original = Number(product.original_price ?? selling);
|
|
80
85
|
const uid = product.metadata?.unique_identification_number;
|
|
81
|
-
const option = (0, _utils.getProductSkuOptions)(product);
|
|
82
|
-
const bundle = mapOrderBundleToOtherBundle(Array.isArray(product.product_bundle) ? product.product_bundle : []);
|
|
83
86
|
const originExtend = product.metadata?.origin?._extend;
|
|
87
|
+
const shouldPreserveEntitlementPriceOverride = hasEntitlementPassDiscount(product) && (originExtend?.priceOverride !== undefined || product.metadata?.price_override != null);
|
|
88
|
+
const hasPriceOverride = originExtend?.priceOverride !== undefined || shouldPreserveEntitlementPriceOverride;
|
|
89
|
+
const option = (0, _utils.getProductSkuOptions)(product);
|
|
90
|
+
const bundle = mapOrderBundleToOtherBundle(Array.isArray(product.product_bundle) ? product.product_bundle : [], shouldPreserveEntitlementPriceOverride);
|
|
84
91
|
const productOptionString = (0, _orderLineDisplay.buildProductOptionStringFromOrderLine)(product);
|
|
85
92
|
const discountList = product.discount_list || [];
|
|
86
93
|
const other = {
|
|
@@ -114,8 +121,8 @@ function buildNormalProductCacheItemFromOrderLine(input) {
|
|
|
114
121
|
...(productOptionString ? {
|
|
115
122
|
product_option_string: productOptionString
|
|
116
123
|
} : {}),
|
|
117
|
-
...(
|
|
118
|
-
priceOverride: originExtend.priceOverride
|
|
124
|
+
...(hasPriceOverride ? {
|
|
125
|
+
priceOverride: shouldPreserveEntitlementPriceOverride ? originExtend?.priceOverride ?? product.metadata?.price_override : originExtend?.priceOverride
|
|
119
126
|
} : {}),
|
|
120
127
|
...(originExtend?.bundle_edit !== undefined ? {
|
|
121
128
|
bundle_edit: originExtend.bundle_edit
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare const ENTITLEMENT_PASS_TYPE = "entitlement_pass";
|
|
2
|
+
export declare const GOOD_PASS_TYPE = "good_pass";
|
|
3
|
+
type DiscountLike = {
|
|
4
|
+
id?: number | string | null;
|
|
5
|
+
tag?: unknown;
|
|
6
|
+
type?: unknown;
|
|
7
|
+
discount?: object | null;
|
|
8
|
+
metadata?: object | null;
|
|
9
|
+
extension_data?: unknown;
|
|
10
|
+
balance?: unknown;
|
|
11
|
+
expire_time?: unknown;
|
|
12
|
+
};
|
|
13
|
+
export type EntitlementQuota = {
|
|
14
|
+
type: 'limited';
|
|
15
|
+
value: number;
|
|
16
|
+
balance: number;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'unlimited';
|
|
19
|
+
value: null;
|
|
20
|
+
balance: null;
|
|
21
|
+
};
|
|
22
|
+
export declare function isEntitlementPass(discount: DiscountLike | null | undefined): boolean;
|
|
23
|
+
export declare function isFullCoveragePass(discount: DiscountLike | null | undefined): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the authoritative total-use contract for an Entitlement Pass.
|
|
26
|
+
* Invalid or missing configuration fails closed. Legacy mode/total_uses fields
|
|
27
|
+
* are intentionally unsupported.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveEntitlementQuota(discount: DiscountLike | null | undefined): EntitlementQuota | null;
|
|
30
|
+
export declare function getRemainingEntitlementUses(discount: DiscountLike | null | undefined, usedCount: number, requestedCount: number): number;
|
|
31
|
+
export declare function hasAvailableEntitlementUses(discount: DiscountLike | null | undefined): boolean;
|
|
32
|
+
/** Sort Entitlement Passes by expiry, finite balance, then card instance id. */
|
|
33
|
+
export declare function compareEntitlementPassPriority(left: DiscountLike, right: DiscountLike): number;
|
|
34
|
+
export {};
|