{({ insert, remove }) => (
<>
@@ -1287,16 +1314,17 @@ const AddSaltReportFormFields = ({ setInitialValues, formValues, setValidationSc
-
+
-
+
+ Select an option
Drinking Water
Aquatic Life
Wetlands
@@ -1319,7 +1347,7 @@ const AddSaltReportFormFields = ({ setInitialValues, formValues, setValidationSc
remove(index)}>
- Remove row
+ Remove
diff --git a/client/src/js/components/forms/saltreport/DefaultValues.js b/client/src/js/components/forms/saltreport/DefaultValues.js
index 23fefe90..7dd54f90 100644
--- a/client/src/js/components/forms/saltreport/DefaultValues.js
+++ b/client/src/js/components/forms/saltreport/DefaultValues.js
@@ -58,24 +58,7 @@ export const defaultValues = {
},
sect4: {
saltStorageSitesTotal: null,
- stockpiles: [
- {
- siteName: '',
- motiOwned: false,
- roadSalts: {
- stockpilesTotal: null,
- onImpermeableSurface: null,
- underPermanentRoof: null,
- underTarp: null,
- },
- treatedAbrasives: {
- stockpilesTotal: null,
- onImpermeableSurface: null,
- underPermanentRoof: null,
- underTarp: null,
- },
- },
- ],
+ stockpiles: [],
practices: {
allMaterialsHandled: {
hasPlan: false,
@@ -212,18 +195,7 @@ export const defaultValues = {
areasWithChloride: null,
},
},
- vulnerableAreas: [
- {
- highwayNumber: null,
- latitude: null,
- longitude: null,
- feature: null,
- type: null,
- protectionMeasures: null,
- environmentalMonitoring: false,
- comments: null
- },
- ],
+ vulnerableAreas: [],
},
appendix: {
materialStorage: {
diff --git a/client/src/js/components/forms/saltreport/ValidationSchema.js b/client/src/js/components/forms/saltreport/ValidationSchema.js
index 19496400..4439bebe 100644
--- a/client/src/js/components/forms/saltreport/ValidationSchema.js
+++ b/client/src/js/components/forms/saltreport/ValidationSchema.js
@@ -24,93 +24,84 @@ const coordinatePrecision = (precision) => {
};
const stockpileSchema = Yup.object().shape({
- siteName: Yup.string(),
- motiOwned: Yup.boolean(),
+ siteName: Yup.string().nullable(true),
+ motiOwned: Yup.boolean().nullable(true),
roadSalts: Yup.object().shape({
stockpilesTotal: Yup.number().min(0, 'Cannot be negative').nullable(true),
onImpermeableSurface: Yup.number().min(0, 'Cannot be negative').nullable(true),
underPermanentRoof: Yup.number().min(0, 'Cannot be negative').nullable(true),
underTarp: Yup.number().min(0, 'Cannot be negative').nullable(true),
- }),
+ }).nullable(true),
treatedAbrasives: Yup.object().shape({
stockpilesTotal: Yup.number().min(0, 'Cannot be negative').nullable(true),
onImpermeableSurface: Yup.number().min(0, 'Cannot be negative').nullable(true),
underPermanentRoof: Yup.number().min(0, 'Cannot be negative').nullable(true),
underTarp: Yup.number().min(0, 'Cannot be negative').nullable(true),
- }),
+ }).nullable(true),
});
const houseKeepingPracticeSchema = Yup.object().shape({
allMaterialsHandled: Yup.object().shape({
- hasPlan: Yup.boolean(),
+ hasPlan: Yup.boolean().nullable(true),
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- }),
+ }).nullable(true),
equipmentPreventsOverloading: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
wastewaterSystem: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
controlDiversionExternalWaters: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
drainageCollectionSystem: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
municipalSewerSystem: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
removalContainment: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
watercourse: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
otherDischargePoint: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
ongoingCleanup: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
riskManagementPlan: Yup.object().shape({
numSites: Yup.number().integer('Must be an integer').min(0, 'Cannot be negative').nullable(),
-
- hasPlan: Yup.boolean(),
- }),
+ hasPlan: Yup.boolean().nullable(true),
+ }).nullable(true),
});
const vulnerableAreaSchema = Yup.object().shape({
- highwayNumber: Yup.string().nullable(),
+ highwayNumber: Yup.string().max(16).nullable(true),
latitude: coordinatePrecision(6)
.min(-90, 'Latitude must be greater than or equal to -90')
- .max(90, 'Latitude must be less than or equal to 90'),
+ .max(90, 'Latitude must be less than or equal to 90')
+ .nullable(true), // aligns with LAT decimal(9,6)
longitude: coordinatePrecision(6)
.min(-180, 'Longitude must be greater than or equal to -180')
- .max(180, 'Longitude must be less than or equal to 180'),
- feature: Yup.string().nullable(),
- type: Yup.string().nullable(),
- protectionMeasures: Yup.string().nullable(),
- environmentalMonitoring: Yup.boolean().nullable(),
- comments: Yup.string().nullable(),
+ .max(180, 'Longitude must be less than or equal to 180')
+ .nullable(true), // aligns with LONG decimal(9,6)
+ feature: Yup.string().max(255).nullable(true),
+ type: Yup.string().max(255).nullable(true),
+ protectionMeasures: Yup.string().max(255).nullable(true),
+ environmentalMonitoring: Yup.boolean().nullable(true),
+ comments: Yup.string().max(255).nullable(true),
});
const typesOfVulnerableAreasSchema = Yup.object().shape({
@@ -118,145 +109,158 @@ const typesOfVulnerableAreasSchema = Yup.object().shape({
areasIdentified: Yup.number().nullable(true),
areasWithProtection: Yup.number().nullable(true),
areasWithChloride: Yup.number().nullable(true),
- }),
+ }).nullable(true),
aquaticLife: Yup.object().shape({
areasIdentified: Yup.number().nullable(true),
areasWithProtection: Yup.number().nullable(true),
areasWithChloride: Yup.number().nullable(true),
- }),
+ }).nullable(true),
wetlands: Yup.object().shape({
areasIdentified: Yup.number().nullable(true),
areasWithProtection: Yup.number().nullable(true),
areasWithChloride: Yup.number().nullable(true),
- }),
+ }).nullable(true),
delimitedAreas: Yup.object().shape({
areasIdentified: Yup.number().nullable(true),
areasWithProtection: Yup.number().nullable(true),
areasWithChloride: Yup.number().nullable(true),
- }),
+ }).nullable(true),
valuedLands: Yup.object().shape({
areasIdentified: Yup.number().nullable(true),
areasWithProtection: Yup.number().nullable(true),
areasWithChloride: Yup.number().nullable(true),
- }),
+ }).nullable(true),
+});
+
+const weatherMonitoringSourceSchema = Yup.object().shape({
+ relied: Yup.boolean().nullable(true),
+ number: Yup.number().integer().nullable(true).min(0, 'Cannot be negative'),
});
export const validationSchema = Yup.object({
serviceArea: Yup.string().required('Service Area is required'),
- contactName: Yup.string().required('Contact Name is required'),
+ contactName: Yup.string().max(200).required('Contact Name is required'),
telephone: Yup.string()
.required('Telephone is required')
.matches(/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s./0-9]*$/, 'Invalid telephone format'),
- email: Yup.string().required('Email is required').email('Invalid email format'),
+ email: Yup.string().max(100).required('Email is required').email('Invalid email format'),
sect1: Yup.object().shape({
- planDeveloped: Yup.string(),
- planReviewed: Yup.string(),
- planUpdated: Yup.string(),
+ planDeveloped: Yup.string().max(20).nullable(true),
+ planReviewed: Yup.string().max(20).nullable(true),
+ planUpdated: Yup.string().max(20).nullable(true),
training: Yup.object().shape({
- manager: Yup.string(),
- supervisor: Yup.string(),
- operator: Yup.string(),
- mechanical: Yup.string(),
- patroller: Yup.string(),
- }),
+ manager: Yup.string().max(20).nullable(true),
+ supervisor: Yup.string().max(20).nullable(true),
+ operator: Yup.string().max(20).nullable(true),
+ mechanical: Yup.string().max(20).nullable(true),
+ patroller: Yup.string().max(20).nullable(true),
+ }).nullable(true),
objectives: Yup.object().shape({
materialStorage: Yup.object().shape({
- identified: Yup.number().min(0, 'Cannot be negative').nullable(),
- achieved: Yup.number().min(0, 'Cannot be negative').nullable(),
- }),
+ identified: Yup.number().min(0, 'Cannot be negative').nullable(true),
+ achieved: Yup.number().min(0, 'Cannot be negative').nullable(true),
+ }).nullable(true),
saltApplication: Yup.object().shape({
- identified: Yup.number().min(0, 'Cannot be negative').nullable(),
- achieved: Yup.number().min(0, 'Cannot be negative').nullable(),
- }),
- }),
- }),
+ identified: Yup.number().min(0, 'Cannot be negative').nullable(true),
+ achieved: Yup.number().min(0, 'Cannot be negative').nullable(true),
+ }).nullable(true),
+ }).nullable(true),
+ }).nullable(true),
sect2: Yup.object().shape({
- roadTotalLength: Yup.number().nullable().min(0, 'Cannot be negative').required('Required'),
- saltTotalDays: Yup.number().nullable().min(0, 'Cannot be negative').required(),
- }),
+ roadTotalLength: Yup.number().nullable(true).min(0, 'Cannot be negative').required('Required'),
+ saltTotalDays: Yup.number().nullable(true).min(0, 'Cannot be negative').required('Required'),
+ }).nullable(true),
sect3: Yup.object().shape({
deicer: Yup.object().shape({
- nacl: decimalWithPrecision(2),
- mgcl2: decimalWithPrecision(2),
- cacl2: decimalWithPrecision(2),
- acetate: decimalWithPrecision(2),
- }),
+ nacl: decimalWithPrecision(2).nullable(true),
+ mgcl2: decimalWithPrecision(2).nullable(true),
+ cacl2: decimalWithPrecision(2).nullable(true),
+ acetate: decimalWithPrecision(2).nullable(true),
+ }).nullable(true),
treatedAbrasives: Yup.object().shape({
- sandStoneDust: decimalWithPrecision(2),
- nacl: decimalWithPrecision(2),
- mgcl2: decimalWithPrecision(2),
- cacl2: decimalWithPrecision(2),
- }),
+ sandStoneDust: decimalWithPrecision(2).nullable(true),
+ nacl: decimalWithPrecision(2).nullable(true),
+ mgcl2: decimalWithPrecision(2).nullable(true),
+ cacl2: decimalWithPrecision(2).nullable(true),
+ }).nullable(true),
prewetting: Yup.object().shape({
- nacl: decimalWithPrecision(2),
- mgcl2: decimalWithPrecision(2),
- cacl2: decimalWithPrecision(2),
- acetate: decimalWithPrecision(2),
- nonchloride: decimalWithPrecision(2),
- }),
+ nacl: decimalWithPrecision(2).nullable(true),
+ mgcl2: decimalWithPrecision(2).nullable(true),
+ cacl2: decimalWithPrecision(2).nullable(true),
+ acetate: decimalWithPrecision(2).nullable(true),
+ nonchloride: decimalWithPrecision(2).nullable(true),
+ }).nullable(true),
pretreatment: Yup.object().shape({
- nacl: decimalWithPrecision(2),
- mgcl2: decimalWithPrecision(2),
- cacl2: decimalWithPrecision(2),
- acetate: decimalWithPrecision(2),
- nonchloride: decimalWithPrecision(2),
- }),
+ nacl: decimalWithPrecision(2).nullable(true),
+ mgcl2: decimalWithPrecision(2).nullable(true),
+ cacl2: decimalWithPrecision(2).nullable(true),
+ acetate: decimalWithPrecision(2).nullable(true),
+ nonchloride: decimalWithPrecision(2).nullable(true),
+ }).nullable(true),
antiicing: Yup.object().shape({
- nacl: decimalWithPrecision(2),
- mgcl2: decimalWithPrecision(2),
- cacl2: decimalWithPrecision(2),
- acetate: decimalWithPrecision(2),
- nonchloride: decimalWithPrecision(2),
- }),
+ nacl: decimalWithPrecision(2).nullable(true),
+ mgcl2: decimalWithPrecision(2).nullable(true),
+ cacl2: decimalWithPrecision(2).nullable(true),
+ acetate: decimalWithPrecision(2).nullable(true),
+ nonchloride: decimalWithPrecision(2).nullable(true),
+ }).nullable(true),
multiChlorideA: Yup.object().shape({
- litres: decimalWithPrecision(2),
- naclPercentage: decimalWithPrecision(2),
- mgcl2Percentage: decimalWithPrecision(2),
- cacl2Percentage: decimalWithPrecision(2),
- }),
+ litres: decimalWithPrecision(2).nullable(true),
+ naclPercentage: decimalWithPrecision(2).nullable(true),
+ mgcl2Percentage: decimalWithPrecision(2).nullable(true),
+ cacl2Percentage: decimalWithPrecision(2).nullable(true),
+ }).nullable(true),
multiChlorideB: Yup.object().shape({
- litres: decimalWithPrecision(2),
- naclPercentage: decimalWithPrecision(2),
- mgcl2Percentage: decimalWithPrecision(2),
- cacl2Percentage: decimalWithPrecision(2),
- }),
- }),
+ litres: decimalWithPrecision(2).nullable(true),
+ naclPercentage: decimalWithPrecision(2).nullable(true),
+ mgcl2Percentage: decimalWithPrecision(2).nullable(true),
+ cacl2Percentage: decimalWithPrecision(2).nullable(true),
+ }).nullable(true),
+ }).nullable(true),
sect4: Yup.object()
.shape({
- saltStorageTotal: Yup.number().nullable(true),
- stockpiles: Yup.array().of(stockpileSchema),
- houseKeepingPractice: houseKeepingPracticeSchema.nullable(true),
+ saltStorageSitesTotal: Yup.number().min(0).nullable(true),
+ stockpiles: Yup.array().of(stockpileSchema).nullable(true),
+ practices: houseKeepingPracticeSchema.nullable(true),
})
.nullable(true),
sect5: Yup.object().shape({
- numberOfVehicles: Yup.number().min(0).nullable().required('Number of Vehicles is required'),
- vehiclesForSaltApplication: Yup.number().min(0).nullable().required('Vehicles for Salt Application is required'),
- vehiclesWithConveyors: Yup.number().min(0).nullable().required('Vehicles with Conveyors is required'),
+ numberOfVehicles: Yup.number().min(0).nullable(true).required('Number of Vehicles is required'),
+ vehiclesForSaltApplication: Yup.number().min(0).nullable(true).required('Vehicles for Salt Application is required'),
+ vehiclesWithConveyors: Yup.number().min(0).nullable(true).required('Vehicles with Conveyors is required'),
vehiclesWithPreWettingEquipment: Yup.number()
.min(0)
- .nullable()
+ .nullable(true)
.required('Vehicles with Pre-Wetting Equipment is required'),
- vehiclesForDLA: Yup.number().min(0).nullable().required('Vehicles for DLA is required'),
+ vehiclesForDLA: Yup.number().min(0).nullable(true).required('Vehicles for DLA is required'),
regularCalibration: Yup.boolean().nullable(true),
regularCalibrationTotal: Yup.number()
.nullable(true)
.when('regularCalibration', {
is: true,
- then: Yup.number()
+ then: Yup.number().integer()
.min(0, 'Frequency must be non-negative')
.required('Frequency number is required when equipment is regularly calibrated'),
- otherwise: Yup.number().nullable(true),
+ otherwise: Yup.number().integer().nullable(true),
}),
- }),
+ weatherMonitoringSources: Yup.object().shape({
+ infraredThermometer: weatherMonitoringSourceSchema,
+ meteorologicalService: Yup.object().shape({
+ relied: Yup.boolean().nullable(true),
+ }),
+ fixedRWISStations: weatherMonitoringSourceSchema,
+ mobileRWISMounted: weatherMonitoringSourceSchema,
+ }).nullable(true),
+ }).nullable(true),
sect7: Yup.object()
.shape({
- completedInventory: Yup.string(),
- setVulnerableAreas: Yup.string(),
- actionPlanPrepared: Yup.string(),
- protectionMeasuresImplemented: Yup.string(),
- environmentalMonitoringConducted: Yup.string(),
- typesOfVulnerableAreas: typesOfVulnerableAreasSchema,
- vulnerableAreas: Yup.array().of(vulnerableAreaSchema),
+ completedInventory: Yup.string().nullable(true),
+ setVulnerableAreas: Yup.string().nullable(true),
+ actionPlanPrepared: Yup.string().nullable(true),
+ protectionMeasuresImplemented: Yup.string().nullable(true),
+ environmentalMonitoringConducted: Yup.string().nullable(true),
+ typesOfVulnerableAreas: typesOfVulnerableAreasSchema.nullable(true),
+ vulnerableAreas: Yup.array().of(vulnerableAreaSchema).nullable(true),
})
.nullable(true),
});
diff --git a/database/V28.0/CREATE_HMR_SALT_REPORT.sql b/database/V28.0/CREATE_HMR_SALT_REPORT.sql
index 91e1aa27..11b067c1 100644
--- a/database/V28.0/CREATE_HMR_SALT_REPORT.sql
+++ b/database/V28.0/CREATE_HMR_SALT_REPORT.sql
@@ -1,14 +1,85 @@
-- Script to create and enable Salt Reporting in HMCR database.
-USE HMR_DEV; -- uncomment appropriate instance
---USE HMR_TST;
---USE HMR_UAT;
---USE HMR_PRD;
-GO
+-- ROLE AND PERMISSION BINDING:
+-- Step 1: Insert into HMR_PERMISSION and capture PERMISSION_ID
+DECLARE @NewPermissionID TABLE (PERMISSION_ID INT);
+INSERT INTO [dbo].[HMR_PERMISSION]
+ ([PERMISSION_ID],[NAME],[DESCRIPTION],[END_DATE],[APP_CREATE_USERID],[APP_CREATE_TIMESTAMP],[APP_CREATE_USER_GUID],[APP_CREATE_USER_DIRECTORY],[APP_LAST_UPDATE_USERID],[APP_LAST_UPDATE_TIMESTAMP],[APP_LAST_UPDATE_USER_GUID],[APP_LAST_UPDATE_USER_DIRECTORY])
+OUTPUT INSERTED.PERMISSION_ID INTO @NewPermissionID
+VALUES
+ (NEXT VALUE FOR [dbo].[HMR_RL_PERM_ID_SEQ],'SALT','Salt Reporting',NULL,user_name(),GETUTCDATE(),'31587d92-0297-4493-a7e5-c078c6ba0d37','IDIR',user_name(),GETUTCDATE(),'31587d92-0297-4493-a7e5-c078c6ba0d37','IDIR');
+
+-- Step 2: Insert into HMR_ROLE and capture ROLE_ID
+DECLARE @NewRoleID TABLE (ROLE_ID INT);
+INSERT INTO [dbo].[HMR_ROLE]
+ ([ROLE_ID],[NAME],[DESCRIPTION],[END_DATE],[APP_CREATE_USERID],[APP_CREATE_TIMESTAMP],[APP_CREATE_USER_GUID],[APP_CREATE_USER_DIRECTORY],[APP_LAST_UPDATE_USERID],[APP_LAST_UPDATE_TIMESTAMP],[APP_LAST_UPDATE_USER_GUID],[APP_LAST_UPDATE_USER_DIRECTORY])
+OUTPUT INSERTED.ROLE_ID INTO @NewRoleID
+VALUES
+ (NEXT VALUE FOR [dbo].[HMR_RL_ID_SEQ],'Salt Reporting','Submit and view Submitted Annual Salt Report',NULL,user_name(),GETUTCDATE(),'31587d92-0297-4493-a7e5-c078c6ba0d37','IDIR',user_name(),GETUTCDATE(),'31587d92-0297-4493-a7e5-c078c6ba0d37','IDIR');
+
+-- Step 3: Insert into HMR_ROLE_PERMISSION using captured PERMISSION_ID and ROLE_ID
+INSERT INTO [dbo].[HMR_ROLE_PERMISSION]
+ ([ROLE_PERMISSION_ID],[ROLE_ID],[PERMISSION_ID],[END_DATE],[APP_CREATE_USERID],[APP_CREATE_TIMESTAMP],[APP_CREATE_USER_GUID],[APP_CREATE_USER_DIRECTORY],[APP_LAST_UPDATE_USERID],[APP_LAST_UPDATE_TIMESTAMP],[APP_LAST_UPDATE_USER_GUID],[APP_LAST_UPDATE_USER_DIRECTORY])
+SELECT
+ NEXT VALUE FOR [dbo].[HMR_RL_PERM_ID_SEQ],
+ r.ROLE_ID,
+ p.PERMISSION_ID,
+ NULL,
+ user_name(),
+ GETUTCDATE(),
+ '31587d92-0297-4493-a7e5-c078c6ba0d37',
+ 'IDIR',
+ user_name(),
+ GETUTCDATE(),
+ '31587d92-0297-4493-a7e5-c078c6ba0d37',
+ 'IDIR'
+FROM @NewRoleID r, @NewPermissionID p;
+
+-- Step 4: Assign the newly created role to all users in HMR_SYSTEM_USER, with END_DATE check
+DECLARE @UserID INT;
+DECLARE @CapturedRoleID INT;
+
+-- Retrieve the single role ID from the table variable
+SELECT @CapturedRoleID = ROLE_ID FROM @NewRoleID;
+
+DECLARE user_cursor CURSOR FOR
+SELECT SYSTEM_USER_ID
+FROM [dbo].[HMR_SYSTEM_USER];
+
+OPEN user_cursor;
+
+FETCH NEXT FROM user_cursor INTO @UserID;
+
+WHILE @@FETCH_STATUS = 0
+BEGIN
+ INSERT INTO [dbo].[HMR_USER_ROLE]
+ ([USER_ROLE_ID],[ROLE_ID],[SYSTEM_USER_ID],[END_DATE],[APP_CREATE_USERID],[APP_CREATE_TIMESTAMP],[APP_CREATE_USER_GUID],[APP_CREATE_USER_DIRECTORY],[APP_LAST_UPDATE_USERID],[APP_LAST_UPDATE_TIMESTAMP],[APP_LAST_UPDATE_USER_GUID],[APP_LAST_UPDATE_USER_DIRECTORY])
+ SELECT
+ NEXT VALUE FOR [dbo].[HMR_USR_RL_ID_SEQ],
+ @CapturedRoleID,
+ @UserID,
+ NULL,
+ user_name(),
+ GETUTCDATE(),
+ '31587d92-0297-4493-a7e5-c078c6ba0d37',
+ 'IDIR',
+ user_name(),
+ GETUTCDATE(),
+ '31587d92-0297-4493-a7e5-c078c6ba0d37',
+ 'IDIR'
+ WHERE NOT EXISTS (
+ SELECT 1
+ FROM [dbo].[HMR_USER_ROLE] ur
+ WHERE ur.ROLE_ID = @CapturedRoleID
+ AND ur.SYSTEM_USER_ID = @UserID
+ AND (ur.END_DATE IS NULL OR ur.END_DATE > GETDATE())
+ );
-INSERT INTO [dbo].[HMR_PERMISSION] ([PERMISSION_ID],[NAME],[DESCRIPTION],[END_DATE],[CONCURRENCY_CONTROL_NUMBER],[APP_CREATE_USERID],[APP_CREATE_TIMESTAMP],[APP_CREATE_USER_GUID],[APP_CREATE_USER_DIRECTORY],[APP_LAST_UPDATE_USERID],[APP_LAST_UPDATE_TIMESTAMP],[APP_LAST_UPDATE_USER_GUID],[APP_LAST_UPDATE_USER_DIRECTORY],[DB_AUDIT_CREATE_USERID],[DB_AUDIT_CREATE_TIMESTAMP],[DB_AUDIT_LAST_UPDATE_USERID],[DB_AUDIT_LAST_UPDATE_TIMESTAMP])
-VALUES (NEXT VALUE FOR [dbo].[HMR_RL_PERM_ID_SEQ],'SALT','Salt Reporting',NULL,1,user_name(),GETUTCDATE(),'31587d92-0297-4493-a7e5-c078c6ba0d37','IDIR',user_name(),GETUTCDATE(),'31587d92-0297-4493-a7e5-c078c6ba0d37','IDIR','IDIR\ISEAN',GETUTCDATE(),'IDIR\ISEAN',GETUTCDATE());
+ FETCH NEXT FROM user_cursor INTO @UserID;
+END;
+CLOSE user_cursor;
+DEALLOCATE user_cursor;
-- Sequence Definitions
-- HMR_SLT_RPT_ID_SEQ: Sequence for report IDs
diff --git a/database/rollback/ROLLBACK_HMR_SALT_REPORT.sql b/database/rollback/ROLLBACK_HMR_SALT_REPORT.sql
index 1c93c5bf..1feedd26 100644
--- a/database/rollback/ROLLBACK_HMR_SALT_REPORT.sql
+++ b/database/rollback/ROLLBACK_HMR_SALT_REPORT.sql
@@ -1,11 +1,5 @@
-- Script to rollback Salt Reporting features in HMCR database.
-USE HMR_DEV; -- uncomment appropriate instance
---USE HMR_TST;
---USE HMR_UAT;
---USE HMR_PRD;
-GO
-
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'HMR_SALT_REPORT', @level2type=N'COLUMN',@level2name=N'WETLANDS_PROT_ID'
GO
EXEC sys.sp_dropextendedproperty @name=N'MS_Description' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'HMR_SALT_REPORT', @level2type=N'COLUMN',@level2name=N'WETLANDS_CHLOR_ID'
@@ -343,19 +337,30 @@ GO
DROP SEQUENCE [dbo].[HMR_SALT_REPORT_H_ID_SEQ];
GO
+-- Step 1: Find the IDs of the inserted role and permission
+DECLARE @RoleID INT;
+DECLARE @PermissionID INT;
+
+SELECT @RoleID = [ROLE_ID]
+FROM [dbo].[HMR_ROLE]
+WHERE [NAME] = 'Salt Reporting' AND [DESCRIPTION] = 'Submit and view Submitted Annual Salt Report';
+
+SELECT @PermissionID = [PERMISSION_ID]
+FROM [dbo].[HMR_PERMISSION]
+WHERE [NAME] = 'SALT' AND [DESCRIPTION] = 'Salt Reporting';
+
+-- Step 2: Delete from HMR_USER_ROLE using the captured RoleID
+DELETE FROM [dbo].[HMR_USER_ROLE]
+WHERE [ROLE_ID] = @RoleID;
+
+-- Step 3: Delete from HMR_ROLE_PERMISSION using the captured RoleID and PermissionID
DELETE FROM [dbo].[HMR_ROLE_PERMISSION]
-WHERE [PERMISSION_ID] IN (
- SELECT [PERMISSION_ID]
- FROM [dbo].[HMR_PERMISSION]
- WHERE [NAME] = 'SALT'
-);
-GO
+WHERE [ROLE_ID] = @RoleID AND [PERMISSION_ID] = @PermissionID;
-DELETE FROM [dbo].[HMR_PERMISSION]
-WHERE [NAME] = 'SALT';
-GO
+-- Step 4: Delete from HMR_ROLE
+DELETE FROM [dbo].[HMR_ROLE]
+WHERE [ROLE_ID] = @RoleID;
-IF OBJECT_ID('[dbo].[hmr_error_handling]', 'P') IS NOT NULL
-BEGIN
- DROP PROCEDURE [dbo].[hmr_error_handling];
-END;
+-- Step 5: Delete from HMR_PERMISSION
+DELETE FROM [dbo].[HMR_PERMISSION]
+WHERE [PERMISSION_ID] = @PermissionID;