Skip to content

Commit 75133db

Browse files
authored
feat: diamond email handler changes (#1617)
1 parent 41a2eac commit 75133db

2 files changed

Lines changed: 77 additions & 27 deletions

File tree

apps/backend/src/eventHandlers/email/DLS/proposalCoProposerInvitesUpdatedHandler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ export async function proposalCoProposerInvitesUpdatedHandler(
5959
template: emailTemplate.id.toString(),
6060
},
6161
substitution_data: {
62-
sender: inviter.preferredname + ' ' + inviter.lastname,
62+
sender:
63+
(inviter.preferredname || inviter.firstname) + ' ' + inviter.lastname,
6364
redeem_code: invite.code,
6465
uos_instance: process.env.BASE_URL,
6566
},

apps/backend/src/eventHandlers/email/DLS/proposalSubmittedHandler.ts

Lines changed: 75 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,39 @@ import { QuestionaryDataSource } from '../../../datasources/QuestionaryDataSourc
1010
import { UserDataSource } from '../../../datasources/UserDataSource';
1111
import { ApplicationEvent } from '../../../events/applicationEvents';
1212
import { Event } from '../../../events/event.enum';
13+
import { getTopicActiveAnswers } from '../../../models/ProposalModelFunctions';
14+
import { Answer, QuestionaryStep } from '../../../models/Questionary';
15+
import { DataType } from '../../../models/Template';
1316
import { MailService } from '../../MailService/MailService';
1417
import { EmailTemplateId } from '../emailTemplateId';
1518

19+
type InstrumentPickerAnswerValue = {
20+
instrumentId: number | string;
21+
timeRequested?: number | string | null;
22+
};
23+
24+
const getInstrumentPickerAnswers = (
25+
questionarySteps: QuestionaryStep[]
26+
): Answer[] =>
27+
questionarySteps
28+
.flatMap((step) => getTopicActiveAnswers(questionarySteps, step.topic.id))
29+
.filter(
30+
(answer) => answer.question.dataType === DataType.INSTRUMENT_PICKER
31+
);
32+
33+
const getInstrumentPickerAnswerValues = (
34+
value: unknown
35+
): InstrumentPickerAnswerValue[] => {
36+
const values = Array.isArray(value) ? value : value ? [value] : [];
37+
38+
return values.filter(
39+
(instrumentAnswer): instrumentAnswer is InstrumentPickerAnswerValue =>
40+
typeof instrumentAnswer === 'object' &&
41+
instrumentAnswer !== null &&
42+
'instrumentId' in instrumentAnswer
43+
);
44+
};
45+
1646
export async function proposalSubmittedHandler(event: ApplicationEvent) {
1747
if (event.type != Event.PROPOSAL_SUBMITTED) return;
1848

@@ -54,28 +84,49 @@ export async function proposalSubmittedHandler(event: ApplicationEvent) {
5484
event.proposal.callId
5585
);
5686

57-
const instruments = await instrumentSource.getInstrumentsByProposalPk(
58-
event.proposal.primaryKey
87+
const questionarySteps = await questionaryDataSource.getQuestionarySteps(
88+
event.proposal.questionaryId
5989
);
6090

61-
// Postgres implementation doesn't match interface - impliementation wants questionaryId, not proposalId
62-
const answer = await questionaryDataSource.getAnswer(
63-
event.proposal.questionaryId,
64-
'instrument_picker'
91+
const instrumentPickerAnswers = getInstrumentPickerAnswers(questionarySteps);
92+
const instrumentPickerAnswerValues = instrumentPickerAnswers.flatMap(
93+
(answer) => getInstrumentPickerAnswerValues(answer.value)
94+
);
95+
const instrumentIds = Array.from(
96+
new Set(
97+
instrumentPickerAnswerValues
98+
.map((instrumentAnswer) => Number(instrumentAnswer.instrumentId))
99+
.filter((instrumentId) => Number.isFinite(instrumentId))
100+
)
65101
);
66102

67-
(
68-
answer?.answer as {
69-
value: { instrumentId: number; timeRequested: number }[];
70-
}
71-
)?.value.forEach((instrumentAnswer: any) => {
72-
const instrument = instruments.find(
73-
(inst) => inst.id === Number(instrumentAnswer.instrumentId)
74-
);
75-
if (instrument) {
76-
instrument.managementTimeAllocation = instrumentAnswer.timeRequested || 0;
77-
}
78-
});
103+
const instruments = await instrumentSource.getInstrumentsByIds(instrumentIds);
104+
const requested = instrumentPickerAnswerValues
105+
.map((instrumentAnswer) => {
106+
const requestedTime = Number(instrumentAnswer.timeRequested ?? 0);
107+
const formattedRequestedTime = Number.isFinite(requestedTime)
108+
? requestedTime
109+
: 0;
110+
const instrument = instruments.find(
111+
(inst) => inst.id === Number(instrumentAnswer.instrumentId)
112+
);
113+
if (!instrument) {
114+
return null;
115+
}
116+
117+
const timeUnit = `${call.allocationTimeUnit}${
118+
formattedRequestedTime > 1 || formattedRequestedTime === 0 ? 's' : ''
119+
}`;
120+
121+
return [
122+
`${instrument.name}:`,
123+
instrument.description,
124+
formattedRequestedTime,
125+
timeUnit,
126+
].join(' ');
127+
})
128+
.filter((request): request is string => request !== null)
129+
.join(', ');
79130

80131
const shortDateFormat = new Intl.DateTimeFormat('en-GB', {
81132
month: 'short',
@@ -115,19 +166,17 @@ export async function proposalSubmittedHandler(event: ApplicationEvent) {
115166
submittedOn: event.proposal.submittedDate!.toLocaleString(),
116167
accessRoute: workflow?.name || 'N/A',
117168
principalInvestigator:
118-
principalInvestigator.preferredname +
169+
(principalInvestigator.preferredname ||
170+
principalInvestigator.firstname) +
119171
' ' +
120172
principalInvestigator.lastname,
121173
establishment: principalInvestigator.institution,
122174
alternativeContacts: '',
123175
coinvestigators: participants.map(
124-
(partipant) => `${partipant.preferredname} ${partipant.lastname} `
176+
(partipant) =>
177+
`${partipant.preferredname || partipant.firstname} ${partipant.lastname} `
125178
),
126-
requested: instruments
127-
.map((instrument) => {
128-
return `${instrument.name}: ${instrument.description} ${instrument.managementTimeAllocation} ${call.allocationTimeUnit}${instrument.managementTimeAllocation > 1 ? 's' : ''}`;
129-
})
130-
.join(', '),
179+
requested,
131180
},
132181
allocationPeriod: allocationPeriod,
133182
deadline: longDateFormat.format(call.endCall),
@@ -153,7 +202,7 @@ export async function proposalSubmittedHandler(event: ApplicationEvent) {
153202
...options,
154203
substitution_data: {
155204
...(options.substitution_data as any),
156-
name: participant.preferredname,
205+
name: participant.preferredname || participant.firstname,
157206
},
158207
recipients: [
159208
{

0 commit comments

Comments
 (0)