@labdigital/commercetools-mock 2.59.1 → 2.60.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.js +178 -58
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/tax.test.ts +119 -0
- package/src/lib/tax.ts +186 -0
- package/src/repositories/cart/actions.ts +67 -0
- package/src/repositories/cart/helpers.ts +1 -80
- package/src/repositories/cart/index.test.ts +48 -0
- package/src/repositories/cart/index.ts +5 -4
- package/src/repositories/order/index.test.ts +183 -0
- package/src/repositories/order/index.ts +48 -5
- package/src/services/cart.test.ts +211 -0
|
@@ -192,6 +192,106 @@ describe("Order repository", () => {
|
|
|
192
192
|
expect(result.shippingInfo).toEqual(cart.shippingInfo);
|
|
193
193
|
});
|
|
194
194
|
|
|
195
|
+
test("should calculate taxed price when creating order from cart", () => {
|
|
196
|
+
const cart: Cart = {
|
|
197
|
+
...getBaseResourceProperties(),
|
|
198
|
+
id: "cart-with-taxed-items",
|
|
199
|
+
version: 1,
|
|
200
|
+
cartState: "Active",
|
|
201
|
+
lineItems: [
|
|
202
|
+
{
|
|
203
|
+
id: "li-1",
|
|
204
|
+
productId: "product-1",
|
|
205
|
+
variantId: 1,
|
|
206
|
+
quantity: 1,
|
|
207
|
+
name: { en: "Test" },
|
|
208
|
+
variant: {
|
|
209
|
+
id: 1,
|
|
210
|
+
sku: "TEST",
|
|
211
|
+
},
|
|
212
|
+
price: {
|
|
213
|
+
value: {
|
|
214
|
+
type: "centPrecision",
|
|
215
|
+
currencyCode: "EUR",
|
|
216
|
+
centAmount: 1000,
|
|
217
|
+
fractionDigits: 2,
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
totalPrice: {
|
|
221
|
+
type: "centPrecision",
|
|
222
|
+
currencyCode: "EUR",
|
|
223
|
+
centAmount: 1000,
|
|
224
|
+
fractionDigits: 2,
|
|
225
|
+
},
|
|
226
|
+
taxedPrice: {
|
|
227
|
+
totalNet: {
|
|
228
|
+
type: "centPrecision",
|
|
229
|
+
currencyCode: "EUR",
|
|
230
|
+
centAmount: 1000,
|
|
231
|
+
fractionDigits: 2,
|
|
232
|
+
},
|
|
233
|
+
totalGross: {
|
|
234
|
+
type: "centPrecision",
|
|
235
|
+
currencyCode: "EUR",
|
|
236
|
+
centAmount: 1210,
|
|
237
|
+
fractionDigits: 2,
|
|
238
|
+
},
|
|
239
|
+
taxPortions: [
|
|
240
|
+
{
|
|
241
|
+
rate: 0.21,
|
|
242
|
+
amount: {
|
|
243
|
+
type: "centPrecision",
|
|
244
|
+
currencyCode: "EUR",
|
|
245
|
+
centAmount: 210,
|
|
246
|
+
fractionDigits: 2,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
totalTax: {
|
|
251
|
+
type: "centPrecision",
|
|
252
|
+
currencyCode: "EUR",
|
|
253
|
+
centAmount: 210,
|
|
254
|
+
fractionDigits: 2,
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
} as unknown as LineItem,
|
|
258
|
+
],
|
|
259
|
+
customLineItems: [],
|
|
260
|
+
totalPrice: {
|
|
261
|
+
type: "centPrecision",
|
|
262
|
+
currencyCode: "EUR",
|
|
263
|
+
centAmount: 1000,
|
|
264
|
+
fractionDigits: 2,
|
|
265
|
+
},
|
|
266
|
+
priceRoundingMode: "HalfEven",
|
|
267
|
+
refusedGifts: [],
|
|
268
|
+
shippingMode: "Single",
|
|
269
|
+
shipping: [],
|
|
270
|
+
shippingAddress: { country: "NL" },
|
|
271
|
+
taxMode: "Platform",
|
|
272
|
+
taxRoundingMode: "HalfEven",
|
|
273
|
+
taxCalculationMode: "LineItemLevel",
|
|
274
|
+
origin: "Customer",
|
|
275
|
+
itemShippingAddresses: [],
|
|
276
|
+
directDiscounts: [],
|
|
277
|
+
discountCodes: [],
|
|
278
|
+
discountOnTotalPrice: undefined,
|
|
279
|
+
inventoryMode: "None",
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
storage.add("dummy", "cart", cart);
|
|
283
|
+
const ctx = { projectKey: "dummy" };
|
|
284
|
+
const result = repository.create(ctx, {
|
|
285
|
+
cart: { id: cart.id, typeId: "cart" },
|
|
286
|
+
version: cart.version,
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
expect(result.taxedPrice).toBeDefined();
|
|
290
|
+
expect(result.taxedPrice?.totalNet.centAmount).toBe(1000);
|
|
291
|
+
expect(result.taxedPrice?.totalGross.centAmount).toBe(1210);
|
|
292
|
+
expect(result.taxedPrice?.totalTax?.centAmount).toBe(210);
|
|
293
|
+
});
|
|
294
|
+
|
|
195
295
|
test("create order in store", async () => {
|
|
196
296
|
storage.add("dummy", "store", {
|
|
197
297
|
...getBaseResourceProperties(),
|
|
@@ -274,6 +374,89 @@ describe("Order repository", () => {
|
|
|
274
374
|
expect(result.paymentState).toBe("Paid");
|
|
275
375
|
});
|
|
276
376
|
|
|
377
|
+
test("should calculate taxed price when importing order", () => {
|
|
378
|
+
storage.add("dummy", "product", {
|
|
379
|
+
...getBaseResourceProperties(),
|
|
380
|
+
id: "product-import",
|
|
381
|
+
productType: {
|
|
382
|
+
typeId: "product-type",
|
|
383
|
+
id: "product-type-id",
|
|
384
|
+
},
|
|
385
|
+
masterData: {
|
|
386
|
+
current: {
|
|
387
|
+
name: { en: "Imported" },
|
|
388
|
+
slug: { en: "imported" },
|
|
389
|
+
categories: [],
|
|
390
|
+
masterVariant: {
|
|
391
|
+
id: 1,
|
|
392
|
+
sku: "IMPORT-SKU",
|
|
393
|
+
prices: [],
|
|
394
|
+
attributes: [],
|
|
395
|
+
},
|
|
396
|
+
variants: [],
|
|
397
|
+
searchKeywords: {},
|
|
398
|
+
attributes: [],
|
|
399
|
+
},
|
|
400
|
+
staged: {
|
|
401
|
+
name: { en: "Imported" },
|
|
402
|
+
slug: { en: "imported" },
|
|
403
|
+
categories: [],
|
|
404
|
+
masterVariant: {
|
|
405
|
+
id: 1,
|
|
406
|
+
sku: "IMPORT-SKU",
|
|
407
|
+
prices: [],
|
|
408
|
+
attributes: [],
|
|
409
|
+
},
|
|
410
|
+
variants: [],
|
|
411
|
+
searchKeywords: {},
|
|
412
|
+
attributes: [],
|
|
413
|
+
},
|
|
414
|
+
published: false,
|
|
415
|
+
hasStagedChanges: false,
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
const draft: OrderImportDraft = {
|
|
420
|
+
orderNumber: "IMPORT-ORDER-1",
|
|
421
|
+
totalPrice: {
|
|
422
|
+
centAmount: 1000,
|
|
423
|
+
currencyCode: "EUR",
|
|
424
|
+
},
|
|
425
|
+
lineItems: [
|
|
426
|
+
{
|
|
427
|
+
name: { en: "Imported" },
|
|
428
|
+
variant: {
|
|
429
|
+
sku: "IMPORT-SKU",
|
|
430
|
+
},
|
|
431
|
+
price: {
|
|
432
|
+
value: {
|
|
433
|
+
type: "centPrecision",
|
|
434
|
+
currencyCode: "EUR",
|
|
435
|
+
centAmount: 1000,
|
|
436
|
+
fractionDigits: 2,
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
quantity: 1,
|
|
440
|
+
taxRate: {
|
|
441
|
+
name: "Standard VAT",
|
|
442
|
+
amount: 0.21,
|
|
443
|
+
includedInPrice: false,
|
|
444
|
+
country: "NL",
|
|
445
|
+
id: "import-tax-rate",
|
|
446
|
+
subRates: [],
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
],
|
|
450
|
+
customLineItems: [],
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
const result = repository.import({ projectKey: "dummy" }, draft);
|
|
454
|
+
expect(result.taxedPrice).toBeDefined();
|
|
455
|
+
expect(result.taxedPrice?.totalNet.centAmount).toBe(1000);
|
|
456
|
+
expect(result.taxedPrice?.totalGross.centAmount).toBe(1210);
|
|
457
|
+
expect(result.taxedPrice?.totalTax?.centAmount).toBe(210);
|
|
458
|
+
});
|
|
459
|
+
|
|
277
460
|
test("import exiting product", async () => {
|
|
278
461
|
storage.add("dummy", "product", {
|
|
279
462
|
id: "15fc56ba-a74e-4cf8-b4b0-bada5c101541",
|
|
@@ -26,6 +26,7 @@ import { Decimal } from "decimal.js/decimal";
|
|
|
26
26
|
import type { Config } from "~src/config";
|
|
27
27
|
import { CommercetoolsError } from "~src/exceptions";
|
|
28
28
|
import { generateRandomString, getBaseResourceProperties } from "~src/helpers";
|
|
29
|
+
import { calculateTaxTotals, calculateTaxedPriceFromRate } from "~src/lib/tax";
|
|
29
30
|
import {
|
|
30
31
|
createShippingInfoFromMethod,
|
|
31
32
|
getShippingMethodsMatchingCart,
|
|
@@ -75,7 +76,7 @@ export class OrderRepository extends AbstractResourceRepository<"order"> {
|
|
|
75
76
|
throw new Error("Cannot find cart");
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
const resource: Order = {
|
|
79
|
+
const resource: Writable<Order> = {
|
|
79
80
|
...getBaseResourceProperties(),
|
|
80
81
|
anonymousId: cart.anonymousId,
|
|
81
82
|
billingAddress: cart.billingAddress,
|
|
@@ -110,6 +111,16 @@ export class OrderRepository extends AbstractResourceRepository<"order"> {
|
|
|
110
111
|
totalPrice: cart.totalPrice,
|
|
111
112
|
store: cart.store,
|
|
112
113
|
};
|
|
114
|
+
|
|
115
|
+
const { taxedPrice, taxedShippingPrice } = calculateTaxTotals({
|
|
116
|
+
lineItems: cart.lineItems,
|
|
117
|
+
customLineItems: cart.customLineItems,
|
|
118
|
+
shippingInfo: cart.shippingInfo,
|
|
119
|
+
totalPrice: cart.totalPrice,
|
|
120
|
+
});
|
|
121
|
+
resource.taxedPrice = resource.taxedPrice ?? taxedPrice;
|
|
122
|
+
resource.taxedShippingPrice =
|
|
123
|
+
resource.taxedShippingPrice ?? taxedShippingPrice;
|
|
113
124
|
return this.saveNew(context, resource);
|
|
114
125
|
}
|
|
115
126
|
|
|
@@ -194,6 +205,16 @@ export class OrderRepository extends AbstractResourceRepository<"order"> {
|
|
|
194
205
|
});
|
|
195
206
|
}
|
|
196
207
|
|
|
208
|
+
const { taxedPrice, taxedShippingPrice } = calculateTaxTotals({
|
|
209
|
+
lineItems: resource.lineItems,
|
|
210
|
+
customLineItems: resource.customLineItems,
|
|
211
|
+
shippingInfo: resource.shippingInfo,
|
|
212
|
+
totalPrice: resource.totalPrice,
|
|
213
|
+
});
|
|
214
|
+
resource.taxedPrice = resource.taxedPrice ?? taxedPrice;
|
|
215
|
+
resource.taxedShippingPrice =
|
|
216
|
+
resource.taxedShippingPrice ?? taxedShippingPrice;
|
|
217
|
+
|
|
197
218
|
return this.saveNew(context, resource);
|
|
198
219
|
}
|
|
199
220
|
|
|
@@ -238,6 +259,12 @@ export class OrderRepository extends AbstractResourceRepository<"order"> {
|
|
|
238
259
|
throw new Error("No product found");
|
|
239
260
|
}
|
|
240
261
|
|
|
262
|
+
const quantity = draft.quantity ?? 1;
|
|
263
|
+
const totalPrice = createCentPrecisionMoney({
|
|
264
|
+
...draft.price.value,
|
|
265
|
+
centAmount: (draft.price.value.centAmount ?? 0) * quantity,
|
|
266
|
+
});
|
|
267
|
+
|
|
241
268
|
const lineItem: LineItem = {
|
|
242
269
|
...getBaseResourceProperties(),
|
|
243
270
|
custom: createCustomFields(
|
|
@@ -252,12 +279,17 @@ export class OrderRepository extends AbstractResourceRepository<"order"> {
|
|
|
252
279
|
priceMode: "Platform",
|
|
253
280
|
productId: product.id,
|
|
254
281
|
productType: product.productType,
|
|
255
|
-
quantity
|
|
282
|
+
quantity,
|
|
256
283
|
state: draft.state || [],
|
|
257
284
|
taxRate: draft.taxRate,
|
|
285
|
+
taxedPrice: calculateTaxedPriceFromRate(
|
|
286
|
+
totalPrice.centAmount,
|
|
287
|
+
totalPrice.currencyCode,
|
|
288
|
+
draft.taxRate,
|
|
289
|
+
),
|
|
258
290
|
taxedPricePortions: [],
|
|
259
291
|
perMethodTaxRate: [],
|
|
260
|
-
totalPrice
|
|
292
|
+
totalPrice,
|
|
261
293
|
variant: {
|
|
262
294
|
id: variant.id,
|
|
263
295
|
sku: variant.sku,
|
|
@@ -273,6 +305,12 @@ export class OrderRepository extends AbstractResourceRepository<"order"> {
|
|
|
273
305
|
context: RepositoryContext,
|
|
274
306
|
draft: CustomLineItemImportDraft,
|
|
275
307
|
): CustomLineItem {
|
|
308
|
+
const quantity = draft.quantity ?? 1;
|
|
309
|
+
const totalPrice = createCentPrecisionMoney({
|
|
310
|
+
...draft.money,
|
|
311
|
+
centAmount: (draft.money.centAmount ?? 0) * quantity,
|
|
312
|
+
});
|
|
313
|
+
|
|
276
314
|
const lineItem: CustomLineItem = {
|
|
277
315
|
...getBaseResourceProperties(),
|
|
278
316
|
custom: createCustomFields(
|
|
@@ -283,12 +321,17 @@ export class OrderRepository extends AbstractResourceRepository<"order"> {
|
|
|
283
321
|
discountedPricePerQuantity: [],
|
|
284
322
|
money: createTypedMoney(draft.money),
|
|
285
323
|
name: draft.name,
|
|
286
|
-
quantity
|
|
324
|
+
quantity,
|
|
287
325
|
perMethodTaxRate: [],
|
|
288
326
|
priceMode: draft.priceMode ?? "Standard",
|
|
289
327
|
slug: draft.slug,
|
|
290
328
|
state: [],
|
|
291
|
-
totalPrice
|
|
329
|
+
totalPrice,
|
|
330
|
+
taxedPrice: calculateTaxedPriceFromRate(
|
|
331
|
+
totalPrice.centAmount,
|
|
332
|
+
totalPrice.currencyCode,
|
|
333
|
+
draft.taxRate,
|
|
334
|
+
),
|
|
292
335
|
taxedPricePortions: [],
|
|
293
336
|
};
|
|
294
337
|
|
|
@@ -711,6 +711,217 @@ describe("Cart Update Actions", () => {
|
|
|
711
711
|
]);
|
|
712
712
|
});
|
|
713
713
|
|
|
714
|
+
test("setLineItemPrice sets an external price for a line item", async () => {
|
|
715
|
+
const product = await supertest(ctMock.app)
|
|
716
|
+
.post("/dummy/products")
|
|
717
|
+
.send(productDraft)
|
|
718
|
+
.then((x) => x.body);
|
|
719
|
+
|
|
720
|
+
assert(product, "product not created");
|
|
721
|
+
|
|
722
|
+
const baseCartResponse = await supertest(ctMock.app)
|
|
723
|
+
.post("/dummy/carts")
|
|
724
|
+
.send({ currency: "EUR" });
|
|
725
|
+
expect(baseCartResponse.status).toBe(201);
|
|
726
|
+
const baseCart = baseCartResponse.body as Cart;
|
|
727
|
+
|
|
728
|
+
const addLineItemResponse = await supertest(ctMock.app)
|
|
729
|
+
.post(`/dummy/carts/${baseCart.id}`)
|
|
730
|
+
.send({
|
|
731
|
+
version: baseCart.version,
|
|
732
|
+
actions: [
|
|
733
|
+
{
|
|
734
|
+
action: "addLineItem",
|
|
735
|
+
sku: product.masterData.current.masterVariant.sku,
|
|
736
|
+
quantity: 2,
|
|
737
|
+
key: "line-item-key",
|
|
738
|
+
},
|
|
739
|
+
],
|
|
740
|
+
});
|
|
741
|
+
expect(addLineItemResponse.status).toBe(200);
|
|
742
|
+
const cartWithLineItem = addLineItemResponse.body as Cart;
|
|
743
|
+
const lineItem = cartWithLineItem.lineItems[0];
|
|
744
|
+
assert(lineItem, "lineItem not created");
|
|
745
|
+
|
|
746
|
+
const externalPrice: CentPrecisionMoney = {
|
|
747
|
+
type: "centPrecision",
|
|
748
|
+
currencyCode: "EUR",
|
|
749
|
+
centAmount: 2500,
|
|
750
|
+
fractionDigits: 2,
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
const response = await supertest(ctMock.app)
|
|
754
|
+
.post(`/dummy/carts/${cartWithLineItem.id}`)
|
|
755
|
+
.send({
|
|
756
|
+
version: cartWithLineItem.version,
|
|
757
|
+
actions: [
|
|
758
|
+
{
|
|
759
|
+
action: "setLineItemPrice",
|
|
760
|
+
lineItemKey: lineItem.key,
|
|
761
|
+
externalPrice,
|
|
762
|
+
},
|
|
763
|
+
],
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
expect(response.status).toBe(200);
|
|
767
|
+
expect(response.body.version).toBe(cartWithLineItem.version + 1);
|
|
768
|
+
expect(response.body.lineItems).toHaveLength(1);
|
|
769
|
+
|
|
770
|
+
const updatedLineItem = response.body.lineItems[0];
|
|
771
|
+
expect(updatedLineItem.priceMode).toBe("ExternalPrice");
|
|
772
|
+
expect(updatedLineItem.price.value.centAmount).toBe(
|
|
773
|
+
externalPrice.centAmount,
|
|
774
|
+
);
|
|
775
|
+
expect(updatedLineItem.price.value.currencyCode).toBe(
|
|
776
|
+
externalPrice.currencyCode,
|
|
777
|
+
);
|
|
778
|
+
expect(updatedLineItem.totalPrice.centAmount).toBe(
|
|
779
|
+
externalPrice.centAmount * updatedLineItem.quantity,
|
|
780
|
+
);
|
|
781
|
+
expect(response.body.totalPrice.centAmount).toBe(
|
|
782
|
+
externalPrice.centAmount * updatedLineItem.quantity,
|
|
783
|
+
);
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
test("setLineItemPrice fails when the money uses another currency", async () => {
|
|
787
|
+
const product = await supertest(ctMock.app)
|
|
788
|
+
.post("/dummy/products")
|
|
789
|
+
.send(productDraft)
|
|
790
|
+
.then((x) => x.body);
|
|
791
|
+
|
|
792
|
+
assert(product, "product not created");
|
|
793
|
+
|
|
794
|
+
const baseCartResponse = await supertest(ctMock.app)
|
|
795
|
+
.post("/dummy/carts")
|
|
796
|
+
.send({ currency: "EUR" });
|
|
797
|
+
expect(baseCartResponse.status).toBe(201);
|
|
798
|
+
const baseCart = baseCartResponse.body as Cart;
|
|
799
|
+
|
|
800
|
+
const addLineItemResponse = await supertest(ctMock.app)
|
|
801
|
+
.post(`/dummy/carts/${baseCart.id}`)
|
|
802
|
+
.send({
|
|
803
|
+
version: baseCart.version,
|
|
804
|
+
actions: [
|
|
805
|
+
{
|
|
806
|
+
action: "addLineItem",
|
|
807
|
+
sku: product.masterData.current.masterVariant.sku,
|
|
808
|
+
quantity: 1,
|
|
809
|
+
},
|
|
810
|
+
],
|
|
811
|
+
});
|
|
812
|
+
expect(addLineItemResponse.status).toBe(200);
|
|
813
|
+
const cartWithLineItem = addLineItemResponse.body as Cart;
|
|
814
|
+
const lineItem = cartWithLineItem.lineItems[0];
|
|
815
|
+
assert(lineItem, "lineItem not created");
|
|
816
|
+
|
|
817
|
+
const response = await supertest(ctMock.app)
|
|
818
|
+
.post(`/dummy/carts/${cartWithLineItem.id}`)
|
|
819
|
+
.send({
|
|
820
|
+
version: cartWithLineItem.version,
|
|
821
|
+
actions: [
|
|
822
|
+
{
|
|
823
|
+
action: "setLineItemPrice",
|
|
824
|
+
lineItemId: lineItem.id,
|
|
825
|
+
externalPrice: {
|
|
826
|
+
type: "centPrecision",
|
|
827
|
+
currencyCode: "USD",
|
|
828
|
+
centAmount: 5000,
|
|
829
|
+
fractionDigits: 2,
|
|
830
|
+
},
|
|
831
|
+
},
|
|
832
|
+
],
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
expect(response.status).toBe(400);
|
|
836
|
+
expect(response.body.message).toContain("Currency mismatch");
|
|
837
|
+
});
|
|
838
|
+
|
|
839
|
+
test("setLineItemPrice removes external price when no value is provided", async () => {
|
|
840
|
+
const product = await supertest(ctMock.app)
|
|
841
|
+
.post("/dummy/products")
|
|
842
|
+
.send(productDraft)
|
|
843
|
+
.then((x) => x.body);
|
|
844
|
+
|
|
845
|
+
assert(product, "product not created");
|
|
846
|
+
|
|
847
|
+
const baseCartResponse = await supertest(ctMock.app)
|
|
848
|
+
.post("/dummy/carts")
|
|
849
|
+
.send({ currency: "EUR" });
|
|
850
|
+
expect(baseCartResponse.status).toBe(201);
|
|
851
|
+
const baseCart = baseCartResponse.body as Cart;
|
|
852
|
+
|
|
853
|
+
const addLineItemResponse = await supertest(ctMock.app)
|
|
854
|
+
.post(`/dummy/carts/${baseCart.id}`)
|
|
855
|
+
.send({
|
|
856
|
+
version: baseCart.version,
|
|
857
|
+
actions: [
|
|
858
|
+
{
|
|
859
|
+
action: "addLineItem",
|
|
860
|
+
sku: product.masterData.current.masterVariant.sku,
|
|
861
|
+
quantity: 1,
|
|
862
|
+
},
|
|
863
|
+
],
|
|
864
|
+
});
|
|
865
|
+
expect(addLineItemResponse.status).toBe(200);
|
|
866
|
+
const cartWithLineItem = addLineItemResponse.body as Cart;
|
|
867
|
+
const lineItem = cartWithLineItem.lineItems[0];
|
|
868
|
+
assert(lineItem, "lineItem not created");
|
|
869
|
+
|
|
870
|
+
const externalPrice: CentPrecisionMoney = {
|
|
871
|
+
type: "centPrecision",
|
|
872
|
+
currencyCode: "EUR",
|
|
873
|
+
centAmount: 1000,
|
|
874
|
+
fractionDigits: 2,
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
const setExternalPriceResponse = await supertest(ctMock.app)
|
|
878
|
+
.post(`/dummy/carts/${cartWithLineItem.id}`)
|
|
879
|
+
.send({
|
|
880
|
+
version: cartWithLineItem.version,
|
|
881
|
+
actions: [
|
|
882
|
+
{
|
|
883
|
+
action: "setLineItemPrice",
|
|
884
|
+
lineItemId: lineItem.id,
|
|
885
|
+
externalPrice,
|
|
886
|
+
},
|
|
887
|
+
],
|
|
888
|
+
});
|
|
889
|
+
expect(setExternalPriceResponse.status).toBe(200);
|
|
890
|
+
const cartWithExternalPrice = setExternalPriceResponse.body as Cart;
|
|
891
|
+
expect(cartWithExternalPrice.lineItems[0].priceMode).toBe("ExternalPrice");
|
|
892
|
+
|
|
893
|
+
const resetResponse = await supertest(ctMock.app)
|
|
894
|
+
.post(`/dummy/carts/${cartWithExternalPrice.id}`)
|
|
895
|
+
.send({
|
|
896
|
+
version: cartWithExternalPrice.version,
|
|
897
|
+
actions: [
|
|
898
|
+
{
|
|
899
|
+
action: "setLineItemPrice",
|
|
900
|
+
lineItemId: lineItem.id,
|
|
901
|
+
},
|
|
902
|
+
],
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
expect(resetResponse.status).toBe(200);
|
|
906
|
+
expect(resetResponse.body.version).toBe(cartWithExternalPrice.version + 1);
|
|
907
|
+
expect(resetResponse.body.lineItems).toHaveLength(1);
|
|
908
|
+
|
|
909
|
+
const revertedLineItem = resetResponse.body.lineItems[0];
|
|
910
|
+
const expectedCentAmount =
|
|
911
|
+
product.masterData.current.masterVariant.prices?.[0].value.centAmount;
|
|
912
|
+
if (typeof expectedCentAmount !== "number") {
|
|
913
|
+
throw new Error("product price not found");
|
|
914
|
+
}
|
|
915
|
+
expect(revertedLineItem.priceMode).toBe("Platform");
|
|
916
|
+
expect(revertedLineItem.price.value.centAmount).toBe(expectedCentAmount);
|
|
917
|
+
expect(revertedLineItem.totalPrice.centAmount).toBe(
|
|
918
|
+
expectedCentAmount * revertedLineItem.quantity,
|
|
919
|
+
);
|
|
920
|
+
expect(resetResponse.body.totalPrice.centAmount).toBe(
|
|
921
|
+
expectedCentAmount * revertedLineItem.quantity,
|
|
922
|
+
);
|
|
923
|
+
});
|
|
924
|
+
|
|
714
925
|
test("setLineItemCustomField", async () => {
|
|
715
926
|
const product = await supertest(ctMock.app)
|
|
716
927
|
.post("/dummy/products")
|