package pdf import ( "fmt" "time" "code.springupsoftware.com/cmc/cmc-sales/internal/cmc/db" ) // QuotePDFData contains all data needed to generate a quote PDF type QuotePDFData struct { Document *db.Document Quote interface{} // Quote specific data Enquiry *db.Enquiry Customer *db.Customer Contact interface{} // Contact data User *db.GetUserRow LineItems []db.GetLineItemsTableRow Currency interface{} // Currency data CurrencySymbol string ShowGST bool CommercialComments string } // GenerateQuotePDF generates a PDF for a quote func GenerateQuotePDF(data *QuotePDFData, outputDir string) (string, error) { fmt.Printf("GenerateQuotePDF called with outputDir: %s\n", outputDir) gen := NewGenerator(outputDir) // First page with header gen.AddPage() gen.Page1Header() // Extract data for details box companyName := "" // TODO: Get from customer data if data.Customer != nil { companyName = data.Customer.Name } emailTo := "" // TODO: Get from contact attention := "" // TODO: Get from contact fromName := fmt.Sprintf("%s %s", data.User.FirstName, data.User.LastName) fromEmail := data.User.Email // Use CMC reference as the quote number quoteNumber := data.Document.CmcReference if data.Document.Revision > 0 { quoteNumber = fmt.Sprintf("%s.%d", quoteNumber, data.Document.Revision) } yourReference := fmt.Sprintf("Enquiry on %s", data.Document.Created.Format("2 Jan 2006")) issueDate := data.Document.Created.Format("2 January 2006") // Add details box gen.DetailsBox("QUOTE", companyName, emailTo, attention, fromName, fromEmail, quoteNumber, yourReference, issueDate) // Add page content if any // TODO: Add document pages content gen.Page1Footer() // Add pricing page gen.AddPage() gen.pdf.SetFont("Helvetica", "B", 14) gen.pdf.CellFormat(0, 10, "PRICING & SPECIFICATIONS", "", 1, "C", false, 0, "") gen.pdf.Ln(5) // Convert line items pdfItems := make([]LineItem, len(data.LineItems)) for i, item := range data.LineItems { unitPrice := 0.0 totalPrice := 0.0 // Parse prices if item.GrossUnitPrice.Valid { fmt.Sscanf(item.GrossUnitPrice.String, "%f", &unitPrice) } if item.GrossPrice.Valid { fmt.Sscanf(item.GrossPrice.String, "%f", &totalPrice) } pdfItems[i] = LineItem{ ItemNumber: item.ItemNumber, Quantity: item.Quantity, Title: item.Title, UnitPrice: unitPrice, TotalPrice: totalPrice, } } // Add line items table gen.AddLineItemsTable(pdfItems, data.CurrencySymbol, data.ShowGST) // Add commercial comments if any if data.CommercialComments != "" { gen.pdf.Ln(10) gen.pdf.SetFont("Helvetica", "B", 10) gen.pdf.CellFormat(0, 5, "COMMERCIAL COMMENTS", "", 1, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "", 9) gen.pdf.MultiCell(0, 5, data.CommercialComments, "", "L", false) } // TODO: Add terms and conditions page // Generate filename filename := quoteNumber if data.Document.Revision > 0 { filename = fmt.Sprintf("%s_%d.pdf", quoteNumber, data.Document.Revision) } else { filename = fmt.Sprintf("%s.pdf", quoteNumber) } // Save PDF fmt.Printf("Saving PDF with filename: %s to outputDir: %s\n", filename, outputDir) err := gen.Save(filename) if err != nil { fmt.Printf("Error saving PDF: %v\n", err) } else { fmt.Printf("PDF saved successfully: %s\n", filename) } return filename, err } // InvoicePDFData contains all data needed to generate an invoice PDF type InvoicePDFData struct { Document *db.Document Invoice *db.Invoice Enquiry *db.Enquiry Customer *db.Customer Job interface{} // Job data LineItems []db.GetLineItemsTableRow Currency interface{} // Currency data CurrencySymbol string ShowGST bool ShipVia string FOB string IssueDate time.Time } // GenerateInvoicePDF generates a PDF for an invoice func GenerateInvoicePDF(data *InvoicePDFData, outputDir string) (string, error) { gen := NewGenerator(outputDir) // First page with header gen.AddPage() gen.Page1Header() // Extract data for details box companyName := data.Customer.Name emailTo := "" // TODO: Get from contact attention := "" // TODO: Get from contact fromName := "" // TODO: Get from user fromEmail := "" // TODO: Get from user invoiceNumber := data.Invoice.Title yourReference := "" // TODO: Get reference issueDate := data.IssueDate.Format("2 January 2006") // Add details box gen.DetailsBox("INVOICE", companyName, emailTo, attention, fromName, fromEmail, invoiceNumber, yourReference, issueDate) // Add shipping details gen.pdf.Ln(5) gen.pdf.SetFont("Helvetica", "B", 10) gen.pdf.CellFormat(30, 5, "Ship Via:", "", 0, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "", 10) gen.pdf.CellFormat(60, 5, data.ShipVia, "", 1, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "B", 10) gen.pdf.CellFormat(30, 5, "FOB:", "", 0, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "", 10) gen.pdf.CellFormat(60, 5, data.FOB, "", 1, "L", false, 0, "") gen.Page1Footer() // Add line items page gen.AddPage() gen.pdf.SetFont("Helvetica", "B", 14) gen.pdf.CellFormat(0, 10, "INVOICE DETAILS", "", 1, "C", false, 0, "") gen.pdf.Ln(5) // Convert line items pdfItems := make([]LineItem, len(data.LineItems)) for i, item := range data.LineItems { unitPrice := 0.0 totalPrice := 0.0 // Parse prices if item.GrossUnitPrice.Valid { fmt.Sscanf(item.GrossUnitPrice.String, "%f", &unitPrice) } if item.GrossPrice.Valid { fmt.Sscanf(item.GrossPrice.String, "%f", &totalPrice) } pdfItems[i] = LineItem{ ItemNumber: item.ItemNumber, Quantity: item.Quantity, Title: item.Title, UnitPrice: unitPrice, TotalPrice: totalPrice, } } // Add line items table gen.AddLineItemsTable(pdfItems, data.CurrencySymbol, data.ShowGST) // Generate filename filename := fmt.Sprintf("%s.pdf", invoiceNumber) // Save PDF err := gen.Save(filename) return filename, err } // PurchaseOrderPDFData contains all data needed to generate a purchase order PDF type PurchaseOrderPDFData struct { Document *db.Document PurchaseOrder *db.PurchaseOrder Principle *db.Principle LineItems []db.GetLineItemsTableRow Currency interface{} // Currency data CurrencySymbol string ShowGST bool } // GeneratePurchaseOrderPDF generates a PDF for a purchase order func GeneratePurchaseOrderPDF(data *PurchaseOrderPDFData, outputDir string) (string, error) { gen := NewGenerator(outputDir) // First page with header gen.AddPage() gen.Page1Header() // Extract data for details box companyName := data.Principle.Name emailTo := "" // TODO: Get from principle contact attention := "" // TODO: Get from principle contact fromName := "" // TODO: Get from user fromEmail := "" // TODO: Get from user poNumber := data.PurchaseOrder.Title yourReference := data.PurchaseOrder.PrincipleReference issueDate := data.PurchaseOrder.IssueDate.Format("Monday, 2 January 2006") // Add details box gen.DetailsBox("PURCHASE ORDER", companyName, emailTo, attention, fromName, fromEmail, poNumber, yourReference, issueDate) // Add PO specific details gen.pdf.Ln(5) gen.pdf.SetFont("Helvetica", "B", 10) gen.pdf.CellFormat(40, 5, "Ordered From:", "", 0, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "", 10) gen.pdf.MultiCell(0, 5, data.PurchaseOrder.OrderedFrom, "", "L", false) gen.pdf.SetFont("Helvetica", "B", 10) gen.pdf.CellFormat(40, 5, "Dispatch By:", "", 0, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "", 10) gen.pdf.CellFormat(0, 5, data.PurchaseOrder.DispatchBy, "", 1, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "B", 10) gen.pdf.CellFormat(40, 5, "Deliver To:", "", 0, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "", 10) gen.pdf.MultiCell(0, 5, data.PurchaseOrder.DeliverTo, "", "L", false) if data.PurchaseOrder.ShippingInstructions != "" { gen.pdf.SetFont("Helvetica", "B", 10) gen.pdf.CellFormat(0, 5, "Shipping Instructions:", "", 1, "L", false, 0, "") gen.pdf.SetFont("Helvetica", "", 10) gen.pdf.MultiCell(0, 5, data.PurchaseOrder.ShippingInstructions, "", "L", false) } gen.Page1Footer() // Add line items page gen.AddPage() gen.pdf.SetFont("Helvetica", "B", 14) gen.pdf.CellFormat(0, 10, "ORDER DETAILS", "", 1, "C", false, 0, "") gen.pdf.Ln(5) // Convert line items pdfItems := make([]LineItem, len(data.LineItems)) for i, item := range data.LineItems { unitPrice := 0.0 totalPrice := 0.0 // Parse prices if item.GrossUnitPrice.Valid { fmt.Sscanf(item.GrossUnitPrice.String, "%f", &unitPrice) } if item.GrossPrice.Valid { fmt.Sscanf(item.GrossPrice.String, "%f", &totalPrice) } pdfItems[i] = LineItem{ ItemNumber: item.ItemNumber, Quantity: item.Quantity, Title: item.Title, UnitPrice: unitPrice, TotalPrice: totalPrice, } } // Add line items table gen.AddLineItemsTable(pdfItems, data.CurrencySymbol, data.ShowGST) // Generate filename filename := poNumber if data.Document.Revision > 0 { filename = fmt.Sprintf("%s-Rev%d.pdf", data.PurchaseOrder.Title, data.Document.Revision) } else { filename = fmt.Sprintf("%s.pdf", data.PurchaseOrder.Title) } // Save PDF err := gen.Save(filename) return filename, err }