Skip to content

Commit

Permalink
feat: add talpa status and decision date to apps which are "in paymen…
Browse files Browse the repository at this point in the history
…t" state
  • Loading branch information
sirtawast committed Oct 15, 2024
1 parent bfa6591 commit d88e1f9
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 67 deletions.
19 changes: 15 additions & 4 deletions backend/benefit/applications/api/v1/serializers/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
ApplicationBatchStatus,
ApplicationOrigin,
ApplicationStatus,
ApplicationTalpaStatus,
AttachmentRequirement,
AttachmentType,
BenefitType,
Expand Down Expand Up @@ -1904,6 +1905,7 @@ class Meta:
"ahjo_case_id",
"batch",
"ahjo_error",
"talpa_status",
]

read_only_fields = [
Expand All @@ -1927,6 +1929,7 @@ class Meta:
"ahjo_case_id",
"batch",
"ahjo_error",
"talpa_status",
]

archived = serializers.BooleanField()
Expand Down Expand Up @@ -1971,18 +1974,26 @@ def get_latest_ahjo_error(self, obj) -> Union[Dict, None]:
),
)

batch = serializers.SerializerMethodField("get_batch_status")
batch = serializers.SerializerMethodField("get_batch_info")

def get_batch_status(self, obj):
return {"status": getattr(obj.batch, "status", None)}
def get_batch_info(self, obj):
return {
"status": getattr(obj.batch, "status", None),
"decision_date": getattr(obj.batch, "decision_date", None),
}

ahjo_case_id = serializers.CharField()
application_number = serializers.IntegerField()

status = serializers.ChoiceField(
choices=ApplicationStatus.choices,
validators=[ApplicantApplicationStatusValidator()],
help_text="Status of the application, visible to the applicant",
help_text="Status of the application",
)

talpa_status = serializers.ChoiceField(
choices=ApplicationTalpaStatus.choices,
help_text="Talpa status of the application",
)

application_origin = serializers.CharField()
Expand Down
8 changes: 7 additions & 1 deletion frontend/benefit/handler/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
"statusArchive": "Päätös",
"ahjoStatus": "Päätös",
"talpaStatus": "Maksun tila",
"decisionDate": "Päätöspäivä",
"benefitAmount": "Tuen määrä",
"statuses": {
"cancelled": "Peruutettu",
Expand All @@ -213,6 +214,11 @@
"rejected": "Kielteinen",
"archival": "Myönteinen"
},
"talpaStatuses": {
"not_sent_to_talpa": "Odottaa maksua",
"rejected_by_talpa": "Virhe maksussa",
"succesfully_sent_to_talpa": "Lähetetty maksuun"
},
"calculationEndDate": "Viim. tukipäivä"
},
"messages": {
Expand Down Expand Up @@ -1144,7 +1150,7 @@
"cancelled": "Hakemus peruttiin",
"decisionMakerName": "Päättäjä",
"decisionMakerTitle": "Päättäjän titteli",
"decisionDate": "Päätöspäivämäärä",
"decisionDate": "Päätöspäivä",
"sectionOfTheLaw": "Pykälä",
"p2pTitle": "P2P-tarkastuksen tiedot",
"p2pInspector": "Tarkastaja, P2P",
Expand Down
8 changes: 7 additions & 1 deletion frontend/benefit/handler/public/locales/fi/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
"statusArchive": "Päätös tai tila",
"ahjoStatus": "Päätös",
"talpaStatus": "Maksun tila",
"decisionDate": "Päätöspäivä",
"benefitAmount": "Tuen määrä",
"statuses": {
"cancelled": "Peruutettu",
Expand All @@ -213,6 +214,11 @@
"rejected": "Kielteinen",
"archival": "Myönteinen"
},
"talpaStatuses": {
"not_sent_to_talpa": "Odottaa maksua",
"rejected_by_talpa": "Virhe maksussa",
"succesfully_sent_to_talpa": "Lähetetty maksuun"
},
"calculationEndDate": "Viim. tukipäivä"
},
"messages": {
Expand Down Expand Up @@ -1144,7 +1150,7 @@
"cancelled": "Hakemus peruttiin",
"decisionMakerName": "Päättäjä",
"decisionMakerTitle": "Päättäjän titteli",
"decisionDate": "Päätöspäivämäärä",
"decisionDate": "Päätöspäivä",
"sectionOfTheLaw": "Pykälä",
"p2pTitle": "P2P-tarkastuksen tiedot",
"p2pInspector": "Tarkastaja, P2P",
Expand Down
8 changes: 7 additions & 1 deletion frontend/benefit/handler/public/locales/sv/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
"statusArchive": "Päätös",
"ahjoStatus": "Päätös",
"talpaStatus": "Maksun tila",
"decisionDate": "Päätöspäivä",
"benefitAmount": "Tuen määrä",
"statuses": {
"cancelled": "Peruutettu",
Expand All @@ -213,6 +214,11 @@
"rejected": "Kielteinen",
"archival": "Myönteinen"
},
"talpaStatuses": {
"not_sent_to_talpa": "Odottaa maksua",
"rejected_by_talpa": "Virhe maksussa",
"succesfully_sent_to_talpa": "Lähetetty maksuun"
},
"calculationEndDate": "Viim. tukipäivä"
},
"messages": {
Expand Down Expand Up @@ -1144,7 +1150,7 @@
"cancelled": "Hakemus peruttiin",
"decisionMakerName": "Päättäjä",
"decisionMakerTitle": "Päättäjän titteli",
"decisionDate": "Päätöspäivämäärä",
"decisionDate": "Päätöspäivä",
"sectionOfTheLaw": "Pykälä",
"p2pTitle": "P2P-tarkastuksen tiedot",
"p2pInspector": "Tarkastaja, P2P",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import {
} from 'benefit/handler/types/applicationList';
import { getTagStyleForStatus } from 'benefit/handler/utils/applications';
import { APPLICATION_STATUSES } from 'benefit-shared/constants';
import { ApplicationListItemData } from 'benefit-shared/types/application';
import {
AhjoError,
ApplicationListItemData,
} from 'benefit-shared/types/application';
import { IconSpeechbubbleText, Table, Tag, Tooltip } from 'hds-react';
import * as React from 'react';
import LoadingSkeleton from 'react-loading-skeleton';
Expand Down Expand Up @@ -34,6 +37,7 @@ export interface ApplicationListProps {
status: APPLICATION_STATUSES[];
list?: ApplicationListItemData[];
isLoading: boolean;
inPayment?: boolean;
}

const buildApplicationUrl = (
Expand Down Expand Up @@ -61,6 +65,7 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
status,
list = [],
isLoading = true,
inPayment = false,
}) => {
const { t, translationsBase, getHeader } = useApplicationList();
const theme = useTheme();
Expand All @@ -83,6 +88,59 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
[isAllStatuses, status]
);

