@labdigital/commercetools-mock 2.54.0 → 2.56.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.
Files changed (53) hide show
  1. package/dist/index.d.ts +107 -77
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +455 -8
  4. package/dist/index.js.map +1 -1
  5. package/package.json +4 -3
  6. package/src/lib/predicateParser.test.ts +13 -37
  7. package/src/lib/predicateParser.ts +12 -1
  8. package/src/lib/productSearchFilter.test.ts +1 -0
  9. package/src/lib/projectionSearchFilter.test.ts +1 -0
  10. package/src/priceSelector.test.ts +1 -0
  11. package/src/product-projection-search.ts +2 -0
  12. package/src/product-search.ts +1 -0
  13. package/src/repositories/cart/actions.ts +178 -0
  14. package/src/repositories/cart/helpers.ts +170 -3
  15. package/src/repositories/cart/index.test.ts +86 -2
  16. package/src/repositories/cart/index.ts +19 -2
  17. package/src/repositories/cart-discount/index.ts +1 -1
  18. package/src/repositories/customer/index.ts +2 -0
  19. package/src/repositories/discount-group/actions.ts +50 -0
  20. package/src/repositories/discount-group/index.ts +29 -0
  21. package/src/repositories/index.ts +6 -0
  22. package/src/repositories/order/index.test.ts +126 -125
  23. package/src/repositories/payment/actions.ts +87 -0
  24. package/src/repositories/payment/index.ts +1 -1
  25. package/src/repositories/product/index.ts +1 -0
  26. package/src/repositories/product-type.ts +1 -0
  27. package/src/repositories/quote/index.ts +1 -0
  28. package/src/repositories/quote-request/index.test.ts +1 -0
  29. package/src/repositories/quote-request/index.ts +1 -0
  30. package/src/repositories/recurrence-policy/actions.ts +53 -0
  31. package/src/repositories/recurrence-policy/index.ts +36 -0
  32. package/src/repositories/recurring-order/actions.ts +157 -0
  33. package/src/repositories/recurring-order/index.ts +52 -0
  34. package/src/repositories/review.test.ts +2 -0
  35. package/src/repositories/shopping-list/actions.ts +1 -0
  36. package/src/repositories/shopping-list/index.ts +1 -0
  37. package/src/services/cart.test.ts +282 -0
  38. package/src/services/discount-group.test.ts +270 -0
  39. package/src/services/discount-group.ts +16 -0
  40. package/src/services/index.ts +12 -0
  41. package/src/services/my-cart.test.ts +1 -0
  42. package/src/services/my-payment.test.ts +1 -0
  43. package/src/services/payment.test.ts +1 -0
  44. package/src/services/product-projection.test.ts +4 -0
  45. package/src/services/product-type.test.ts +1 -0
  46. package/src/services/product.test.ts +1 -0
  47. package/src/services/recurrence-policy.test.ts +316 -0
  48. package/src/services/recurrence-policy.ts +16 -0
  49. package/src/services/recurring-order.test.ts +424 -0
  50. package/src/services/recurring-order.ts +16 -0
  51. package/src/services/shopping-list.test.ts +3 -0
  52. package/src/storage/in-memory.ts +6 -0
  53. package/src/types.ts +6 -0
