@pisell/pisellos 2.2.314 → 2.2.316
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/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
- package/dist/model/strategy/adapter/itemRule/adapter.js +74 -7
- package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
- package/dist/model/strategy/adapter/itemRule/evaluator.js +13 -0
- package/dist/model/strategy/adapter/itemRule/type.d.ts +40 -1
- package/dist/model/strategy/adapter/itemRule/type.js +10 -0
- package/dist/model/strategy/adapter/promotion/evaluator.js +89 -104
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +28 -4
- package/dist/modules/BookingContext/utils/productExtend.d.ts +7 -0
- package/dist/modules/BookingContext/utils/productExtend.js +62 -18
- package/dist/modules/BookingContext/utils/resources.js +1 -1
- package/dist/modules/BusinessAvailability/index.d.ts +30 -0
- package/dist/modules/BusinessAvailability/index.js +204 -0
- package/dist/modules/Cart/index.js +4 -3
- package/dist/modules/Cart/types.d.ts +2 -0
- package/dist/modules/Cart/utils/cartProduct.d.ts +3 -1
- package/dist/modules/Cart/utils/cartProduct.js +59 -32
- package/dist/modules/FulfillmentTiming/index.d.ts +11 -0
- package/dist/modules/FulfillmentTiming/index.js +407 -0
- package/dist/modules/FulfillmentTiming/types.d.ts +67 -0
- package/dist/modules/FulfillmentTiming/types.js +1 -0
- package/dist/modules/Holder/utils.d.ts +2 -0
- package/dist/modules/Holder/utils.js +32 -2
- package/dist/modules/OpenData/contactInfo.d.ts +20 -0
- package/dist/modules/OpenData/contactInfo.js +70 -0
- package/dist/modules/OpenData/index.d.ts +1 -0
- package/dist/modules/OpenData/index.js +1 -0
- package/dist/modules/OpenData/types.d.ts +23 -0
- package/dist/modules/Order/holderRelations.d.ts +14 -0
- package/dist/modules/Order/holderRelations.js +154 -0
- package/dist/modules/Order/index.d.ts +16 -4
- package/dist/modules/Order/index.js +926 -511
- package/dist/modules/Order/localEftposState.d.ts +13 -0
- package/dist/modules/Order/localEftposState.js +39 -0
- package/dist/modules/Order/pickupTiming.d.ts +46 -0
- package/dist/modules/Order/pickupTiming.js +53 -0
- package/dist/modules/Order/types.d.ts +49 -3
- package/dist/modules/Order/types.js +2 -0
- package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
- package/dist/modules/Order/utils/discountProductLineIdentity.js +142 -7
- package/dist/modules/Order/utils/orderCollectionIdentity.js +24 -10
- package/dist/modules/Order/utils.d.ts +2 -1
- package/dist/modules/Order/utils.js +61 -17
- package/dist/modules/Payment/index.js +9 -10
- package/dist/modules/Product/types.d.ts +11 -0
- package/dist/modules/ProductList/index.js +1 -1
- package/dist/modules/ResourcePlanner/planner.d.ts +2 -0
- package/dist/modules/ResourcePlanner/planner.js +332 -23
- package/dist/modules/ResourcePlanner/types.d.ts +29 -0
- package/dist/modules/Rules/index.js +62 -61
- package/dist/modules/Schedule/index.d.ts +8 -0
- package/dist/modules/Schedule/index.js +141 -39
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +1 -0
- package/dist/plugins/request.d.ts +7 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1557 -1322
- package/dist/server/modules/form/index.d.ts +19 -0
- package/dist/server/modules/form/index.js +205 -0
- package/dist/server/modules/form/types.d.ts +13 -0
- package/dist/server/modules/form/types.js +3 -0
- package/dist/server/modules/index.d.ts +3 -0
- package/dist/server/modules/index.js +4 -0
- package/dist/server/modules/order/index.d.ts +19 -0
- package/dist/server/modules/order/index.js +1071 -774
- package/dist/server/modules/order/types.d.ts +4 -0
- package/dist/server/modules/products/index.d.ts +28 -7
- package/dist/server/modules/products/index.js +1297 -770
- package/dist/server/modules/products/replication.d.ts +8 -0
- package/dist/server/modules/products/replication.js +69 -0
- package/dist/server/modules/products/types.d.ts +12 -1
- package/dist/server/modules/products/types.js +4 -0
- package/dist/server/test.json +1 -1
- package/dist/server/utils/small-ticket.d.ts +1 -85
- package/dist/server/utils/small-ticket.js +2 -2542
- package/dist/shared/payment/loadPaymentMethods.d.ts +9 -0
- package/dist/shared/payment/loadPaymentMethods.js +66 -0
- package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
- package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
- package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
- package/dist/shared/receipt/loadCustomerInvoiceLayout.js +184 -0
- package/dist/shared/receipt/small-ticket.d.ts +96 -0
- package/dist/shared/receipt/small-ticket.js +2763 -0
- package/dist/shared/receipt/templateVisibility.d.ts +26 -0
- package/dist/shared/receipt/templateVisibility.js +68 -0
- package/dist/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
- package/dist/shared/sales/loadSalesOrderSnapshot.js +21 -0
- package/dist/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
- package/dist/solution/BaseSales/fulfillmentItemRules.js +750 -0
- package/dist/solution/BaseSales/index.d.ts +43 -16
- package/dist/solution/BaseSales/index.js +2028 -1247
- package/dist/solution/BaseSales/pickupTiming.d.ts +47 -0
- package/dist/solution/BaseSales/pickupTiming.js +616 -0
- package/dist/solution/BaseSales/types.d.ts +12 -0
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
- package/dist/solution/BaseSales/utils/parseSalesResponse.js +10 -3
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -4
- package/dist/solution/BookingByStep/index.d.ts +4 -2
- package/dist/solution/BookingByStep/index.js +8 -3
- package/dist/solution/BookingTicket/index.d.ts +23 -3
- package/dist/solution/BookingTicket/index.js +867 -507
- package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
- package/dist/solution/BookingTicket/utils/addProductDecision.js +1 -1
- package/dist/solution/BookingTicket/utils/cartView.js +3 -1
- package/dist/solution/OrderInvoicePreview/index.d.ts +66 -0
- package/dist/solution/OrderInvoicePreview/index.js +340 -0
- package/dist/solution/RegisterAndLogin/config.js +54 -11
- package/dist/solution/RegisterAndLogin/index.d.ts +2 -0
- package/dist/solution/RegisterAndLogin/index.js +1 -1
- package/dist/solution/RegisterAndLogin/utils.d.ts +12 -4
- package/dist/solution/RegisterAndLogin/utils.js +36 -16
- package/dist/solution/ScanOrder/index.js +65 -31
- package/dist/solution/ScanOrder/types.d.ts +3 -0
- package/dist/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
- package/dist/solution/UnifiedBookingSales/businessAvailability.js +292 -0
- package/dist/solution/UnifiedBookingSales/index.d.ts +36 -4
- package/dist/solution/UnifiedBookingSales/index.js +1715 -906
- package/dist/solution/UnifiedBookingSales/types.d.ts +16 -2
- package/dist/solution/VenueBooking/index.d.ts +15 -2
- package/dist/solution/VenueBooking/index.js +1062 -785
- package/dist/solution/VenueBooking/types.d.ts +2 -1
- package/dist/solution/VenueBooking/types.js +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.js +7 -4
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
- package/dist/solution/VenueBooking/utils/smartPricing.js +273 -0
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/timeSlot.js +6 -3
- package/dist/solution/index.d.ts +1 -0
- package/dist/solution/index.js +2 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +21 -1
- package/lib/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
- package/lib/model/strategy/adapter/itemRule/adapter.js +54 -4
- package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
- package/lib/model/strategy/adapter/itemRule/evaluator.js +9 -0
- package/lib/model/strategy/adapter/itemRule/type.d.ts +40 -1
- package/lib/model/strategy/adapter/itemRule/type.js +10 -0
- package/lib/model/strategy/adapter/promotion/evaluator.js +9 -14
- package/lib/model/strategy/adapter/promotion/index.js +46 -1
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +17 -1
- package/lib/modules/BookingContext/utils/productExtend.d.ts +7 -0
- package/lib/modules/BookingContext/utils/productExtend.js +45 -2
- package/lib/modules/BookingContext/utils/resources.js +1 -1
- package/lib/modules/BusinessAvailability/index.d.ts +30 -0
- package/lib/modules/BusinessAvailability/index.js +146 -0
- package/lib/modules/Cart/index.js +4 -2
- package/lib/modules/Cart/types.d.ts +2 -0
- package/lib/modules/Cart/utils/cartProduct.d.ts +3 -1
- package/lib/modules/Cart/utils/cartProduct.js +39 -20
- package/lib/modules/FulfillmentTiming/index.d.ts +11 -0
- package/lib/modules/FulfillmentTiming/index.js +359 -0
- package/lib/modules/FulfillmentTiming/types.d.ts +67 -0
- package/lib/modules/FulfillmentTiming/types.js +5 -0
- package/lib/modules/Holder/utils.d.ts +2 -0
- package/lib/modules/Holder/utils.js +27 -1
- package/lib/modules/OpenData/contactInfo.d.ts +20 -0
- package/lib/modules/OpenData/contactInfo.js +56 -0
- package/lib/modules/OpenData/index.d.ts +1 -0
- package/lib/modules/OpenData/index.js +12 -0
- package/lib/modules/OpenData/types.d.ts +23 -0
- package/lib/modules/Order/holderRelations.d.ts +14 -0
- package/lib/modules/Order/holderRelations.js +98 -0
- package/lib/modules/Order/index.d.ts +16 -4
- package/lib/modules/Order/index.js +284 -50
- package/lib/modules/Order/localEftposState.d.ts +13 -0
- package/lib/modules/Order/localEftposState.js +44 -0
- package/lib/modules/Order/pickupTiming.d.ts +46 -0
- package/lib/modules/Order/pickupTiming.js +61 -0
- package/lib/modules/Order/types.d.ts +49 -3
- package/lib/modules/Order/types.js +1 -0
- package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
- package/lib/modules/Order/utils/discountProductLineIdentity.js +51 -2
- package/lib/modules/Order/utils/orderCollectionIdentity.js +5 -0
- package/lib/modules/Order/utils.d.ts +2 -1
- package/lib/modules/Order/utils.js +49 -11
- package/lib/modules/Payment/index.js +3 -4
- package/lib/modules/Product/types.d.ts +11 -0
- package/lib/modules/ProductList/index.js +1 -1
- package/lib/modules/ResourcePlanner/planner.d.ts +2 -0
- package/lib/modules/ResourcePlanner/planner.js +252 -8
- package/lib/modules/ResourcePlanner/types.d.ts +29 -0
- package/lib/modules/Rules/index.js +2 -1
- package/lib/modules/Schedule/index.d.ts +8 -0
- package/lib/modules/Schedule/index.js +68 -12
- package/lib/modules/index.d.ts +1 -0
- package/lib/modules/index.js +11 -0
- package/lib/plugins/request.d.ts +7 -0
- package/lib/server/index.d.ts +1 -0
- package/lib/server/index.js +166 -39
- package/lib/server/modules/form/index.d.ts +19 -0
- package/lib/server/modules/form/index.js +73 -0
- package/lib/server/modules/form/types.d.ts +13 -0
- package/lib/server/modules/form/types.js +9 -0
- package/lib/server/modules/index.d.ts +3 -0
- package/lib/server/modules/index.js +15 -1
- package/lib/server/modules/order/index.d.ts +19 -0
- package/lib/server/modules/order/index.js +160 -7
- package/lib/server/modules/order/types.d.ts +4 -0
- package/lib/server/modules/products/index.d.ts +28 -7
- package/lib/server/modules/products/index.js +226 -63
- package/lib/server/modules/products/replication.d.ts +8 -0
- package/lib/server/modules/products/replication.js +30 -0
- package/lib/server/modules/products/types.d.ts +12 -1
- package/lib/server/modules/products/types.js +3 -0
- package/lib/server/test.json +1 -1
- package/lib/server/utils/small-ticket.d.ts +1 -85
- package/lib/server/utils/small-ticket.js +9 -2305
- package/lib/shared/payment/loadPaymentMethods.d.ts +9 -0
- package/lib/shared/payment/loadPaymentMethods.js +40 -0
- package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
- package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
- package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
- package/lib/shared/receipt/loadCustomerInvoiceLayout.js +124 -0
- package/lib/shared/receipt/small-ticket.d.ts +96 -0
- package/lib/shared/receipt/small-ticket.js +2555 -0
- package/lib/shared/receipt/templateVisibility.d.ts +26 -0
- package/lib/shared/receipt/templateVisibility.js +67 -0
- package/lib/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
- package/lib/shared/sales/loadSalesOrderSnapshot.js +22 -0
- package/lib/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
- package/lib/solution/BaseSales/fulfillmentItemRules.js +259 -0
- package/lib/solution/BaseSales/index.d.ts +43 -16
- package/lib/solution/BaseSales/index.js +401 -33
- package/lib/solution/BaseSales/pickupTiming.d.ts +47 -0
- package/lib/solution/BaseSales/pickupTiming.js +290 -0
- package/lib/solution/BaseSales/types.d.ts +12 -0
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +7 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +16 -8
- package/lib/solution/BookingByStep/index.d.ts +4 -2
- package/lib/solution/BookingByStep/index.js +7 -3
- package/lib/solution/BookingTicket/index.d.ts +23 -3
- package/lib/solution/BookingTicket/index.js +197 -9
- package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
- package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -1
- package/lib/solution/BookingTicket/utils/cartView.js +3 -1
- package/lib/solution/OrderInvoicePreview/index.d.ts +66 -0
- package/lib/solution/OrderInvoicePreview/index.js +246 -0
- package/lib/solution/RegisterAndLogin/config.js +57 -11
- package/lib/solution/RegisterAndLogin/index.d.ts +2 -0
- package/lib/solution/RegisterAndLogin/index.js +9 -1
- package/lib/solution/RegisterAndLogin/utils.d.ts +12 -4
- package/lib/solution/RegisterAndLogin/utils.js +24 -17
- package/lib/solution/ScanOrder/index.js +59 -20
- package/lib/solution/ScanOrder/types.d.ts +3 -0
- package/lib/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
- package/lib/solution/UnifiedBookingSales/businessAvailability.js +138 -0
- package/lib/solution/UnifiedBookingSales/index.d.ts +36 -4
- package/lib/solution/UnifiedBookingSales/index.js +562 -75
- package/lib/solution/UnifiedBookingSales/types.d.ts +16 -2
- package/lib/solution/VenueBooking/index.d.ts +15 -2
- package/lib/solution/VenueBooking/index.js +243 -96
- package/lib/solution/VenueBooking/types.d.ts +2 -1
- package/lib/solution/VenueBooking/types.js +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.js +7 -4
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
- package/lib/solution/VenueBooking/utils/smartPricing.js +224 -0
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/timeSlot.js +5 -2
- package/lib/solution/index.d.ts +1 -0
- package/lib/solution/index.js +11 -0
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
var _excluded = ["option"];
|
|
2
3
|
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
3
4
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
5
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -10,6 +11,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
10
11
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
11
12
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
12
13
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
14
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
15
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
13
16
|
import Decimal from 'decimal.js';
|
|
14
17
|
import { isNormalProduct } from "../../Product/utils";
|
|
15
18
|
import { getDiscountAmount } from "../../../solution/ShopDiscount/utils";
|
|
@@ -117,7 +120,7 @@ export var formatProductToCartItem = function formatProductToCartItem(params) {
|
|
|
117
120
|
cartItem.bundle = formatBundle(bundle);
|
|
118
121
|
}
|
|
119
122
|
if (options !== null && options !== void 0 && options.length) {
|
|
120
|
-
cartItem.options = formatOptions(options);
|
|
123
|
+
cartItem.options = formatOptions(options, product);
|
|
121
124
|
}
|
|
122
125
|
// 拼装出 product_option_string
|
|
123
126
|
if (product_variant_id) {
|
|
@@ -167,7 +170,9 @@ export var formatProductToCartItemOrigin = function formatProductToCartItemOrigi
|
|
|
167
170
|
options = params.options,
|
|
168
171
|
product_variant_id = params.product_variant_id,
|
|
169
172
|
_params$quantity2 = params.quantity,
|
|
170
|
-
quantity = _params$quantity2 === void 0 ? 1 : _params$quantity2
|
|
173
|
+
quantity = _params$quantity2 === void 0 ? 1 : _params$quantity2,
|
|
174
|
+
_params$isLegacyOrder = params.isLegacyOrder,
|
|
175
|
+
isLegacyOrder = _params$isLegacyOrder === void 0 ? false : _params$isLegacyOrder;
|
|
171
176
|
var origin = cartItem._origin;
|
|
172
177
|
var product_discount_difference = (((_origin$product = origin.product) === null || _origin$product === void 0 ? void 0 : _origin$product.discount_list) || []).filter(function (item) {
|
|
173
178
|
var _item$metadata;
|
|
@@ -177,15 +182,23 @@ export var formatProductToCartItemOrigin = function formatProductToCartItemOrigi
|
|
|
177
182
|
return pre + ((cur === null || cur === void 0 || (_cur$metadata = cur.metadata) === null || _cur$metadata === void 0 ? void 0 : _cur$metadata.product_discount_difference) || 0);
|
|
178
183
|
}, 0);
|
|
179
184
|
if (product) {
|
|
180
|
-
var _origin$product2, _origin$product3, _product$duration, _product$duration2;
|
|
181
|
-
|
|
185
|
+
var _origin$product2, _origin$product3, _origin$product4, _origin$product5, _product$duration, _product$duration2;
|
|
186
|
+
var _ref = ((_origin$product2 = origin.product) === null || _origin$product2 === void 0 ? void 0 : _origin$product2.product_sku) || {},
|
|
187
|
+
_option = _ref.option,
|
|
188
|
+
legacyProductSku = _objectWithoutProperties(_ref, _excluded);
|
|
189
|
+
origin.product = _objectSpread(_objectSpread(_objectSpread({}, origin.product || {}), {}, {
|
|
182
190
|
num: quantity,
|
|
183
191
|
product_id: product.id,
|
|
184
192
|
product_variant_id: product_variant_id || 0,
|
|
185
|
-
product_bundle: ((_origin$
|
|
186
|
-
|
|
193
|
+
product_bundle: ((_origin$product3 = origin.product) === null || _origin$product3 === void 0 ? void 0 : _origin$product3.product_bundle) || []
|
|
194
|
+
}, isLegacyOrder ? {
|
|
195
|
+
product_sku: legacyProductSku,
|
|
196
|
+
product_option_item: ((_origin$product4 = origin.product) === null || _origin$product4 === void 0 ? void 0 : _origin$product4.product_option_item) || []
|
|
197
|
+
} : {
|
|
198
|
+
product_sku: ((_origin$product5 = origin.product) === null || _origin$product5 === void 0 ? void 0 : _origin$product5.product_sku) || {
|
|
187
199
|
option: []
|
|
188
|
-
}
|
|
200
|
+
}
|
|
201
|
+
}), {}, {
|
|
189
202
|
metadata: {
|
|
190
203
|
product_discount_difference: product_discount_difference
|
|
191
204
|
}
|
|
@@ -198,16 +211,21 @@ export var formatProductToCartItemOrigin = function formatProductToCartItemOrigi
|
|
|
198
211
|
origin.product.product_bundle = formatBundleToOrigin(bundle);
|
|
199
212
|
}
|
|
200
213
|
if (options !== null && options !== void 0 && options.length) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
214
|
+
var formattedOptions = formatOptionsToOrigin(options);
|
|
215
|
+
if (isLegacyOrder) {
|
|
216
|
+
origin.product.product_option_item = formattedOptions;
|
|
217
|
+
} else {
|
|
218
|
+
origin.product.product_sku = _objectSpread(_objectSpread({}, origin.product.product_sku || {}), {}, {
|
|
219
|
+
option: formattedOptions.map(function (option) {
|
|
220
|
+
var _option$add_price;
|
|
221
|
+
var next = _objectSpread(_objectSpread({}, option), {}, {
|
|
222
|
+
add_price: (_option$add_price = option.add_price) !== null && _option$add_price !== void 0 ? _option$add_price : option.price
|
|
223
|
+
});
|
|
224
|
+
delete next.price;
|
|
225
|
+
return next;
|
|
226
|
+
})
|
|
227
|
+
});
|
|
228
|
+
}
|
|
211
229
|
}
|
|
212
230
|
}
|
|
213
231
|
return origin;
|
|
@@ -230,10 +248,10 @@ export var getProductTotalPrice = function getProductTotalPrice(params) {
|
|
|
230
248
|
|
|
231
249
|
// option 行:unit 折后价在循环中与主商品使用同一套 getDiscountAmount(含 deductOptionPrice)
|
|
232
250
|
var optionRows = (_options$map = options === null || options === void 0 ? void 0 : options.map(function (currentValue) {
|
|
233
|
-
var
|
|
251
|
+
var _ref2, _currentValue$price, _ref3, _currentValue$num;
|
|
234
252
|
return {
|
|
235
|
-
unit: Number((
|
|
236
|
-
num: Number((
|
|
253
|
+
unit: Number((_ref2 = (_currentValue$price = currentValue.price) !== null && _currentValue$price !== void 0 ? _currentValue$price : currentValue.add_price) !== null && _ref2 !== void 0 ? _ref2 : 0),
|
|
254
|
+
num: Number((_ref3 = (_currentValue$num = currentValue.num) !== null && _currentValue$num !== void 0 ? _currentValue$num : currentValue.quantity) !== null && _ref3 !== void 0 ? _ref3 : 1)
|
|
237
255
|
};
|
|
238
256
|
})) !== null && _options$map !== void 0 ? _options$map : [];
|
|
239
257
|
|
|
@@ -317,12 +335,21 @@ export var getProductOriginTotalPrice = function getProductOriginTotalPrice(para
|
|
|
317
335
|
* @param options 套餐规格信息
|
|
318
336
|
* @returns 格式化后的套餐规格信息
|
|
319
337
|
*/
|
|
320
|
-
export var formatOptions = function formatOptions(options) {
|
|
338
|
+
export var formatOptions = function formatOptions(options, product) {
|
|
321
339
|
if (!(options !== null && options !== void 0 && options.length)) return [];
|
|
322
340
|
return options.map(function (item) {
|
|
341
|
+
var _ref4, _item$id, _product$option_group, _optionGroup$option_i, _ref5, _ref6, _item$name;
|
|
342
|
+
var optionGroupId = item === null || item === void 0 ? void 0 : item.option_group_id;
|
|
343
|
+
var optionItemId = (_ref4 = (_item$id = item === null || item === void 0 ? void 0 : item.id) !== null && _item$id !== void 0 ? _item$id : item === null || item === void 0 ? void 0 : item.option_group_item_id) !== null && _ref4 !== void 0 ? _ref4 : item === null || item === void 0 ? void 0 : item.product_option_item_id;
|
|
344
|
+
var optionGroup = product === null || product === void 0 || (_product$option_group = product.option_group) === null || _product$option_group === void 0 ? void 0 : _product$option_group.find(function (group) {
|
|
345
|
+
return String(group === null || group === void 0 ? void 0 : group.id) === String(optionGroupId);
|
|
346
|
+
});
|
|
347
|
+
var optionItem = optionGroup === null || optionGroup === void 0 || (_optionGroup$option_i = optionGroup.option_item) === null || _optionGroup$option_i === void 0 ? void 0 : _optionGroup$option_i.find(function (candidate) {
|
|
348
|
+
return String(candidate === null || candidate === void 0 ? void 0 : candidate.id) === String(optionItemId);
|
|
349
|
+
});
|
|
323
350
|
return {
|
|
324
|
-
id:
|
|
325
|
-
name: item === null || item === void 0 ? void 0 : item.name,
|
|
351
|
+
id: optionItemId,
|
|
352
|
+
name: (_ref5 = (_ref6 = (_item$name = item === null || item === void 0 ? void 0 : item.name) !== null && _item$name !== void 0 ? _item$name : item === null || item === void 0 ? void 0 : item.title) !== null && _ref6 !== void 0 ? _ref6 : optionItem === null || optionItem === void 0 ? void 0 : optionItem.name) !== null && _ref5 !== void 0 ? _ref5 : optionItem === null || optionItem === void 0 ? void 0 : optionItem.title,
|
|
326
353
|
num: item === null || item === void 0 ? void 0 : item.num,
|
|
327
354
|
price: item === null || item === void 0 ? void 0 : item.price,
|
|
328
355
|
total: item === null || item === void 0 ? void 0 : item.price,
|
|
@@ -337,7 +364,7 @@ export var formatOptionsToOrigin = function formatOptionsToOrigin(options) {
|
|
|
337
364
|
return options.map(function (d) {
|
|
338
365
|
return {
|
|
339
366
|
num: d.num,
|
|
340
|
-
option_group_item_id: d.option_group_item_id,
|
|
367
|
+
option_group_item_id: (d === null || d === void 0 ? void 0 : d.option_group_item_id) || (d === null || d === void 0 ? void 0 : d.product_option_item_id),
|
|
341
368
|
option_group_id: d.option_group_id
|
|
342
369
|
};
|
|
343
370
|
});
|
|
@@ -431,11 +458,11 @@ export var getProductDeposit = function getProductDeposit(params) {
|
|
|
431
458
|
// 判定商品是否有定金规则
|
|
432
459
|
if ((product === null || product === void 0 || (_product$custom_depos2 = product.custom_deposit_data) === null || _product$custom_depos2 === void 0 ? void 0 : _product$custom_depos2.has_deposit) == 1) {
|
|
433
460
|
var total = new Decimal(0);
|
|
434
|
-
var
|
|
435
|
-
deposit_fixed =
|
|
436
|
-
deposit_percentage =
|
|
437
|
-
deposit_policy_data =
|
|
438
|
-
self_deposit_policy_ids =
|
|
461
|
+
var _ref7 = (product === null || product === void 0 ? void 0 : product.custom_deposit_data) || {},
|
|
462
|
+
deposit_fixed = _ref7.deposit_fixed,
|
|
463
|
+
deposit_percentage = _ref7.deposit_percentage,
|
|
464
|
+
deposit_policy_data = _ref7.deposit_policy_data,
|
|
465
|
+
self_deposit_policy_ids = _ref7.self_deposit_policy_ids;
|
|
439
466
|
// 所有协议数据
|
|
440
467
|
var allProtocols = deposit_policy_data || [];
|
|
441
468
|
// 是否存在定金,主商品has_deposit为1,但是自身没有定金设置,需要判定子商品是否存在定金,如果不存在最终判定也是不存在定金
|
|
@@ -529,9 +556,9 @@ export var handleProductDeposit = function handleProductDeposit(params) {
|
|
|
529
556
|
depositTotal: new Decimal(0)
|
|
530
557
|
};
|
|
531
558
|
}
|
|
532
|
-
var
|
|
533
|
-
deposit_fixed =
|
|
534
|
-
deposit_percentage =
|
|
559
|
+
var _ref8 = depositData || {},
|
|
560
|
+
deposit_fixed = _ref8.deposit_fixed,
|
|
561
|
+
deposit_percentage = _ref8.deposit_percentage;
|
|
535
562
|
if (typeof deposit_fixed === 'string' && typeof deposit_percentage === 'string') {
|
|
536
563
|
var depositFixed = Decimal(deposit_fixed || 0);
|
|
537
564
|
var depositPercent = Decimal(deposit_percentage || 0);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PickupTimingAvailability, PickupTimingBookingTimes, PickupTimingClockInput, PickupTimingComputeInput, PickupTimingConfig, PickupTimingSelection, PickupTimingSlot, PickupTimingValidationResult } from './types';
|
|
2
|
+
export * from './types';
|
|
3
|
+
/** Consume effective OpenData values only; legacy switches never enable Pickup. */
|
|
4
|
+
export declare function normalizePickupTimingConfig(openData: Record<string, unknown>): PickupTimingConfig;
|
|
5
|
+
export declare function resolvePickupTimingDateTime(date: string, time: string, timezone: string, instant?: string): PickupTimingSlot | undefined;
|
|
6
|
+
export declare function getAsapPickupTiming({ config, timezone, now }: PickupTimingClockInput): PickupTimingSlot;
|
|
7
|
+
export declare function pickupTimingSlotToBookingTimes(slot: PickupTimingSlot): PickupTimingBookingTimes;
|
|
8
|
+
export declare function computePickupTimingAvailability(input: PickupTimingComputeInput): PickupTimingAvailability;
|
|
9
|
+
export declare function validatePickupTimingSelection(selection: PickupTimingSelection, input: PickupTimingComputeInput & {
|
|
10
|
+
allowManualOverride?: boolean;
|
|
11
|
+
}): PickupTimingValidationResult;
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
2
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
3
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
5
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
6
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
7
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
8
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
9
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
10
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
11
|
+
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; }
|
|
12
|
+
import dayjs from 'dayjs';
|
|
13
|
+
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
|
|
14
|
+
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
|
|
15
|
+
import { getScheduleStartEndTimePoints } from "../Schedule/getDateIsInSchedule";
|
|
16
|
+
export * from "./types";
|
|
17
|
+
|
|
18
|
+
// The shared Schedule resolver uses these comparisons without registering them.
|
|
19
|
+
dayjs.extend(isSameOrAfter);
|
|
20
|
+
dayjs.extend(isSameOrBefore);
|
|
21
|
+
var MINUTE = 60000;
|
|
22
|
+
var DAY = 24 * 60 * MINUTE;
|
|
23
|
+
var integerSetting = function integerSetting(value, min, max, fallback) {
|
|
24
|
+
return typeof value === 'number' && Number.isInteger(value) && value >= min && value <= max ? value : fallback;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** Consume effective OpenData values only; legacy switches never enable Pickup. */
|
|
28
|
+
export function normalizePickupTimingConfig(openData) {
|
|
29
|
+
var handovers = openData['fulfillment.handover_mode'];
|
|
30
|
+
var scheduleIds = openData['fulfillment.pickup.schedule'];
|
|
31
|
+
var operatingHoursScheduleIds = openData['availability.operating_hours'];
|
|
32
|
+
var mode = openData['fulfillment.pickup.timing_mode'];
|
|
33
|
+
return {
|
|
34
|
+
handoverModes: Array.isArray(handovers) ? _toConsumableArray(new Set(handovers.filter(function (value) {
|
|
35
|
+
return typeof value === 'string' && value.length > 0;
|
|
36
|
+
}))) : [],
|
|
37
|
+
timingMode: mode === 'scheduled_only' || mode === 'asap_and_scheduled' ? mode : 'asap_only',
|
|
38
|
+
scheduleIds: Array.isArray(scheduleIds) ? _toConsumableArray(new Set(scheduleIds.filter(function (value) {
|
|
39
|
+
return typeof value === 'number' && Number.isInteger(value) && value > 0;
|
|
40
|
+
}))) : [],
|
|
41
|
+
operatingHoursScheduleIds: Array.isArray(operatingHoursScheduleIds) ? _toConsumableArray(new Set(operatingHoursScheduleIds.map(function (value) {
|
|
42
|
+
return typeof value === 'number' || typeof value === 'string' ? Number(value) : NaN;
|
|
43
|
+
}).filter(function (value) {
|
|
44
|
+
return Number.isInteger(value) && value > 0;
|
|
45
|
+
}))) : [],
|
|
46
|
+
slotIntervalMinutes: integerSetting(openData['fulfillment.pickup.slot_interval_minutes'], 1, 1440, 15),
|
|
47
|
+
preparationTimeMinutes: integerSetting(openData['fulfillment.pickup.preparation_time_minutes'], 0, 1440, 0),
|
|
48
|
+
advanceDays: integerSetting(openData['fulfillment.pickup.advance_days'], 0, 365, 7),
|
|
49
|
+
fulfillmentRefMode: typeof openData['fulfillment.fulfillment_ref_mode'] === 'string' ? openData['fulfillment.fulfillment_ref_mode'] : undefined,
|
|
50
|
+
manualInputType: typeof openData['fulfillment.manual_input_type'] === 'string' ? openData['fulfillment.manual_input_type'] : undefined
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function dateStamp(date) {
|
|
54
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) return NaN;
|
|
55
|
+
var value = Date.parse("".concat(date, "T00:00:00Z"));
|
|
56
|
+
return Number.isFinite(value) && new Date(value).toISOString().slice(0, 10) === date ? value : NaN;
|
|
57
|
+
}
|
|
58
|
+
function addDays(date, days) {
|
|
59
|
+
return new Date(dateStamp(date) + days * DAY).toISOString().slice(0, 10);
|
|
60
|
+
}
|
|
61
|
+
function timeMinutes(time) {
|
|
62
|
+
var allowDayEnd = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
63
|
+
if (!/^\d{2}:\d{2}(?::00)?$/.test(time)) return NaN;
|
|
64
|
+
var _time$split$map = time.split(':').map(Number),
|
|
65
|
+
_time$split$map2 = _slicedToArray(_time$split$map, 2),
|
|
66
|
+
hours = _time$split$map2[0],
|
|
67
|
+
minutes = _time$split$map2[1];
|
|
68
|
+
if (allowDayEnd && hours === 24 && minutes === 0) return 1440;
|
|
69
|
+
return hours < 24 && minutes < 60 ? hours * 60 + minutes : NaN;
|
|
70
|
+
}
|
|
71
|
+
function instantStamp(value) {
|
|
72
|
+
// A local string would silently use the device timezone instead of the store.
|
|
73
|
+
if (typeof value === 'string' && !/(Z|[+-]\d{2}:?\d{2})$/i.test(value)) return NaN;
|
|
74
|
+
return value instanceof Date ? value.getTime() : new Date(value).getTime();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Per-query timezone adapter; no device-offset arithmetic or global time cache. */
|
|
78
|
+
function createClock(timezone) {
|
|
79
|
+
if (!timezone || typeof timezone !== 'string') throw new Error('Store timezone is unavailable.');
|
|
80
|
+
var formatter;
|
|
81
|
+
try {
|
|
82
|
+
formatter = new Intl.DateTimeFormat('en-GB', {
|
|
83
|
+
timeZone: timezone,
|
|
84
|
+
year: 'numeric',
|
|
85
|
+
month: '2-digit',
|
|
86
|
+
day: '2-digit',
|
|
87
|
+
hour: '2-digit',
|
|
88
|
+
minute: '2-digit',
|
|
89
|
+
second: '2-digit',
|
|
90
|
+
hourCycle: 'h23'
|
|
91
|
+
});
|
|
92
|
+
} catch (_unused) {
|
|
93
|
+
throw new Error('Store timezone is invalid.');
|
|
94
|
+
}
|
|
95
|
+
var offsetsByDate = new Map();
|
|
96
|
+
var local = function local(timestamp) {
|
|
97
|
+
var parts = {};
|
|
98
|
+
formatter.formatToParts(timestamp).forEach(function (part) {
|
|
99
|
+
parts[part.type] = part.value;
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
date: "".concat(parts.year, "-").concat(parts.month, "-").concat(parts.day),
|
|
103
|
+
time: "".concat(parts.hour, ":").concat(parts.minute),
|
|
104
|
+
second: parts.second
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
var offsets = function offsets(date) {
|
|
108
|
+
var cached = offsetsByDate.get(date);
|
|
109
|
+
if (cached) return cached;
|
|
110
|
+
var result = new Set();
|
|
111
|
+
var nominal = dateStamp(date);
|
|
112
|
+
// Sampling both sides of the target day discovers pre/post-transition offsets.
|
|
113
|
+
for (var hours = -36; hours <= 36; hours += 6) {
|
|
114
|
+
var sample = nominal + hours * 60 * MINUTE;
|
|
115
|
+
var wall = local(sample);
|
|
116
|
+
result.add(Date.parse("".concat(wall.date, "T").concat(wall.time, ":").concat(wall.second, "Z")) - sample);
|
|
117
|
+
}
|
|
118
|
+
var values = _toConsumableArray(result);
|
|
119
|
+
offsetsByDate.set(date, values);
|
|
120
|
+
return values;
|
|
121
|
+
};
|
|
122
|
+
var resolve = function resolve(date, time) {
|
|
123
|
+
var day = dateStamp(date);
|
|
124
|
+
var minutes = timeMinutes(time);
|
|
125
|
+
if (!Number.isFinite(day) || !Number.isFinite(minutes)) return [];
|
|
126
|
+
var label = time.slice(0, 5);
|
|
127
|
+
var nominal = day + minutes * MINUTE;
|
|
128
|
+
return offsets(date).map(function (offset) {
|
|
129
|
+
return nominal - offset;
|
|
130
|
+
}).filter(function (timestamp) {
|
|
131
|
+
var wall = local(timestamp);
|
|
132
|
+
return wall.date === date && wall.time === label;
|
|
133
|
+
}).sort(function (a, b) {
|
|
134
|
+
return a - b;
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
var slot = function slot(timestamp) {
|
|
138
|
+
var _local = local(timestamp),
|
|
139
|
+
date = _local.date,
|
|
140
|
+
time = _local.time;
|
|
141
|
+
var instant = new Date(timestamp).toISOString();
|
|
142
|
+
return {
|
|
143
|
+
id: instant,
|
|
144
|
+
date: date,
|
|
145
|
+
time: time,
|
|
146
|
+
instant: instant
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
return {
|
|
150
|
+
local: local,
|
|
151
|
+
resolve: resolve,
|
|
152
|
+
slot: slot,
|
|
153
|
+
hasOffsetTransition: function hasOffsetTransition(date) {
|
|
154
|
+
return offsets(date).length > 1;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
export function resolvePickupTimingDateTime(date, time, timezone, instant) {
|
|
159
|
+
var clock = createClock(timezone);
|
|
160
|
+
var matches = clock.resolve(date, time);
|
|
161
|
+
var selected = instant ? instantStamp(instant) : matches.length === 1 ? matches[0] : NaN;
|
|
162
|
+
return matches.includes(selected) ? clock.slot(selected) : undefined;
|
|
163
|
+
}
|
|
164
|
+
export function getAsapPickupTiming(_ref) {
|
|
165
|
+
var config = _ref.config,
|
|
166
|
+
timezone = _ref.timezone,
|
|
167
|
+
now = _ref.now;
|
|
168
|
+
var timestamp = instantStamp(now);
|
|
169
|
+
if (!Number.isFinite(timestamp)) throw new Error('Current time is invalid.');
|
|
170
|
+
return createClock(timezone).slot(timestamp + config.preparationTimeMinutes * MINUTE);
|
|
171
|
+
}
|
|
172
|
+
export function pickupTimingSlotToBookingTimes(slot) {
|
|
173
|
+
return {
|
|
174
|
+
start_date: slot.date,
|
|
175
|
+
start_time: slot.time,
|
|
176
|
+
end_date: slot.date,
|
|
177
|
+
end_time: slot.time
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function createEvaluation(input) {
|
|
181
|
+
var config = input.config,
|
|
182
|
+
timezone = input.timezone;
|
|
183
|
+
var clock = createClock(timezone);
|
|
184
|
+
var now = instantStamp(input.now);
|
|
185
|
+
if (!Number.isFinite(now)) throw new Error('Current time is invalid.');
|
|
186
|
+
var today = clock.local(now).date;
|
|
187
|
+
var maxDate = addDays(today, config.advanceDays);
|
|
188
|
+
var earliest = now + config.preparationTimeMinutes * MINUTE;
|
|
189
|
+
var schedules = input.schedules.filter(function (schedule) {
|
|
190
|
+
return config.scheduleIds.includes(schedule.id);
|
|
191
|
+
});
|
|
192
|
+
var windowCache = new Map();
|
|
193
|
+
var windows = function windows(date) {
|
|
194
|
+
if (!windowCache.has(date)) {
|
|
195
|
+
windowCache.set(date, getScheduleStartEndTimePoints(date, schedules));
|
|
196
|
+
}
|
|
197
|
+
return windowCache.get(date);
|
|
198
|
+
};
|
|
199
|
+
var operatingIds = config.operatingHoursScheduleIds || [];
|
|
200
|
+
var operatingSchedules = input.schedules.filter(function (schedule) {
|
|
201
|
+
return operatingIds.includes(schedule.id);
|
|
202
|
+
});
|
|
203
|
+
var operatingWindowCache = new Map();
|
|
204
|
+
var operatingWindows = function operatingWindows(date) {
|
|
205
|
+
if (!operatingWindowCache.has(date)) {
|
|
206
|
+
var ranges = [];
|
|
207
|
+
for (var _i = 0, _arr = [-1, 0]; _i < _arr.length; _i++) {
|
|
208
|
+
var offset = _arr[_i];
|
|
209
|
+
var _iterator = _createForOfIteratorHelper(getScheduleStartEndTimePoints(addDays(date, offset), operatingSchedules)),
|
|
210
|
+
_step;
|
|
211
|
+
try {
|
|
212
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
213
|
+
var window = _step.value;
|
|
214
|
+
var start = timeMinutes(window.start_time);
|
|
215
|
+
var end = timeMinutes(window.end_time, true);
|
|
216
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) continue;
|
|
217
|
+
// Store hours use equal endpoints for a full operating day, while
|
|
218
|
+
// the Pickup Schedule may deliberately contain a single time point.
|
|
219
|
+
if (end <= start) end += 1440;
|
|
220
|
+
ranges.push({
|
|
221
|
+
start: start + offset * 1440,
|
|
222
|
+
end: end + offset * 1440
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
} catch (err) {
|
|
226
|
+
_iterator.e(err);
|
|
227
|
+
} finally {
|
|
228
|
+
_iterator.f();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
operatingWindowCache.set(date, ranges);
|
|
232
|
+
}
|
|
233
|
+
return operatingWindowCache.get(date);
|
|
234
|
+
};
|
|
235
|
+
var slotsForDate = function slotsForDate(date) {
|
|
236
|
+
var firstOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
237
|
+
if (!Number.isFinite(dateStamp(date)) || date < today || date > maxDate || !config.handoverModes.includes('pick_up') || config.timingMode === 'asap_only') return [];
|
|
238
|
+
var found = new Map();
|
|
239
|
+
// Missing hours configuration preserves the existing all-day convention.
|
|
240
|
+
// Referenced but missing schedules yield no windows, never an all-day fallback.
|
|
241
|
+
var businessWindows = operatingIds.length ? operatingWindows(date) : undefined;
|
|
242
|
+
// Include the prior day's windows so overnight tails belong to their actual date.
|
|
243
|
+
for (var _i2 = 0, _arr2 = [addDays(date, -1), date]; _i2 < _arr2.length; _i2++) {
|
|
244
|
+
var windowDate = _arr2[_i2];
|
|
245
|
+
var _iterator2 = _createForOfIteratorHelper(windows(windowDate)),
|
|
246
|
+
_step2;
|
|
247
|
+
try {
|
|
248
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
249
|
+
var window = _step2.value;
|
|
250
|
+
var start = timeMinutes(window.start_time);
|
|
251
|
+
var end = timeMinutes(window.end_time, true);
|
|
252
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) continue;
|
|
253
|
+
if (end < start) end += 1440;
|
|
254
|
+
var firstFoundInWindow = false;
|
|
255
|
+
var _loop = function _loop() {
|
|
256
|
+
var targetDate = minute >= 1440 ? addDays(windowDate, 1) : windowDate;
|
|
257
|
+
if (targetDate !== date) return 0; // continue
|
|
258
|
+
var localMinute = minute % 1440;
|
|
259
|
+
// Filter the original Pickup grid rather than moving its anchor to
|
|
260
|
+
// the store opening time. A zero-duration pickup may be at closing.
|
|
261
|
+
if (businessWindows && !businessWindows.some(function (_ref2) {
|
|
262
|
+
var start = _ref2.start,
|
|
263
|
+
end = _ref2.end;
|
|
264
|
+
return localMinute >= start && localMinute <= end;
|
|
265
|
+
})) return 0; // continue
|
|
266
|
+
var time = "".concat(String(Math.floor(localMinute / 60)).padStart(2, '0'), ":").concat(String(localMinute % 60).padStart(2, '0'));
|
|
267
|
+
var _iterator3 = _createForOfIteratorHelper(clock.resolve(date, time)),
|
|
268
|
+
_step3;
|
|
269
|
+
try {
|
|
270
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
271
|
+
var timestamp = _step3.value;
|
|
272
|
+
if (timestamp < earliest) continue;
|
|
273
|
+
found.set(timestamp, clock.slot(timestamp));
|
|
274
|
+
firstFoundInWindow = true;
|
|
275
|
+
}
|
|
276
|
+
// Summary needs only an available candidate, not a full year's slots.
|
|
277
|
+
// During a repeated hour, an earlier wall label's second occurrence can
|
|
278
|
+
// be later than a subsequent label's first occurrence. Sort them all.
|
|
279
|
+
} catch (err) {
|
|
280
|
+
_iterator3.e(err);
|
|
281
|
+
} finally {
|
|
282
|
+
_iterator3.f();
|
|
283
|
+
}
|
|
284
|
+
if (firstOnly && firstFoundInWindow && !clock.hasOffsetTransition(date)) return 1; // break
|
|
285
|
+
},
|
|
286
|
+
_ret;
|
|
287
|
+
for (var minute = start; minute <= end; minute += config.slotIntervalMinutes) {
|
|
288
|
+
_ret = _loop();
|
|
289
|
+
if (_ret === 0) continue;
|
|
290
|
+
if (_ret === 1) break;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
} catch (err) {
|
|
294
|
+
_iterator2.e(err);
|
|
295
|
+
} finally {
|
|
296
|
+
_iterator2.f();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
var result = _toConsumableArray(found.entries()).sort(function (_ref3, _ref4) {
|
|
300
|
+
var _ref5 = _slicedToArray(_ref3, 1),
|
|
301
|
+
a = _ref5[0];
|
|
302
|
+
var _ref6 = _slicedToArray(_ref4, 1),
|
|
303
|
+
b = _ref6[0];
|
|
304
|
+
return a - b;
|
|
305
|
+
}).map(function (_ref7) {
|
|
306
|
+
var _ref8 = _slicedToArray(_ref7, 2),
|
|
307
|
+
slot = _ref8[1];
|
|
308
|
+
return slot;
|
|
309
|
+
});
|
|
310
|
+
return firstOnly ? result.slice(0, 1) : result;
|
|
311
|
+
};
|
|
312
|
+
return {
|
|
313
|
+
clock: clock,
|
|
314
|
+
now: now,
|
|
315
|
+
today: today,
|
|
316
|
+
maxDate: maxDate,
|
|
317
|
+
slotsForDate: slotsForDate
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
export function computePickupTimingAvailability(input) {
|
|
321
|
+
if (!input.config.handoverModes.includes('pick_up')) {
|
|
322
|
+
var now = instantStamp(input.now);
|
|
323
|
+
if (!Number.isFinite(now)) throw new Error('Current time is invalid.');
|
|
324
|
+
return {
|
|
325
|
+
config: input.config,
|
|
326
|
+
timezone: input.timezone,
|
|
327
|
+
now: new Date(now).toISOString(),
|
|
328
|
+
today: '',
|
|
329
|
+
maxDate: '',
|
|
330
|
+
date: input.date || '',
|
|
331
|
+
dates: [],
|
|
332
|
+
slots: []
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
var evaluation = createEvaluation(input);
|
|
336
|
+
var today = evaluation.today,
|
|
337
|
+
maxDate = evaluation.maxDate,
|
|
338
|
+
slotsForDate = evaluation.slotsForDate;
|
|
339
|
+
var date = input.date || today;
|
|
340
|
+
if (!Number.isFinite(dateStamp(date))) throw new Error('Pickup date is invalid.');
|
|
341
|
+
var slots = slotsForDate(date);
|
|
342
|
+
var dates = [];
|
|
343
|
+
var firstSlot;
|
|
344
|
+
for (var day = today; day <= maxDate; day = addDays(day, 1)) {
|
|
345
|
+
var first = day === date ? slots[0] : slotsForDate(day, true)[0];
|
|
346
|
+
dates.push({
|
|
347
|
+
date: day,
|
|
348
|
+
status: first ? 'available' : 'unavailable'
|
|
349
|
+
});
|
|
350
|
+
if (!firstSlot && first) firstSlot = first;
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
config: input.config,
|
|
354
|
+
timezone: input.timezone,
|
|
355
|
+
now: new Date(evaluation.now).toISOString(),
|
|
356
|
+
today: today,
|
|
357
|
+
maxDate: maxDate,
|
|
358
|
+
date: date,
|
|
359
|
+
dates: dates,
|
|
360
|
+
slots: slots,
|
|
361
|
+
firstSlot: firstSlot
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
export function validatePickupTimingSelection(selection, input) {
|
|
365
|
+
var fail = function fail(code, message) {
|
|
366
|
+
return {
|
|
367
|
+
valid: false,
|
|
368
|
+
code: code,
|
|
369
|
+
message: message
|
|
370
|
+
};
|
|
371
|
+
};
|
|
372
|
+
var config = input.config;
|
|
373
|
+
if (config.handoverModes.length === 0) return {
|
|
374
|
+
valid: true
|
|
375
|
+
};
|
|
376
|
+
if (!config.handoverModes.includes(selection.serviceType)) {
|
|
377
|
+
return fail('handover_unavailable', 'Choose an available handover method.');
|
|
378
|
+
}
|
|
379
|
+
if (selection.serviceType !== 'pick_up') return {
|
|
380
|
+
valid: true
|
|
381
|
+
};
|
|
382
|
+
if (selection.mode === 'asap') {
|
|
383
|
+
return config.timingMode === 'scheduled_only' ? fail('scheduled_required', 'Choose a pickup date and time.') : {
|
|
384
|
+
valid: true,
|
|
385
|
+
slot: getAsapPickupTiming(input)
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
if (selection.mode !== 'scheduled' || config.timingMode === 'asap_only') {
|
|
389
|
+
return fail('mode_unavailable', 'The selected pickup timing mode is unavailable.');
|
|
390
|
+
}
|
|
391
|
+
var slot = resolvePickupTimingDateTime(selection.date || '', selection.time || '', input.timezone, selection.instant);
|
|
392
|
+
if (!slot) return fail('invalid_time', 'Choose a valid pickup date and time.');
|
|
393
|
+
var now = instantStamp(input.now);
|
|
394
|
+
if (!Number.isFinite(now)) throw new Error('Current time is invalid.');
|
|
395
|
+
if (instantStamp(slot.instant) < now) return fail('time_in_past', 'Pickup time cannot be in the past.');
|
|
396
|
+
if (selection.source === 'pos_manual' && input.allowManualOverride) return {
|
|
397
|
+
valid: true,
|
|
398
|
+
slot: slot
|
|
399
|
+
};
|
|
400
|
+
var legal = createEvaluation(input).slotsForDate(slot.date).some(function (candidate) {
|
|
401
|
+
return candidate.instant === slot.instant;
|
|
402
|
+
});
|
|
403
|
+
return legal ? {
|
|
404
|
+
valid: true,
|
|
405
|
+
slot: slot
|
|
406
|
+
} : fail('time_unavailable', 'This pickup time is no longer available. Choose another time.');
|
|
407
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ScheduleItem } from '../Schedule/types';
|
|
2
|
+
export type PickupTimingMode = 'asap_only' | 'scheduled_only' | 'asap_and_scheduled';
|
|
3
|
+
export interface PickupTimingConfig {
|
|
4
|
+
handoverModes: string[];
|
|
5
|
+
timingMode: PickupTimingMode;
|
|
6
|
+
scheduleIds: number[];
|
|
7
|
+
/** Empty or absent means no additional store-hours restriction. */
|
|
8
|
+
operatingHoursScheduleIds?: number[];
|
|
9
|
+
slotIntervalMinutes: number;
|
|
10
|
+
preparationTimeMinutes: number;
|
|
11
|
+
advanceDays: number;
|
|
12
|
+
fulfillmentRefMode?: string;
|
|
13
|
+
manualInputType?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PickupTimingSelection {
|
|
16
|
+
serviceType: string;
|
|
17
|
+
mode: 'asap' | 'scheduled';
|
|
18
|
+
date?: string;
|
|
19
|
+
time?: string;
|
|
20
|
+
/** The absolute instant disambiguates a repeated local minute during DST. */
|
|
21
|
+
instant?: string;
|
|
22
|
+
source?: 'schedule' | 'pos_manual' | 'asap';
|
|
23
|
+
}
|
|
24
|
+
export interface PickupTimingSlot {
|
|
25
|
+
id: string;
|
|
26
|
+
date: string;
|
|
27
|
+
time: string;
|
|
28
|
+
instant: string;
|
|
29
|
+
}
|
|
30
|
+
export interface PickupTimingAvailability {
|
|
31
|
+
/** Config remains available when Schedule or store timezone cannot be loaded. */
|
|
32
|
+
error?: string;
|
|
33
|
+
config: PickupTimingConfig;
|
|
34
|
+
timezone: string;
|
|
35
|
+
now: string;
|
|
36
|
+
today: string;
|
|
37
|
+
maxDate: string;
|
|
38
|
+
date: string;
|
|
39
|
+
dates: Array<{
|
|
40
|
+
date: string;
|
|
41
|
+
status: 'available' | 'unavailable';
|
|
42
|
+
}>;
|
|
43
|
+
slots: PickupTimingSlot[];
|
|
44
|
+
/** Earliest legal candidate across all permitted dates, for POS prefill. */
|
|
45
|
+
firstSlot?: PickupTimingSlot;
|
|
46
|
+
}
|
|
47
|
+
export interface PickupTimingClockInput {
|
|
48
|
+
config: PickupTimingConfig;
|
|
49
|
+
timezone: string;
|
|
50
|
+
now: Date | string | number;
|
|
51
|
+
}
|
|
52
|
+
export interface PickupTimingComputeInput extends PickupTimingClockInput {
|
|
53
|
+
schedules: ScheduleItem[];
|
|
54
|
+
date?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface PickupTimingValidationResult {
|
|
57
|
+
valid: boolean;
|
|
58
|
+
code?: string;
|
|
59
|
+
message?: string;
|
|
60
|
+
slot?: PickupTimingSlot;
|
|
61
|
+
}
|
|
62
|
+
export interface PickupTimingBookingTimes {
|
|
63
|
+
start_date: string;
|
|
64
|
+
start_time: string;
|
|
65
|
+
end_date: string;
|
|
66
|
+
end_time: string;
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|