Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: notify analyst when coverage kmz uploaded #3325

Merged
9 changes: 9 additions & 0 deletions app/backend/lib/emails/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import handleEmailNotification from './handleEmailNotification';
import agreementSignedStatusChangeDataTeam from './templates/agreementSignedStatusChangeDataTeam';
import assessmentAssigneeChange from './templates/assessmentAssigneeChange';
import householdCountUpdate from './templates/householdCountUpdate';
import rfiCoverageMapKmzUploaded from './templates/rfiCoverageMapKmzUploaded';

const email = Router();

Expand Down Expand Up @@ -51,5 +52,13 @@ email.post('/api/email/householdCountUpdate', limiter, (req, res) => {
const { params } = req.body;
return handleEmailNotification(req, res, householdCountUpdate, params);
});
email.post(
'/api/email/notifyRfiCoverageMapKmzUploaded',
limiter,
(req, res) => {
const params = req.body;
return handleEmailNotification(req, res, rfiCoverageMapKmzUploaded, params);
}
);

export default email;
31 changes: 31 additions & 0 deletions app/backend/lib/emails/templates/rfiCoverageMapKmzUploaded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
EmailTemplate,
EmailTemplateProvider,
} from '../handleEmailNotification';

const rfiCoverageMapKmzUploaded: EmailTemplateProvider = (
applicationId: string,
url: string,
initiator: any,
params: any
): EmailTemplate => {
const { ccbcNumber, rfiFormData, rfiNumber, changes, organizationName } =
params;
return {
emailTo: [77, 34, 72], // Temporary IDs to handle email recipients
emailCC: [],
tag: 'rfi-coverage-map-kmz-uploaded',
subject: `Notification - A KMZ was uploaded to ${ccbcNumber}`,
body: `
<h1>KMZ file uploaded for RFI ${rfiNumber}</h1>
<p>${organizationName || initiator.givenName} has uploaded the following KMZ(s):</p>
<ul>
${changes.map((file: any) => `<li>${file.name} ${file?.fileDate ? `received on ${file?.fileDate}` : `uploaded on ${file.uploadedAt}`}</li>`).join('')}
</ul>
<p>This <a href='${url}/analyst/application/${applicationId}/rfi'>RFI</a> closes/closed on ${rfiFormData?.rfiDueBy}<p>
<p>To unsubscribe from this notification please forward this email with your request to <a href="mailto:[email protected]">[email protected]<a/></p>
`,
};
};

export default rfiCoverageMapKmzUploaded;
21 changes: 16 additions & 5 deletions app/components/Analyst/RFI/RFIAnalystUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { rfiAnalystUiSchema } from 'formSchema/uiSchema/analyst/rfiUiSchema';
import { useRouter } from 'next/router';
import { useUpdateWithTrackingRfiMutation } from 'schema/mutations/application/updateWithTrackingRfiMutation';
import styled from 'styled-components';

import { useCreateNewFormDataMutation } from 'schema/mutations/application/createNewFormData';
import useHHCountUpdateEmail from 'lib/helpers/useHHCountUpdateEmail';
import useRfiCoverageMapKmzUploadedEmail from 'lib/helpers/useRfiCoverageMapKmzUploadedEmail';