const renderTableActions = React.useCallback(
(
id: string,
applicationStatus: APPLICATION_STATUSES,
unreadMessagesCount: number,
ahjoError: AhjoError
): JSX.Element => (
<$TableActions>
{Number(unreadMessagesCount) > 0 ? (
<$ActionMessages>
<$Link href={buildApplicationUrl(id, applicationStatus, true)}>
<IconSpeechbubbleText color={theme.colors.coatOfArms} />
<$UnreadMessagesCount>
{Number(unreadMessagesCount)}
</$UnreadMessagesCount>
</$Link>
</$ActionMessages>
) : null}
{ahjoError?.errorFromAhjo && (
<$ActionErrors
$errorText={t(
'common:applications.list.errors.ahjoError.buttonText'
)}
>
<Tooltip
placement="top"
boxShadow
className="custom-tooltip-error"
tooltipLabel={t(
'common:applications.list.errors.ahjoError.tooltipLabel'
)}
buttonLabel={t(
'common:applications.list.errors.ahjoError.buttonLabel'
)}
>
<div>
<strong>
Ahjo, {convertToUIDateAndTimeFormat(ahjoError?.modifiedAt)}
</strong>
</div>
<ul>
{ahjoError?.errorFromAhjo?.map(({ message }) => (
<li>{message}</li>
))}
</ul>
</Tooltip>
</$ActionErrors>
)}
</$TableActions>
),
[t, theme.colors.coatOfArms]
);

