317 lines
9.2 KiB
Go
317 lines
9.2 KiB
Go
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
|
|
} |