const Flex = styled('header')`
display: flex;
Expand Down Expand Up @@ -61,6 +63,8 @@ const RfiAnalystUpload = ({ query }) => {
const [excelImportFields, setExcelImportFields] = useState([]);
const router = useRouter();
const { notifyHHCountUpdate } = useHHCountUpdateEmail();
const { notifyRfiCoverageMapKmzUploaded } =
useRfiCoverageMapKmzUploadedEmail();

useEffect(() => {
if (templateData?.templateNumber === 1) {
Expand Down Expand Up @@ -125,14 +129,21 @@ const RfiAnalystUpload = ({ query }) => {
}
);
}
router.push(
`/analyst/application/${router.query.applicationId}/rfi`
);
},
});
} else {
router.push(`/analyst/application/${router.query.applicationId}/rfi`);
}
if (
rfiFormData?.rfiAdditionalFiles?.geographicCoverageMap?.length > 0
) {
notifyRfiCoverageMapKmzUploaded(
rfiDataByRowId,
rfiFormData,
applicationId,
ccbcNumber,
rfiNumber
);
}
router.push(`/analyst/application/${router.query.applicationId}/rfi`);
},
onError: (err) => {
// eslint-disable-next-line no-console
Expand Down
53 changes: 53 additions & 0 deletions app/lib/helpers/useRfiCoverageMapKmzUploadedEmail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as Sentry from '@sentry/nextjs';

const useRfiCoverageMapKmzUploadedEmail = () => {
const notifyRfiCoverageMapKmzUploaded = async (
rfiDataByRowId,
rfiFormData,
applicationId,
ccbcNumber,
rfiNumber,
organizationName = null
) => {
const originalGeoCoverageMap =
rfiDataByRowId?.jsonData?.rfiAdditionalFiles?.geographicCoverageMap || [];
const newGeoCoverageMap =
rfiFormData?.rfiAdditionalFiles?.geographicCoverageMap || [];
const originalSet = new Set(originalGeoCoverageMap.map((k) => k.uuid));
const changes = newGeoCoverageMap.filter((k) => !originalSet.has(k.uuid));
// only send new emails if the actual coverage map has changed
// as a save can occur without modification or only modification to other fields
if (changes.length > 0) {
const commonEmailObject = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
applicationId,
host: window.location.origin,
ccbcNumber,
rfiFormData,
rfiNumber,
changes,
organizationName,
}),
};
fetch(
'/api/email/notifyRfiCoverageMapKmzUploaded',
commonEmailObject
).then((r) => {
if (!r.ok) {
Sentry.captureException({
name: 'Email sending Agreement Signed Data Team failed',
message: r,
});
}
return r.json();
});
}
};
return { notifyRfiCoverageMapKmzUploaded };
};

export default useRfiCoverageMapKmzUploadedEmail;
13 changes: 13 additions & 0 deletions app/pages/applicantportal/form/[id]/rfi/[applicantRfiId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import styled from 'styled-components';
import { useEffect, useState } from 'react';
import { useCreateNewFormDataMutation } from 'schema/mutations/application/createNewFormData';
import useHHCountUpdateEmail from 'lib/helpers/useHHCountUpdateEmail';
import useRfiCoverageMapKmzUploadedEmail from 'lib/helpers/useRfiCoverageMapKmzUploadedEmail';

const Flex = styled('header')`
display: flex;
Expand Down Expand Up @@ -73,6 +74,8 @@ const ApplicantRfiPage = ({
const [templateData, setTemplateData] = useState(null);
const [formData, setFormData] = useState(rfiDataByRowId.jsonData);
const { notifyHHCountUpdate } = useHHCountUpdateEmail();
const { notifyRfiCoverageMapKmzUploaded } =
useRfiCoverageMapKmzUploadedEmail();

useEffect(() => {
if (templateData?.templateNumber === 1) {
Expand Down Expand Up @@ -109,6 +112,16 @@ const ApplicantRfiPage = ({
},
},
onCompleted: () => {
if (e.formData?.rfiAdditionalFiles?.geographicCoverageMap?.length > 0) {
notifyRfiCoverageMapKmzUploaded(
rfiDataByRowId,
e.formData,
applicationId,
ccbcNumber,
rfiNumber,
applicationByRowId.organizationName
);
}
if (!templateData) {
router.push(`/applicantportal/dashboard`);
}
Expand Down
68 changes: 68 additions & 0 deletions app/tests/backend/lib/emails/email.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import agreementSignedStatusChange from 'backend/lib/emails/templates/agreementS
import agreementSignedStatusChangeDataTeam from 'backend/lib/emails/templates/agreementSignedStatusChangeDataTeam';
import assessmentAssigneeChange from 'backend/lib/emails/templates/assessmentAssigneeChange';
import householdCountUpdate from 'backend/lib/emails/templates/householdCountUpdate';
import rfiCoverageMapKmzUploaded from 'backend/lib/emails/templates/rfiCoverageMapKmzUploaded';

jest.mock('backend/lib/emails/handleEmailNotification');

Expand Down Expand Up @@ -107,4 +108,71 @@ describe('Email API Endpoints', () => {
{ organizationName: 'test' }
);
});

it('calls handleEmailNotification with correct parameters once rfiCoverageMapKmzUploaded called', async () => {
const reqBody = {
applicationId: '1',
params: {
applicationId: '1',
host: 'http://mock_host.ca',
ccbcNumber: 'CCBC-010040',
rfiFormData: {
rfiType: ['Technical'],
rfiAdditionalFiles: {
geographicCoverageMap: {},
geographicCoverageMapRfi: true,
},
rfiDueBy: '2024-06-26',
},
rfiNumber: 'CCBC-010040-8',
changes: [
{
id: 1937,
uuid: 'e723c93c-e656-45c9-9a5c-39ab8d4ab6e5',
name: '1.kmz',
size: 0,
type: '',
uploadedAt: '2024-05-31T14:05:03.509-07:00',
},
],
organizationName: 'test',
},
};
await request(app)
.post('/api/email/notifyRfiCoverageMapKmzUploaded')
.send(reqBody);
expect(handleEmailNotification).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
rfiCoverageMapKmzUploaded,
{
applicationId: '1',
params: {
applicationId: '1',
host: 'http://mock_host.ca',
ccbcNumber: 'CCBC-010040',
rfiFormData: {
rfiType: ['Technical'],
rfiAdditionalFiles: {
geographicCoverageMap: {},
geographicCoverageMapRfi: true,
},
rfiDueBy: '2024-06-26',
},
rfiNumber: 'CCBC-010040-8',
changes: [
{
id: 1937,
uuid: 'e723c93c-e656-45c9-9a5c-39ab8d4ab6e5',
name: '1.kmz',
size: 0,
type: '',
uploadedAt: '2024-05-31T14:05:03.509-07:00',
},
],
organizationName: 'test',
},
}
);
});
});
Loading
Loading