Skip to content

Commit

Permalink
feat: ui to recover from first instalment talpa failure
Browse files Browse the repository at this point in the history
  • Loading branch information
sirtawast committed Dec 16, 2024
1 parent 75d6506 commit aefe6e4
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 64 deletions.
4 changes: 4 additions & 0 deletions frontend/benefit/handler/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,10 @@
"noChanges": "Ei muutoksia lomaketietoihin. Mikäli poistit tai lisäsit liitetiedostoja, voit kirjata niiden syyn."
},
"helperText": "Kirjaa milloin ja mitä kautta hakija on ollut yhteydessä. Tiedot tulevat näkyviin hakemuksen muutoshistoriassa."
},
"talpaStatusChange": {
"heading": "Maksun tilan muutos",
"text": "Tuen automaattinen maksu on epäonnistunut. Palauta hakemus odottamaan automaattista Talpa-käsittelyä tai merkitse maksu suoritetuksi jolloin maksutapahtuma on vahvistettava manuaalisesti Talpalta."
}
},
"decision": {
Expand Down
4 changes: 4 additions & 0 deletions frontend/benefit/handler/public/locales/fi/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,10 @@
"noChanges": "Ei muutoksia lomaketietoihin. Mikäli poistit tai lisäsit liitetiedostoja, voit kirjata niiden syyn."
},
"helperText": "Kirjaa milloin ja mitä kautta hakija on ollut yhteydessä. Tiedot tulevat näkyviin hakemuksen muutoshistoriassa."
},
"talpaStatusChange": {
"heading": "Maksun tilan muutos",
"text": "Tuen automaattinen maksu on epäonnistunut. Palauta hakemus odottamaan automaattista Talpa-käsittelyä tai merkitse maksu suoritetuksi jolloin maksutapahtuma on vahvistettava manuaalisesti Talpalta."
}
},
"decision": {
Expand Down
4 changes: 4 additions & 0 deletions frontend/benefit/handler/public/locales/sv/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,10 @@
"noChanges": "Ei muutoksia lomaketietoihin. Mikäli poistit tai lisäsit liitetiedostoja, voit kirjata niiden syyn."
},
"helperText": "Kirjaa milloin ja mitä kautta hakija on ollut yhteydessä. Tiedot tulevat näkyviin hakemuksen muutoshistoriassa."
},
"talpaStatusChange": {
"heading": "Maksun tilan muutos",
"text": "Tuen automaattinen maksu on epäonnistunut. Palauta hakemus odottamaan automaattista Talpa-käsittelyä tai merkitse maksu suoritetuksi jolloin maksutapahtuma on vahvistettava manuaalisesti Talpalta."
}
},
"decision": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ALL_APPLICATION_STATUSES, ROUTES } from 'benefit/handler/constants';
import useTalpaStatusTransition from 'benefit/handler/hooks/useTalpaStatusTransition';
import useInstalmentStatusTransition from 'benefit/handler/hooks/useInstalmentStatusTransition';
import {
ApplicationListTableColumns,
ApplicationListTableTransforms,
Expand All @@ -8,31 +8,21 @@ import {
getTagStyleForStatus,
getTalpaTagStyleForStatus,
} from 'benefit/handler/utils/applications';
import { APPLICATION_STATUSES, TALPA_STATUSES } from 'benefit-shared/constants';
import {
APPLICATION_STATUSES,
INSTALMENT_STATUSES,
TALPA_STATUSES,
} from 'benefit-shared/constants';
import {
AhjoError,
ApplicationAlteration,
ApplicationListItemData,
Instalment,
} from 'benefit-shared/types/application';
import {
Button,
IconArrowRedo,
IconArrowUndo,
IconSpeechbubbleText,
Table,
Tag,
Tooltip,
} from 'hds-react';
import { IconSpeechbubbleText, Table, Tag, Tooltip } from 'hds-react';
import { TFunction } from 'next-i18next';
import * as React from 'react';
import LoadingSkeleton from 'react-loading-skeleton';
import Container from 'shared/components/container/Container';
import {
$Grid,
$GridCell,
} from 'shared/components/forms/section/FormSection.sc';
import Modal from 'shared/components/modal/Modal';
import { $Link } from 'shared/components/table/Table.sc';
import {
convertToUIDateAndTimeFormat,
Expand All @@ -52,6 +42,7 @@ import {
$TagWrapper,
$UnreadMessagesCount,
} from './ApplicationList.sc';
import TalpaStatusChangeModal from './TalpaStatusChangeDialog';
import { useApplicationList } from './useApplicationList';

export interface ApplicationListProps {
Expand Down Expand Up @@ -120,7 +111,13 @@ export const renderPaymentTagPerStatus = (
clickTalpaTag?: (id: string, talpaStatus: TALPA_STATUSES) => void
): JSX.Element => (
<$TagWrapper $colors={getTalpaTagStyleForStatus(talpaStatus)}>
<Tag onClick={() => clickTalpaTag(id, talpaStatus)}>
<Tag
onClick={
talpaStatus === TALPA_STATUSES.REJECTED_BY_TALPA && id
? () => clickTalpaTag(id, talpaStatus)
: null
}
>
{t(`applications.list.columns.talpaStatuses.${String(talpaStatus)}`)}
</Tag>
</$TagWrapper>
Expand Down Expand Up @@ -170,7 +167,16 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
const [showTalpaModal, setShowTaplaModal] = React.useState(false);
const [selectedApplication, setSelectedApplication] = React.useState('');

const { mutate: changeTalpaStatus } = useTalpaStatusTransition();
const {
mutate: changeInstalmentStatus,
isSuccess: isInstalmentStatusChanged,
} = useInstalmentStatusTransition();

React.useEffect(() => {
if (isInstalmentStatusChanged) {
setShowTaplaModal(false);
}
}, [isInstalmentStatusChanged]);

const renderTableActions = React.useCallback(
(
Expand Down Expand Up @@ -401,11 +407,14 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
headerName: getHeader('paymentStatus'),
key: 'paymentStatus',
isSortable: true,
transform: ({ talpaStatus, id }: ApplicationListTableTransforms) =>
transform: ({
talpaStatus,
firstInstalment,
}: ApplicationListTableTransforms) =>
renderPaymentTagPerStatus(
t,
talpaStatus as TALPA_STATUSES,
id,
firstInstalment?.id,
onTalpaTagClick
),
},
Expand Down Expand Up @@ -460,9 +469,8 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
}

const statusAsString = isAllStatuses ? 'all' : status.join(',');
const handleTalpaStatusChange = (talpaStatus: TALPA_STATUSES): void => {
changeTalpaStatus({ id: selectedApplication, status: talpaStatus });
console.log('status:', talpaStatus, selectedApplication);
const handleTalpaStatusChange = (talpaStatus: INSTALMENT_STATUSES): void => {
changeInstalmentStatus({ id: selectedApplication, status: talpaStatus });
};

return (
Expand All @@ -482,44 +490,10 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
</$EmptyHeading>
)}

<Modal
id="1234"
variant="primary"
<TalpaStatusChangeModal
isOpen={showTalpaModal}
submitButtonLabel="ues"
cancelButtonLabel="cancel"
handleToggle={() => false}
handleSubmit={() => false}
customContent={
<Container>
<$Grid columns={2}>
<$GridCell>
<Button
theme="coat"
iconLeft={<IconArrowUndo />}
onClick={() =>
handleTalpaStatusChange(TALPA_STATUSES.NOT_SENT_TO_TALPA)
}
>
Palauta odottamaan
</Button>
</$GridCell>
<$GridCell>
<Button
theme="coat"
iconLeft={<IconArrowRedo />}
onClick={() =>
handleTalpaStatusChange(
TALPA_STATUSES.PARTIALLY_SENT_TO_TALPA
)
}
>
Merkitse maksetuksi
</Button>
</$GridCell>
</$Grid>
</Container>
}
onClose={() => setShowTaplaModal(false)}
onStatusChange={handleTalpaStatusChange}
/>
</$ApplicationList>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { INSTALMENT_STATUSES } from 'benefit-shared/constants';
import { Button, Dialog, IconArrowRedo, IconArrowUndo } from 'hds-react';
import React from 'react';
import {
$Grid,
$GridCell,
} from 'shared/components/forms/section/FormSection.sc';
import Modal from 'shared/components/modal/Modal';
import { useTheme } from 'styled-components';

import { useApplicationList } from './useApplicationList';

const TalpaStatusChangeModal: React.FC<{
isOpen: boolean;
onClose: () => void;
onStatusChange: (status: INSTALMENT_STATUSES) => void;
}> = ({ isOpen, onClose, onStatusChange }) => {
const { t } = useApplicationList();
const theme = useTheme();

return (
<Modal
id="dialog-talpa-payment-status-change"
theme={theme.components.modal.coat}
variant="primary"
isOpen={isOpen}
submitButtonLabel="yes"
cancelButtonLabel="cancel"
handleToggle={() => false}
handleSubmit={() => false}
customContent={
<>
<Dialog.Content>
<$Grid columns={1} alignItems="center">
<$GridCell>
<h2>{t('applications.dialog.talpaStatusChange.heading')}</h2>
<p>{t('applications.dialog.talpaStatusChange.text')}</p>
</$GridCell>
</$Grid>
</Dialog.Content>

<Dialog.ActionButtons>
<Button
theme="coat"
iconLeft={<IconArrowUndo />}
onClick={() => onStatusChange(INSTALMENT_STATUSES.WAITING)}
>
{t('common:applications.list.actions.return_as_waiting')}
</Button>
<Button
theme="coat"
iconLeft={<IconArrowRedo />}
onClick={() => onStatusChange(INSTALMENT_STATUSES.PAID)}
>
{t('common:applications.list.actions.mark_as_paid')}
</Button>
<Button theme="coat" variant="secondary" onClick={onClose}>
{t('common:applications.actions.close')}
</Button>
</Dialog.ActionButtons>
</>
}
/>
);
};

export default TalpaStatusChangeModal;
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const useApplicationListData = (
handled_by_ahjo_automation,
handled_at: handledAt,
ahjo_error,
first_instalment,
second_instalment,
alterations,
} = application;
Expand Down Expand Up @@ -77,6 +78,7 @@ const useApplicationListData = (
ahjoError: camelcaseKeys(ahjo_error, { deep: true }) || null,
decisionDate: convertToUIDateFormat(batch?.decision_date) || '-',
calculatedBenefitAmount: calculation?.calculated_benefit_amount || '0',
firstInstalment: camelcaseKeys(first_instalment),
secondInstalment: camelcaseKeys(second_instalment),
alterations: alterations || [],
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { $Section } from 'benefit/handler/components/applicationReview/handlingView/DecisionCalculationAccordion.sc';
import useInstalmentStatusTransition from 'benefit/handler/hooks/useInstalmentStatusTransition';
import {
ALTERATION_STATE,
INSTALMENT_STATUSES,
Expand All @@ -14,6 +15,7 @@ import { formatFloatToEvenEuros } from 'shared/utils/string.utils';

import { renderPaymentTagPerStatus } from '../../applicationList/ApplicationList';
import { renderInstalmentTagPerStatus } from '../../applicationList/ApplicationListForInstalments';
import TalpaStatusChangeModal from '../../applicationList/TalpaStatusChangeDialog';
import {
$Column,
$Wrapper,
Expand All @@ -28,7 +30,24 @@ type Props = {
const InstalmentAccordionSections: React.FC<Props> = ({ data }) => {
const translationsBase = 'common:calculators.result';
const { t } = useTranslation();

const [showTalpaModal, setShowTaplaModal] = React.useState(false);
const {
mutate: changeInstalmentStatus,
isSuccess: isInstalmentStatusChanged,
} = useInstalmentStatusTransition();

React.useEffect(() => {
if (isInstalmentStatusChanged) {
setShowTaplaModal(false);
}
}, [isInstalmentStatusChanged]);

const handleTalpaStatusChange = (talpaStatus: INSTALMENT_STATUSES): void => {
changeInstalmentStatus({
id: data?.firstInstalment?.id,
status: talpaStatus,
});
};
const secondInstalmentText = data.secondInstalment ? (
<>
{t(`${translationsBase}.secondInstalment`)}{' '}
Expand All @@ -39,14 +58,23 @@ const InstalmentAccordionSections: React.FC<Props> = ({ data }) => {
const { amounts, areInstalmentsPaid, isSecondInstalmentReduced } =
useInstalmentAccordionSections(data);

const onTalpaTagClick = (): void => {
setShowTaplaModal(true);
};

return (
<>
<$Section>
<$CalculatorTableRow>
<$ViewField>{t(`${translationsBase}.firstInstalment`)}</$ViewField>

<$RowWrap>
{renderPaymentTagPerStatus(t, data.talpaStatus)}
{renderPaymentTagPerStatus(
t,
data.talpaStatus,
data?.firstInstalment?.id,
onTalpaTagClick
)}
<div>{formatFloatToEvenEuros(amounts.firstInstalment)}</div>
</$RowWrap>
</$CalculatorTableRow>
Expand Down Expand Up @@ -179,6 +207,12 @@ const InstalmentAccordionSections: React.FC<Props> = ({ data }) => {
{formatFloatToEvenEuros(amounts.totalAfterRecoveries)}
</$CalculatorTableRow>
</$Section>

<TalpaStatusChangeModal
isOpen={showTalpaModal}
onClose={() => setShowTaplaModal(false)}
onStatusChange={handleTalpaStatusChange}
/>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const useInstalmentStatusTransition = (): UseMutationResult<
{
onSuccess: () => {
void queryClient.invalidateQueries('applicationsList');
void queryClient.invalidateQueries('application');
void queryClient.invalidateQueries('applications');
},
onError: (error: AxiosError<Error, Record<string, string[]>>) => {
showErrorToast(
Expand Down
1 change: 1 addition & 0 deletions frontend/benefit/handler/src/types/applicationList.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface ApplicationListTableTransforms {
applicationOrigin?: APPLICATION_ORIGINS;
ahjoError: AhjoError;
calculatedBenefitAmount?: string;
firstInstalment?: Instalment;
secondInstalment?: Instalment;
alterations: ApplicationAlterationData[];
talpaStatus?: TALPA_STATUSES;
Expand Down
3 changes: 2 additions & 1 deletion frontend/benefit/handler/src/utils/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ export const getTalpaTagStyleForStatus = (
text = theme.colors.white;
break;

case TALPA_STATUSES.SUCCESFULLY_SENT_TO_TALPA:
case TALPA_STATUSES.SUCCESFULLY_SENT_TO_TALPA ||
TALPA_STATUSES.PARTIALLY_SENT_TO_TALPA:
background = theme.colors.success;
text = theme.colors.white;
break;
Expand Down
1 change: 1 addition & 0 deletions frontend/benefit/shared/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export enum TALPA_STATUSES {
NOT_SENT_TO_TALPA = 'not_sent_to_talpa',
REJECTED_BY_TALPA = 'rejected_by_talpa',
SUCCESFULLY_SENT_TO_TALPA = 'succesfully_sent_to_talpa',
PARTIALLY_SENT_TO_TALPA = 'partially_sent_to_talpa',
}

export enum APPLICATION_ORIGINS {
Expand Down
Loading

0 comments on commit aefe6e4

Please sign in to comment.