Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ workflows:
context : org-global
filters:
branches:
only: ['develop', 'migration-setup', 'pm-1613']
only: ['develop', 'migration-setup', 'pm-1611']
- deployProd:
context : org-global
filters:
Expand Down
2 changes: 2 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ export const TEMPLATE_IDS = {
INFORM_PM_COPILOT_APPLICATION_ACCEPTED: 'd-b35d073e302b4279a1bd208fcfe96f58',
COPILOT_ALREADY_PART_OF_PROJECT: 'd-003d41cdc9de4bbc9e14538e8f2e0585',
COPILOT_APPLICATION_ACCEPTED: 'd-eef5e7568c644940b250e76d026ced5b',
COPILOT_OPPORTUNITY_COMPLETED: 'd-dc448919d11b4e7d8b4ba351c4b67b8b',
COPILOT_OPPORTUNITY_CANCELED: 'd-2a67ba71e82f4d70891fe6989c3522a3'
}
export const REGEX = {
URL: /^(http(s?):\/\/)?(www\.)?[a-zA-Z0-9\.\-\_]+(\.[a-zA-Z]{2,15})+(\:[0-9]{2,5})?(\/[a-zA-Z0-9\_\-\s\.\/\?\%\#\&\=;]*)?$/, // eslint-disable-line
Expand Down
38 changes: 38 additions & 0 deletions src/routes/copilotOpportunity/assign.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,41 @@ module.exports = [
return next(err);
}

const sendEmailToAllApplicants = async (opportunity, copilotRequest, applicationId) => {
const allApplications = await models.Sequelize.CopilotApplication.findAll({
where: {
opportunityId: opportunity.id,
id: {
[Op.notIn]: [applicationId],
}
}
});

const userIds = allApplications.map(item => item.userId);

const users = await util.getMemberDetailsByUserIds(userIds, req.log, req.id);

users.forEach(async (user) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a Promise.all to handle asynchronous operations in the forEach loop. This will ensure that all emails are sent before proceeding, and can help catch any errors in the email sending process.

req.log.debug(`Sending email notification to copilots who are not accepted`);
const emailEventType = CONNECT_NOTIFICATION_EVENT.EXTERNAL_ACTION_EMAIL;
const copilotPortalUrl = config.get('copilotPortalUrl');
const requestData = copilotRequest.data;
createEvent(emailEventType, {
data: {
opportunity_details_url: `${copilotPortalUrl}/opportunity`,
opportunity_title: requestData.opportunityTitle,
user_name: user ? user.handle : "",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user_name field is being set to an empty string if user is falsy. Consider handling cases where user might be undefined or null more explicitly to avoid sending incomplete data.

},
sendgrid_template_id: TEMPLATE_IDS.COPILOT_OPPORTUNITY_COMPLETED,
recipients: [user.email],
version: 'v3',
}, req.log);

req.log.debug(`Email sent to copilots who are not accepted`);
});

};

return models.sequelize.transaction(async (t) => {
const opportunity = await models.CopilotOpportunity.findOne({
where: { id: copilotOpportunityId },
Expand Down Expand Up @@ -134,6 +169,9 @@ module.exports = [
}, req.log);

req.log.debug(`Email sent`);

// Send email to all applicants about opportunity completion
await sendEmailToAllApplicants(opportunity, copilotRequest, application.id);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sendEmailToAllApplicants function call has been modified to remove the req parameter. Ensure that this change is intentional and that the function sendEmailToAllApplicants does not require the req parameter for its execution. If req is needed for logging or other purposes, consider revising the function signature or implementation.

};

const existingMember = activeMembers.find(item => item.userId === userId);
Expand Down
31 changes: 30 additions & 1 deletion src/routes/copilotOpportunity/delete.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import _ from 'lodash';
import { Op } from 'sequelize';
import config from 'config';

import models from '../../models';
import util from '../../util';
import { COPILOT_APPLICATION_STATUS, COPILOT_OPPORTUNITY_STATUS, COPILOT_REQUEST_STATUS, EVENT, INVITE_STATUS, RESOURCES } from '../../constants';
import { CONNECT_NOTIFICATION_EVENT, COPILOT_APPLICATION_STATUS, COPILOT_OPPORTUNITY_STATUS, COPILOT_REQUEST_STATUS, EVENT, INVITE_STATUS, RESOURCES, TEMPLATE_IDS } from '../../constants';
import { createEvent } from '../../services/busApi';
import { PERMISSION } from '../../permissions/constants';


Expand All @@ -20,6 +22,31 @@ module.exports = [
// default values
const opportunityId = _.parseInt(req.params.id);

const sendEmailToAllApplicants = async (copilotRequest, applications) => {
const userIds = applications.map(item => item.userId);
const users = await util.getMemberDetailsByUserIds(userIds, req.log, req.id);

users.forEach(async (user) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using Promise.all to handle asynchronous operations within the forEach loop. This ensures that all emails are sent before proceeding, and can help avoid potential issues with unhandled promises.

req.log.debug(`Sending email notification to copilots who applied`);
const emailEventType = CONNECT_NOTIFICATION_EVENT.EXTERNAL_ACTION_EMAIL;
const copilotPortalUrl = config.get('copilotPortalUrl');
const requestData = copilotRequest.data;
createEvent(emailEventType, {
data: {
opportunity_details_url: `${copilotPortalUrl}/opportunity`,
opportunity_title: requestData.opportunityTitle,
user_name: user ? user.handle : "",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a default value or handling the case where user.handle might be null or undefined to prevent potential issues with the email content.

},
sendgrid_template_id: TEMPLATE_IDS.COPILOT_OPPORTUNITY_CANCELED,
recipients: [user.email],
version: 'v3',
}, req.log);

req.log.debug(`Email sent to copilots who applied`);
});

};

return models.sequelize.transaction(async (transaction) => {
req.log.debug('Canceling Copilot opportunity transaction', opportunityId);
const opportunity = await models.CopilotOpportunity.findOne({
Expand Down Expand Up @@ -93,6 +120,8 @@ module.exports = [
invite.toJSON());
}

await sendEmailToAllApplicants(copilotRequest, applications)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sendEmailToAllApplicants function call has been modified to remove the req parameter. Ensure that this change does not affect the function's behavior or cause any issues, as the req parameter might have been used within the function for accessing request-specific data.


res.status(200).send({ id: opportunity.id });
})

Expand Down