@labdigital/commercetools-mock 2.45.1 → 2.47.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 +614 -250
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +788 -59
- package/dist/index.d.ts +788 -59
- package/dist/index.js +602 -238
- package/dist/index.js.map +1 -1
- package/package.json +41 -48
- package/src/ctMock.ts +11 -13
- package/src/index.test.ts +5 -5
- package/src/lib/predicateParser.test.ts +91 -60
- package/src/lib/predicateParser.ts +38 -42
- package/src/lib/productSearchFilter.test.ts +18 -0
- package/src/lib/productSearchFilter.ts +7 -0
- package/src/lib/projectionSearchFilter.test.ts +17 -17
- package/src/lib/projectionSearchFilter.ts +2 -3
- package/src/oauth/server.test.ts +1 -1
- package/src/oauth/server.ts +11 -11
- package/src/priceSelector.ts +1 -1
- package/src/product-projection-search.ts +18 -19
- package/src/product-search.ts +48 -8
- package/src/repositories/business-unit.ts +17 -16
- package/src/repositories/cart/actions.ts +32 -32
- package/src/repositories/cart/helpers.ts +1 -1
- package/src/repositories/cart/index.ts +25 -8
- package/src/repositories/cart-discount/actions.ts +1 -4
- package/src/repositories/category/actions.ts +2 -6
- package/src/repositories/custom-object.ts +20 -21
- package/src/repositories/customer/actions.ts +4 -4
- package/src/repositories/errors.ts +1 -1
- package/src/repositories/extension.ts +2 -1
- package/src/repositories/helpers.ts +27 -27
- package/src/repositories/index.ts +17 -17
- package/src/repositories/my-customer.ts +1 -1
- package/src/repositories/my-order.ts +2 -2
- package/src/repositories/order/index.ts +1 -1
- package/src/repositories/product/actions.ts +1 -1
- package/src/repositories/quote/actions.ts +83 -0
- package/src/repositories/quote/index.ts +54 -0
- package/src/repositories/quote-request/actions.ts +84 -0
- package/src/repositories/quote-request/index.test.ts +167 -0
- package/src/repositories/quote-request/index.ts +67 -0
- package/src/repositories/quote-staged/actions.ts +84 -0
- package/src/repositories/quote-staged/index.ts +47 -0
- package/src/repositories/review.ts +4 -4
- package/src/repositories/shipping-method/actions.ts +17 -17
- package/src/repositories/shipping-method/index.ts +6 -6
- package/src/repositories/shopping-list/actions.ts +1 -1
- package/src/repositories/shopping-list/index.ts +9 -1
- package/src/repositories/subscription.ts +2 -4
- package/src/server.ts +3 -2
- package/src/services/abstract.ts +7 -7
- package/src/services/as-associate-order.test.ts +1 -1
- package/src/services/cart-discount.test.ts +1 -1
- package/src/services/cart.test.ts +40 -15
- package/src/services/category.test.ts +1 -1
- package/src/services/customer.test.ts +16 -55
- package/src/services/customer.ts +1 -1
- package/src/services/index.ts +20 -14
- package/src/services/inventory-entry.test.ts +5 -5
- package/src/services/my-cart.test.ts +2 -2
- package/src/services/my-customer.test.ts +2 -2
- package/src/services/order.test.ts +8 -8
- package/src/services/product-projection.test.ts +5 -5
- package/src/services/product-projection.ts +12 -14
- package/src/services/product.test.ts +155 -71
- package/src/services/quote-request.test.ts +59 -0
- package/src/services/quote-request.ts +16 -0
- package/src/services/quote-staged.ts +16 -0
- package/src/services/quote.ts +16 -0
- package/src/services/standalone-price.test.ts +4 -4
- package/src/services/state.test.ts +1 -1
- package/src/services/store.test.ts +2 -2
- package/src/services/tax-category.test.ts +1 -1
- package/src/shipping.ts +3 -3
- package/src/storage/in-memory.ts +55 -63
- package/src/testing/customer.ts +40 -0
- package/src/types.ts +51 -31
- package/src/repositories/quote-request.ts +0 -17
- package/src/repositories/quote.ts +0 -14
- package/src/repositories/staged-quote.ts +0 -17
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
InvalidJsonInputError,
|
|
3
|
+
QuoteRequest,
|
|
4
|
+
QuoteRequestSetCustomFieldAction,
|
|
5
|
+
QuoteRequestSetCustomTypeAction,
|
|
6
|
+
QuoteRequestTransitionStateAction,
|
|
7
|
+
QuoteRequestUpdateAction,
|
|
8
|
+
StateReference,
|
|
9
|
+
} from "@commercetools/platform-sdk";
|
|
10
|
+
import { CommercetoolsError } from "~src/exceptions";
|
|
11
|
+
import type { Writable } from "~src/types";
|
|
12
|
+
import type { RepositoryContext, UpdateHandlerInterface } from "../abstract";
|
|
13
|
+
import { AbstractUpdateHandler } from "../abstract";
|
|
14
|
+
import { getReferenceFromResourceIdentifier } from "../helpers";
|
|
15
|
+
|
|
16
|
+
export class QuoteRequestUpdateHandler
|
|
17
|
+
extends AbstractUpdateHandler
|
|
18
|
+
implements
|
|
19
|
+
Partial<UpdateHandlerInterface<QuoteRequest, QuoteRequestUpdateAction>>
|
|
20
|
+
{
|
|
21
|
+
setCustomField(
|
|
22
|
+
context: RepositoryContext,
|
|
23
|
+
resource: QuoteRequest,
|
|
24
|
+
{ name, value }: QuoteRequestSetCustomFieldAction,
|
|
25
|
+
) {
|
|
26
|
+
if (!resource.custom) {
|
|
27
|
+
throw new Error("Resource has no custom field");
|
|
28
|
+
}
|
|
29
|
+
resource.custom.fields[name] = value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
setCustomType(
|
|
33
|
+
context: RepositoryContext,
|
|
34
|
+
resource: Writable<QuoteRequest>,
|
|
35
|
+
{ type, fields }: QuoteRequestSetCustomTypeAction,
|
|
36
|
+
) {
|
|
37
|
+
if (!type) {
|
|
38
|
+
resource.custom = undefined;
|
|
39
|
+
} else {
|
|
40
|
+
const resolvedType = this._storage.getByResourceIdentifier(
|
|
41
|
+
context.projectKey,
|
|
42
|
+
type,
|
|
43
|
+
);
|
|
44
|
+
if (!resolvedType) {
|
|
45
|
+
throw new Error(`Type ${type} not found`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
resource.custom = {
|
|
49
|
+
type: {
|
|
50
|
+
typeId: "type",
|
|
51
|
+
id: resolvedType.id,
|
|
52
|
+
},
|
|
53
|
+
fields: fields || {},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
transitionState(
|
|
59
|
+
context: RepositoryContext,
|
|
60
|
+
resource: Writable<QuoteRequest>,
|
|
61
|
+
{ state, force }: QuoteRequestTransitionStateAction,
|
|
62
|
+
) {
|
|
63
|
+
let stateReference: StateReference | undefined = undefined;
|
|
64
|
+
if (state) {
|
|
65
|
+
stateReference = getReferenceFromResourceIdentifier<StateReference>(
|
|
66
|
+
state,
|
|
67
|
+
context.projectKey,
|
|
68
|
+
this._storage,
|
|
69
|
+
);
|
|
70
|
+
resource.state = stateReference;
|
|
71
|
+
} else {
|
|
72
|
+
throw new CommercetoolsError<InvalidJsonInputError>(
|
|
73
|
+
{
|
|
74
|
+
code: "InvalidJsonInput",
|
|
75
|
+
message: "Request body does not contain valid JSON.",
|
|
76
|
+
detailedErrorMessage: "actions -> state: Missing required value",
|
|
77
|
+
},
|
|
78
|
+
400,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return resource;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { Cart, LineItem } from "@commercetools/platform-sdk";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import type { Config } from "~src/config";
|
|
4
|
+
import { InMemoryStorage } from "~src/storage";
|
|
5
|
+
import { QuoteRequestRepository } from ".";
|
|
6
|
+
|
|
7
|
+
describe("QuoteRequest repository", () => {
|
|
8
|
+
const storage = new InMemoryStorage();
|
|
9
|
+
const config: Config = {
|
|
10
|
+
storage,
|
|
11
|
+
strict: false,
|
|
12
|
+
};
|
|
13
|
+
const repository = new QuoteRequestRepository(config);
|
|
14
|
+
|
|
15
|
+
test("create from cart", async () => {
|
|
16
|
+
const cart: Cart = {
|
|
17
|
+
id: "b3875a58-4ab2-4aaa-b399-184ce7561c27",
|
|
18
|
+
version: 1,
|
|
19
|
+
createdAt: "2021-09-02T12:23:30.036Z",
|
|
20
|
+
lastModifiedAt: "2021-09-02T12:23:30.546Z",
|
|
21
|
+
discountCodes: [],
|
|
22
|
+
directDiscounts: [],
|
|
23
|
+
inventoryMode: "None",
|
|
24
|
+
itemShippingAddresses: [],
|
|
25
|
+
lineItems: [
|
|
26
|
+
{
|
|
27
|
+
id: "15fc56ba-a74e-4cf8-b4b0-bada5c101541",
|
|
28
|
+
productId: "PRODUCTID",
|
|
29
|
+
variantId: 1,
|
|
30
|
+
quantity: 1,
|
|
31
|
+
} as unknown as LineItem,
|
|
32
|
+
],
|
|
33
|
+
customLineItems: [],
|
|
34
|
+
totalPrice: {
|
|
35
|
+
type: "centPrecision",
|
|
36
|
+
currencyCode: "EUR",
|
|
37
|
+
centAmount: 10000,
|
|
38
|
+
fractionDigits: 2,
|
|
39
|
+
},
|
|
40
|
+
cartState: "Active",
|
|
41
|
+
shippingMode: "Single",
|
|
42
|
+
shipping: [],
|
|
43
|
+
taxMode: "Platform",
|
|
44
|
+
taxRoundingMode: "HalfEven",
|
|
45
|
+
taxCalculationMode: "UnitPriceLevel",
|
|
46
|
+
refusedGifts: [],
|
|
47
|
+
origin: "Customer",
|
|
48
|
+
anonymousId: "1234567890",
|
|
49
|
+
billingAddress: {
|
|
50
|
+
id: "1234567890",
|
|
51
|
+
country: "NL",
|
|
52
|
+
firstName: "John",
|
|
53
|
+
lastName: "Doe",
|
|
54
|
+
streetName: "Main Street",
|
|
55
|
+
streetNumber: "123",
|
|
56
|
+
postalCode: "123456",
|
|
57
|
+
},
|
|
58
|
+
customerEmail: "john.doe@example.com",
|
|
59
|
+
customerGroup: {
|
|
60
|
+
id: "1234567890",
|
|
61
|
+
typeId: "customer-group",
|
|
62
|
+
},
|
|
63
|
+
customerId: "1234567890",
|
|
64
|
+
custom: {
|
|
65
|
+
type: {
|
|
66
|
+
typeId: "type",
|
|
67
|
+
id: "1234567890",
|
|
68
|
+
},
|
|
69
|
+
fields: {
|
|
70
|
+
description: "example description",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
shippingAddress: {
|
|
75
|
+
id: "1234567890",
|
|
76
|
+
country: "NL",
|
|
77
|
+
firstName: "John",
|
|
78
|
+
lastName: "Doe",
|
|
79
|
+
streetName: "Main Street",
|
|
80
|
+
streetNumber: "123",
|
|
81
|
+
postalCode: "123456",
|
|
82
|
+
},
|
|
83
|
+
shippingInfo: {
|
|
84
|
+
shippingMethodName: "Standard Shipping",
|
|
85
|
+
price: {
|
|
86
|
+
type: "centPrecision",
|
|
87
|
+
currencyCode: "EUR",
|
|
88
|
+
centAmount: 1000,
|
|
89
|
+
fractionDigits: 2,
|
|
90
|
+
},
|
|
91
|
+
shippingRate: {
|
|
92
|
+
price: {
|
|
93
|
+
type: "centPrecision",
|
|
94
|
+
currencyCode: "EUR",
|
|
95
|
+
centAmount: 1000,
|
|
96
|
+
fractionDigits: 2,
|
|
97
|
+
},
|
|
98
|
+
tiers: [],
|
|
99
|
+
},
|
|
100
|
+
shippingMethodState: "Shipped",
|
|
101
|
+
},
|
|
102
|
+
taxedPrice: {
|
|
103
|
+
totalNet: {
|
|
104
|
+
type: "centPrecision",
|
|
105
|
+
currencyCode: "EUR",
|
|
106
|
+
centAmount: 1000,
|
|
107
|
+
fractionDigits: 2,
|
|
108
|
+
},
|
|
109
|
+
taxPortions: [],
|
|
110
|
+
totalGross: {
|
|
111
|
+
type: "centPrecision",
|
|
112
|
+
currencyCode: "EUR",
|
|
113
|
+
centAmount: 1210,
|
|
114
|
+
fractionDigits: 2,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
taxedShippingPrice: {
|
|
118
|
+
totalNet: {
|
|
119
|
+
type: "centPrecision",
|
|
120
|
+
currencyCode: "EUR",
|
|
121
|
+
centAmount: 100,
|
|
122
|
+
fractionDigits: 2,
|
|
123
|
+
},
|
|
124
|
+
taxPortions: [],
|
|
125
|
+
totalGross: {
|
|
126
|
+
type: "centPrecision",
|
|
127
|
+
currencyCode: "EUR",
|
|
128
|
+
centAmount: 121,
|
|
129
|
+
fractionDigits: 2,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
storage.add("dummy", "cart", cart);
|
|
135
|
+
const ctx = { projectKey: "dummy" };
|
|
136
|
+
|
|
137
|
+
const result = repository.create(ctx, {
|
|
138
|
+
cart: {
|
|
139
|
+
id: cart.id,
|
|
140
|
+
typeId: "cart",
|
|
141
|
+
},
|
|
142
|
+
cartVersion: cart.version,
|
|
143
|
+
});
|
|
144
|
+
expect(result.cart?.id).toBe(cart.id);
|
|
145
|
+
|
|
146
|
+
const items = repository.query(ctx);
|
|
147
|
+
expect(items.count).toBe(1);
|
|
148
|
+
|
|
149
|
+
expect(result.billingAddress).toEqual(cart.billingAddress);
|
|
150
|
+
expect(result.cart?.id).toEqual(cart.id);
|
|
151
|
+
expect(result.country).toEqual(cart.country);
|
|
152
|
+
expect(result.custom).toEqual(cart.custom);
|
|
153
|
+
expect(result.customerGroup).toEqual(cart.customerGroup);
|
|
154
|
+
expect(result.customer.id).toEqual(cart.customerId);
|
|
155
|
+
expect(result.customLineItems).toEqual(cart.customLineItems);
|
|
156
|
+
expect(result.directDiscounts).toEqual(cart.directDiscounts);
|
|
157
|
+
expect(result.lineItems).toEqual(cart.lineItems);
|
|
158
|
+
expect(result.paymentInfo).toEqual(cart.paymentInfo);
|
|
159
|
+
expect(result.shippingAddress).toEqual(cart.shippingAddress);
|
|
160
|
+
expect(result.taxCalculationMode).toEqual(cart.taxCalculationMode);
|
|
161
|
+
expect(result.taxedPrice).toEqual(cart.taxedPrice);
|
|
162
|
+
expect(result.taxMode).toEqual(cart.taxMode);
|
|
163
|
+
expect(result.taxRoundingMode).toEqual(cart.taxRoundingMode);
|
|
164
|
+
expect(result.totalPrice).toEqual(cart.totalPrice);
|
|
165
|
+
expect(result.store).toEqual(cart.store);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import type {
|
|
3
|
+
Cart,
|
|
4
|
+
CartReference,
|
|
5
|
+
QuoteRequest,
|
|
6
|
+
QuoteRequestDraft,
|
|
7
|
+
} from "@commercetools/platform-sdk";
|
|
8
|
+
import type { Config } from "~src/config";
|
|
9
|
+
import { getBaseResourceProperties } from "~src/helpers";
|
|
10
|
+
import type { RepositoryContext } from "../abstract";
|
|
11
|
+
import { AbstractResourceRepository } from "../abstract";
|
|
12
|
+
import { QuoteRequestUpdateHandler } from "./actions";
|
|
13
|
+
|
|
14
|
+
export class QuoteRequestRepository extends AbstractResourceRepository<"quote-request"> {
|
|
15
|
+
constructor(config: Config) {
|
|
16
|
+
super("quote-request", config);
|
|
17
|
+
this.actions = new QuoteRequestUpdateHandler(config.storage);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
create(context: RepositoryContext, draft: QuoteRequestDraft): QuoteRequest {
|
|
21
|
+
assert(draft.cart, "draft.cart is missing");
|
|
22
|
+
return this.createFromCart(context, {
|
|
23
|
+
id: draft.cart.id!,
|
|
24
|
+
typeId: "cart",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
createFromCart(context: RepositoryContext, cartReference: CartReference) {
|
|
29
|
+
const cart = this._storage.getByResourceIdentifier(
|
|
30
|
+
context.projectKey,
|
|
31
|
+
cartReference,
|
|
32
|
+
) as Cart | null;
|
|
33
|
+
if (!cart) {
|
|
34
|
+
throw new Error("Cannot find cart");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!cart.customerId) {
|
|
38
|
+
throw new Error("Cart does not have a customer");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const resource: QuoteRequest = {
|
|
42
|
+
...getBaseResourceProperties(),
|
|
43
|
+
billingAddress: cart.billingAddress,
|
|
44
|
+
cart: cartReference,
|
|
45
|
+
country: cart.country,
|
|
46
|
+
custom: cart.custom,
|
|
47
|
+
customer: {
|
|
48
|
+
typeId: "customer",
|
|
49
|
+
id: cart.customerId,
|
|
50
|
+
},
|
|
51
|
+
customerGroup: cart.customerGroup,
|
|
52
|
+
customLineItems: [],
|
|
53
|
+
directDiscounts: cart.directDiscounts,
|
|
54
|
+
lineItems: cart.lineItems,
|
|
55
|
+
paymentInfo: cart.paymentInfo,
|
|
56
|
+
quoteRequestState: "Submitted",
|
|
57
|
+
shippingAddress: cart.shippingAddress,
|
|
58
|
+
taxCalculationMode: cart.taxCalculationMode,
|
|
59
|
+
taxedPrice: cart.taxedPrice,
|
|
60
|
+
taxMode: cart.taxMode,
|
|
61
|
+
taxRoundingMode: cart.taxRoundingMode,
|
|
62
|
+
totalPrice: cart.totalPrice,
|
|
63
|
+
store: cart.store,
|
|
64
|
+
};
|
|
65
|
+
return this.saveNew(context, resource);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
InvalidJsonInputError,
|
|
3
|
+
StagedQuote,
|
|
4
|
+
StagedQuoteSetCustomFieldAction,
|
|
5
|
+
StagedQuoteSetCustomTypeAction,
|
|
6
|
+
StagedQuoteTransitionStateAction,
|
|
7
|
+
StagedQuoteUpdateAction,
|
|
8
|
+
StateReference,
|
|
9
|
+
} from "@commercetools/platform-sdk";
|
|
10
|
+
import { CommercetoolsError } from "~src/exceptions";
|
|
11
|
+
import type { Writable } from "~src/types";
|
|
12
|
+
import type { RepositoryContext, UpdateHandlerInterface } from "../abstract";
|
|
13
|
+
import { AbstractUpdateHandler } from "../abstract";
|
|
14
|
+
import { getReferenceFromResourceIdentifier } from "../helpers";
|
|
15
|
+
|
|
16
|
+
export class StagedQuoteUpdateHandler
|
|
17
|
+
extends AbstractUpdateHandler
|
|
18
|
+
implements
|
|
19
|
+
Partial<UpdateHandlerInterface<StagedQuote, StagedQuoteUpdateAction>>
|
|
20
|
+
{
|
|
21
|
+
setCustomField(
|
|
22
|
+
context: RepositoryContext,
|
|
23
|
+
resource: StagedQuote,
|
|
24
|
+
{ name, value }: StagedQuoteSetCustomFieldAction,
|
|
25
|
+
) {
|
|
26
|
+
if (!resource.custom) {
|
|
27
|
+
throw new Error("Resource has no custom field");
|
|
28
|
+
}
|
|
29
|
+
resource.custom.fields[name] = value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
setCustomType(
|
|
33
|
+
context: RepositoryContext,
|
|
34
|
+
resource: Writable<StagedQuote>,
|
|
35
|
+
{ type, fields }: StagedQuoteSetCustomTypeAction,
|
|
36
|
+
) {
|
|
37
|
+
if (!type) {
|
|
38
|
+
resource.custom = undefined;
|
|
39
|
+
} else {
|
|
40
|
+
const resolvedType = this._storage.getByResourceIdentifier(
|
|
41
|
+
context.projectKey,
|
|
42
|
+
type,
|
|
43
|
+
);
|
|
44
|
+
if (!resolvedType) {
|
|
45
|
+
throw new Error(`Type ${type} not found`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
resource.custom = {
|
|
49
|
+
type: {
|
|
50
|
+
typeId: "type",
|
|
51
|
+
id: resolvedType.id,
|
|
52
|
+
},
|
|
53
|
+
fields: fields || {},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
transitionState(
|
|
59
|
+
context: RepositoryContext,
|
|
60
|
+
resource: Writable<StagedQuote>,
|
|
61
|
+
{ state, force }: StagedQuoteTransitionStateAction,
|
|
62
|
+
) {
|
|
63
|
+
let stateReference: StateReference | undefined = undefined;
|
|
64
|
+
if (state) {
|
|
65
|
+
stateReference = getReferenceFromResourceIdentifier<StateReference>(
|
|
66
|
+
state,
|
|
67
|
+
context.projectKey,
|
|
68
|
+
this._storage,
|
|
69
|
+
);
|
|
70
|
+
resource.state = stateReference;
|
|
71
|
+
} else {
|
|
72
|
+
throw new CommercetoolsError<InvalidJsonInputError>(
|
|
73
|
+
{
|
|
74
|
+
code: "InvalidJsonInput",
|
|
75
|
+
message: "Request body does not contain valid JSON.",
|
|
76
|
+
detailedErrorMessage: "actions -> state: Missing required value",
|
|
77
|
+
},
|
|
78
|
+
400,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return resource;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
StagedQuote,
|
|
3
|
+
StagedQuoteDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import type { Config } from "~src/config";
|
|
6
|
+
import { getBaseResourceProperties } from "~src/helpers";
|
|
7
|
+
import type { RepositoryContext } from "../abstract";
|
|
8
|
+
import { AbstractResourceRepository } from "../abstract";
|
|
9
|
+
import { StagedQuoteUpdateHandler } from "./actions";
|
|
10
|
+
|
|
11
|
+
export class StagedQuoteRepository extends AbstractResourceRepository<"staged-quote"> {
|
|
12
|
+
constructor(config: Config) {
|
|
13
|
+
super("staged-quote", config);
|
|
14
|
+
this.actions = new StagedQuoteUpdateHandler(config.storage);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
create(context: RepositoryContext, draft: StagedQuoteDraft): StagedQuote {
|
|
18
|
+
const quoteRequest = this._storage.getByResourceIdentifier<"quote-request">(
|
|
19
|
+
context.projectKey,
|
|
20
|
+
draft.quoteRequest,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
if (!quoteRequest.cart) {
|
|
24
|
+
throw new Error("Cannot find quote request");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const cart = this._storage.getByResourceIdentifier<"cart">(
|
|
28
|
+
context.projectKey,
|
|
29
|
+
quoteRequest.cart,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const resource: StagedQuote = {
|
|
33
|
+
...getBaseResourceProperties(),
|
|
34
|
+
stagedQuoteState: "InProgress",
|
|
35
|
+
quoteRequest: {
|
|
36
|
+
typeId: "quote-request",
|
|
37
|
+
id: quoteRequest.id,
|
|
38
|
+
},
|
|
39
|
+
quotationCart: {
|
|
40
|
+
typeId: "cart",
|
|
41
|
+
id: cart.id,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return resource;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -2,10 +2,10 @@ import type {
|
|
|
2
2
|
ChannelReference,
|
|
3
3
|
ProductReference,
|
|
4
4
|
} from "@commercetools/platform-sdk";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import type {
|
|
6
|
+
Review,
|
|
7
|
+
ReviewDraft,
|
|
8
|
+
StateReference,
|
|
9
9
|
} from "@commercetools/platform-sdk";
|
|
10
10
|
import type { Config } from "~src/config";
|
|
11
11
|
import { getBaseResourceProperties } from "../helpers";
|
|
@@ -2,23 +2,23 @@ import type {
|
|
|
2
2
|
ShippingMethodChangeTaxCategoryAction,
|
|
3
3
|
ShippingMethodRemoveShippingRateAction,
|
|
4
4
|
} from "@commercetools/platform-sdk";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
5
|
+
import type {
|
|
6
|
+
ShippingMethod,
|
|
7
|
+
ShippingMethodAddShippingRateAction,
|
|
8
|
+
ShippingMethodAddZoneAction,
|
|
9
|
+
ShippingMethodChangeActiveAction,
|
|
10
|
+
ShippingMethodChangeIsDefaultAction,
|
|
11
|
+
ShippingMethodChangeNameAction,
|
|
12
|
+
ShippingMethodRemoveZoneAction,
|
|
13
|
+
ShippingMethodSetCustomFieldAction,
|
|
14
|
+
ShippingMethodSetCustomTypeAction,
|
|
15
|
+
ShippingMethodSetDescriptionAction,
|
|
16
|
+
ShippingMethodSetKeyAction,
|
|
17
|
+
ShippingMethodSetLocalizedDescriptionAction,
|
|
18
|
+
ShippingMethodSetLocalizedNameAction,
|
|
19
|
+
ShippingMethodSetPredicateAction,
|
|
20
|
+
ShippingMethodUpdateAction,
|
|
21
|
+
ZoneReference,
|
|
22
22
|
} from "@commercetools/platform-sdk";
|
|
23
23
|
import deepEqual from "deep-equal";
|
|
24
24
|
import type { Writable } from "~src/types";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import type {
|
|
2
|
+
ShippingMethod,
|
|
3
|
+
ShippingMethodDraft,
|
|
4
|
+
ZoneRate,
|
|
5
|
+
ZoneRateDraft,
|
|
6
|
+
ZoneReference,
|
|
7
7
|
} from "@commercetools/platform-sdk";
|
|
8
8
|
import type { Config } from "~src/config";
|
|
9
9
|
import { getBaseResourceProperties } from "../../helpers";
|
|
@@ -137,7 +137,7 @@ export class ShoppingListUpdateHandler
|
|
|
137
137
|
} else {
|
|
138
138
|
throw new CommercetoolsError<GeneralError>({
|
|
139
139
|
code: "General",
|
|
140
|
-
message:
|
|
140
|
+
message: "Either lineItemid or lineItemKey needs to be provided.",
|
|
141
141
|
});
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -13,6 +13,7 @@ import type { RepositoryContext } from "../abstract";
|
|
|
13
13
|
import { AbstractResourceRepository } from "../abstract";
|
|
14
14
|
import {
|
|
15
15
|
createCustomFields,
|
|
16
|
+
getBusinessUnitKeyReference,
|
|
16
17
|
getReferenceFromResourceIdentifier,
|
|
17
18
|
getStoreKeyReference,
|
|
18
19
|
} from "../helpers";
|
|
@@ -50,6 +51,13 @@ export class ShoppingListRepository extends AbstractResourceRepository<"shopping
|
|
|
50
51
|
store: draft.store
|
|
51
52
|
? getStoreKeyReference(draft.store, context.projectKey, this._storage)
|
|
52
53
|
: undefined,
|
|
54
|
+
businessUnit: draft.businessUnit
|
|
55
|
+
? getBusinessUnitKeyReference(
|
|
56
|
+
draft.businessUnit,
|
|
57
|
+
context.projectKey,
|
|
58
|
+
this._storage,
|
|
59
|
+
)
|
|
60
|
+
: undefined,
|
|
53
61
|
};
|
|
54
62
|
return this.saveNew(context, resource);
|
|
55
63
|
}
|
|
@@ -117,7 +125,7 @@ export class ShoppingListRepository extends AbstractResourceRepository<"shopping
|
|
|
117
125
|
}
|
|
118
126
|
|
|
119
127
|
throw new Error(
|
|
120
|
-
|
|
128
|
+
"must provide either sku, productId or variantId for ShoppingListLineItem",
|
|
121
129
|
);
|
|
122
130
|
};
|
|
123
131
|
}
|
|
@@ -29,10 +29,7 @@ export class SubscriptionRepository extends AbstractResourceRepository<"subscrip
|
|
|
29
29
|
throw new CommercetoolsError<InvalidInputError>(
|
|
30
30
|
{
|
|
31
31
|
code: "InvalidInput",
|
|
32
|
-
message:
|
|
33
|
-
"A test message could not be delivered to this destination: " +
|
|
34
|
-
`SQS ${dest.queueUrl} in ${dest.region} for ${dest.accessKey}. ` +
|
|
35
|
-
"Please make sure your destination is correctly configured.",
|
|
32
|
+
message: `A test message could not be delivered to this destination: SQS ${dest.queueUrl} in ${dest.region} for ${dest.accessKey}. Please make sure your destination is correctly configured.`,
|
|
36
33
|
},
|
|
37
34
|
400,
|
|
38
35
|
);
|
|
@@ -49,6 +46,7 @@ export class SubscriptionRepository extends AbstractResourceRepository<"subscrip
|
|
|
49
46
|
key: draft.key,
|
|
50
47
|
messages: draft.messages || [],
|
|
51
48
|
status: "Healthy",
|
|
49
|
+
events: draft.events || [],
|
|
52
50
|
};
|
|
53
51
|
return this.saveNew(context, resource);
|
|
54
52
|
}
|
package/src/server.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CommercetoolsMock } from "./index";
|
|
2
2
|
|
|
3
|
-
process.on("SIGINT",
|
|
3
|
+
process.on("SIGINT", () => {
|
|
4
4
|
console.info("Stopping server...");
|
|
5
5
|
process.exit();
|
|
6
6
|
});
|
|
@@ -9,6 +9,7 @@ const instance = new CommercetoolsMock();
|
|
|
9
9
|
|
|
10
10
|
let port = 3000;
|
|
11
11
|
|
|
12
|
-
if (process.env.HTTP_SERVER_PORT)
|
|
12
|
+
if (process.env.HTTP_SERVER_PORT)
|
|
13
|
+
port = Number.parseInt(process.env.HTTP_SERVER_PORT);
|
|
13
14
|
|
|
14
15
|
instance.runServer(port);
|
package/src/services/abstract.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Update } from "@commercetools/platform-sdk";
|
|
2
|
-
import {
|
|
2
|
+
import { type Request, type Response, Router } from "express";
|
|
3
3
|
import type { ParsedQs } from "qs";
|
|
4
4
|
import { updateRequestSchema } from "~src/schemas/update-request";
|
|
5
5
|
import { validateData } from "~src/validate";
|
|
@@ -68,7 +68,7 @@ export default abstract class AbstractService {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
getWithId(request: Request, response: Response) {
|
|
71
|
-
const result = this._expandWithId(request, request.params
|
|
71
|
+
const result = this._expandWithId(request, request.params.id);
|
|
72
72
|
if (!result) {
|
|
73
73
|
return response.status(404).send();
|
|
74
74
|
}
|
|
@@ -78,7 +78,7 @@ export default abstract class AbstractService {
|
|
|
78
78
|
getWithKey(request: Request, response: Response) {
|
|
79
79
|
const result = this.repository.getByKey(
|
|
80
80
|
getRepositoryContext(request),
|
|
81
|
-
request.params
|
|
81
|
+
request.params.key,
|
|
82
82
|
{
|
|
83
83
|
expand: this._parseParam(request.query.expand),
|
|
84
84
|
},
|
|
@@ -90,7 +90,7 @@ export default abstract class AbstractService {
|
|
|
90
90
|
deleteWithId(request: Request, response: Response) {
|
|
91
91
|
const result = this.repository.delete(
|
|
92
92
|
getRepositoryContext(request),
|
|
93
|
-
request.params
|
|
93
|
+
request.params.id,
|
|
94
94
|
{
|
|
95
95
|
expand: this._parseParam(request.query.expand),
|
|
96
96
|
},
|
|
@@ -104,7 +104,7 @@ export default abstract class AbstractService {
|
|
|
104
104
|
deleteWithKey(request: Request, response: Response) {
|
|
105
105
|
const resource = this.repository.getByKey(
|
|
106
106
|
getRepositoryContext(request),
|
|
107
|
-
request.params
|
|
107
|
+
request.params.key,
|
|
108
108
|
);
|
|
109
109
|
if (!resource) {
|
|
110
110
|
return response.status(404).send("Not found");
|
|
@@ -140,7 +140,7 @@ export default abstract class AbstractService {
|
|
|
140
140
|
);
|
|
141
141
|
const resource = this.repository.get(
|
|
142
142
|
getRepositoryContext(request),
|
|
143
|
-
request.params
|
|
143
|
+
request.params.id,
|
|
144
144
|
);
|
|
145
145
|
if (!resource) {
|
|
146
146
|
return response.status(404).send("Not found");
|
|
@@ -165,7 +165,7 @@ export default abstract class AbstractService {
|
|
|
165
165
|
|
|
166
166
|
const resource = this.repository.getByKey(
|
|
167
167
|
getRepositoryContext(request),
|
|
168
|
-
request.params
|
|
168
|
+
request.params.key,
|
|
169
169
|
);
|
|
170
170
|
if (!resource) {
|
|
171
171
|
return response.status(404).send("Not found");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
1
2
|
import type { Order } from "@commercetools/platform-sdk";
|
|
2
|
-
import assert from "assert";
|
|
3
3
|
import supertest from "supertest";
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
5
5
|
import { CommercetoolsMock } from "../index";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
1
2
|
import type { CartDiscount, TypeDraft } from "@commercetools/platform-sdk";
|
|
2
|
-
import assert from "assert";
|
|
3
3
|
import supertest from "supertest";
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
5
5
|
import { CommercetoolsMock } from "..";
|