Skip to content

Commit

Permalink
feat(pn-13915): show custom payment button when user comes from TPP a…
Browse files Browse the repository at this point in the history
…pp (#1468)
  • Loading branch information
fbianchicodermine authored Feb 24, 2025
1 parent 07579cf commit 96accd9
Show file tree
Hide file tree
Showing 14 changed files with 351 additions and 98 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Fragment, memo, useEffect, useState } from 'react';
import React, { memo, useEffect, useState } from 'react';

import { Download } from '@mui/icons-material/';
import { Alert, Box, Button, Link, RadioGroup, Typography } from '@mui/material';
Expand All @@ -14,6 +14,7 @@ import {
PaymentStatus,
PaymentsData,
} from '../../models';
import { PaymentTpp } from '../../models/NotificationDetail';
import { formatEurocentToCurrency } from '../../utility';
import { getLocalizedOrDefaultLabel } from '../../utility/localization.utility';
import { getPaymentCache, setPaymentCache } from '../../utility/paymentCaching.utility';
Expand All @@ -26,6 +27,7 @@ const FAQ_NOTIFICATION_CANCELLED_REFUND = '/faq#notifica-pagata-rimborso';

type Props = {
payments: PaymentsData;
paymentTpp?: PaymentTpp;
isCancelled: boolean;
timerF24: number;
landingSiteUrl: string;
Expand All @@ -38,18 +40,21 @@ type Props = {
unwrap: () => Promise<PaymentAttachment>;
};
onPayClick: (noticeCode?: string, creditorTaxId?: string, amount?: number) => void;
onPayTppClick?: (noticeCode?: string, creditorTaxId?: string, retrievalId?: string) => void;
handleTrackEvent?: (event: EventPaymentRecipientType, param?: object) => void;
handleFetchPaymentsInfo: (payment: Array<PaymentDetails | NotificationDetailPayment>) => void;
};

