@labdigital/commercetools-mock 3.0.0-beta.3 → 3.0.0-beta.4

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.
@@ -720,6 +720,82 @@ describe("createShippingInfo", () => {
720
720
  expect(result.taxedPrice!.totalNet.centAmount).toBe(995);
721
721
  });
722
722
 
723
+ test("should use external tax rate when cart taxMode is External", async () => {
724
+ await storage.add("dummy", "shipping-method", {
725
+ ...getBaseResourceProperties(),
726
+ id: "external-tax-shipping-id",
727
+ name: "Standard Shipping",
728
+ taxCategory: {
729
+ typeId: "tax-category",
730
+ id: "shipping-tax-category-id",
731
+ },
732
+ zoneRates: [
733
+ {
734
+ zone: {
735
+ typeId: "zone",
736
+ id: "test-zone-id",
737
+ obj: {
738
+ ...getBaseResourceProperties(),
739
+ id: "test-zone-id",
740
+ name: "Test Zone",
741
+ locations: [{ country: "NL" }],
742
+ },
743
+ },
744
+ shippingRates: [
745
+ {
746
+ price: {
747
+ currencyCode: "EUR",
748
+ centAmount: 1000,
749
+ type: "centPrecision",
750
+ fractionDigits: 2,
751
+ },
752
+ tiers: [],
753
+ },
754
+ ],
755
+ },
756
+ ],
757
+ active: true,
758
+ isDefault: false,
759
+ });
760
+
761
+ const cart: any = {
762
+ ...getBaseResourceProperties(),
763
+ id: "external-tax-cart-id",
764
+ version: 1,
765
+ cartState: "Active",
766
+ taxMode: "External",
767
+ totalPrice: {
768
+ currencyCode: "EUR",
769
+ centAmount: 3000,
770
+ type: "centPrecision",
771
+ fractionDigits: 2,
772
+ },
773
+ shippingAddress: { country: "NL" },
774
+ taxRoundingMode: "HalfEven",
775
+ };
776
+
777
+ const context = { projectKey: "dummy", storeKey: "testStore" };
778
+
779
+ const result = await repository.createShippingInfo(
780
+ context,
781
+ cart,
782
+ { typeId: "shipping-method", id: "external-tax-shipping-id" },
783
+ {
784
+ name: "External VAT",
785
+ amount: 0.1,
786
+ includedInPrice: false,
787
+ country: "NL",
788
+ },
789
+ );
790
+
791
+ expect(result.price.centAmount).toBe(1000);
792
+ expect(result.taxRate?.name).toBe("External VAT");
793
+ expect(result.taxRate?.amount).toBe(0.1);
794
+ expect(result.taxRate?.country).toBe("NL");
795
+ expect(result.taxedPrice!.totalNet.centAmount).toBe(1000);
796
+ expect(result.taxedPrice!.totalGross.centAmount).toBe(1100);
797
+ });
798
+
723
799
  test("create cart with discount code", async () => {
724
800
  const code = await storage.add("dummy", "discount-code", {
725
801
  ...getBaseResourceProperties(),
@@ -3,6 +3,7 @@ import type {
3
3
  Cart,
4
4
  CartDraft,
5
5
  DiscountCodeInfo,
6
+ ExternalTaxRateDraft,
6
7
  GeneralError,
7
8
  InvalidOperationError,
8
9
  LineItem,
@@ -15,7 +16,11 @@ import { v4 as uuidv4 } from "uuid";
15
16
  import type { Config } from "#src/config.ts";
16
17
  import { CommercetoolsError } from "#src/exceptions.ts";
17
18
  import { getBaseResourceProperties } from "#src/helpers.ts";
18
- import { calculateTaxTotals } from "#src/lib/tax.ts";
19
+ import {
20
+ calculateTaxedPriceFromRate,
21
+ calculateTaxTotals,
22
+ taxRateFromExternalDraft,
23
+ } from "#src/lib/tax.ts";
19
24
  import { CartDraftSchema } from "#src/schemas/generated/cart.ts";
20
25
  import {
21
26
  createShippingInfoFromMethod,
@@ -76,6 +81,9 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
76
81
  );
77
82
  }
78
83
 
84
+ const taxMode = draft.taxMode ?? "Platform";
85
+ const taxRoundingMode = draft.taxRoundingMode ?? "HalfEven";
86
+
79
87
  const lineItems = draft.lineItems
80
88
  ? await Promise.all(
81
89
  draft.lineItems.map((draftLineItem) =>
@@ -84,6 +92,8 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
84
92
  draftLineItem,
85
93
  draft.currency,
86
94
  draft.country,
95
+ taxMode,
96
+ taxRoundingMode,
87
97
  ),
88
98
  ),
89
99
  )
@@ -97,6 +107,8 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
97
107
  draftCustomLineItem,
98
108
  this._storage,
99
109
  draft.shippingAddress?.country ?? draft.country,
110
+ taxMode,
111
+ taxRoundingMode,
100
112
  ),
101
113
  ),
102
114
  )
