Ensuring automatic quote reminder emails have pdfs

This commit is contained in:
Finley Ghosh 2025-12-07 22:15:09 +11:00
parent 57e7f7fe24
commit 3950cef4c9

View file

@ -5,7 +5,6 @@ import (
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"log" "log"
"net/http" "net/http"
"os" "os"
@ -447,7 +446,12 @@ func (h *QuotesHandler) DailyQuoteExpirationCheck() {
q["UserEmail"].(string), q["UserEmail"].(string),
) )
err := h.SendQuoteReminderEmail( // Construct PDF path from filesystem
enquiryRef := q["EnquiryRef"].(string)
pdfPath := fmt.Sprintf("/root/webroot/pdf/%s.pdf", enquiryRef)
pdfFilename := fmt.Sprintf("%s.pdf", enquiryRef)
err := h.SendQuoteReminderEmailWithPDF(
context.Background(), context.Background(),
q["ID"].(int32), q["ID"].(int32),
job.ReminderType, job.ReminderType,
@ -457,7 +461,8 @@ func (h *QuotesHandler) DailyQuoteExpirationCheck() {
templateData, templateData,
ccs, ccs,
nil, nil,
false, pdfPath,
pdfFilename,
) )
if err != nil { if err != nil {
fmt.Printf("Error sending %s for quote %v: %v\n", job.ReminderType.String(), q["ID"], err) fmt.Printf("Error sending %s for quote %v: %v\n", job.ReminderType.String(), q["ID"], err)
@ -530,10 +535,8 @@ func (h *QuotesHandler) SendQuoteReminderEmail(ctx context.Context, quoteID int3
return nil return nil
} }
// SendQuoteReminderEmailWithAttachment is like SendQuoteReminderEmail but includes a PDF attachment // SendQuoteReminderEmailWithPDF sends a reminder email with PDF attachment loaded from filesystem
func (h *QuotesHandler) SendQuoteReminderEmailWithAttachment(ctx context.Context, quoteID int32, reminderType QuoteReminderType, recipient string, subject string, templateName string, templateData map[string]interface{}, ccs []string, username *string, pdfPath string, pdfFilename string, sourceReq *http.Request) error { func (h *QuotesHandler) SendQuoteReminderEmailWithPDF(ctx context.Context, quoteID int32, reminderType QuoteReminderType, recipient string, subject string, templateName string, templateData map[string]interface{}, ccs []string, username *string, pdfPath string, pdfFilename string) error {
log.Printf("SendQuoteReminderEmailWithAttachment called for quote %d, recipient: %s, PDF URL: %s", quoteID, recipient, pdfPath)
// Safeguard: check for valid recipient // Safeguard: check for valid recipient
if strings.TrimSpace(recipient) == "" { if strings.TrimSpace(recipient) == "" {
return fmt.Errorf("recipient email is required") return fmt.Errorf("recipient email is required")
@ -547,54 +550,38 @@ func (h *QuotesHandler) SendQuoteReminderEmailWithAttachment(ctx context.Context
return fmt.Errorf("invalid reminder type: %v", reminderType) return fmt.Errorf("invalid reminder type: %v", reminderType)
} }
// Download PDF from URL and prepare attachment if available // Check if reminder already sent
var attachments []interface{} reminders, err := h.queries.GetQuoteRemindersByType(ctx, db.GetQuoteRemindersByTypeParams{
QuoteID: quoteID,
// Create authenticated request for PDF download ReminderType: int32(reminderType),
req, err := auth.NewAuthenticatedRequest("GET", pdfPath, sourceReq) })
if err != nil { if err != nil {
log.Printf("Failed to create PDF download request for quote %d: %v", quoteID, err) return fmt.Errorf("failed to check existing reminders: %w", err)
} else { }
client := &http.Client{}
resp, err := client.Do(req)
if err == nil && resp.StatusCode == 200 {
defer resp.Body.Close()
// Create temporary file for the PDF // Exit if the email has already been sent
tmpFile, err := os.CreateTemp("", "quote_*.pdf") if len(reminders) > 0 {
if err == nil { return nil
defer os.Remove(tmpFile.Name()) }
defer tmpFile.Close()
// Copy PDF content to temp file // Prepare PDF attachment if file exists
if _, err := io.Copy(tmpFile, resp.Body); err == nil { var attachments []interface{}
if _, err := os.Stat(pdfPath); err == nil {
attachments = []interface{}{ attachments = []interface{}{
struct { struct {
Filename string Filename string
FilePath string FilePath string
}{ }{
Filename: pdfFilename, Filename: pdfFilename,
FilePath: tmpFile.Name(), FilePath: pdfPath,
}, },
} }
log.Printf("Successfully downloaded and attached PDF for quote %d: %s (tmpFile: %s)", quoteID, pdfFilename, tmpFile.Name()) log.Printf("Attaching PDF for quote %d: %s", quoteID, pdfPath)
} else { } else {
log.Printf("Failed to copy PDF content for quote %d: %v", quoteID, err) log.Printf("PDF not found for quote %d at %s, sending without attachment", quoteID, pdfPath)
} }
} else {
log.Printf("Failed to create temporary file for quote %d PDF: %v", quoteID, err)
}
} else if err != nil {
log.Printf("Failed to download PDF from %s for quote %d: %v", pdfPath, quoteID, err)
} else if resp != nil {
defer resp.Body.Close()
log.Printf("PDF download returned status %d for quote %d at %s", resp.StatusCode, quoteID, pdfPath)
}
}
// If PDF download fails, just send email without attachment
// Send the email (with or without attachment) // Send the email (with or without attachment)
log.Printf("Sending email for quote %d with %d attachment(s)", quoteID, len(attachments))
err = h.emailService.SendTemplateEmailWithAttachments( err = h.emailService.SendTemplateEmailWithAttachments(
recipient, recipient,
subject, subject,
@ -692,8 +679,8 @@ func (h *QuotesHandler) SendManualReminder(w http.ResponseWriter, r *http.Reques
ccs = append(ccs, userEmail) ccs = append(ccs, userEmail)
} }
// Attach PDF quote from URL // Attach PDF quote from filesystem
pdfURL := fmt.Sprintf("https://stg.cmctechnologies.com.au/pdf/%s.pdf", enquiryRef) pdfPath := fmt.Sprintf("/root/webroot/pdf/%s.pdf", enquiryRef)
pdfFilename := fmt.Sprintf("%s.pdf", enquiryRef) pdfFilename := fmt.Sprintf("%s.pdf", enquiryRef)
// Get username from request // Get username from request
@ -701,7 +688,7 @@ func (h *QuotesHandler) SendManualReminder(w http.ResponseWriter, r *http.Reques
usernamePtr := &username usernamePtr := &username
// Send the reminder with attachment // Send the reminder with attachment
err = h.SendQuoteReminderEmailWithAttachment( err = h.SendQuoteReminderEmailWithPDF(
r.Context(), r.Context(),
int32(quoteID), int32(quoteID),
reminderType, reminderType,
@ -711,9 +698,8 @@ func (h *QuotesHandler) SendManualReminder(w http.ResponseWriter, r *http.Reques
templateData, templateData,
ccs, ccs,
usernamePtr, usernamePtr,
pdfURL, pdfPath,
pdfFilename, pdfFilename,
r,
) )
if err != nil { if err != nil {