@lookiero/checkout 14.7.0 → 14.8.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 (68) hide show
  1. package/cypress/support/interceptViewPricingByCheckoutId.ts +3 -3
  2. package/dist/src/ExpoRoot.js +2 -3
  3. package/dist/src/infrastructure/delivery/bootstrap.mock.js +2 -2
  4. package/dist/src/infrastructure/projection/pricing/httpPricingByCheckoutIdView.js +2 -3
  5. package/dist/src/infrastructure/projection/pricing/pricing.mock.d.ts +3 -9
  6. package/dist/src/infrastructure/projection/pricing/pricing.mock.js +11 -50
  7. package/dist/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.d.ts +2 -2
  8. package/dist/src/infrastructure/tracking/useTrackCheckout.d.ts +2 -2
  9. package/dist/src/infrastructure/tracking/useTrackCheckout.js +3 -3
  10. package/dist/src/infrastructure/ui/components/atoms/price/Price.d.ts +7 -2
  11. package/dist/src/infrastructure/ui/components/atoms/price/Price.js +7 -7
  12. package/dist/src/infrastructure/ui/views/checkout/Checkout.js +2 -2
  13. package/dist/src/infrastructure/ui/views/item/components/productVariantDescription/ProductVariantDescription.js +1 -1
  14. package/dist/src/infrastructure/ui/views/item/components/productVariantSlider/ProductVariantSlider.js +2 -1
  15. package/dist/src/infrastructure/ui/views/item/components/productVariantSlider/components/aspectRatioView/AspectRatioView.d.ts +15 -0
  16. package/dist/src/infrastructure/ui/views/item/components/productVariantSlider/components/aspectRatioView/AspectRatioView.js +16 -0
  17. package/dist/src/infrastructure/ui/views/return/components/price/Price.d.ts +7 -2
  18. package/dist/src/infrastructure/ui/views/return/components/price/Price.js +7 -7
  19. package/dist/src/infrastructure/ui/views/return/components/productVariantPreview/ProductVariantPreview.js +1 -1
  20. package/dist/src/infrastructure/ui/views/shared/components/productVariant/ProductVariant.js +1 -1
  21. package/dist/src/infrastructure/ui/views/summary/Summary.js +3 -3
  22. package/dist/src/infrastructure/ui/views/summary/components/collapsiblePricing/CollapsiblePricing.d.ts +2 -5
  23. package/dist/src/infrastructure/ui/views/summary/components/collapsiblePricing/CollapsiblePricing.js +4 -4
  24. package/dist/src/infrastructure/ui/views/summary/components/pricing/Pricing.d.ts +2 -5
  25. package/dist/src/infrastructure/ui/views/summary/components/pricing/Pricing.js +16 -18
  26. package/dist/src/projection/customer/customer.d.ts +0 -1
  27. package/dist/src/projection/pricing/pricing.d.ts +6 -24
  28. package/dist/src/projection/pricing/pricing.js +1 -1
  29. package/dist/src/projection/pricing/viewPricingByCheckoutId.d.ts +2 -2
  30. package/dist/src/version.d.ts +2 -2
  31. package/dist/src/version.js +2 -2
  32. package/package.json +1 -1
  33. package/src/ExpoRoot.tsx +2 -3
  34. package/src/infrastructure/delivery/bootstrap.mock.ts +2 -2
  35. package/src/infrastructure/projection/pricing/httpPricingByCheckoutIdView.test.ts +3 -7
  36. package/src/infrastructure/projection/pricing/httpPricingByCheckoutIdView.ts +3 -8
  37. package/src/infrastructure/projection/pricing/pricing.mock.ts +13 -61
  38. package/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.test.ts +3 -3
  39. package/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.ts +2 -2
  40. package/src/infrastructure/tracking/useTrackCheckout.test.tsx +9 -9
  41. package/src/infrastructure/tracking/useTrackCheckout.ts +5 -5
  42. package/src/infrastructure/ui/components/atoms/price/Price.test.tsx +22 -4
  43. package/src/infrastructure/ui/components/atoms/price/Price.tsx +14 -9
  44. package/src/infrastructure/ui/hooks/useCheckoutFlow.test.tsx +2 -2
  45. package/src/infrastructure/ui/views/checkout/Checkout.test.tsx +4 -10
  46. package/src/infrastructure/ui/views/checkout/Checkout.tsx +2 -7
  47. package/src/infrastructure/ui/views/item/components/productVariantDescription/ProductVariantDescription.tsx +1 -1
  48. package/src/infrastructure/ui/views/item/components/productVariantSlider/ProductVariantSlider.tsx +1 -1
  49. package/src/infrastructure/ui/views/item/components/productVariantSlider/__snapshots__/ProductVariantSlider.test.tsx.snap +198 -192
  50. package/src/infrastructure/ui/views/item/components/productVariantSlider/components/aspectRatioView/AspectRatioView.tsx +46 -0
  51. package/src/infrastructure/ui/views/item/views/productVariant/__snapshots__/ProductVariant.test.tsx.snap +594 -576
  52. package/src/infrastructure/ui/views/return/components/price/Price.test.tsx +22 -4
  53. package/src/infrastructure/ui/views/return/components/price/Price.tsx +14 -9
  54. package/src/infrastructure/ui/views/return/components/productVariantPreview/ProductVariantPreview.tsx +6 -1
  55. package/src/infrastructure/ui/views/shared/components/productVariant/ProductVariant.tsx +6 -1
  56. package/src/infrastructure/ui/views/summary/Summary.test.tsx +4 -10
  57. package/src/infrastructure/ui/views/summary/Summary.tsx +1 -5
  58. package/src/infrastructure/ui/views/summary/components/collapsiblePricing/CollapsiblePricing.test.tsx +10 -24
  59. package/src/infrastructure/ui/views/summary/components/collapsiblePricing/CollapsiblePricing.tsx +5 -15
  60. package/src/infrastructure/ui/views/summary/components/collapsiblePricing/__snapshots__/CollapsiblePricing.test.tsx.snap +2 -2
  61. package/src/infrastructure/ui/views/summary/components/pricing/Pricing.tsx +42 -38
  62. package/src/projection/customer/customer.ts +0 -1
  63. package/src/projection/pricing/pricing.ts +6 -26
  64. package/src/projection/pricing/viewPricingByCheckoutId.test.ts +4 -5
  65. package/src/projection/pricing/viewPricingByCheckoutId.ts +2 -2
  66. package/dist/src/infrastructure/projection/pricing/pricing.d.ts +0 -18
  67. package/dist/src/infrastructure/projection/pricing/pricing.js +0 -12
  68. package/src/infrastructure/projection/pricing/pricing.ts +0 -32