@@ -145,8 +157,8 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
145
157
  locale: draft.locale,
146
158
  priceRoundingMode: draft.priceRoundingMode ?? "HalfEven",
147
159
  taxCalculationMode: draft.taxCalculationMode ?? "LineItemLevel",
148
- taxMode: draft.taxMode ?? "Platform",
149
- taxRoundingMode: draft.taxRoundingMode ?? "HalfEven",
160
+ taxMode,
161
+ taxRoundingMode,
150
162
  totalPrice: {
151
163
  type: "centPrecision",
152
164
  centAmount: 0,
@@ -184,6 +196,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
184
196
  context,
185
197
  resource,
186
198
  draft.shippingMethod,
199
+ draft.externalTaxRateForShippingMethod ?? undefined,
187
200
  );
188
201
  }
189
202
 
@@ -211,6 +224,8 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
211
224
  draftLineItem: LineItemDraft,
212
225
  currency: string,
213
226
  country: string | undefined,
227
+ taxMode: Cart["taxMode"] = "Platform",
228
+ roundingMode: Cart["taxRoundingMode"] = "HalfEven",
214
229
  ): Promise<LineItem> => {
215
230
  const { productId, quantity, variantId, sku } = draftLineItem;
216
231
 
@@ -277,6 +292,19 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
277
292
  centAmount: calculateMoneyTotalCentAmount(price.value, quant),
278
293
  });
279
294
 
295
+ const taxRate =
296
+ taxMode === "External" && draftLineItem.externalTaxRate
297
+ ? taxRateFromExternalDraft(draftLineItem.externalTaxRate)
298
+ : undefined;
299
+ const taxedPrice = taxRate
300
+ ? calculateTaxedPriceFromRate(
301
+ totalPrice.centAmount,
302
+ totalPrice.currencyCode,
303
+ taxRate,
304
+ roundingMode,
305
+ )
306
+ : undefined;
307
+
280
308
  return {
281
309
  id: uuidv4(),
282
310
  productId: product.id,
@@ -287,6 +315,8 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
287
315
  variant,
288
316
  price: price,
289
317
  totalPrice,
318
+ taxRate,
319
+ taxedPrice,
290
320
  taxedPricePortions: [],
291
321
  perMethodTaxRate: [],
292
322
  quantity: quant,
@@ -306,11 +336,13 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
306
336
  context: RepositoryContext,
307
337
  resource: Writable<Cart>,
308
338
  shippingMethodRef: NonNullable<CartDraft["shippingMethod"]>,
339
+ externalTaxRate?: ExternalTaxRateDraft,
309
340
  ): Promise<NonNullable<Cart["shippingInfo"]>> {
310
- if (resource.taxMode === "External") {
341
+ if (resource.taxMode === "External" && !externalTaxRate) {
311
342
  throw new CommercetoolsError<InvalidOperationError>({
312
343
  code: "InvalidOperation",
313
- message: "External tax rate is not supported",
344
+ message:
345
+ "An external tax rate is required for a cart with External tax mode.",
314
346
  });
315
347
  }
316
348
 
@@ -355,6 +387,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
355
387
  this._storage,
356
388
  resource,
357
389
  method,
390
+ resource.taxMode === "External" ? externalTaxRate : undefined,
358
391
  );
359
392
  }
360
393
  }