package pdf
import (
"bytes"
"fmt"
"html/template"
"path/filepath"
"strconv"
)
// OrderAckLineItemTemplateData represents an order ack line item for template rendering
type OrderAckLineItemTemplateData struct {
Title string
Description template.HTML
Quantity string
UnitPrice float64
Discount float64
TotalPrice float64
}
// BuildOrderAckHTML generates the complete HTML for an order acknowledgement using templates
func (g *HTMLDocumentGenerator) BuildOrderAckHTML(data *OrderAckPDFData, totalPages int, currentPage int) string {
orderAckNumber := data.OrderAcknowledgement.CmcReference
// Calculate totals
subtotal := 0.0
lineItemsData := []OrderAckLineItemTemplateData{}
for _, item := range data.LineItems {
unitPrice := 0.0
totalPrice := 0.0
discount := 0.0
if item.GrossUnitPrice.Valid {
unitPrice, _ = strconv.ParseFloat(item.GrossUnitPrice.String, 64)
}
if item.GrossPrice.Valid {
totalPrice, _ = strconv.ParseFloat(item.GrossPrice.String, 64)
subtotal += totalPrice
}
if item.DiscountAmountTotal.Valid {
discount, _ = strconv.ParseFloat(item.DiscountAmountTotal.String, 64)
}
lineItemsData = append(lineItemsData, OrderAckLineItemTemplateData{
Title: item.Title,
Description: template.HTML(item.Description),
Quantity: item.Quantity,
UnitPrice: unitPrice,
Discount: discount,
TotalPrice: totalPrice,
})
}
gstAmount := 0.0
total := subtotal
if data.ShowGST {
gstAmount = subtotal * 0.1
total = subtotal + gstAmount
}
// Prepare template data
templateData := struct {
OrderAckNumber string
CompanyName string
EmailTo string
Attention string
IssueDateString string
YourReference string
JobTitle string
BillTo string
ShipTo string
ShipVia string
FOB string
PaymentTerms string
CurrencyCode string
CurrencySymbol string
LineItems []OrderAckLineItemTemplateData
Subtotal float64
GSTAmount float64
Total float64
ShowGST bool
LogoDataURI string
}{
OrderAckNumber: orderAckNumber,
CompanyName: data.Customer.Name,
EmailTo: data.EmailTo,
Attention: data.Attention,
IssueDateString: data.IssueDateString,
YourReference: data.YourReference,
JobTitle: data.JobTitle,
BillTo: data.BillTo,
ShipTo: data.ShipTo,
ShipVia: data.ShipVia,
FOB: data.FOB,
PaymentTerms: data.PaymentTerms,
CurrencyCode: data.CurrencyCode,
CurrencySymbol: data.CurrencySymbol,
LineItems: lineItemsData,
Subtotal: subtotal,
GSTAmount: gstAmount,
Total: total,
ShowGST: data.ShowGST,
LogoDataURI: g.loadLogo("quote_logo.png"),
}
// Define template functions
funcMap := template.FuncMap{
"formatPrice": func(price float64) template.HTML {
formatted := FormatPriceWithCommas(fmt.Sprintf("%.2f", price))
return template.HTML(fmt.Sprintf("%s%s", data.CurrencySymbol, formatted))
},
"formatTotal": func(amount float64) template.HTML {
formatted := FormatPriceWithCommas(fmt.Sprintf("%.2f", amount))
return template.HTML(fmt.Sprintf("%s%s", data.CurrencySymbol, formatted))
},
}
// Parse and execute template
possiblePathSets := [][]string{
{
filepath.Join("internal", "cmc", "documents", "templates", "order-acknowledgement.html"),
filepath.Join("internal", "cmc", "documents", "templates", "header.html"),
},
{
filepath.Join("go", "internal", "cmc", "documents", "templates", "order-acknowledgement.html"),
filepath.Join("go", "internal", "cmc", "documents", "templates", "header.html"),
},
{
filepath.Join("templates", "pdf", "order-acknowledgement.html"),
filepath.Join("templates", "pdf", "header.html"),
},
{
"/app/templates/pdf/order-acknowledgement.html",
"/app/templates/pdf/header.html",
},
}
var tmpl *template.Template
var err error
for _, pathSet := range possiblePathSets {
tmpl, err = template.New("order-acknowledgement.html").Funcs(funcMap).ParseFiles(pathSet...)
if err == nil {
break
}
}
if tmpl == nil || err != nil {
fmt.Printf("Error parsing template from any path: %v\n", err)
return ""
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, templateData); err != nil {
fmt.Printf("Error executing template: %v\n", err)
return ""
}
return buf.String()
}