const columns = React.useMemo(() => {
const cols: ApplicationListTableColumns[] = [
{
Expand Down Expand Up @@ -167,10 +225,11 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
}

if (
isVisibleOnlyForStatus.accepted ||
isVisibleOnlyForStatus.rejected ||
isVisibleOnlyForStatus.infoRequired ||
isAllStatuses
!inPayment &&
(isVisibleOnlyForStatus.accepted ||
isVisibleOnlyForStatus.rejected ||
isVisibleOnlyForStatus.infoRequired ||
isAllStatuses)
) {
cols.push({
transform: ({
Expand Down Expand Up @@ -216,63 +275,56 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
});
}

if (inPayment) {
cols.push(
{
headerName: getHeader('decisionDate'),
key: 'decisionDate',
isSortable: true,
},
{
headerName: getHeader('talpaStatus'),
key: 'talpaStatus',
isSortable: true,
transform: ({ talpaStatus }) =>
t(`applications.list.columns.talpaStatuses.${String(talpaStatus)}`),
}
);
}

cols.push({
transform: ({
unreadMessagesCount,
id,
status: applicationStatus,
unreadMessagesCount,
ahjoError,
}: ApplicationListTableTransforms) => (
<$TableActions>
{Number(unreadMessagesCount) > 0 ? (
<$ActionMessages>
<$Link href={buildApplicationUrl(id, applicationStatus, true)}>
<IconSpeechbubbleText color={theme.colors.coatOfArms} />
<$UnreadMessagesCount>
{Number(unreadMessagesCount)}
</$UnreadMessagesCount>
</$Link>
</$ActionMessages>
) : null}
{ahjoError?.errorFromAhjo && (
<$ActionErrors
$errorText={t(
'common:applications.list.errors.ahjoError.buttonText'
)}
>
<Tooltip
placement="top"
boxShadow
className="custom-tooltip-error"
tooltipLabel={t(
'common:applications.list.errors.ahjoError.tooltipLabel'
)}
buttonLabel={t(
'common:applications.list.errors.ahjoError.buttonLabel'
)}
>
<div>
<strong>
Ahjo, {convertToUIDateAndTimeFormat(ahjoError?.modifiedAt)}
</strong>
</div>
<ul>
{ahjoError?.errorFromAhjo?.map(({ message }) => (
<li>{message}</li>
))}
</ul>
</Tooltip>
</$ActionErrors>
)}
</$TableActions>
),
}: ApplicationListTableTransforms) =>
renderTableActions(
id,
applicationStatus,
unreadMessagesCount,
ahjoError
),
headerName: getHeader('unreadMessagesCount'),
key: 'unreadMessagesCount',
isSortable: false,
});

return cols.filter(Boolean);
}, [t, getHeader, status, theme, isAllStatuses, isVisibleOnlyForStatus]);
}, [
getHeader,
isVisibleOnlyForStatus.handling,
isVisibleOnlyForStatus.infoRequired,
isVisibleOnlyForStatus.accepted,
isVisibleOnlyForStatus.rejected,
isVisibleOnlyForStatus.draft,
isVisibleOnlyForStatus.received,
status,
isAllStatuses,
inPayment,
t,
renderTableActions,
]);

if (isLoading) {
return (
Expand All @@ -293,7 +345,6 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
}

const statusAsString = isAllStatuses ? 'all' : status.join(',');

return (
<$ApplicationList data-testid={`application-list-${statusAsString}`}>
{list.length > 0 ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ const HandlerIndex: React.FC<ApplicationListProps> = ({
const updateTabToUrl = (tabNumber: APPLICATION_LIST_TABS): void =>
window.history.pushState({ tab }, '', `/?tab=${tabNumber}`);

const isInPayment = (application: ApplicationListItemData): boolean =>
[APPLICATION_STATUSES.ACCEPTED].includes(application.status) &&
!isString(application.batch) &&
[BATCH_STATUSES.DECIDED_ACCEPTED].includes(application?.batch?.status);

return (
<FrontPageProvider>
<$BackgroundWrapper backgroundColor={layoutBackgroundColor}>
Expand Down Expand Up @@ -241,14 +246,8 @@ const HandlerIndex: React.FC<ApplicationListProps> = ({
<Tabs.TabPanel>
<ApplicationList
isLoading={isLoading}
list={list.filter(
(app) =>
[APPLICATION_STATUSES.ACCEPTED].includes(app.status) &&
!isString(app.batch) &&
[BATCH_STATUSES.DECIDED_ACCEPTED].includes(
app?.batch?.status
)
)}
list={list.filter((app) => isInPayment(app))}
inPayment={!!list.filter((app) => isInPayment(app))}
heading={t(`${translationBase}.inPayment`)}
status={[APPLICATION_STATUSES.ACCEPTED]}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const useApplicationListData = (
handledByAhjoAutomation: handled_by_ahjo_automation,
handledAt: convertToUIDateFormat(handledAt) || '-',
ahjoError: camelcaseKeys(ahjo_error, { deep: true }) || null,
decisionDate: convertToUIDateFormat(batch?.decision_date) || '-',
};
})
.filter(
Expand Down
Loading

0 comments on commit d88e1f9

Please sign in to comment.