Skip to content

Commit

Permalink
MOL-439/MOL-532: integration for processor module
Browse files Browse the repository at this point in the history
  • Loading branch information
tdang1-shopmacher committed Oct 14, 2024
1 parent ee27c45 commit 119662d
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 66 deletions.
2 changes: 1 addition & 1 deletion application/.env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ENABLE_NEW_JSX_TRANSFORM="true"
FAST_REFRESH="true"

ENTRY_POINT_URI_PATH="mollie"
PROJECT_KEY="shopm-adv-dev"
PROJECT_KEY="shopm-adv-windev"
CLOUD_IDENTIFIER="gcp-eu"
CUSTOM_APPLICATION_ID="app-id"
APPLICATION_URL="http://localhost:3001"
2 changes: 1 addition & 1 deletion application/custom-application-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const config = {
cloudIdentifier: CLOUD_IDENTIFIER,
env: {
development: {
initialProjectKey: 'shopm-adv-dev',
initialProjectKey: 'shopm-adv-windev',
},
production: {
applicationId: CUSTOM_APPLICATION_ID,
Expand Down
2 changes: 1 addition & 1 deletion application/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jest.mock('./src/constants', () => {
View: 'ViewMollie',
Manage: 'TestMollie',
},
PROJECT_KEY: 'shopm-adv-dev',
PROJECT_KEY: 'shopm-adv-windev',
CLOUD_IDENTIFIER: 'gcp-eu',
CUSTOM_APPLICATION_ID: '',
APPLICATION_URL: 'http://localhost:3001',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const MethodDetailsForm = (props: TCustomObjectDetailsFormProps) => {
onBlur={formik.handleBlur}
isReadOnly={props.isReadOnly}
horizontalConstraint={13}
isRequired={false}
renderError={(errorKey) => {
if (errorKey === 'invalidLength') {
return intl.formatMessage(
Expand Down
15 changes: 6 additions & 9 deletions application/src/components/method-details/method-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const MethodDetails = (props: TMethodDetailsProps) => {
});

const handleSubmit = async (formikValues: TMethodObjectValueFormValues) => {
console.log('formikValues', formikValues);
try {
if (method?.container && method?.key && formikValues) {
await customObjectUpdater.execute({
Expand Down Expand Up @@ -88,16 +87,11 @@ const MethodDetails = (props: TMethodDetailsProps) => {
) => {
try {
if (method?.container && method?.key && formikValues) {
let clonedValues = { ...formikValues, ...{ status: status } };
await customObjectUpdater.execute({
container: method?.container,
key: method?.key,
value: JSON.stringify({
id: formikValues.id,
description: formikValues.description,
status: status,
imageUrl: formikValues.imageUrl,
displayOrder: formikValues.displayOrder,
}),
value: JSON.stringify(clonedValues),
});
showNotification({
kind: NOTIFICATION_KINDS_SIDE.success,
Expand Down Expand Up @@ -219,7 +213,10 @@ const MethodDetails = (props: TMethodDetailsProps) => {
/>
<CustomFormModalPage.FormPrimaryButton
label={CustomFormModalPage.Intl.save}
onClick={() => formProps.submitForm()}
onClick={(event) => {
event.preventDefault();
formProps.submitForm();
}}
isDisabled={
formProps.isSubmitting || !formProps.isDirty || !canManage
}
Expand Down
44 changes: 20 additions & 24 deletions application/src/components/welcome/welcome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ const Welcome = () => {
),
},
{ key: 'image', label: intl.formatMessage(messages.iconHeader) },
{ key: 'order', label: intl.formatMessage(messages.displayOrderHeader) },
{
key: 'order',
label: intl.formatMessage(messages.displayOrderHeader),
},
];
const customObjectUpdater = useCustomObjectDetailsUpdater();
const { page, perPage } = usePaginationState();
Expand All @@ -85,7 +88,8 @@ const Welcome = () => {
const [refresh, setRefresh] = useState<number>(0);

const { fetchedData, fetchedDataLoading } = usePaymentMethodsFetcher(
extension?.destination?.url
extension?.destination?.url,
projectLanguages
);

const handleRefresh = useCallback(() => {
Expand Down Expand Up @@ -175,23 +179,19 @@ const Welcome = () => {
<CheckInactiveIcon color="neutral60"></CheckInactiveIcon>
);
case 'name':
return (
<Text.Wrap data-testid={`name-column-${item.id}`}>
{item.name
? formatLocalizedString(
{
name: item.name,
},
{
key: 'name',
locale: dataLocale,
fallbackOrder: projectLanguages,
fallback: NO_VALUE_FALLBACK,
}
)
: item.description}
</Text.Wrap>
);
return item.name
? formatLocalizedString(
{
name: item.name,
},
{
key: 'name',
locale: dataLocale,
fallbackOrder: projectLanguages,
fallback: NO_VALUE_FALLBACK,
}
)
: item.description;
case 'image':
return (
<IconButton
Expand All @@ -209,11 +209,7 @@ const Welcome = () => {
></IconButton>
);
case 'order':
return (
<Text.Wrap data-testid={`display-order-column-${item.id}`}>
{item.displayOrder ?? '-'}
</Text.Wrap>
);
return item.displayOrder ?? '-';
default:
return null;
}
Expand Down
38 changes: 25 additions & 13 deletions application/src/hooks/use-mollie-connector/use-mollie-connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
MollieMethod,
CustomMethodObject,
MollieResult,
SupportedPaymentMethods,
} from '../../types/app';

/**
Expand All @@ -29,27 +30,32 @@ const config = {
};

const convertMollieMethodToCustomMethod = (
results: MollieResult
results: MollieResult,
projectLanguages: string[]
): CustomMethodObject[] => {
const methods = results['_embedded']['methods'];
const availableMethods = methods.filter(
(method: MollieMethod) => method.status === 'activated'
(method: MollieMethod) =>
method.status === 'activated' &&
SupportedPaymentMethods[method.id as SupportedPaymentMethods]
);
return availableMethods.map((method: MollieMethod) => ({
id: method.id,
name: {
'en-GB': method.description,
},
description: {
'en-GB': '',
},
name: projectLanguages.reduce((acc, lang) => {
acc[lang] = method.description;
return acc;
}, {} as Record<string, string>),
description: projectLanguages.reduce((acc, lang) => {
acc[lang] = '';
return acc;
}, {} as Record<string, string>),
imageUrl: method.image.svg,
status: 'Inactive',
displayOrder: undefined,
}));
};

const getMethods = async (targetUrl?: string) => {
const getMethods = async (projectLanguages: string[], targetUrl?: string) => {
if (!targetUrl) {
logger.error('usePaymentMethodsFetcher - No target URL provided');
return [];
Expand Down Expand Up @@ -78,26 +84,32 @@ const getMethods = async (targetUrl?: string) => {
}
)
.then((res) =>
convertMollieMethodToCustomMethod(res as unknown as MollieResult)
convertMollieMethodToCustomMethod(
res as unknown as MollieResult,
projectLanguages
)
)
.catch((error) => logger.error(error));
};

export const usePaymentMethodsFetcher = (url: string | undefined) => {
export const usePaymentMethodsFetcher = (
url: string | undefined,
projectLanguages: string[]
) => {
const [fetchedData, setFetchedData] = useState<CustomMethodObject[]>([]);
const [fetchedDataLoading, setFetchedDataLoading] = useState<boolean>(true);

useEffect(() => {
const fetchData = async () => {
const data = (await getMethods(url)) ?? [];
const data = (await getMethods(projectLanguages, url)) ?? [];
setFetchedData(data);
setFetchedDataLoading(false);
};

if (url) {
fetchData();
}
}, [url]);
}, [url, projectLanguages]);

return { fetchedData, fetchedDataLoading };
};
13 changes: 13 additions & 0 deletions application/src/types/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,16 @@ export type MollieResult = {
methods: MollieMethod[];
};
};

export enum SupportedPaymentMethods {
ideal = 'ideal',
creditcard = 'creditcard',
bancontact = 'bancontact',
banktransfer = 'banktransfer',
przelewy24 = 'przelewy24',
kbc = 'kbc',
blik = 'blik',
applepay = 'applepay',
paypal = 'paypal',
giftcard = 'giftcard',
}
102 changes: 85 additions & 17 deletions processor/src/service/payment.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,80 @@ import { parseStringToJsonObject } from '../utils/app.utils';
import ApplePaySession from '@mollie/api-client/dist/types/src/data/applePaySession/ApplePaySession';
import { getMethodConfigObjects } from '../commercetools/customObjects.commercetools';

type CustomMethod = {
id: string;
name: Record<string, string>;
description: Record<string, string>;
image: string;
order: number;
};

/**
* Validates and sorts the payment methods.
*
* @param {CustomMethod[]} methods - The list of payment methods.
* @param {CustomObject[]} configObjects - The configuration objects.
* @return {CustomMethod[]} - The validated and sorted payment methods.
*/
const validateAndSortMethods = (methods: CustomMethod[], configObjects: CustomObject[]): CustomMethod[] => {
if (!configObjects.length) {
return methods.filter(
(method: CustomMethod) => SupportedPaymentMethods[method.id.toString() as SupportedPaymentMethods],
);
}

return methods
.filter((method) => isValidMethod(method, configObjects))
.map((method) => mapMethodToCustomMethod(method, configObjects))
.sort((a, b) => b.order - a.order); // Descending order sort
};

/**
* Checks if a method is valid based on the configuration objects.
*
* @param {CustomMethod} method - The payment method.
* @param {CustomObject[]} configObjects - The configuration objects.
* @return {boolean} - True if the method is valid, false otherwise.
*/
const isValidMethod = (method: CustomMethod, configObjects: CustomObject[]): boolean => {
return (
!!configObjects.find((config) => config.key === method.id && config.value.status === 'Active') &&
!!SupportedPaymentMethods[method.id.toString() as SupportedPaymentMethods]
);
};

/**
* Maps a payment method to a custom method.
*
* @param {CustomMethod} method - The payment method.
* @param {CustomObject[]} configObjects - The configuration objects.
* @return {CustomMethod} - The custom method.
*/
const mapMethodToCustomMethod = (method: CustomMethod, configObjects: CustomObject[]): CustomMethod => {
const config = configObjects.find((config) => config.key === method.id);

return {
id: method.id,
name: config?.value?.name,
description: config?.value?.description,
image: config?.value?.imageUrl,
order: config?.value?.displayOrder || 0,
};
};

/**
* Determines if the card component should be enabled.
*
* @param {CustomMethod[]} validatedMethods - The validated payment methods.
* @return {boolean} - True if the card component should be enabled, false otherwise.
*/
const shouldEnableCardComponent = (validatedMethods: CustomMethod[]): boolean => {
return (
toBoolean(readConfiguration().mollie.cardComponent, true) &&
validatedMethods.some((method) => method.id === PaymentMethod.creditcard)
);
};

/**
* Handles listing payment methods by payment.
*
Expand All @@ -72,27 +146,21 @@ export const handleListPaymentMethodsByPayment = async (ctPayment: Payment): Pro
const mollieOptions = await mapCommercetoolsPaymentCustomFieldsToMollieListParams(ctPayment);
const methods: List<Method> = await listPaymentMethods(mollieOptions);
const configObjects: CustomObject[] = await getMethodConfigObjects();
let validatedMethods: Method[] = [];
if (configObjects.length) {
validatedMethods = methods.filter(
(method) =>
!!configObjects.find((config) => config.key === method.id && config.value.status === 'Active') &&
SupportedPaymentMethods[method.id.toString() as SupportedPaymentMethods],
);
} else {
validatedMethods = methods.filter(
(method: Method) => SupportedPaymentMethods[method.id.toString() as SupportedPaymentMethods],
);
}

const enableCardComponent =
toBoolean(readConfiguration().mollie.cardComponent, true) &&
validatedMethods.filter((method: Method) => method.id === PaymentMethod.creditcard).length > 0;
const customMethods = methods.map((method) => ({
id: method.id,
name: { 'en-GB': method.description },
description: { 'en-GB': '' },
image: method.image.svg,
order: 0,
}));
const validatedMethods = validateAndSortMethods(customMethods, configObjects);

const enableCardComponent = shouldEnableCardComponent(validatedMethods);
const ctUpdateActions: UpdateAction[] = [];

if (enableCardComponent) {
validatedMethods.splice(
validatedMethods.findIndex((method: Method) => method.id === PaymentMethod.creditcard),
validatedMethods.findIndex((method) => method.id === PaymentMethod.creditcard),
1,
);
}
Expand Down

0 comments on commit 119662d

Please sign in to comment.