Skip to content

Commit

Permalink
Update email automation (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
ansonjwhe authored Aug 28, 2024
1 parent a5c0d8c commit 580c48d
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 71 deletions.
134 changes: 68 additions & 66 deletions backend/emails/emails.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,25 @@
const { EMAIL_RECIPIENTS } = require('../models/constants')
const { EMAIL_RECIPIENTS, ADMIN_GROUP_EMAIL } = require('../models/constants')
const { sendEmail } = require('../service/sendEmail')
const { getUserByUID } = require('../service/users.service')

const FINANCE_GROUP_EMAIL = '[email protected]'
const DivisionEmails = {
software: '[email protected]',
mechanical: '[email protected]',
business: '[email protected]',
electrical: '[email protected]',
}

const currencyFormatter = new Intl.NumberFormat('en-CA', {
style: 'currency',
currency: 'CAD',
})

const getEmailToSection = async (reporter_id, recipients) => {
const emailToSet = new Set([FINANCE_GROUP_EMAIL])
const emailToSet = new Set([ADMIN_GROUP_EMAIL])

if (recipients.includes(EMAIL_RECIPIENTS.admin)) {
// TODO: use ADMIN_IDENTIFIERS (rename to ADMIN_EMAILS) after migrating to new onboarding data
emailToSet.add(ADMIN_GROUP_EMAIL)
}

if (recipients.includes(EMAIL_RECIPIENTS.coordinator)) {
// TODO: determine which is the correct coordinator email
// emailToSet.add('[email protected]')
// emailToSet.add('[email protected]')
}

if (recipients.includes(EMAIL_RECIPIENTS.director)) {
// TODO: get director emails
}

if (recipients.includes(EMAIL_RECIPIENTS.faculty_advisor)) {
// emailToSet.add('[email protected]')
}

if (recipients.includes(EMAIL_RECIPIENTS.finance)) {
// emailToSet.add(process.env.WATO_FINANCE_FINANCE_EMAIL)
// TODO: emailToSet.add('[email protected]')
}

if (recipients.includes(EMAIL_RECIPIENTS.reporter)) {
Expand All @@ -47,10 +29,6 @@ const getEmailToSection = async (reporter_id, recipients) => {
}
}

if (recipients.includes(EMAIL_RECIPIENTS.team_captain)) {
// TODO: get team captain emails
}

return [...emailToSet].map((Email) => ({ Email }))
}

Expand Down Expand Up @@ -129,18 +107,19 @@ const getTicketLinkHTML = (ticketPath) => `
</p>
`

const sendEmailPPRCreatedToApprovers = async (ppr) => {
const Subject = `[Seeking Approval] ${ppr.codename}`
// ******************** UPR EMAILS ********************

const sendEmailUPRCreatedToApprovers = async (upr) => {
const Subject = `[Seeking Approval] ${upr.codename}`
const HTMLPart =
getMainMessageHTML(
'A new Personal Purchase Request needs your approval!'
'A new UW Finance Purchase Request needs your approval!'
) +
(await getPPRTicketInfoHTML(ppr)) +
getTicketLinkHTML(ppr.path)
const To = await getEmailToSection(ppr.reporter_id, [
(await getUPRTicketInfoHTML(upr)) +
getTicketLinkHTML(upr.path)
const To = await getEmailToSection(upr.reporter_id, [
EMAIL_RECIPIENTS.faculty_advisor,
EMAIL_RECIPIENTS.team_captain,
EMAIL_RECIPIENTS.director,
EMAIL_RECIPIENTS.admin,
])

await sendEmail({
Expand All @@ -150,18 +129,17 @@ const sendEmailPPRCreatedToApprovers = async (ppr) => {
})
}

const sendEmailUPRCreatedToApprovers = async (upr) => {
const Subject = `[Seeking Approval] ${upr.codename}`
const sendEmailUPRApprovedToCoordinator = async (upr) => {
const Subject = `[Ready to Buy] ${upr.codename}`
const HTMLPart =
getMainMessageHTML(
'A new UW Finance Purchase Request needs your approval!'
`A new UW Finance Purchase Request has been approved! Please purchase the approved item(s).<br>
After purchase, update the purchase order number and requisition number at the ticket link below.`
) +
(await getUPRTicketInfoHTML(upr)) +
getTicketLinkHTML(upr.path)
const To = await getEmailToSection(upr.reporter_id, [
EMAIL_RECIPIENTS.faculty_advisor,
EMAIL_RECIPIENTS.team_captain,
EMAIL_RECIPIENTS.director,
EMAIL_RECIPIENTS.coordinator,
])

await sendEmail({
Expand Down Expand Up @@ -209,7 +187,7 @@ const sendEmailUPRPurchasedToCoordinator = async (upr) => {
})
}

const sendEmailUPRReadyForPickupToCoordinator = async (upr) => {
const sendEmailUPRReadyForPickupToReporter = async (upr) => {
const Subject = `[Ready for pickup] ${upr.codename}`
const HTMLPart =
getMainMessageHTML(
Expand All @@ -220,25 +198,48 @@ const sendEmailUPRReadyForPickupToCoordinator = async (upr) => {
const To = await getEmailToSection(upr.reporter_id, [
EMAIL_RECIPIENTS.reporter,
])
const Cc = await getEmailToSection(upr.reporter_id, [
EMAIL_RECIPIENTS.coordinator, // cc'd for convenience if reporter needs to contact coordinator
])

await sendEmail({
Subject,
HTMLPart,
To,
Cc,
})
}

const sendEmailPPRApprovedToReporter = async (ppr) => {
const Subject = `[Ready to Buy] ${ppr.codename}`
const sendEmailUPRPickedUpToAdmin = async (upr) => {
const Subject = `[Picked up] ${upr.codename}`
const HTMLPart =
getMainMessageHTML(`${upr.codename} has been picked up!`) +
(await getUPRTicketInfoHTML(upr)) +
getTicketLinkHTML(upr.path)
const To = await getEmailToSection(upr.reporter_id, [
EMAIL_RECIPIENTS.admin,
])

await sendEmail({
Subject,
HTMLPart,
To,
})
}

// ******************** PPR EMAILS ********************

const sendEmailPPRCreatedToApprovers = async (ppr) => {
const Subject = `[Seeking Approval] ${ppr.codename}`
const HTMLPart =
getMainMessageHTML(
`Your Personal Purchase Request has been approved! Please purchase the approved item(s).<br>
Upload your proof of purchase at the ticket link below to request reimbursement.`
'A new Personal Purchase Request needs your approval!'
) +
(await getPPRTicketInfoHTML(ppr)) +
getTicketLinkHTML(ppr.path)
const To = await getEmailToSection(ppr.reporter_id, [
EMAIL_RECIPIENTS.reporter,
EMAIL_RECIPIENTS.faculty_advisor,
EMAIL_RECIPIENTS.admin,
])

await sendEmail({
Expand All @@ -248,17 +249,17 @@ const sendEmailPPRApprovedToReporter = async (ppr) => {
})
}

const sendEmailUPRApprovedToCoordinator = async (upr) => {
const Subject = `[Ready to Buy] ${upr.codename}`
const sendEmailPPRApprovedToReporter = async (ppr) => {
const Subject = `[Ready to Buy] ${ppr.codename}`
const HTMLPart =
getMainMessageHTML(
`A new UW Finance Purchase Request has been approved! Please purchase the approved item(s).<br>
After purchase, update the purchase order number and requisition number at the ticket link below.`
`Your Personal Purchase Request has been approved! Please purchase the approved item(s).<br>
Upload your proof of purchase at the ticket link below to request reimbursement.`
) +
(await getUPRTicketInfoHTML(upr)) +
getTicketLinkHTML(upr.path)
const To = await getEmailToSection(upr.reporter_id, [
EMAIL_RECIPIENTS.coordinator,
(await getPPRTicketInfoHTML(ppr)) +
getTicketLinkHTML(ppr.path)
const To = await getEmailToSection(ppr.reporter_id, [
EMAIL_RECIPIENTS.reporter,
])

await sendEmail({
Expand All @@ -277,13 +278,16 @@ const sendEmailPPRPurchasedAndReceiptsSubmittedToCoordinator = async (ppr) => {
(await getPPRTicketInfoHTML(ppr)) +
getTicketLinkHTML(ppr.path)
const To = await getEmailToSection(ppr.reporter_id, [
EMAIL_RECIPIENTS.finance,
EMAIL_RECIPIENTS.coordinator,
])
const Cc = await getEmailToSection(ppr.reporter_id, [
EMAIL_RECIPIENTS.reporter, // cc'd for convenience if coordinator needs to contact reporter
])
await sendEmail({
Subject,
HTMLPart,
To,
Cc,
})
}

Expand All @@ -296,8 +300,7 @@ const sendEmailPPRReimbursedToReporter = async (ppr) => {
(await getPPRTicketInfoHTML(ppr)) +
getTicketLinkHTML(ppr.path)
const To = await getEmailToSection(ppr.reporter_id, [
EMAIL_RECIPIENTS.finance,
EMAIL_RECIPIENTS.coordinator,
EMAIL_RECIPIENTS.reporter,
])
await sendEmail({
Subject,
Expand All @@ -306,6 +309,8 @@ const sendEmailPPRReimbursedToReporter = async (ppr) => {
})
}

// ******************** SF EMAILS ********************

const sendEmailSFReimbursementRequestToCoordinator = async (sf) => {
const Subject = `[Action Needed] Submit Reimbursement Request ${sf.codename}`
const HTMLPart =
Expand Down Expand Up @@ -342,17 +347,13 @@ const sendEmailSFConfirmReimbursementSubmitToCoordinator = async (sf) => {
})
}

const sendEmailSFReimbursementReceivedToTeam = async (sf) => {
const sendEmailSFReimbursementReceivedToAdmin = async (sf) => {
const Subject = `[Reimbursed] ${sf.codename}`
const HTMLPart =
getMainMessageHTML(`${sf.codename} has been reimbursed!`) +
(await getSFTicketInfoHTML(sf)) +
getTicketLinkHTML(sf.path)
const To = await getEmailToSection(sf.reporter_id, [
EMAIL_RECIPIENTS.finance,
EMAIL_RECIPIENTS.coordinator,
EMAIL_RECIPIENTS.team_captain,
])
const To = await getEmailToSection(sf.reporter_id, [EMAIL_RECIPIENTS.admin])
await sendEmail({
Subject,
HTMLPart,
Expand All @@ -365,12 +366,13 @@ module.exports = {
sendEmailUPRApprovedToCoordinator,
sendEmailUPRPurchasedToReporter,
sendEmailUPRPurchasedToCoordinator,
sendEmailUPRReadyForPickupToCoordinator,
sendEmailPPRApprovedToReporter,
sendEmailUPRReadyForPickupToReporter,
sendEmailUPRPickedUpToAdmin,
sendEmailPPRCreatedToApprovers,
sendEmailPPRApprovedToReporter,
sendEmailPPRPurchasedAndReceiptsSubmittedToCoordinator,
sendEmailPPRReimbursedToReporter,
sendEmailSFReimbursementRequestToCoordinator,
sendEmailSFConfirmReimbursementSubmitToCoordinator,
sendEmailSFReimbursementReceivedToTeam,
sendEmailSFReimbursementReceivedToAdmin,
}
2 changes: 2 additions & 0 deletions backend/models/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const TICKET_ENDPOINTS = Object.freeze({
})

const ADMIN_IDENTIFIERS = ['drayside', 'v2zheng', 'jw4he', 'william.li']
const ADMIN_GROUP_EMAIL = '[email protected]'

module.exports = {
ENDOWMENT_FUNDS,
Expand All @@ -68,4 +69,5 @@ module.exports = {
AUTH_ROLES,
EMAIL_RECIPIENTS,
ADMIN_IDENTIFIERS,
ADMIN_GROUP_EMAIL,
}
3 changes: 2 additions & 1 deletion backend/service/sendEmail.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const mailjet = Mailjet.apiConnect(
process.env.WATO_FINANCE_MAILJET_SECRET_KEY
)

const sendEmail = async ({ To, Subject, HTMLPart }) => {
const sendEmail = async ({ Subject, HTMLPart, To, Cc = [] }) => {
console.log('📧 Subject:', Subject)
console.log('📬 Recipients:', To)
try {
Expand All @@ -16,6 +16,7 @@ const sendEmail = async ({ To, Subject, HTMLPart }) => {
Email: process.env.WATO_FINANCE_FINANCE_EMAIL,
},
To,
Cc,
Subject,
HTMLPart,
},
Expand Down
4 changes: 2 additions & 2 deletions backend/service/sponsorshipfunds.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const {
const {
sendEmailSFReimbursementRequestToCoordinator,
sendEmailSFConfirmReimbursementSubmitToCoordinator,
sendEmailSFReimbursementReceivedToTeam,
sendEmailSFReimbursementReceivedToAdmin,
} = require('../emails/emails')

const getAllSponsorshipFunds = () => {
Expand Down Expand Up @@ -79,7 +79,7 @@ const updateSponsorshipFund = async (id, body) => {
}

if (status === 'REIMBURSED') {
await sendEmailSFReimbursementReceivedToTeam(annotatedSponsorshipFund)
await sendEmailSFReimbursementReceivedToAdmin(annotatedSponsorshipFund)
}

return newSponsorshipFund
Expand Down
10 changes: 8 additions & 2 deletions backend/service/uwfinancepurchases.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const {
sendEmailUPRApprovedToCoordinator,
sendEmailUPRPurchasedToCoordinator,
sendEmailUPRPurchasedToReporter,
sendEmailUPRReadyForPickupToCoordinator,
sendEmailUPRReadyForPickupToReporter,
sendEmailUPRPickedUpToAdmin,
} = require('../emails/emails')

const getAllUWFinancePurchases = () => {
Expand Down Expand Up @@ -53,7 +54,12 @@ const updateUWFinancePurchase = async (id, body) => {
// ORDERED -> READY_FOR_PICKUP
if (body.status === 'READY_FOR_PICKUP') {
const annotatedUPR = await getUWFinancePurchase(id)
await sendEmailUPRReadyForPickupToCoordinator(annotatedUPR)
await sendEmailUPRReadyForPickupToReporter(annotatedUPR)
}
// READY_FOR_PICKUP -> PICKED_UP
if (body.status === 'PICKED_UP') {
const annotatedUPR = await getUWFinancePurchase(id)
await sendEmailUPRPickedUpToAdmin(annotatedUPR)
}
return newPurchaseTicket
}
Expand Down

0 comments on commit 580c48d

Please sign in to comment.