@@ -5,6 +5,8 @@ import type {
5
5
  import type {
6
6
  Cart,
7
7
  CartDraft,
8
+ CustomLineItem,
9
+ CustomLineItemDraft,
8
10
  GeneralError,
9
11
  LineItem,
10
12
  LineItemDraft,
@@ -22,7 +24,11 @@ import {
22
24
  } from "../abstract";
23
25
  import { createAddress, createCustomFields } from "../helpers";
24
26
  import { CartUpdateHandler } from "./actions";
25
- import { calculateCartTotalPrice, selectPrice } from "./helpers";
27
+ import {
28
+ calculateCartTotalPrice,
29
+ createCustomLineItemFromDraft,
30
+ selectPrice,
31
+ } from "./helpers";
26
32
 
27
33
  export class CartRepository extends AbstractResourceRepository<"cart"> {
28
34
  constructor(config: Config) {
@@ -69,6 +75,16 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
69
75
  ),
70
76
  ) ?? [];
71
77
 
78
+ const customLineItems =
79
+ draft.customLineItems?.map((draftCustomLineItem) =>
80
+ createCustomLineItemFromDraft(
81
+ context.projectKey,
82
+ draftCustomLineItem,
83
+ this._storage,
84
+ draft.country,
85
+ ),
86
+ ) ?? [];
87
+
72
88
  const resource: Writable<Cart> = {
73
89
  ...getBaseResourceProperties(),
74
90
  anonymousId: draft.anonymousId,
@@ -86,13 +102,14 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
86
102
  country: draft.country,
87
103
  customerId: draft.customerId,
88
104
  customerEmail: draft.customerEmail,
89
- customLineItems: [],
105
+ customLineItems,
90
106
  directDiscounts: [],
91
107
  discountCodes: [],
92
108
  inventoryMode: "None",
93
109
  itemShippingAddresses: [],
94
110
  lineItems,
95
111
  locale: draft.locale,
112
+ priceRoundingMode: draft.priceRoundingMode ?? "HalfEven",
96
113
  taxCalculationMode: draft.taxCalculationMode ?? "LineItemLevel",
97
114
  taxMode: draft.taxMode ?? "Platform",
98
115
  taxRoundingMode: draft.taxRoundingMode ?? "HalfEven",
@@ -41,7 +41,7 @@ export class CartDiscountRepository extends AbstractResourceRepository<"cart-dis
41
41
  references: [],
42
42
  target: draft.target,
43
43
  requiresDiscountCode: draft.requiresDiscountCode || false,
44
- sortOrder: draft.sortOrder,
44
+ sortOrder: draft.sortOrder ?? "0.1",
45
45
  stackingMode: draft.stackingMode || "Stacking",
46
46
  validFrom: draft.validFrom,
47
47
  validUntil: draft.validUntil,
@@ -189,6 +189,7 @@ export class CustomerRepository extends AbstractResourceRepository<"customer"> {
189
189
  customerId: customer.id,
190
190
  expiresAt: expiresAt.toISOString(),
191
191
  value: token,
192
+ invalidateOlderTokens: request.invalidateOlderTokens || false,
192
193
  };
193
194
  }
194
195
 
@@ -249,6 +250,7 @@ export class CustomerRepository extends AbstractResourceRepository<"customer"> {
249
250
  customerId: customer.id,
250
251
  expiresAt: expiresAt.toISOString(),
251
252
  value: token,
253
+ invalidateOlderTokens: false,
252
254
  };
253
255
  }
254
256
 
@@ -0,0 +1,50 @@
1
+ import type {
2
+ DiscountGroup,
3
+ DiscountGroupSetDescriptionAction,
4
+ DiscountGroupSetKeyAction,
5
+ DiscountGroupSetNameAction,
6
+ DiscountGroupSetSortOrderAction,
7
+ DiscountGroupUpdateAction,
8
+ } from "@commercetools/platform-sdk";
9
+ import type { Writable } from "~src/types";
10
+ import type { UpdateHandlerInterface } from "../abstract";
11
+ import { AbstractUpdateHandler, type RepositoryContext } from "../abstract";
12
+ import { createCustomFields } from "../helpers";
13
+
14
+ export class DiscountGroupUpdateHandler
15
+ extends AbstractUpdateHandler
16
+ implements
17
+ Partial<UpdateHandlerInterface<DiscountGroup, DiscountGroupUpdateAction>>
18
+ {
19
+ setDescription(
20
+ context: RepositoryContext,
21
+ resource: Writable<DiscountGroup>,
22
+ { description }: DiscountGroupSetDescriptionAction,
23
+ ) {
24
+ resource.description = description;
25
+ }
26
+
27
+ setKey(
28
+ context: RepositoryContext,
29
+ resource: Writable<DiscountGroup>,
30
+ { key }: DiscountGroupSetKeyAction,
31
+ ) {
32
+ resource.key = key;
33
+ }
34
+
35
+ setName(
36
+ context: RepositoryContext,
37
+ resource: Writable<DiscountGroup>,
38
+ { name }: DiscountGroupSetNameAction,
39
+ ) {
40
+ resource.name = name;
41
+ }
42
+
43
+ setSortOrder(
44
+ context: RepositoryContext,
45
+ resource: Writable<DiscountGroup>,
46
+ { sortOrder }: DiscountGroupSetSortOrderAction,
47
+ ) {
48
+ resource.sortOrder = sortOrder;
49
+ }
50
+ }
@@ -0,0 +1,29 @@
1
+ import type {
2
+ DiscountGroup,
3
+ DiscountGroupDraft,
4
+ } from "@commercetools/platform-sdk";
5
+ import type { Config } from "~src/config";
6
+ import { getBaseResourceProperties } from "~src/helpers";
7
+ import {
8
+ AbstractResourceRepository,
9
+ type RepositoryContext,
10
+ } from "../abstract";
11
+ import { DiscountGroupUpdateHandler } from "./actions";
12
+
13
+ export class DiscountGroupRepository extends AbstractResourceRepository<"discount-group"> {
14
+ constructor(config: Config) {
15
+ super("discount-group", config);
16
+ this.actions = new DiscountGroupUpdateHandler(config.storage);
17
+ }
18
+
19
+ create(context: RepositoryContext, draft: DiscountGroupDraft): DiscountGroup {
20
+ const resource: DiscountGroup = {
21
+ ...getBaseResourceProperties(),
22
+ description: draft.description,
23
+ name: draft.name,
24
+ key: draft.key,
25
+ sortOrder: draft.sortOrder,
26
+ };
27
+ return this.saveNew(context, resource);
28
+ }
29
+ }
@@ -16,6 +16,7 @@ import { CustomObjectRepository } from "./custom-object";
16
16
  import { CustomerRepository } from "./customer";
17
17
  import { CustomerGroupRepository } from "./customer-group";
18
18
  import { DiscountCodeRepository } from "./discount-code";
19
+ import { DiscountGroupRepository } from "./discount-group";
19
20
  import { ExtensionRepository } from "./extension";
20
21
  import { InventoryEntryRepository } from "./inventory-entry";
21
22
  import { MyCustomerRepository } from "./my-customer";
@@ -32,6 +33,8 @@ import { ProjectRepository } from "./project";
32
33
  import { QuoteRepository } from "./quote";
33
34
  import { QuoteRequestRepository } from "./quote-request";
34
35
  import { StagedQuoteRepository } from "./quote-staged";
36
+ import { RecurrencePolicyRepository } from "./recurrence-policy";
37
+ import { RecurringOrderRepository } from "./recurring-order";
35
38
  import { ReviewRepository } from "./review";
36
39
  import { ShippingMethodRepository } from "./shipping-method";
37
40
  import { ShoppingListRepository } from "./shopping-list";
@@ -61,6 +64,7 @@ export const createRepositories = (config: Config) => ({
61
64
  channel: new ChannelRepository(config),
62
65
  "customer-group": new CustomerGroupRepository(config),
63
66
  "discount-code": new DiscountCodeRepository(config),
67
+ "discount-group": new DiscountGroupRepository(config),
64
68
  extension: new ExtensionRepository(config),
65
69
  "inventory-entry": new InventoryEntryRepository(config),
66
70
  "key-value-document": new CustomObjectRepository(config),
@@ -79,6 +83,8 @@ export const createRepositories = (config: Config) => ({
79
83
  "product-selection": new ProductSelectionRepository(config),
80
84
  "product-tailoring": new ProductTailoringRepository(config),
81
85
  project: new ProjectRepository(config),
86
+ "recurring-order": new RecurringOrderRepository(config),
87
+ "recurrence-policy": new RecurrencePolicyRepository(config),
82
88
  review: new ReviewRepository(config),
83
89
  quote: new QuoteRepository(config),
84
90
  "quote-request": new QuoteRequestRepository(config),
@@ -35,6 +35,7 @@ describe("Order repository", () => {
35
35
  } as unknown as LineItem,
36
36
  ],
37
37
  customLineItems: [],
38
+ priceRoundingMode: "HalfEven",
38
39
  totalPrice: {
39
40
  type: "centPrecision",
40
41
  currencyCode: "EUR",
@@ -293,132 +294,132 @@ describe("Order repository", () => {
293
294
  });
294
295
  /*
295
296
  test('import non exiting product', async () => {
296
- const draft: OrderImportDraft = {
297
- orderNumber: '100000001',
298
- totalPrice: {
299
- centAmount: 1000,
300
- currencyCode: 'EUR',
301
- },
302
- customLineItems: [],
303
- lineItems: [
304
- {
305
- id: '15fc56ba-a74e-4cf8-b4b0-bada5c101541',
306
- productId: 'PRODUCTID',
307
- name: {
308
- 'en-US': 'The product',
309
- },
310
- productType: {
311
- typeId: 'product-type',
312
- id: '109caecb-abe6-4900-ab03-7af5af985ff3',
313
- // @ts-ignore
314
- version: 1,
315
- },
316
- variant: {
317
- id: 1,
318
- sku: 'MYSKU',
319
- key: 'MYKEY',
320
- prices: [
321
- {
322
- value: {
323
- // @ts-ignore
324
- type: 'centPrecision',
325
- currencyCode: 'EUR',
326
- centAmount: 14900,
327
- fractionDigits: 2,
328
- },
329
- id: '87943be5-c7e6-44eb-b867-f127f94ccfe7',
330
- country: 'NL',
331
- // channel: {
332
- // typeId: 'channel',
333
- // id: '411485eb-7875-46f4-8d40-1db9e61374ed',
334
- // },
335
- // custom: {
336
- // type: {
337
- // typeId: 'type',
338
- // id: '55071385-b6e4-44c4-8c4b-6f2ec0f23649',
339
- // },
340
- // fields: {},
341
- // },
342
- },
343
- ],
344
- images: [],
345
- attributes: [],
346
- assets: [],
347
- },
348
- price: {
349
- value: {
350
- // @ts-ignore
351
- type: 'centPrecision',
352
- currencyCode: 'EUR',
353
- centAmount: 14900,
354
- fractionDigits: 2,
355
- },
356
- id: '87943be5-c7e6-44eb-b867-f127f94ccfe7',
357
- country: 'NL',
358
- // channel: {
359
- // typeId: 'channel',
360
- // id: '411485eb-7875-46f4-8d40-1db9e61374ed',
361
- // },
362
- // custom: {
363
- // type: {
364
- // typeId: 'type',
365
- // id: '55071385-b6e4-44c4-8c4b-6f2ec0f23649',
366
- // },
367
- // fields: {},
368
- // },
369
- },
370
- quantity: 3,
371
- discountedPricePerQuantity: [],
372
- // distributionChannel: {
373
- // typeId: 'channel',
374
- // id: '411485eb-7875-46f4-8d40-1db9e61374ed',
375
- // },
376
- taxRate: {
377
- name: '21% BTW',
378
- amount: 0.21,
379
- includedInPrice: true,
380
- country: 'NL',
381
- id: 'Z0wLUuYw',
382
- subRates: [],
383
- },
384
- addedAt: '2020-12-08T09:10:27.085Z',
385
- lastModifiedAt: '2020-12-08T09:10:27.085Z',
386
- // state: [
387
- // {
388
- // quantity: 3,
389
- // state: {
390
- // typeId: 'state',
391
- // id: 'f1d9531d-41f0-46a7-82f2-c4b0748aa9f5',
392
- // },
393
- // },
394
- // ],
395
- priceMode: 'Platform',
396
- totalPrice: {
397
- type: 'centPrecision',
398
- currencyCode: 'EUR',
399
- centAmount: 44700,
400
- fractionDigits: 2,
401
- },
402
- taxedPrice: {
403
- totalNet: {
404
- type: 'centPrecision',
405
- currencyCode: 'EUR',
406
- centAmount: 36942,
407
- fractionDigits: 2,
408
- },
409
- totalGross: {
410
- type: 'centPrecision',
411
- currencyCode: 'EUR',
412
- centAmount: 44700,
413
- fractionDigits: 2,
414
- },
415
- },
416
- lineItemMode: 'Standard',
417
- },
418
- ],
419
- }
297
+ const draft: OrderImportDraft = {
298
+ orderNumber: '100000001',
299
+ totalPrice: {
300
+ centAmount: 1000,
301
+ currencyCode: 'EUR',
302
+ },
303
+ customLineItems: [],
304
+ lineItems: [
305
+ {
306
+ id: '15fc56ba-a74e-4cf8-b4b0-bada5c101541',
307
+ productId: 'PRODUCTID',
308
+ name: {
309
+ 'en-US': 'The product',
310
+ },
311
+ productType: {
312
+ typeId: 'product-type',
313
+ id: '109caecb-abe6-4900-ab03-7af5af985ff3',
314
+ // @ts-ignore
315
+ version: 1,
316
+ },
317
+ variant: {
318
+ id: 1,
319
+ sku: 'MYSKU',
320
+ key: 'MYKEY',
321
+ prices: [
322
+ {
323
+ value: {
324
+ // @ts-ignore
325
+ type: 'centPrecision',
326
+ currencyCode: 'EUR',
327
+ centAmount: 14900,
328
+ fractionDigits: 2,
329
+ },
330
+ id: '87943be5-c7e6-44eb-b867-f127f94ccfe7',
331
+ country: 'NL',
332
+ // channel: {
333
+ // typeId: 'channel',
334
+ // id: '411485eb-7875-46f4-8d40-1db9e61374ed',
335
+ // },
336
+ // custom: {
337
+ // type: {
338
+ // typeId: 'type',
339
+ // id: '55071385-b6e4-44c4-8c4b-6f2ec0f23649',
340
+ // },
341
+ // fields: {},
342
+ // },
343
+ },
344
+ ],
345
+ images: [],
346
+ attributes: [],
347
+ assets: [],
348
+ },
349
+ price: {
350
+ value: {
351
+ // @ts-ignore
352
+ type: 'centPrecision',
353
+ currencyCode: 'EUR',
354
+ centAmount: 14900,
355
+ fractionDigits: 2,
356
+ },
357
+ id: '87943be5-c7e6-44eb-b867-f127f94ccfe7',
358
+ country: 'NL',
359
+ // channel: {
360
+ // typeId: 'channel',
361
+ // id: '411485eb-7875-46f4-8d40-1db9e61374ed',
362
+ // },
363
+ // custom: {
364
+ // type: {
365
+ // typeId: 'type',
366
+ // id: '55071385-b6e4-44c4-8c4b-6f2ec0f23649',
367
+ // },
368
+ // fields: {},
369
+ // },
370
+ },
371
+ quantity: 3,
372
+ discountedPricePerQuantity: [],
373
+ // distributionChannel: {
374
+ // typeId: 'channel',
375
+ // id: '411485eb-7875-46f4-8d40-1db9e61374ed',
376
+ // },
377
+ taxRate: {
378
+ name: '21% BTW',
379
+ amount: 0.21,
380
+ includedInPrice: true,
381
+ country: 'NL',
382
+ id: 'Z0wLUuYw',
383
+ subRates: [],
384
+ },
385
+ addedAt: '2020-12-08T09:10:27.085Z',
386
+ lastModifiedAt: '2020-12-08T09:10:27.085Z',
387
+ // state: [
388
+ // {
389
+ // quantity: 3,
390
+ // state: {
391
+ // typeId: 'state',
392
+ // id: 'f1d9531d-41f0-46a7-82f2-c4b0748aa9f5',
393
+ // },
394
+ // },
395
+ // ],
396
+ priceMode: 'Platform',
397
+ totalPrice: {
398
+ type: 'centPrecision',
399
+ currencyCode: 'EUR',
400
+ centAmount: 44700,
401
+ fractionDigits: 2,
402
+ },
403
+ taxedPrice: {
404
+ totalNet: {
405
+ type: 'centPrecision',
406
+ currencyCode: 'EUR',
407
+ centAmount: 36942,
408
+ fractionDigits: 2,
409
+ },
410
+ totalGross: {
411
+ type: 'centPrecision',
412
+ currencyCode: 'EUR',
413
+ centAmount: 44700,
414
+ fractionDigits: 2,
415
+ },
416
+ },
417
+ lineItemMode: 'Standard',
418
+ },
419
+ ],
420
+ }
420
421
 
421
- repository.import('dummy', draft)
422
+ repository.import('dummy', draft)
422
423
  })
423
424
  */
424
425
  });
@@ -13,9 +13,14 @@ import type {
13
13
  PaymentSetCustomerAction,
14
14
  PaymentSetInterfaceIdAction,
15
15
  PaymentSetKeyAction,
16
+ PaymentSetMethodInfoAction,
17
+ PaymentSetMethodInfoCustomFieldAction,
18
+ PaymentSetMethodInfoCustomTypeAction,
19
+ PaymentSetMethodInfoInterfaceAccountAction,
16
20
  PaymentSetMethodInfoInterfaceAction,
17
21
  PaymentSetMethodInfoMethodAction,
18
22
  PaymentSetMethodInfoNameAction,
23
+ PaymentSetMethodInfoTokenAction,
19
24
  PaymentSetStatusInterfaceCodeAction,
20
25
  PaymentSetStatusInterfaceTextAction,
21
26
  PaymentSetTransactionCustomFieldAction,
@@ -299,4 +304,86 @@ export class PaymentUpdateHandler
299
304
  obj: stateObj,
300
305
  };
301
306
  }
307
+
308
+ setMethodInfo(
309
+ context: RepositoryContext,
310
+ resource: Writable<Payment>,
311
+ {
312
+ paymentInterface,
313
+ method,
314
+ name,
315
+ interfaceAccount,
316
+ token,
317
+ }: PaymentSetMethodInfoAction,
318
+ ) {
319
+ if (paymentInterface !== undefined) {
320
+ resource.paymentMethodInfo.paymentInterface = paymentInterface;
321
+ }
322
+ if (method !== undefined) {
323
+ resource.paymentMethodInfo.method = method;
324
+ }
325
+ if (name !== undefined) {
326
+ resource.paymentMethodInfo.name = name;
327
+ }
328
+ if (interfaceAccount !== undefined) {
329
+ resource.paymentMethodInfo.interfaceAccount = interfaceAccount;
330
+ }
331
+ if (token !== undefined) {
332
+ resource.paymentMethodInfo.token = token;
333
+ }
334
+ }
335
+
336
+ setMethodInfoCustomField(
337
+ context: RepositoryContext,
338
+ resource: Writable<Payment>,
339
+ { name, value }: PaymentSetMethodInfoCustomFieldAction,
340
+ ) {
341
+ if (!resource.paymentMethodInfo.custom) {
342
+ throw new Error("PaymentMethodInfo has no custom field");
343
+ }
344
+
345
+ resource.paymentMethodInfo.custom.fields[name] = value;
346
+ }
347
+
348
+ setMethodInfoCustomType(
349
+ context: RepositoryContext,
350
+ resource: Writable<Payment>,
351
+ { type, fields }: PaymentSetMethodInfoCustomTypeAction,
352
+ ) {
353
+ if (!type) {
354
+ resource.paymentMethodInfo.custom = undefined;
355
+ } else {
356
+ const resolvedType = this._storage.getByResourceIdentifier(
357
+ context.projectKey,
358
+ type,
359
+ );
360
+ if (!resolvedType) {
361
+ throw new Error(`Type ${type} not found`);
362
+ }
363
+
364
+ resource.paymentMethodInfo.custom = {
365
+ type: {
366
+ typeId: "type",
367
+ id: resolvedType.id,
368
+ },
369
+ fields: fields ?? {},
370
+ };
371
+ }
372
+ }
373
+
374
+ setMethodInfoInterfaceAccount(
375
+ _context: RepositoryContext,
376
+ resource: Writable<Payment>,
377
+ { interfaceAccount }: PaymentSetMethodInfoInterfaceAccountAction,
378
+ ) {
379
+ resource.paymentMethodInfo.interfaceAccount = interfaceAccount;
380
+ }
381
+
382
+ setMethodInfoToken(
383
+ _context: RepositoryContext,
384
+ resource: Writable<Payment>,
385
+ { token }: PaymentSetMethodInfoTokenAction,
386
+ ) {
387
+ resource.paymentMethodInfo.token = token;
388
+ }
302
389
  }
@@ -26,7 +26,7 @@ export class PaymentRepository extends AbstractResourceRepository<"payment"> {
26
26
  ...getBaseResourceProperties(),
27
27
  key: draft.key,
28
28
  amountPlanned: createCentPrecisionMoney(draft.amountPlanned),
29
- paymentMethodInfo: draft.paymentMethodInfo!,
29
+ paymentMethodInfo: { ...draft.paymentMethodInfo!, custom: undefined },
30
30
  paymentStatus: draft.paymentStatus
31
31
  ? {
32
32
  ...draft.paymentStatus,
@@ -108,6 +108,7 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
108
108
  name: draft.name,
109
109
  slug: draft.slug,
110
110
  description: draft.description,
111
+ attributes: draft.attributes ?? [],
111
112
  categories: categoryReferences,
112
113
  masterVariant: variantFromDraft(
113
114
  context,
@@ -44,6 +44,7 @@ const attributeDefinitionFromAttributeDefinitionDraft = (
44
44
  draft: AttributeDefinitionDraft,
45
45
  ): AttributeDefinition => ({
46
46
  ...draft,
47
+ level: draft.level ?? "Variant",
47
48
  attributeConstraint: draft.attributeConstraint ?? "None",
48
49
  inputHint: draft.inputHint ?? "SingleLine",
49
50
  inputTip:
@@ -40,6 +40,7 @@ export class QuoteRepository extends AbstractResourceRepository<"quote"> {
40
40
  typeId: "staged-quote",
41
41
  id: staged.id,
42
42
  },
43
+ priceRoundingMode: cart.priceRoundingMode,
43
44
  totalPrice: cart.totalPrice,
44
45
  taxedPrice: cart.taxedPrice,
45
46
  taxMode: cart.taxMode,
@@ -30,6 +30,7 @@ describe("QuoteRequest repository", () => {
30
30
  quantity: 1,
31
31
  } as unknown as LineItem,
32
32
  ],
33
+ priceRoundingMode: "HalfEven",
33
34
  customLineItems: [],
34
35
  totalPrice: {
35
36
  type: "centPrecision",
@@ -65,6 +65,7 @@ export class QuoteRequestRepository extends AbstractResourceRepository<"quote-re
65
65
  directDiscounts: cart.directDiscounts,
66
66
  lineItems: cart.lineItems,
67
67
  paymentInfo: cart.paymentInfo,
68
+ priceRoundingMode: cart.priceRoundingMode,
68
69
  quoteRequestState: "Submitted",
69
70
  shippingAddress: cart.shippingAddress,
70
71
  taxCalculationMode: cart.taxCalculationMode,
@@ -0,0 +1,53 @@
1
+ import type {
2
+ RecurrencePolicy,
3
+ RecurrencePolicySetDescriptionAction,
4
+ RecurrencePolicySetKeyAction,
5
+ RecurrencePolicySetNameAction,
6
+ RecurrencePolicySetScheduleAction,
7
+ RecurrencePolicyUpdateAction,
8
+ } from "@commercetools/platform-sdk";
9
+ import type { Writable } from "~src/types";
10
+ import type { UpdateHandlerInterface } from "../abstract";
11
+ import { AbstractUpdateHandler, type RepositoryContext } from "../abstract";
12
+
13
+ export class RecurrencePolicyUpdateHandler
14
+ extends AbstractUpdateHandler
15
+ implements
16
+ Partial<
17
+ UpdateHandlerInterface<RecurrencePolicy, RecurrencePolicyUpdateAction>
18
+ >
19
+ {
20
+ setKey(
21
+ context: RepositoryContext,
22
+ resource: Writable<RecurrencePolicy>,
23
+ { key }: RecurrencePolicySetKeyAction,
24
+ ) {
25
+ if (key) {
26
+ resource.key = key;
27
+ }
28
+ }
29
+
30
+ setDescription(
31
+ context: RepositoryContext,
32
+ resource: Writable<RecurrencePolicy>,
33
+ { description }: RecurrencePolicySetDescriptionAction,
34
+ ) {
35
+ resource.description = description;
36
+ }
37
+
38
+ setName(
39
+ context: RepositoryContext,
40
+ resource: Writable<RecurrencePolicy>,
41
+ { name }: RecurrencePolicySetNameAction,
42
+ ) {
43
+ resource.name = name;
44
+ }
45
+
46
+ setSchedule(
47
+ context: RepositoryContext,
48
+ resource: Writable<RecurrencePolicy>,
49
+ { schedule }: RecurrencePolicySetScheduleAction,
50
+ ) {
51
+ resource.schedule = schedule;
52
+ }
53
+ }