Skip to content

Commit

Permalink
ORV2-3314 - FE: Cannot amend permit with start date in the past (#1748)
Browse files Browse the repository at this point in the history
Co-authored-by: GlenAOT <[email protected]>
  • Loading branch information
glen-aot and glen-aot authored Jan 17, 2025
1 parent 47d11d8 commit 503a79e
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 113 deletions.
52 changes: 27 additions & 25 deletions frontend/src/features/permits/context/ApplicationFormContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,30 @@ interface ApplicationFormContextType {
onContinue: () => Promise<void>;
}

export const ApplicationFormContext = createContext<ApplicationFormContextType>({
initialFormData: getDefaultValues(DEFAULT_PERMIT_TYPE, undefined),
formData: getDefaultValues(DEFAULT_PERMIT_TYPE, undefined),
policyEngine: undefined,
durationOptions: [],
allVehiclesFromInventory: [],
powerUnitSubtypeNamesMap: new Map<string, string>(),
trailerSubtypeNamesMap: new Map<string, string>(),
isLcvDesignated: false,
feature: "",
companyInfo: undefined,
isAmendAction: false,
createdDateTime: undefined,
updatedDateTime: undefined,
pastStartDateStatus: PAST_START_DATE_STATUSES.ALLOWED,
companyLOAs: [],
revisionHistory: [],
policyViolations: {},
clearViolation: () => undefined,
triggerPolicyValidation: async () => ({}),
onLeave: undefined,
onSave: undefined,
onCancel: undefined,
onContinue: async () => undefined,
});
export const ApplicationFormContext = createContext<ApplicationFormContextType>(
{
initialFormData: getDefaultValues(DEFAULT_PERMIT_TYPE, undefined),
formData: getDefaultValues(DEFAULT_PERMIT_TYPE, undefined),
policyEngine: undefined,
durationOptions: [],
allVehiclesFromInventory: [],
powerUnitSubtypeNamesMap: new Map<string, string>(),
trailerSubtypeNamesMap: new Map<string, string>(),
isLcvDesignated: false,
feature: "",
companyInfo: undefined,
isAmendAction: false,
createdDateTime: undefined,
updatedDateTime: undefined,
pastStartDateStatus: PAST_START_DATE_STATUSES.ALLOWED,
companyLOAs: [],
revisionHistory: [],
policyViolations: {},
clearViolation: () => undefined,
triggerPolicyValidation: async () => ({}),
onLeave: undefined,
onSave: undefined,
onCancel: undefined,
onContinue: async () => undefined,
},
);
201 changes: 113 additions & 88 deletions frontend/src/features/permits/pages/Amend/components/AmendPermitForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,32 @@ import { Application } from "../../../types/application";
import { useCompanyInfoDetailsQuery } from "../../../../manageProfile/apiManager/hooks";
import { Breadcrumb } from "../../../../../common/components/breadcrumb/Breadcrumb";
import { ApplicationFormContext } from "../../../context/ApplicationFormContext";
import { isNull, isUndefined, Nullable } from "../../../../../common/types/common";
import {
isNull,
isUndefined,
Nullable,
} from "../../../../../common/types/common";
import { ERROR_ROUTES } from "../../../../../routes/constants";
import { applyWhenNotNullable, getDefaultRequiredVal } from "../../../../../common/helpers/util";
import {
applyWhenNotNullable,
getDefaultRequiredVal,
} from "../../../../../common/helpers/util";
import { PermitVehicleDetails } from "../../../types/PermitVehicleDetails";
import { getDatetimes } from "./helpers/getDatetimes";
import { PAST_START_DATE_STATUSES } from "../../../../../common/components/form/subFormComponents/CustomDatePicker";
import { useFetchLOAs } from "../../../../settings/hooks/LOA";
import { useFetchSpecialAuthorizations } from "../../../../settings/hooks/specialAuthorizations";
import { filterLOAsForPermitType, filterNonExpiredLOAs } from "../../../helpers/permitLOA";
import {
filterLOAsForPermitType,
filterNonExpiredLOAs,
} from "../../../helpers/permitLOA";
import { usePolicyEngine } from "../../../../policy/hooks/usePolicyEngine";
import { Loading } from "../../../../../common/pages/Loading";
import { serializePermitVehicleDetails } from "../../../helpers/serialize/serializePermitVehicleDetails";
import { serializeForUpdateApplication } from "../../../helpers/serialize/serializeApplication";
import { requiredPowerUnit } from "../../../../../common/helpers/validationMessages";
import { PERMIT_TYPES } from "../../../types/PermitType";
import {
dayjsToUtcStr,
now,
} from "../../../../../common/helpers/formatDate";
import { dayjsToUtcStr, now } from "../../../../../common/helpers/formatDate";

import {
useAmendPermit,
Expand All @@ -41,6 +48,7 @@ import {
durationOptionsForPermitType,
minDurationForPermitType,
} from "../../../helpers/dateSelection";
import OnRouteBCContext from "../../../../../common/authentication/OnRouteBCContext";

const FEATURE = "amend-permit";

Expand All @@ -57,17 +65,26 @@ export const AmendPermitForm = () => {
} = useContext(AmendPermitContext);

const { companyId: companyIdParam } = useParams();
const companyId: number = applyWhenNotNullable(id => Number(id), companyIdParam, 0);
const companyId: number = applyWhenNotNullable(
(id) => Number(id),
companyIdParam,
0,
);
const navigate = useNavigate();

const { data: activeLOAs } = useFetchLOAs(companyId, false);
const companyLOAs = useMemo(() => getDefaultRequiredVal(
[],
activeLOAs,
), [activeLOAs]);
const companyLOAs = useMemo(
() => getDefaultRequiredVal([], activeLOAs),
[activeLOAs],
);

const { idirUserDetails } = useContext(OnRouteBCContext);

const isStaffUser = Boolean(idirUserDetails?.userRole);

const { data: companyInfo } = useCompanyInfoDetailsQuery(companyId);
const { data: specialAuthorizations } = useFetchSpecialAuthorizations(companyId);
const { data: specialAuthorizations } =
useFetchSpecialAuthorizations(companyId);
const isLcvDesignated = Boolean(specialAuthorizations?.isLcvAllowed);

const {
Expand All @@ -79,11 +96,7 @@ export const AmendPermitForm = () => {

const policyEngine = usePolicyEngine();

const {
initialFormData,
formData,
formMethods,
} = useAmendPermitForm({
const { initialFormData, formData, formMethods } = useAmendPermitForm({
repopulateFormData: currentStepIndex === 0,
isLcvDesignated,
companyLOAs,
Expand All @@ -103,26 +116,26 @@ export const AmendPermitForm = () => {
// 1. Applicable for the current permit type
// 2. Have expiry date that is on or after the start date for an application
const applicableLOAs = filterNonExpiredLOAs(
filterLOAsForPermitType(
companyLOAs,
formData.permitType,
),
filterLOAsForPermitType(companyLOAs, formData.permitType),
formData.permitData.startDate,
);

const { mutateAsync: createAmendment } = useAmendPermit(companyId);
const { mutateAsync: modifyAmendment } = useModifyAmendmentApplication();
const snackBar = useContext(SnackBarContext);

const { handleSubmit } = formMethods;

const [policyViolations, setPolicyViolations] = useState<Record<string, string>>({});
const [policyViolations, setPolicyViolations] = useState<
Record<string, string>
>({});

const clearViolation = (fieldReference: string) => {
if (fieldReference in policyViolations) {
const otherViolations = Object.entries(policyViolations)
.filter(([fieldRef]) => fieldRef !== fieldReference);

const otherViolations = Object.entries(policyViolations).filter(
([fieldRef]) => fieldRef !== fieldReference,
);

setPolicyViolations(Object.fromEntries(otherViolations));
}
};
Expand All @@ -136,16 +149,27 @@ export const AmendPermitForm = () => {
[],
validationResults?.violations
.filter(({ fieldReference }) => Boolean(fieldReference))
.map(violation => ({
.map((violation) => ({
fieldReference: violation.fieldReference as string,
message: violation.message,
})),
).concat(formData.permitType === PERMIT_TYPES.STOS && !formData.permitData.vehicleDetails.vin ? [
{ fieldReference: "permitData.vehicleDetails", message: requiredPowerUnit() },
] : []);
).concat(
formData.permitType === PERMIT_TYPES.STOS &&
!formData.permitData.vehicleDetails.vin
? [
{
fieldReference: "permitData.vehicleDetails",
message: requiredPowerUnit(),
},
]
: [],
);

const updatedViolations = Object.fromEntries(
violations.map(({ fieldReference, message }) => [fieldReference, message]),
violations.map(({ fieldReference, message }) => [
fieldReference,
message,
]),
);

setPolicyViolations(updatedViolations);
Expand All @@ -155,11 +179,14 @@ export const AmendPermitForm = () => {
// When "Continue" button is clicked
const onContinue = async (data: FieldValues) => {
const updatedViolations = await triggerPolicyValidation();
if (Object.keys(updatedViolations).length > 0) {
// prevent CV client continuing if there are policy engine validation errors
if (Object.keys(updatedViolations).length > 0 && !isStaffUser) {
return;
}

const vehicleData = serializePermitVehicleDetails(data.permitData.vehicleDetails);
const vehicleData = serializePermitVehicleDetails(
data.permitData.vehicleDetails,
);
const savedVehicle = await handleSaveVehicle(vehicleData);

// Save application before continuing
Expand Down Expand Up @@ -207,10 +234,7 @@ export const AmendPermitForm = () => {

const response = shouldUpdateApplication
? await modifyAmendment({
applicationId: getDefaultRequiredVal(
"",
permitToBeAmended.permitId,
),
applicationId: getDefaultRequiredVal("", permitToBeAmended.permitId),
application: permitToBeAmended,
companyId,
})
Expand Down Expand Up @@ -241,55 +265,58 @@ export const AmendPermitForm = () => {
permit?.permitData?.permitDuration,
);

const durationOptions = durationOptionsForPermitType(formData.permitType).filter(
(duration) => duration.value <= permitOldDuration,
const durationOptions = durationOptionsForPermitType(
formData.permitType,
).filter((duration) => duration.value <= permitOldDuration);

const applicationFormContextData = useMemo(
() => ({
initialFormData,
formData,
policyEngine,
durationOptions,
allVehiclesFromInventory,
powerUnitSubtypeNamesMap,
trailerSubtypeNamesMap,
isLcvDesignated,
feature: FEATURE,
companyInfo,
isAmendAction: true,
createdDateTime,
updatedDateTime,
pastStartDateStatus: PAST_START_DATE_STATUSES.WARNING,
companyLOAs: applicableLOAs,
revisionHistory,
policyViolations,
onLeave: undefined,
onSave: undefined,
onCancel: goHome,
onContinue: handleSubmit(onContinue),
triggerPolicyValidation,
clearViolation,
}),
[
initialFormData,
formData,
policyEngine,
durationOptions,
allVehiclesFromInventory,
powerUnitSubtypeNamesMap,
trailerSubtypeNamesMap,
isLcvDesignated,
companyInfo,
createdDateTime,
updatedDateTime,
applicableLOAs,
revisionHistory,
policyViolations,
goHome,
onContinue,
triggerPolicyValidation,
clearViolation,
],
);

const applicationFormContextData = useMemo(() => ({
initialFormData,
formData,
policyEngine,
durationOptions,
allVehiclesFromInventory,
powerUnitSubtypeNamesMap,
trailerSubtypeNamesMap,
isLcvDesignated,
feature: FEATURE,
companyInfo,
isAmendAction: true,
createdDateTime,
updatedDateTime,
pastStartDateStatus: PAST_START_DATE_STATUSES.WARNING,
companyLOAs: applicableLOAs,
revisionHistory,
policyViolations,
onLeave: undefined,
onSave: undefined,
onCancel: goHome,
onContinue: handleSubmit(onContinue),
triggerPolicyValidation,
clearViolation,
}), [
initialFormData,
formData,
policyEngine,
durationOptions,
allVehiclesFromInventory,
powerUnitSubtypeNamesMap,
trailerSubtypeNamesMap,
isLcvDesignated,
companyInfo,
createdDateTime,
updatedDateTime,
applicableLOAs,
revisionHistory,
policyViolations,
goHome,
onContinue,
triggerPolicyValidation,
clearViolation,
]);

if (isUndefined(policyEngine)) return <Loading />;
if (isNull(policyEngine)) return <Navigate to={ERROR_ROUTES.UNEXPECTED} />;

Expand All @@ -298,9 +325,7 @@ export const AmendPermitForm = () => {
<Breadcrumb links={getLinks()} />

<FormProvider {...formMethods}>
<ApplicationFormContext.Provider
value={applicationFormContextData}
>
<ApplicationFormContext.Provider value={applicationFormContextData}>
<PermitForm />
</ApplicationFormContext.Provider>
</FormProvider>
Expand Down

0 comments on commit 503a79e

Please sign in to comment.