Skip to content

Commit

Permalink
feat: Allow LCV permitting for STOS (#1761)
Browse files Browse the repository at this point in the history
Co-authored-by: GlenAOT <[email protected]>
  • Loading branch information
john-fletcher-aot and glen-aot authored Jan 22, 2025
1 parent c98724d commit fb57ad8
Show file tree
Hide file tree
Showing 21 changed files with 187 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ INSERT [dbo].[ORBC_POWER_UNIT] ([POWER_UNIT_ID], [UNIT_NUMBER], [PLATE], [PROVIN
INSERT [dbo].[ORBC_POWER_UNIT] ([POWER_UNIT_ID], [UNIT_NUMBER], [PLATE], [PROVINCE_TYPE], [YEAR], [MAKE], [VIN], [LICENSED_GVW], [POWER_UNIT_TYPE], [STEER_AXLE_TIRE_SIZE], [CONCURRENCY_CONTROL_NUMBER], [DB_CREATE_USERID], [DB_CREATE_TIMESTAMP], [DB_LAST_UPDATE_USERID], [DB_LAST_UPDATE_TIMESTAMP], [COMPANY_ID]) VALUES (99, N'9', N'F7XC0M', N'CA-BC', 2020, N'Freightliner', N'713995', CAST(18917.00 AS Numeric(18, 2)), N'CONCRET', 711, NULL, N'dbo', GETUTCDATE(), N'dbo', GETUTCDATE(), 99)
INSERT [dbo].[ORBC_POWER_UNIT] ([POWER_UNIT_ID], [UNIT_NUMBER], [PLATE], [PROVINCE_TYPE], [YEAR], [MAKE], [VIN], [LICENSED_GVW], [POWER_UNIT_TYPE], [STEER_AXLE_TIRE_SIZE], [CONCURRENCY_CONTROL_NUMBER], [DB_CREATE_USERID], [DB_CREATE_TIMESTAMP], [DB_LAST_UPDATE_USERID], [DB_LAST_UPDATE_TIMESTAMP], [COMPANY_ID]) VALUES (100, N'9', N'VCUDWK', N'CA-BC', 2014, N'Hyundai', N'925292', CAST(4989.00 AS Numeric(18, 2)), N'TRKTRAC', 325, NULL, N'dbo', GETUTCDATE(), N'dbo', GETUTCDATE(), 100)


INSERT [dbo].[ORBC_POWER_UNIT] ([POWER_UNIT_ID], [UNIT_NUMBER], [PLATE], [PROVINCE_TYPE], [YEAR], [MAKE], [VIN], [LICENSED_GVW], [POWER_UNIT_TYPE], [STEER_AXLE_TIRE_SIZE], [CONCURRENCY_CONTROL_NUMBER], [DB_CREATE_USERID], [DB_CREATE_TIMESTAMP], [DB_LAST_UPDATE_USERID], [DB_LAST_UPDATE_TIMESTAMP], [COMPANY_ID]) VALUES (101, N'LCV1', N'TTH199', N'CA-BC', 2020, N'Western Star', N'657854', CAST(20000 AS Numeric(18, 2)), N'LCVRMDB', 325, NULL, N'dbo', GETUTCDATE(), N'dbo', GETUTCDATE(), 74)
INSERT [dbo].[ORBC_POWER_UNIT] ([POWER_UNIT_ID], [UNIT_NUMBER], [PLATE], [PROVINCE_TYPE], [YEAR], [MAKE], [VIN], [LICENSED_GVW], [POWER_UNIT_TYPE], [STEER_AXLE_TIRE_SIZE], [CONCURRENCY_CONTROL_NUMBER], [DB_CREATE_USERID], [DB_CREATE_TIMESTAMP], [DB_LAST_UPDATE_USERID], [DB_LAST_UPDATE_TIMESTAMP], [COMPANY_ID]) VALUES (102, N'LCV2', N'HIU499', N'CA-BC', 2022, N'Kenworth', N'199876', CAST(22000 AS Numeric(18, 2)), N'LCVTPDB', 431, NULL, N'dbo', GETUTCDATE(), N'dbo', GETUTCDATE(), 74)

SET IDENTITY_INSERT [dbo].[ORBC_POWER_UNIT] OFF
GO
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SET NOCOUNT ON
GO

INSERT INTO permit.ORBC_SPECIAL_AUTH (COMPANY_ID, LCV) VALUES (74, 'Y')
GO
2 changes: 2 additions & 0 deletions database/mssql/scripts/utility/refresh-sample-data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ USAGE="-u ORBC_USER -p ORBC_PASS -s ORBC_SERVER -d ORBC_DATABASE"
parse_options "${USAGE}" ${@}

echo "Deleting existing sample data"
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -Q "SET QUOTED_IDENTIFIER ON; SET NOCOUNT ON; DELETE FROM permit.ORBC_SPECIAL_AUTH"
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -Q "SET QUOTED_IDENTIFIER ON; SET NOCOUNT ON; DELETE FROM dbo.ORBC_FEATURE_FLAG"
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -Q "SET QUOTED_IDENTIFIER ON; SET NOCOUNT ON; DELETE FROM dbo.ORBC_TRAILER"
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -Q "SET QUOTED_IDENTIFIER ON; SET NOCOUNT ON; DELETE FROM dbo.ORBC_POWER_UNIT"
Expand All @@ -25,6 +26,7 @@ sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -i ${SCRIPT_DIR}/sampledata/dbo.ORBC_POWER_UNIT.Table.sql
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -i ${SCRIPT_DIR}/sampledata/dbo.ORBC_TRAILER.Table.sql
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -i ${SCRIPT_DIR}/sampledata/dbo.ORBC_FEATURE_FLAG.Table.sql
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -i ${SCRIPT_DIR}/sampledata/permit.ORBC_SPECIAL_AUTH.Table.sql

echo "Setting credit account sequence restart to current timestamp (used only for lower environments)"
sqlcmd -C -U ${ORBC_USER} -P "${ORBC_PASS}" -S ${ORBC_SERVER} -d ${ORBC_DATABASE} -i ${SCRIPT_DIR}/sampledata/permit.ORBC_CREDIT_ACCOUNT_NUMBER_SEQ.sql
Expand Down
43 changes: 43 additions & 0 deletions database/mssql/scripts/versions/revert/v_55_ddl_revert.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET NOCOUNT ON
GO
SET XACT_ABORT ON
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
BEGIN TRANSACTION
GO

-- Remove the newly added policy configuration
DELETE FROM [dbo].[ORBC_POLICY_CONFIGURATION]
WHERE POLICY_CONFIGURATION_ID = (SELECT MAX(POLICY_CONFIGURATION_ID) FROM [dbo].[ORBC_POLICY_CONFIGURATION])
GO

IF @@ERROR <> 0 SET NOEXEC ON
GO

DECLARE @VersionDescription VARCHAR(255)
SET @VersionDescription = 'Reverting updates to policy configuration JSON allowing lcv vehicles for TROS and TROW'

INSERT [dbo].[ORBC_SYS_VERSION] ([VERSION_ID], [DESCRIPTION], [RELEASE_DATE]) VALUES (54, @VersionDescription, getutcdate())
GO

IF @@ERROR <> 0 SET NOEXEC ON
GO

COMMIT TRANSACTION
GO
IF @@ERROR <> 0 SET NOEXEC ON
GO
DECLARE @Success AS BIT
SET @Success = 1
SET NOEXEC OFF
IF (@Success = 1) PRINT 'The database revert succeeded'
ELSE BEGIN
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION
PRINT 'The database revert failed'
END
GO
48 changes: 48 additions & 0 deletions database/mssql/scripts/versions/v_55_ddl.sql

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"material-react-table": "^2.13.3",
"mui-nested-menu": "^3.4.0",
"oidc-client-ts": "^3.1.0",
"onroute-policy-engine": "^1.1.0",
"onroute-policy-engine": "^1.4.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.1.2",
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/features/permits/ApplicationSteps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { ErrorBoundary } from "react-error-boundary";

import { ApplicationStepPage } from "./components/dashboard/ApplicationStepPage";
import { ErrorFallback } from "../../common/pages/ErrorFallback";
import { ApplicationStep, ApplicationStepContext } from "../../routes/constants";
import {
ApplicationStep,
ApplicationStepContext,
} from "../../routes/constants";

export const ApplicationSteps = React.memo(
({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ export const ApplicationStepPage = ({
<ApplicationReview companyId={companyId} />
);
}

return (
<ApplicationForm
permitType={applicationPermitType}
companyId={companyId}
applicationStepContext={applicationStepContext}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { Policy } from "onroute-policy-engine";

import { Nullable } from "../../../../../common/types/common";
import { PERMIT_TYPES, PermitType } from "../../../types/PermitType";
import { PermitType } from "../../../types/PermitType";
import { getDefaultRequiredVal } from "../../../../../common/helpers/util";
import { TROW_ELIGIBLE_VEHICLE_SUBTYPES } from "../../../constants/trow";
import { TROS_ELIGIBLE_VEHICLE_SUBTYPES } from "../../../constants/tros";
import {
DEFAULT_COMMODITY_SELECT_VALUE,
LCV_VEHICLE_SUBTYPES,
} from "../../../constants/constants";

/**
* Get eligible vehicle subtypes based on given criteria.
Expand All @@ -20,41 +14,30 @@ import {
*/
export const getEligibleVehicleSubtypes = (
permitType: PermitType,
isLcvDesignated: boolean,
selectedCommodity?: Nullable<string>,
policyEngine?: Nullable<Policy>,
) => {
const lcvSubtypes = LCV_VEHICLE_SUBTYPES.map(({ typeCode }) => typeCode);
switch (permitType) {
case PERMIT_TYPES.STOS: {
if (!selectedCommodity || !policyEngine || (selectedCommodity === DEFAULT_COMMODITY_SELECT_VALUE))
return new Set<string>();
if (!policyEngine)
return new Set<string>();

const subtypesMap = policyEngine.getPermittableVehicleTypes(permitType, selectedCommodity);
return new Set(
[
...getDefaultRequiredVal(
new Map<string, string>(),
subtypesMap.get("powerUnits"),
).keys(),
...getDefaultRequiredVal(
new Map<string, string>(),
subtypesMap.get("trailers"),
).keys(),
].concat(isLcvDesignated ? lcvSubtypes : []),
);
}
// Policy engine currently doesn't return vehicle subtypes unless a commodity is provided
// which TROW and TROS doesn't have, thus here the hardcoded subtypes are being used
case PERMIT_TYPES.TROW:
return new Set(
TROW_ELIGIBLE_VEHICLE_SUBTYPES.concat(isLcvDesignated ? lcvSubtypes : []),
);
case PERMIT_TYPES.TROS:
return new Set(
TROS_ELIGIBLE_VEHICLE_SUBTYPES.concat(isLcvDesignated ? lcvSubtypes : []),
);
default:
return new Set<string>();
}
// The policy engine requires a commodity to be provided for any
// permit type where commodity is required, hence the nullish
// coalescing operator on the second parameter. An empty string will
// result in an empty map returned.
const subtypesMap = policyEngine.getPermittableVehicleTypes(
permitType,
getDefaultRequiredVal('-', selectedCommodity),
);
return new Set(
[
...getDefaultRequiredVal(
new Map<string, string>(),
subtypesMap.get("powerUnits"),
).keys(),
...getDefaultRequiredVal(
new Map<string, string>(),
subtypesMap.get("trailers"),
).keys(),
],
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export const useInitApplicationFormData = (
const initialFormData = useMemo(() => {
const eligibleVehicleSubtypes = getEligibleVehicleSubtypes(
permitType,
isLcvDesignated,
applicationData?.permitData?.permittedCommodity?.commodityType,
policyEngine,
);
Expand Down
1 change: 0 additions & 1 deletion frontend/src/features/permits/hooks/usePermitVehicles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export const usePermitVehicles = (
const eligibleVehicleSubtypes = useMemo(() => {
return getEligibleVehicleSubtypes(
permitType,
isLcvDesignated,
selectedCommodity,
policyEngine,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export const AmendPermitForm = () => {
trailerSubtypeNamesMap,
} = usePermitVehicleManagement(companyId);

const policyEngine = usePolicyEngine();
const policyEngine = usePolicyEngine(specialAuthorizations);

const { initialFormData, formData, formMethods } = useAmendPermitForm({
repopulateFormData: currentStepIndex === 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
applyWhenNotNullable,
getDefaultRequiredVal,
} from "../../../../../common/helpers/util";
import { useFetchSpecialAuthorizations } from "../../../../settings/hooks/specialAuthorizations";

export const AmendPermitReview = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -59,8 +60,9 @@ export const AmendPermitReview = () => {
amendmentApplication?.permitType,
permit?.permitType,
);
const { data: specialAuthorizations } = useFetchSpecialAuthorizations(companyId);

const policyEngine = usePolicyEngine();
const policyEngine = usePolicyEngine(specialAuthorizations);
const { commodityOptions } = useCommodityOptions(policyEngine, permitType);
const powerUnitSubTypesQuery = usePowerUnitSubTypesQuery();
const trailerSubTypesQuery = useTrailerSubTypesQuery();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export const useAmendPermitForm = (
if (amendmentApplication) {
const eligibleSubtypes = getEligibleVehicleSubtypes(
amendmentApplication.permitType,
isLcvDesignated,
amendmentApplication.permitData.permittedCommodity?.commodityType,
policyEngine,
);
Expand Down Expand Up @@ -80,7 +79,6 @@ export const useAmendPermitForm = (

const eligibleSubtypes = getEligibleVehicleSubtypes(
defaultPermitFormData.permitType,
isLcvDesignated,
defaultPermitFormData.permitData.permittedCommodity?.commodityType,
policyEngine,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ import {

import {
APPLICATIONS_ROUTES,
APPLICATION_QUEUE_ROUTES,
APPLICATION_STEPS,
APPLICATION_STEP_CONTEXTS,
ApplicationStepContext,
ERROR_ROUTES,
} from "../../../../routes/constants";

Expand All @@ -59,9 +62,11 @@ const FEATURE = "application";
export const ApplicationForm = ({
permitType,
companyId,
applicationStepContext,
}: {
permitType: PermitType;
companyId: number;
applicationStepContext: ApplicationStepContext;
}) => {
// Context to hold all of the application data related to the application
const applicationContext = useContext(ApplicationContext);
Expand All @@ -88,7 +93,7 @@ export const ApplicationForm = ({
trailerSubtypeNamesMap,
} = usePermitVehicleManagement(companyId);

const policyEngine = usePolicyEngine();
const policyEngine = usePolicyEngine(specialAuthorizations);

// Use a custom hook that performs the following whenever page is rendered (or when application context is updated/changed):
// 1. Get all data needed to initialize the application form (from application context, company, user details)
Expand Down Expand Up @@ -192,6 +197,7 @@ export const ApplicationForm = ({
const updatedViolations = await triggerPolicyValidation();
// prevent CV client continuing if there are policy engine validation errors
if (Object.keys(updatedViolations).length > 0 && !isStaffUser) {
console.error(updatedViolations);
return;
}

Expand All @@ -201,10 +207,13 @@ export const ApplicationForm = ({
const savedVehicleDetails = await handleSaveVehicle(vehicleData);

// Save application before continuing
await onSaveApplication(
(permitId) => navigate(APPLICATIONS_ROUTES.REVIEW(permitId)),
savedVehicleDetails,
);
await onSaveApplication((permitId) => {
return navigate(
applicationStepContext === APPLICATION_STEP_CONTEXTS.QUEUE
? APPLICATION_QUEUE_ROUTES.REVIEW(companyId, permitId)
: APPLICATIONS_ROUTES.REVIEW(permitId),
);
}, savedVehicleDetails);
};

const onSaveSuccess = (savedApplication: Application, status: number) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const ApplicationReview = ({

const navigate = useNavigate();

const policyEngine = usePolicyEngine();
const policyEngine = usePolicyEngine(specialAuth);
const { commodityOptions } = useCommodityOptions(policyEngine, permitType);
const powerUnitSubTypesQuery = usePowerUnitSubTypesQuery();
const trailerSubTypesQuery = useTrailerSubTypesQuery();
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/features/policy/hooks/usePolicyEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { Policy } from "onroute-policy-engine";

import { usePolicyConfigurationQuery } from "./usePolicyConfigurationQuery";
import { isNull } from "../../../common/types/common";
import { SpecialAuthorizationData } from "../../settings/types/SpecialAuthorization";

/**
* Hook that instantiates the policy engine instance.
* The hook will return undefined when policy configuration is still loading,
* and null when there's a problem getting the policy configuration.
* @returns The instantiated policy engine, or undefined when loading, and null on error
*/
export const usePolicyEngine = () => {
export const usePolicyEngine = (specialAuthorizations?: SpecialAuthorizationData) => {
const { data: policyConfiguration } = usePolicyConfigurationQuery();

const policyEngine = useMemo(() => {
Expand All @@ -20,5 +21,9 @@ export const usePolicyEngine = () => {
return new Policy(policyConfiguration.policy);
}, [policyConfiguration]);

if (specialAuthorizations) {
policyEngine?.setSpecialAuthorizations(specialAuthorizations);
}

return policyEngine;
};
Loading

0 comments on commit fb57ad8

Please sign in to comment.