@labdigital/commercetools-mock 2.34.2 → 2.35.0
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.cjs +250 -160
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +250 -160
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/product-projection-search.ts +1 -1
- package/src/product-search.ts +1 -1
- package/src/repositories/cart/actions.ts +160 -4
- package/src/repositories/cart/index.test.ts +151 -0
- package/src/repositories/cart/index.ts +15 -5
- package/src/repositories/helpers.ts +21 -0
- package/src/repositories/product-projection.ts +1 -1
- package/src/repositories/shipping-method/index.ts +2 -54
- package/src/services/cart.test.ts +417 -0
- package/src/{shippingCalculator.test.ts → shipping.test.ts} +1 -1
- package/src/shipping.ts +147 -0
- package/src/shippingCalculator.ts +0 -74
package/dist/index.cjs
CHANGED
|
@@ -183,8 +183,7 @@ var OAuth2Store = class {
|
|
|
183
183
|
};
|
|
184
184
|
}
|
|
185
185
|
validateToken(token) {
|
|
186
|
-
if (!this.validate)
|
|
187
|
-
return true;
|
|
186
|
+
if (!this.validate) return true;
|
|
188
187
|
const foundToken = this.tokens.find((t) => t.access_token === token);
|
|
189
188
|
if (foundToken) {
|
|
190
189
|
return true;
|
|
@@ -654,19 +653,16 @@ function toRegExp(str) {
|
|
|
654
653
|
return new RegExp(str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"));
|
|
655
654
|
}
|
|
656
655
|
function normalize(regex) {
|
|
657
|
-
if (typeof regex === "string")
|
|
658
|
-
regex = toRegExp(regex);
|
|
656
|
+
if (typeof regex === "string") regex = toRegExp(regex);
|
|
659
657
|
if (!regex.source.startsWith("^"))
|
|
660
658
|
return new RegExp(`^${regex.source}`, regex.flags);
|
|
661
|
-
else
|
|
662
|
-
return regex;
|
|
659
|
+
else return regex;
|
|
663
660
|
}
|
|
664
661
|
function first(arr, predicate) {
|
|
665
662
|
let i = 0;
|
|
666
663
|
for (const item of arr) {
|
|
667
664
|
const result = predicate(item, i++);
|
|
668
|
-
if (result)
|
|
669
|
-
return { item, result };
|
|
665
|
+
if (result) return { item, result };
|
|
670
666
|
}
|
|
671
667
|
}
|
|
672
668
|
var TokenTypes = class {
|
|
@@ -830,8 +826,7 @@ var Lexer = class {
|
|
|
830
826
|
*/
|
|
831
827
|
peek(position = this._state.position) {
|
|
832
828
|
const read = (i = position) => {
|
|
833
|
-
if (i >= this._state.source.length)
|
|
834
|
-
return EOF(this);
|
|
829
|
+
if (i >= this._state.source.length) return EOF(this);
|
|
835
830
|
const n = this._tokenTypes.peek(this._state.source, i);
|
|
836
831
|
if (!n || !n.result) {
|
|
837
832
|
throw new Error(
|
|
@@ -851,8 +846,7 @@ var Lexer = class {
|
|
|
851
846
|
) : null;
|
|
852
847
|
};
|
|
853
848
|
const t = read();
|
|
854
|
-
if (t)
|
|
855
|
-
return t;
|
|
849
|
+
if (t) return t;
|
|
856
850
|
let unexpected = this._state.source.substring(position, position + 1);
|
|
857
851
|
try {
|
|
858
852
|
this.peek(position + 1);
|
|
@@ -874,8 +868,7 @@ var Lexer = class {
|
|
|
874
868
|
*/
|
|
875
869
|
strpos(i) {
|
|
876
870
|
let lines = this._state.source.substring(0, i).split(/\r?\n/);
|
|
877
|
-
if (!Array.isArray(lines))
|
|
878
|
-
lines = [lines];
|
|
871
|
+
if (!Array.isArray(lines)) lines = [lines];
|
|
879
872
|
const line = lines.length;
|
|
880
873
|
const column = lines[lines.length - 1].length + 1;
|
|
881
874
|
return { line, column };
|
|
@@ -974,8 +967,7 @@ var Parser = class {
|
|
|
974
967
|
* @returns {number} The binding power of the specified token type
|
|
975
968
|
*/
|
|
976
969
|
bp(tokenOrType) {
|
|
977
|
-
if (tokenOrType == null)
|
|
978
|
-
return Number.NEGATIVE_INFINITY;
|
|
970
|
+
if (tokenOrType == null) return Number.NEGATIVE_INFINITY;
|
|
979
971
|
if (tokenOrType && typeof tokenOrType.isEof == "function" && tokenOrType.isEof())
|
|
980
972
|
return Number.NEGATIVE_INFINITY;
|
|
981
973
|
const type = this._type(tokenOrType);
|
|
@@ -1020,27 +1012,21 @@ var Parser = class {
|
|
|
1020
1012
|
parse(opts = { terminals: [0] }) {
|
|
1021
1013
|
const stop = opts.stop = opts.stop || createStop();
|
|
1022
1014
|
const check = () => {
|
|
1023
|
-
if (stop.isStopped())
|
|
1024
|
-
return false;
|
|
1015
|
+
if (stop.isStopped()) return false;
|
|
1025
1016
|
const t = this.lexer.peek();
|
|
1026
1017
|
const bp = this.bp(t);
|
|
1027
1018
|
return opts.terminals.reduce((canContinue, rbpOrType) => {
|
|
1028
|
-
if (!canContinue)
|
|
1029
|
-
|
|
1030
|
-
if (typeof rbpOrType == "
|
|
1031
|
-
return rbpOrType < bp;
|
|
1032
|
-
if (typeof rbpOrType == "string")
|
|
1033
|
-
return t.type != rbpOrType;
|
|
1019
|
+
if (!canContinue) return false;
|
|
1020
|
+
if (typeof rbpOrType == "number") return rbpOrType < bp;
|
|
1021
|
+
if (typeof rbpOrType == "string") return t.type != rbpOrType;
|
|
1034
1022
|
}, true);
|
|
1035
1023
|
};
|
|
1036
1024
|
const mkinfo = (token) => {
|
|
1037
1025
|
const bp = this.bp(token);
|
|
1038
1026
|
return { token, bp, stop, ctx: opts.ctx, options: opts };
|
|
1039
1027
|
};
|
|
1040
|
-
if (!opts.terminals)
|
|
1041
|
-
|
|
1042
|
-
if (opts.terminals.length == 0)
|
|
1043
|
-
opts.terminals.push(0);
|
|
1028
|
+
if (!opts.terminals) opts.terminals = [0];
|
|
1029
|
+
if (opts.terminals.length == 0) opts.terminals.push(0);
|
|
1044
1030
|
let left = this.nud(mkinfo(this.lexer.next()));
|
|
1045
1031
|
while (check()) {
|
|
1046
1032
|
const operator = this.lexer.next();
|
|
@@ -1380,8 +1366,7 @@ var generateMatchFunc = (predicate) => {
|
|
|
1380
1366
|
const expr = parser.parse({ terminals: [")"] });
|
|
1381
1367
|
return (obj, vars) => {
|
|
1382
1368
|
const value = resolveValue(obj, left);
|
|
1383
|
-
if (!value)
|
|
1384
|
-
return false;
|
|
1369
|
+
if (!value) return false;
|
|
1385
1370
|
const maxDistance = resolveSymbol(expr[2], vars);
|
|
1386
1371
|
const distance = haversineDistance(
|
|
1387
1372
|
{
|
|
@@ -1468,8 +1453,7 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1468
1453
|
getProject = (projectKey) => this.addProject(projectKey);
|
|
1469
1454
|
// Expand resolves a nested reference and injects the object in the given obj
|
|
1470
1455
|
expand = (projectKey, obj, clause) => {
|
|
1471
|
-
if (!clause)
|
|
1472
|
-
return obj;
|
|
1456
|
+
if (!clause) return obj;
|
|
1473
1457
|
const newObj = cloneObject(obj);
|
|
1474
1458
|
if (Array.isArray(clause)) {
|
|
1475
1459
|
for (const c of clause) {
|
|
@@ -1500,15 +1484,13 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1500
1484
|
this._resolveReference(projectKey, reference, params.rest);
|
|
1501
1485
|
} else if (params.index === "*") {
|
|
1502
1486
|
const reference = obj[params.element];
|
|
1503
|
-
if (reference === void 0 || !Array.isArray(reference))
|
|
1504
|
-
return;
|
|
1487
|
+
if (reference === void 0 || !Array.isArray(reference)) return;
|
|
1505
1488
|
for (const itemRef of reference) {
|
|
1506
1489
|
this._resolveReference(projectKey, itemRef, params.rest);
|
|
1507
1490
|
}
|
|
1508
1491
|
} else {
|
|
1509
1492
|
const reference = obj[params.element][params.index];
|
|
1510
|
-
if (reference === void 0)
|
|
1511
|
-
return;
|
|
1493
|
+
if (reference === void 0) return;
|
|
1512
1494
|
this._resolveReference(projectKey, reference, params.rest);
|
|
1513
1495
|
}
|
|
1514
1496
|
};
|
|
@@ -1719,8 +1701,7 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1719
1701
|
});
|
|
1720
1702
|
}
|
|
1721
1703
|
_resolveReference(projectKey, reference, expand) {
|
|
1722
|
-
if (reference === void 0)
|
|
1723
|
-
return;
|
|
1704
|
+
if (reference === void 0) return;
|
|
1724
1705
|
if (reference.typeId !== void 0 && (reference.id !== void 0 || reference.key !== void 0)) {
|
|
1725
1706
|
if (!reference.obj) {
|
|
1726
1707
|
reference.obj = this.getByResourceIdentifier(projectKey, {
|
|
@@ -1768,8 +1749,7 @@ var import_deep_equal = __toESM(require("deep-equal"), 1);
|
|
|
1768
1749
|
|
|
1769
1750
|
// src/repositories/errors.ts
|
|
1770
1751
|
var checkConcurrentModification = (currentVersion, expectedVersion, identifier) => {
|
|
1771
|
-
if (currentVersion === expectedVersion)
|
|
1772
|
-
return;
|
|
1752
|
+
if (currentVersion === expectedVersion) return;
|
|
1773
1753
|
console.error(
|
|
1774
1754
|
`Object ${identifier} has a different version than expected. Expected: ${expectedVersion} - Actual: ${currentVersion}.`
|
|
1775
1755
|
);
|
|
@@ -1942,10 +1922,10 @@ var ProductTailoringUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
1942
1922
|
};
|
|
1943
1923
|
|
|
1944
1924
|
// src/repositories/helpers.ts
|
|
1925
|
+
var import_decimal = require("decimal.js/decimal");
|
|
1945
1926
|
var import_uuid4 = require("uuid");
|
|
1946
1927
|
var createAddress = (base, projectKey, storage) => {
|
|
1947
|
-
if (!base)
|
|
1948
|
-
return void 0;
|
|
1928
|
+
if (!base) return void 0;
|
|
1949
1929
|
if (!base?.country) {
|
|
1950
1930
|
throw new Error("Country is required");
|
|
1951
1931
|
}
|
|
@@ -1954,12 +1934,9 @@ var createAddress = (base, projectKey, storage) => {
|
|
|
1954
1934
|
};
|
|
1955
1935
|
};
|
|
1956
1936
|
var createCustomFields = (draft, projectKey, storage) => {
|
|
1957
|
-
if (!draft)
|
|
1958
|
-
|
|
1959
|
-
if (!draft.type)
|
|
1960
|
-
return void 0;
|
|
1961
|
-
if (!draft.type.typeId)
|
|
1962
|
-
return void 0;
|
|
1937
|
+
if (!draft) return void 0;
|
|
1938
|
+
if (!draft.type) return void 0;
|
|
1939
|
+
if (!draft.type.typeId) return void 0;
|
|
1963
1940
|
const typeResource = storage.getByResourceIdentifier(
|
|
1964
1941
|
projectKey,
|
|
1965
1942
|
draft.type
|
|
@@ -1981,6 +1958,18 @@ var createPrice = (draft) => ({
|
|
|
1981
1958
|
id: (0, import_uuid4.v4)(),
|
|
1982
1959
|
value: createTypedMoney(draft.value)
|
|
1983
1960
|
});
|
|
1961
|
+
var roundDecimal = (decimal, roundingMode) => {
|
|
1962
|
+
switch (roundingMode) {
|
|
1963
|
+
case "HalfEven":
|
|
1964
|
+
return decimal.toDecimalPlaces(0, import_decimal.Decimal.ROUND_HALF_EVEN);
|
|
1965
|
+
case "HalfUp":
|
|
1966
|
+
return decimal.toDecimalPlaces(0, import_decimal.Decimal.ROUND_HALF_UP);
|
|
1967
|
+
case "HalfDown":
|
|
1968
|
+
return decimal.toDecimalPlaces(0, import_decimal.Decimal.ROUND_HALF_DOWN);
|
|
1969
|
+
default:
|
|
1970
|
+
throw new Error(`Unknown rounding mode: ${roundingMode}`);
|
|
1971
|
+
}
|
|
1972
|
+
};
|
|
1984
1973
|
var createCentPrecisionMoney = (value) => {
|
|
1985
1974
|
let fractionDigits = 2;
|
|
1986
1975
|
switch (value.currencyCode.toUpperCase()) {
|
|
@@ -2030,8 +2019,7 @@ var createTypedMoney = (value) => {
|
|
|
2030
2019
|
return result;
|
|
2031
2020
|
};
|
|
2032
2021
|
var resolveStoreReference = (ref, projectKey, storage) => {
|
|
2033
|
-
if (!ref)
|
|
2034
|
-
return void 0;
|
|
2022
|
+
if (!ref) return void 0;
|
|
2035
2023
|
const resource = storage.getByResourceIdentifier(projectKey, ref);
|
|
2036
2024
|
if (!resource) {
|
|
2037
2025
|
throw new Error("No such store");
|
|
@@ -2099,8 +2087,7 @@ var getRepositoryContext = (request) => ({
|
|
|
2099
2087
|
storeKey: request.params.storeKey
|
|
2100
2088
|
});
|
|
2101
2089
|
var createAssociate = (a, projectKey, storage) => {
|
|
2102
|
-
if (!a)
|
|
2103
|
-
return void 0;
|
|
2090
|
+
if (!a) return void 0;
|
|
2104
2091
|
if (!a.associateRoleAssignments) {
|
|
2105
2092
|
throw new Error("AssociateRoleAssignments is required");
|
|
2106
2093
|
}
|
|
@@ -2406,8 +2393,95 @@ var BusinessUnitUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
2406
2393
|
var import_uuid6 = require("uuid");
|
|
2407
2394
|
|
|
2408
2395
|
// src/repositories/cart/actions.ts
|
|
2396
|
+
var import_decimal2 = require("decimal.js/decimal");
|
|
2409
2397
|
var import_uuid5 = require("uuid");
|
|
2410
2398
|
|
|
2399
|
+
// src/shipping.ts
|
|
2400
|
+
var markMatchingShippingRate = (cart, shippingRate) => {
|
|
2401
|
+
const isMatching = shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
|
|
2402
|
+
return {
|
|
2403
|
+
...shippingRate,
|
|
2404
|
+
tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
|
|
2405
|
+
isMatching
|
|
2406
|
+
};
|
|
2407
|
+
};
|
|
2408
|
+
var markMatchingShippingRatePriceTiers = (cart, tiers) => {
|
|
2409
|
+
if (tiers.length === 0) {
|
|
2410
|
+
return [];
|
|
2411
|
+
}
|
|
2412
|
+
if (new Set(tiers.map((tier) => tier.type)).size > 1) {
|
|
2413
|
+
throw new Error("Can't handle multiple types of tiers");
|
|
2414
|
+
}
|
|
2415
|
+
const tierType = tiers[0].type;
|
|
2416
|
+
switch (tierType) {
|
|
2417
|
+
case "CartValue":
|
|
2418
|
+
return markMatchingCartValueTiers(cart, tiers);
|
|
2419
|
+
// case 'CartClassification':
|
|
2420
|
+
// return markMatchingCartClassificationTiers(cart, tiers)
|
|
2421
|
+
// case 'CartScore':
|
|
2422
|
+
// return markMatchingCartScoreTiers(cart, tiers)
|
|
2423
|
+
default:
|
|
2424
|
+
throw new Error(`Unsupported tier type: ${tierType}`);
|
|
2425
|
+
}
|
|
2426
|
+
};
|
|
2427
|
+
var markMatchingCartValueTiers = (cart, tiers) => {
|
|
2428
|
+
const sortedTiers = [...tiers].sort(
|
|
2429
|
+
(a, b) => b.minimumCentAmount - a.minimumCentAmount
|
|
2430
|
+
);
|
|
2431
|
+
const result = {};
|
|
2432
|
+
let hasMatchingTier = false;
|
|
2433
|
+
for (const tier of sortedTiers) {
|
|
2434
|
+
const isMatching = !hasMatchingTier && cart.totalPrice.currencyCode === tier.price.currencyCode && cart.totalPrice.centAmount >= tier.minimumCentAmount;
|
|
2435
|
+
if (isMatching) hasMatchingTier = true;
|
|
2436
|
+
result[tier.minimumCentAmount] = {
|
|
2437
|
+
...tier,
|
|
2438
|
+
isMatching
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
return tiers.map((tier) => result[tier.minimumCentAmount]);
|
|
2442
|
+
};
|
|
2443
|
+
var getShippingMethodsMatchingCart = (context, storage, cart, params = {}) => {
|
|
2444
|
+
if (!cart.shippingAddress?.country) {
|
|
2445
|
+
throw new CommercetoolsError({
|
|
2446
|
+
code: "InvalidOperation",
|
|
2447
|
+
message: `The cart with ID '${cart.id}' does not have a shipping address set.`
|
|
2448
|
+
});
|
|
2449
|
+
}
|
|
2450
|
+
const zones = storage.query(context.projectKey, "zone", {
|
|
2451
|
+
where: [`locations(country="${cart.shippingAddress.country}"))`],
|
|
2452
|
+
limit: 100
|
|
2453
|
+
});
|
|
2454
|
+
const zoneIds = zones.results.map((zone) => zone.id);
|
|
2455
|
+
const shippingMethods = storage.query(
|
|
2456
|
+
context.projectKey,
|
|
2457
|
+
"shipping-method",
|
|
2458
|
+
{
|
|
2459
|
+
"where": [
|
|
2460
|
+
`zoneRates(zone(id in (:zoneIds)))`,
|
|
2461
|
+
`zoneRates(shippingRates(price(currencyCode="${cart.totalPrice.currencyCode}")))`
|
|
2462
|
+
],
|
|
2463
|
+
"var.zoneIds": zoneIds,
|
|
2464
|
+
"expand": params.expand
|
|
2465
|
+
}
|
|
2466
|
+
);
|
|
2467
|
+
const results = shippingMethods.results.map((shippingMethod) => {
|
|
2468
|
+
const rates = shippingMethod.zoneRates.map((zoneRate) => ({
|
|
2469
|
+
zone: zoneRate.zone,
|
|
2470
|
+
// Iterate through the shippingRates and mark the matching ones
|
|
2471
|
+
// then we filter out the non-matching ones
|
|
2472
|
+
shippingRates: zoneRate.shippingRates.map((rate) => markMatchingShippingRate(cart, rate)).filter((rate) => rate.isMatching)
|
|
2473
|
+
})).filter((zoneRate) => zoneRate.shippingRates.length > 0);
|
|
2474
|
+
return {
|
|
2475
|
+
...shippingMethod,
|
|
2476
|
+
zoneRates: rates
|
|
2477
|
+
};
|
|
2478
|
+
}).filter((shippingMethod) => shippingMethod.zoneRates.length > 0);
|
|
2479
|
+
return {
|
|
2480
|
+
...shippingMethods,
|
|
2481
|
+
results
|
|
2482
|
+
};
|
|
2483
|
+
};
|
|
2484
|
+
|
|
2411
2485
|
// src/repositories/cart/helpers.ts
|
|
2412
2486
|
var selectPrice = ({
|
|
2413
2487
|
prices,
|
|
@@ -2469,10 +2543,8 @@ var CartUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
2469
2543
|
product.masterData.current.masterVariant,
|
|
2470
2544
|
...product.masterData.current.variants
|
|
2471
2545
|
].find((x) => {
|
|
2472
|
-
if (sku)
|
|
2473
|
-
|
|
2474
|
-
if (variantId)
|
|
2475
|
-
return x.id === variantId;
|
|
2546
|
+
if (sku) return x.sku === sku;
|
|
2547
|
+
if (variantId) return x.id === variantId;
|
|
2476
2548
|
return false;
|
|
2477
2549
|
});
|
|
2478
2550
|
if (!variant) {
|
|
@@ -2778,16 +2850,116 @@ var CartUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
2778
2850
|
}
|
|
2779
2851
|
setShippingMethod(context, resource, { shippingMethod }) {
|
|
2780
2852
|
if (shippingMethod) {
|
|
2781
|
-
|
|
2853
|
+
if (resource.taxMode === "External") {
|
|
2854
|
+
throw new Error("External tax rate is not supported");
|
|
2855
|
+
}
|
|
2856
|
+
const country = resource.shippingAddress?.country;
|
|
2857
|
+
if (!country) {
|
|
2858
|
+
throw new CommercetoolsError({
|
|
2859
|
+
code: "InvalidOperation",
|
|
2860
|
+
message: `The cart with ID '${resource.id}' does not have a shipping address set.`
|
|
2861
|
+
});
|
|
2862
|
+
}
|
|
2863
|
+
this._storage.getByResourceIdentifier(
|
|
2782
2864
|
context.projectKey,
|
|
2783
2865
|
shippingMethod
|
|
2784
2866
|
);
|
|
2867
|
+
const shippingMethods = getShippingMethodsMatchingCart(
|
|
2868
|
+
context,
|
|
2869
|
+
this._storage,
|
|
2870
|
+
resource,
|
|
2871
|
+
{
|
|
2872
|
+
expand: ["zoneRates[*].zone"]
|
|
2873
|
+
}
|
|
2874
|
+
);
|
|
2875
|
+
const method = shippingMethods.results.find(
|
|
2876
|
+
(candidate) => shippingMethod.id ? candidate.id === shippingMethod.id : candidate.key === shippingMethod.key
|
|
2877
|
+
);
|
|
2878
|
+
if (!method) {
|
|
2879
|
+
throw new CommercetoolsError({
|
|
2880
|
+
code: "ShippingMethodDoesNotMatchCart",
|
|
2881
|
+
message: `The shipping method with ${shippingMethod.id ? `ID '${shippingMethod.id}'` : `key '${shippingMethod.key}'`} is not allowed for the cart with ID '${resource.id}'.`
|
|
2882
|
+
});
|
|
2883
|
+
}
|
|
2884
|
+
const taxCategory = this._storage.getByResourceIdentifier(
|
|
2885
|
+
context.projectKey,
|
|
2886
|
+
method.taxCategory
|
|
2887
|
+
);
|
|
2888
|
+
const taxRate = taxCategory.rates.find(
|
|
2889
|
+
(rate) => rate.country === country
|
|
2890
|
+
);
|
|
2891
|
+
if (!taxRate) {
|
|
2892
|
+
throw new CommercetoolsError({
|
|
2893
|
+
code: "MissingTaxRateForCountry",
|
|
2894
|
+
message: `Tax category '${taxCategory.id}' is missing a tax rate for country '${country}'.`,
|
|
2895
|
+
taxCategoryId: taxCategory.id
|
|
2896
|
+
});
|
|
2897
|
+
}
|
|
2898
|
+
const zoneRate = method.zoneRates.find(
|
|
2899
|
+
(rate) => rate.zone.obj.locations.some((loc) => loc.country === country)
|
|
2900
|
+
);
|
|
2901
|
+
if (!zoneRate) {
|
|
2902
|
+
throw new Error("Zone rate not found");
|
|
2903
|
+
}
|
|
2904
|
+
const shippingRate = zoneRate.shippingRates[0];
|
|
2905
|
+
if (!shippingRate) {
|
|
2906
|
+
throw new Error("Shipping rate not found");
|
|
2907
|
+
}
|
|
2908
|
+
const shippingRateTier = shippingRate.tiers.find(
|
|
2909
|
+
(tier) => tier.isMatching
|
|
2910
|
+
);
|
|
2911
|
+
if (shippingRateTier && shippingRateTier.type !== "CartValue") {
|
|
2912
|
+
throw new Error("Non-CartValue shipping rate tier is not supported");
|
|
2913
|
+
}
|
|
2914
|
+
const shippingPrice = shippingRateTier ? createCentPrecisionMoney(shippingRateTier.price) : shippingRate.price;
|
|
2915
|
+
const totalGross = taxRate.includedInPrice ? shippingPrice : {
|
|
2916
|
+
...shippingPrice,
|
|
2917
|
+
centAmount: roundDecimal(
|
|
2918
|
+
new import_decimal2.Decimal(shippingPrice.centAmount).mul(1 + taxRate.amount),
|
|
2919
|
+
resource.taxRoundingMode
|
|
2920
|
+
).toNumber()
|
|
2921
|
+
};
|
|
2922
|
+
const totalNet = taxRate.includedInPrice ? {
|
|
2923
|
+
...shippingPrice,
|
|
2924
|
+
centAmount: roundDecimal(
|
|
2925
|
+
new import_decimal2.Decimal(shippingPrice.centAmount).div(1 + taxRate.amount),
|
|
2926
|
+
resource.taxRoundingMode
|
|
2927
|
+
).toNumber()
|
|
2928
|
+
} : shippingPrice;
|
|
2929
|
+
const taxPortions = [
|
|
2930
|
+
{
|
|
2931
|
+
name: taxRate.name,
|
|
2932
|
+
rate: taxRate.amount,
|
|
2933
|
+
amount: {
|
|
2934
|
+
...shippingPrice,
|
|
2935
|
+
centAmount: totalGross.centAmount - totalNet.centAmount
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
];
|
|
2939
|
+
const totalTax = {
|
|
2940
|
+
...shippingPrice,
|
|
2941
|
+
centAmount: taxPortions.reduce(
|
|
2942
|
+
(acc, portion) => acc + portion.amount.centAmount,
|
|
2943
|
+
0
|
|
2944
|
+
)
|
|
2945
|
+
};
|
|
2946
|
+
const taxedPrice = {
|
|
2947
|
+
totalNet,
|
|
2948
|
+
totalGross,
|
|
2949
|
+
taxPortions,
|
|
2950
|
+
totalTax
|
|
2951
|
+
};
|
|
2785
2952
|
resource.shippingInfo = {
|
|
2786
2953
|
shippingMethod: {
|
|
2787
2954
|
typeId: "shipping-method",
|
|
2788
2955
|
id: method.id
|
|
2789
2956
|
},
|
|
2790
|
-
shippingMethodName: method.name
|
|
2957
|
+
shippingMethodName: method.name,
|
|
2958
|
+
price: shippingPrice,
|
|
2959
|
+
shippingRate,
|
|
2960
|
+
taxedPrice,
|
|
2961
|
+
taxRate,
|
|
2962
|
+
taxCategory: method.taxCategory
|
|
2791
2963
|
};
|
|
2792
2964
|
} else {
|
|
2793
2965
|
resource.shippingInfo = void 0;
|
|
@@ -2812,8 +2984,11 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2812
2984
|
) ?? [];
|
|
2813
2985
|
const resource = {
|
|
2814
2986
|
...getBaseResourceProperties(),
|
|
2987
|
+
anonymousId: draft.anonymousId,
|
|
2988
|
+
billingAddress: draft.billingAddress ? createAddress(draft.billingAddress, context.projectKey, this._storage) : void 0,
|
|
2815
2989
|
cartState: "Active",
|
|
2816
2990
|
country: draft.country,
|
|
2991
|
+
customerEmail: draft.customerEmail,
|
|
2817
2992
|
customLineItems: [],
|
|
2818
2993
|
directDiscounts: [],
|
|
2819
2994
|
discountCodes: [],
|
|
@@ -2831,11 +3006,11 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2831
3006
|
fractionDigits: 0
|
|
2832
3007
|
},
|
|
2833
3008
|
shippingMode: "Single",
|
|
2834
|
-
shippingAddress: createAddress(
|
|
3009
|
+
shippingAddress: draft.shippingAddress ? createAddress(
|
|
2835
3010
|
draft.shippingAddress,
|
|
2836
3011
|
context.projectKey,
|
|
2837
3012
|
this._storage
|
|
2838
|
-
),
|
|
3013
|
+
) : void 0,
|
|
2839
3014
|
shipping: [],
|
|
2840
3015
|
origin: draft.origin ?? "Customer",
|
|
2841
3016
|
refusedGifts: [],
|
|
@@ -2846,6 +3021,7 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2846
3021
|
)
|
|
2847
3022
|
};
|
|
2848
3023
|
resource.totalPrice.centAmount = calculateCartTotalPrice(resource);
|
|
3024
|
+
resource.store = context.storeKey ? { typeId: "store", key: context.storeKey } : void 0;
|
|
2849
3025
|
return this.saveNew(context, resource);
|
|
2850
3026
|
}
|
|
2851
3027
|
getActiveCart(projectKey) {
|
|
@@ -2882,10 +3058,8 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2882
3058
|
product.masterData.current.masterVariant,
|
|
2883
3059
|
...product.masterData.current.variants
|
|
2884
3060
|
].find((x) => {
|
|
2885
|
-
if (sku)
|
|
2886
|
-
|
|
2887
|
-
if (variantId)
|
|
2888
|
-
return x.id === variantId;
|
|
3061
|
+
if (sku) return x.sku === sku;
|
|
3062
|
+
if (variantId) return x.id === variantId;
|
|
2889
3063
|
return false;
|
|
2890
3064
|
});
|
|
2891
3065
|
if (!variant) {
|
|
@@ -4143,8 +4317,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4143
4317
|
(0, import_assert2.default)(resource.shippingInfo, "shippingInfo is not defined");
|
|
4144
4318
|
if (Array.isArray(resource.shippingInfo.deliveries)) {
|
|
4145
4319
|
resource.shippingInfo.deliveries.map((delivery) => {
|
|
4146
|
-
if (delivery.id !== deliveryId)
|
|
4147
|
-
throw "No matching delivery id found";
|
|
4320
|
+
if (delivery.id !== deliveryId) throw "No matching delivery id found";
|
|
4148
4321
|
if (delivery.custom) {
|
|
4149
4322
|
const update = delivery.custom.fields;
|
|
4150
4323
|
update[name] = value;
|
|
@@ -4171,8 +4344,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4171
4344
|
);
|
|
4172
4345
|
}
|
|
4173
4346
|
setStore(context, resource, { store }) {
|
|
4174
|
-
if (!store)
|
|
4175
|
-
return;
|
|
4347
|
+
if (!store) return;
|
|
4176
4348
|
const resolvedType = this._storage.getByResourceIdentifier(
|
|
4177
4349
|
context.projectKey,
|
|
4178
4350
|
store
|
|
@@ -4203,8 +4375,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4203
4375
|
};
|
|
4204
4376
|
}
|
|
4205
4377
|
updateSyncInfo(context, resource, { channel, externalId, syncedAt }) {
|
|
4206
|
-
if (!channel)
|
|
4207
|
-
return;
|
|
4378
|
+
if (!channel) return;
|
|
4208
4379
|
const resolvedType = this._storage.getByResourceIdentifier(
|
|
4209
4380
|
context.projectKey,
|
|
4210
4381
|
channel
|
|
@@ -4794,8 +4965,7 @@ var generateMatchFunc2 = (filter) => {
|
|
|
4794
4965
|
throw new Error(`Syntax error while parsing '${filter}'.`);
|
|
4795
4966
|
}
|
|
4796
4967
|
return (obj) => {
|
|
4797
|
-
if (!result.children)
|
|
4798
|
-
return false;
|
|
4968
|
+
if (!result.children) return false;
|
|
4799
4969
|
return result.children.some((c) => c.match(obj));
|
|
4800
4970
|
};
|
|
4801
4971
|
};
|
|
@@ -5109,7 +5279,7 @@ var ProductSearch = class {
|
|
|
5109
5279
|
let resources = this._storage.all(projectKey, "product").map(
|
|
5110
5280
|
(r) => this.transform(r, params.productProjectionParameters?.staged ?? false)
|
|
5111
5281
|
).filter((p) => {
|
|
5112
|
-
if (!params.productProjectionParameters?.staged) {
|
|
5282
|
+
if (!(params.productProjectionParameters?.staged ?? false)) {
|
|
5113
5283
|
return p.published;
|
|
5114
5284
|
}
|
|
5115
5285
|
return true;
|
|
@@ -6106,7 +6276,7 @@ var ProductProjectionSearch = class {
|
|
|
6106
6276
|
}
|
|
6107
6277
|
search(projectKey, params) {
|
|
6108
6278
|
let resources = this._storage.all(projectKey, "product").map((r) => this.transform(r, params.staged ?? false)).filter((p) => {
|
|
6109
|
-
if (!params.staged) {
|
|
6279
|
+
if (!(params.staged ?? false)) {
|
|
6110
6280
|
return p.published;
|
|
6111
6281
|
}
|
|
6112
6282
|
return true;
|
|
@@ -6191,8 +6361,7 @@ var ProductProjectionSearch = class {
|
|
|
6191
6361
|
};
|
|
6192
6362
|
}
|
|
6193
6363
|
getFacets(params, products) {
|
|
6194
|
-
if (!params.facet)
|
|
6195
|
-
return {};
|
|
6364
|
+
if (!params.facet) return {};
|
|
6196
6365
|
const result = {};
|
|
6197
6366
|
const regexp = new RegExp(/ counting products$/);
|
|
6198
6367
|
for (let facet of params.facet) {
|
|
@@ -6371,7 +6540,7 @@ var ProductProjectionRepository = class extends AbstractResourceRepository {
|
|
|
6371
6540
|
}
|
|
6372
6541
|
query(context, params = {}) {
|
|
6373
6542
|
let resources = this._storage.all(context.projectKey, "product").map((r) => this._searchService.transform(r, params.staged ?? false)).filter((p) => {
|
|
6374
|
-
if (!params.staged) {
|
|
6543
|
+
if (!(params.staged ?? false)) {
|
|
6375
6544
|
return p.published;
|
|
6376
6545
|
}
|
|
6377
6546
|
return true;
|
|
@@ -6675,8 +6844,7 @@ var ReviewRepository = class extends AbstractResourceRepository {
|
|
|
6675
6844
|
super("review", storage);
|
|
6676
6845
|
}
|
|
6677
6846
|
create(context, draft) {
|
|
6678
|
-
if (!draft.target)
|
|
6679
|
-
throw new Error("Missing target");
|
|
6847
|
+
if (!draft.target) throw new Error("Missing target");
|
|
6680
6848
|
const resource = {
|
|
6681
6849
|
...getBaseResourceProperties(),
|
|
6682
6850
|
locale: draft.locale,
|
|
@@ -6702,48 +6870,6 @@ var ReviewRepository = class extends AbstractResourceRepository {
|
|
|
6702
6870
|
}
|
|
6703
6871
|
};
|
|
6704
6872
|
|
|
6705
|
-
// src/shippingCalculator.ts
|
|
6706
|
-
var markMatchingShippingRate = (cart, shippingRate) => {
|
|
6707
|
-
const isMatching = shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
|
|
6708
|
-
return {
|
|
6709
|
-
...shippingRate,
|
|
6710
|
-
tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
|
|
6711
|
-
isMatching
|
|
6712
|
-
};
|
|
6713
|
-
};
|
|
6714
|
-
var markMatchingShippingRatePriceTiers = (cart, tiers) => {
|
|
6715
|
-
if (tiers.length === 0) {
|
|
6716
|
-
return [];
|
|
6717
|
-
}
|
|
6718
|
-
if (new Set(tiers.map((tier) => tier.type)).size > 1) {
|
|
6719
|
-
throw new Error("Can't handle multiple types of tiers");
|
|
6720
|
-
}
|
|
6721
|
-
const tierType = tiers[0].type;
|
|
6722
|
-
switch (tierType) {
|
|
6723
|
-
case "CartValue":
|
|
6724
|
-
return markMatchingCartValueTiers(cart, tiers);
|
|
6725
|
-
default:
|
|
6726
|
-
throw new Error(`Unsupported tier type: ${tierType}`);
|
|
6727
|
-
}
|
|
6728
|
-
};
|
|
6729
|
-
var markMatchingCartValueTiers = (cart, tiers) => {
|
|
6730
|
-
const sortedTiers = [...tiers].sort(
|
|
6731
|
-
(a, b) => b.minimumCentAmount - a.minimumCentAmount
|
|
6732
|
-
);
|
|
6733
|
-
const result = {};
|
|
6734
|
-
let hasMatchingTier = false;
|
|
6735
|
-
for (const tier of sortedTiers) {
|
|
6736
|
-
const isMatching = !hasMatchingTier && cart.totalPrice.currencyCode === tier.price.currencyCode && cart.totalPrice.centAmount >= tier.minimumCentAmount;
|
|
6737
|
-
if (isMatching)
|
|
6738
|
-
hasMatchingTier = true;
|
|
6739
|
-
result[tier.minimumCentAmount] = {
|
|
6740
|
-
...tier,
|
|
6741
|
-
isMatching
|
|
6742
|
-
};
|
|
6743
|
-
}
|
|
6744
|
-
return tiers.map((tier) => result[tier.minimumCentAmount]);
|
|
6745
|
-
};
|
|
6746
|
-
|
|
6747
6873
|
// src/repositories/shipping-method/actions.ts
|
|
6748
6874
|
var import_deep_equal3 = __toESM(require("deep-equal"), 1);
|
|
6749
6875
|
|
|
@@ -6887,41 +7013,7 @@ var ShippingMethodRepository = class extends AbstractResourceRepository {
|
|
|
6887
7013
|
if (!cart) {
|
|
6888
7014
|
return void 0;
|
|
6889
7015
|
}
|
|
6890
|
-
|
|
6891
|
-
throw new CommercetoolsError({
|
|
6892
|
-
code: "InvalidOperation",
|
|
6893
|
-
message: `The cart with ID '${cart.id}' does not have a shipping address set.`
|
|
6894
|
-
});
|
|
6895
|
-
}
|
|
6896
|
-
const zones = this._storage.query(context.projectKey, "zone", {
|
|
6897
|
-
where: [`locations(country="${cart.shippingAddress.country}"))`],
|
|
6898
|
-
limit: 100
|
|
6899
|
-
});
|
|
6900
|
-
const zoneIds = zones.results.map((zone) => zone.id);
|
|
6901
|
-
const shippingMethods = this.query(context, {
|
|
6902
|
-
"where": [
|
|
6903
|
-
`zoneRates(zone(id in (:zoneIds)))`,
|
|
6904
|
-
`zoneRates(shippingRates(price(currencyCode="${cart.totalPrice.currencyCode}")))`
|
|
6905
|
-
],
|
|
6906
|
-
"var.zoneIds": zoneIds,
|
|
6907
|
-
"expand": params.expand
|
|
6908
|
-
});
|
|
6909
|
-
const results = shippingMethods.results.map((shippingMethod) => {
|
|
6910
|
-
const rates = shippingMethod.zoneRates.map((zoneRate) => ({
|
|
6911
|
-
zone: zoneRate.zone,
|
|
6912
|
-
// Iterate through the shippingRates and mark the matching ones
|
|
6913
|
-
// then we filter out the non-matching ones
|
|
6914
|
-
shippingRates: zoneRate.shippingRates.map((rate) => markMatchingShippingRate(cart, rate)).filter((rate) => rate.isMatching)
|
|
6915
|
-
})).filter((zoneRate) => zoneRate.shippingRates.length > 0);
|
|
6916
|
-
return {
|
|
6917
|
-
...shippingMethod,
|
|
6918
|
-
zoneRates: rates
|
|
6919
|
-
};
|
|
6920
|
-
}).filter((shippingMethod) => shippingMethod.zoneRates.length > 0);
|
|
6921
|
-
return {
|
|
6922
|
-
...shippingMethods,
|
|
6923
|
-
results
|
|
6924
|
-
};
|
|
7016
|
+
return getShippingMethodsMatchingCart(context, this._storage, cart, params);
|
|
6925
7017
|
}
|
|
6926
7018
|
_transformZoneRateDraft(context, draft) {
|
|
6927
7019
|
return {
|
|
@@ -7361,8 +7453,7 @@ var StoreRepository = class extends AbstractResourceRepository {
|
|
|
7361
7453
|
}
|
|
7362
7454
|
};
|
|
7363
7455
|
var transformChannels = (context, storage, channels) => {
|
|
7364
|
-
if (!channels)
|
|
7365
|
-
return [];
|
|
7456
|
+
if (!channels) return [];
|
|
7366
7457
|
return channels.map(
|
|
7367
7458
|
(ref) => getReferenceFromResourceIdentifier(
|
|
7368
7459
|
ref,
|
|
@@ -7785,8 +7876,7 @@ var AbstractService = class {
|
|
|
7785
7876
|
expand: this._parseParam(request.query.expand)
|
|
7786
7877
|
}
|
|
7787
7878
|
);
|
|
7788
|
-
if (!result)
|
|
7789
|
-
return response.status(404).send();
|
|
7879
|
+
if (!result) return response.status(404).send();
|
|
7790
7880
|
return response.status(200).send(result);
|
|
7791
7881
|
}
|
|
7792
7882
|
deleteWithId(request, response) {
|