Skip to content

Commit 1a3244e

Browse files
committed
feat: move admin email notif to post actions for encrypt
1 parent 4e09eef commit 1a3244e

File tree

4 files changed

+125
-97
lines changed

4 files changed

+125
-97
lines changed

src/app/modules/submission/encrypt-submission/encrypt-submission.controller.ts

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
} from '../../../../../shared/types'
1818
import {
1919
IAttachmentInfo,
20-
IEncryptedForm,
2120
IEncryptedSubmissionSchema,
2221
IPopulatedEncryptedForm,
2322
StripePaymentMetadataDto,
@@ -35,7 +34,6 @@ import getPaymentModel from '../../../models/payment.server.model'
3534
import { getEncryptPendingSubmissionModel } from '../../../models/pending_submission.server.model'
3635
import { getEncryptSubmissionModel } from '../../../models/submission.server.model'
3736
import * as CaptchaMiddleware from '../../../services/captcha/captcha.middleware'
38-
import MailService from '../../../services/mail/mail.service'
3937
import * as TurnstileMiddleware from '../../../services/turnstile/turnstile.middleware'
4038
import { Pipeline } from '../../../utils/pipeline-middleware'
4139
import { createReqMeta } from '../../../utils/request'
@@ -56,7 +54,6 @@ import { getOidcService } from '../../spcp/spcp.oidc.service'
5654
import { getPopulatedUserById } from '../../user/user.service'
5755
import * as VerifiedContentService from '../../verified-content/verified-content.service'
5856
import { MYINFO_PREFIX } from '../email-submission/email-submission.constants'
59-
import * as EmailSubmissionService from '../email-submission/email-submission.service'
6057
import { SubmissionEmailObj } from '../email-submission/email-submission.util'
6158
import * as EncryptSubmissionMiddleware from '../encrypt-submission/encrypt-submission.middleware'
6259
import ParsedResponsesObject from '../ParsedResponsesObject.class'
@@ -778,50 +775,7 @@ const _createSubmission = async ({
778775
})
779776

780777
const createdTime = submission.created || new Date()
781-
782-
const logMetaWithSubmission = {
783-
...logMeta,
784-
submissionId,
785-
responseMetadata,
786-
}
787-
788-
const emailData = new SubmissionEmailObj(
789-
emailFields,
790-
new Set(), // the MyInfo prefixes are already inserted in middleware
791-
form.authType,
792-
)
793-
794-
// Since we insert the [MyInfo] prefix in `encrypt-submission.middleware.ts`:L434
795-
// we want to remove it for the dataCollationData
796-
const dataCollationData = emailData.dataCollationData.map((item) => ({
797-
question: item.question.startsWith(MYINFO_PREFIX)
798-
? item.question.slice(MYINFO_PREFIX.length)
799-
: item.question,
800-
answer: item.answer,
801-
}))
802-
803778
const emailAttachments = [...(unencryptedAttachments ?? [])]
804-
// We don't await for email submission, as the submission gets saved for encrypt
805-
// submissions regardless, the email is more of a notification and shouldn't
806-
// stop the storage of the data in the db
807-
if (((form as IEncryptedForm)?.emails || []).length > 0) {
808-
logger.info({
809-
message: 'Sending admin notification mail',
810-
meta: logMetaWithSubmission,
811-
})
812-
813-
void MailService.sendSubmissionToAdmin({
814-
replyToEmails: EmailSubmissionService.extractEmailAnswers(emailFields),
815-
form,
816-
submission: {
817-
created: createdTime,
818-
id: submission.id,
819-
},
820-
attachments: emailAttachments,
821-
formData: emailData.formData,
822-
dataCollationData,
823-
})
824-
}
825779

826780
// TODO 6395 make responseMetadata mandatory
827781
if (responseMetadata) {
@@ -847,7 +801,7 @@ const _createSubmission = async ({
847801
submission,
848802
responses,
849803
growthbook: req.growthbook,
850-
emailData,
804+
emailFields,
851805
attachments: emailAttachments,
852806
respondentEmails,
853807
})

src/app/modules/submission/encrypt-submission/encrypt-submission.service.ts

Lines changed: 90 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { err, ok, okAsync, Result, ResultAsync } from 'neverthrow'
44
import Mail from 'nodemailer/lib/mailer'
55

66
import { AutoReplyMailData } from 'src/app/services/mail/mail.types'
7+
import MailService from '../../../services/mail/mail.service'
8+
import * as EmailSubmissionService from '../email-submission/email-submission.service'
79

810
import { featureFlags } from '../../../../../shared/constants'
911
import {
@@ -12,10 +14,9 @@ import {
1214
SubmissionType,
1315
} from '../../../../../shared/types'
1416
import {
15-
FieldResponse,
16-
IEncryptedSubmissionSchema,
17+
FieldResponse, IEncryptedSubmissionSchema,
1718
IPopulatedEncryptedForm,
18-
IPopulatedForm,
19+
IPopulatedForm
1920
} from '../../../../types'
2021
import { createLoggerWithLabel } from '../../../config/logger'
2122
import { getEncryptSubmissionModel } from '../../../models/submission.server.model'
@@ -41,6 +42,9 @@ import {
4142
import { sendEmailConfirmations } from '../submission.service'
4243
import { extractEmailConfirmationData } from '../submission.utils'
4344

45+
import { AutoreplyPdfGenerationError } from 'src/app/services/mail/mail.errors'
46+
import { MYINFO_PREFIX } from '../email-submission/email-submission.constants'
47+
import { ProcessedFieldResponse } from '../submission.types'
4448
import { CHARTS_MAX_SUBMISSION_RESULTS } from './encrypt-submission.constants'
4549
import { SaveEncryptSubmissionParams } from './encrypt-submission.types'
4650

@@ -98,10 +102,10 @@ export const assertFormIsSingleSubmissionDisabled = (
98102
return !form.isSingleSubmission
99103
? ok(form)
100104
: err(
101-
new UnsupportedSettingsError(
102-
'isSingleSubmission cannot be enabled for payment forms as it is not currently supported',
103-
),
104-
)
105+
new UnsupportedSettingsError(
106+
'isSingleSubmission cannot be enabled for payment forms as it is not currently supported',
107+
),
108+
)
105109
}
106110

107111
/**
@@ -131,6 +135,26 @@ export const createEncryptSubmissionWithoutSave = ({
131135
})
132136
}
133137

138+
const checkIfAdminPdfIsRequired = (): boolean => {
139+
return false
140+
}
141+
142+
const checkIfRespondentFormSummaryIsRequired = (): boolean => {
143+
return false
144+
}
145+
146+
const checkIfPdfGenerationIsRequired = (): boolean => {
147+
return checkIfAdminPdfIsRequired() || checkIfRespondentFormSummaryIsRequired()
148+
}
149+
150+
const generatePdfAttachmentIfRequired = (): ResultAsync<Mail.Attachment | undefined, AutoreplyPdfGenerationError> => {
151+
if (!checkIfPdfGenerationIsRequired()) {
152+
return okAsync(undefined)
153+
}
154+
155+
return okAsync(undefined)
156+
}
157+
134158
/**
135159
* Performs the post-submission actions for encrypt submissions. This is to be
136160
* called when the submission is completed
@@ -149,14 +173,14 @@ export const performEncryptPostSubmissionActions = ({
149173
submission,
150174
responses,
151175
growthbook,
152-
emailData,
176+
emailFields,
153177
attachments,
154178
respondentEmails,
155179
}: {
156180
submission: IEncryptedSubmissionSchema
157181
responses: FieldResponse[]
158182
growthbook?: GrowthBook
159-
emailData?: SubmissionEmailObj
183+
emailFields: ProcessedFieldResponse[]
160184
attachments?: Mail.Attachment[]
161185
respondentEmails?: string[]
162186
}): ResultAsync<
@@ -207,11 +231,11 @@ export const performEncryptPostSubmissionActions = ({
207231
.andThen((form) => {
208232
const respondentCopyEmailData: AutoReplyMailData[] = respondentEmails
209233
? respondentEmails?.map((val) => {
210-
return {
211-
email: val,
212-
includeFormSummary: true,
213-
}
214-
})
234+
return {
235+
email: val,
236+
includeFormSummary: true,
237+
}
238+
})
215239
: []
216240

217241
// TODO [PDF-LAMBDA-GENERATION]: Remove setting of Growthbook targetting once pdf generation rollout is complete
@@ -230,25 +254,60 @@ export const performEncryptPostSubmissionActions = ({
230254
},
231255
})
232256

233-
return sendEmailConfirmations({
234-
form,
235-
submission,
236-
attachments,
237-
responsesData: emailData?.autoReplyData,
238-
recipientData: [
239-
...extractEmailConfirmationData(responses, form.form_fields),
240-
...respondentCopyEmailData,
241-
],
242-
isUseLambdaOutput,
243-
}).mapErr((error) => {
244-
logger.error({
245-
message: 'Error while sending email confirmations',
246-
meta: {
247-
action: 'sendEmailAutoReplies',
257+
const emailData = new SubmissionEmailObj(
258+
emailFields,
259+
new Set(), // the MyInfo prefixes are already inserted in middleware
260+
form.authType,
261+
)
262+
263+
// Since we insert the [MyInfo] prefix in `encrypt-submission.middleware.ts`:L434
264+
// we want to remove it for the dataCollationData
265+
const dataCollationData = emailData.dataCollationData.map((item) => ({
266+
question: item.question.startsWith(MYINFO_PREFIX)
267+
? item.question.slice(MYINFO_PREFIX.length)
268+
: item.question,
269+
answer: item.answer,
270+
}))
271+
272+
const pdfAttachmentResult = generatePdfAttachmentIfRequired()
273+
274+
return pdfAttachmentResult.andThen((pdfAttachment) => {
275+
if (pdfAttachment) {
276+
attachments = [...(attachments ?? []), pdfAttachment]
277+
}
278+
279+
void MailService.sendSubmissionToAdmin({
280+
replyToEmails: EmailSubmissionService.extractEmailAnswers(emailFields),
281+
form,
282+
submission: {
283+
created: submission.created,
284+
id: submission.id,
248285
},
249-
error,
286+
attachments,
287+
formData: emailData.formData,
288+
dataCollationData,
289+
})
290+
291+
return sendEmailConfirmations({
292+
form,
293+
submission,
294+
attachments,
295+
responsesData: emailData?.autoReplyData,
296+
recipientData: [
297+
...extractEmailConfirmationData(responses, form.form_fields),
298+
...respondentCopyEmailData,
299+
],
300+
isUseLambdaOutput,
301+
}).mapErr((error) => {
302+
logger.error({
303+
message: 'Error while sending email confirmations',
304+
meta: {
305+
action: 'sendEmailAutoReplies',
306+
},
307+
error,
308+
})
309+
return error
250310
})
251-
return error
252311
})
253312
})
254313
)

src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -737,17 +737,17 @@ export const createMultiRespondentFormSubmission = ({
737737
})
738738
}
739739

740-
interface CheckHasRespondentCopyFormSummaryArgs {
740+
interface CheckIfRespondentFormSummaryIsRequiredArgs {
741741
responses: FieldResponsesV3
742742
formFields: FormFieldSchema[] | FormFieldDto[]
743743
currentStepActiveFields: string[]
744744
}
745745

746-
const checkHasRespondentCopyFormSummary = ({
746+
const checkIfRespondentFormSummaryIsRequired = ({
747747
responses,
748748
formFields,
749749
currentStepActiveFields,
750-
}: CheckHasRespondentCopyFormSummaryArgs): boolean => {
750+
}: CheckIfRespondentFormSummaryIsRequiredArgs): boolean => {
751751
const respondentCopyEmailDatas = extractRespondentCopyEmailDatas({
752752
responses,
753753
formFields,
@@ -756,7 +756,7 @@ const checkHasRespondentCopyFormSummary = ({
756756
return respondentCopyEmailDatas && respondentCopyEmailDatas.some(emailData => emailData.includeFormSummary)
757757
}
758758

759-
interface CheckIsWorkflowCompletionEmailRequiredArgs {
759+
interface CheckIsWorkflowCompletionEmailPdfRequiredArgs {
760760
currentStepNumber: number
761761
form: Pick<IPopulatedMultirespondentForm, '_id' | 'workflow' | 'emails' | 'stepsToNotify' | 'stepOneEmailNotificationFieldId'> & {
762762
form_fields: FormFieldSchema[] | FormFieldDto[]
@@ -766,13 +766,13 @@ interface CheckIsWorkflowCompletionEmailRequiredArgs {
766766
submissionId: string
767767
}
768768

769-
const checkIsWorkflowCompletionEmailRequired = ({
769+
const checkIsWorkflowCompletionEmailPdfRequired = ({
770770
currentStepNumber,
771771
form,
772772
responses,
773773
isRejected,
774774
submissionId,
775-
}: CheckIsWorkflowCompletionEmailRequiredArgs) => {
775+
}: CheckIsWorkflowCompletionEmailPdfRequiredArgs) => {
776776
const isWorkflowCompleted = checkIsWorkflowCompleted({
777777
currentStepNumber,
778778
form,
@@ -789,7 +789,7 @@ const checkIsWorkflowCompletionEmailRequired = ({
789789
return isWorkflowCompleted && hasEmailsToSendMrfOutcomeNotification.isOk() && hasEmailsToSendMrfOutcomeNotification.value.length > 0
790790
}
791791

792-
type CheckIsPdfGenerationRequiredArgs = Omit<CheckHasRespondentCopyFormSummaryArgs, 'formFields'> & CheckIsWorkflowCompletionEmailRequiredArgs
792+
type CheckIsPdfGenerationRequiredArgs = Omit<CheckIfRespondentFormSummaryIsRequiredArgs, 'formFields'> & CheckIsWorkflowCompletionEmailPdfRequiredArgs
793793

794794
const checkIsPdfGenerationRequired = ({
795795
responses,
@@ -799,8 +799,8 @@ const checkIsPdfGenerationRequired = ({
799799
isRejected,
800800
submissionId,
801801
}: CheckIsPdfGenerationRequiredArgs): boolean => {
802-
return checkHasRespondentCopyFormSummary({ responses, formFields: form.form_fields, currentStepActiveFields })
803-
|| checkIsWorkflowCompletionEmailRequired({
802+
return checkIfRespondentFormSummaryIsRequired({ responses, formFields: form.form_fields, currentStepActiveFields })
803+
|| checkIsWorkflowCompletionEmailPdfRequired({
804804
currentStepNumber,
805805
form,
806806
responses,
@@ -809,7 +809,7 @@ const checkIsPdfGenerationRequired = ({
809809
})
810810
}
811811

812-
const generatePdfIfRequired = ({
812+
const generatePdfAttachmentIfRequired = ({
813813
submission,
814814
form,
815815
responses,
@@ -882,7 +882,7 @@ export const performMultiRespondentPostSubmissionCreateActions = ({
882882
submissionId,
883883
}
884884

885-
const pdfResult = generatePdfIfRequired({
885+
const pdfResult = generatePdfAttachmentIfRequired({
886886
submission,
887887
form,
888888
responses,
@@ -1197,7 +1197,7 @@ export const performMultiRespondentPostSubmissionUpdateActions = ({
11971197
})
11981198
}
11991199

1200-
const pdfResult = generatePdfIfRequired({
1200+
const pdfResult = generatePdfAttachmentIfRequired({
12011201
submission,
12021202
form: snapshottedFormDef,
12031203
responses,

0 commit comments

Comments
 (0)