@lookiero/checkout 15.0.2 → 15.1.1
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/AGENTS.md +54 -0
- package/CHANGELOG.md +9 -0
- package/cypress/integration/checkout.spec.ts +9 -10
- package/cypress/support/interceptViewPricingByCheckoutId.ts +2 -3
- package/dist/index.d.ts +0 -2
- package/dist/index.js +2 -2
- package/dist/src/ExpoRoot.js +2 -3
- package/dist/src/infrastructure/delivery/bootstrap.d.ts +0 -3
- package/dist/src/infrastructure/delivery/bootstrap.js +1 -3
- package/dist/src/infrastructure/projection/checkoutItem/checkoutItem.mock.d.ts +1 -1
- package/dist/src/infrastructure/projection/pricing/httpPricingByCheckoutIdView.d.ts +0 -3
- package/dist/src/infrastructure/projection/pricing/httpPricingByCheckoutIdView.js +3 -4
- package/dist/src/infrastructure/projection/pricing/pricing.mock.d.ts +1 -3
- package/dist/src/infrastructure/projection/pricing/pricing.mock.js +1 -16
- package/dist/src/infrastructure/ui/Root.d.ts +0 -1
- package/dist/src/infrastructure/ui/Root.js +2 -2
- package/dist/src/infrastructure/ui/hooks/useStaticInfo.d.ts +0 -2
- package/dist/src/infrastructure/ui/hooks/useStaticInfo.js +2 -3
- package/dist/src/infrastructure/ui/routing/Routing.d.ts +0 -1
- package/dist/src/infrastructure/ui/routing/Routing.js +2 -2
- package/dist/src/version.d.ts +2 -2
- package/dist/src/version.js +2 -2
- package/index.ts +2 -4
- package/package.json +1 -1
- package/src/ExpoRoot.tsx +1 -3
- package/src/infrastructure/delivery/bootstrap.ts +1 -6
- package/src/infrastructure/projection/checkoutItem/checkoutItem.mock.ts +1 -1
- package/src/infrastructure/projection/pricing/httpPricingByCheckoutIdView.test.ts +9 -88
- package/src/infrastructure/projection/pricing/httpPricingByCheckoutIdView.ts +4 -12
- package/src/infrastructure/projection/pricing/pricing.mock.ts +1 -18
- package/src/infrastructure/ui/Root.tsx +0 -3
- package/src/infrastructure/ui/hooks/useStaticInfo.test.tsx +1 -9
- package/src/infrastructure/ui/hooks/useStaticInfo.tsx +2 -12
- package/src/infrastructure/ui/routing/CheckoutMiddleware.test.tsx +0 -1
- package/src/infrastructure/ui/routing/Routing.tsx +1 -9
- package/dist/src/infrastructure/projection/pricing/pricing.d.ts +0 -31
- package/dist/src/infrastructure/projection/pricing/pricing.js +0 -39
- package/src/infrastructure/projection/pricing/pricing.ts +0 -83
package/AGENTS.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# checkout — AI Agent Ruleset
|
|
2
|
+
|
|
3
|
+
Workspace: `@lookiero/checkout`. Expo + `sty-psp` tooling. Has EAS hooks, Cypress (port 19004), Detox e2e.
|
|
4
|
+
|
|
5
|
+
Root rules: see `../../AGENTS.md`. This file overrides root on conflict.
|
|
6
|
+
|
|
7
|
+
## Auto-invoke skills
|
|
8
|
+
|
|
9
|
+
| Action | Skill |
|
|
10
|
+
| ---------------------------------------------- | ---------------------- |
|
|
11
|
+
| Add/modify Expo Router native UI | `building-native-ui` |
|
|
12
|
+
| Build/distribute Expo dev clients | `expo-dev-client` |
|
|
13
|
+
| Create Expo Router API routes (EAS Hosting) | `expo-api-routes` |
|
|
14
|
+
| Deploy to stores / web | `expo-deployment` |
|
|
15
|
+
| Implement network requests / React Query / SWR | `native-data-fetching` |
|
|
16
|
+
| Migrate web code to native via DOM components | `use-dom` |
|
|
17
|
+
| Upgrade Expo SDK and dependencies | `upgrading-expo` |
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Local dev (web on proxy-server)
|
|
23
|
+
npm run dev --workspace @lookiero/checkout
|
|
24
|
+
|
|
25
|
+
# Build / lint / test
|
|
26
|
+
npm run build --workspace @lookiero/checkout
|
|
27
|
+
npm run lint --workspace @lookiero/checkout
|
|
28
|
+
npm run test --workspace @lookiero/checkout
|
|
29
|
+
|
|
30
|
+
# Specific Jest test
|
|
31
|
+
npm run test --workspace @lookiero/checkout -- -t "<name>"
|
|
32
|
+
|
|
33
|
+
# Cypress (port 19004)
|
|
34
|
+
npm run cypress --workspace @lookiero/checkout
|
|
35
|
+
npm run cypress:open --workspace @lookiero/checkout
|
|
36
|
+
|
|
37
|
+
# Native
|
|
38
|
+
npx expo prebuild --clean
|
|
39
|
+
npx expo run:android
|
|
40
|
+
npx expo run:ios
|
|
41
|
+
|
|
42
|
+
# Detox e2e
|
|
43
|
+
EXPO_PUBLIC_APP_VARIANT=test npx detox build --configuration android.release
|
|
44
|
+
npx detox test --configuration android.release
|
|
45
|
+
|
|
46
|
+
# EAS
|
|
47
|
+
npm run eas:all --workspace @lookiero/checkout
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Notes
|
|
51
|
+
|
|
52
|
+
- `eas-hooks/` runs on EAS build lifecycle — do not bypass.
|
|
53
|
+
- `proxy-server.js` for local dev; Cypress relies on it.
|
|
54
|
+
- E2E specs in `e2e/`; Cypress in `cypress/`.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@lookiero/checkout` are generated from Conventional Commits scoped to `apps/checkout`.
|
|
4
|
+
|
|
5
|
+
This file follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
Regenerate with `sp-changelog` (see `skills/sp-changelog/SKILL.md`).
|
|
8
|
+
|
|
9
|
+
> History before 2026-05-15 is not captured here — pre-existing commits did not follow Conventional Commits. New entries are generated from this point forward.
|
|
@@ -6,7 +6,7 @@ import { checkoutBooking } from "../../src/infrastructure/projection/checkoutBoo
|
|
|
6
6
|
import { checkoutFeedbackDefinition } from "../../src/infrastructure/projection/checkoutFeedback/checkoutFeedbackDefinition.mock";
|
|
7
7
|
import { checkoutItem } from "../../src/infrastructure/projection/checkoutItem/checkoutItem.mock";
|
|
8
8
|
import { paymentFlowPayload } from "../../src/infrastructure/projection/payment/paymentFlowPayload.mock";
|
|
9
|
-
import {
|
|
9
|
+
import { mockCheckoutPricingProjection } from "../../src/infrastructure/projection/pricing/pricing.mock";
|
|
10
10
|
import { returnQuestions } from "../../src/infrastructure/projection/returnQuestion/returnQuestions.mock";
|
|
11
11
|
import { Routes } from "../../src/infrastructure/ui/routing/routes";
|
|
12
12
|
import { CheckoutFeedbackQuestionType } from "../../src/projection/checkoutFeedback/checkoutFeedback.constants";
|
|
@@ -81,20 +81,19 @@ const confirmCheckout = () => {
|
|
|
81
81
|
const checkoutFeedback = () => {
|
|
82
82
|
cy.shouldIncludePathInUrl(`${BASEPATH}/${Routes.FEEDBACK}`);
|
|
83
83
|
|
|
84
|
-
const answers = [];
|
|
85
|
-
checkoutFeedbackDefinition.
|
|
84
|
+
const answers: string[] = [];
|
|
85
|
+
checkoutFeedbackDefinition.forEach((checkoutQuestion) => {
|
|
86
86
|
if (checkoutFeedbackQuestionHasChildren(checkoutQuestion)) {
|
|
87
87
|
const index = randomIndex(checkoutQuestion.children.length);
|
|
88
88
|
const randomCheckoutQuestionItem = checkoutQuestion.children[index];
|
|
89
89
|
answers.push(randomCheckoutQuestionItem.id);
|
|
90
90
|
|
|
91
|
+
const { metadata } = checkoutQuestion;
|
|
92
|
+
|
|
91
93
|
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
checkoutQuestion?.metadata?.showCondition.length === 0 ||
|
|
96
|
-
// @ts-ignore
|
|
97
|
-
checkoutQuestion?.metadata?.showCondition.some((condition) => answers.includes(condition))
|
|
94
|
+
!metadata?.showCondition ||
|
|
95
|
+
metadata.showCondition.length === 0 ||
|
|
96
|
+
metadata.showCondition.some((condition) => answers.includes(condition))
|
|
98
97
|
) {
|
|
99
98
|
if (checkoutQuestion.type === CheckoutFeedbackQuestionType.HOST_TEXTAREA) {
|
|
100
99
|
cy.getByTestId(randomCheckoutQuestionItem.id).type("Cypress E2E test");
|
|
@@ -130,7 +129,7 @@ describe("Checkout", () => {
|
|
|
130
129
|
interceptViewFiveItemsDiscountByCustomerId(0);
|
|
131
130
|
interceptViewBookedProductsVariantsForCheckoutItem(bookedProductsVariants);
|
|
132
131
|
interceptListReturnQuestionsByCheckoutItemId(returnQuestions);
|
|
133
|
-
interceptViewPricingByCheckoutId(
|
|
132
|
+
interceptViewPricingByCheckoutId(mockCheckoutPricingProjection);
|
|
134
133
|
interceptViewPaymentFlowPayloadByCheckoutId(paymentFlowPayload);
|
|
135
134
|
interceptViewCheckoutFeedbackDefinitionByCheckoutId(checkoutFeedbackDefinition);
|
|
136
135
|
interceptViewCheckoutBookingById(checkoutBooking);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { PricingDto } from "../../src/infrastructure/projection/pricing/pricing";
|
|
2
1
|
import { CheckoutPricingProjection } from "../../src/projection/pricing/pricing";
|
|
3
2
|
|
|
4
|
-
const interceptViewPricingByCheckoutId = (response:
|
|
5
|
-
cy.intercept({ method: "POST", url: "/local-to-dev/view-pricing-by-checkout-id" }, { body:
|
|
3
|
+
const interceptViewPricingByCheckoutId = (response: CheckoutPricingProjection) =>
|
|
4
|
+
cy.intercept({ method: "POST", url: "/local-to-dev/view-checkout-pricing-by-checkout-id" }, { body: response });
|
|
6
5
|
|
|
7
6
|
export { interceptViewPricingByCheckoutId };
|
package/dist/index.d.ts
CHANGED
|
@@ -19,8 +19,6 @@ interface FirstAvailableCheckoutByCustomerIdFunction {
|
|
|
19
19
|
interface BootstrapFunctionArgs {
|
|
20
20
|
readonly getAuthToken: () => Promise<string>;
|
|
21
21
|
readonly apiUrl: () => string;
|
|
22
|
-
readonly tradename: Tradename;
|
|
23
|
-
readonly migrated: boolean;
|
|
24
22
|
readonly sentry: () => SentryEnvironment;
|
|
25
23
|
readonly kameleoon: () => KameleoonEnvironment;
|
|
26
24
|
}
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,8 @@ import { CheckoutStatus } from "./src/domain/checkout/model/checkout";
|
|
|
6
6
|
import { bootstrap as checkoutBootstrap } from "./src/infrastructure/delivery/bootstrap";
|
|
7
7
|
import { root } from "./src/infrastructure/ui/Root";
|
|
8
8
|
import { viewFirstAvailableCheckoutByCustomerId } from "./src/projection/checkout/viewFirstAvailableCheckoutByCustomerId";
|
|
9
|
-
const bootstrap = ({ apiUrl, getAuthToken,
|
|
10
|
-
const { Component: Messaging, queryBus } = checkoutBootstrap({ apiUrl, getAuthToken
|
|
9
|
+
const bootstrap = ({ apiUrl, getAuthToken, sentry, kameleoon }) => {
|
|
10
|
+
const { Component: Messaging, queryBus } = checkoutBootstrap({ apiUrl, getAuthToken });
|
|
11
11
|
const firstAvailableCheckoutByCustomerId = ({ customerId }) => queryBus(viewFirstAvailableCheckoutByCustomerId({ customerId: customerId }));
|
|
12
12
|
return {
|
|
13
13
|
root: root({ Messaging, queryBus, getAuthToken, sentry, kameleoon }),
|
package/dist/src/ExpoRoot.js
CHANGED
|
@@ -17,7 +17,6 @@ import { root } from "./infrastructure/ui/Root";
|
|
|
17
17
|
import { Router } from "./infrastructure/ui/routing/router/Router";
|
|
18
18
|
import { RELEASE } from "./version";
|
|
19
19
|
const tradename = Tradename.LOOKIERO;
|
|
20
|
-
const migrated = false;
|
|
21
20
|
const theme = themeByTradename({ tradename });
|
|
22
21
|
const locale = Locale.es_ES;
|
|
23
22
|
const customer = {
|
|
@@ -74,7 +73,7 @@ const kameleoonConfig = {
|
|
|
74
73
|
};
|
|
75
74
|
const { Component: Messaging, queryBus } = process.env.EXPO_PUBLIC_APP_VARIANT === "test"
|
|
76
75
|
? checkoutMockBootstrap()
|
|
77
|
-
: checkoutBootstrap({ apiUrl: () => apiUrl, getAuthToken
|
|
76
|
+
: checkoutBootstrap({ apiUrl: () => apiUrl, getAuthToken });
|
|
78
77
|
const Root = root({
|
|
79
78
|
Messaging,
|
|
80
79
|
queryBus,
|
|
@@ -101,7 +100,7 @@ const ExpoRoot = () => {
|
|
|
101
100
|
isAccessible === false && React.createElement(Text, { variant: "heading" }, "Checkout is not accessible!"),
|
|
102
101
|
React.createElement(Router, null,
|
|
103
102
|
React.createElement(Routes, null,
|
|
104
|
-
React.createElement(Route, { path: "/checkout/*", element: React.createElement(Root, { basePath: "/checkout", customer: customer, layout: DummyLayout, locale: locale,
|
|
103
|
+
React.createElement(Route, { path: "/checkout/*", element: React.createElement(Root, { basePath: "/checkout", customer: customer, layout: DummyLayout, locale: locale, tradename: tradename, useRedirect: useRedirect, onCheckoutFlowSuccess: () => console.log("Checkout flow success!"), onNotAccessible: onNotAccessible }) }),
|
|
105
104
|
React.createElement(Route, { element: React.createElement(Navigate, { to: "/checkout", replace: true }), path: "*" })))))))) : null;
|
|
106
105
|
};
|
|
107
106
|
export { ExpoRoot };
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { BuildBootstrapFunctionReturn } from "@lookiero/messaging-react";
|
|
2
|
-
import { Tradename } from "@lookiero/sty-sp-tradename";
|
|
3
2
|
interface BootstrapFunctionArgs {
|
|
4
3
|
readonly getAuthToken: () => Promise<string>;
|
|
5
4
|
readonly apiUrl: () => string;
|
|
6
|
-
readonly tradename: Tradename;
|
|
7
|
-
readonly migrated: boolean;
|
|
8
5
|
}
|
|
9
6
|
interface BootstrapFunction {
|
|
10
7
|
(args: BootstrapFunctionArgs): BuildBootstrapFunctionReturn;
|
|
@@ -19,7 +19,7 @@ import { httpPricingByCheckoutIdView } from "../projection/pricing/httpPricingBy
|
|
|
19
19
|
import { httpReturnQuestionsByCheckoutItemIdView } from "../projection/returnQuestion/httpReturnQuestionsByCheckoutItemIdView";
|
|
20
20
|
import { baseBootstrap } from "./baseBootstrap";
|
|
21
21
|
const device = Platform.OS;
|
|
22
|
-
const bootstrap = ({ apiUrl, getAuthToken
|
|
22
|
+
const bootstrap = ({ apiUrl, getAuthToken }) => {
|
|
23
23
|
const httpGet = fetchHttpGet({ apiUrl, getAuthToken, device, version: VERSION });
|
|
24
24
|
const httpPost = fetchHttpPost({ apiUrl, getAuthToken, device, version: VERSION });
|
|
25
25
|
return baseBootstrap({
|
|
@@ -36,8 +36,6 @@ const bootstrap = ({ apiUrl, getAuthToken, tradename, migrated }) => {
|
|
|
36
36
|
}),
|
|
37
37
|
pricingByCheckoutIdView: httpPricingByCheckoutIdView({
|
|
38
38
|
httpPost,
|
|
39
|
-
tradename,
|
|
40
|
-
migrated,
|
|
41
39
|
}),
|
|
42
40
|
paymentFlowPayloadByCheckoutIdView: httpPaymentFlowPayloadByCheckoutIdView({
|
|
43
41
|
httpPost,
|
|
@@ -5,7 +5,7 @@ interface CheckoutItemFunctionArgs {
|
|
|
5
5
|
readonly id?: string;
|
|
6
6
|
readonly status: CheckoutItemStatus;
|
|
7
7
|
readonly feedbacks?: FeedbackProjection;
|
|
8
|
-
readonly replacedFor?: CheckoutItemProductVariantProjection;
|
|
8
|
+
readonly replacedFor?: CheckoutItemProductVariantProjection | null;
|
|
9
9
|
}
|
|
10
10
|
interface CheckoutItemFunction {
|
|
11
11
|
(args: CheckoutItemFunctionArgs): CheckoutItemProjection;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { HttpPostFunction } from "@lookiero/sty-psp-http";
|
|
2
|
-
import { Tradename } from "@lookiero/sty-sp-tradename";
|
|
3
2
|
import { PricingByCheckoutIdView } from "../../../projection/pricing/viewPricingByCheckoutId";
|
|
4
3
|
interface HttpPricingByCheckoutIdView extends PricingByCheckoutIdView {
|
|
5
4
|
}
|
|
6
5
|
interface HttpPricingByCheckoutIdViewFunctionArgs {
|
|
7
6
|
readonly httpPost: HttpPostFunction;
|
|
8
|
-
readonly tradename: Tradename;
|
|
9
|
-
readonly migrated: boolean;
|
|
10
7
|
}
|
|
11
8
|
interface HttpPricingByCheckoutIdViewFunction {
|
|
12
9
|
(args: HttpPricingByCheckoutIdViewFunctionArgs): HttpPricingByCheckoutIdView;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
endpoint: "/view-pricing-by-checkout-id",
|
|
1
|
+
const httpPricingByCheckoutIdView = ({ httpPost }) => async ({ checkoutId, signal }) => await httpPost({
|
|
2
|
+
endpoint: "/view-checkout-pricing-by-checkout-id",
|
|
4
3
|
body: { checkoutId },
|
|
5
4
|
signal,
|
|
6
5
|
result: {
|
|
7
6
|
error: null,
|
|
8
|
-
success: (response) =>
|
|
7
|
+
success: (response) => response,
|
|
9
8
|
},
|
|
10
9
|
});
|
|
11
10
|
export { httpPricingByCheckoutIdView };
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import { CheckoutPricingProjection } from "../../../projection/pricing/pricing";
|
|
2
|
-
import { PricingDto } from "./pricing";
|
|
3
2
|
declare const mockCheckoutPricingProjection: CheckoutPricingProjection;
|
|
4
|
-
|
|
5
|
-
export { mockCheckoutPricingProjection, mockPricingDto };
|
|
3
|
+
export { mockCheckoutPricingProjection };
|
|
@@ -26,19 +26,4 @@ const mockCheckoutPricingProjection = {
|
|
|
26
26
|
},
|
|
27
27
|
],
|
|
28
28
|
};
|
|
29
|
-
|
|
30
|
-
pendingToPay: { amount: 12127, currency: Currency.EUR },
|
|
31
|
-
subtotal: { amount: 21195, currency: Currency.EUR },
|
|
32
|
-
discount: { amount: 7068, currency: Currency.EUR },
|
|
33
|
-
discountPercentage: 35,
|
|
34
|
-
balanceDiscount: { amount: 1000, currency: Currency.EUR },
|
|
35
|
-
service: {
|
|
36
|
-
discount: { amount: 0, currency: Currency.EUR },
|
|
37
|
-
finalPrice: { amount: 1000, currency: Currency.EUR },
|
|
38
|
-
originalPrice: { amount: 1000, currency: Currency.EUR },
|
|
39
|
-
prepaid: false,
|
|
40
|
-
reference: "ps-fee",
|
|
41
|
-
},
|
|
42
|
-
orderTotal: { amount: 13127, currency: Currency.EUR },
|
|
43
|
-
};
|
|
44
|
-
export { mockCheckoutPricingProjection, mockPricingDto };
|
|
29
|
+
export { mockCheckoutPricingProjection };
|
|
@@ -26,7 +26,6 @@ interface RootProps {
|
|
|
26
26
|
readonly customer: Customer;
|
|
27
27
|
readonly layout: Layout;
|
|
28
28
|
readonly tradename: Tradename;
|
|
29
|
-
readonly migrated: boolean;
|
|
30
29
|
readonly onNotAccessible: () => void;
|
|
31
30
|
readonly onCheckoutFlowSuccess: OnCheckoutFlowSuccessFunction;
|
|
32
31
|
readonly useRedirect: () => Record<string, string>;
|
|
@@ -9,11 +9,11 @@ const root = ({ Messaging, queryBus, getAuthToken, development, sentry, kameleoo
|
|
|
9
9
|
const logger = sentryLogger(sentry);
|
|
10
10
|
const kameleoon = kameleoonConfig();
|
|
11
11
|
// eslint-disable-next-line react/display-name, react/prop-types
|
|
12
|
-
const Root = ({ basePath, locale, customer, layout, tradename,
|
|
12
|
+
const Root = ({ basePath, locale, customer, layout, tradename, onNotAccessible, onCheckoutFlowSuccess, useRedirect, useRoutes = reactRouterUseRoutes, }) => {
|
|
13
13
|
const handleOnI18nError = useCallback((error) => logger.captureException(error), []);
|
|
14
14
|
return (React.createElement(Messaging, { includeReactQueryDevTools: Platform.OS === "web" },
|
|
15
15
|
React.createElement(QueryBusProvider, { queryBus: queryBus },
|
|
16
|
-
React.createElement(Routing, { I18n: i18n({ tradename }), basePath: basePath, customer: customer, getAuthToken: getAuthToken, kameleoon: kameleoon, layout: layout, locale: locale,
|
|
16
|
+
React.createElement(Routing, { I18n: i18n({ tradename }), basePath: basePath, customer: customer, getAuthToken: getAuthToken, kameleoon: kameleoon, layout: layout, locale: locale, tradename: tradename, useRedirect: useRedirect, useRoutes: useRoutes, onCheckoutFlowSuccess: onCheckoutFlowSuccess, onI18nError: development ? undefined : handleOnI18nError, onNotAccessible: onNotAccessible }))));
|
|
17
17
|
};
|
|
18
18
|
const hoc = sentryLoggerHOC({ logger });
|
|
19
19
|
/**
|
|
@@ -6,7 +6,6 @@ interface StaticInfo {
|
|
|
6
6
|
readonly kameleoon: KameleoonEnvironment;
|
|
7
7
|
readonly customer: Customer;
|
|
8
8
|
readonly tradename: Tradename;
|
|
9
|
-
readonly migrated: boolean;
|
|
10
9
|
readonly basePath: string;
|
|
11
10
|
}
|
|
12
11
|
interface StaticInfoProviderProps {
|
|
@@ -14,7 +13,6 @@ interface StaticInfoProviderProps {
|
|
|
14
13
|
readonly kameleoon: KameleoonEnvironment;
|
|
15
14
|
readonly customer: Customer;
|
|
16
15
|
readonly tradename: Tradename;
|
|
17
|
-
readonly migrated: boolean;
|
|
18
16
|
readonly basePath: string;
|
|
19
17
|
}
|
|
20
18
|
declare const StaticInfoProvider: FC<StaticInfoProviderProps>;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import React, { createContext, useContext, useMemo } from "react";
|
|
2
2
|
import invariant from "tiny-invariant";
|
|
3
3
|
const StaticInfoContext = createContext(null);
|
|
4
|
-
const StaticInfoProvider = ({ children, kameleoon, customer, tradename,
|
|
4
|
+
const StaticInfoProvider = ({ children, kameleoon, customer, tradename, basePath }) => {
|
|
5
5
|
const value = useMemo(() => ({
|
|
6
6
|
kameleoon,
|
|
7
7
|
customer,
|
|
8
8
|
tradename,
|
|
9
|
-
migrated,
|
|
10
9
|
basePath,
|
|
11
|
-
}), [basePath, customer, kameleoon,
|
|
10
|
+
}), [basePath, customer, kameleoon, tradename]);
|
|
12
11
|
return React.createElement(StaticInfoContext.Provider, { value: value }, children);
|
|
13
12
|
};
|
|
14
13
|
const useStaticInfo = () => {
|
|
@@ -15,7 +15,6 @@ interface RoutingProps {
|
|
|
15
15
|
readonly kameleoon: KameleoonEnvironment;
|
|
16
16
|
readonly layout: Layout;
|
|
17
17
|
readonly tradename: Tradename;
|
|
18
|
-
readonly migrated: boolean;
|
|
19
18
|
readonly getAuthToken: () => Promise<string>;
|
|
20
19
|
readonly onNotAccessible: () => void;
|
|
21
20
|
readonly onCheckoutFlowSuccess: OnCheckoutFlowSuccessFunction;
|
|
@@ -12,11 +12,11 @@ import { Summary } from "../views/summary/Summary";
|
|
|
12
12
|
import { SummaryTabs } from "../views/summaryTabs/SummaryTabs";
|
|
13
13
|
import { CheckoutMiddleware } from "./CheckoutMiddleware";
|
|
14
14
|
import { Routes } from "./routes";
|
|
15
|
-
const Routing = ({ basePath = "", customer, locale, I18n, kameleoon, layout, tradename,
|
|
15
|
+
const Routing = ({ basePath = "", customer, locale, I18n, kameleoon, layout, tradename, getAuthToken, onI18nError, onNotAccessible, onCheckoutFlowSuccess, useRedirect, useRoutes = reactRouterUseRoutes, }) => {
|
|
16
16
|
return useRoutes([
|
|
17
17
|
{
|
|
18
18
|
path: "",
|
|
19
|
-
element: (React.createElement(StaticInfoProvider, { basePath: basePath, customer: customer, kameleoon: kameleoon,
|
|
19
|
+
element: (React.createElement(StaticInfoProvider, { basePath: basePath, customer: customer, kameleoon: kameleoon, tradename: tradename },
|
|
20
20
|
React.createElement(I18n, { loader: React.createElement(Spinner, null), locale: locale, onError: onI18nError },
|
|
21
21
|
React.createElement(Kameleoon, { loader: React.createElement(Spinner, null), siteCode: kameleoon.siteCode },
|
|
22
22
|
React.createElement(CheckoutMiddleware, { customerId: customer?.customerId, onNotAccessible: onNotAccessible },
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "15.
|
|
2
|
-
export declare const RELEASE = "checkout@15.
|
|
1
|
+
export declare const VERSION = "15.1.1";
|
|
2
|
+
export declare const RELEASE = "checkout@15.1.1";
|
package/dist/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "15.
|
|
2
|
-
export const RELEASE = "checkout@15.
|
|
1
|
+
export const VERSION = "15.1.1";
|
|
2
|
+
export const RELEASE = "checkout@15.1.1";
|
package/index.ts
CHANGED
|
@@ -24,8 +24,6 @@ interface FirstAvailableCheckoutByCustomerIdFunction {
|
|
|
24
24
|
interface BootstrapFunctionArgs {
|
|
25
25
|
readonly getAuthToken: () => Promise<string>;
|
|
26
26
|
readonly apiUrl: () => string;
|
|
27
|
-
readonly tradename: Tradename;
|
|
28
|
-
readonly migrated: boolean;
|
|
29
27
|
readonly sentry: () => SentryEnvironment;
|
|
30
28
|
readonly kameleoon: () => KameleoonEnvironment;
|
|
31
29
|
}
|
|
@@ -39,8 +37,8 @@ interface BootstrapFunction {
|
|
|
39
37
|
(args: BootstrapFunctionArgs): BootstrapFunctionReturn;
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
const bootstrap: BootstrapFunction = ({ apiUrl, getAuthToken,
|
|
43
|
-
const { Component: Messaging, queryBus } = checkoutBootstrap({ apiUrl, getAuthToken
|
|
40
|
+
const bootstrap: BootstrapFunction = ({ apiUrl, getAuthToken, sentry, kameleoon }) => {
|
|
41
|
+
const { Component: Messaging, queryBus } = checkoutBootstrap({ apiUrl, getAuthToken });
|
|
44
42
|
|
|
45
43
|
const firstAvailableCheckoutByCustomerId: FirstAvailableCheckoutByCustomerIdFunction = ({ customerId }) =>
|
|
46
44
|
queryBus(viewFirstAvailableCheckoutByCustomerId({ customerId: customerId as string }));
|
package/package.json
CHANGED
package/src/ExpoRoot.tsx
CHANGED
|
@@ -21,7 +21,6 @@ import { Customer } from "./projection/customer/customer";
|
|
|
21
21
|
import { RELEASE } from "./version";
|
|
22
22
|
|
|
23
23
|
const tradename = Tradename.LOOKIERO;
|
|
24
|
-
const migrated = false;
|
|
25
24
|
const theme = themeByTradename({ tradename });
|
|
26
25
|
const locale: Locale = Locale.es_ES;
|
|
27
26
|
|
|
@@ -89,7 +88,7 @@ const kameleoonConfig: KameleoonEnvironment = {
|
|
|
89
88
|
const { Component: Messaging, queryBus } =
|
|
90
89
|
process.env.EXPO_PUBLIC_APP_VARIANT === "test"
|
|
91
90
|
? checkoutMockBootstrap()
|
|
92
|
-
: checkoutBootstrap({ apiUrl: () => apiUrl, getAuthToken
|
|
91
|
+
: checkoutBootstrap({ apiUrl: () => apiUrl, getAuthToken });
|
|
93
92
|
|
|
94
93
|
const Root = root({
|
|
95
94
|
Messaging,
|
|
@@ -130,7 +129,6 @@ const ExpoRoot: FC = () => {
|
|
|
130
129
|
customer={customer}
|
|
131
130
|
layout={DummyLayout}
|
|
132
131
|
locale={locale}
|
|
133
|
-
migrated={migrated}
|
|
134
132
|
tradename={tradename}
|
|
135
133
|
useRedirect={useRedirect}
|
|
136
134
|
onCheckoutFlowSuccess={() => console.log("Checkout flow success!")}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Platform } from "react-native";
|
|
2
2
|
import { BuildBootstrapFunctionReturn } from "@lookiero/messaging-react";
|
|
3
3
|
import { fetchHttpGet, fetchHttpPost } from "@lookiero/sty-psp-http";
|
|
4
|
-
import { Tradename } from "@lookiero/sty-sp-tradename";
|
|
5
4
|
import { VERSION } from "../../version";
|
|
6
5
|
import { getCheckout, saveCheckout } from "../domain/checkout/model/httpCheckouts";
|
|
7
6
|
import { getCheckoutBooking, saveCheckoutBooking } from "../domain/checkoutBooking/model/httpCheckoutBookings";
|
|
@@ -28,15 +27,13 @@ const device = Platform.OS as Device;
|
|
|
28
27
|
interface BootstrapFunctionArgs {
|
|
29
28
|
readonly getAuthToken: () => Promise<string>;
|
|
30
29
|
readonly apiUrl: () => string;
|
|
31
|
-
readonly tradename: Tradename;
|
|
32
|
-
readonly migrated: boolean;
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
interface BootstrapFunction {
|
|
36
33
|
(args: BootstrapFunctionArgs): BuildBootstrapFunctionReturn;
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
const bootstrap: BootstrapFunction = ({ apiUrl, getAuthToken
|
|
36
|
+
const bootstrap: BootstrapFunction = ({ apiUrl, getAuthToken }) => {
|
|
40
37
|
const httpGet = fetchHttpGet({ apiUrl, getAuthToken, device, version: VERSION });
|
|
41
38
|
const httpPost = fetchHttpPost({ apiUrl, getAuthToken, device, version: VERSION });
|
|
42
39
|
|
|
@@ -54,8 +51,6 @@ const bootstrap: BootstrapFunction = ({ apiUrl, getAuthToken, tradename, migrate
|
|
|
54
51
|
}),
|
|
55
52
|
pricingByCheckoutIdView: httpPricingByCheckoutIdView({
|
|
56
53
|
httpPost,
|
|
57
|
-
tradename,
|
|
58
|
-
migrated,
|
|
59
54
|
}),
|
|
60
55
|
paymentFlowPayloadByCheckoutIdView: httpPaymentFlowPayloadByCheckoutIdView({
|
|
61
56
|
httpPost,
|
|
@@ -11,7 +11,7 @@ interface CheckoutItemFunctionArgs {
|
|
|
11
11
|
readonly id?: string;
|
|
12
12
|
readonly status: CheckoutItemStatus;
|
|
13
13
|
readonly feedbacks?: FeedbackProjection;
|
|
14
|
-
readonly replacedFor?: CheckoutItemProductVariantProjection;
|
|
14
|
+
readonly replacedFor?: CheckoutItemProductVariantProjection | null;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
interface CheckoutItemFunction {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { mock } from "jest-mock-extended";
|
|
2
2
|
import { fetchHttpPost } from "@lookiero/sty-psp-http";
|
|
3
|
-
import { Tradename } from "@lookiero/sty-sp-tradename";
|
|
4
3
|
import { httpPricingByCheckoutIdView as sut } from "./httpPricingByCheckoutIdView";
|
|
5
|
-
import {
|
|
6
|
-
import { mockCheckoutPricingProjection, mockPricingDto } from "./pricing.mock";
|
|
4
|
+
import { mockCheckoutPricingProjection } from "./pricing.mock";
|
|
7
5
|
|
|
8
6
|
const fetchMock = jest.fn();
|
|
9
7
|
global.fetch = fetchMock;
|
|
@@ -11,8 +9,6 @@ const apiUrl = "/api";
|
|
|
11
9
|
const getAuthToken = () => Promise.resolve("token");
|
|
12
10
|
const view = sut({
|
|
13
11
|
httpPost: fetchHttpPost({ apiUrl: () => apiUrl, getAuthToken, device: "web", version: "1.0.0" }),
|
|
14
|
-
tradename: Tradename.LOOKIERO,
|
|
15
|
-
migrated: false,
|
|
16
12
|
});
|
|
17
13
|
const signal = mock<AbortSignal>();
|
|
18
14
|
|
|
@@ -20,7 +16,7 @@ const checkoutId = "29790d24-b139-4ab8-b618-d796d101e974";
|
|
|
20
16
|
const pricingResponseOk: Response = {
|
|
21
17
|
ok: true,
|
|
22
18
|
status: 200,
|
|
23
|
-
text: () => Promise.resolve(JSON.stringify(
|
|
19
|
+
text: () => Promise.resolve(JSON.stringify(mockCheckoutPricingProjection)),
|
|
24
20
|
} as Response;
|
|
25
21
|
const pricingResponseNotFound: Response = {
|
|
26
22
|
ok: false,
|
|
@@ -37,88 +33,13 @@ describe("httpPricingByCheckoutIdView", () => {
|
|
|
37
33
|
const returnedPricing = await view({ checkoutId, signal });
|
|
38
34
|
|
|
39
35
|
expect(returnedPricing).toStrictEqual(mockCheckoutPricingProjection);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
});
|
|
48
|
-
fetchMock.mockReturnValue(Promise.resolve(pricingResponseOk));
|
|
49
|
-
|
|
50
|
-
const returnedPricing = await outfitteryMigratedView({ checkoutId, signal });
|
|
51
|
-
|
|
52
|
-
expect(returnedPricing).toStrictEqual({
|
|
53
|
-
currency: mockPricingDto.pendingToPay.currency,
|
|
54
|
-
finalPrice: mockPricingDto.pendingToPay.amount,
|
|
55
|
-
originalPrice: mockPricingDto.subtotal.amount,
|
|
56
|
-
modifiers: [
|
|
57
|
-
{
|
|
58
|
-
amount: mockPricingDto.discount.amount,
|
|
59
|
-
type: "DISCOUNT",
|
|
60
|
-
context: "PROMOCODE",
|
|
61
|
-
translationKey: "summary.discount",
|
|
62
|
-
percentage: mockPricingDto.discountPercentage,
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
amount: mockPricingDto.balanceDiscount.amount,
|
|
66
|
-
type: "DISCOUNT",
|
|
67
|
-
context: "BALANCE",
|
|
68
|
-
translationKey: "summary.credit",
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("filters zero modifiers and maps negative amounts as absolute values", async () => {
|
|
75
|
-
const mockPricingWithZeroAndNegativeAmounts: PricingDto = {
|
|
76
|
-
pendingToPay: { amount: 12127, currency: mockPricingDto.pendingToPay.currency },
|
|
77
|
-
subtotal: { amount: 21195, currency: mockPricingDto.subtotal.currency },
|
|
78
|
-
discount: { amount: -7068, currency: mockPricingDto.discount.currency },
|
|
79
|
-
discountPercentage: 35,
|
|
80
|
-
balanceDiscount: { amount: 0, currency: mockPricingDto.balanceDiscount.currency },
|
|
81
|
-
service: {
|
|
82
|
-
discount: { amount: 0, currency: mockPricingDto.service.discount.currency },
|
|
83
|
-
finalPrice: { amount: -1000, currency: mockPricingDto.service.finalPrice.currency },
|
|
84
|
-
originalPrice: {
|
|
85
|
-
amount: mockPricingDto.service.originalPrice.amount,
|
|
86
|
-
currency: mockPricingDto.service.originalPrice.currency,
|
|
87
|
-
},
|
|
88
|
-
prepaid: false,
|
|
89
|
-
reference: "ps-fee",
|
|
90
|
-
},
|
|
91
|
-
orderTotal: { amount: 13127, currency: mockPricingDto.orderTotal.currency },
|
|
92
|
-
};
|
|
93
|
-
const pricingResponseOkWithNegativeAndZeroModifiers: Response = {
|
|
94
|
-
ok: true,
|
|
95
|
-
status: 200,
|
|
96
|
-
text: () => Promise.resolve(JSON.stringify({ result: mockPricingWithZeroAndNegativeAmounts })),
|
|
97
|
-
} as Response;
|
|
98
|
-
fetchMock.mockReturnValue(Promise.resolve(pricingResponseOkWithNegativeAndZeroModifiers));
|
|
99
|
-
|
|
100
|
-
const returnedPricing = await view({ checkoutId, signal });
|
|
101
|
-
|
|
102
|
-
expect(returnedPricing).toStrictEqual({
|
|
103
|
-
currency: mockPricingDto.pendingToPay.currency,
|
|
104
|
-
finalPrice: 12127,
|
|
105
|
-
originalPrice: 21195,
|
|
106
|
-
modifiers: [
|
|
107
|
-
{
|
|
108
|
-
amount: 7068,
|
|
109
|
-
type: "DISCOUNT",
|
|
110
|
-
context: "PROMOCODE",
|
|
111
|
-
translationKey: "summary.discount",
|
|
112
|
-
percentage: 35,
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
amount: 1000,
|
|
116
|
-
type: "DISCOUNT",
|
|
117
|
-
context: "PS_FEE",
|
|
118
|
-
translationKey: "summary.fee",
|
|
119
|
-
},
|
|
120
|
-
],
|
|
121
|
-
});
|
|
36
|
+
expect(fetchMock).toHaveBeenCalledWith(
|
|
37
|
+
`${apiUrl}/view-checkout-pricing-by-checkout-id`,
|
|
38
|
+
expect.objectContaining({
|
|
39
|
+
body: JSON.stringify({ checkoutId }),
|
|
40
|
+
method: "POST",
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
122
43
|
});
|
|
123
44
|
|
|
124
45
|
it("returns null for a 404 response", async () => {
|
|
@@ -1,37 +1,29 @@
|
|
|
1
1
|
import { HttpPostFunction } from "@lookiero/sty-psp-http";
|
|
2
|
-
import { Tradename } from "@lookiero/sty-sp-tradename";
|
|
3
2
|
import {
|
|
4
3
|
PricingByCheckoutIdView,
|
|
5
4
|
ViewPricingByCheckoutIdResult,
|
|
6
5
|
} from "../../../projection/pricing/viewPricingByCheckoutId";
|
|
7
|
-
import { PricingDto, toPricingProjection } from "./pricing";
|
|
8
6
|
|
|
9
7
|
interface HttpPricingByCheckoutIdView extends PricingByCheckoutIdView {}
|
|
10
8
|
|
|
11
9
|
interface HttpPricingByCheckoutIdViewFunctionArgs {
|
|
12
10
|
readonly httpPost: HttpPostFunction;
|
|
13
|
-
readonly tradename: Tradename;
|
|
14
|
-
readonly migrated: boolean;
|
|
15
11
|
}
|
|
16
12
|
|
|
17
13
|
interface HttpPricingByCheckoutIdViewFunction {
|
|
18
14
|
(args: HttpPricingByCheckoutIdViewFunctionArgs): HttpPricingByCheckoutIdView;
|
|
19
15
|
}
|
|
20
16
|
|
|
21
|
-
interface ViewPricingByCheckoutIdResponse {
|
|
22
|
-
readonly result: PricingDto;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
17
|
const httpPricingByCheckoutIdView: HttpPricingByCheckoutIdViewFunction =
|
|
26
|
-
({ httpPost
|
|
18
|
+
({ httpPost }) =>
|
|
27
19
|
async ({ checkoutId, signal }) =>
|
|
28
|
-
await httpPost<
|
|
29
|
-
endpoint: "/view-pricing-by-checkout-id",
|
|
20
|
+
await httpPost<ViewPricingByCheckoutIdResult>({
|
|
21
|
+
endpoint: "/view-checkout-pricing-by-checkout-id",
|
|
30
22
|
body: { checkoutId },
|
|
31
23
|
signal,
|
|
32
24
|
result: {
|
|
33
25
|
error: null,
|
|
34
|
-
success: (response) =>
|
|
26
|
+
success: (response) => response,
|
|
35
27
|
},
|
|
36
28
|
});
|
|
37
29
|
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
CheckoutPricingContext,
|
|
5
5
|
CheckoutPricingType,
|
|
6
6
|
} from "../../../projection/pricing/pricing";
|
|
7
|
-
import { PricingDto } from "./pricing";
|
|
8
7
|
|
|
9
8
|
const mockCheckoutPricingProjection: CheckoutPricingProjection = {
|
|
10
9
|
currency: Currency.EUR,
|
|
@@ -33,20 +32,4 @@ const mockCheckoutPricingProjection: CheckoutPricingProjection = {
|
|
|
33
32
|
],
|
|
34
33
|
};
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
pendingToPay: { amount: 12127, currency: Currency.EUR },
|
|
38
|
-
subtotal: { amount: 21195, currency: Currency.EUR },
|
|
39
|
-
discount: { amount: 7068, currency: Currency.EUR },
|
|
40
|
-
discountPercentage: 35,
|
|
41
|
-
balanceDiscount: { amount: 1000, currency: Currency.EUR },
|
|
42
|
-
service: {
|
|
43
|
-
discount: { amount: 0, currency: Currency.EUR },
|
|
44
|
-
finalPrice: { amount: 1000, currency: Currency.EUR },
|
|
45
|
-
originalPrice: { amount: 1000, currency: Currency.EUR },
|
|
46
|
-
prepaid: false,
|
|
47
|
-
reference: "ps-fee",
|
|
48
|
-
},
|
|
49
|
-
orderTotal: { amount: 13127, currency: Currency.EUR },
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export { mockCheckoutPricingProjection, mockPricingDto };
|
|
35
|
+
export { mockCheckoutPricingProjection };
|
|
@@ -33,7 +33,6 @@ interface RootProps {
|
|
|
33
33
|
readonly customer: Customer;
|
|
34
34
|
readonly layout: Layout;
|
|
35
35
|
readonly tradename: Tradename;
|
|
36
|
-
readonly migrated: boolean;
|
|
37
36
|
readonly onNotAccessible: () => void;
|
|
38
37
|
readonly onCheckoutFlowSuccess: OnCheckoutFlowSuccessFunction;
|
|
39
38
|
readonly useRedirect: () => Record<string, string>;
|
|
@@ -51,7 +50,6 @@ const root: RootFunction = ({ Messaging, queryBus, getAuthToken, development, se
|
|
|
51
50
|
customer,
|
|
52
51
|
layout,
|
|
53
52
|
tradename,
|
|
54
|
-
migrated,
|
|
55
53
|
onNotAccessible,
|
|
56
54
|
onCheckoutFlowSuccess,
|
|
57
55
|
useRedirect,
|
|
@@ -70,7 +68,6 @@ const root: RootFunction = ({ Messaging, queryBus, getAuthToken, development, se
|
|
|
70
68
|
kameleoon={kameleoon}
|
|
71
69
|
layout={layout}
|
|
72
70
|
locale={locale}
|
|
73
|
-
migrated={migrated}
|
|
74
71
|
tradename={tradename}
|
|
75
72
|
useRedirect={useRedirect}
|
|
76
73
|
useRoutes={useRoutes}
|
|
@@ -8,7 +8,6 @@ import { StaticInfoProvider, useStaticInfo as sut } from "./useStaticInfo";
|
|
|
8
8
|
const kameleoon = {} as KameleoonEnvironment;
|
|
9
9
|
const customer = { customerId: "6667283e-5f61-457e-b637-88736265b78f" } as Customer;
|
|
10
10
|
const tradename = Tradename.LOOKIERO;
|
|
11
|
-
const migrated = false;
|
|
12
11
|
const basePath = "";
|
|
13
12
|
|
|
14
13
|
interface WrapperProps {
|
|
@@ -16,13 +15,7 @@ interface WrapperProps {
|
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
const Wrapper: FC<WrapperProps> = ({ children }) => (
|
|
19
|
-
<StaticInfoProvider
|
|
20
|
-
basePath={basePath}
|
|
21
|
-
customer={customer}
|
|
22
|
-
kameleoon={kameleoon}
|
|
23
|
-
migrated={migrated}
|
|
24
|
-
tradename={tradename}
|
|
25
|
-
>
|
|
18
|
+
<StaticInfoProvider basePath={basePath} customer={customer} kameleoon={kameleoon} tradename={tradename}>
|
|
26
19
|
{children}
|
|
27
20
|
</StaticInfoProvider>
|
|
28
21
|
);
|
|
@@ -35,7 +28,6 @@ describe("useStaticInfo hook", () => {
|
|
|
35
28
|
kameleoon,
|
|
36
29
|
customer,
|
|
37
30
|
tradename,
|
|
38
|
-
migrated,
|
|
39
31
|
basePath,
|
|
40
32
|
};
|
|
41
33
|
|
|
@@ -8,7 +8,6 @@ interface StaticInfo {
|
|
|
8
8
|
readonly kameleoon: KameleoonEnvironment;
|
|
9
9
|
readonly customer: Customer;
|
|
10
10
|
readonly tradename: Tradename;
|
|
11
|
-
readonly migrated: boolean;
|
|
12
11
|
readonly basePath: string;
|
|
13
12
|
}
|
|
14
13
|
|
|
@@ -19,27 +18,18 @@ interface StaticInfoProviderProps {
|
|
|
19
18
|
readonly kameleoon: KameleoonEnvironment;
|
|
20
19
|
readonly customer: Customer;
|
|
21
20
|
readonly tradename: Tradename;
|
|
22
|
-
readonly migrated: boolean;
|
|
23
21
|
readonly basePath: string;
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
const StaticInfoProvider: FC<StaticInfoProviderProps> = ({
|
|
27
|
-
children,
|
|
28
|
-
kameleoon,
|
|
29
|
-
customer,
|
|
30
|
-
tradename,
|
|
31
|
-
migrated,
|
|
32
|
-
basePath,
|
|
33
|
-
}) => {
|
|
24
|
+
const StaticInfoProvider: FC<StaticInfoProviderProps> = ({ children, kameleoon, customer, tradename, basePath }) => {
|
|
34
25
|
const value = useMemo(
|
|
35
26
|
() => ({
|
|
36
27
|
kameleoon,
|
|
37
28
|
customer,
|
|
38
29
|
tradename,
|
|
39
|
-
migrated,
|
|
40
30
|
basePath,
|
|
41
31
|
}),
|
|
42
|
-
[basePath, customer, kameleoon,
|
|
32
|
+
[basePath, customer, kameleoon, tradename],
|
|
43
33
|
);
|
|
44
34
|
|
|
45
35
|
return <StaticInfoContext.Provider value={value}>{children}</StaticInfoContext.Provider>;
|
|
@@ -28,7 +28,6 @@ interface RoutingProps {
|
|
|
28
28
|
readonly kameleoon: KameleoonEnvironment;
|
|
29
29
|
readonly layout: Layout;
|
|
30
30
|
readonly tradename: Tradename;
|
|
31
|
-
readonly migrated: boolean;
|
|
32
31
|
readonly getAuthToken: () => Promise<string>;
|
|
33
32
|
readonly onNotAccessible: () => void;
|
|
34
33
|
readonly onCheckoutFlowSuccess: OnCheckoutFlowSuccessFunction;
|
|
@@ -45,7 +44,6 @@ const Routing: FC<RoutingProps> = ({
|
|
|
45
44
|
kameleoon,
|
|
46
45
|
layout,
|
|
47
46
|
tradename,
|
|
48
|
-
migrated,
|
|
49
47
|
getAuthToken,
|
|
50
48
|
onI18nError,
|
|
51
49
|
onNotAccessible,
|
|
@@ -57,13 +55,7 @@ const Routing: FC<RoutingProps> = ({
|
|
|
57
55
|
{
|
|
58
56
|
path: "",
|
|
59
57
|
element: (
|
|
60
|
-
<StaticInfoProvider
|
|
61
|
-
basePath={basePath}
|
|
62
|
-
customer={customer}
|
|
63
|
-
kameleoon={kameleoon}
|
|
64
|
-
migrated={migrated}
|
|
65
|
-
tradename={tradename}
|
|
66
|
-
>
|
|
58
|
+
<StaticInfoProvider basePath={basePath} customer={customer} kameleoon={kameleoon} tradename={tradename}>
|
|
67
59
|
<I18n loader={<Spinner />} locale={locale} onError={onI18nError}>
|
|
68
60
|
<Kameleoon loader={<Spinner />} siteCode={kameleoon.siteCode}>
|
|
69
61
|
<CheckoutMiddleware customerId={customer?.customerId as string} onNotAccessible={onNotAccessible}>
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Tradename } from "@lookiero/sty-sp-tradename";
|
|
2
|
-
import { PriceProjection } from "../../../projection/price/price";
|
|
3
|
-
import { CheckoutPricingProjection } from "../../../projection/pricing/pricing";
|
|
4
|
-
interface ServiceDto {
|
|
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
|
-
interface PricingDto {
|
|
13
|
-
readonly balanceDiscount: PriceProjection;
|
|
14
|
-
readonly discount: PriceProjection;
|
|
15
|
-
readonly discountPercentage: number;
|
|
16
|
-
readonly orderTotal: PriceProjection;
|
|
17
|
-
readonly pendingToPay: PriceProjection;
|
|
18
|
-
readonly service: ServiceDto;
|
|
19
|
-
readonly subtotal: PriceProjection;
|
|
20
|
-
}
|
|
21
|
-
interface ToPricingProjectionFunctionArgs {
|
|
22
|
-
readonly pricing: PricingDto;
|
|
23
|
-
readonly tradename: Tradename;
|
|
24
|
-
readonly migrated: boolean;
|
|
25
|
-
}
|
|
26
|
-
interface ToPricingProjectionFunction {
|
|
27
|
-
(args: ToPricingProjectionFunctionArgs): CheckoutPricingProjection;
|
|
28
|
-
}
|
|
29
|
-
declare const toPricingProjection: ToPricingProjectionFunction;
|
|
30
|
-
export type { PricingDto };
|
|
31
|
-
export { toPricingProjection };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Tradename } from "@lookiero/sty-sp-tradename";
|
|
2
|
-
import { CheckoutPricingContext, CheckoutPricingType, } from "../../../projection/pricing/pricing";
|
|
3
|
-
const toPricingProjection = ({ pricing, tradename, migrated, }) => {
|
|
4
|
-
const shouldDisplayPsFeeModifier = tradename === Tradename.LOOKIERO || (tradename === Tradename.OUTFITTERY && !migrated);
|
|
5
|
-
const modifiers = [
|
|
6
|
-
{
|
|
7
|
-
amount: pricing.discount.amount,
|
|
8
|
-
type: CheckoutPricingType.DISCOUNT,
|
|
9
|
-
context: CheckoutPricingContext.PROMOCODE,
|
|
10
|
-
translationKey: "summary.discount",
|
|
11
|
-
percentage: pricing.discountPercentage,
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
amount: pricing.balanceDiscount.amount,
|
|
15
|
-
type: CheckoutPricingType.DISCOUNT,
|
|
16
|
-
context: CheckoutPricingContext.BALANCE,
|
|
17
|
-
translationKey: "summary.credit",
|
|
18
|
-
},
|
|
19
|
-
...(shouldDisplayPsFeeModifier
|
|
20
|
-
? [
|
|
21
|
-
{
|
|
22
|
-
amount: pricing.service.finalPrice.amount,
|
|
23
|
-
type: CheckoutPricingType.DISCOUNT,
|
|
24
|
-
context: CheckoutPricingContext.PS_FEE,
|
|
25
|
-
translationKey: "summary.fee",
|
|
26
|
-
},
|
|
27
|
-
]
|
|
28
|
-
: []),
|
|
29
|
-
]
|
|
30
|
-
.map((modifier) => ({ ...modifier, amount: Math.abs(modifier.amount) }))
|
|
31
|
-
.filter(({ amount }) => amount !== 0);
|
|
32
|
-
return {
|
|
33
|
-
currency: pricing.pendingToPay.currency,
|
|
34
|
-
finalPrice: pricing.pendingToPay.amount,
|
|
35
|
-
originalPrice: pricing.subtotal.amount,
|
|
36
|
-
modifiers,
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
export { toPricingProjection };
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Tradename } from "@lookiero/sty-sp-tradename";
|
|
2
|
-
import { PriceProjection } from "../../../projection/price/price";
|
|
3
|
-
import {
|
|
4
|
-
CheckoutPricingContext,
|
|
5
|
-
CheckoutPricingProjection,
|
|
6
|
-
CheckoutPricingType,
|
|
7
|
-
} from "../../../projection/pricing/pricing";
|
|
8
|
-
|
|
9
|
-
interface ServiceDto {
|
|
10
|
-
readonly discount: PriceProjection;
|
|
11
|
-
readonly finalPrice: PriceProjection;
|
|
12
|
-
readonly originalPrice: PriceProjection;
|
|
13
|
-
readonly prepaid: boolean;
|
|
14
|
-
readonly reference: string;
|
|
15
|
-
readonly paidWithPromocode?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface PricingDto {
|
|
19
|
-
readonly balanceDiscount: PriceProjection;
|
|
20
|
-
readonly discount: PriceProjection;
|
|
21
|
-
readonly discountPercentage: number;
|
|
22
|
-
readonly orderTotal: PriceProjection;
|
|
23
|
-
readonly pendingToPay: PriceProjection;
|
|
24
|
-
readonly service: ServiceDto;
|
|
25
|
-
readonly subtotal: PriceProjection;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface ToPricingProjectionFunctionArgs {
|
|
29
|
-
readonly pricing: PricingDto;
|
|
30
|
-
readonly tradename: Tradename;
|
|
31
|
-
readonly migrated: boolean;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface ToPricingProjectionFunction {
|
|
35
|
-
(args: ToPricingProjectionFunctionArgs): CheckoutPricingProjection;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const toPricingProjection: ToPricingProjectionFunction = ({
|
|
39
|
-
pricing,
|
|
40
|
-
tradename,
|
|
41
|
-
migrated,
|
|
42
|
-
}): CheckoutPricingProjection => {
|
|
43
|
-
const shouldDisplayPsFeeModifier =
|
|
44
|
-
tradename === Tradename.LOOKIERO || (tradename === Tradename.OUTFITTERY && !migrated);
|
|
45
|
-
|
|
46
|
-
const modifiers = [
|
|
47
|
-
{
|
|
48
|
-
amount: pricing.discount.amount,
|
|
49
|
-
type: CheckoutPricingType.DISCOUNT,
|
|
50
|
-
context: CheckoutPricingContext.PROMOCODE,
|
|
51
|
-
translationKey: "summary.discount",
|
|
52
|
-
percentage: pricing.discountPercentage,
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
amount: pricing.balanceDiscount.amount,
|
|
56
|
-
type: CheckoutPricingType.DISCOUNT,
|
|
57
|
-
context: CheckoutPricingContext.BALANCE,
|
|
58
|
-
translationKey: "summary.credit",
|
|
59
|
-
},
|
|
60
|
-
...(shouldDisplayPsFeeModifier
|
|
61
|
-
? [
|
|
62
|
-
{
|
|
63
|
-
amount: pricing.service.finalPrice.amount,
|
|
64
|
-
type: CheckoutPricingType.DISCOUNT,
|
|
65
|
-
context: CheckoutPricingContext.PS_FEE,
|
|
66
|
-
translationKey: "summary.fee",
|
|
67
|
-
},
|
|
68
|
-
]
|
|
69
|
-
: []),
|
|
70
|
-
]
|
|
71
|
-
.map((modifier) => ({ ...modifier, amount: Math.abs(modifier.amount) }))
|
|
72
|
-
.filter(({ amount }) => amount !== 0);
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
currency: pricing.pendingToPay.currency,
|
|
76
|
-
finalPrice: pricing.pendingToPay.amount,
|
|
77
|
-
originalPrice: pricing.subtotal.amount,
|
|
78
|
-
modifiers,
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export type { PricingDto };
|
|
83
|
-
export { toPricingProjection };
|