@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.js
CHANGED
|
@@ -146,8 +146,7 @@ var OAuth2Store = class {
|
|
|
146
146
|
};
|
|
147
147
|
}
|
|
148
148
|
validateToken(token) {
|
|
149
|
-
if (!this.validate)
|
|
150
|
-
return true;
|
|
149
|
+
if (!this.validate) return true;
|
|
151
150
|
const foundToken = this.tokens.find((t) => t.access_token === token);
|
|
152
151
|
if (foundToken) {
|
|
153
152
|
return true;
|
|
@@ -617,19 +616,16 @@ function toRegExp(str) {
|
|
|
617
616
|
return new RegExp(str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"));
|
|
618
617
|
}
|
|
619
618
|
function normalize(regex) {
|
|
620
|
-
if (typeof regex === "string")
|
|
621
|
-
regex = toRegExp(regex);
|
|
619
|
+
if (typeof regex === "string") regex = toRegExp(regex);
|
|
622
620
|
if (!regex.source.startsWith("^"))
|
|
623
621
|
return new RegExp(`^${regex.source}`, regex.flags);
|
|
624
|
-
else
|
|
625
|
-
return regex;
|
|
622
|
+
else return regex;
|
|
626
623
|
}
|
|
627
624
|
function first(arr, predicate) {
|
|
628
625
|
let i = 0;
|
|
629
626
|
for (const item of arr) {
|
|
630
627
|
const result = predicate(item, i++);
|
|
631
|
-
if (result)
|
|
632
|
-
return { item, result };
|
|
628
|
+
if (result) return { item, result };
|
|
633
629
|
}
|
|
634
630
|
}
|
|
635
631
|
var TokenTypes = class {
|
|
@@ -793,8 +789,7 @@ var Lexer = class {
|
|
|
793
789
|
*/
|
|
794
790
|
peek(position = this._state.position) {
|
|
795
791
|
const read = (i = position) => {
|
|
796
|
-
if (i >= this._state.source.length)
|
|
797
|
-
return EOF(this);
|
|
792
|
+
if (i >= this._state.source.length) return EOF(this);
|
|
798
793
|
const n = this._tokenTypes.peek(this._state.source, i);
|
|
799
794
|
if (!n || !n.result) {
|
|
800
795
|
throw new Error(
|
|
@@ -814,8 +809,7 @@ var Lexer = class {
|
|
|
814
809
|
) : null;
|
|
815
810
|
};
|
|
816
811
|
const t = read();
|
|
817
|
-
if (t)
|
|
818
|
-
return t;
|
|
812
|
+
if (t) return t;
|
|
819
813
|
let unexpected = this._state.source.substring(position, position + 1);
|
|
820
814
|
try {
|
|
821
815
|
this.peek(position + 1);
|
|
@@ -837,8 +831,7 @@ var Lexer = class {
|
|
|
837
831
|
*/
|
|
838
832
|
strpos(i) {
|
|
839
833
|
let lines = this._state.source.substring(0, i).split(/\r?\n/);
|
|
840
|
-
if (!Array.isArray(lines))
|
|
841
|
-
lines = [lines];
|
|
834
|
+
if (!Array.isArray(lines)) lines = [lines];
|
|
842
835
|
const line = lines.length;
|
|
843
836
|
const column = lines[lines.length - 1].length + 1;
|
|
844
837
|
return { line, column };
|
|
@@ -937,8 +930,7 @@ var Parser = class {
|
|
|
937
930
|
* @returns {number} The binding power of the specified token type
|
|
938
931
|
*/
|
|
939
932
|
bp(tokenOrType) {
|
|
940
|
-
if (tokenOrType == null)
|
|
941
|
-
return Number.NEGATIVE_INFINITY;
|
|
933
|
+
if (tokenOrType == null) return Number.NEGATIVE_INFINITY;
|
|
942
934
|
if (tokenOrType && typeof tokenOrType.isEof == "function" && tokenOrType.isEof())
|
|
943
935
|
return Number.NEGATIVE_INFINITY;
|
|
944
936
|
const type = this._type(tokenOrType);
|
|
@@ -983,27 +975,21 @@ var Parser = class {
|
|
|
983
975
|
parse(opts = { terminals: [0] }) {
|
|
984
976
|
const stop = opts.stop = opts.stop || createStop();
|
|
985
977
|
const check = () => {
|
|
986
|
-
if (stop.isStopped())
|
|
987
|
-
return false;
|
|
978
|
+
if (stop.isStopped()) return false;
|
|
988
979
|
const t = this.lexer.peek();
|
|
989
980
|
const bp = this.bp(t);
|
|
990
981
|
return opts.terminals.reduce((canContinue, rbpOrType) => {
|
|
991
|
-
if (!canContinue)
|
|
992
|
-
|
|
993
|
-
if (typeof rbpOrType == "
|
|
994
|
-
return rbpOrType < bp;
|
|
995
|
-
if (typeof rbpOrType == "string")
|
|
996
|
-
return t.type != rbpOrType;
|
|
982
|
+
if (!canContinue) return false;
|
|
983
|
+
if (typeof rbpOrType == "number") return rbpOrType < bp;
|
|
984
|
+
if (typeof rbpOrType == "string") return t.type != rbpOrType;
|
|
997
985
|
}, true);
|
|
998
986
|
};
|
|
999
987
|
const mkinfo = (token) => {
|
|
1000
988
|
const bp = this.bp(token);
|
|
1001
989
|
return { token, bp, stop, ctx: opts.ctx, options: opts };
|
|
1002
990
|
};
|
|
1003
|
-
if (!opts.terminals)
|
|
1004
|
-
|
|
1005
|
-
if (opts.terminals.length == 0)
|
|
1006
|
-
opts.terminals.push(0);
|
|
991
|
+
if (!opts.terminals) opts.terminals = [0];
|
|
992
|
+
if (opts.terminals.length == 0) opts.terminals.push(0);
|
|
1007
993
|
let left = this.nud(mkinfo(this.lexer.next()));
|
|
1008
994
|
while (check()) {
|
|
1009
995
|
const operator = this.lexer.next();
|
|
@@ -1343,8 +1329,7 @@ var generateMatchFunc = (predicate) => {
|
|
|
1343
1329
|
const expr = parser.parse({ terminals: [")"] });
|
|
1344
1330
|
return (obj, vars) => {
|
|
1345
1331
|
const value = resolveValue(obj, left);
|
|
1346
|
-
if (!value)
|
|
1347
|
-
return false;
|
|
1332
|
+
if (!value) return false;
|
|
1348
1333
|
const maxDistance = resolveSymbol(expr[2], vars);
|
|
1349
1334
|
const distance = haversineDistance(
|
|
1350
1335
|
{
|
|
@@ -1431,8 +1416,7 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1431
1416
|
getProject = (projectKey) => this.addProject(projectKey);
|
|
1432
1417
|
// Expand resolves a nested reference and injects the object in the given obj
|
|
1433
1418
|
expand = (projectKey, obj, clause) => {
|
|
1434
|
-
if (!clause)
|
|
1435
|
-
return obj;
|
|
1419
|
+
if (!clause) return obj;
|
|
1436
1420
|
const newObj = cloneObject(obj);
|
|
1437
1421
|
if (Array.isArray(clause)) {
|
|
1438
1422
|
for (const c of clause) {
|
|
@@ -1463,15 +1447,13 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1463
1447
|
this._resolveReference(projectKey, reference, params.rest);
|
|
1464
1448
|
} else if (params.index === "*") {
|
|
1465
1449
|
const reference = obj[params.element];
|
|
1466
|
-
if (reference === void 0 || !Array.isArray(reference))
|
|
1467
|
-
return;
|
|
1450
|
+
if (reference === void 0 || !Array.isArray(reference)) return;
|
|
1468
1451
|
for (const itemRef of reference) {
|
|
1469
1452
|
this._resolveReference(projectKey, itemRef, params.rest);
|
|
1470
1453
|
}
|
|
1471
1454
|
} else {
|
|
1472
1455
|
const reference = obj[params.element][params.index];
|
|
1473
|
-
if (reference === void 0)
|
|
1474
|
-
return;
|
|
1456
|
+
if (reference === void 0) return;
|
|
1475
1457
|
this._resolveReference(projectKey, reference, params.rest);
|
|
1476
1458
|
}
|
|
1477
1459
|
};
|
|
@@ -1682,8 +1664,7 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1682
1664
|
});
|
|
1683
1665
|
}
|
|
1684
1666
|
_resolveReference(projectKey, reference, expand) {
|
|
1685
|
-
if (reference === void 0)
|
|
1686
|
-
return;
|
|
1667
|
+
if (reference === void 0) return;
|
|
1687
1668
|
if (reference.typeId !== void 0 && (reference.id !== void 0 || reference.key !== void 0)) {
|
|
1688
1669
|
if (!reference.obj) {
|
|
1689
1670
|
reference.obj = this.getByResourceIdentifier(projectKey, {
|
|
@@ -1731,8 +1712,7 @@ import deepEqual from "deep-equal";
|
|
|
1731
1712
|
|
|
1732
1713
|
// src/repositories/errors.ts
|
|
1733
1714
|
var checkConcurrentModification = (currentVersion, expectedVersion, identifier) => {
|
|
1734
|
-
if (currentVersion === expectedVersion)
|
|
1735
|
-
return;
|
|
1715
|
+
if (currentVersion === expectedVersion) return;
|
|
1736
1716
|
console.error(
|
|
1737
1717
|
`Object ${identifier} has a different version than expected. Expected: ${expectedVersion} - Actual: ${currentVersion}.`
|
|
1738
1718
|
);
|
|
@@ -1905,10 +1885,10 @@ var ProductTailoringUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
1905
1885
|
};
|
|
1906
1886
|
|
|
1907
1887
|
// src/repositories/helpers.ts
|
|
1888
|
+
import { Decimal } from "decimal.js/decimal";
|
|
1908
1889
|
import { v4 as uuidv44 } from "uuid";
|
|
1909
1890
|
var createAddress = (base, projectKey, storage) => {
|
|
1910
|
-
if (!base)
|
|
1911
|
-
return void 0;
|
|
1891
|
+
if (!base) return void 0;
|
|
1912
1892
|
if (!base?.country) {
|
|
1913
1893
|
throw new Error("Country is required");
|
|
1914
1894
|
}
|
|
@@ -1917,12 +1897,9 @@ var createAddress = (base, projectKey, storage) => {
|
|
|
1917
1897
|
};
|
|
1918
1898
|
};
|
|
1919
1899
|
var createCustomFields = (draft, projectKey, storage) => {
|
|
1920
|
-
if (!draft)
|
|
1921
|
-
|
|
1922
|
-
if (!draft.type)
|
|
1923
|
-
return void 0;
|
|
1924
|
-
if (!draft.type.typeId)
|
|
1925
|
-
return void 0;
|
|
1900
|
+
if (!draft) return void 0;
|
|
1901
|
+
if (!draft.type) return void 0;
|
|
1902
|
+
if (!draft.type.typeId) return void 0;
|
|
1926
1903
|
const typeResource = storage.getByResourceIdentifier(
|
|
1927
1904
|
projectKey,
|
|
1928
1905
|
draft.type
|
|
@@ -1944,6 +1921,18 @@ var createPrice = (draft) => ({
|
|
|
1944
1921
|
id: uuidv44(),
|
|
1945
1922
|
value: createTypedMoney(draft.value)
|
|
1946
1923
|
});
|
|
1924
|
+
var roundDecimal = (decimal, roundingMode) => {
|
|
1925
|
+
switch (roundingMode) {
|
|
1926
|
+
case "HalfEven":
|
|
1927
|
+
return decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_EVEN);
|
|
1928
|
+
case "HalfUp":
|
|
1929
|
+
return decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_UP);
|
|
1930
|
+
case "HalfDown":
|
|
1931
|
+
return decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_DOWN);
|
|
1932
|
+
default:
|
|
1933
|
+
throw new Error(`Unknown rounding mode: ${roundingMode}`);
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1947
1936
|
var createCentPrecisionMoney = (value) => {
|
|
1948
1937
|
let fractionDigits = 2;
|
|
1949
1938
|
switch (value.currencyCode.toUpperCase()) {
|
|
@@ -1993,8 +1982,7 @@ var createTypedMoney = (value) => {
|
|
|
1993
1982
|
return result;
|
|
1994
1983
|
};
|
|
1995
1984
|
var resolveStoreReference = (ref, projectKey, storage) => {
|
|
1996
|
-
if (!ref)
|
|
1997
|
-
return void 0;
|
|
1985
|
+
if (!ref) return void 0;
|
|
1998
1986
|
const resource = storage.getByResourceIdentifier(projectKey, ref);
|
|
1999
1987
|
if (!resource) {
|
|
2000
1988
|
throw new Error("No such store");
|
|
@@ -2062,8 +2050,7 @@ var getRepositoryContext = (request) => ({
|
|
|
2062
2050
|
storeKey: request.params.storeKey
|
|
2063
2051
|
});
|
|
2064
2052
|
var createAssociate = (a, projectKey, storage) => {
|
|
2065
|
-
if (!a)
|
|
2066
|
-
return void 0;
|
|
2053
|
+
if (!a) return void 0;
|
|
2067
2054
|
if (!a.associateRoleAssignments) {
|
|
2068
2055
|
throw new Error("AssociateRoleAssignments is required");
|
|
2069
2056
|
}
|
|
@@ -2369,8 +2356,95 @@ var BusinessUnitUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
2369
2356
|
import { v4 as uuidv46 } from "uuid";
|
|
2370
2357
|
|
|
2371
2358
|
// src/repositories/cart/actions.ts
|
|
2359
|
+
import { Decimal as Decimal2 } from "decimal.js/decimal";
|
|
2372
2360
|
import { v4 as uuidv45 } from "uuid";
|
|
2373
2361
|
|
|
2362
|
+
// src/shipping.ts
|
|
2363
|
+
var markMatchingShippingRate = (cart, shippingRate) => {
|
|
2364
|
+
const isMatching = shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
|
|
2365
|
+
return {
|
|
2366
|
+
...shippingRate,
|
|
2367
|
+
tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
|
|
2368
|
+
isMatching
|
|
2369
|
+
};
|
|
2370
|
+
};
|
|
2371
|
+
var markMatchingShippingRatePriceTiers = (cart, tiers) => {
|
|
2372
|
+
if (tiers.length === 0) {
|
|
2373
|
+
return [];
|
|
2374
|
+
}
|
|
2375
|
+
if (new Set(tiers.map((tier) => tier.type)).size > 1) {
|
|
2376
|
+
throw new Error("Can't handle multiple types of tiers");
|
|
2377
|
+
}
|
|
2378
|
+
const tierType = tiers[0].type;
|
|
2379
|
+
switch (tierType) {
|
|
2380
|
+
case "CartValue":
|
|
2381
|
+
return markMatchingCartValueTiers(cart, tiers);
|
|
2382
|
+
// case 'CartClassification':
|
|
2383
|
+
// return markMatchingCartClassificationTiers(cart, tiers)
|
|
2384
|
+
// case 'CartScore':
|
|
2385
|
+
// return markMatchingCartScoreTiers(cart, tiers)
|
|
2386
|
+
default:
|
|
2387
|
+
throw new Error(`Unsupported tier type: ${tierType}`);
|
|
2388
|
+
}
|
|
2389
|
+
};
|
|
2390
|
+
var markMatchingCartValueTiers = (cart, tiers) => {
|
|
2391
|
+
const sortedTiers = [...tiers].sort(
|
|
2392
|
+
(a, b) => b.minimumCentAmount - a.minimumCentAmount
|
|
2393
|
+
);
|
|
2394
|
+
const result = {};
|
|
2395
|
+
let hasMatchingTier = false;
|
|
2396
|
+
for (const tier of sortedTiers) {
|
|
2397
|
+
const isMatching = !hasMatchingTier && cart.totalPrice.currencyCode === tier.price.currencyCode && cart.totalPrice.centAmount >= tier.minimumCentAmount;
|
|
2398
|
+
if (isMatching) hasMatchingTier = true;
|
|
2399
|
+
result[tier.minimumCentAmount] = {
|
|
2400
|
+
...tier,
|
|
2401
|
+
isMatching
|
|
2402
|
+
};
|
|
2403
|
+
}
|
|
2404
|
+
return tiers.map((tier) => result[tier.minimumCentAmount]);
|
|
2405
|
+
};
|
|
2406
|
+
var getShippingMethodsMatchingCart = (context, storage, cart, params = {}) => {
|
|
2407
|
+
if (!cart.shippingAddress?.country) {
|
|
2408
|
+
throw new CommercetoolsError({
|
|
2409
|
+
code: "InvalidOperation",
|
|
2410
|
+
message: `The cart with ID '${cart.id}' does not have a shipping address set.`
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2413
|
+
const zones = storage.query(context.projectKey, "zone", {
|
|
2414
|
+
where: [`locations(country="${cart.shippingAddress.country}"))`],
|
|
2415
|
+
limit: 100
|
|
2416
|
+
});
|
|
2417
|
+
const zoneIds = zones.results.map((zone) => zone.id);
|
|
2418
|
+
const shippingMethods = storage.query(
|
|
2419
|
+
context.projectKey,
|
|
2420
|
+
"shipping-method",
|
|
2421
|
+
{
|
|
2422
|
+
"where": [
|
|
2423
|
+
`zoneRates(zone(id in (:zoneIds)))`,
|
|
2424
|
+
`zoneRates(shippingRates(price(currencyCode="${cart.totalPrice.currencyCode}")))`
|
|
2425
|
+
],
|
|
2426
|
+
"var.zoneIds": zoneIds,
|
|
2427
|
+
"expand": params.expand
|
|
2428
|
+
}
|
|
2429
|
+
);
|
|
2430
|
+
const results = shippingMethods.results.map((shippingMethod) => {
|
|
2431
|
+
const rates = shippingMethod.zoneRates.map((zoneRate) => ({
|
|
2432
|
+
zone: zoneRate.zone,
|
|
2433
|
+
// Iterate through the shippingRates and mark the matching ones
|
|
2434
|
+
// then we filter out the non-matching ones
|
|
2435
|
+
shippingRates: zoneRate.shippingRates.map((rate) => markMatchingShippingRate(cart, rate)).filter((rate) => rate.isMatching)
|
|
2436
|
+
})).filter((zoneRate) => zoneRate.shippingRates.length > 0);
|
|
2437
|
+
return {
|
|
2438
|
+
...shippingMethod,
|
|
2439
|
+
zoneRates: rates
|
|
2440
|
+
};
|
|
2441
|
+
}).filter((shippingMethod) => shippingMethod.zoneRates.length > 0);
|
|
2442
|
+
return {
|
|
2443
|
+
...shippingMethods,
|
|
2444
|
+
results
|
|
2445
|
+
};
|
|
2446
|
+
};
|
|
2447
|
+
|
|
2374
2448
|
// src/repositories/cart/helpers.ts
|
|
2375
2449
|
var selectPrice = ({
|
|
2376
2450
|
prices,
|
|
@@ -2432,10 +2506,8 @@ var CartUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
2432
2506
|
product.masterData.current.masterVariant,
|
|
2433
2507
|
...product.masterData.current.variants
|
|
2434
2508
|
].find((x) => {
|
|
2435
|
-
if (sku)
|
|
2436
|
-
|
|
2437
|
-
if (variantId)
|
|
2438
|
-
return x.id === variantId;
|
|
2509
|
+
if (sku) return x.sku === sku;
|
|
2510
|
+
if (variantId) return x.id === variantId;
|
|
2439
2511
|
return false;
|
|
2440
2512
|
});
|
|
2441
2513
|
if (!variant) {
|
|
@@ -2741,16 +2813,116 @@ var CartUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
2741
2813
|
}
|
|
2742
2814
|
setShippingMethod(context, resource, { shippingMethod }) {
|
|
2743
2815
|
if (shippingMethod) {
|
|
2744
|
-
|
|
2816
|
+
if (resource.taxMode === "External") {
|
|
2817
|
+
throw new Error("External tax rate is not supported");
|
|
2818
|
+
}
|
|
2819
|
+
const country = resource.shippingAddress?.country;
|
|
2820
|
+
if (!country) {
|
|
2821
|
+
throw new CommercetoolsError({
|
|
2822
|
+
code: "InvalidOperation",
|
|
2823
|
+
message: `The cart with ID '${resource.id}' does not have a shipping address set.`
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
this._storage.getByResourceIdentifier(
|
|
2745
2827
|
context.projectKey,
|
|
2746
2828
|
shippingMethod
|
|
2747
2829
|
);
|
|
2830
|
+
const shippingMethods = getShippingMethodsMatchingCart(
|
|
2831
|
+
context,
|
|
2832
|
+
this._storage,
|
|
2833
|
+
resource,
|
|
2834
|
+
{
|
|
2835
|
+
expand: ["zoneRates[*].zone"]
|
|
2836
|
+
}
|
|
2837
|
+
);
|
|
2838
|
+
const method = shippingMethods.results.find(
|
|
2839
|
+
(candidate) => shippingMethod.id ? candidate.id === shippingMethod.id : candidate.key === shippingMethod.key
|
|
2840
|
+
);
|
|
2841
|
+
if (!method) {
|
|
2842
|
+
throw new CommercetoolsError({
|
|
2843
|
+
code: "ShippingMethodDoesNotMatchCart",
|
|
2844
|
+
message: `The shipping method with ${shippingMethod.id ? `ID '${shippingMethod.id}'` : `key '${shippingMethod.key}'`} is not allowed for the cart with ID '${resource.id}'.`
|
|
2845
|
+
});
|
|
2846
|
+
}
|
|
2847
|
+
const taxCategory = this._storage.getByResourceIdentifier(
|
|
2848
|
+
context.projectKey,
|
|
2849
|
+
method.taxCategory
|
|
2850
|
+
);
|
|
2851
|
+
const taxRate = taxCategory.rates.find(
|
|
2852
|
+
(rate) => rate.country === country
|
|
2853
|
+
);
|
|
2854
|
+
if (!taxRate) {
|
|
2855
|
+
throw new CommercetoolsError({
|
|
2856
|
+
code: "MissingTaxRateForCountry",
|
|
2857
|
+
message: `Tax category '${taxCategory.id}' is missing a tax rate for country '${country}'.`,
|
|
2858
|
+
taxCategoryId: taxCategory.id
|
|
2859
|
+
});
|
|
2860
|
+
}
|
|
2861
|
+
const zoneRate = method.zoneRates.find(
|
|
2862
|
+
(rate) => rate.zone.obj.locations.some((loc) => loc.country === country)
|
|
2863
|
+
);
|
|
2864
|
+
if (!zoneRate) {
|
|
2865
|
+
throw new Error("Zone rate not found");
|
|
2866
|
+
}
|
|
2867
|
+
const shippingRate = zoneRate.shippingRates[0];
|
|
2868
|
+
if (!shippingRate) {
|
|
2869
|
+
throw new Error("Shipping rate not found");
|
|
2870
|
+
}
|
|
2871
|
+
const shippingRateTier = shippingRate.tiers.find(
|
|
2872
|
+
(tier) => tier.isMatching
|
|
2873
|
+
);
|
|
2874
|
+
if (shippingRateTier && shippingRateTier.type !== "CartValue") {
|
|
2875
|
+
throw new Error("Non-CartValue shipping rate tier is not supported");
|
|
2876
|
+
}
|
|
2877
|
+
const shippingPrice = shippingRateTier ? createCentPrecisionMoney(shippingRateTier.price) : shippingRate.price;
|
|
2878
|
+
const totalGross = taxRate.includedInPrice ? shippingPrice : {
|
|
2879
|
+
...shippingPrice,
|
|
2880
|
+
centAmount: roundDecimal(
|
|
2881
|
+
new Decimal2(shippingPrice.centAmount).mul(1 + taxRate.amount),
|
|
2882
|
+
resource.taxRoundingMode
|
|
2883
|
+
).toNumber()
|
|
2884
|
+
};
|
|
2885
|
+
const totalNet = taxRate.includedInPrice ? {
|
|
2886
|
+
...shippingPrice,
|
|
2887
|
+
centAmount: roundDecimal(
|
|
2888
|
+
new Decimal2(shippingPrice.centAmount).div(1 + taxRate.amount),
|
|
2889
|
+
resource.taxRoundingMode
|
|
2890
|
+
).toNumber()
|
|
2891
|
+
} : shippingPrice;
|
|
2892
|
+
const taxPortions = [
|
|
2893
|
+
{
|
|
2894
|
+
name: taxRate.name,
|
|
2895
|
+
rate: taxRate.amount,
|
|
2896
|
+
amount: {
|
|
2897
|
+
...shippingPrice,
|
|
2898
|
+
centAmount: totalGross.centAmount - totalNet.centAmount
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
];
|
|
2902
|
+
const totalTax = {
|
|
2903
|
+
...shippingPrice,
|
|
2904
|
+
centAmount: taxPortions.reduce(
|
|
2905
|
+
(acc, portion) => acc + portion.amount.centAmount,
|
|
2906
|
+
0
|
|
2907
|
+
)
|
|
2908
|
+
};
|
|
2909
|
+
const taxedPrice = {
|
|
2910
|
+
totalNet,
|
|
2911
|
+
totalGross,
|
|
2912
|
+
taxPortions,
|
|
2913
|
+
totalTax
|
|
2914
|
+
};
|
|
2748
2915
|
resource.shippingInfo = {
|
|
2749
2916
|
shippingMethod: {
|
|
2750
2917
|
typeId: "shipping-method",
|
|
2751
2918
|
id: method.id
|
|
2752
2919
|
},
|
|
2753
|
-
shippingMethodName: method.name
|
|
2920
|
+
shippingMethodName: method.name,
|
|
2921
|
+
price: shippingPrice,
|
|
2922
|
+
shippingRate,
|
|
2923
|
+
taxedPrice,
|
|
2924
|
+
taxRate,
|
|
2925
|
+
taxCategory: method.taxCategory
|
|
2754
2926
|
};
|
|
2755
2927
|
} else {
|
|
2756
2928
|
resource.shippingInfo = void 0;
|
|
@@ -2849,10 +3021,8 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2849
3021
|
product.masterData.current.masterVariant,
|
|
2850
3022
|
...product.masterData.current.variants
|
|
2851
3023
|
].find((x) => {
|
|
2852
|
-
if (sku)
|
|
2853
|
-
|
|
2854
|
-
if (variantId)
|
|
2855
|
-
return x.id === variantId;
|
|
3024
|
+
if (sku) return x.sku === sku;
|
|
3025
|
+
if (variantId) return x.id === variantId;
|
|
2856
3026
|
return false;
|
|
2857
3027
|
});
|
|
2858
3028
|
if (!variant) {
|
|
@@ -4110,8 +4280,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4110
4280
|
assert2(resource.shippingInfo, "shippingInfo is not defined");
|
|
4111
4281
|
if (Array.isArray(resource.shippingInfo.deliveries)) {
|
|
4112
4282
|
resource.shippingInfo.deliveries.map((delivery) => {
|
|
4113
|
-
if (delivery.id !== deliveryId)
|
|
4114
|
-
throw "No matching delivery id found";
|
|
4283
|
+
if (delivery.id !== deliveryId) throw "No matching delivery id found";
|
|
4115
4284
|
if (delivery.custom) {
|
|
4116
4285
|
const update = delivery.custom.fields;
|
|
4117
4286
|
update[name] = value;
|
|
@@ -4138,8 +4307,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4138
4307
|
);
|
|
4139
4308
|
}
|
|
4140
4309
|
setStore(context, resource, { store }) {
|
|
4141
|
-
if (!store)
|
|
4142
|
-
return;
|
|
4310
|
+
if (!store) return;
|
|
4143
4311
|
const resolvedType = this._storage.getByResourceIdentifier(
|
|
4144
4312
|
context.projectKey,
|
|
4145
4313
|
store
|
|
@@ -4170,8 +4338,7 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
4170
4338
|
};
|
|
4171
4339
|
}
|
|
4172
4340
|
updateSyncInfo(context, resource, { channel, externalId, syncedAt }) {
|
|
4173
|
-
if (!channel)
|
|
4174
|
-
return;
|
|
4341
|
+
if (!channel) return;
|
|
4175
4342
|
const resolvedType = this._storage.getByResourceIdentifier(
|
|
4176
4343
|
context.projectKey,
|
|
4177
4344
|
channel
|
|
@@ -4761,8 +4928,7 @@ var generateMatchFunc2 = (filter) => {
|
|
|
4761
4928
|
throw new Error(`Syntax error while parsing '${filter}'.`);
|
|
4762
4929
|
}
|
|
4763
4930
|
return (obj) => {
|
|
4764
|
-
if (!result.children)
|
|
4765
|
-
return false;
|
|
4931
|
+
if (!result.children) return false;
|
|
4766
4932
|
return result.children.some((c) => c.match(obj));
|
|
4767
4933
|
};
|
|
4768
4934
|
};
|
|
@@ -5076,7 +5242,7 @@ var ProductSearch = class {
|
|
|
5076
5242
|
let resources = this._storage.all(projectKey, "product").map(
|
|
5077
5243
|
(r) => this.transform(r, params.productProjectionParameters?.staged ?? false)
|
|
5078
5244
|
).filter((p) => {
|
|
5079
|
-
if (!params.productProjectionParameters?.staged) {
|
|
5245
|
+
if (!(params.productProjectionParameters?.staged ?? false)) {
|
|
5080
5246
|
return p.published;
|
|
5081
5247
|
}
|
|
5082
5248
|
return true;
|
|
@@ -6073,7 +6239,7 @@ var ProductProjectionSearch = class {
|
|
|
6073
6239
|
}
|
|
6074
6240
|
search(projectKey, params) {
|
|
6075
6241
|
let resources = this._storage.all(projectKey, "product").map((r) => this.transform(r, params.staged ?? false)).filter((p) => {
|
|
6076
|
-
if (!params.staged) {
|
|
6242
|
+
if (!(params.staged ?? false)) {
|
|
6077
6243
|
return p.published;
|
|
6078
6244
|
}
|
|
6079
6245
|
return true;
|
|
@@ -6158,8 +6324,7 @@ var ProductProjectionSearch = class {
|
|
|
6158
6324
|
};
|
|
6159
6325
|
}
|
|
6160
6326
|
getFacets(params, products) {
|
|
6161
|
-
if (!params.facet)
|
|
6162
|
-
return {};
|
|
6327
|
+
if (!params.facet) return {};
|
|
6163
6328
|
const result = {};
|
|
6164
6329
|
const regexp = new RegExp(/ counting products$/);
|
|
6165
6330
|
for (let facet of params.facet) {
|
|
@@ -6338,7 +6503,7 @@ var ProductProjectionRepository = class extends AbstractResourceRepository {
|
|
|
6338
6503
|
}
|
|
6339
6504
|
query(context, params = {}) {
|
|
6340
6505
|
let resources = this._storage.all(context.projectKey, "product").map((r) => this._searchService.transform(r, params.staged ?? false)).filter((p) => {
|
|
6341
|
-
if (!params.staged) {
|
|
6506
|
+
if (!(params.staged ?? false)) {
|
|
6342
6507
|
return p.published;
|
|
6343
6508
|
}
|
|
6344
6509
|
return true;
|
|
@@ -6642,8 +6807,7 @@ var ReviewRepository = class extends AbstractResourceRepository {
|
|
|
6642
6807
|
super("review", storage);
|
|
6643
6808
|
}
|
|
6644
6809
|
create(context, draft) {
|
|
6645
|
-
if (!draft.target)
|
|
6646
|
-
throw new Error("Missing target");
|
|
6810
|
+
if (!draft.target) throw new Error("Missing target");
|
|
6647
6811
|
const resource = {
|
|
6648
6812
|
...getBaseResourceProperties(),
|
|
6649
6813
|
locale: draft.locale,
|
|
@@ -6669,48 +6833,6 @@ var ReviewRepository = class extends AbstractResourceRepository {
|
|
|
6669
6833
|
}
|
|
6670
6834
|
};
|
|
6671
6835
|
|
|
6672
|
-
// src/shippingCalculator.ts
|
|
6673
|
-
var markMatchingShippingRate = (cart, shippingRate) => {
|
|
6674
|
-
const isMatching = shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
|
|
6675
|
-
return {
|
|
6676
|
-
...shippingRate,
|
|
6677
|
-
tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
|
|
6678
|
-
isMatching
|
|
6679
|
-
};
|
|
6680
|
-
};
|
|
6681
|
-
var markMatchingShippingRatePriceTiers = (cart, tiers) => {
|
|
6682
|
-
if (tiers.length === 0) {
|
|
6683
|
-
return [];
|
|
6684
|
-
}
|
|
6685
|
-
if (new Set(tiers.map((tier) => tier.type)).size > 1) {
|
|
6686
|
-
throw new Error("Can't handle multiple types of tiers");
|
|
6687
|
-
}
|
|
6688
|
-
const tierType = tiers[0].type;
|
|
6689
|
-
switch (tierType) {
|
|
6690
|
-
case "CartValue":
|
|
6691
|
-
return markMatchingCartValueTiers(cart, tiers);
|
|
6692
|
-
default:
|
|
6693
|
-
throw new Error(`Unsupported tier type: ${tierType}`);
|
|
6694
|
-
}
|
|
6695
|
-
};
|
|
6696
|
-
var markMatchingCartValueTiers = (cart, tiers) => {
|
|
6697
|
-
const sortedTiers = [...tiers].sort(
|
|
6698
|
-
(a, b) => b.minimumCentAmount - a.minimumCentAmount
|
|
6699
|
-
);
|
|
6700
|
-
const result = {};
|
|
6701
|
-
let hasMatchingTier = false;
|
|
6702
|
-
for (const tier of sortedTiers) {
|
|
6703
|
-
const isMatching = !hasMatchingTier && cart.totalPrice.currencyCode === tier.price.currencyCode && cart.totalPrice.centAmount >= tier.minimumCentAmount;
|
|
6704
|
-
if (isMatching)
|
|
6705
|
-
hasMatchingTier = true;
|
|
6706
|
-
result[tier.minimumCentAmount] = {
|
|
6707
|
-
...tier,
|
|
6708
|
-
isMatching
|
|
6709
|
-
};
|
|
6710
|
-
}
|
|
6711
|
-
return tiers.map((tier) => result[tier.minimumCentAmount]);
|
|
6712
|
-
};
|
|
6713
|
-
|
|
6714
6836
|
// src/repositories/shipping-method/actions.ts
|
|
6715
6837
|
import deepEqual3 from "deep-equal";
|
|
6716
6838
|
|
|
@@ -6854,41 +6976,7 @@ var ShippingMethodRepository = class extends AbstractResourceRepository {
|
|
|
6854
6976
|
if (!cart) {
|
|
6855
6977
|
return void 0;
|
|
6856
6978
|
}
|
|
6857
|
-
|
|
6858
|
-
throw new CommercetoolsError({
|
|
6859
|
-
code: "InvalidOperation",
|
|
6860
|
-
message: `The cart with ID '${cart.id}' does not have a shipping address set.`
|
|
6861
|
-
});
|
|
6862
|
-
}
|
|
6863
|
-
const zones = this._storage.query(context.projectKey, "zone", {
|
|
6864
|
-
where: [`locations(country="${cart.shippingAddress.country}"))`],
|
|
6865
|
-
limit: 100
|
|
6866
|
-
});
|
|
6867
|
-
const zoneIds = zones.results.map((zone) => zone.id);
|
|
6868
|
-
const shippingMethods = this.query(context, {
|
|
6869
|
-
"where": [
|
|
6870
|
-
`zoneRates(zone(id in (:zoneIds)))`,
|
|
6871
|
-
`zoneRates(shippingRates(price(currencyCode="${cart.totalPrice.currencyCode}")))`
|
|
6872
|
-
],
|
|
6873
|
-
"var.zoneIds": zoneIds,
|
|
6874
|
-
"expand": params.expand
|
|
6875
|
-
});
|
|
6876
|
-
const results = shippingMethods.results.map((shippingMethod) => {
|
|
6877
|
-
const rates = shippingMethod.zoneRates.map((zoneRate) => ({
|
|
6878
|
-
zone: zoneRate.zone,
|
|
6879
|
-
// Iterate through the shippingRates and mark the matching ones
|
|
6880
|
-
// then we filter out the non-matching ones
|
|
6881
|
-
shippingRates: zoneRate.shippingRates.map((rate) => markMatchingShippingRate(cart, rate)).filter((rate) => rate.isMatching)
|
|
6882
|
-
})).filter((zoneRate) => zoneRate.shippingRates.length > 0);
|
|
6883
|
-
return {
|
|
6884
|
-
...shippingMethod,
|
|
6885
|
-
zoneRates: rates
|
|
6886
|
-
};
|
|
6887
|
-
}).filter((shippingMethod) => shippingMethod.zoneRates.length > 0);
|
|
6888
|
-
return {
|
|
6889
|
-
...shippingMethods,
|
|
6890
|
-
results
|
|
6891
|
-
};
|
|
6979
|
+
return getShippingMethodsMatchingCart(context, this._storage, cart, params);
|
|
6892
6980
|
}
|
|
6893
6981
|
_transformZoneRateDraft(context, draft) {
|
|
6894
6982
|
return {
|
|
@@ -7328,8 +7416,7 @@ var StoreRepository = class extends AbstractResourceRepository {
|
|
|
7328
7416
|
}
|
|
7329
7417
|
};
|
|
7330
7418
|
var transformChannels = (context, storage, channels) => {
|
|
7331
|
-
if (!channels)
|
|
7332
|
-
return [];
|
|
7419
|
+
if (!channels) return [];
|
|
7333
7420
|
return channels.map(
|
|
7334
7421
|
(ref) => getReferenceFromResourceIdentifier(
|
|
7335
7422
|
ref,
|
|
@@ -7752,8 +7839,7 @@ var AbstractService = class {
|
|
|
7752
7839
|
expand: this._parseParam(request.query.expand)
|
|
7753
7840
|
}
|
|
7754
7841
|
);
|
|
7755
|
-
if (!result)
|
|
7756
|
-
return response.status(404).send();
|
|
7842
|
+
if (!result) return response.status(404).send();
|
|
7757
7843
|
return response.status(200).send(result);
|
|
7758
7844
|
}
|
|
7759
7845
|
deleteWithId(request, response) {
|