@final-commerce/common 2.4.0-staging.1 → 2.4.1-staging2.1

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.mjs CHANGED
@@ -422,7 +422,6 @@ var StripeCurrencyCode = /* @__PURE__ */ ((StripeCurrencyCode2) => {
422
422
  var ProductType = /* @__PURE__ */ ((ProductType2) => {
423
423
  ProductType2["SIMPLE"] = "simple";
424
424
  ProductType2["VARIABLE"] = "variable";
425
- ProductType2["BOOKING"] = "booking";
426
425
  return ProductType2;
427
426
  })(ProductType || {});
428
427
  var ProductStatus = /* @__PURE__ */ ((ProductStatus2) => {
@@ -440,50 +439,6 @@ var PaymentProcessor = /* @__PURE__ */ ((PaymentProcessor2) => {
440
439
  return PaymentProcessor2;
441
440
  })(PaymentProcessor || {});
442
441
 
443
- // enums/booking.enum.ts
444
- var BookingType = /* @__PURE__ */ ((BookingType3) => {
445
- BookingType3["RENTAL"] = "rental";
446
- BookingType3["APPOINTMENT"] = "appointment";
447
- BookingType3["OVERNIGHT"] = "overnight";
448
- BookingType3["GROUP"] = "group";
449
- return BookingType3;
450
- })(BookingType || {});
451
- var BookingRatePeriod = /* @__PURE__ */ ((BookingRatePeriod2) => {
452
- BookingRatePeriod2["SLOT"] = "slot";
453
- BookingRatePeriod2["DAY"] = "day";
454
- BookingRatePeriod2["NIGHT"] = "night";
455
- BookingRatePeriod2["WEEK"] = "week";
456
- BookingRatePeriod2["MONTH"] = "month";
457
- return BookingRatePeriod2;
458
- })(BookingRatePeriod || {});
459
- var BookingResourceKind = /* @__PURE__ */ ((BookingResourceKind2) => {
460
- BookingResourceKind2["ASSET"] = "asset";
461
- BookingResourceKind2["ROOM"] = "room";
462
- BookingResourceKind2["PROPERTY"] = "property";
463
- BookingResourceKind2["SPACE"] = "space";
464
- BookingResourceKind2["STAFF"] = "staff";
465
- BookingResourceKind2["TABLE"] = "table";
466
- return BookingResourceKind2;
467
- })(BookingResourceKind || {});
468
- var ReservationStatus = /* @__PURE__ */ ((ReservationStatus2) => {
469
- ReservationStatus2["HELD"] = "held";
470
- ReservationStatus2["CONFIRMED"] = "confirmed";
471
- ReservationStatus2["CANCELLED"] = "cancelled";
472
- ReservationStatus2["EXPIRED"] = "expired";
473
- return ReservationStatus2;
474
- })(ReservationStatus || {});
475
- var BookingResourceStatus = /* @__PURE__ */ ((BookingResourceStatus2) => {
476
- BookingResourceStatus2["ACTIVE"] = "active";
477
- BookingResourceStatus2["INACTIVE"] = "inactive";
478
- return BookingResourceStatus2;
479
- })(BookingResourceStatus || {});
480
- var ResourceAvailabilityState = /* @__PURE__ */ ((ResourceAvailabilityState2) => {
481
- ResourceAvailabilityState2["AVAILABLE"] = "available";
482
- ResourceAvailabilityState2["FULLY_BOOKED"] = "fullyBooked";
483
- ResourceAvailabilityState2["NO_HOURS_IN_RANGE"] = "noHoursInRange";
484
- return ResourceAvailabilityState2;
485
- })(ResourceAvailabilityState || {});
486
-
487
442
  // utils/currency.util.ts
488
443
  var CURRENCY_CONFIG = {
489
444
  // Major currencies with 2 decimal places
@@ -1695,15 +1650,6 @@ function sumRefundQuantities(refunds) {
1695
1650
  }
1696
1651
  return t;
1697
1652
  }
1698
- var asCount = (value) => typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : 0;
1699
- function countsOf(row) {
1700
- const quantity = asCount(row.quantity);
1701
- return {
1702
- quantity,
1703
- fulfilled: Math.min(asCount(row.fulfilledQuantity), quantity),
1704
- returned: Math.min(asCount(row.returnedQuantity), quantity)
1705
- };
1706
- }
1707
1653
  function buildOrderContext(order, extras) {
1708
1654
  const o = order ?? {};
1709
1655
  const total = typeof o.total === "number" && Number.isFinite(o.total) ? o.total : 0;
@@ -1711,7 +1657,6 @@ function buildOrderContext(order, extras) {
1711
1657
  const paymentMethods = o.paymentMethods ?? [];
1712
1658
  const refunds = o.refunds ?? o.refund ?? [];
1713
1659
  const lineItems = o.lineItems ?? [];
1714
- const reservations = o.reservations ?? [];
1715
1660
  const totalPaid = sumNumbers(paymentMethods);
1716
1661
  const totalRefunded = sumRefundQuantities(refunds);
1717
1662
  const isFullyPaid = total > 0 ? balance <= 0 : totalPaid > 0 && balance <= 0;
@@ -1719,11 +1664,13 @@ function buildOrderContext(order, extras) {
1719
1664
  let itemCount = 0;
1720
1665
  let fulfilledItemCount = 0;
1721
1666
  let returnedItemCount = 0;
1722
- for (const row of [...lineItems, ...reservations]) {
1723
- const { quantity, fulfilled, returned } = countsOf(row);
1724
- itemCount += quantity;
1725
- fulfilledItemCount += fulfilled;
1726
- returnedItemCount += returned;
1667
+ for (const li of lineItems) {
1668
+ const q = typeof li.quantity === "number" && Number.isFinite(li.quantity) ? Math.max(0, li.quantity) : 0;
1669
+ itemCount += q;
1670
+ const fq = typeof li.fulfilledQuantity === "number" && Number.isFinite(li.fulfilledQuantity) ? Math.max(0, li.fulfilledQuantity) : 0;
1671
+ fulfilledItemCount += Math.min(fq, q);
1672
+ const rq = typeof li.returnedQuantity === "number" && Number.isFinite(li.returnedQuantity) ? Math.max(0, li.returnedQuantity) : 0;
1673
+ returnedItemCount += Math.min(rq, q);
1727
1674
  }
1728
1675
  const isFullyReturned = itemCount > 0 ? returnedItemCount >= itemCount : returnedItemCount > 0;
1729
1676
  const hasPartialReturns = returnedItemCount > 0 && !isFullyReturned;
@@ -1733,8 +1680,7 @@ function buildOrderContext(order, extras) {
1733
1680
  balance,
1734
1681
  paymentMethods,
1735
1682
  refunds,
1736
- lineItems,
1737
- reservations
1683
+ lineItems
1738
1684
  },
1739
1685
  computed: {
1740
1686
  balance,
@@ -2814,371 +2760,43 @@ var ORDER_STATE_EVENTS = {
2814
2760
  configUpdated: "config-updated"
2815
2761
  };
2816
2762
 
2817
- // booking/types.ts
2818
- var BookingRulesError = class extends Error {
2819
- constructor(message) {
2820
- super(message);
2821
- this.name = "BookingRulesError";
2822
- }
2823
- };
2824
-
2825
- // booking/zoned-time.ts
2826
- var MINUTE = 6e4;
2827
- var formatters = /* @__PURE__ */ new Map();
2828
- var formatterFor = (timeZone) => {
2829
- const existing = formatters.get(timeZone);
2830
- if (existing) return existing;
2831
- let created;
2832
- try {
2833
- created = new Intl.DateTimeFormat("en-US", {
2834
- timeZone,
2835
- hour12: false,
2836
- year: "numeric",
2837
- month: "2-digit",
2838
- day: "2-digit",
2839
- hour: "2-digit",
2840
- minute: "2-digit",
2841
- second: "2-digit",
2842
- weekday: "short"
2843
- });
2844
- } catch {
2845
- throw new BookingRulesError(`Booking rules: "${timeZone}" is not a known time zone`);
2846
- }
2847
- formatters.set(timeZone, created);
2848
- return created;
2849
- };
2850
- var WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
2851
- function zonedParts(instant, timeZone) {
2852
- const parts = {};
2853
- for (const { type, value } of formatterFor(timeZone).formatToParts(instant)) parts[type] = value;
2854
- const hour = Number(parts.hour) % 24;
2855
- return {
2856
- year: Number(parts.year),
2857
- month: Number(parts.month),
2858
- day: Number(parts.day),
2859
- hour,
2860
- minute: Number(parts.minute),
2861
- second: Number(parts.second),
2862
- weekday: WEEKDAYS.indexOf(parts.weekday)
2863
- };
2864
- }
2865
- function offsetAt(instant, timeZone) {
2866
- const { year, month, day, hour, minute, second } = zonedParts(instant, timeZone);
2867
- return Date.UTC(year, month - 1, day, hour, minute, second) - Math.floor(instant.getTime() / 1e3) * 1e3;
2868
- }
2869
- function instantFromLocal(year, month, day, minutes, timeZone) {
2870
- const naive = Date.UTC(year, month - 1, day) + minutes * MINUTE;
2871
- const firstGuess = naive - offsetAt(new Date(naive), timeZone);
2872
- return new Date(naive - offsetAt(new Date(firstGuess), timeZone));
2873
- }
2874
- function startOfZonedDay(instant, timeZone) {
2875
- const { year, month, day } = zonedParts(instant, timeZone);
2876
- return instantFromLocal(year, month, day, 0, timeZone);
2877
- }
2878
- function nextZonedDay(dayStart, timeZone) {
2879
- const { year, month, day } = zonedParts(dayStart, timeZone);
2880
- return instantFromLocal(year, month, day + 1, 0, timeZone);
2763
+ // constants/adyen.constants.ts
2764
+ var ADYEN_ROLLOUT_COUNTRY_CODES = /* @__PURE__ */ new Set(["CA"]);
2765
+ function isAdyenRolloutCountry(alpha2) {
2766
+ return ADYEN_ROLLOUT_COUNTRY_CODES.has(alpha2);
2881
2767
  }
2882
- function atZonedMinute(dayStart, minutes, timeZone) {
2883
- const { year, month, day } = zonedParts(dayStart, timeZone);
2884
- return instantFromLocal(year, month, day, minutes, timeZone);
2768
+ var ADYEN_STORE_STATE_PROVINCE_COUNTRIES = /* @__PURE__ */ new Set(["AU", "BR", "CA", "IN", "MX", "NZ", "US"]);
2769
+ function adyenStoreRequiresStateOrProvince(alpha2) {
2770
+ return !!alpha2 && ADYEN_STORE_STATE_PROVINCE_COUNTRIES.has(alpha2);
2885
2771
  }
2886
-
2887
- // booking/grid.ts
2888
- var MINUTE2 = 6e4;
2889
- var MAX_RANGE_DAYS = 366;
2890
- var asTime = (value, field) => {
2891
- if (value == null) return void 0;
2892
- const time = new Date(value).getTime();
2893
- if (Number.isNaN(time)) throw new BookingRulesError(`Booking rules: ${field} is not a date, got "${String(value)}"`);
2894
- return time;
2895
- };
2896
- function parseHhMm(value, field) {
2897
- const [hours, minutes] = value.split(":").map(Number);
2898
- if (!Number.isInteger(hours) || !Number.isInteger(minutes)) {
2899
- throw new BookingRulesError(`Booking rules: ${field} must be "HH:mm", got "${value}"`);
2900
- }
2901
- return hours * 60 + minutes;
2902
- }
2903
- function windowEndsAt(rule, now) {
2904
- const { maxAdvanceDays, bookableTo } = rule.window;
2905
- const ends = Math.min(
2906
- maxAdvanceDays ? now.getTime() + maxAdvanceDays * 1440 * MINUTE2 : Number.POSITIVE_INFINITY,
2907
- asTime(bookableTo, "window.bookableTo") ?? Number.POSITIVE_INFINITY
2908
- );
2909
- return Number.isFinite(ends) ? new Date(ends) : null;
2910
- }
2911
- function periodSlot(dayStart, timeZone, rule, openMinute, closeMinute) {
2912
- const { ratePeriod, slot, checkInTime, checkOutTime } = rule;
2913
- const at = (minutes) => atZonedMinute(dayStart, minutes, timeZone);
2914
- if (ratePeriod === "night" /* NIGHT */) {
2915
- if (!checkInTime || !checkOutTime) {
2916
- throw new BookingRulesError("Overnight booking rules need both checkInTime and checkOutTime");
2917
- }
2918
- const checkIn = parseHhMm(checkInTime, "checkInTime");
2919
- const checkOut = parseHhMm(checkOutTime, "checkOutTime");
2920
- return {
2921
- startAt: at(checkIn),
2922
- endAt: at(1440 + checkOut),
2923
- // Housekeeping sits between check-out and the next check-in: it costs no night.
2924
- bufferEndAt: at(1440 + checkIn),
2925
- canStart: true
2926
- };
2927
- }
2928
- const from = ratePeriod === "day" /* DAY */ ? openMinute ?? 0 : 0;
2929
- const to = ratePeriod === "day" /* DAY */ ? closeMinute ?? 1440 : 1440;
2930
- return {
2931
- startAt: at(from),
2932
- endAt: at(to),
2933
- bufferEndAt: at(to + (slot.bufferMinutes ?? 0)),
2934
- canStart: true
2935
- };
2936
- }
2937
- function freeGaps(openAt, closeAt, busy) {
2938
- const inside = busy.map(({ startAt, bufferEndAt }) => ({ from: +startAt, to: +bufferEndAt })).filter(({ from, to }) => to > openAt && from < closeAt).sort((first, second) => first.from - second.from);
2939
- const gaps = [];
2940
- let cursor = openAt;
2941
- for (const { from, to } of inside) {
2942
- if (from > cursor) gaps.push({ from: cursor, to: from, endsAtBooking: true });
2943
- cursor = Math.max(cursor, to);
2944
- if (cursor >= closeAt) break;
2945
- }
2946
- if (cursor < closeAt) gaps.push({ from: cursor, to: closeAt, endsAtBooking: false });
2947
- return gaps;
2948
- }
2949
- function buildGrid(rule, timeZone, from, to, now, busy = []) {
2950
- if (to.getTime() - from.getTime() > MAX_RANGE_DAYS * 1440 * MINUTE2) {
2951
- throw new BookingRulesError(`A booking range may span at most ${MAX_RANGE_DAYS} days`);
2952
- }
2953
- const { availability, slot, window, ratePeriod } = rule;
2954
- const periodMode = ratePeriod !== "slot" /* SLOT */;
2955
- const weeklyHours = availability.weeklyHours ?? [];
2956
- const notBefore = Math.max(
2957
- now.getTime() + (window.minNoticeMinutes ?? 0) * MINUTE2,
2958
- asTime(window.bookableFrom, "window.bookableFrom") ?? 0,
2959
- asTime(availability.availableFrom, "availability.availableFrom") ?? 0
2960
- );
2961
- const notAfter = windowEndsAt(rule, now)?.getTime() ?? Number.POSITIVE_INFINITY;
2962
- const blocked = (availability.offMarket ?? []).map(({ from: blockFrom, to: blockTo }) => ({
2963
- from: asTime(blockFrom, "availability.offMarket.from"),
2964
- to: asTime(blockTo, "availability.offMarket.to")
2965
- }));
2966
- const arrivalDays = availability.arrivalDays;
2967
- const step = slot.lengthMinutes + (slot.bufferMinutes ?? 0);
2968
- const slots = [];
2969
- const lastDay = startOfZonedDay(to, timeZone).getTime();
2970
- let dayStart = startOfZonedDay(from, timeZone);
2971
- while (dayStart.getTime() <= lastDay) {
2972
- const weekday = zonedParts(dayStart, timeZone).weekday;
2973
- const rows = weeklyHours.filter((entry) => entry.weekday === weekday);
2974
- if (periodMode) {
2975
- const openToday = weeklyHours.length === 0 || rows.length > 0;
2976
- if (openToday) {
2977
- const built = periodSlot(dayStart, timeZone, rule, rows[0]?.openMinute, rows[0]?.closeMinute);
2978
- slots.push({ ...built, canStart: !arrivalDays?.length || arrivalDays.includes(weekday) });
2979
- }
2980
- } else {
2981
- for (const row of rows) {
2982
- const openAt = +atZonedMinute(dayStart, row.openMinute, timeZone);
2983
- const closeAt = +atZonedMinute(dayStart, row.closeMinute, timeZone);
2984
- for (const gap of freeGaps(openAt, closeAt, busy)) {
2985
- const mustFit = (gap.endsAtBooking ? step : slot.lengthMinutes) * MINUTE2;
2986
- for (let start = gap.from; start + mustFit <= gap.to; start += step * MINUTE2) {
2987
- slots.push({
2988
- startAt: new Date(start),
2989
- endAt: new Date(start + slot.lengthMinutes * MINUTE2),
2990
- bufferEndAt: new Date(start + step * MINUTE2),
2991
- canStart: true
2992
- });
2993
- }
2994
- }
2995
- }
2996
- }
2997
- dayStart = nextZonedDay(dayStart, timeZone);
2998
- }
2999
- const askedFrom = from.getTime();
3000
- const askedTo = to.getTime();
3001
- return slots.filter(({ startAt, bufferEndAt }) => {
3002
- const start = startAt.getTime();
3003
- if (start < askedFrom || start >= askedTo) return false;
3004
- if (start < notBefore || start > notAfter) return false;
3005
- return !blocked.some(({ from: blockFrom, to: blockTo }) => start < blockTo && bufferEndAt.getTime() > blockFrom);
3006
- }).sort((first, second) => +first.startAt - +second.startAt);
3007
- }
3008
- function slotsForWindow(grid, startAt, endAt) {
3009
- const startIndex = grid.findIndex((entry) => entry.startAt.getTime() === startAt.getTime());
3010
- if (startIndex < 0) {
3011
- throw new BookingRulesError(`${startAt.toISOString()} is not a bookable slot start for these rules`);
3012
- }
3013
- if (!grid[startIndex].canStart) {
3014
- throw new BookingRulesError(`${startAt.toISOString()} is not an arrival day for these rules`);
3015
- }
3016
- const covered = [];
3017
- for (let index = startIndex; index < grid.length; index++) {
3018
- const entry = grid[index];
3019
- const previous = covered[covered.length - 1];
3020
- if (previous && entry.startAt.getTime() !== previous.bufferEndAt.getTime()) break;
3021
- covered.push(entry);
3022
- if (entry.endAt.getTime() === endAt.getTime()) return covered;
3023
- if (entry.endAt.getTime() > endAt.getTime()) break;
3024
- }
3025
- throw new BookingRulesError(
3026
- `${startAt.toISOString()} \u2192 ${endAt.toISOString()} does not line up with the bookable grid`
3027
- );
2772
+ var ADYEN_LEGAL_ENTITY_STATE_PROVINCE_COUNTRIES = /* @__PURE__ */ new Set(["AU", "BR", "CA", "IN", "MX", "NZ", "US"]);
2773
+ function adyenLegalEntityRequiresStateOrProvince(alpha2) {
2774
+ return !!alpha2 && ADYEN_LEGAL_ENTITY_STATE_PROVINCE_COUNTRIES.has(alpha2);
3028
2775
  }
3029
-
3030
- // booking/availability.ts
3031
- var withinPresence = (slot, timeZone, presence) => {
3032
- if (!presence?.length) return true;
3033
- const dayStart = startOfZonedDay(slot.startAt, timeZone);
3034
- const weekday = zonedParts(dayStart, timeZone).weekday;
3035
- return presence.some(
3036
- (shift) => shift.weekday === weekday && slot.startAt.getTime() >= atZonedMinute(dayStart, shift.openMinute, timeZone).getTime() && slot.endAt.getTime() <= atZonedMinute(dayStart, shift.closeMinute, timeZone).getTime()
3037
- );
3038
- };
3039
- var overlaps = (entry, startAt, bufferEndAt) => entry.startAt.getTime() < bufferEndAt.getTime() && entry.bufferEndAt.getTime() > startAt.getTime();
3040
- function occupancyIn(occupied, productId, startAt, bufferEndAt, shared) {
3041
- const clashing = occupied.filter((entry) => overlaps(entry, startAt, bufferEndAt));
3042
- const foreign = shared ? void 0 : clashing.find((entry) => entry.productId !== productId);
3043
- return {
3044
- taken: clashing.filter((entry) => shared || entry.productId === productId).reduce((sum, entry) => sum + entry.qty, 0),
3045
- foreignProductId: foreign?.productId
3046
- };
2776
+ var ADYEN_NO_TAX_NUMBER_ABSENT_COUNTRIES = /* @__PURE__ */ new Set(["CA"]);
2777
+ function adyenSupportsTaxNumberAbsent(alpha2) {
2778
+ return !!alpha2 && !ADYEN_NO_TAX_NUMBER_ABSENT_COUNTRIES.has(alpha2);
3047
2779
  }
3048
- var stateFor = (hasShift, offerable, free) => {
3049
- if (offerable === 0) {
3050
- return hasShift() ? "fullyBooked" /* FULLY_BOOKED */ : "noHoursInRange" /* NO_HOURS_IN_RANGE */;
3051
- }
3052
- return free === 0 ? "fullyBooked" /* FULLY_BOOKED */ : "available" /* AVAILABLE */;
2780
+ var ADYEN_TAX_NUMBER_FORMATS = {
2781
+ CA: { pattern: /^\d{9}$/, length: 9 }
3053
2782
  };
3054
- function buildAvailability({
3055
- productId,
3056
- bookingRulesId,
3057
- bookingType,
3058
- rule,
3059
- resources,
3060
- occupied,
3061
- from,
3062
- to,
3063
- now
3064
- }) {
3065
- const shared = rule.slot.sharedAcrossProducts ?? false;
3066
- const bookableUntil = windowEndsAt(rule, now);
3067
- const header = {
3068
- productId,
3069
- bookingRulesId,
3070
- bookingType,
3071
- ratePeriod: rule.ratePeriod,
3072
- // Passed through for the UI to label: a group slot under minimumToRun may not run.
3073
- minimumToRun: rule.slot.minimumToRun,
3074
- minStay: rule.slot.minStay,
3075
- maxStay: rule.slot.maxStay,
3076
- // Why a day can come back empty. Past this instant the rule refuses everything, so the UI
3077
- // can say "beyond the booking window" where it would otherwise claim "nothing free".
3078
- bookableUntil,
3079
- // The comparison itself, not just the boundary: deciding whether a day lies past the
3080
- // window is a rule, and a UI that re-derives it owns a copy of that rule — which is how
3081
- // the same empty grid ends up explained one way on the till and another in a flow.
3082
- beyondWindow: !!bookableUntil && from.getTime() > bookableUntil.getTime()
3083
- };
3084
- const byResource = /* @__PURE__ */ new Map();
3085
- for (const entry of occupied) {
3086
- byResource.set(entry.resourceId, [...byResource.get(entry.resourceId) ?? [], entry]);
3087
- }
3088
- const grids = resources.map((resource) => {
3089
- const mine = byResource.get(resource.id) ?? [];
3090
- const busy = (resource.seats ?? 1) === 1 ? mine : [];
3091
- const slots = buildGrid(rule, resource.timeZone, from, to, now, busy).filter(
3092
- (slot) => withinPresence(slot, resource.timeZone, resource.presence)
3093
- );
3094
- return { resource, slots };
3095
- });
3096
- const byInstant = /* @__PURE__ */ new Map();
3097
- const freeSlotsPerResource = /* @__PURE__ */ new Map();
3098
- for (const { resource, slots } of grids) {
3099
- const capacity = resource.seats ?? 1;
3100
- const mine = byResource.get(resource.id) ?? [];
3101
- for (const slot of slots) {
3102
- const { taken, foreignProductId } = occupancyIn(mine, productId, slot.startAt, slot.bufferEndAt, shared);
3103
- const free = foreignProductId ? 0 : Math.max(capacity - taken, 0);
3104
- const entry = byInstant.get(+slot.startAt) ?? { ...slot, capacity: 0, booked: 0, free: 0, resources: [] };
3105
- entry.capacity += capacity;
3106
- entry.booked += foreignProductId ? capacity : taken;
3107
- entry.free += free;
3108
- entry.canStart = entry.canStart || slot.canStart;
3109
- entry.resources.push({ resourceId: resource.id, name: resource.name, capacity, booked: taken, free });
3110
- if (free > 0) freeSlotsPerResource.set(resource.id, (freeSlotsPerResource.get(resource.id) ?? 0) + 1);
3111
- byInstant.set(+slot.startAt, entry);
3112
- }
3113
- }
3114
- const inWindow = grids.map(({ resource, slots }) => {
3115
- const free = freeSlotsPerResource.get(resource.id) ?? 0;
3116
- return {
3117
- resourceId: resource.id,
3118
- name: resource.name,
3119
- slots: slots.length,
3120
- free,
3121
- // Lazily: the shift grid is a second walk, and only an empty answer needs it.
3122
- state: stateFor(
3123
- () => buildGrid(rule, resource.timeZone, from, to, now).filter(
3124
- (slot) => withinPresence(slot, resource.timeZone, resource.presence)
3125
- ).length > 0,
3126
- slots.length,
3127
- free
3128
- )
3129
- };
3130
- });
3131
- return {
3132
- ...header,
3133
- resources: inWindow,
3134
- slots: [...byInstant.values()].sort((first, second) => +first.startAt - +second.startAt)
3135
- };
2783
+ function adyenTaxNumberFormat(alpha2) {
2784
+ return alpha2 ? ADYEN_TAX_NUMBER_FORMATS[alpha2] : void 0;
3136
2785
  }
3137
- function presentAt(resources, rows, outletId) {
3138
- const byResource = /* @__PURE__ */ new Map();
3139
- for (const row of rows) {
3140
- byResource.set(row.resourceId, [...byResource.get(row.resourceId) ?? [], row]);
3141
- }
3142
- return resources.flatMap((resource) => {
3143
- const own = byResource.get(resource.id) ?? [];
3144
- if (own.length === 0 || !outletId) return [{ resource }];
3145
- const here = own.find((row) => row.outletId === outletId);
3146
- return here ? [{ resource, presence: here.weeklyHours }] : [];
3147
- });
3148
- }
3149
-
3150
- // booking/plan.ts
3151
- var DEFAULT_HOLD_MINUTES = 10;
3152
- function planWindow({ rule, timeZone, presence, startAt, endAt, now, busy = [] }) {
3153
- const grid = buildGrid(rule, timeZone, startAt, endAt, now, busy).filter(
3154
- (slot) => withinPresence(slot, timeZone, presence)
3155
- );
3156
- const slots = slotsForWindow(grid, startAt, endAt);
3157
- const { minStay, maxStay } = rule.slot;
3158
- if (minStay && slots.length < minStay) {
3159
- throw new BookingRulesError(`These rules ask for at least ${minStay} period(s), got ${slots.length}`);
3160
- }
3161
- if (maxStay && slots.length > maxStay) {
3162
- throw new BookingRulesError(`These rules allow at most ${maxStay} period(s), got ${slots.length}`);
3163
- }
3164
- const last = slots[slots.length - 1];
3165
- return { slots, endAt: last.endAt, bufferEndAt: last.bufferEndAt };
3166
- }
3167
- var holdExpiresAt = (rule, now) => new Date(now.getTime() + (rule.window.holdMinutes ?? DEFAULT_HOLD_MINUTES) * 6e4);
3168
-
3169
- // constants/adyen.constants.ts
3170
- var ADYEN_ROLLOUT_COUNTRY_CODES = /* @__PURE__ */ new Set(["CA"]);
3171
- function isAdyenRolloutCountry(alpha2) {
3172
- return ADYEN_ROLLOUT_COUNTRY_CODES.has(alpha2);
2786
+ var ADYEN_TAX_NUMBER_MIN_LENGTH = 5;
2787
+ var ADYEN_JOB_TITLE_ASSOCIATION_TYPES = ["signatory", "uboThroughControl"];
2788
+ function adyenRequiresJobTitle(associationType) {
2789
+ return ADYEN_JOB_TITLE_ASSOCIATION_TYPES.includes(associationType);
3173
2790
  }
3174
2791
  export {
2792
+ ADYEN_JOB_TITLE_ASSOCIATION_TYPES,
2793
+ ADYEN_LEGAL_ENTITY_STATE_PROVINCE_COUNTRIES,
2794
+ ADYEN_NO_TAX_NUMBER_ABSENT_COUNTRIES,
3175
2795
  ADYEN_ROLLOUT_COUNTRY_CODES,
2796
+ ADYEN_STORE_STATE_PROVINCE_COUNTRIES,
2797
+ ADYEN_TAX_NUMBER_FORMATS,
2798
+ ADYEN_TAX_NUMBER_MIN_LENGTH,
3176
2799
  AttributeType,
3177
- BookingRatePeriod,
3178
- BookingResourceKind,
3179
- BookingResourceStatus,
3180
- BookingRulesError,
3181
- BookingType,
3182
2800
  CONDITION_OPERATORS,
3183
2801
  COUNTRY_CURRENCIES,
3184
2802
  CURRENCY_CONFIG,
@@ -3189,7 +2807,6 @@ export {
3189
2807
  DEFAULT_CONFIG,
3190
2808
  DEFAULT_CROSS_AXIS_RULES,
3191
2809
  DEFAULT_DISPLAY_STATE_MAP,
3192
- DEFAULT_HOLD_MINUTES,
3193
2810
  DEFAULT_RESOLVED_CONFIG,
3194
2811
  DEFAULT_UNIT_ID,
3195
2812
  DualWriteStrategy,
@@ -3233,10 +2850,8 @@ export {
3233
2850
  REPORT_NEGATE_PATHS,
3234
2851
  ReceiptSendChannel,
3235
2852
  ReceiptType,
3236
- ReservationStatus,
3237
2853
  ResidualPaymentMethod,
3238
2854
  ResidualStatus,
3239
- ResourceAvailabilityState,
3240
2855
  STATE_SCHEMA,
3241
2856
  STRIPE_SUPPORTED_COUNTRIES,
3242
2857
  SYSTEM_FAMILIES,
@@ -3250,6 +2865,11 @@ export {
3250
2865
  TopMetericsSort,
3251
2866
  UserTypes,
3252
2867
  addAmounts,
2868
+ adyenLegalEntityRequiresStateOrProvince,
2869
+ adyenRequiresJobTitle,
2870
+ adyenStoreRequiresStateOrProvince,
2871
+ adyenSupportsTaxNumberAbsent,
2872
+ adyenTaxNumberFormat,
3253
2873
  amountToString,
3254
2874
  assertUnitSane,
3255
2875
  availableIn,
@@ -3257,8 +2877,6 @@ export {
3257
2877
  baseFulfillmentDefinitions,
3258
2878
  baseOf,
3259
2879
  basePaymentDefinitions,
3260
- buildAvailability,
3261
- buildGrid,
3262
2880
  buildOrderContext,
3263
2881
  buildPosPresetConfig,
3264
2882
  buildResolvedConfig,
@@ -3298,7 +2916,6 @@ export {
3298
2916
  getPricingRegionFromCountry,
3299
2917
  getSettlementTotal,
3300
2918
  getTotalCollected,
3301
- holdExpiresAt,
3302
2919
  inferStatesFromLegacyStatus,
3303
2920
  isAdyenRolloutCountry,
3304
2921
  isConditionOperator,
@@ -3313,12 +2930,9 @@ export {
3313
2930
  mergeFragment,
3314
2931
  multiplyAmount,
3315
2932
  normalizeMongoIdString,
3316
- occupancyIn,
3317
2933
  parseAmountToMinorUnits,
3318
2934
  parseCurrencyCode,
3319
2935
  parseStripeCurrencyCode,
3320
- planWindow,
3321
- presentAt,
3322
2936
  removeFragment,
3323
2937
  resolveFamily,
3324
2938
  resolveTemplate,
@@ -3327,15 +2941,12 @@ export {
3327
2941
  sameFamily,
3328
2942
  setOrderState,
3329
2943
  signReportForDisplay,
3330
- slotsForWindow,
3331
2944
  stringifyMinorUnits,
3332
2945
  subtractAmounts,
3333
2946
  toBase,
3334
2947
  toMinorUnits,
3335
2948
  validateConfig,
3336
2949
  validateFragmentCompatibility,
3337
- violatesFinancialInvariant,
3338
- windowEndsAt,
3339
- withinPresence
2950
+ violatesFinancialInvariant
3340
2951
  };
3341
2952
  //# sourceMappingURL=index.mjs.map