Skip to content

Commit 7731031

Browse files
authored
ORV2-3407 - CV Client and Staff Apply for Non-Resident Single-Trip ICBC Basic-Insurance Permit (#1814)
1 parent 009204d commit 7731031

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+735
-212
lines changed

database/mssql/scripts/sampledata/dbo.ORBC_FEATURE_FLAG.Table.sql

+46
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,52 @@ VALUES
324324
GETUTCDATE()
325325
);
326326

327+
INSERT INTO
328+
[dbo].[ORBC_FEATURE_FLAG] (
329+
[FEATURE_ID],
330+
[FEATURE_KEY],
331+
[FEATURE_VALUE],
332+
[CONCURRENCY_CONTROL_NUMBER],
333+
[DB_CREATE_USERID],
334+
[DB_CREATE_TIMESTAMP],
335+
[DB_LAST_UPDATE_USERID],
336+
[DB_LAST_UPDATE_TIMESTAMP]
337+
)
338+
VALUES
339+
(
340+
'15',
341+
'STFR',
342+
'ENABLED',
343+
NULL,
344+
N'dbo',
345+
GETUTCDATE(),
346+
N'dbo',
347+
GETUTCDATE()
348+
);
349+
350+
INSERT INTO
351+
[dbo].[ORBC_FEATURE_FLAG] (
352+
[FEATURE_ID],
353+
[FEATURE_KEY],
354+
[FEATURE_VALUE],
355+
[CONCURRENCY_CONTROL_NUMBER],
356+
[DB_CREATE_USERID],
357+
[DB_CREATE_TIMESTAMP],
358+
[DB_LAST_UPDATE_USERID],
359+
[DB_LAST_UPDATE_TIMESTAMP]
360+
)
361+
VALUES
362+
(
363+
'16',
364+
'QRFR',
365+
'ENABLED',
366+
NULL,
367+
N'dbo',
368+
GETUTCDATE(),
369+
N'dbo',
370+
GETUTCDATE()
371+
);
372+
327373
SET
328374
IDENTITY_INSERT [dbo].[ORBC_FEATURE_FLAG] OFF
329375
GO

frontend/src/common/components/form/CountryAndProvince.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ interface CountryAndProvinceProps {
2525
provinceClassName?: string;
2626
readOnly?: boolean;
2727
disabled?: boolean;
28+
countryValidationRules?: Record<string, (country?: string) => boolean | string>;
29+
provinceValidationRules?: Record<string, (province?: string) => boolean | string>;
2830
}
2931

