diff --git a/server/src/integrations/email/balance-change-template.ts b/server/src/integrations/email/balance-change-template.ts new file mode 100644 index 00000000..e6156708 --- /dev/null +++ b/server/src/integrations/email/balance-change-template.ts @@ -0,0 +1,67 @@ +import ejs from "ejs" +import { centsToDollarString } from "../currency/currency.js" +import { getAccountOwner } from "../../repositories/Currency/CurrencyAccountsRepository.js"; + +const templateSource: string = ` + + + +
+ RIT SHED Logo +

Account Balance Modification Notice

+ + <% if (info.type == "credit") { %> +

Your balance has been credited <%= formatCents(info.amount) %>

+ <% } else { %> +

Your balance has been charged <%= formatCents(info.amount) %>

+ <% } %> + +

Reason: <%= info.desc %>

+ +
+` + +let template = ejs.compile(templateSource, { async: false }) + +function generateHTMLChange(desc:balChangeInfo) { + let data = { + info: desc, + formatCents: centsToDollarString, + }; + return template(data); +} + +function generateTextChange(desc: balChangeInfo) { + return desc.type +} + +export type balChangeInfo ={ + amount: number + type: "credit" | "charge" + desc: string +} + +export function generateBalanceChangeEmail(desc: balChangeInfo): {text: string, html: string} { + const text = generateTextChange(desc); + const html = generateHTMLChange(desc); + return {text, html} +} diff --git a/server/src/integrations/email/email.ts b/server/src/integrations/email/email.ts index a3c58dbe..e6f9054c 100644 --- a/server/src/integrations/email/email.ts +++ b/server/src/integrations/email/email.ts @@ -2,6 +2,8 @@ import FormData from "form-data"; import * as Mailgun from "mailgun.js" import { generateReceiptEmail } from "./receipt-template.js" import { generateExpiryEmail, ExpiryDescription } from "./training-expiry-template.js" +import { balChangeInfo, generateBalanceChangeEmail } from "./balance-change-template.js"; +import { generateHoldPlacedEmail } from "./hold-placed-template.js"; const mailgun = new Mailgun.default(FormData); const mg = mailgun.client({ username: 'api', key: process.env.MAILGUN_API_KEY || 'key-yourkeyhere' }); const MAIL_DOMAIN = process.env.MAIL_DOMAIN ?? ""; @@ -69,4 +71,26 @@ export async function send_training_expiry_email(email: string, desc: ExpiryDesc textContent: content.text, htmlContent: content.html, }) +} + +export async function send_cc_balance_change_email(email: string, desc: balChangeInfo) { + const content = generateBalanceChangeEmail(desc); + send_generic_email({ + fromAccount: "cc", + to: [email], + subject: "RIT SHED: Account Balance Adjusted - " + new Date().toLocaleDateString(), + textContent: content.text, + htmlContent: content.html, + }) +} + +export async function send_hold_placed_email(email: string, desc: string) { + const content = generateHoldPlacedEmail(desc); + send_generic_email({ + fromAccount: "holds", + to: [email], + subject: "RIT SHED: Hold Placed On Account - " + new Date().toLocaleDateString(), + textContent: content.text, + htmlContent: content.html, + }) } \ No newline at end of file diff --git a/server/src/integrations/email/hold-placed-template.ts b/server/src/integrations/email/hold-placed-template.ts new file mode 100644 index 00000000..2237f8f0 --- /dev/null +++ b/server/src/integrations/email/hold-placed-template.ts @@ -0,0 +1,52 @@ +import ejs from "ejs" +import { centsToDollarString } from "../currency/currency.js" +import { getAccountOwner } from "../../repositories/Currency/CurrencyAccountsRepository.js"; + +const templateSource: string = ` + + +
+ RIT SHED Logo +

Account Hold Notice

+
+

A hold has been placed on your account.

+

Reason: <%= desc %>

+ +
+
+ + Please see Makerspace staff to remove hold. + +
+` + +let template = ejs.compile(templateSource, { async: false }) + +function generateHTMLHold(desc: string) { + let data = { + desc: desc, + }; + return template(data); +} + +export function generateHoldPlacedEmail(desc: string): {text: string, html: string} { + const html = generateHTMLHold(desc); + return {text: html, html} +} \ No newline at end of file diff --git a/server/src/resolvers/currencyAccountResolver.ts b/server/src/resolvers/currencyAccountResolver.ts index af8cea8e..cd075bfc 100644 --- a/server/src/resolvers/currencyAccountResolver.ts +++ b/server/src/resolvers/currencyAccountResolver.ts @@ -1,5 +1,6 @@ import { ApolloContext } from "../context.js"; import { CurrencyAccountsRow } from "../db/tables.js"; +import { send_cc_balance_change_email } from "../integrations/email/email.js"; import * as CurrencyAccountRepo from "../repositories/Currency/CurrencyAccountsRepository.js" export const CurrencyAccountResolvers = { @@ -45,6 +46,12 @@ export const CurrencyAccountResolvers = { }, { isManager }: ApolloContext ) => { + const owner = await CurrencyAccountRepo.getAccountOwner(args.accountID); + send_cc_balance_change_email(owner?.username + "@rit.edu", { + amount: Math.abs(args.amount), + type: args.amount > 0 ? "credit" : "charge", + desc: args.description, + }); return isManager(async (user) => ( await CurrencyAccountRepo.adjustAccountBalanceCents(args.accountID, args.amount, "make-website", `adjustment by ${user.ritUsername}: ${args.description}`) )) diff --git a/server/src/resolvers/holdsResolver.ts b/server/src/resolvers/holdsResolver.ts index 41e0e526..31df9f4d 100644 --- a/server/src/resolvers/holdsResolver.ts +++ b/server/src/resolvers/holdsResolver.ts @@ -4,6 +4,7 @@ import * as UsersRepo from "../repositories/Users/UserRepository.js"; import { createLog } from "../repositories/AuditLogs/AuditLogRepository.js"; import { getUsersFullName } from "../repositories/Users/UserRepository.js"; import { HoldRow } from "../db/tables.js"; +import { send_hold_placed_email } from "../integrations/email/email.js"; const HoldsResolvers = { Hold: { @@ -51,6 +52,7 @@ const HoldsResolvers = { ); await UsersRepo.setActiveHold(Number(args.userID), true) + send_hold_placed_email(user.ritUsername + "@rit.edu", args.description); return HoldsRepo.createHold(user.id, Number(args.userID), args.description); }),