@labdigital/commercetools-mock 2.34.3 → 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 +244 -158
- 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 +244 -158
- 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/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;
|
|
@@ -2886,10 +3058,8 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2886
3058
|
product.masterData.current.masterVariant,
|
|
2887
3059
|
...product.masterData.current.variants
|
|
2888
3060
|
].find((x) => {
|
|
2889
|
-
if (sku)
|
|
2890
|
-
|
|
2891
|
-
if (variantId)
|
|
2892
|
-
return x.id === variantId;
|
|
3061
|
+
if (sku) return x.sku === sku;
|
|
3062
|
+
if (variantId) return x.id === variantId;
|
|
2893
3063
|
return false;
|
|
2894
3064
|
});
|
|
2895
3065
|
if (!variant) {
|
|
@@ -4147,8 +4317,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4147
4317
|
(0, import_assert2.default)(resource.shippingInfo, "shippingInfo is not defined");
|
|
4148
4318
|
if (Array.isArray(resource.shippingInfo.deliveries)) {
|
|
4149
4319
|
resource.shippingInfo.deliveries.map((delivery) => {
|
|
4150
|
-
if (delivery.id !== deliveryId)
|
|
4151
|
-
throw "No matching delivery id found";
|
|
4320
|
+
if (delivery.id !== deliveryId) throw "No matching delivery id found";
|
|
4152
4321
|
if (delivery.custom) {
|
|
4153
4322
|
const update = delivery.custom.fields;
|
|
4154
4323
|
update[name] = value;
|
|
@@ -4175,8 +4344,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4175
4344
|
);
|
|
4176
4345
|
}
|
|
4177
4346
|
setStore(context, resource, { store }) {
|
|
4178
|
-
if (!store)
|
|
4179
|
-
return;
|
|
4347
|
+
if (!store) return;
|
|
4180
4348
|
const resolvedType = this._storage.getByResourceIdentifier(
|
|
4181
4349
|
context.projectKey,
|
|
4182
4350
|
store
|
|
@@ -4207,8 +4375,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4207
4375
|
};
|
|
4208
4376
|
}
|
|
4209
4377
|
updateSyncInfo(context, resource, { channel, externalId, syncedAt }) {
|
|
4210
|
-
if (!channel)
|
|
4211
|
-
return;
|
|
4378
|
+
if (!channel) return;
|
|
4212
4379
|
const resolvedType = this._storage.getByResourceIdentifier(
|
|
4213
4380
|
context.projectKey,
|
|
4214
4381
|
channel
|
|
@@ -4798,8 +4965,7 @@ var generateMatchFunc2 = (filter) => {
|
|
|
4798
4965
|
throw new Error(`Syntax error while parsing '${filter}'.`);
|
|
4799
4966
|
}
|
|
4800
4967
|
return (obj) => {
|
|
4801
|
-
if (!result.children)
|
|
4802
|
-
return false;
|
|
4968
|
+
if (!result.children) return false;
|
|
4803
4969
|
return result.children.some((c) => c.match(obj));
|
|
4804
4970
|
};
|
|
4805
4971
|
};
|
|
@@ -5113,7 +5279,7 @@ var ProductSearch = class {
|
|
|
5113
5279
|
let resources = this._storage.all(projectKey, "product").map(
|
|
5114
5280
|
(r) => this.transform(r, params.productProjectionParameters?.staged ?? false)
|
|
5115
5281
|
).filter((p) => {
|
|
5116
|
-
if (!params.productProjectionParameters?.staged) {
|
|
5282
|
+
if (!(params.productProjectionParameters?.staged ?? false)) {
|
|
5117
5283
|
return p.published;
|
|
5118
5284
|
}
|
|
5119
5285
|
return true;
|
|
@@ -6110,7 +6276,7 @@ var ProductProjectionSearch = class {
|
|
|
6110
6276
|
}
|
|
6111
6277
|
search(projectKey, params) {
|
|
6112
6278
|
let resources = this._storage.all(projectKey, "product").map((r) => this.transform(r, params.staged ?? false)).filter((p) => {
|
|
6113
|
-
if (!params.staged) {
|
|
6279
|
+
if (!(params.staged ?? false)) {
|
|
6114
6280
|
return p.published;
|
|
6115
6281
|
}
|
|
6116
6282
|
return true;
|
|
@@ -6195,8 +6361,7 @@ var ProductProjectionSearch = class {
|
|
|
6195
6361
|
};
|
|
6196
6362
|
}
|
|
6197
6363
|
getFacets(params, products) {
|
|
6198
|
-
if (!params.facet)
|
|
6199
|
-
return {};
|
|
6364
|
+
if (!params.facet) return {};
|
|
6200
6365
|
const result = {};
|
|
6201
6366
|
const regexp = new RegExp(/ counting products$/);
|
|
6202
6367
|
for (let facet of params.facet) {
|
|
@@ -6375,7 +6540,7 @@ var ProductProjectionRepository = class extends AbstractResourceRepository {
|
|
|
6375
6540
|
}
|
|
6376
6541
|
query(context, params = {}) {
|
|
6377
6542
|
let resources = this._storage.all(context.projectKey, "product").map((r) => this._searchService.transform(r, params.staged ?? false)).filter((p) => {
|
|
6378
|
-
if (!params.staged) {
|
|
6543
|
+
if (!(params.staged ?? false)) {
|
|
6379
6544
|
return p.published;
|
|
6380
6545
|
}
|
|
6381
6546
|
return true;
|
|
@@ -6679,8 +6844,7 @@ var ReviewRepository = class extends AbstractResourceRepository {
|
|
|
6679
6844
|
super("review", storage);
|
|
6680
6845
|
}
|
|
6681
6846
|
create(context, draft) {
|
|
6682
|
-
if (!draft.target)
|
|
6683
|
-
throw new Error("Missing target");
|
|
6847
|
+
if (!draft.target) throw new Error("Missing target");
|
|
6684
6848
|
const resource = {
|
|
6685
6849
|
...getBaseResourceProperties(),
|
|
6686
6850
|
locale: draft.locale,
|
|
@@ -6706,48 +6870,6 @@ var ReviewRepository = class extends AbstractResourceRepository {
|
|
|
6706
6870
|
}
|
|
6707
6871
|
};
|
|
6708
6872
|
|
|
6709
|
-
// src/shippingCalculator.ts
|
|
6710
|
-
var markMatchingShippingRate = (cart, shippingRate) => {
|
|
6711
|
-
const isMatching = shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
|
|
6712
|
-
return {
|
|
6713
|
-
...shippingRate,
|
|
6714
|
-
tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
|
|
6715
|
-
isMatching
|
|
6716
|
-
};
|
|
6717
|
-
};
|
|
6718
|
-
var markMatchingShippingRatePriceTiers = (cart, tiers) => {
|
|
6719
|
-
if (tiers.length === 0) {
|
|
6720
|
-
return [];
|
|
6721
|
-
}
|
|
6722
|
-
if (new Set(tiers.map((tier) => tier.type)).size > 1) {
|
|
6723
|
-
throw new Error("Can't handle multiple types of tiers");
|
|
6724
|
-
}
|
|
6725
|
-
const tierType = tiers[0].type;
|
|
6726
|
-
switch (tierType) {
|
|
6727
|
-
case "CartValue":
|
|
6728
|
-
return markMatchingCartValueTiers(cart, tiers);
|
|
6729
|
-
default:
|
|
6730
|
-
throw new Error(`Unsupported tier type: ${tierType}`);
|
|
6731
|
-
}
|
|
6732
|
-
};
|
|
6733
|
-
var markMatchingCartValueTiers = (cart, tiers) => {
|
|
6734
|
-
const sortedTiers = [...tiers].sort(
|
|
6735
|
-
(a, b) => b.minimumCentAmount - a.minimumCentAmount
|
|
6736
|
-
);
|
|
6737
|
-
const result = {};
|
|
6738
|
-
let hasMatchingTier = false;
|
|
6739
|
-
for (const tier of sortedTiers) {
|
|
6740
|
-
const isMatching = !hasMatchingTier && cart.totalPrice.currencyCode === tier.price.currencyCode && cart.totalPrice.centAmount >= tier.minimumCentAmount;
|
|
6741
|
-
if (isMatching)
|
|
6742
|
-
hasMatchingTier = true;
|
|
6743
|
-
result[tier.minimumCentAmount] = {
|
|
6744
|
-
...tier,
|
|
6745
|
-
isMatching
|
|
6746
|
-
};
|
|
6747
|
-
}
|
|
6748
|
-
return tiers.map((tier) => result[tier.minimumCentAmount]);
|
|
6749
|
-
};
|
|
6750
|
-
|
|
6751
6873
|
// src/repositories/shipping-method/actions.ts
|
|
6752
6874
|
var import_deep_equal3 = __toESM(require("deep-equal"), 1);
|
|
6753
6875
|
|
|
@@ -6891,41 +7013,7 @@ var ShippingMethodRepository = class extends AbstractResourceRepository {
|
|
|
6891
7013
|
if (!cart) {
|
|
6892
7014
|
return void 0;
|
|
6893
7015
|
}
|
|
6894
|
-
|
|
6895
|
-
throw new CommercetoolsError({
|
|
6896
|
-
code: "InvalidOperation",
|
|
6897
|
-
message: `The cart with ID '${cart.id}' does not have a shipping address set.`
|
|
6898
|
-
});
|
|
6899
|
-
}
|
|
6900
|
-
const zones = this._storage.query(context.projectKey, "zone", {
|
|
6901
|
-
where: [`locations(country="${cart.shippingAddress.country}"))`],
|
|
6902
|
-
limit: 100
|
|
6903
|
-
});
|
|
6904
|
-
const zoneIds = zones.results.map((zone) => zone.id);
|
|
6905
|
-
const shippingMethods = this.query(context, {
|
|
6906
|
-
"where": [
|
|
6907
|
-
`zoneRates(zone(id in (:zoneIds)))`,
|
|
6908
|
-
`zoneRates(shippingRates(price(currencyCode="${cart.totalPrice.currencyCode}")))`
|
|
6909
|
-
],
|
|
6910
|
-
"var.zoneIds": zoneIds,
|
|
6911
|
-
"expand": params.expand
|
|
6912
|
-
});
|
|
6913
|
-
const results = shippingMethods.results.map((shippingMethod) => {
|
|
6914
|
-
const rates = shippingMethod.zoneRates.map((zoneRate) => ({
|
|
6915
|
-
zone: zoneRate.zone,
|
|
6916
|
-
// Iterate through the shippingRates and mark the matching ones
|
|
6917
|
-
// then we filter out the non-matching ones
|
|
6918
|
-
shippingRates: zoneRate.shippingRates.map((rate) => markMatchingShippingRate(cart, rate)).filter((rate) => rate.isMatching)
|
|
6919
|
-
})).filter((zoneRate) => zoneRate.shippingRates.length > 0);
|
|
6920
|
-
return {
|
|
6921
|
-
...shippingMethod,
|
|
6922
|
-
zoneRates: rates
|
|
6923
|
-
};
|
|
6924
|
-
}).filter((shippingMethod) => shippingMethod.zoneRates.length > 0);
|
|
6925
|
-
return {
|
|
6926
|
-
...shippingMethods,
|
|
6927
|
-
results
|
|
6928
|
-
};
|
|
7016
|
+
return getShippingMethodsMatchingCart(context, this._storage, cart, params);
|
|
6929
7017
|
}
|
|
6930
7018
|
_transformZoneRateDraft(context, draft) {
|
|
6931
7019
|
return {
|
|
@@ -7365,8 +7453,7 @@ var StoreRepository = class extends AbstractResourceRepository {
|
|
|
7365
7453
|
}
|
|
7366
7454
|
};
|
|
7367
7455
|
var transformChannels = (context, storage, channels) => {
|
|
7368
|
-
if (!channels)
|
|
7369
|
-
return [];
|
|
7456
|
+
if (!channels) return [];
|
|
7370
7457
|
return channels.map(
|
|
7371
7458
|
(ref) => getReferenceFromResourceIdentifier(
|
|
7372
7459
|
ref,
|
|
@@ -7789,8 +7876,7 @@ var AbstractService = class {
|
|
|
7789
7876
|
expand: this._parseParam(request.query.expand)
|
|
7790
7877
|
}
|
|
7791
7878
|
);
|
|
7792
|
-
if (!result)
|
|
7793
|
-
return response.status(404).send();
|
|
7879
|
+
if (!result) return response.status(404).send();
|
|
7794
7880
|
return response.status(200).send(result);
|
|
7795
7881
|
}
|
|
7796
7882
|
deleteWithId(request, response) {
|