@@ -20,19 +20,31 @@ const discountedPrice: PriceProjection = {
20
20
 
21
21
  describe("Price atom", () => {
22
22
  it("matches the snapshot for a non-discounted price", async () => {
23
- const { toJSON } = render(<Price price={price} />);
23
+ const { toJSON } = render(<Price amount={price.amount} currency={price.currency} />);
24
24
 
25
25
  expect(toJSON()).toMatchSnapshot("non-discounted price");
26
26
  });
27
27
 
28
28
  it("matches the snapshot for a discounted price", async () => {
29
- const { toJSON } = render(<Price price={discountedPrice} />);
29
+ const { toJSON } = render(
30
+ <Price
31
+ amount={discountedPrice.amount}
32
+ currency={discountedPrice.currency}
33
+ discountedPrice={discountedPrice.discountedPrice}
34
+ />,
35
+ );
30
36
 
31
37
  expect(toJSON()).toMatchSnapshot("discounted price");
32
38
  });
33
39
 
34
40
  it("renders the non-discounted price text", async () => {
35
- const { findByTestId } = render(<Price price={discountedPrice} />);
41
+ const { findByTestId } = render(
42
+ <Price
43
+ amount={discountedPrice.amount}
44
+ currency={discountedPrice.currency}
45
+ discountedPrice={discountedPrice.discountedPrice}
46
+ />,
47
+ );
36
48
 
37
49
  const priceText = await findByTestId("price-text");
38
50
 
@@ -40,7 +52,13 @@ describe("Price atom", () => {
40
52
  });
41
53
 
42
54
  it("renders the discounted price text", async () => {
43
- const { findByTestId } = render(<Price price={discountedPrice} />);
55
+ const { findByTestId } = render(
56
+ <Price
57
+ amount={discountedPrice.amount}
58
+ currency={discountedPrice.currency}
59
+ discountedPrice={discountedPrice.discountedPrice}
60
+ />,
61
+ );
44
62
 
45
63
  const discountedPriceText = await findByTestId("discounted-price-text");
46
64
 
@@ -1,28 +1,33 @@
1
1
  import React, { FC, useMemo } from "react";
2
2
  import { View } from "react-native";
3
3
  import { useI18nNumber } from "@lookiero/i18n-react";
4
+ import { Currency } from "@lookiero/sty-psp-locale";
4
5
  import { Text } from "@lookiero/sty-psp-ui";
5
- import { PriceProjection } from "../../../../../../projection/price/price";
6
6
  import { DOMAIN } from "../../../../i18n/i18n";
7
7
  import { style as priceStyle } from "./Price.style";
8
8
 
9
9
  interface PriceProps {
10
- readonly price: PriceProjection;
10
+ readonly amount: number;
11
+ readonly currency: Currency;
12
+ readonly discountedPrice?: {
13
+ readonly amount: number;
14
+ readonly percentage: number;
15
+ };
11
16
  readonly withPercentage?: boolean;
12
17
  }
13
- const Price: FC<PriceProps> = ({ price, withPercentage = false }) => {
14
- const isDiscounted = price.discountedPrice && price.discountedPrice.percentage > 0;
18
+ const Price: FC<PriceProps> = ({ amount, currency, discountedPrice, withPercentage = false }) => {
19
+ const isDiscounted = discountedPrice && discountedPrice.percentage > 0;
15
20
  const productPrice = useI18nNumber({
16
21
  domain: DOMAIN,
17
- value: price.amount / 100,
22
+ value: amount / 100,
18
23
  style: "currency",
19
- currency: price.currency,
24
+ currency,
20
25
  });
21
26
  const productDiscountedPrice = useI18nNumber({
22
27
  domain: DOMAIN,
23
- value: (price.discountedPrice?.amount || 0) / 100,
28
+ value: (discountedPrice?.amount || 0) / 100,
24
29
  style: "currency",
25
- currency: price.currency,
30
+ currency,
26
31
  });
27
32
 
28
33
  const priceValue = isDiscounted ? productDiscountedPrice : productPrice;
@@ -42,7 +47,7 @@ const Price: FC<PriceProps> = ({ price, withPercentage = false }) => {
42
47
  </Text>
43
48
  {isDiscounted && withPercentage ? (
44
49
  <Text level={1} style={style.discountedPercentage} testID="discounted-percentage-text" variant="detail">
45
- {`-${price.discountedPrice.percentage}%`}
50
+ {`-${discountedPrice.percentage}%`}
46
51
  </Text>
47
52
  ) : null}
48
53
  </View>
@@ -63,7 +63,12 @@ const ProductVariantPreview: FC<ProductVariantPreviewProps> = ({ item, country }
63
63
  </View>
64
64
 
65
65
  <View style={style.price}>
66
- <Price price={price} withPercentage />
66
+ <Price
67
+ amount={price.amount}
68
+ currency={price.currency}
69
+ discountedPrice={price.discountedPrice}
70
+ withPercentage
71
+ />
67
72
  </View>
68
73
  </Column>
69
74
  </Row>
@@ -88,7 +88,12 @@ const ProductVariant: FC<ProductVariantProps> = ({
88
88
  )}
89
89
  </View>
90
90
 
91
- <Price price={price} variant="detail" />
91
+ <Price
92
+ amount={price.amount}
93
+ currency={price.currency}
94
+ discountedPrice={price.discountedPrice}
95
+ variant="detail"
96
+ />
92
97
  </View>
93
98
  </View>
94
99
 
@@ -11,7 +11,7 @@ import { Customer } from "../../../../projection/customer/customer";
11
11
  import { checkout } from "../../../projection/checkout/checkout.mock";
12
12
  import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
13
13
  import { useViewFiveItemsDiscountByCustomerId } from "../../../projection/checkout/react/useViewFiveItemsDiscountByCustomerId";
14
- import { pricing } from "../../../projection/pricing/pricing.mock";
14
+ import { mockCheckoutPricingProjection } from "../../../projection/pricing/pricing.mock";
15
15
  import { useViewPricingByCheckoutId } from "../../../projection/pricing/react/useViewPricingByCheckoutId";
16
16
  import { I18nMessages } from "../../i18n/i18n";
17
17
  import { render } from "../../test/render";
@@ -33,7 +33,6 @@ const mockCustomer: Customer = {
33
33
  customerId,
34
34
  country,
35
35
  segment,
36
- migrated: false,
37
36
  } as Customer;
38
37
 
39
38
  const mockTradename = Tradename.LOOKIERO;
@@ -74,7 +73,7 @@ afterAll(() => {
74
73
  describe("Summary view", () => {
75
74
  it("renders correctly", async () => {
76
75
  (useViewFirstAvailableCheckoutByCustomerId as jest.Mock).mockReturnValue([checkoutMock, QueryStatus.SUCCESS]);
77
- (useViewPricingByCheckoutId as jest.Mock).mockReturnValue([pricing(), QueryStatus.SUCCESS]);
76
+ (useViewPricingByCheckoutId as jest.Mock).mockReturnValue([mockCheckoutPricingProjection, QueryStatus.SUCCESS]);
78
77
  (useViewFiveItemsDiscountByCustomerId as jest.Mock).mockReturnValue([fiveItemsDiscountMock, QueryStatus.SUCCESS]);
79
78
 
80
79
  const { findByText, getByText, getByTestId } = render(
@@ -89,7 +88,7 @@ describe("Summary view", () => {
89
88
  expect(mockUseNavigate).toHaveBeenCalledWith("tabs/keep", { replace: true });
90
89
 
91
90
  expect(getByText(`${I18nMessages.SUMMARY_TOTAL} ${I18nMessages.SUMMARY_TOTAL_ITEMS_KEPT}`)).toBeTruthy();
92
- expect(getByText("€163.01")).toBeTruthy();
91
+ expect(getByText("€121.27")).toBeTruthy();
93
92
 
94
93
  fireEvent.press(getByTestId("pricing-collapsed"));
95
94
  expect(mockTrackPressPricing).toHaveBeenCalledWith({
@@ -97,16 +96,11 @@ describe("Summary view", () => {
97
96
  });
98
97
 
99
98
  expect(getByText(`${I18nMessages.SUMMARY_SUBTOTAL} ${I18nMessages.SUMMARY_TOTAL_ITEMS_KEPT}`)).toBeTruthy();
100
- expect(getByText("€218.01")).toBeTruthy();
99
+ expect(getByText("€211.95")).toBeTruthy();
101
100
 
102
101
  expect(getByText(I18nMessages.SUMMARY_DISCOUNT)).toBeTruthy();
103
- expect(getByText("-€25.00")).toBeTruthy();
104
-
105
102
  expect(getByText(I18nMessages.SUMMARY_CREDIT)).toBeTruthy();
106
- expect(getByText("-€20.00")).toBeTruthy();
107
-
108
103
  expect(getByText(I18nMessages.SUMMARY_FEE)).toBeTruthy();
109
- expect(getByText("-€10.00")).toBeTruthy();
110
104
 
111
105
  fireEvent.press(getByText(I18nMessages.SUMMARY_SUBMIT_BUTTON));
112
106
  expect(mockTrackPressContinue).toHaveBeenCalled();
@@ -28,7 +28,7 @@ interface SummaryProps {
28
28
 
29
29
  const Summary: FC<SummaryProps> = ({ layout: Layout, children }) => {
30
30
  const {
31
- customer: { customerId, country, segment, migrated },
31
+ customer: { customerId, country, segment },
32
32
  basePath,
33
33
  tradename,
34
34
  } = useStaticInfo();
@@ -152,11 +152,9 @@ const Summary: FC<SummaryProps> = ({ layout: Layout, children }) => {
152
152
  <CollapsiblePricing
153
153
  collapsed={false}
154
154
  collapsible={false}
155
- migrated={migrated}
156
155
  pricing={pricing}
157
156
  submitButtonText={submitButtonText}
158
157
  totalCheckoutItemsKept={totalCheckoutItemsKept}
159
- tradename={tradename}
160
158
  onSubmit={handleOnSubmit}
161
159
  />
162
160
  </View>
@@ -170,11 +168,9 @@ const Summary: FC<SummaryProps> = ({ layout: Layout, children }) => {
170
168
  <Body>
171
169
  <CollapsiblePricing
172
170
  collapsed={pricingCollapsed}
173
- migrated={migrated}
174
171
  pricing={pricing}
175
172
  submitButtonText={submitButtonText}
176
173
  totalCheckoutItemsKept={totalCheckoutItemsKept}
177
- tradename={tradename}
178
174
  onPress={handleOnPressPricing}
179
175
  onSubmit={handleOnSubmit}
180
176
  />
@@ -1,8 +1,7 @@
1
1
  import { RenderResult, fireEvent } from "@testing-library/react-native";
2
2
  import React from "react";
3
- import { Tradename } from "@lookiero/sty-sp-tradename";
4
- import { PricingProjection } from "../../../../../../projection/pricing/pricing";
5
- import { pricing as pricingFunction } from "../../../../../projection/pricing/pricing.mock";
3
+ import { CheckoutPricingProjection } from "../../../../../../projection/pricing/pricing";
4
+ import { mockCheckoutPricingProjection } from "../../../../../projection/pricing/pricing.mock";
6
5
  import { I18nMessages } from "../../../../i18n/i18n";
7
6
  import { render } from "../../../../test/render";
8
7
  import { CollapsiblePricing } from "./CollapsiblePricing";
@@ -13,7 +12,7 @@ const mockOnSubmit = jest.fn();
13
12
  interface RenderPricingFunctionArgs {
14
13
  readonly collapsed?: boolean;
15
14
  readonly collapsible?: boolean;
16
- readonly pricing?: PricingProjection;
15
+ readonly pricing?: CheckoutPricingProjection;
17
16
  }
18
17
 
19
18
  interface RenderPricingFunction {
@@ -23,17 +22,15 @@ interface RenderPricingFunction {
23
22
  const renderPricing: RenderPricingFunction = ({
24
23
  collapsed = true,
25
24
  collapsible = true,
26
- pricing = pricingFunction(),
25
+ pricing = mockCheckoutPricingProjection,
27
26
  } = {}) =>
28
27
  render(
29
28
  <CollapsiblePricing
30
29
  collapsed={collapsed}
31
30
  collapsible={collapsible}
32
- migrated={false}
33
31
  pricing={pricing}
34
32
  submitButtonText={I18nMessages.SUMMARY_SUBMIT_BUTTON}
35
33
  totalCheckoutItemsKept={3}
36
- tradename={Tradename.LOOKIERO}
37
34
  onPress={mockOnPress}
38
35
  onSubmit={mockOnSubmit}
39
36
  />,
@@ -58,7 +55,7 @@ describe("Pricing component", () => {
58
55
  // expect(getByTestId("arrow-up")).toBeTruthy();
59
56
 
60
57
  expect(getByText(`${I18nMessages.SUMMARY_TOTAL} ${I18nMessages.SUMMARY_TOTAL_ITEMS_KEPT}`)).toBeTruthy();
61
- expect(getByText("€163.01")).toBeTruthy();
58
+ expect(getByText("€121.27")).toBeTruthy();
62
59
 
63
60
  fireEvent.press(getByTestId("pricing-collapsed"));
64
61
  expect(mockOnPress).toHaveBeenCalled();
@@ -73,19 +70,14 @@ describe("Pricing component", () => {
73
70
  // expect(getByTestId("arrow-down")).toBeTruthy();
74
71
 
75
72
  expect(getByText(`${I18nMessages.SUMMARY_SUBTOTAL} ${I18nMessages.SUMMARY_TOTAL_ITEMS_KEPT}`)).toBeTruthy();
76
- expect(getByText("€218.01")).toBeTruthy();
73
+ expect(getByText("€211.95")).toBeTruthy();
77
74
 
78
75
  expect(getByText(I18nMessages.SUMMARY_DISCOUNT)).toBeTruthy();
79
- expect(getByText("-€25.00")).toBeTruthy();
80
-
81
76
  expect(getByText(I18nMessages.SUMMARY_CREDIT)).toBeTruthy();
82
- expect(getByText("-€20.00")).toBeTruthy();
83
-
84
77
  expect(getByText(I18nMessages.SUMMARY_FEE)).toBeTruthy();
85
- expect(getByText("-€10.00")).toBeTruthy();
86
78
 
87
79
  expect(getByText(I18nMessages.SUMMARY_TOTAL)).toBeTruthy();
88
- expect(getByText("€163.01")).toBeTruthy();
80
+ expect(getByText("€121.27")).toBeTruthy();
89
81
 
90
82
  fireEvent.press(getByTestId("pricing-collapsed"));
91
83
  expect(mockOnPress).toHaveBeenCalled();
@@ -94,18 +86,12 @@ describe("Pricing component", () => {
94
86
  expect(mockOnSubmit).toHaveBeenCalled();
95
87
  });
96
88
 
97
- it("renders correctly for a paidWithPromocode service", () => {
98
- const { getByText } = renderPricing({ collapsed: false, pricing: pricingFunction({ paidWithPromocode: true }) });
99
-
100
- expect(getByText(I18nMessages.SUMMARY_FEE)).toBeTruthy();
101
- expect(getByText(I18nMessages.SUMMARY_FREE)).toBeTruthy();
102
- });
103
-
104
- it("renders correctly for a NON paidWithPromocode service", () => {
89
+ it("renders correctly with modifiers", () => {
105
90
  const { getByText } = renderPricing({ collapsed: false });
106
91
 
92
+ expect(getByText(I18nMessages.SUMMARY_DISCOUNT)).toBeTruthy();
93
+ expect(getByText(I18nMessages.SUMMARY_CREDIT)).toBeTruthy();
107
94
  expect(getByText(I18nMessages.SUMMARY_FEE)).toBeTruthy();
108
- expect(getByText("-€10.00")).toBeTruthy();
109
95
  });
110
96
 
111
97
  it.skip("renders correctly for non-collapsible pricing", () => {
@@ -3,17 +3,14 @@ import { Pressable, View } from "react-native";
3
3
  import Animated, { useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";
4
4
  import { useI18nMessage } from "@lookiero/i18n-react";
5
5
  import { Button, Icon, Text } from "@lookiero/sty-psp-ui";
6
- import { Tradename } from "@lookiero/sty-sp-tradename";
7
- import { PricingProjection } from "../../../../../../projection/pricing/pricing";
6
+ import { CheckoutPricingProjection } from "../../../../../../projection/pricing/pricing";
8
7
  import { Price } from "../../../../components/atoms/price/Price";
9
8
  import { DOMAIN, I18nMessages } from "../../../../i18n/i18n";
10
9
  import { Pricing } from "../pricing/Pricing";
11
10
  import { style as collapsiblePricingStyle } from "./CollapsiblePricing.style";
12
11
 
13
12
  interface CollapsiblePricingProps {
14
- readonly tradename: Tradename;
15
- readonly migrated: boolean;
16
- readonly pricing: PricingProjection;
13
+ readonly pricing: CheckoutPricingProjection;
17
14
  readonly totalCheckoutItemsKept: number;
18
15
  readonly collapsible?: boolean;
19
16
  readonly collapsed?: boolean;
@@ -22,8 +19,6 @@ interface CollapsiblePricingProps {
22
19
  readonly onSubmit: () => void;
23
20
  }
24
21
  const CollapsiblePricing: FC<CollapsiblePricingProps> = ({
25
- migrated,
26
- tradename,
27
22
  pricing,
28
23
  totalCheckoutItemsKept,
29
24
  collapsible = true,
@@ -32,7 +27,7 @@ const CollapsiblePricing: FC<CollapsiblePricingProps> = ({
32
27
  onPress = () => void 0,
33
28
  onSubmit,
34
29
  }) => {
35
- const { pendingToPay } = pricing;
30
+ const { finalPrice, currency } = pricing;
36
31
 
37
32
  const totalText = useI18nMessage({ domain: DOMAIN, id: I18nMessages.SUMMARY_TOTAL });
38
33
  const totalCheckoutItemsKeptText = useI18nMessage({
@@ -74,7 +69,7 @@ const CollapsiblePricing: FC<CollapsiblePricingProps> = ({
74
69
  <Text level={1} style={style.totalCollapsed} variant="detail">
75
70
  {totalText} {totalCheckoutItemsKeptText}
76
71
  </Text>
77
- <Price price={pendingToPay} variant="detail" />
72
+ <Price amount={finalPrice} currency={currency} variant="detail" />
78
73
  </View>
79
74
 
80
75
  <View style={style.collapsedContent}>
@@ -85,12 +80,7 @@ const CollapsiblePricing: FC<CollapsiblePricingProps> = ({
85
80
  </Animated.View>
86
81
  ) : (
87
82
  <Animated.View key="not-collapsed" style={notCollapsedAnimatedStyle}>
88
- <Pricing
89
- migrated={migrated}
90
- pricing={pricing}
91
- totalCheckoutItemsKept={totalCheckoutItemsKept}
92
- tradename={tradename}
93
- />
83
+ <Pricing pricing={pricing} totalCheckoutItemsKept={totalCheckoutItemsKept} />
94
84
 
95
85
  <Button testID="submit-checkout-button" onPress={onSubmit}>
96
86
  {submitButtonText}
@@ -172,7 +172,7 @@ exports[`Pricing component matches the snapshot for collaped pricing: collapsed
172
172
  }
173
173
  testID="price-text"
174
174
  >
175
- 163.01
175
+ 121.27
176
176
  </Text>
177
177
  </View>
178
178
  </View>
@@ -484,7 +484,7 @@ exports[`Pricing component matches the snapshot for non-collaped pricing: non-co
484
484
  }
485
485
  testID="price-text"
486
486
  >
487
- 163.01
487
+ 121.27
488
488
  </Text>
489
489
  </View>
490
490
  </View>
@@ -1,9 +1,9 @@
1
1
  import React, { FC, ReactNode, useMemo } from "react";
2
2
  import { View } from "react-native";
3
3
  import { useI18nMessage } from "@lookiero/i18n-react";
4
+ import { Currency } from "@lookiero/sty-psp-locale";
4
5
  import { Text } from "@lookiero/sty-psp-ui";
5
- import { Tradename } from "@lookiero/sty-sp-tradename";
6
- import { PricingProjection } from "../../../../../../projection/pricing/pricing";
6
+ import { CheckoutPricingProjection, CheckoutPricingType } from "../../../../../../projection/pricing/pricing";
7
7
  import { Price } from "../../../../components/atoms/price/Price";
8
8
  import { DOMAIN, I18nMessages } from "../../../../i18n/i18n";
9
9
  import { style as pricingStyle } from "./Pricing.style";
@@ -26,15 +26,38 @@ const Row: FC<RowProps> = ({ action = false, text, level = 3, children }) => {
26
26
  </View>
27
27
  );
28
28
  };
29
+
30
+ interface ModifierRowProps {
31
+ readonly translationKey: string;
32
+ readonly amount: number;
33
+ readonly percentage?: number;
34
+ readonly type: CheckoutPricingType;
35
+ readonly currency: Currency;
36
+ }
37
+
38
+ const ModifierRow: FC<ModifierRowProps> = ({ translationKey, amount, percentage, currency, type }) => {
39
+ const modifierText = useI18nMessage({
40
+ domain: DOMAIN,
41
+ id: translationKey,
42
+ values: percentage ? { discount: percentage.toString() } : undefined,
43
+ });
44
+
45
+ const displayAmount = type === CheckoutPricingType.DISCOUNT ? -amount : amount;
46
+
47
+ return (
48
+ <Row text={modifierText}>
49
+ <Price amount={displayAmount} currency={currency} variant="subtotal" />
50
+ </Row>
51
+ );
52
+ };
53
+
29
54
  interface PricingProps {
30
- readonly pricing: PricingProjection;
55
+ readonly pricing: CheckoutPricingProjection;
31
56
  readonly totalCheckoutItemsKept: number;
32
- readonly tradename: Tradename;
33
- readonly migrated: boolean;
34
57
  }
35
58
 
36
- const Pricing: FC<PricingProps> = ({ pricing, totalCheckoutItemsKept, tradename, migrated }) => {
37
- const { pendingToPay, subtotal, balanceDiscount, discount, discountPercentage = 0, service } = pricing;
59
+ const Pricing: FC<PricingProps> = ({ pricing, totalCheckoutItemsKept }) => {
60
+ const { originalPrice, finalPrice, modifiers, currency } = pricing;
38
61
 
39
62
  const style = useMemo(() => pricingStyle(), []);
40
63
 
@@ -45,47 +68,28 @@ const Pricing: FC<PricingProps> = ({ pricing, totalCheckoutItemsKept, tradename,
45
68
  values: { items: totalCheckoutItemsKept.toString() },
46
69
  });
47
70
  const subtotalText = useI18nMessage({ domain: DOMAIN, id: I18nMessages.SUMMARY_SUBTOTAL });
48
- const freeText = useI18nMessage({ domain: DOMAIN, id: I18nMessages.SUMMARY_FREE });
49
- const discountText = useI18nMessage({
50
- domain: DOMAIN,
51
- id: I18nMessages.SUMMARY_DISCOUNT,
52
- values: { discount: discountPercentage?.toString() },
53
- });
54
- const creditText = useI18nMessage({ domain: DOMAIN, id: I18nMessages.SUMMARY_CREDIT });
55
- const feeText = useI18nMessage({ domain: DOMAIN, id: I18nMessages.SUMMARY_FEE });
56
71
 
57
72
  return (
58
73
  <View>
59
74
  <Row text={`${subtotalText} ${totalCheckoutItemsKeptText}`}>
60
- <Price price={subtotal} variant="subtotal" />
75
+ <Price amount={originalPrice} currency={currency} variant="subtotal" />
61
76
  </Row>
62
77
 
63
- {discount && discount.amount !== 0 && (
64
- <Row text={discountText}>
65
- <Price price={discount} variant="subtotal" />
66
- </Row>
67
- )}
68
-
69
- {balanceDiscount && balanceDiscount.amount !== 0 && (
70
- <Row text={creditText}>
71
- <Price price={balanceDiscount} variant="subtotal" />
72
- </Row>
73
- )}
74
-
75
- {(tradename === Tradename.LOOKIERO || (tradename === Tradename.OUTFITTERY && !migrated)) && (
76
- <Row text={feeText}>
77
- {service.paidWithPromocode ? (
78
- <Text level={3}>{freeText}</Text>
79
- ) : (
80
- <Price price={service.finalPrice} variant="subtotal" />
81
- )}
82
- </Row>
83
- )}
78
+ {modifiers.map((modifier, index) => (
79
+ <ModifierRow
80
+ key={`modifier-${index}`}
81
+ amount={modifier.amount}
82
+ currency={currency}
83
+ percentage={modifier.percentage}
84
+ translationKey={modifier.translationKey}
85
+ type={modifier.type}
86
+ />
87
+ ))}
84
88
 
85
89
  <View style={style.divider} />
86
90
 
87
91
  <Row level={2} text={totalText} action>
88
- <Price price={pendingToPay} variant="total" />
92
+ <Price amount={finalPrice} currency={currency} variant="total" />
89
93
  </Row>
90
94
  </View>
91
95
  );
@@ -7,7 +7,6 @@ interface Customer {
7
7
  readonly segment: Segment;
8
8
  readonly name: string;
9
9
  readonly email: string;
10
- readonly migrated: boolean;
11
10
  }
12
11
 
13
12
  export type { Customer };
@@ -1,24 +1,4 @@
1
1
  import { Currency } from "@lookiero/sty-psp-locale";
2
- import { PriceProjection } from "../price/price";
3
-
4
- interface ServiceProjection {
5
- readonly discount: PriceProjection;
6
- readonly finalPrice: PriceProjection;
7
- readonly originalPrice: PriceProjection;
8
- readonly prepaid: boolean;
9
- readonly reference: string;
10
- readonly paidWithPromocode?: boolean;
11
- }
12
-
13
- interface PricingProjection {
14
- readonly balanceDiscount: PriceProjection;
15
- readonly discount: PriceProjection;
16
- readonly discountPercentage: number;
17
- readonly orderTotal: PriceProjection;
18
- readonly pendingToPay: PriceProjection;
19
- readonly service: ServiceProjection;
20
- readonly subtotal: PriceProjection;
21
- }
22
2
 
23
3
  enum Type {
24
4
  DISCOUNT = "DISCOUNT",
@@ -31,7 +11,7 @@ enum Context {
31
11
  BALANCE = "BALANCE",
32
12
  }
33
13
 
34
- interface Modify {
14
+ interface Modifier {
35
15
  readonly amount: number;
36
16
  readonly percentage?: number;
37
17
  readonly type: Type;
@@ -41,10 +21,10 @@ interface Modify {
41
21
 
42
22
  interface CheckoutPricingProjection {
43
23
  readonly currency: Currency;
44
- readonly final: number; // total a pagar
45
- readonly original: number; // precio original de la caja
46
- readonly modifiers: Modify[];
24
+ readonly finalPrice: number; // total a pagar
25
+ readonly originalPrice: number; // precio original de la caja
26
+ readonly modifiers: Modifier[];
47
27
  }
48
28
 
49
- export type { PricingProjection, ServiceProjection, CheckoutPricingProjection };
50
- export { Type as CheckoutPrincingType, Context as CheckoutPrincingContext };
29
+ export type { CheckoutPricingProjection };
30
+ export { Type as CheckoutPricingType, Context as CheckoutPricingContext };
@@ -1,6 +1,6 @@
1
1
  import { mock } from "jest-mock-extended";
2
2
  import { QueryBus } from "@lookiero/messaging";
3
- import { pricing } from "../../infrastructure/projection/pricing/pricing.mock";
3
+ import { mockCheckoutPricingProjection } from "../../infrastructure/projection/pricing/pricing.mock";
4
4
  import { viewPricingByCheckoutId, viewPricingByCheckoutIdHandler as sut } from "./viewPricingByCheckoutId";
5
5
 
6
6
  const checkoutId = "29790d24-b139-4ab8-b618-d796d101e974";
@@ -8,10 +8,9 @@ const queryBus = mock<QueryBus>();
8
8
  const signal = mock<AbortSignal>();
9
9
 
10
10
  describe("viewPricingByCheckoutId", () => {
11
- it("returns checkout booking for checkout item", async () => {
12
- const aPricing = pricing();
11
+ it("returns checkout pricing for checkout item", async () => {
13
12
  const query = viewPricingByCheckoutId({ checkoutId });
14
- const view = jest.fn(() => Promise.resolve(aPricing));
13
+ const view = jest.fn(() => Promise.resolve(mockCheckoutPricingProjection));
15
14
 
16
15
  const pricingProjectionResult = await sut({
17
16
  view,
@@ -19,6 +18,6 @@ describe("viewPricingByCheckoutId", () => {
19
18
  signal,
20
19
  })(query);
21
20
 
22
- expect(pricingProjectionResult).toBe(aPricing);
21
+ expect(pricingProjectionResult).toBe(mockCheckoutPricingProjection);
23
22
  });
24
23
  });
@@ -5,7 +5,7 @@ import {
5
5
  QueryHandlerFunction,
6
6
  QueryHandlerFunctionArgs,
7
7
  } from "@lookiero/messaging";
8
- import { PricingProjection } from "./pricing";
8
+ import { CheckoutPricingProjection } from "./pricing";
9
9
 
10
10
  const VIEW_PRICING_BY_CHECKOUT_ID = "view_pricing_by_checkout_id";
11
11
 
@@ -24,7 +24,7 @@ const viewPricingByCheckoutId: ViewPricingByCheckoutIdFunction = (payload) => ({
24
24
  ...payload,
25
25
  });
26
26
 
27
- type ViewPricingByCheckoutIdResult = PricingProjection | null;
27
+ type ViewPricingByCheckoutIdResult = CheckoutPricingProjection | null;
28
28
 
29
29
  interface PricingByCheckoutIdViewArgs extends CancelableQueryViewArgs {
30
30
  readonly checkoutId: string;
@@ -1,18 +0,0 @@
1
- import { PriceProjection } from "../../../projection/price/price";
2
- import { PricingProjection, ServiceProjection } from "../../../projection/pricing/pricing";
3
- interface PricingDto {
4
- readonly balanceDiscount: PriceProjection;
5
- readonly discount: PriceProjection;
6
- readonly discountPercentage: number;
7
- readonly orderTotal: PriceProjection;
8
- readonly pendingToPay: PriceProjection;
9
- readonly service: ServiceProjection;
10
- readonly subtotal: PriceProjection;
11
- readonly paidWithPromocode?: boolean;
12
- }
13
- interface ToPricingProjectionFunction {
14
- (pricingDto: PricingDto): PricingProjection;
15
- }
16
- declare const toPricingProjection: ToPricingProjectionFunction;
17
- export type { PricingDto };
18
- export { toPricingProjection };
@@ -1,12 +0,0 @@
1
- const toPricingProjection = (pricingDto) => ({
2
- ...pricingDto,
3
- discount: {
4
- ...pricingDto.discount,
5
- amount: -Math.abs(pricingDto.discount.amount),
6
- },
7
- balanceDiscount: {
8
- ...pricingDto.balanceDiscount,
9
- amount: -Math.abs(pricingDto.balanceDiscount.amount),
10
- },
11
- });
12
- export { toPricingProjection };