@final-commerce/common 2.8.0 → 2.8.1-online.2
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.mts +205 -2
- package/dist/index.d.ts +205 -2
- package/dist/index.js +473 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +448 -0
- package/dist/index.mjs.map +1 -1
- package/dist/pos-types/index.d.mts +305 -226
- package/dist/pos-types/index.d.ts +305 -226
- package/dist/pos-types/index.js +1 -0
- package/dist/pos-types/index.js.map +1 -1
- package/dist/pos-types/index.mjs +1 -0
- package/dist/pos-types/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -200,6 +200,7 @@ var OrderPlatform = /* @__PURE__ */ ((OrderPlatform2) => {
|
|
|
200
200
|
OrderPlatform2["POS"] = "in-store";
|
|
201
201
|
OrderPlatform2["WOO_COMMERCE"] = "woo-commerce";
|
|
202
202
|
OrderPlatform2["PUBLIC_API"] = "public-api";
|
|
203
|
+
OrderPlatform2["ONLINE_STORE"] = "online-store";
|
|
203
204
|
return OrderPlatform2;
|
|
204
205
|
})(OrderPlatform || {});
|
|
205
206
|
var CustomerPlatform = /* @__PURE__ */ ((CustomerPlatform2) => {
|
|
@@ -486,6 +487,50 @@ var ResourceAvailabilityState = /* @__PURE__ */ ((ResourceAvailabilityState2) =>
|
|
|
486
487
|
return ResourceAvailabilityState2;
|
|
487
488
|
})(ResourceAvailabilityState || {});
|
|
488
489
|
|
|
490
|
+
// enums/shipping.enum.ts
|
|
491
|
+
var ShippingZoneKind = /* @__PURE__ */ ((ShippingZoneKind2) => {
|
|
492
|
+
ShippingZoneKind2["COUNTRY"] = "country";
|
|
493
|
+
ShippingZoneKind2["PROVINCE"] = "province";
|
|
494
|
+
ShippingZoneKind2["CITY"] = "city";
|
|
495
|
+
ShippingZoneKind2["EVERYWHERE"] = "everywhere";
|
|
496
|
+
return ShippingZoneKind2;
|
|
497
|
+
})(ShippingZoneKind || {});
|
|
498
|
+
var ShippingOptionType = /* @__PURE__ */ ((ShippingOptionType2) => {
|
|
499
|
+
ShippingOptionType2["SHIP"] = "ship";
|
|
500
|
+
ShippingOptionType2["PICKUP"] = "pickup";
|
|
501
|
+
return ShippingOptionType2;
|
|
502
|
+
})(ShippingOptionType || {});
|
|
503
|
+
var ShippingRateType = /* @__PURE__ */ ((ShippingRateType2) => {
|
|
504
|
+
ShippingRateType2["FLAT"] = "flat";
|
|
505
|
+
return ShippingRateType2;
|
|
506
|
+
})(ShippingRateType || {});
|
|
507
|
+
var ShippingChannel = /* @__PURE__ */ ((ShippingChannel2) => {
|
|
508
|
+
ShippingChannel2["WEB"] = "web";
|
|
509
|
+
ShippingChannel2["POS"] = "pos";
|
|
510
|
+
return ShippingChannel2;
|
|
511
|
+
})(ShippingChannel || {});
|
|
512
|
+
var ShippingNoOptionReason = /* @__PURE__ */ ((ShippingNoOptionReason2) => {
|
|
513
|
+
ShippingNoOptionReason2["INCOMPLETE"] = "INCOMPLETE";
|
|
514
|
+
ShippingNoOptionReason2["ADDRESS_MISMATCH"] = "ADDRESS_MISMATCH";
|
|
515
|
+
ShippingNoOptionReason2["NO_COVERAGE"] = "NO_COVERAGE";
|
|
516
|
+
ShippingNoOptionReason2["BLOCKED"] = "BLOCKED";
|
|
517
|
+
ShippingNoOptionReason2["NO_OPTION"] = "NO_OPTION";
|
|
518
|
+
return ShippingNoOptionReason2;
|
|
519
|
+
})(ShippingNoOptionReason || {});
|
|
520
|
+
var ShippingZoneError = /* @__PURE__ */ ((ShippingZoneError2) => {
|
|
521
|
+
ShippingZoneError2["NO_PLACES"] = "NO_PLACES";
|
|
522
|
+
ShippingZoneError2["INVALID_PLACE"] = "INVALID_PLACE";
|
|
523
|
+
ShippingZoneError2["DUPLICATE_PLACE"] = "DUPLICATE_PLACE";
|
|
524
|
+
ShippingZoneError2["NO_WEBSITE_OPTION"] = "NO_WEBSITE_OPTION";
|
|
525
|
+
ShippingZoneError2["INVALID_PRICE"] = "INVALID_PRICE";
|
|
526
|
+
ShippingZoneError2["INVALID_DAYS"] = "INVALID_DAYS";
|
|
527
|
+
ShippingZoneError2["INVALID_TIERS"] = "INVALID_TIERS";
|
|
528
|
+
ShippingZoneError2["NO_CHANNEL"] = "NO_CHANNEL";
|
|
529
|
+
ShippingZoneError2["PICKUP_WITHOUT_STORE"] = "PICKUP_WITHOUT_STORE";
|
|
530
|
+
ShippingZoneError2["MISSING_NAME"] = "MISSING_NAME";
|
|
531
|
+
return ShippingZoneError2;
|
|
532
|
+
})(ShippingZoneError || {});
|
|
533
|
+
|
|
489
534
|
// utils/currency.util.ts
|
|
490
535
|
var CURRENCY_CONFIG = {
|
|
491
536
|
// Major currencies with 2 decimal places
|
|
@@ -1661,6 +1706,48 @@ function compositeReservationMismatches(order) {
|
|
|
1661
1706
|
});
|
|
1662
1707
|
}
|
|
1663
1708
|
|
|
1709
|
+
// utils/line-stock-moves.util.ts
|
|
1710
|
+
function lineStockMoves(item, quantity, reservations = []) {
|
|
1711
|
+
const sign = Math.sign(quantity);
|
|
1712
|
+
const pool = (stockVariantId) => stockVariantId ? { stockVariantId: stockVariantId.toString() } : {};
|
|
1713
|
+
if (!item.components?.length)
|
|
1714
|
+
return [
|
|
1715
|
+
{
|
|
1716
|
+
productId: item.productId.toString(),
|
|
1717
|
+
variantId: item.variantId.toString(),
|
|
1718
|
+
fields: {
|
|
1719
|
+
quantity,
|
|
1720
|
+
...item.stockQuantity != null ? { stockQuantity: sign * item.stockQuantity, unitId: item.unitId?.toString() } : {},
|
|
1721
|
+
...pool(item.stockVariantId)
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
];
|
|
1725
|
+
const booked = new Set(
|
|
1726
|
+
reservations.filter((reservation) => reservation.lineItemInternalId && reservation.lineItemInternalId === item.internalId).map((reservation) => reservation.componentIndex)
|
|
1727
|
+
);
|
|
1728
|
+
return item.components.flatMap((component, componentIndex) => {
|
|
1729
|
+
if (booked.has(componentIndex)) return [];
|
|
1730
|
+
if (component.unitId && component.stockQuantity == null)
|
|
1731
|
+
throw new Error(
|
|
1732
|
+
`Composite ${item.productId?.toString()} component ${component.variantId.toString()} is sold in ${component.unitId.toString()} but carries no stockQuantity`
|
|
1733
|
+
);
|
|
1734
|
+
return [
|
|
1735
|
+
{
|
|
1736
|
+
productId: component.productId.toString(),
|
|
1737
|
+
variantId: component.variantId.toString(),
|
|
1738
|
+
componentIndex,
|
|
1739
|
+
fields: {
|
|
1740
|
+
quantity: component.quantity * quantity,
|
|
1741
|
+
...component.stockQuantity != null ? { stockQuantity: component.stockQuantity * quantity, unitId: component.unitId?.toString() } : {},
|
|
1742
|
+
...pool(component.stockVariantId),
|
|
1743
|
+
...item.productId ? { compositeProductId: item.productId.toString() } : {},
|
|
1744
|
+
...item.name ? { compositeName: item.name } : {}
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
];
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1664
1751
|
// units/family-code.ts
|
|
1665
1752
|
var MAX_SLUG_LENGTH = 32;
|
|
1666
1753
|
var FALLBACK_SLUG = "family";
|
|
@@ -3564,6 +3651,321 @@ function planWindow({ rule, timeZone, presence, startAt, endAt, now, busy = [] }
|
|
|
3564
3651
|
}
|
|
3565
3652
|
var holdExpiresAt = (rule, now) => new Date(now.getTime() + (rule.window.holdMinutes ?? DEFAULT_HOLD_MINUTES) * 6e4);
|
|
3566
3653
|
|
|
3654
|
+
// shipping/fold-text.ts
|
|
3655
|
+
function foldText(value) {
|
|
3656
|
+
return value.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/&/g, " and ").replace(/[^a-z0-9]+/g, " ").trim();
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
// shipping/countries.ts
|
|
3660
|
+
var NOT_COUNTRIES = /* @__PURE__ */ new Set(["AC", "CP", "CQ", "DG", "EA", "EU", "EZ", "IC", "QO", "TA", "UN", "XA", "XB", "ZZ"]);
|
|
3661
|
+
var ALIASES = {
|
|
3662
|
+
canada: "CA",
|
|
3663
|
+
"united states": "US",
|
|
3664
|
+
usa: "US",
|
|
3665
|
+
"united states of america": "US",
|
|
3666
|
+
uk: "GB",
|
|
3667
|
+
"great britain": "GB",
|
|
3668
|
+
england: "GB",
|
|
3669
|
+
uae: "AE",
|
|
3670
|
+
can: "CA",
|
|
3671
|
+
mex: "MX",
|
|
3672
|
+
aus: "AU",
|
|
3673
|
+
gbr: "GB"
|
|
3674
|
+
};
|
|
3675
|
+
var NAME_LOCALES = ["en", "fr"];
|
|
3676
|
+
function regionNames(locale) {
|
|
3677
|
+
try {
|
|
3678
|
+
return new Intl.DisplayNames([locale], { type: "region", fallback: "none" });
|
|
3679
|
+
} catch {
|
|
3680
|
+
return null;
|
|
3681
|
+
}
|
|
3682
|
+
}
|
|
3683
|
+
function canonicalCode(code) {
|
|
3684
|
+
try {
|
|
3685
|
+
return new Intl.Locale(`und-${code}`).maximize().region ?? code;
|
|
3686
|
+
} catch {
|
|
3687
|
+
return code;
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
function allCodes() {
|
|
3691
|
+
const names = regionNames("en");
|
|
3692
|
+
if (!names) return [];
|
|
3693
|
+
const codes2 = [];
|
|
3694
|
+
for (let a = 65; a <= 90; a++) {
|
|
3695
|
+
for (let b = 65; b <= 90; b++) {
|
|
3696
|
+
const code = String.fromCharCode(a, b);
|
|
3697
|
+
if (!NOT_COUNTRIES.has(code) && names.of(code) && canonicalCode(code) === code) codes2.push(code);
|
|
3698
|
+
}
|
|
3699
|
+
}
|
|
3700
|
+
return codes2;
|
|
3701
|
+
}
|
|
3702
|
+
var lookup = null;
|
|
3703
|
+
var codes = null;
|
|
3704
|
+
function countryCodes() {
|
|
3705
|
+
codes ??= allCodes();
|
|
3706
|
+
return codes;
|
|
3707
|
+
}
|
|
3708
|
+
function countryLookup() {
|
|
3709
|
+
if (lookup) return lookup;
|
|
3710
|
+
lookup = new Map(Object.entries(ALIASES));
|
|
3711
|
+
for (const locale of NAME_LOCALES) {
|
|
3712
|
+
const names = regionNames(locale);
|
|
3713
|
+
if (!names) continue;
|
|
3714
|
+
for (const code of countryCodes()) {
|
|
3715
|
+
const name = names.of(code);
|
|
3716
|
+
if (name) lookup.set(foldText(name), code);
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
return lookup;
|
|
3720
|
+
}
|
|
3721
|
+
function normalizeCountry(value) {
|
|
3722
|
+
const text = (value ?? "").trim();
|
|
3723
|
+
if (!text) return void 0;
|
|
3724
|
+
const upper = text.toUpperCase();
|
|
3725
|
+
if (upper.length === 2) {
|
|
3726
|
+
if (NOT_COUNTRIES.has(upper)) return void 0;
|
|
3727
|
+
if (countryCodes().length === 0) return /^[A-Z]{2}$/.test(upper) ? upper : void 0;
|
|
3728
|
+
const code = canonicalCode(upper);
|
|
3729
|
+
if (countryCodes().includes(code)) return code;
|
|
3730
|
+
}
|
|
3731
|
+
return countryLookup().get(foldText(text));
|
|
3732
|
+
}
|
|
3733
|
+
function listCountries(locale = "en") {
|
|
3734
|
+
const names = regionNames(locale) ?? regionNames("en");
|
|
3735
|
+
return countryCodes().map((code) => ({ code, name: names?.of(code) ?? code })).sort((a, b) => a.name.localeCompare(b.name, locale));
|
|
3736
|
+
}
|
|
3737
|
+
|
|
3738
|
+
// shipping/provinces.ts
|
|
3739
|
+
var CANADA_PROVINCES = [
|
|
3740
|
+
{ code: "AB", name: "Alberta", nameFr: "Alberta", postalLetters: ["T"] },
|
|
3741
|
+
{ code: "BC", name: "British Columbia", nameFr: "Colombie-Britannique", postalLetters: ["V"] },
|
|
3742
|
+
{ code: "MB", name: "Manitoba", nameFr: "Manitoba", postalLetters: ["R"] },
|
|
3743
|
+
{ code: "NB", name: "New Brunswick", nameFr: "Nouveau-Brunswick", postalLetters: ["E"] },
|
|
3744
|
+
{
|
|
3745
|
+
code: "NL",
|
|
3746
|
+
name: "Newfoundland and Labrador",
|
|
3747
|
+
nameFr: "Terre-Neuve-et-Labrador",
|
|
3748
|
+
postalLetters: ["A"],
|
|
3749
|
+
aliases: ["NF", "LB", "Newfoundland", "Labrador"]
|
|
3750
|
+
},
|
|
3751
|
+
{ code: "NS", name: "Nova Scotia", nameFr: "Nouvelle-\xC9cosse", postalLetters: ["B"] },
|
|
3752
|
+
{ code: "NT", name: "Northwest Territories", nameFr: "Territoires du Nord-Ouest", postalLetters: ["X"] },
|
|
3753
|
+
{ code: "NU", name: "Nunavut", nameFr: "Nunavut", postalLetters: ["X"] },
|
|
3754
|
+
{ code: "ON", name: "Ontario", nameFr: "Ontario", postalLetters: ["K", "L", "M", "N", "P"] },
|
|
3755
|
+
{
|
|
3756
|
+
code: "PE",
|
|
3757
|
+
name: "Prince Edward Island",
|
|
3758
|
+
nameFr: "\xCEle-du-Prince-\xC9douard",
|
|
3759
|
+
postalLetters: ["C"],
|
|
3760
|
+
aliases: ["PEI"]
|
|
3761
|
+
},
|
|
3762
|
+
{ code: "QC", name: "Quebec", nameFr: "Qu\xE9bec", postalLetters: ["G", "H", "J"], aliases: ["PQ"] },
|
|
3763
|
+
{ code: "SK", name: "Saskatchewan", nameFr: "Saskatchewan", postalLetters: ["S"] },
|
|
3764
|
+
{ code: "YT", name: "Yukon", nameFr: "Yukon", postalLetters: ["Y"], aliases: ["YK"] }
|
|
3765
|
+
];
|
|
3766
|
+
var PROVINCES_BY_COUNTRY = { CA: CANADA_PROVINCES };
|
|
3767
|
+
var lookups = /* @__PURE__ */ new Map();
|
|
3768
|
+
function provinceLookup(country) {
|
|
3769
|
+
const provinces = PROVINCES_BY_COUNTRY[country];
|
|
3770
|
+
if (!provinces) return void 0;
|
|
3771
|
+
let lookup2 = lookups.get(country);
|
|
3772
|
+
if (!lookup2) {
|
|
3773
|
+
lookup2 = /* @__PURE__ */ new Map();
|
|
3774
|
+
for (const p of provinces) {
|
|
3775
|
+
for (const label of [p.code, p.name, p.nameFr, ...p.aliases ?? []]) lookup2.set(foldText(label), p.code);
|
|
3776
|
+
}
|
|
3777
|
+
lookups.set(country, lookup2);
|
|
3778
|
+
}
|
|
3779
|
+
return lookup2;
|
|
3780
|
+
}
|
|
3781
|
+
function normalizeProvince(country, value) {
|
|
3782
|
+
if (!country || !value?.trim()) return void 0;
|
|
3783
|
+
return provinceLookup(country)?.get(foldText(value));
|
|
3784
|
+
}
|
|
3785
|
+
function listProvinces(country) {
|
|
3786
|
+
return PROVINCES_BY_COUNTRY[country] ?? [];
|
|
3787
|
+
}
|
|
3788
|
+
function provincesForPostCode(country, postCode) {
|
|
3789
|
+
const letter = postCode?.charAt(0);
|
|
3790
|
+
if (!country || !letter) return [];
|
|
3791
|
+
return listProvinces(country).filter((p) => p.postalLetters.includes(letter)).map((p) => p.code);
|
|
3792
|
+
}
|
|
3793
|
+
|
|
3794
|
+
// shipping/normalize.ts
|
|
3795
|
+
var EVERYWHERE_KEY = "*";
|
|
3796
|
+
function normalizeCityKey(value) {
|
|
3797
|
+
const words = foldText(value ?? "").split(" ").filter(Boolean).map((word) => word === "saint" ? "st" : word === "sainte" ? "ste" : word);
|
|
3798
|
+
return words.length ? words.join("") : void 0;
|
|
3799
|
+
}
|
|
3800
|
+
function normalizePostCode(value) {
|
|
3801
|
+
const compact = (value ?? "").replace(/[^0-9a-z]/gi, "").toUpperCase();
|
|
3802
|
+
return compact || void 0;
|
|
3803
|
+
}
|
|
3804
|
+
function normalizeAddress(address) {
|
|
3805
|
+
if (!address) return {};
|
|
3806
|
+
const country = normalizeCountry(address.country);
|
|
3807
|
+
const postCode = normalizePostCode(address.postCode ?? address.postalCode ?? address.zip);
|
|
3808
|
+
const fromPostCode = provincesForPostCode(country, postCode);
|
|
3809
|
+
const province = normalizeProvince(country, address.state ?? address.province) ?? (fromPostCode.length === 1 ? fromPostCode[0] : void 0);
|
|
3810
|
+
return { country, province, cityKey: normalizeCityKey(address.city), postCode };
|
|
3811
|
+
}
|
|
3812
|
+
function postCodeMatchesProvince(address) {
|
|
3813
|
+
const candidates = provincesForPostCode(address.country, address.postCode);
|
|
3814
|
+
if (!address.province || candidates.length === 0) return true;
|
|
3815
|
+
return candidates.includes(address.province);
|
|
3816
|
+
}
|
|
3817
|
+
function placeKey(place) {
|
|
3818
|
+
const country = normalizeCountry(place.country);
|
|
3819
|
+
if (!country) return void 0;
|
|
3820
|
+
if (!place.province) return country;
|
|
3821
|
+
const province = normalizeProvince(country, place.province);
|
|
3822
|
+
if (!province) return void 0;
|
|
3823
|
+
if (!place.city) return `${country}-${province}`;
|
|
3824
|
+
const city = normalizeCityKey(place.city);
|
|
3825
|
+
return city ? `${country}-${province}/${city}` : void 0;
|
|
3826
|
+
}
|
|
3827
|
+
function addressPlaceKeys(address) {
|
|
3828
|
+
const keys = [];
|
|
3829
|
+
if (address.country && address.province && address.cityKey) {
|
|
3830
|
+
keys.push(`${address.country}-${address.province}/${address.cityKey}`);
|
|
3831
|
+
}
|
|
3832
|
+
if (address.country && address.province) keys.push(`${address.country}-${address.province}`);
|
|
3833
|
+
if (address.country) keys.push(address.country);
|
|
3834
|
+
keys.push(EVERYWHERE_KEY);
|
|
3835
|
+
return keys;
|
|
3836
|
+
}
|
|
3837
|
+
|
|
3838
|
+
// shipping/resolve.ts
|
|
3839
|
+
function resolveShipping({ zones, address, itemsTotal, channel }) {
|
|
3840
|
+
const shipsToCountries = countriesShippedTo(zones);
|
|
3841
|
+
const none = (reason, zone2) => ({
|
|
3842
|
+
zoneId: zone2?.id ?? null,
|
|
3843
|
+
options: [],
|
|
3844
|
+
reason,
|
|
3845
|
+
message: zone2?.message?.trim() || null,
|
|
3846
|
+
shipsToCountries
|
|
3847
|
+
});
|
|
3848
|
+
const normalized = normalizeAddress(address);
|
|
3849
|
+
if (!normalized.country) return none("INCOMPLETE" /* INCOMPLETE */);
|
|
3850
|
+
if (!postCodeMatchesProvince(normalized)) return none("ADDRESS_MISMATCH" /* ADDRESS_MISMATCH */);
|
|
3851
|
+
const zone = findZone(zones, addressPlaceKeys(normalized));
|
|
3852
|
+
if (!zone) return none("NO_COVERAGE" /* NO_COVERAGE */);
|
|
3853
|
+
const offered = zone.options.filter((option) => isOffered(option, zone, channel));
|
|
3854
|
+
if (offered.length === 0) {
|
|
3855
|
+
return none(zone.ships ? "NO_OPTION" /* NO_OPTION */ : "BLOCKED" /* BLOCKED */, zone);
|
|
3856
|
+
}
|
|
3857
|
+
const quotes = offered.map((option) => quote(option, zone.id, itemsTotal));
|
|
3858
|
+
const ship = quotes.filter((q) => q.type === "ship" /* SHIP */).sort((a, b) => a.amount - b.amount);
|
|
3859
|
+
const pickup = quotes.filter((q) => q.type === "pickup" /* PICKUP */).sort((a, b) => a.amount - b.amount);
|
|
3860
|
+
return {
|
|
3861
|
+
zoneId: zone.id,
|
|
3862
|
+
options: [...ship, ...pickup],
|
|
3863
|
+
reason: null,
|
|
3864
|
+
message: zone.ships ? null : zone.message?.trim() || null,
|
|
3865
|
+
shipsToCountries
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
function findZone(zones, keys) {
|
|
3869
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
3870
|
+
for (const zone of zones) {
|
|
3871
|
+
for (const key of zoneKeys(zone)) if (!byKey.has(key)) byKey.set(key, zone);
|
|
3872
|
+
}
|
|
3873
|
+
for (const key of keys) {
|
|
3874
|
+
const zone = byKey.get(key);
|
|
3875
|
+
if (zone) return zone;
|
|
3876
|
+
}
|
|
3877
|
+
return void 0;
|
|
3878
|
+
}
|
|
3879
|
+
function zoneKeys(zone) {
|
|
3880
|
+
if (zone.kind === "everywhere" /* EVERYWHERE */) return [EVERYWHERE_KEY];
|
|
3881
|
+
return zone.places.map(placeKey).filter((key) => Boolean(key));
|
|
3882
|
+
}
|
|
3883
|
+
function isOffered(option, zone, channel) {
|
|
3884
|
+
if (!option.channels.some((c) => c === channel)) return false;
|
|
3885
|
+
if (option.type === "pickup" /* PICKUP */) return channel !== "pos" /* POS */;
|
|
3886
|
+
return zone.ships;
|
|
3887
|
+
}
|
|
3888
|
+
function priceForTotal(option, itemsTotal) {
|
|
3889
|
+
const tiers = [...option.priceByTotal ?? []].sort((a, b) => a.from - b.from);
|
|
3890
|
+
let price = option.price;
|
|
3891
|
+
for (const tier of tiers) if (itemsTotal >= tier.from) price = tier.price;
|
|
3892
|
+
if (option.freeOver != null && itemsTotal >= option.freeOver) return 0;
|
|
3893
|
+
return price;
|
|
3894
|
+
}
|
|
3895
|
+
function quote(option, zoneId, itemsTotal) {
|
|
3896
|
+
const amount = priceForTotal(option, itemsTotal);
|
|
3897
|
+
const freeOver = option.freeOver ?? null;
|
|
3898
|
+
return {
|
|
3899
|
+
optionId: option.id,
|
|
3900
|
+
zoneId,
|
|
3901
|
+
type: option.type,
|
|
3902
|
+
name: option.name?.trim() || null,
|
|
3903
|
+
amount,
|
|
3904
|
+
amountToFree: freeOver != null && amount > 0 ? freeOver - itemsTotal : null,
|
|
3905
|
+
minDays: option.minDays ?? null,
|
|
3906
|
+
maxDays: option.maxDays ?? null,
|
|
3907
|
+
outletId: option.outletId ?? null
|
|
3908
|
+
};
|
|
3909
|
+
}
|
|
3910
|
+
function countriesShippedTo(zones) {
|
|
3911
|
+
const countries = /* @__PURE__ */ new Set();
|
|
3912
|
+
for (const zone of zones) {
|
|
3913
|
+
if (!zone.ships) continue;
|
|
3914
|
+
for (const key of zoneKeys(zone)) if (key !== EVERYWHERE_KEY) countries.add(key.slice(0, 2));
|
|
3915
|
+
}
|
|
3916
|
+
return [...countries].sort();
|
|
3917
|
+
}
|
|
3918
|
+
|
|
3919
|
+
// shipping/validate.ts
|
|
3920
|
+
function validateShippingZone(zone) {
|
|
3921
|
+
const problems = [...placeProblems(zone)];
|
|
3922
|
+
for (const option of zone.options) problems.push(...optionProblems(option));
|
|
3923
|
+
const reachesWebsite = zone.options.some((option) => option.channels.includes("web" /* WEB */));
|
|
3924
|
+
if (zone.ships && !reachesWebsite) problems.push({ code: "NO_WEBSITE_OPTION" /* NO_WEBSITE_OPTION */ });
|
|
3925
|
+
return problems;
|
|
3926
|
+
}
|
|
3927
|
+
function placeProblems(zone) {
|
|
3928
|
+
if (zone.kind === "everywhere" /* EVERYWHERE */) {
|
|
3929
|
+
return zone.places.length ? [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }] : [];
|
|
3930
|
+
}
|
|
3931
|
+
if (zone.places.length === 0) return [{ code: "NO_PLACES" /* NO_PLACES */ }];
|
|
3932
|
+
if (!zone.places.every((place) => fitsKind(place, zone.kind))) return [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }];
|
|
3933
|
+
const keys = zone.places.map(placeKey);
|
|
3934
|
+
if (keys.some((key) => !key)) return [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }];
|
|
3935
|
+
if (new Set(keys).size !== keys.length) return [{ code: "DUPLICATE_PLACE" /* DUPLICATE_PLACE */ }];
|
|
3936
|
+
return [];
|
|
3937
|
+
}
|
|
3938
|
+
function fitsKind(place, kind) {
|
|
3939
|
+
const hasProvince = Boolean(place.province?.trim());
|
|
3940
|
+
const hasCity = Boolean(place.city?.trim());
|
|
3941
|
+
if (kind === "country" /* COUNTRY */) return !hasProvince && !hasCity;
|
|
3942
|
+
if (kind === "province" /* PROVINCE */) return hasProvince && !hasCity;
|
|
3943
|
+
if (kind === "city" /* CITY */) return hasProvince && hasCity;
|
|
3944
|
+
return false;
|
|
3945
|
+
}
|
|
3946
|
+
var isAmount = (value) => Number.isInteger(value) && value >= 0;
|
|
3947
|
+
var isDays = (value) => value == null || isAmount(value);
|
|
3948
|
+
function optionProblems(option) {
|
|
3949
|
+
const problems = [];
|
|
3950
|
+
const isPickup = option.type === "pickup" /* PICKUP */;
|
|
3951
|
+
if (!isAmount(option.price) || option.freeOver != null && !isAmount(option.freeOver)) {
|
|
3952
|
+
problems.push("INVALID_PRICE" /* INVALID_PRICE */);
|
|
3953
|
+
}
|
|
3954
|
+
if (!isPickup && !option.name?.trim()) problems.push("MISSING_NAME" /* MISSING_NAME */);
|
|
3955
|
+
if (!isDays(option.minDays) || !isDays(option.maxDays) || (option.minDays ?? 0) > (option.maxDays ?? Infinity)) {
|
|
3956
|
+
problems.push("INVALID_DAYS" /* INVALID_DAYS */);
|
|
3957
|
+
}
|
|
3958
|
+
if (!tiersAreValid(option)) problems.push("INVALID_TIERS" /* INVALID_TIERS */);
|
|
3959
|
+
if (option.channels.length === 0) problems.push("NO_CHANNEL" /* NO_CHANNEL */);
|
|
3960
|
+
if (isPickup && !option.outletId) problems.push("PICKUP_WITHOUT_STORE" /* PICKUP_WITHOUT_STORE */);
|
|
3961
|
+
return problems.map((code) => ({ code, optionId: option.id }));
|
|
3962
|
+
}
|
|
3963
|
+
function tiersAreValid(option) {
|
|
3964
|
+
const tiers = option.priceByTotal ?? [];
|
|
3965
|
+
const froms = tiers.map((tier) => tier.from);
|
|
3966
|
+
return tiers.every((tier) => Number.isInteger(tier.from) && tier.from > 0 && isAmount(tier.price)) && new Set(froms).size === froms.length;
|
|
3967
|
+
}
|
|
3968
|
+
|
|
3567
3969
|
// constants/adyen.constants.ts
|
|
3568
3970
|
var ADYEN_ROLLOUT_COUNTRY_CODES = /* @__PURE__ */ new Set(["CA"]);
|
|
3569
3971
|
function isAdyenRolloutCountry(alpha2) {
|
|
@@ -3613,6 +4015,27 @@ var BNPL_SKIP_REASON = {
|
|
|
3613
4015
|
NO_BUSINESS_LINE: "no_business_line"
|
|
3614
4016
|
};
|
|
3615
4017
|
|
|
4018
|
+
// pos-types/active/ProcessorType.ts
|
|
4019
|
+
var ProcessorType = /* @__PURE__ */ ((ProcessorType2) => {
|
|
4020
|
+
ProcessorType2["FINAL_PAY"] = "Terminal";
|
|
4021
|
+
ProcessorType2["TAP_TO_PAY"] = "TapToPay";
|
|
4022
|
+
ProcessorType2["MOTO"] = "Moto";
|
|
4023
|
+
ProcessorType2["CLOUD"] = "Cloud";
|
|
4024
|
+
ProcessorType2["BLUETOOTH"] = "Bluetooth";
|
|
4025
|
+
ProcessorType2["CASH"] = "Cash";
|
|
4026
|
+
ProcessorType2["CUSTOM_PAY"] = "CustomPay";
|
|
4027
|
+
ProcessorType2["VENDARA"] = "Vendara";
|
|
4028
|
+
ProcessorType2["REDEEM"] = "Redeem";
|
|
4029
|
+
ProcessorType2["INTEGRATION"] = "Integration";
|
|
4030
|
+
ProcessorType2["PAYMENT_LINK"] = "PaymentLink";
|
|
4031
|
+
ProcessorType2["ONLINE_PAYMENT"] = "OnlinePayment";
|
|
4032
|
+
ProcessorType2["EXTERNAL"] = "External";
|
|
4033
|
+
return ProcessorType2;
|
|
4034
|
+
})(ProcessorType || {});
|
|
4035
|
+
|
|
4036
|
+
// constants/payment-channel.constants.ts
|
|
4037
|
+
var PAYMENT_CHANNELS = ["inPerson", "online"];
|
|
4038
|
+
|
|
3616
4039
|
// constants/expense.constants.ts
|
|
3617
4040
|
var EXPENSE_PAYMENT_METHOD_PRESETS = [
|
|
3618
4041
|
"Cash",
|
|
@@ -3654,6 +4077,7 @@ export {
|
|
|
3654
4077
|
BookingResourceStatus,
|
|
3655
4078
|
BookingRulesError,
|
|
3656
4079
|
BookingType,
|
|
4080
|
+
CANADA_PROVINCES,
|
|
3657
4081
|
CONDITION_OPERATORS,
|
|
3658
4082
|
COUNTRY_CURRENCIES,
|
|
3659
4083
|
CURRENCY_CONFIG,
|
|
@@ -3670,6 +4094,7 @@ export {
|
|
|
3670
4094
|
DualWriteStrategy,
|
|
3671
4095
|
EUFixedRates,
|
|
3672
4096
|
EUROPE,
|
|
4097
|
+
EVERYWHERE_KEY,
|
|
3673
4098
|
EXPENSE_DEFAULT_CATEGORIES,
|
|
3674
4099
|
EXPENSE_NAME_MAX_LENGTH,
|
|
3675
4100
|
EXPENSE_PAYMENT_METHOD_PRESETS,
|
|
@@ -3694,6 +4119,7 @@ export {
|
|
|
3694
4119
|
OtherFixedRates,
|
|
3695
4120
|
OwnerType,
|
|
3696
4121
|
PATH_MODES,
|
|
4122
|
+
PAYMENT_CHANNELS,
|
|
3697
4123
|
PAYMENT_STATES,
|
|
3698
4124
|
POS_VALID_INITIAL_STATES,
|
|
3699
4125
|
PaymentMethod,
|
|
@@ -3703,6 +4129,7 @@ export {
|
|
|
3703
4129
|
PricingLevel,
|
|
3704
4130
|
PricingPlanEnum,
|
|
3705
4131
|
PricingRegionEnum,
|
|
4132
|
+
ProcessorType,
|
|
3706
4133
|
ProductStatus,
|
|
3707
4134
|
ProductType,
|
|
3708
4135
|
PublicationAvailability,
|
|
@@ -3721,6 +4148,12 @@ export {
|
|
|
3721
4148
|
SYSTEM_FAMILY_IDS,
|
|
3722
4149
|
SYSTEM_UNITS,
|
|
3723
4150
|
SYSTEM_UNIT_IDS,
|
|
4151
|
+
ShippingChannel,
|
|
4152
|
+
ShippingNoOptionReason,
|
|
4153
|
+
ShippingOptionType,
|
|
4154
|
+
ShippingRateType,
|
|
4155
|
+
ShippingZoneError,
|
|
4156
|
+
ShippingZoneKind,
|
|
3724
4157
|
StationStatus,
|
|
3725
4158
|
StripeCurrencyCode,
|
|
3726
4159
|
StripeStatus,
|
|
@@ -3728,6 +4161,7 @@ export {
|
|
|
3728
4161
|
TopMetericsSort,
|
|
3729
4162
|
UserTypes,
|
|
3730
4163
|
addAmounts,
|
|
4164
|
+
addressPlaceKeys,
|
|
3731
4165
|
adyenLegalEntityRequiresStateOrProvince,
|
|
3732
4166
|
adyenRequiresJobTitle,
|
|
3733
4167
|
adyenStoreRequiresStateOrProvince,
|
|
@@ -3806,25 +4240,38 @@ export {
|
|
|
3806
4240
|
isSystemFamilyCode,
|
|
3807
4241
|
isValidQuantity,
|
|
3808
4242
|
isWhole,
|
|
4243
|
+
lineStockMoves,
|
|
4244
|
+
listCountries,
|
|
4245
|
+
listProvinces,
|
|
3809
4246
|
mapToLegacyStatus,
|
|
3810
4247
|
maxPrecisionFor,
|
|
3811
4248
|
mergeFragment,
|
|
3812
4249
|
modifiersSellable,
|
|
3813
4250
|
multiplyAmount,
|
|
4251
|
+
normalizeAddress,
|
|
4252
|
+
normalizeCityKey,
|
|
4253
|
+
normalizeCountry,
|
|
3814
4254
|
normalizeMongoIdString,
|
|
4255
|
+
normalizePostCode,
|
|
4256
|
+
normalizeProvince,
|
|
3815
4257
|
occupancyIn,
|
|
3816
4258
|
parseAmountToMinorUnits,
|
|
3817
4259
|
parseCurrencyCode,
|
|
3818
4260
|
parseStripeCurrencyCode,
|
|
4261
|
+
placeKey,
|
|
3819
4262
|
planWindow,
|
|
3820
4263
|
poolDemand,
|
|
3821
4264
|
poolOf,
|
|
3822
4265
|
poolShortfall,
|
|
3823
4266
|
poolStockAt,
|
|
4267
|
+
postCodeMatchesProvince,
|
|
3824
4268
|
presentAt,
|
|
4269
|
+
priceForTotal,
|
|
4270
|
+
provincesForPostCode,
|
|
3825
4271
|
removeFragment,
|
|
3826
4272
|
resolveFamily,
|
|
3827
4273
|
resolveModifiersForProduct,
|
|
4274
|
+
resolveShipping,
|
|
3828
4275
|
resolveTemplate,
|
|
3829
4276
|
resolveUnit,
|
|
3830
4277
|
roundToPrecision,
|
|
@@ -3841,6 +4288,7 @@ export {
|
|
|
3841
4288
|
validateConfig,
|
|
3842
4289
|
validateFragmentCompatibility,
|
|
3843
4290
|
validateOrderStatuses,
|
|
4291
|
+
validateShippingZone,
|
|
3844
4292
|
violatesFinancialInvariant,
|
|
3845
4293
|
windowEndsAt,
|
|
3846
4294
|
withinPresence
|