3032
/**
@@ -42,6 +44,8 @@ export const CountryAndProvince = <T extends ORBC_FormTypes>({
4244
provinceClassName,
4345
disabled,
4446
readOnly,
47+
countryValidationRules = {},
48+
provinceValidationRules = {},
4549
}: CountryAndProvinceProps): JSX.Element => {
4650
const { resetField, watch, setValue } = useFormContext();
4751
const countrySelected = watch(countryField);
@@ -117,6 +121,7 @@ export const CountryAndProvince = <T extends ORBC_FormTypes>({
117121
(!isCountryRequired && (country == null || country === "")) ||
118122
(country != null && country !== "" && /^[A-Z]{2}$/.test(country)) ||
119123
invalidCountryCode(),
124+
...countryValidationRules,
120125
},
121126
onChange: onChangeCountry,
122127
};
@@ -131,6 +136,7 @@ export const CountryAndProvince = <T extends ORBC_FormTypes>({
131136
(!isProvinceRequired && (province == null || province === "")) ||
132137
(province != null && province !== "" && /^[A-Z]{2}$/.test(province)) ||
133138
invalidProvinceCode(),
139+
...provinceValidationRules,
134140
},
135141
};
136142

frontend/src/common/constants/bannerMessages.ts

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export const BANNER_MESSAGES = {
3939
EXAMPLE:
4040
"e.g. If the origin is Victoria, BC and the destination is Hope, BC, the sequence of highways travelled in order will be 17 1 3.",
4141
},
42+
PERMIT_SINGLE_ROUND_TRIP: "This permit allows only one round trip into and out of the province during the permit duration.",
43+
PERMIT_START_DATE_VALID_QUARTER: "The start date you choose determines the valid quarter for the permit. This permit allows multiple trips into and out of the province during the permit duration.",
4244
TOTAL_DISTANCE:
4345
"The total distance, in km, is the distance that will be travelled within BC (or from/to BC border). This is to include the return trip distance.",
4446
BRIDGE_FORMULA_CALCULATION_TOOL:

frontend/src/common/constants/validation_messages.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@
3333
"defaultMessage": "Invalid country code"
3434
},
3535
"province": {
36-
"defaultMessage": "Invalid province code"
36+
"defaultMessage": "Invalid province code",
37+
"provinceVehicleDoesNotRequirePermit": {
38+
"messageTemplate": ":province plated vehicles don't require this permit.",
39+
"placeholders": [":province"]
40+
}
3741
},
3842
"date": {
3943
"defaultMessage": "Your date is not valid",

frontend/src/common/helpers/validationMessages.ts

+7
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ export const requiredHighway = () => validationMessages.highway.missing;
153153

154154
export const requiredPowerUnit = () => validationMessages.powerUnit.required;
155155

156+
export const provinceVehicleDoesNotRequirePermit = (province: string) => {
157+
const { messageTemplate, placeholders }
158+
= validationMessages.province.provinceVehicleDoesNotRequirePermit;
159+
160+
return replacePlaceholders(messageTemplate, placeholders, province);
161+
};
162+
156163
/**
157164
* Checks if a given string is
158165
* null, empty or conforms to length requirements if it has a value.

frontend/src/features/permits/components/dashboard/ApplicationStepPage.tsx

+11-11
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import { getCompanyIdFromSession } from "../../../../common/apiManager/httpReque
1010
import { Loading } from "../../../../common/pages/Loading";
1111
import { useApplicationForStepsQuery } from "../../hooks/hooks";
1212
import { PERMIT_STATUSES } from "../../types/PermitStatus";
13+
import { useFeatureFlagsQuery } from "../../../../common/hooks/hooks";
14+
import { ApplicationReview } from "../../pages/Application/ApplicationReview";
1315
import {
1416
applyWhenNotNullable,
1517
getDefaultRequiredVal,
1618
} from "../../../../common/helpers/util";
17-
import { useFeatureFlagsQuery } from "../../../../common/hooks/hooks";
19+
1820
import {
1921
DEFAULT_PERMIT_TYPE,
2022
PERMIT_TYPES,
@@ -28,7 +30,6 @@ import {
2830
ApplicationStepContext,
2931
ERROR_ROUTES,
3032
} from "../../../../routes/constants";
31-
import { ApplicationReview } from "../../pages/Application/ApplicationReview";
3233

3334
const displayHeaderText = (stepKey: ApplicationStep) => {
3435
switch (stepKey) {
@@ -62,7 +63,8 @@ export const ApplicationStepPage = ({
6263
const { data: featureFlags } = useFeatureFlagsQuery();
6364
const enableSTOS = featureFlags?.["STOS"] === "ENABLED";
6465
const enableMFP = featureFlags?.["MFP"] === "ENABLED";
65-
66+
const enableSTFR = featureFlags?.["STFR"] === "ENABLED";
67+
6668
// Query for the application data whenever this page is rendered
6769
const {
6870
applicationData,
@@ -98,15 +100,13 @@ export const ApplicationStepPage = ({
98100
applicationData?.permitType,
99101
);
100102

101-
// Currently onRouteBC only handles TROS and TROW permits, and STOS and MFP only if feature flag is enabled
103+
// Currently onRouteBC only handles TROS and TROW permits
104+
// STOS is only allowed if feature flag is enabled, and same for MFP, STFR, etc.
102105
const isPermitTypeAllowed = () => {
103-
const allowedPermitTypes: string[] = [
104-
PERMIT_TYPES.TROS,
105-
PERMIT_TYPES.TROW,
106-
PERMIT_TYPES.STOS,
107-
PERMIT_TYPES.MFP,
108-
].filter(pType => enableSTOS ? true : pType !== PERMIT_TYPES.STOS)
109-
.filter(pType => enableMFP ? true : pType !== PERMIT_TYPES.MFP);
106+
const allowedPermitTypes: string[] = ([PERMIT_TYPES.TROS, PERMIT_TYPES.TROW] as string[])
107+
.concat(enableSTOS ? [PERMIT_TYPES.STOS] : [])
108+
.concat(enableMFP ? [PERMIT_TYPES.MFP] : [])
109+
.concat(enableSTFR ? [PERMIT_TYPES.STFR] : []);
110110

111111
return allowedPermitTypes.includes(applicationPermitType);
112112
};

frontend/src/features/permits/components/feeSummary/FeeSummary.tsx

+1-10
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,13 @@ import { getPermitTypeName, PermitType } from "../../types/PermitType";
66
export const FeeSummary = ({
77
permitType,
88
feeSummary,
9-
permitDuration,
109
hideDescriptions,
11-
permittedRouteTotalDistance,
1210
}: {
1311
permitType?: Nullable<PermitType>;
1412
feeSummary?: Nullable<string>;
15-
permitDuration?: number;
1613
hideDescriptions?: boolean;
17-
permittedRouteTotalDistance?: Nullable<number>;
1814
}) => {
19-
const feeDisplayText = feeSummaryDisplayText(
20-
feeSummary,
21-
permitDuration,
22-
permitType,
23-
permittedRouteTotalDistance,
24-
);
15+
const feeDisplayText = feeSummaryDisplayText(feeSummary);
2516

2617
return (
2718
<div className="fee-summary">

frontend/src/features/permits/constants/constants.ts

+14-8
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,20 @@ export const ALL_PERMIT_TYPE_CHOOSE_FROM_OPTIONS: PermitTypeChooseFromItem[] = [
5454
// })),
5555
},
5656
/* TODO uncomment these when required */
57-
// {
58-
// value: PERMIT_CATEGORIES.NON_RESIDENT,
59-
// label: getPermitCategoryName(PERMIT_CATEGORIES.NON_RESIDENT),
60-
// items: NON_RESIDENT_PERMIT_LIST.map((permitType: PermitType) => ({
61-
// value: permitType,
62-
// label: getPermitTypeShortName(permitType),
63-
// })),
64-
// },
57+
{
58+
value: PERMIT_CATEGORIES.NON_RESIDENT,
59+
label: getPermitCategoryName(PERMIT_CATEGORIES.NON_RESIDENT),
60+
items: [
61+
{
62+
value: PERMIT_TYPES.STFR,
63+
label: getPermitTypeShortName(PERMIT_TYPES.STFR),
64+
},
65+
],
66+
// items: NON_RESIDENT_PERMIT_LIST.map((permitType: PermitType) => ({
67+
// value: permitType,
68+
// label: getPermitTypeShortName(permitType),
69+
// })),
70+
},
6571
{
6672
value: PERMIT_TYPES.MFP,
6773
label: getPermitTypeShortName(PERMIT_TYPES.MFP),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { PermitCondition } from "../types/PermitCondition";
2+
3+
export const STFR_CONDITIONS: PermitCondition[] = [
4+
{
5+
description: "Insurance Certificate Conditions",
6+
condition: "APV96",
7+
conditionLink: "https://www.th.gov.bc.ca/forms/getForm.aspx?formId=1547",
8+
checked: true,
9+
disabled: true
10+
},
11+
];
12+
13+
export const MANDATORY_STFR_CONDITIONS: PermitCondition[] = [...STFR_CONDITIONS];
14+
15+
export const MIN_STFR_DURATION = 1;
16+
export const MAX_STFR_DURATION = 30;
17+
export const STFR_DURATION_OPTIONS = [
18+
{ value: MIN_STFR_DURATION, label: "1 Day" },
19+
{ value: 2, label: "2 Days" },
20+
{ value: 3, label: "3 Days" },
21+
{ value: 4, label: "4 Days" },
22+
{ value: 5, label: "5 Days" },
23+
{ value: 6, label: "6 Days" },
24+
{ value: 7, label: "7 Days" },
25+
{ value: 8, label: "8 Days" },
26+
{ value: 9, label: "9 Days" },
27+
{ value: 10, label: "10 Days" },
28+
{ value: 11, label: "11 Days" },
29+
{ value: 12, label: "12 Days" },
30+
{ value: 13, label: "13 Days" },
31+
{ value: 14, label: "14 Days" },
32+
{ value: 15, label: "15 Days" },
33+
{ value: 16, label: "16 Days" },
34+
{ value: 17, label: "17 Days" },
35+
{ value: 18, label: "18 Days" },
36+
{ value: 19, label: "19 Days" },
37+
{ value: 20, label: "20 Days" },
38+
{ value: 21, label: "21 Days" },
39+
{ value: 22, label: "22 Days" },
40+
{ value: 23, label: "23 Days" },
41+
{ value: 24, label: "24 Days" },
42+
{ value: 25, label: "25 Days" },
43+
{ value: 26, label: "26 Days" },
44+
{ value: 27, label: "27 Days" },
45+
{ value: 28, label: "28 Days" },
46+
{ value: 29, label: "29 Days" },
47+
{ value: MAX_STFR_DURATION, label: "30 Days" },
48+
];
49+
50+
export const STFR_DURATION_INTERVAL_DAYS = 1;

frontend/src/features/permits/helpers/conditions.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { isVehicleSubtypeLCV } from "../../manageVehicles/helpers/vehicleSubtypes";
22
import { LCV_CONDITION } from "../constants/constants";
3+
import { MANDATORY_STFR_CONDITIONS, STFR_CONDITIONS } from "../constants/stfr";
34
import { MANDATORY_MFP_CONDITIONS, MFP_CONDITIONS } from "../constants/mfp";
45
import { MANDATORY_STOS_CONDITIONS, STOS_CONDITIONS } from "../constants/stos";
56
import { MANDATORY_TROS_CONDITIONS, TROS_CONDITIONS } from "../constants/tros";
@@ -19,6 +20,8 @@ export const getMandatoryConditions = (
1920
) => {
2021
const additionalConditions = includeLcvCondition ? [LCV_CONDITION] : [];
2122
switch (permitType) {
23+
case PERMIT_TYPES.STFR:
24+
return MANDATORY_STFR_CONDITIONS.concat(additionalConditions);
2225
case PERMIT_TYPES.MFP:
2326
return MANDATORY_MFP_CONDITIONS.concat(additionalConditions);
2427
case PERMIT_TYPES.STOS:
@@ -38,6 +41,8 @@ const getConditionsByPermitType = (
3841
) => {
3942
const additionalConditions = includeLcvCondition ? [LCV_CONDITION] : [];
4043
switch (permitType) {
44+
case PERMIT_TYPES.STFR:
45+
return STFR_CONDITIONS.concat(additionalConditions);
4146
case PERMIT_TYPES.MFP:
4247
return MFP_CONDITIONS.concat(additionalConditions);
4348
case PERMIT_TYPES.STOS:

frontend/src/features/permits/helpers/dateSelection.ts

+15
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ import {
2929
STOS_DURATION_OPTIONS,
3030
} from "../constants/stos";
3131

32+
import {
33+
MAX_STFR_DURATION,
34+
MIN_STFR_DURATION,
35+
STFR_DURATION_INTERVAL_DAYS,
36+
STFR_DURATION_OPTIONS,
37+
} from "../constants/stfr";
38+
3239
import {
3340
MAX_MFP_DURATION,
3441
MFP_DURATION_INTERVAL_DAYS,
@@ -43,6 +50,8 @@ import {
4350
*/
4451
export const durationOptionsForPermitType = (permitType: PermitType) => {
4552
switch (permitType) {
53+
case PERMIT_TYPES.STFR:
54+
return STFR_DURATION_OPTIONS;
4655
case PERMIT_TYPES.MFP:
4756
return MFP_DURATION_OPTIONS;
4857
case PERMIT_TYPES.STOS:
@@ -63,6 +72,8 @@ export const durationOptionsForPermitType = (permitType: PermitType) => {
6372
*/
6473
export const minDurationForPermitType = (permitType: PermitType) => {
6574
switch (permitType) {
75+
case PERMIT_TYPES.STFR:
76+
return MIN_STFR_DURATION;
6677
case PERMIT_TYPES.MFP:
6778
return MIN_MFP_DURATION;
6879
case PERMIT_TYPES.STOS:
@@ -83,6 +94,8 @@ export const minDurationForPermitType = (permitType: PermitType) => {
8394
*/
8495
export const maxDurationForPermitType = (permitType: PermitType) => {
8596
switch (permitType) {
97+
case PERMIT_TYPES.STFR:
98+
return MAX_STFR_DURATION;
8699
case PERMIT_TYPES.MFP:
87100
return MAX_MFP_DURATION;
88101
case PERMIT_TYPES.STOS:
@@ -103,6 +116,8 @@ export const maxDurationForPermitType = (permitType: PermitType) => {
103116
*/
104117
export const getDurationIntervalDays = (permitType: PermitType) => {
105118
switch (permitType) {
119+
case PERMIT_TYPES.STFR:
120+
return STFR_DURATION_INTERVAL_DAYS;
106121
case PERMIT_TYPES.MFP:
107122
return MFP_DURATION_INTERVAL_DAYS;
108123
case PERMIT_TYPES.STOS:

frontend/src/features/permits/helpers/equality.ts

+7
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ export const areVehicleConfigurationsEqual = (
184184
) && (
185185
getDefaultRequiredVal(0, vehicleConfig1?.rearProjection)
186186
=== getDefaultRequiredVal(0, vehicleConfig2?.rearProjection)
187+
) && (
188+
getDefaultRequiredVal(0, vehicleConfig1?.loadedGVW)
189+
=== getDefaultRequiredVal(0, vehicleConfig2?.loadedGVW)
187190
) && areOrderedSequencesEqual(
188191
vehicleConfig1?.trailers,
189192
vehicleConfig2?.trailers,
@@ -263,6 +266,10 @@ export const areApplicationPermitDataEqual = (
263266
arePermittedRoutesEqual(data1.permittedRoute, data2.permittedRoute) &&
264267
(getDefaultRequiredVal("", data1.applicationNotes)
265268
=== getDefaultRequiredVal("", data2.applicationNotes)) &&
269+
(getDefaultRequiredVal("", data1.thirdPartyLiability)
270+
=== getDefaultRequiredVal("", data2.thirdPartyLiability)) &&
271+
(getDefaultRequiredVal("", data1.conditionalLicensingFee)
272+
=== getDefaultRequiredVal("", data2.conditionalLicensingFee)) &&
266273
((!data1.companyName && !data2.companyName) ||
267274
data1.companyName === data2.companyName) &&
268275
((!data1.doingBusinessAs && !data2.doingBusinessAs) ||

0 commit comments

Comments
 (0)