@labdigital/commercetools-mock 2.34.3 → 2.36.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 +305 -170
- 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 +301 -166
- 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/customer/index.ts +43 -9
- 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/services/customer.test.ts +45 -5
- package/src/services/index.ts +2 -0
- package/src/services/my-business-unit.ts +28 -0
- package/src/services/my-customer.test.ts +2 -0
- package/src/{shippingCalculator.test.ts → shipping.test.ts} +1 -1
- package/src/shipping.ts +147 -0
- package/src/types.ts +2 -1
- package/src/shippingCalculator.ts +0 -74
package/src/shipping.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Cart,
|
|
3
|
+
CartValueTier,
|
|
4
|
+
InvalidOperationError,
|
|
5
|
+
ShippingRate,
|
|
6
|
+
ShippingRatePriceTier,
|
|
7
|
+
} from "@commercetools/platform-sdk";
|
|
8
|
+
import { CommercetoolsError } from "./exceptions";
|
|
9
|
+
import { GetParams, RepositoryContext } from "./repositories/abstract";
|
|
10
|
+
import { AbstractStorage } from "./storage/abstract";
|
|
11
|
+
|
|
12
|
+
export const markMatchingShippingRate = (
|
|
13
|
+
cart: Cart,
|
|
14
|
+
shippingRate: ShippingRate,
|
|
15
|
+
): ShippingRate => {
|
|
16
|
+
const isMatching =
|
|
17
|
+
shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
|
|
18
|
+
return {
|
|
19
|
+
...shippingRate,
|
|
20
|
+
tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
|
|
21
|
+
isMatching: isMatching,
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const markMatchingShippingRatePriceTiers = (
|
|
26
|
+
cart: Cart,
|
|
27
|
+
tiers: ShippingRatePriceTier[],
|
|
28
|
+
): ShippingRatePriceTier[] => {
|
|
29
|
+
if (tiers.length === 0) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (new Set(tiers.map((tier) => tier.type)).size > 1) {
|
|
34
|
+
throw new Error("Can't handle multiple types of tiers");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const tierType = tiers[0].type;
|
|
38
|
+
switch (tierType) {
|
|
39
|
+
case "CartValue":
|
|
40
|
+
return markMatchingCartValueTiers(cart, tiers as CartValueTier[]);
|
|
41
|
+
// case 'CartClassification':
|
|
42
|
+
// return markMatchingCartClassificationTiers(cart, tiers)
|
|
43
|
+
// case 'CartScore':
|
|
44
|
+
// return markMatchingCartScoreTiers(cart, tiers)
|
|
45
|
+
default:
|
|
46
|
+
throw new Error(`Unsupported tier type: ${tierType}`);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const markMatchingCartValueTiers = (
|
|
51
|
+
cart: Cart,
|
|
52
|
+
tiers: readonly CartValueTier[],
|
|
53
|
+
): ShippingRatePriceTier[] => {
|
|
54
|
+
// Sort tiers from high to low since we only want to match the highest tier
|
|
55
|
+
const sortedTiers = [...tiers].sort(
|
|
56
|
+
(a, b) => b.minimumCentAmount - a.minimumCentAmount,
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// Find the first tier that matches the cart and set the flag. We push
|
|
60
|
+
// the results into a map so that we can output the tiers in the same order as
|
|
61
|
+
// we received them.
|
|
62
|
+
const result: Record<number, ShippingRatePriceTier> = {};
|
|
63
|
+
let hasMatchingTier = false;
|
|
64
|
+
for (const tier of sortedTiers) {
|
|
65
|
+
const isMatching =
|
|
66
|
+
!hasMatchingTier &&
|
|
67
|
+
cart.totalPrice.currencyCode === tier.price.currencyCode &&
|
|
68
|
+
cart.totalPrice.centAmount >= tier.minimumCentAmount;
|
|
69
|
+
|
|
70
|
+
if (isMatching) hasMatchingTier = true;
|
|
71
|
+
result[tier.minimumCentAmount] = {
|
|
72
|
+
...tier,
|
|
73
|
+
isMatching: isMatching,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return tiers.map((tier) => result[tier.minimumCentAmount]);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/*
|
|
81
|
+
* Retrieves all the ShippingMethods that can ship to the shipping address of
|
|
82
|
+
* the given Cart. Each ShippingMethod contains exactly one ShippingRate with
|
|
83
|
+
* the flag isMatching set to true. This ShippingRate is used when the
|
|
84
|
+
* ShippingMethod is added to the Cart.
|
|
85
|
+
*/
|
|
86
|
+
export const getShippingMethodsMatchingCart = (
|
|
87
|
+
context: RepositoryContext,
|
|
88
|
+
storage: AbstractStorage,
|
|
89
|
+
cart: Cart,
|
|
90
|
+
params: GetParams = {},
|
|
91
|
+
) => {
|
|
92
|
+
if (!cart.shippingAddress?.country) {
|
|
93
|
+
throw new CommercetoolsError<InvalidOperationError>({
|
|
94
|
+
code: "InvalidOperation",
|
|
95
|
+
message: `The cart with ID '${cart.id}' does not have a shipping address set.`,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Get all shipping methods that have a zone that matches the shipping address
|
|
100
|
+
const zones = storage.query<"zone">(context.projectKey, "zone", {
|
|
101
|
+
where: [`locations(country="${cart.shippingAddress.country}"))`],
|
|
102
|
+
limit: 100,
|
|
103
|
+
});
|
|
104
|
+
const zoneIds = zones.results.map((zone) => zone.id);
|
|
105
|
+
const shippingMethods = storage.query<"shipping-method">(
|
|
106
|
+
context.projectKey,
|
|
107
|
+
"shipping-method",
|
|
108
|
+
{
|
|
109
|
+
"where": [
|
|
110
|
+
`zoneRates(zone(id in (:zoneIds)))`,
|
|
111
|
+
`zoneRates(shippingRates(price(currencyCode="${cart.totalPrice.currencyCode}")))`,
|
|
112
|
+
],
|
|
113
|
+
"var.zoneIds": zoneIds,
|
|
114
|
+
"expand": params.expand,
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Make sure that each shipping method has exactly one shipping rate and
|
|
119
|
+
// that the shipping rate is marked as matching
|
|
120
|
+
const results = shippingMethods.results
|
|
121
|
+
.map((shippingMethod) => {
|
|
122
|
+
// Iterate through the zoneRates, process the shipping rates and filter
|
|
123
|
+
// out all zoneRates which have no matching shipping rates left
|
|
124
|
+
const rates = shippingMethod.zoneRates
|
|
125
|
+
.map((zoneRate) => ({
|
|
126
|
+
zone: zoneRate.zone,
|
|
127
|
+
|
|
128
|
+
// Iterate through the shippingRates and mark the matching ones
|
|
129
|
+
// then we filter out the non-matching ones
|
|
130
|
+
shippingRates: zoneRate.shippingRates
|
|
131
|
+
.map((rate) => markMatchingShippingRate(cart, rate))
|
|
132
|
+
.filter((rate) => rate.isMatching),
|
|
133
|
+
}))
|
|
134
|
+
.filter((zoneRate) => zoneRate.shippingRates.length > 0);
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
...shippingMethod,
|
|
138
|
+
zoneRates: rates,
|
|
139
|
+
};
|
|
140
|
+
})
|
|
141
|
+
.filter((shippingMethod) => shippingMethod.zoneRates.length > 0);
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
...shippingMethods,
|
|
145
|
+
results: results,
|
|
146
|
+
};
|
|
147
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Cart,
|
|
3
|
-
CartValueTier,
|
|
4
|
-
ShippingRate,
|
|
5
|
-
ShippingRatePriceTier,
|
|
6
|
-
} from "@commercetools/platform-sdk";
|
|
7
|
-
|
|
8
|
-
export const markMatchingShippingRate = (
|
|
9
|
-
cart: Cart,
|
|
10
|
-
shippingRate: ShippingRate,
|
|
11
|
-
): ShippingRate => {
|
|
12
|
-
const isMatching =
|
|
13
|
-
shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
|
|
14
|
-
return {
|
|
15
|
-
...shippingRate,
|
|
16
|
-
tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
|
|
17
|
-
isMatching: isMatching,
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export const markMatchingShippingRatePriceTiers = (
|
|
22
|
-
cart: Cart,
|
|
23
|
-
tiers: ShippingRatePriceTier[],
|
|
24
|
-
): ShippingRatePriceTier[] => {
|
|
25
|
-
if (tiers.length === 0) {
|
|
26
|
-
return [];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (new Set(tiers.map((tier) => tier.type)).size > 1) {
|
|
30
|
-
throw new Error("Can't handle multiple types of tiers");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const tierType = tiers[0].type;
|
|
34
|
-
switch (tierType) {
|
|
35
|
-
case "CartValue":
|
|
36
|
-
return markMatchingCartValueTiers(cart, tiers as CartValueTier[]);
|
|
37
|
-
// case 'CartClassification':
|
|
38
|
-
// return markMatchingCartClassificationTiers(cart, tiers)
|
|
39
|
-
// case 'CartScore':
|
|
40
|
-
// return markMatchingCartScoreTiers(cart, tiers)
|
|
41
|
-
default:
|
|
42
|
-
throw new Error(`Unsupported tier type: ${tierType}`);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const markMatchingCartValueTiers = (
|
|
47
|
-
cart: Cart,
|
|
48
|
-
tiers: readonly CartValueTier[],
|
|
49
|
-
): ShippingRatePriceTier[] => {
|
|
50
|
-
// Sort tiers from high to low since we only want to match the highest tier
|
|
51
|
-
const sortedTiers = [...tiers].sort(
|
|
52
|
-
(a, b) => b.minimumCentAmount - a.minimumCentAmount,
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
// Find the first tier that matches the cart and set the flag. We push
|
|
56
|
-
// the results into a map so that we can output the tiers in the same order as
|
|
57
|
-
// we received them.
|
|
58
|
-
const result: Record<number, ShippingRatePriceTier> = {};
|
|
59
|
-
let hasMatchingTier = false;
|
|
60
|
-
for (const tier of sortedTiers) {
|
|
61
|
-
const isMatching =
|
|
62
|
-
!hasMatchingTier &&
|
|
63
|
-
cart.totalPrice.currencyCode === tier.price.currencyCode &&
|
|
64
|
-
cart.totalPrice.centAmount >= tier.minimumCentAmount;
|
|
65
|
-
|
|
66
|
-
if (isMatching) hasMatchingTier = true;
|
|
67
|
-
result[tier.minimumCentAmount] = {
|
|
68
|
-
...tier,
|
|
69
|
-
isMatching: isMatching,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return tiers.map((tier) => result[tier.minimumCentAmount]);
|
|
74
|
-
};
|