@labdigital/commercetools-mock 2.7.0 → 2.9.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 +362 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -2
- package/dist/index.d.ts +36 -2
- package/dist/index.js +362 -77
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/ctMock.ts +4 -0
- package/src/lib/predicateParser.test.ts +96 -11
- package/src/lib/predicateParser.ts +43 -12
- package/src/oauth/server.ts +11 -1
- package/src/priceSelector.ts +10 -5
- package/src/repositories/abstract.ts +5 -4
- package/src/repositories/cart.ts +77 -33
- package/src/repositories/custom-object.ts +18 -0
- package/src/repositories/customer.ts +1 -0
- package/src/repositories/helpers.ts +1 -1
- package/src/repositories/order.ts +45 -3
- package/src/repositories/product-projection.ts +15 -0
- package/src/repositories/product-selection.ts +0 -1
- package/src/repositories/product.ts +37 -24
- package/src/repositories/review.ts +36 -4
- package/src/repositories/shipping-method.ts +98 -22
- package/src/services/custom-object.ts +19 -0
- package/src/services/index.ts +2 -0
- package/src/services/product-selection.test.ts +0 -1
- package/src/services/reviews.ts +16 -0
- package/src/services/shipping-method.test.ts +120 -21
- package/src/services/shipping-method.ts +19 -2
- package/src/shippingCalculator.test.ts +280 -0
- package/src/shippingCalculator.ts +74 -0
- package/src/storage/abstract.ts +1 -1
- package/src/storage/in-memory.ts +91 -65
- package/src/types.ts +2 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@labdigital/commercetools-mock",
|
|
3
3
|
"author": "Michael van Tellingen",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.9.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@changesets/changelog-github": "^0.4.8",
|
|
48
48
|
"@changesets/cli": "^2.26.2",
|
|
49
|
-
"@commercetools/platform-sdk": "
|
|
49
|
+
"@commercetools/platform-sdk": "6.0.0",
|
|
50
50
|
"@types/basic-auth": "^1.1.3",
|
|
51
51
|
"@types/body-parser": "^1.19.2",
|
|
52
52
|
"@types/deep-equal": "^1.0.1",
|
package/src/ctMock.ts
CHANGED
|
@@ -16,7 +16,67 @@ describe('Predicate filter', () => {
|
|
|
16
16
|
stringProperty: 'foobar',
|
|
17
17
|
booleanProperty: true,
|
|
18
18
|
},
|
|
19
|
+
array: [
|
|
20
|
+
{
|
|
21
|
+
numberProperty: 1234,
|
|
22
|
+
stringProperty: 'foo',
|
|
23
|
+
objectProperty: {
|
|
24
|
+
stringProperty: 'foo',
|
|
25
|
+
booleanProperty: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
numberProperty: 2345,
|
|
30
|
+
stringProperty: 'bar',
|
|
31
|
+
objectProperty: {
|
|
32
|
+
stringProperty: 'bar',
|
|
33
|
+
booleanProperty: false,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
19
37
|
},
|
|
38
|
+
array: [
|
|
39
|
+
{
|
|
40
|
+
nestedArray: [
|
|
41
|
+
{
|
|
42
|
+
stringProperty: 'foo',
|
|
43
|
+
nested: [
|
|
44
|
+
{
|
|
45
|
+
stringProperty: 'foo',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
stringProperty: 'bar',
|
|
51
|
+
nested: [
|
|
52
|
+
{
|
|
53
|
+
stringProperty: 'bar',
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
nestedArray: [
|
|
61
|
+
{
|
|
62
|
+
stringProperty: 'foo-2',
|
|
63
|
+
nested: [
|
|
64
|
+
{
|
|
65
|
+
stringProperty: 'foo-2',
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
stringProperty: 'bar-2',
|
|
71
|
+
nested: [
|
|
72
|
+
{
|
|
73
|
+
stringProperty: 'bar-2',
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
20
80
|
|
|
21
81
|
// Longitude, latitude
|
|
22
82
|
geoLocation: [5.110230209615395, 52.06969591642097],
|
|
@@ -115,6 +175,30 @@ describe('Predicate filter', () => {
|
|
|
115
175
|
).toBeTruthy()
|
|
116
176
|
})
|
|
117
177
|
|
|
178
|
+
test('nestedArray filters on property', async () => {
|
|
179
|
+
expect(match(`nested(array(stringProperty="foo"))`)).toBeTruthy()
|
|
180
|
+
expect(match(`nested(array(stringProperty="bar"))`)).toBeTruthy()
|
|
181
|
+
expect(match(`nested(array(stringProperty="foobar"))`)).toBeFalsy()
|
|
182
|
+
|
|
183
|
+
// One level deeper
|
|
184
|
+
expect(
|
|
185
|
+
match(`nested(array(objectProperty(stringProperty="foo")))`)
|
|
186
|
+
).toBeTruthy()
|
|
187
|
+
expect(
|
|
188
|
+
match(`nested(array(objectProperty(stringProperty="bar")))`)
|
|
189
|
+
).toBeTruthy()
|
|
190
|
+
expect(
|
|
191
|
+
match(`nested(array(objectProperty(stringProperty="foobar")))`)
|
|
192
|
+
).toBeFalsy()
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
test('array filters on property', async () => {
|
|
196
|
+
expect(match(`array(nestedArray(stringProperty="foo")))`)).toBeTruthy()
|
|
197
|
+
expect(
|
|
198
|
+
match(`array(nestedArray(nested(stringProperty="foo"))))`)
|
|
199
|
+
).toBeTruthy()
|
|
200
|
+
})
|
|
201
|
+
|
|
118
202
|
test('geolocation within circle (...)', async () => {
|
|
119
203
|
expect(
|
|
120
204
|
match(
|
|
@@ -185,17 +269,18 @@ describe('Predicate filter', () => {
|
|
|
185
269
|
).toBeTruthy()
|
|
186
270
|
})
|
|
187
271
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
272
|
+
// TODO: disabled for now, see remark in predicateParser.ts in resolveValue
|
|
273
|
+
// test('lexer confusion', async () => {
|
|
274
|
+
// expect(() => match(`orSomething="foobar"`)).toThrow(PredicateError)
|
|
275
|
+
// expect(() => match(`orSomething="foobar"`)).toThrow(
|
|
276
|
+
// "The field 'orSomething' does not exist."
|
|
277
|
+
// )
|
|
278
|
+
|
|
279
|
+
// expect(() => match(`andSomething="foobar"`)).toThrow(PredicateError)
|
|
280
|
+
// expect(() => match(`andSomething="foobar"`)).toThrow(
|
|
281
|
+
// "The field 'andSomething' does not exist."
|
|
282
|
+
// )
|
|
283
|
+
// })
|
|
199
284
|
|
|
200
285
|
test('invalid predicate', async () => {
|
|
201
286
|
expect(() => match(`stringProperty=nomatch`)).toThrow(PredicateError)
|
|
@@ -96,7 +96,12 @@ const resolveValue = (obj: any, val: TypeSymbol): any => {
|
|
|
96
96
|
.filter((v) => val.value in v)
|
|
97
97
|
.map((v) => v[val.value])
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
|
|
100
|
+
// TODO: We don't really validate the shape of the object here. To actually
|
|
101
|
+
// match commercetools behaviour we should throw an error if the requested
|
|
102
|
+
// field doesn't exist (unless it's a map)
|
|
103
|
+
// throw new PredicateError(`The field '${val.value}' does not exist.`)
|
|
104
|
+
return undefined
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
return obj[val.value]
|
|
@@ -243,11 +248,21 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
243
248
|
const expr = parser.parse()
|
|
244
249
|
lexer.expect(')')
|
|
245
250
|
return (obj: any, vars: object) => {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
251
|
+
if (Array.isArray(obj)) {
|
|
252
|
+
return obj.some((item) => {
|
|
253
|
+
const value = resolveValue(item, left)
|
|
254
|
+
if (value) {
|
|
255
|
+
return expr(value, vars)
|
|
256
|
+
}
|
|
257
|
+
return false
|
|
258
|
+
})
|
|
259
|
+
} else {
|
|
260
|
+
const value = resolveValue(obj, left)
|
|
261
|
+
if (value) {
|
|
262
|
+
return expr(value, vars)
|
|
263
|
+
}
|
|
264
|
+
return false
|
|
249
265
|
}
|
|
250
|
-
return false
|
|
251
266
|
}
|
|
252
267
|
})
|
|
253
268
|
.bp(')', 0)
|
|
@@ -256,12 +271,23 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
256
271
|
validateSymbol(expr)
|
|
257
272
|
|
|
258
273
|
return (obj: any, vars: VariableMap) => {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
274
|
+
if (Array.isArray(obj)) {
|
|
275
|
+
return obj.some((item) => {
|
|
276
|
+
const value = resolveValue(item, left)
|
|
277
|
+
const other = resolveSymbol(expr, vars)
|
|
278
|
+
if (Array.isArray(value)) {
|
|
279
|
+
return !!value.some((elem) => elem === other)
|
|
280
|
+
}
|
|
281
|
+
return value === other
|
|
282
|
+
})
|
|
283
|
+
} else {
|
|
284
|
+
const resolvedValue = resolveValue(obj, left)
|
|
285
|
+
const resolvedSymbol = resolveSymbol(expr, vars)
|
|
286
|
+
if (Array.isArray(resolvedValue)) {
|
|
287
|
+
return !!resolvedValue.some((elem) => elem === resolvedSymbol)
|
|
288
|
+
}
|
|
289
|
+
return resolvedValue === resolvedSymbol
|
|
263
290
|
}
|
|
264
|
-
return resolvedValue === resolvedSymbol
|
|
265
291
|
}
|
|
266
292
|
})
|
|
267
293
|
.led('!=', 20, ({ left, bp }) => {
|
|
@@ -350,10 +376,15 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
350
376
|
symbols = [expr]
|
|
351
377
|
}
|
|
352
378
|
|
|
353
|
-
|
|
379
|
+
// The expression can be a list of variables, like
|
|
380
|
+
// :value_1, :value_2, but it can also be one variable
|
|
381
|
+
// containing a list, like :values.
|
|
382
|
+
// So to support both we just flatten the list.
|
|
383
|
+
const inValues = symbols.flatMap((item: TypeSymbol) =>
|
|
354
384
|
resolveSymbol(item, vars)
|
|
355
385
|
)
|
|
356
|
-
|
|
386
|
+
const value = resolveValue(obj, left)
|
|
387
|
+
return inValues.includes(value)
|
|
357
388
|
}
|
|
358
389
|
})
|
|
359
390
|
.led('MATCHES_IGNORE_CASE', 20, ({ left, bp }) => {
|
package/src/oauth/server.ts
CHANGED
|
@@ -24,7 +24,7 @@ export class OAuth2Server {
|
|
|
24
24
|
store: OAuth2Store
|
|
25
25
|
private customerRepository: CustomerRepository
|
|
26
26
|
|
|
27
|
-
constructor(options: { enabled: boolean; validate: boolean }) {
|
|
27
|
+
constructor(private options: { enabled: boolean; validate: boolean }) {
|
|
28
28
|
this.store = new OAuth2Store(options.validate)
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -53,6 +53,16 @@ export class OAuth2Server {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
createMiddleware() {
|
|
56
|
+
if (!this.options.validate) {
|
|
57
|
+
return async (
|
|
58
|
+
request: Request,
|
|
59
|
+
response: Response,
|
|
60
|
+
next: NextFunction
|
|
61
|
+
) => {
|
|
62
|
+
next()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
56
66
|
return async (request: Request, response: Response, next: NextFunction) => {
|
|
57
67
|
const token = getBearerToken(request)
|
|
58
68
|
if (!token) {
|
package/src/priceSelector.ts
CHANGED
|
@@ -21,11 +21,13 @@ export type PriceSelector = {
|
|
|
21
21
|
*/
|
|
22
22
|
export const applyPriceSelector = (
|
|
23
23
|
products: ProductProjection[],
|
|
24
|
-
selector: PriceSelector
|
|
24
|
+
selector: PriceSelector,
|
|
25
|
+
noScopedPrice: boolean = false
|
|
25
26
|
) => {
|
|
26
27
|
validatePriceSelector(selector)
|
|
27
28
|
|
|
28
29
|
for (const product of products) {
|
|
30
|
+
// Get list of all variants (master + variants)
|
|
29
31
|
const variants: Writable<ProductVariant>[] = [
|
|
30
32
|
product.masterVariant,
|
|
31
33
|
...(product.variants ?? []),
|
|
@@ -38,10 +40,13 @@ export const applyPriceSelector = (
|
|
|
38
40
|
if (scopedPrices.length > 0) {
|
|
39
41
|
const price = scopedPrices[0]
|
|
40
42
|
|
|
41
|
-
variant.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
variant.price = scopedPrices[0]
|
|
44
|
+
if (!noScopedPrice) {
|
|
45
|
+
variant.scopedPriceDiscounted = false
|
|
46
|
+
variant.scopedPrice = {
|
|
47
|
+
...price,
|
|
48
|
+
currentValue: price.value,
|
|
49
|
+
}
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BaseResource,
|
|
3
3
|
Project,
|
|
4
|
+
QueryParam,
|
|
4
5
|
ResourceNotFoundError,
|
|
5
6
|
UpdateAction,
|
|
6
7
|
} from '@commercetools/platform-sdk'
|
|
@@ -16,6 +17,9 @@ export type QueryParams = {
|
|
|
16
17
|
where?: string[]
|
|
17
18
|
offset?: number
|
|
18
19
|
limit?: number
|
|
20
|
+
|
|
21
|
+
// Predicate var values. Should always start with `var.`
|
|
22
|
+
[key: string]: QueryParam
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
export type GetParams = {
|
|
@@ -118,10 +122,7 @@ export abstract class AbstractResourceRepository<
|
|
|
118
122
|
|
|
119
123
|
query(context: RepositoryContext, params: QueryParams = {}) {
|
|
120
124
|
const result = this._storage.query(context.projectKey, this.getTypeId(), {
|
|
121
|
-
|
|
122
|
-
where: params.where,
|
|
123
|
-
offset: params.offset,
|
|
124
|
-
limit: params.limit,
|
|
125
|
+
...params,
|
|
125
126
|
})
|
|
126
127
|
|
|
127
128
|
// @ts-ignore
|
package/src/repositories/cart.ts
CHANGED
|
@@ -1,31 +1,32 @@
|
|
|
1
|
-
import
|
|
2
|
-
Address,
|
|
3
|
-
AddressDraft,
|
|
4
|
-
Cart,
|
|
5
|
-
CartAddLineItemAction,
|
|
6
|
-
CartChangeLineItemQuantityAction,
|
|
7
|
-
CartAddItemShippingAddressAction,
|
|
8
|
-
CartSetLineItemShippingDetailsAction,
|
|
9
|
-
CartDraft,
|
|
10
|
-
CartRemoveLineItemAction,
|
|
11
|
-
CartSetBillingAddressAction,
|
|
12
|
-
CartSetCountryAction,
|
|
13
|
-
CartSetCustomerEmailAction,
|
|
14
|
-
CartSetCustomFieldAction,
|
|
15
|
-
CartSetCustomTypeAction,
|
|
16
|
-
CartSetLocaleAction,
|
|
17
|
-
CartSetShippingAddressAction,
|
|
18
|
-
CartSetShippingMethodAction,
|
|
19
|
-
CustomFields,
|
|
20
|
-
GeneralError,
|
|
21
|
-
LineItem,
|
|
22
|
-
LineItemDraft,
|
|
23
|
-
ItemShippingDetails,
|
|
24
|
-
Price,
|
|
25
|
-
Product,
|
|
26
|
-
ProductPagedQueryResponse,
|
|
27
|
-
CartRemoveDiscountCodeAction,
|
|
28
|
-
ProductVariant,
|
|
1
|
+
import {
|
|
2
|
+
type Address,
|
|
3
|
+
type AddressDraft,
|
|
4
|
+
type Cart,
|
|
5
|
+
type CartAddLineItemAction,
|
|
6
|
+
type CartChangeLineItemQuantityAction,
|
|
7
|
+
type CartAddItemShippingAddressAction,
|
|
8
|
+
type CartSetLineItemShippingDetailsAction,
|
|
9
|
+
type CartDraft,
|
|
10
|
+
type CartRemoveLineItemAction,
|
|
11
|
+
type CartSetBillingAddressAction,
|
|
12
|
+
type CartSetCountryAction,
|
|
13
|
+
type CartSetCustomerEmailAction,
|
|
14
|
+
type CartSetCustomFieldAction,
|
|
15
|
+
type CartSetCustomTypeAction,
|
|
16
|
+
type CartSetLocaleAction,
|
|
17
|
+
type CartSetShippingAddressAction,
|
|
18
|
+
type CartSetShippingMethodAction,
|
|
19
|
+
type CustomFields,
|
|
20
|
+
type GeneralError,
|
|
21
|
+
type LineItem,
|
|
22
|
+
type LineItemDraft,
|
|
23
|
+
type ItemShippingDetails,
|
|
24
|
+
type Price,
|
|
25
|
+
type Product,
|
|
26
|
+
type ProductPagedQueryResponse,
|
|
27
|
+
type CartRemoveDiscountCodeAction,
|
|
28
|
+
type ProductVariant,
|
|
29
|
+
type CartSetCustomShippingMethodAction,
|
|
29
30
|
} from '@commercetools/platform-sdk'
|
|
30
31
|
import { v4 as uuidv4 } from 'uuid'
|
|
31
32
|
import { CommercetoolsError } from '../exceptions.js'
|
|
@@ -35,7 +36,12 @@ import {
|
|
|
35
36
|
AbstractResourceRepository,
|
|
36
37
|
type RepositoryContext,
|
|
37
38
|
} from './abstract.js'
|
|
38
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
createAddress,
|
|
41
|
+
createCentPrecisionMoney,
|
|
42
|
+
createCustomFields,
|
|
43
|
+
createTypedMoney,
|
|
44
|
+
} from './helpers.js'
|
|
39
45
|
|
|
40
46
|
export class CartRepository extends AbstractResourceRepository<'cart'> {
|
|
41
47
|
getTypeId() {
|
|
@@ -74,6 +80,11 @@ export class CartRepository extends AbstractResourceRepository<'cart'> {
|
|
|
74
80
|
fractionDigits: 0,
|
|
75
81
|
},
|
|
76
82
|
shippingMode: 'Single',
|
|
83
|
+
shippingAddress: createAddress(
|
|
84
|
+
draft.shippingAddress,
|
|
85
|
+
context.projectKey,
|
|
86
|
+
this._storage
|
|
87
|
+
),
|
|
77
88
|
shipping: [],
|
|
78
89
|
origin: draft.origin ?? 'Customer',
|
|
79
90
|
refusedGifts: [],
|
|
@@ -335,10 +346,6 @@ export class CartRepository extends AbstractResourceRepository<'cart'> {
|
|
|
335
346
|
shippingMethod
|
|
336
347
|
)
|
|
337
348
|
|
|
338
|
-
if (!method) {
|
|
339
|
-
throw new Error(`Type ${shippingMethod} not found`)
|
|
340
|
-
}
|
|
341
|
-
|
|
342
349
|
// Based on the address we should select a shipping zone and
|
|
343
350
|
// use that to define the price.
|
|
344
351
|
// @ts-ignore
|
|
@@ -377,6 +384,43 @@ export class CartRepository extends AbstractResourceRepository<'cart'> {
|
|
|
377
384
|
}
|
|
378
385
|
resource.custom.fields[name] = value
|
|
379
386
|
},
|
|
387
|
+
setCustomShippingMethod: (
|
|
388
|
+
context: RepositoryContext,
|
|
389
|
+
resource: Writable<Cart>,
|
|
390
|
+
{
|
|
391
|
+
shippingMethodName,
|
|
392
|
+
shippingRate,
|
|
393
|
+
taxCategory,
|
|
394
|
+
externalTaxRate,
|
|
395
|
+
}: CartSetCustomShippingMethodAction
|
|
396
|
+
) => {
|
|
397
|
+
if (externalTaxRate) {
|
|
398
|
+
throw new Error('External tax rate is not supported')
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const tax = taxCategory
|
|
402
|
+
? this._storage.getByResourceIdentifier<'tax-category'>(
|
|
403
|
+
context.projectKey,
|
|
404
|
+
taxCategory
|
|
405
|
+
)
|
|
406
|
+
: undefined
|
|
407
|
+
|
|
408
|
+
resource.shippingInfo = {
|
|
409
|
+
shippingMethodName,
|
|
410
|
+
price: createCentPrecisionMoney(shippingRate.price),
|
|
411
|
+
shippingRate: {
|
|
412
|
+
price: createTypedMoney(shippingRate.price),
|
|
413
|
+
tiers: [],
|
|
414
|
+
},
|
|
415
|
+
taxCategory: tax
|
|
416
|
+
? {
|
|
417
|
+
typeId: 'tax-category',
|
|
418
|
+
id: tax?.id,
|
|
419
|
+
}
|
|
420
|
+
: undefined,
|
|
421
|
+
shippingMethodState: 'MatchesCart',
|
|
422
|
+
}
|
|
423
|
+
},
|
|
380
424
|
setCustomType: (
|
|
381
425
|
context: RepositoryContext,
|
|
382
426
|
resource: Writable<Cart>,
|
|
@@ -8,6 +8,7 @@ import { cloneObject, getBaseResourceProperties } from '../helpers.js'
|
|
|
8
8
|
import type { Writable } from '../types.js'
|
|
9
9
|
import {
|
|
10
10
|
AbstractResourceRepository,
|
|
11
|
+
QueryParams,
|
|
11
12
|
type RepositoryContext,
|
|
12
13
|
} from './abstract.js'
|
|
13
14
|
import { checkConcurrentModification } from './errors.js'
|
|
@@ -67,6 +68,23 @@ export class CustomObjectRepository extends AbstractResourceRepository<'key-valu
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
queryWithContainer(
|
|
72
|
+
context: RepositoryContext,
|
|
73
|
+
container: string,
|
|
74
|
+
params: QueryParams = {}
|
|
75
|
+
) {
|
|
76
|
+
const whereClause = params.where || []
|
|
77
|
+
whereClause.push(`container="${container}"`)
|
|
78
|
+
const result = this._storage.query(context.projectKey, this.getTypeId(), {
|
|
79
|
+
...params,
|
|
80
|
+
where: whereClause,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
result.results = result.results.map(this.postProcessResource)
|
|
85
|
+
return result
|
|
86
|
+
}
|
|
87
|
+
|
|
70
88
|
getWithContainerAndKey(
|
|
71
89
|
context: RepositoryContext,
|
|
72
90
|
container: string,
|
|
@@ -51,6 +51,7 @@ export class CustomerRepository extends AbstractResourceRepository<'customer'> {
|
|
|
51
51
|
password: draft.password ? hashPassword(draft.password) : undefined,
|
|
52
52
|
isEmailVerified: draft.isEmailVerified || false,
|
|
53
53
|
addresses: [],
|
|
54
|
+
customerNumber: draft.customerNumber,
|
|
54
55
|
}
|
|
55
56
|
this.saveNew(context, resource)
|
|
56
57
|
return resource
|
|
@@ -180,7 +180,7 @@ export const getReferenceFromResourceIdentifier = <T extends Reference>(
|
|
|
180
180
|
if (!resource) {
|
|
181
181
|
const errIdentifier = resourceIdentifier.key
|
|
182
182
|
? `key '${resourceIdentifier.key}'`
|
|
183
|
-
: `identifier '${resourceIdentifier.
|
|
183
|
+
: `identifier '${resourceIdentifier.id}'`
|
|
184
184
|
|
|
185
185
|
throw new CommercetoolsError<ReferencedResourceNotFoundError>(
|
|
186
186
|
{
|
|
@@ -2,12 +2,15 @@ import type {
|
|
|
2
2
|
Cart,
|
|
3
3
|
CartReference,
|
|
4
4
|
CustomLineItem,
|
|
5
|
-
|
|
5
|
+
CustomLineItemImportDraft,
|
|
6
|
+
CustomLineItemReturnItem,
|
|
6
7
|
GeneralError,
|
|
7
8
|
LineItem,
|
|
8
9
|
LineItemImportDraft,
|
|
10
|
+
LineItemReturnItem,
|
|
9
11
|
Order,
|
|
10
12
|
OrderAddPaymentAction,
|
|
13
|
+
OrderAddReturnInfoAction,
|
|
11
14
|
OrderChangeOrderStateAction,
|
|
12
15
|
OrderChangePaymentStateAction,
|
|
13
16
|
OrderFromCartDraft,
|
|
@@ -24,6 +27,7 @@ import type {
|
|
|
24
27
|
Product,
|
|
25
28
|
ProductPagedQueryResponse,
|
|
26
29
|
ProductVariant,
|
|
30
|
+
ReturnInfo,
|
|
27
31
|
State,
|
|
28
32
|
Store,
|
|
29
33
|
} from '@commercetools/platform-sdk'
|
|
@@ -227,7 +231,7 @@ export class OrderRepository extends AbstractResourceRepository<'order'> {
|
|
|
227
231
|
|
|
228
232
|
private customLineItemFromImportDraft(
|
|
229
233
|
context: RepositoryContext,
|
|
230
|
-
draft:
|
|
234
|
+
draft: CustomLineItemImportDraft
|
|
231
235
|
): CustomLineItem {
|
|
232
236
|
const lineItem: CustomLineItem = {
|
|
233
237
|
...getBaseResourceProperties(),
|
|
@@ -241,10 +245,11 @@ export class OrderRepository extends AbstractResourceRepository<'order'> {
|
|
|
241
245
|
name: draft.name,
|
|
242
246
|
quantity: draft.quantity ?? 0,
|
|
243
247
|
perMethodTaxRate: [],
|
|
244
|
-
priceMode: draft.priceMode,
|
|
248
|
+
priceMode: draft.priceMode ?? 'Standard',
|
|
245
249
|
slug: draft.slug,
|
|
246
250
|
state: [],
|
|
247
251
|
totalPrice: createCentPrecisionMoney(draft.money),
|
|
252
|
+
taxedPricePortions: [],
|
|
248
253
|
}
|
|
249
254
|
|
|
250
255
|
return lineItem
|
|
@@ -296,6 +301,43 @@ export class OrderRepository extends AbstractResourceRepository<'order'> {
|
|
|
296
301
|
id: payment.id!,
|
|
297
302
|
})
|
|
298
303
|
},
|
|
304
|
+
addReturnInfo: (
|
|
305
|
+
context: RepositoryContext,
|
|
306
|
+
resource: Writable<Order>,
|
|
307
|
+
info: OrderAddReturnInfoAction
|
|
308
|
+
) => {
|
|
309
|
+
if (!resource.returnInfo) {
|
|
310
|
+
resource.returnInfo = []
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const resolved: ReturnInfo = {
|
|
314
|
+
items: info.items.map((item) => {
|
|
315
|
+
const common = {
|
|
316
|
+
...getBaseResourceProperties(),
|
|
317
|
+
quantity: item.quantity,
|
|
318
|
+
paymentState: 'Initial',
|
|
319
|
+
shipmentState: 'Initial',
|
|
320
|
+
comment: item.comment,
|
|
321
|
+
}
|
|
322
|
+
if (item.customLineItemId) {
|
|
323
|
+
return {
|
|
324
|
+
...common,
|
|
325
|
+
type: 'CustomLineItemReturnItem',
|
|
326
|
+
customLineItemId: item.customLineItemId,
|
|
327
|
+
} as CustomLineItemReturnItem
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
...common,
|
|
331
|
+
type: 'LineItemReturnItem',
|
|
332
|
+
lineItemId: item.customLineItemId || item.lineItemId,
|
|
333
|
+
} as LineItemReturnItem
|
|
334
|
+
}),
|
|
335
|
+
returnTrackingId: info.returnTrackingId,
|
|
336
|
+
returnDate: info.returnDate,
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
resource.returnInfo.push(resolved)
|
|
340
|
+
},
|
|
299
341
|
changeOrderState: (
|
|
300
342
|
context: RepositoryContext,
|
|
301
343
|
resource: Writable<Order>,
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
GetParams,
|
|
14
14
|
RepositoryContext,
|
|
15
15
|
} from './abstract.js'
|
|
16
|
+
import { applyPriceSelector } from '../priceSelector.js'
|
|
16
17
|
|
|
17
18
|
export type ProductProjectionQueryParams = {
|
|
18
19
|
staged?: boolean
|
|
@@ -100,6 +101,20 @@ export class ProductProjectionRepository extends AbstractResourceRepository<'pro
|
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
// We do this after the filtering, since the docs mention:
|
|
105
|
+
// Only available when Price selection is used. Cannot be used in a Query
|
|
106
|
+
// Predicate.
|
|
107
|
+
applyPriceSelector(
|
|
108
|
+
resources,
|
|
109
|
+
{
|
|
110
|
+
country: params.priceCountry,
|
|
111
|
+
channel: params.priceChannel,
|
|
112
|
+
customerGroup: params.priceCustomerGroup,
|
|
113
|
+
currency: params.priceCurrency,
|
|
114
|
+
},
|
|
115
|
+
true
|
|
116
|
+
)
|
|
117
|
+
|
|
103
118
|
// Expand the resources
|
|
104
119
|
if (params.expand !== undefined) {
|
|
105
120
|
resources = resources.map((resource) =>
|