From f7c705c5fdc84959966683cfa9597fbb6c35097a Mon Sep 17 00:00:00 2001 From: Vandana Date: Thu, 11 Jun 2026 08:00:05 -0700 Subject: [PATCH] feat(offers): enrich cashout initiated email with customer name, cashout ID, ERPNext link - Display ERPNext Customer name (erpParty) as primary identifier - Add clickable ERPNext link to cashout record via FrappeConfig.url - Show Cashout ID in header, title, and table row - Surface service fee row from existing payout data - Guard against missing username (?? '') - Fallback: erpParty -> username -> empty string Closes ENG-409 --- src/services/email/EmailService.ts | 17 ++++--- src/services/email/templates/cashout.ts | 60 ++++++++++++++++++++----- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/services/email/EmailService.ts b/src/services/email/EmailService.ts index ee050e258..b96c46b9c 100644 --- a/src/services/email/EmailService.ts +++ b/src/services/email/EmailService.ts @@ -1,11 +1,9 @@ import sgMail from "@sendgrid/mail" -import { Cashout, SendGridConfig } from "@config" +import { Cashout, FrappeConfig, SendGridConfig } from "@config" import { baseLogger } from "@services/logger" -import { CashoutDetails } from "@app/offers" import { CashoutBody } from "./templates/cashout" -import Offer from "@app/offers/Offer" import { InitiatedCashout } from "@app/offers/ValidOffer" type EmailHeaders = { @@ -21,12 +19,19 @@ sgMail.setApiKey(SendGridConfig.apiKey) class EmailService { sendCashoutInitiatedEmail = async (cashout: InitiatedCashout) => { - const username = cashout.offer.account.username - const offer = cashout.offer.details + const account = cashout.offer.account + + const username = account.username ?? "" + const customerName = account.erpParty ?? username + const cashoutId = cashout.cashoutId + const erpNextLink = `${FrappeConfig.url}/app/cashout/${cashoutId}` const body = CashoutBody({ - ...offer, + ...cashout.offer.details, username, + customerName, + cashoutId, + erpNextLink, formattedDate: new Date().toLocaleString("en-US", { month: "short", day: "numeric", diff --git a/src/services/email/templates/cashout.ts b/src/services/email/templates/cashout.ts index 697335f0c..b538c8c58 100644 --- a/src/services/email/templates/cashout.ts +++ b/src/services/email/templates/cashout.ts @@ -1,11 +1,25 @@ import { CashoutDetails } from "@app/offers" -import { JMDAmount } from "@domain/shared" +import { JMDAmount, USDAmount } from "@domain/shared" -type CashoutBodyArgs = CashoutDetails & { username: Username, formattedDate: string } +type CashoutBodyArgs = CashoutDetails & { + username: string + customerName: string + cashoutId: string + erpNextLink: string + formattedDate: string +} export const CashoutBody = (args: CashoutBodyArgs) => { - const currency = args.payout.amount instanceof JMDAmount ? "JMD" : "USD" - const payoutString = `${args.payout.amount.asDollars()} ${currency}` + const payoutCurrency = args.payout.amount instanceof JMDAmount ? "JMD" : "USD" + const payoutString = `${args.payout.amount.asDollars()} ${payoutCurrency}` + + const serviceFeeString = args.payout.serviceFee instanceof USDAmount + ? args.payout.serviceFee.asDollars() + : null + + const feeDetails = serviceFeeString + ? `Service fee: $${serviceFeeString} USD` + : "" return { html: ` @@ -14,13 +28,13 @@ export const CashoutBody = (args: CashoutBodyArgs) => { - Flash Cashout Notification + Flash Cashout Notification — ${args.cashoutId}

FLASH

-

Received Cashout Transaction

+

Cashout Initiated — ${args.cashoutId}

@@ -28,14 +42,27 @@ export const CashoutBody = (args: CashoutBodyArgs) => {

Transaction Details

+ + + + + + + + - + - + + ${serviceFeeString ? ` + + + + ` : ""} @@ -46,7 +73,11 @@ export const CashoutBody = (args: CashoutBodyArgs) => {

User Information

Cashout ID${args.cashoutId}
ERPNext Link${args.erpNextLink}
Ibex Payment${args.payment.invoice.paymentHash}${args.payment.invoice.paymentHash}
Owed to userPayout Amount ${payoutString}
Service Fee$${serviceFeeString} USD
Date & Time ${args.formattedDate}
- + + + + + @@ -66,16 +97,21 @@ export const CashoutBody = (args: CashoutBodyArgs) => { `, text: ` - FLASH - Cashout Initiated + FLASH - Cashout Initiated [${args.cashoutId}] + + ERPNext: ${args.erpNextLink} Transaction Details: -------------------- + Cashout ID: ${args.cashoutId} Ibex Payment: ${args.payment.invoice.paymentHash} - Amount owed: ${payoutString} + Payout Amount: ${payoutString} + ${feeDetails} Date & Time: ${args.formattedDate} User Information: ------------------- + Customer: ${args.customerName} Username: ${args.username} Wallet ID: ${args.payment.userAcct} @@ -84,4 +120,4 @@ export const CashoutBody = (args: CashoutBodyArgs) => { © ${new Date().getFullYear()} Flash. All rights reserved. ` } -} \ No newline at end of file +}
UsernameCustomer${args.customerName}
Username ${args.username}