Skip to content

Commit

Permalink
Feature/admin 2192 (#973)
Browse files Browse the repository at this point in the history
* Add sendPreSelectionDayQuestionnaireNotifications
function

* tidy up

* fix notification type

* update submit

* update email notification
  • Loading branch information
HalcyonJAC authored Nov 29, 2023
1 parent 127ef27 commit 39ec040
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 1 deletion.
98 changes: 97 additions & 1 deletion functions/actions/applications/applications.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ const testApplicationsFileName = 'test_applications.json';
module.exports = (config, firebase, db, auth) => {
const { initialiseApplicationRecords } = require('../../actions/applicationRecords')(config, firebase, db, auth);
const { refreshApplicationCounts } = require('../../actions/exercises/refreshApplicationCounts')(firebase, db);
const { newNotificationApplicationSubmit, newNotificationApplicationReminder, newNotificationApplicationInWelsh, newNotificationCharacterCheckRequest, newNotificationCandidateFlagConfirmation } = require('../../shared/factories')(config);
const {
newNotificationApplicationSubmit,
newNotificationApplicationReminder,
newNotificationApplicationInWelsh,
newNotificationCharacterCheckRequest,
newNotificationCandidateFlagConfirmation,
newCandidateFormNotification,
} = require('../../shared/factories')(config);
const slack = require('../../shared/slack')(config);
const { updateCandidate } = require('../candidates/search')(firebase, db);
return {
Expand All @@ -17,6 +24,7 @@ module.exports = (config, firebase, db, auth) => {
sendApplicationReminders,
sendApplicationInWelsh,
sendCharacterCheckRequests,
sendCandidateFormNotifications,
createApplication,
createApplications,
loadTestApplications,
Expand Down Expand Up @@ -299,6 +307,94 @@ module.exports = (config, firebase, db, auth) => {
return result ? applications.length : false;
}

/**
* Send candidate form notification for each application
*
* @param {*} `params` is an object containing
* `type` (required) task type
* `notificationType` (required) request type (request, reminder, submit)
* `items` (required) IDs of applications
*/
async function sendCandidateFormNotifications(params) {
const {
type,
notificationType,
items: applicationIds,
exerciseMailbox,
exerciseManagerName,
dueDate,
} = params;

// get applications
const applicationRefs = applicationIds.map(id => db.collection('applications').doc(id));
const applications = await getAllDocuments(db, applicationRefs);

// create database commands
const commands = [];
for (let i = 0, len = applications.length; i < len; ++i) {
const application = applications[i];

// create notification
const notification = newCandidateFormNotification(firebase, application, notificationType, exerciseMailbox, exerciseManagerName, dueDate);
if (notification) {
commands.push({
command: 'set',
ref: db.collection('notifications').doc(),
data: notification,
});
}

// update application and applicationRecord
if (notificationType === 'request') {
const data = {
[`${type}.requestedAt`]: firebase.firestore.Timestamp.fromDate(new Date()),
[`${type}.status`]: 'requested',
};
commands.push(
{
command: 'update',
ref: application.ref,
data,
},
{
command: 'update',
ref: db.collection('applicationRecords').doc(application.id),
data,
}
);
} else if (notificationType === 'reminder') {
const data = {
[`${type}.reminderSentAt`]: firebase.firestore.Timestamp.fromDate(new Date()),
[`${type}.status`]: 'requested',
};
commands.push(
{
command: 'update',
ref: application.ref,
data,
},
{
command: 'update',
ref: db.collection('applicationRecords').doc(application.id),
data,
}
);
} else if (notificationType === 'submit') {
commands.push({
command: 'update',
ref: application.ref,
data: {
'emailLog.preSelectionDayQuestionnaireSubmitted': firebase.firestore.Timestamp.fromDate(new Date()),
},
});
}
}

// write to db
const result = await applyUpdates(db, commands);
return result ? applications.length : false;
}

/**
* load test applications JSON file from cloud storage
*/
Expand Down
32 changes: 32 additions & 0 deletions functions/callableFunctions/sendCandidateFormNotifications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const functions = require('firebase-functions');
const config = require('../shared/config.js');
const { firebase, db, auth } = require('../shared/admin.js');
const { checkArguments } = require('../shared/helpers.js');
const { sendCandidateFormNotifications } = require('../actions/applications/applications.js')(config, firebase, db, auth);
const { checkFunctionEnabled } = require('../shared/serviceSettings.js')(db);
const { PERMISSIONS, hasPermissions } = require('../shared/permissions.js');

module.exports = functions.region('europe-west2').https.onCall(async (data, context) => {
await checkFunctionEnabled();
if (!context.auth) {
throw new functions.https.HttpsError('failed-precondition', 'The function must be called while authenticated.');
}

hasPermissions(context.auth.token.rp, [
PERMISSIONS.applications.permissions.canReadApplications.value,
PERMISSIONS.applications.permissions.canUpdateApplications.value,
PERMISSIONS.notifications.permissions.canCreateNotifications.value,
]);

if (!checkArguments({
type: { required: true },
notificationType: { required: true },
items: { required: true },
exerciseMailbox: { required: true },
exerciseManagerName: { required: true },
dueDate: { required: true },
}, data)) {
throw new functions.https.HttpsError('invalid-argument', 'Please provide valid arguments');
}
return await sendCandidateFormNotifications(data);
});
1 change: 1 addition & 0 deletions functions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ exports.generateSignInWithEmailLink = require('./callableFunctions/generateSignI
exports.initialiseApplicationRecords = require('./callableFunctions/initialiseApplicationRecords');
exports.sendApplicationReminders = require('./callableFunctions/sendApplicationReminders');
exports.sendCharacterCheckRequests = require('./callableFunctions/sendCharacterCheckRequests');
exports.sendCandidateFormNotifications = require('./callableFunctions/sendCandidateFormNotifications');
exports.enableCharacterChecks = require('./callableFunctions/enableCharacterChecks');
exports.initialiseMissingApplicationRecords = require('./callableFunctions/initialiseMissingApplicationRecords');
exports.exportExerciseData = require('./callableFunctions/exportExerciseData');
Expand Down
42 changes: 42 additions & 0 deletions functions/shared/factories.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports = (CONSTANTS) => {
newNotificationLateApplicationResponse,
newUser,
newCandidateFormResponse,
newCandidateFormNotification,
};

function newNotificationExerciseApprovalSubmit(firebase, exerciseId, exercise, email) {
Expand Down Expand Up @@ -746,4 +747,45 @@ module.exports = (CONSTANTS) => {
progress: {},
};
}

function newCandidateFormNotification(firebase, application, type, exerciseMailbox, exerciseManagerName, dueDate) {
let templateId = '';
let templateName = '';

if (type === 'request') {
templateId = 'bba6cebb-b3b3-4ba3-818b-af7b9a011f77';
templateName = 'Candidate form consent form request';
} else if (type === 'reminder') {
templateId = '59522cc8-ede1-464c-8ab9-91b05f00af25';
templateName = 'Candidate form consent form reminder';
} else if (type === 'submit') {
templateId = '1492dd03-75b1-45e3-af19-875b7c1bdf11';
templateName = 'Candidate form consent form submit';
}

if (!templateId || !templateName) return null;

return {
email: application.personalDetails.email,
replyTo: exerciseMailbox,
template: {
name: templateName,
id: templateId,
},
personalisation: {
exerciseName: application.exerciseName,
dueDate,
urlRequired: `${CONSTANTS.APPLY_URL}/sign-in`,
applicantName: application.personalDetails.fullName,
selectionExerciseManager: exerciseManagerName,
exerciseMailbox,
},
reference: {
collection: 'applications',
id: application.id,
},
createdAt: firebase.firestore.Timestamp.fromDate(new Date()),
status: 'ready',
};
}
};

0 comments on commit 39ec040

Please sign in to comment.