const NotificationPaymentRecipient: React.FC<Props> = ({
payments,
paymentTpp,
isCancelled,
timerF24,
landingSiteUrl,
iun,
getPaymentAttachmentAction,
onPayClick,
onPayTppClick,
handleTrackEvent,
handleFetchPaymentsInfo,
}) => {
Expand Down Expand Up @@ -137,9 +142,17 @@ const NotificationPaymentRecipient: React.FC<Props> = ({
}
};

const handleCheckPaymentSelected = () => {
const handleCheckPaymentSelected = (paymentType: 'default' | 'tpp') => {
if (selectedPayment.pagoPa) {
setErrorOnPayment(false);
if (paymentType === 'tpp') {
onPayTppClick?.(
selectedPayment?.pagoPa?.noticeCode,
selectedPayment?.pagoPa?.creditorTaxId,
paymentTpp?.retrievalId
);
return;
}
onPayClick(
selectedPayment.pagoPa.noticeCode,
selectedPayment.pagoPa.creditorTaxId,
Expand Down Expand Up @@ -233,57 +246,19 @@ const NotificationPaymentRecipient: React.FC<Props> = ({
</Alert>
)}
{!allPaymentsIsPaid && (
<Fragment>
<Button
color={errorOnPayment ? 'error' : 'primary'}
fullWidth
variant={errorOnPayment ? 'outlined' : 'contained'}
data-testid="pay-button"
onClick={handleCheckPaymentSelected}
>
{getLocalizedOrDefaultLabel('notifications', 'detail.payment.submit')}
&nbsp;
{selectedPayment?.pagoPa?.amount
? formatEurocentToCurrency(selectedPayment.pagoPa?.amount)
: null}
</Button>
{selectedPayment?.pagoPa?.attachment && (
<Button
fullWidth
variant="outlined"
data-testid="download-pagoPA-notice-button"
disabled={!selectedPayment.pagoPa}
onClick={() => downloadAttachment(PaymentAttachmentSName.PAGOPA)}
>
<Download fontSize="small" sx={{ mr: 1 }} />
{getLocalizedOrDefaultLabel(
'notifications',
'detail.payment.download-pagoPA-notice'
)}
</Button>
)}
{selectedPayment?.f24 ? (
<Box key="attachment" data-testid="f24-download">
<NotificationPaymentF24Item
f24Item={selectedPayment?.f24}
getPaymentAttachmentAction={getPaymentAttachmentAction}
isPagoPaAttachment
handleTrackDownloadF24={() =>
handleTrackEventFn(EventPaymentRecipientType.SEND_F24_DOWNLOAD)
}
handleTrackDownloadF24Success={() =>
handleTrackEventFn(EventPaymentRecipientType.SEND_F24_DOWNLOAD_SUCCESS)
}
handleTrackDownloadF24Timeout={() =>
handleTrackEventFn(EventPaymentRecipientType.SEND_F24_DOWNLOAD_TIMEOUT)
}
timerF24={timerF24}
disableDownload={areOtherDowloading}
handleDownload={setAreOtherDowloading}
/>
</Box>
) : null}
</Fragment>
<PaymentButtons
paymentTpp={paymentTpp}
iun={iun}
selectedPayment={selectedPayment}
downloadAttachment={downloadAttachment}
getPaymentAttachmentAction={getPaymentAttachmentAction}
handleTrackEventFn={handleTrackEventFn}
timerF24={timerF24}
areOtherDowloading={areOtherDowloading}
errorOnPayment={errorOnPayment}
setAreOtherDowloading={setAreOtherDowloading}
handleCheckPaymentSelected={handleCheckPaymentSelected}
/>
)}
</>
)}
Expand Down Expand Up @@ -323,3 +298,101 @@ const NotificationPaymentRecipient: React.FC<Props> = ({
};

export default memo(NotificationPaymentRecipient);

type PaymentButtonsProps = Pick<
Props,
'paymentTpp' | 'iun' | 'getPaymentAttachmentAction' | 'timerF24'
> & {
selectedPayment?: PaymentDetails | { pagoPa: null; f24?: null };
areOtherDowloading: boolean;
errorOnPayment: boolean;
setAreOtherDowloading: (value: boolean) => void;
downloadAttachment: (attachmentName: PaymentAttachmentSName) => void;
handleTrackEventFn: (event: EventPaymentRecipientType, param?: object) => void;
handleCheckPaymentSelected: (paymentType: 'default' | 'tpp') => void;
};

const PaymentButtons = ({
paymentTpp,
iun,
selectedPayment,
timerF24,
areOtherDowloading,
errorOnPayment,
setAreOtherDowloading,
downloadAttachment,
getPaymentAttachmentAction,
handleTrackEventFn,
handleCheckPaymentSelected,
}: PaymentButtonsProps) => {
const hasPaymentTpp = paymentTpp?.iun === iun;
return (
<>
{hasPaymentTpp && (
<Button
color={errorOnPayment ? 'error' : 'primary'}
fullWidth
variant={errorOnPayment ? 'outlined' : 'contained'}
data-testid="tpp-pay-button"
onClick={() => handleCheckPaymentSelected('tpp')}
>
{getLocalizedOrDefaultLabel('notifications', 'detail.payment.submit-tpp', undefined, {
name: paymentTpp?.paymentButton,
})}
</Button>
)}
<Button
color={errorOnPayment ? 'error' : 'primary'}
fullWidth
variant={errorOnPayment || hasPaymentTpp ? 'outlined' : 'contained'}
data-testid="pay-button"
onClick={() => handleCheckPaymentSelected('default')}
>
{hasPaymentTpp &&
getLocalizedOrDefaultLabel('notifications', 'detail.payment.pay-with-other-methods')}
{!hasPaymentTpp && (
<>
{getLocalizedOrDefaultLabel('notifications', 'detail.payment.submit')}
&nbsp;
{selectedPayment?.pagoPa?.amount
? formatEurocentToCurrency(selectedPayment.pagoPa?.amount)
: null}
</>
)}
</Button>
{selectedPayment?.pagoPa?.attachment && (
<Button
fullWidth
variant={hasPaymentTpp ? 'text' : 'outlined'}
data-testid="download-pagoPA-notice-button"
disabled={!selectedPayment.pagoPa}
onClick={() => downloadAttachment(PaymentAttachmentSName.PAGOPA)}
>
<Download fontSize="small" sx={{ mr: 1 }} />
{getLocalizedOrDefaultLabel('notifications', 'detail.payment.download-pagoPA-notice')}
</Button>
)}
{selectedPayment?.f24 && (
<Box key="attachment" data-testid="f24-download">
<NotificationPaymentF24Item
f24Item={selectedPayment?.f24}
getPaymentAttachmentAction={getPaymentAttachmentAction}
isPagoPaAttachment
handleTrackDownloadF24={() =>
handleTrackEventFn(EventPaymentRecipientType.SEND_F24_DOWNLOAD)
}
handleTrackDownloadF24Success={() =>
handleTrackEventFn(EventPaymentRecipientType.SEND_F24_DOWNLOAD_SUCCESS)
}
handleTrackDownloadF24Timeout={() =>
handleTrackEventFn(EventPaymentRecipientType.SEND_F24_DOWNLOAD_TIMEOUT)
}
timerF24={timerF24}
disableDownload={areOtherDowloading}
handleDownload={setAreOtherDowloading}
/>
</Box>
)}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -432,4 +432,52 @@ describe('NotificationPaymentRecipient Component', () => {
fireEvent.click(f24ButtonToCheck);
expect(getPaymentAttachmentActionMk).toBeCalledTimes(1);
});

it('should show tpp button if payments tpp is present and click onPayTppClick', () => {
const onPayTppClick = vi.fn();
const paymentTpp = {
retrievalId: 'retrievalId',
iun,
paymentButton: 'paymentButton',
};
const { getByTestId, queryAllByTestId } = render(
<NotificationPaymentRecipient
payments={paymentsData}
paymentTpp={paymentTpp}
isCancelled={false}
timerF24={F24TIMER}
iun={iun}
getPaymentAttachmentAction={vi.fn()}
onPayClick={() => {}}
onPayTppClick={onPayTppClick}
handleFetchPaymentsInfo={() => {}}
landingSiteUrl=""
/>
);
const payTppButton = getByTestId('tpp-pay-button');
expect(payTppButton).toBeInTheDocument();

const payButton = getByTestId('pay-button');
expect(payButton).toHaveTextContent('detail.payment.pay-with-other-methods');

const pageSelector = getByTestId('pageSelector');
const pageButtons = pageSelector?.querySelectorAll('button');
fireEvent.click(pageButtons[1]);

// select payment
const paymentIndex = paymentsData.pagoPaF24.findIndex(
(payment) => payment.pagoPa?.status === PaymentStatus.REQUIRED
);
const item = queryAllByTestId('pagopa-item')[paymentIndex];
const radioButton = item.querySelector('[data-testid="radio-button"] input');
fireEvent.click(radioButton!);

// click pay
fireEvent.click(payTppButton);
expect(onPayTppClick).toHaveBeenCalledWith(
paymentsData.pagoPaF24[paymentIndex].pagoPa?.noticeCode,
paymentsData.pagoPaF24[paymentIndex].pagoPa?.creditorTaxId,
paymentTpp.retrievalId
);
});
});
6 changes: 6 additions & 0 deletions packages/pn-commons/src/models/NotificationDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export interface NotificationDetail {
radd?: INotificationDetailTimeline;
}

export type PaymentTpp = {
paymentButton: string;
retrievalId: string;
iun: string;
};

export type PaymentsData = {
pagoPaF24: Array<PaymentDetails>;
f24Only: Array<F24PaymentDetails>;
Expand Down
2 changes: 1 addition & 1 deletion packages/pn-personafisica-webapp/openapitools.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
},
"bff-payments": {
"generatorName": "typescript-axios",
"inputSpec": "https://raw.githubusercontent.com/pagopa/pn-bff/5355801397984dd3c3187e417d49e90c6c4076ae/docs/openapi/api-external-pn-bff-payments.yaml",
"inputSpec": "https://raw.githubusercontent.com/pagopa/pn-bff/0857ea8cbecae4f892bbb2ed19f24f91db2fcbb2/docs/openapi/api-external-pn-bff-payments.yaml",
"output": "./src/generated-client/payments",
"additionalProperties": {
"supportsES6": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
"summary-in-progress": "Pagamento in corso",
"amount": "Importo",
"submit": "Paga",
"submit-tpp": "Paga con {{name}}",
"pay-with-other-methods": "Paga con altri metodi di pagamento",
"download-f24": "Scarica F24",
"pay-with-f24": "Se preferisci, puoi pagare tramite F24.",
"download-f24-in-progress": "Documento in elaborazione",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@ import { NotificationDetailRouteState } from '../models/NotificationDetail';
import { NotificationId } from '../models/Notifications';
import { PFEventsType } from '../models/PFEventsType';
import { useAppDispatch } from '../redux/hooks';
import {
NOTIFICATION_ACTIONS,
exchangeNotificationQrCode,
exchangeNotificationRetrievalId,
} from '../redux/notification/actions';
import { NOTIFICATION_ACTIONS, exchangeNotificationQrCode } from '../redux/notification/actions';
import { exchangeNotificationRetrievalId } from '../redux/sidemenu/actions';
import { ServerResponseErrorCode } from '../utility/AppError/types';
import PFEventStrategyFactory from '../utility/MixpanelUtils/PFEventStrategyFactory';
import {
Expand Down
Loading

0 comments on commit 96accd9

Please sign in to comment.