Skip to content

Commit

Permalink
fix: resolve issues with start date on handler's side (HL-1270) (#2948)
Browse files Browse the repository at this point in the history
* fix(handler): resolve crash bug where startDate input would be "11111..."

* refactor: introduce new constants for application start date

* feat: add notification when start or end date is far from recommended application dates
  • Loading branch information
sirtawast committed Apr 26, 2024
1 parent f6cf6fb commit 090fe5e
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { validateNumberField } from '@frontend/benefit-shared/src/utils/validation';
import {
APPLICATION_START_DATE,
APPLICATION_START_DATE_WITHIN_MONTHS,
EMPLOYEE_MAX_WORKING_HOURS,
EMPLOYEE_MIN_WORKING_HOURS,
MAX_SHORT_STRING_LENGTH,
Expand All @@ -13,7 +15,6 @@ import {
VALIDATION_MESSAGE_KEYS,
} from 'benefit-shared/constants';
import { validateDateWithinMonths } from 'benefit-shared/utils/dates';
import subMonths from 'date-fns/subMonths';
import { FinnishSSN } from 'finnish-ssn';
import { TFunction } from 'next-i18next';
import { NAMES_REGEX } from 'shared/constants';
Expand Down Expand Up @@ -45,9 +46,10 @@ export const getValidationSchema = (
.required(t(VALIDATION_MESSAGE_KEYS.REQUIRED))
.test({
message: t(VALIDATION_MESSAGE_KEYS.DATE_MIN, {
min: convertToUIDateFormat(subMonths(new Date(), 4)),
min: convertToUIDateFormat(APPLICATION_START_DATE),
}),
test: (value = '') => validateDateWithinMonths(value, 4),
test: (value = '') =>
validateDateWithinMonths(value, APPLICATION_START_DATE_WITHIN_MONTHS),
}),
[APPLICATION_FIELDS_STEP2_KEYS.END_DATE]: Yup.string().required(
t(VALIDATION_MESSAGE_KEYS.REQUIRED)
Expand Down
6 changes: 5 additions & 1 deletion frontend/benefit/applicant/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ export const DE_MINIMIS_AID_GRANTED_AT_MIN_DATE = new Date(
1
);

export const APPLICATION_START_DATE = subMonths(new Date(), 4);
export const APPLICATION_START_DATE_WITHIN_MONTHS = 4;
export const APPLICATION_START_DATE = subMonths(
new Date(),
APPLICATION_START_DATE_WITHIN_MONTHS
);

export const APPLICATION_INITIAL_VALUES = {
status: APPLICATION_STATUSES.DRAFT,
Expand Down
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 @@ -368,6 +368,10 @@
"requiredConsents": {
"label": "Puuttuvat suostumukset",
"content": "Yksi tai useampi suostumus puuttuu."
},
"pastApplicationDates": {
"label": "Haetusta ajanjaksosta on jo pidempi aika",
"content": "Huomaathan että hakijan ilmoittama ajanjakson on pääsääntöisesti enintään {{months}} kuukauden sisällä hakupäivästä."
}
},
"fields": {
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 @@ -368,6 +368,10 @@
"requiredConsents": {
"label": "Puuttuvat suostumukset",
"content": "Yksi tai useampi suostumus puuttuu."
},
"pastApplicationDates": {
"label": "Haetusta ajanjaksosta on jo pidempi aika",
"content": "Huomaathan että hakijan ilmoittama ajanjakson on pääsääntöisesti enintään {{months}} kuukauden sisällä hakupäivästä."
}
},
"fields": {
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 @@ -368,6 +368,10 @@
"requiredConsents": {
"label": "Puuttuvat suostumukset",
"content": "Yksi tai useampi suostumus puuttuu."
},
"pastApplicationDates": {
"label": "Haetusta ajanjaksosta on jo pidempi aika",
"content": "Huomaathan että hakijan ilmoittama ajanjakson on pääsääntöisesti enintään {{months}} kuukauden sisällä hakupäivästä."
}
},
"fields": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { APPLICATION_FIELD_KEYS } from 'benefit/handler/constants';
import { APPLICATION_START_DATE_WITHIN_MONTHS } from 'benefit/applicant/src/constants';
import {
APPLICATION_FIELD_KEYS,
APPLICATION_START_DATE,
} from 'benefit/handler/constants';
import { useAlertBeforeLeaving } from 'benefit/handler/hooks/useAlertBeforeLeaving';
import { useApplicationFormContext } from 'benefit/handler/hooks/useApplicationFormContext';
import { useDependentFieldsEffect } from 'benefit/handler/hooks/useDependentFieldsEffect';
Expand All @@ -8,7 +12,6 @@ import {
} from 'benefit/handler/types/application';
import {
APPLICATION_ORIGINS,
APPLICATION_START_DATE,
ATTACHMENT_TYPES,
ORGANIZATION_TYPES,
PAY_SUBSIDY_GRANTED,
Expand All @@ -21,7 +24,7 @@ import {
} from 'benefit-shared/types/application';
import { paySubsidyTitle } from 'benefit-shared/utils/common';
import { FormikProps } from 'formik';
import { DateInput, SelectionGroup, TextInput } from 'hds-react';
import { DateInput, Notification, SelectionGroup, TextInput } from 'hds-react';
import React from 'react';
import FieldLabel from 'shared/components/forms/fields/fieldLabel/FieldLabel';
import {
Expand Down Expand Up @@ -94,6 +97,7 @@ const FormContent: React.FC<Props> = ({
clearContractValues,
clearAlternativeAddressValues,
getErrorMessage,
displayPastApplicationDatesWarning,
} = useFormContent(formik, fields);

const theme = useTheme();
Expand Down Expand Up @@ -629,6 +633,22 @@ const FormContent: React.FC<Props> = ({
required
/>
</$GridCell>
{displayPastApplicationDatesWarning() && (
<$GridCell $colSpan={13} $colStart={1}>
<Notification
label={t(
'common:applications.sections.notifications.pastApplicationDates.label'
)}
type="alert"
style={{ marginTop: 'var(--spacing-s)' }}
>
{t(
'common:applications.sections.notifications.pastApplicationDates.content',
{ months: APPLICATION_START_DATE_WITHIN_MONTHS }
)}
</Notification>
</$GridCell>
)}
</FormSection>
<FormSection
paddingBottom
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { APPLICATION_START_DATE_WITHIN_MONTHS } from 'benefit/applicant/src/constants';
import { SUPPORTED_LANGUAGES } from 'benefit/handler/constants';
import DeMinimisContext from 'benefit/handler/context/DeMinimisContext';
import {
Application,
ApplicationFields,
} from 'benefit/handler/types/application';
import { getErrorText } from 'benefit/handler/utils/forms';
import parse from 'date-fns/parse';
import { FormikProps } from 'formik';
import { TFunction, useTranslation } from 'next-i18next';
import React from 'react';
import useLocale from 'shared/hooks/useLocale';
import { OptionType } from 'shared/types/common';
import { getLanguageOptions } from 'shared/utils/common';
import { diffMonths } from 'shared/utils/date.utils';
import { capitalize } from 'shared/utils/string.utils';

type ExtendedComponentProps = {
Expand All @@ -27,6 +30,7 @@ type ExtendedComponentProps = {
clearDatesValues: () => void;
clearAlternativeAddressValues: () => void;
getErrorMessage: (fieldName: string) => string | undefined;
displayPastApplicationDatesWarning: () => boolean;
};

const useFormContent = (
Expand All @@ -37,7 +41,7 @@ const useFormContent = (
const translationsBase = 'common:applications.sections';
const cbPrefix = 'application_consent';
const { setDeMinimisAids } = React.useContext(DeMinimisContext);
const { touched, errors, setFieldValue } = formik;
const { touched, errors, setFieldValue, values } = formik;

const languageOptions = React.useMemo(
(): OptionType<string>[] => getLanguageOptions(t, 'languages'),
Expand Down Expand Up @@ -100,6 +104,23 @@ const useFormContent = (
setFieldValue(fields.benefitType.name, null);
}, [fields.benefitType.name, setFieldValue]);

const displayPastApplicationDatesWarning = (): boolean => {
const { startDate, endDate } = values;
if (!startDate || !endDate) {
return false;
}

const parsedStartDate = parse(startDate, 'd.M.yyyy', new Date());
const parsedEndDate = parse(endDate, 'd.M.yyyy', new Date());

return (
diffMonths(new Date(), parsedStartDate) >
APPLICATION_START_DATE_WITHIN_MONTHS ||
diffMonths(new Date(), parsedEndDate) >
APPLICATION_START_DATE_WITHIN_MONTHS
);
};

const language = SUPPORTED_LANGUAGES.FI;
const locale = useLocale();
const textLocale = capitalize(locale);
Expand All @@ -118,6 +139,7 @@ const useFormContent = (
clearDatesValues,
clearAlternativeAddressValues,
getErrorMessage,
displayPastApplicationDatesWarning,
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import { ApplicationData } from 'benefit-shared/types/application';
import camelcaseKeys from 'camelcase-keys';
import isAfter from 'date-fns/isAfter';
import isValid from 'date-fns/isValid';
import isWithinInterval from 'date-fns/isWithinInterval';
import { FormikErrors } from 'formik';
import fromPairs from 'lodash/fromPairs';
Expand Down Expand Up @@ -172,7 +173,7 @@ const getDates = (values: Application): DatesType => {
const endDate = parseDate(values.endDate);
const isEndDateEligible =
endDate &&
(maxEndDate
(isValid(maxEndDate) && maxEndDate
? isWithinInterval(endDate, { start: minEndDate, end: maxEndDate })
: isAfter(endDate, minEndDate));
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
APPLICATION_FIELD_KEYS,
APPLICATION_START_DATE,
APPLICATION_START_DATE_WITHIN_MONTHS,
EMPLOYEE_MAX_WORKING_HOURS,
EMPLOYEE_MIN_WORKING_HOURS,
MAX_LONG_STRING_LENGTH,
Expand All @@ -20,7 +22,6 @@ import {
validateIsTodayOrPastDate,
} from 'benefit-shared/utils/dates';
import { validateNumberField } from 'benefit-shared/utils/validation';
import subMonths from 'date-fns/subMonths';
import { FinnishSSN } from 'finnish-ssn';
import { TFunction } from 'next-i18next';
import {
Expand Down Expand Up @@ -279,9 +280,10 @@ export const getValidationSchema = (
.required(t(VALIDATION_MESSAGE_KEYS.REQUIRED))
.test({
message: t(VALIDATION_MESSAGE_KEYS.DATE_MIN, {
min: convertToUIDateFormat(subMonths(new Date(), 4)),
min: convertToUIDateFormat(APPLICATION_START_DATE),
}),
test: (value = '') => validateDateWithinMonths(value, 4),
test: (value = '') =>
validateDateWithinMonths(value, APPLICATION_START_DATE_WITHIN_MONTHS),
}),
[APPLICATION_FIELD_KEYS.END_DATE]: Yup.string().required(
t(VALIDATION_MESSAGE_KEYS.REQUIRED)
Expand Down
7 changes: 6 additions & 1 deletion frontend/benefit/handler/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
EMPLOYEE_KEYS,
PAY_SUBSIDY_OPTIONS,
} from 'benefit-shared/constants';
import subMonths from 'date-fns/subMonths';

export enum ROUTES {
HOME = '/',
Expand Down Expand Up @@ -101,7 +102,11 @@ export const DE_MINIMIS_AID_GRANTED_AT_MIN_DATE = new Date(
1
);

export const APPLICATION_START_DATE = new Date(new Date().getFullYear(), 0, 1);
export const APPLICATION_START_DATE_WITHIN_MONTHS = 12;
export const APPLICATION_START_DATE = subMonths(
new Date(),
APPLICATION_START_DATE_WITHIN_MONTHS
);

export const MAX_DEMINIMIS_AID_TOTAL_AMOUNT = 300_000;

Expand Down

0 comments on commit 090fe5e

Please sign in to comment.