blob: dc80e4154fbda301b953d840aa2592dff922c2ee [file] [log] [blame]
package main
import (
"bytes"
"fmt"
"html/template"
"strings"
"time"
wkhtml "github.com/SebastiaanKlippert/go-wkhtmltopdf"
pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto"
"code.hackerspace.pl/hscloud/bgpwtf/invoice/templates"
)
var (
invTmpl map[string]*template.Template
languages = []string{"en", "pl"}
defaultLanguage = "en"
)
func init() {
invTmpl = make(map[string]*template.Template)
for _, language := range languages {
filename := fmt.Sprintf("invoice_%s.html", language)
a, err := templates.Asset(filename)
if err != nil {
panic(err)
}
invTmpl[language] = template.Must(template.New(filename).Parse(string(a)))
}
}
func renderInvoicePDF(i *pb.Invoice, language string) ([]byte, error) {
type item struct {
Title string
UnitPrice string
Qty string
VATRate string
TotalNet string
Total string
}
symbols := ""
var parts []string
for _, code := range i.Data.SpCode {
parts = append(parts, code.String())
}
for _, code := range i.GtuCode {
parts = append(parts, code.String())
}
if len(parts) > 0 {
symbols = strings.Join(parts, ", ") + "."
} else {
if language == "en" {
symbols = "<i>brak (none)</i>."
} else {
symbols = "<i>brak</i>."
}
}
data := struct {
InvoiceNumber string
InvoicerBilling []string
InvoicerVAT string
InvoicerCompanyNumber string
InvoiceeBilling []string
InvoiceeVAT string
Date time.Time
DueDate time.Time
IBAN string
SWIFT string
Proforma bool
ReverseVAT bool
USCustomer bool
Items []item
TotalNet string
VATTotal string
Total string
DeliveryCharge string
Symbols template.HTML
}{
InvoiceNumber: i.FinalUid,
Date: time.Unix(0, i.Date),
DueDate: time.Unix(0, i.DueDate),
IBAN: i.Data.Iban,
SWIFT: i.Data.Swift,
InvoicerVAT: i.Data.InvoicerVatId,
InvoicerCompanyNumber: i.Data.InvoicerCompanyNumber,
InvoiceeVAT: i.Data.CustomerVatId,
Proforma: i.State == pb.Invoice_STATE_PROFORMA,
ReverseVAT: i.Data.ReverseVat,
USCustomer: i.Data.UsCustomer,
InvoicerBilling: make([]string, len(i.Data.InvoicerBilling)),
InvoiceeBilling: make([]string, len(i.Data.CustomerBilling)),
Symbols: template.HTML(symbols),
}
for d, s := range i.Data.InvoicerBilling {
data.InvoicerBilling[d] = s
}
for d, s := range i.Data.CustomerBilling {
data.InvoiceeBilling[d] = s
}
unit := i.Unit
for _, it := range i.Data.Item {
data.Items = append(data.Items, item{
Title: it.Title,
Qty: fmt.Sprintf("%d", it.Count),
UnitPrice: fmt.Sprintf(unit+"%.2f", float64(it.UnitPrice)/100),
VATRate: fmt.Sprintf("%.2f%%", float64(it.Vat)/1000),
TotalNet: fmt.Sprintf(unit+"%.2f", float64(it.TotalNet)/100),
Total: fmt.Sprintf(unit+"%.2f", float64(it.Total)/100),
})
}
data.TotalNet = fmt.Sprintf(unit+"%.2f", float64(i.TotalNet)/100)
data.VATTotal = fmt.Sprintf(unit+"%.2f", float64(i.Total-i.TotalNet)/100)
data.Total = fmt.Sprintf(unit+"%.2f", float64(i.Total)/100)
data.DeliveryCharge = fmt.Sprintf(unit+"%.2f", float64(0))
if _, ok := invTmpl[language]; !ok {
language = defaultLanguage
}
var b bytes.Buffer
err := invTmpl[language].Execute(&b, &data)
if err != nil {
return []byte{}, err
}
pdfg, err := wkhtml.NewPDFGenerator()
if err != nil {
return []byte{}, err
}
pdfg.Dpi.Set(600)
pdfg.NoCollate.Set(false)
pdfg.PageSize.Set(wkhtml.PageSizeA4)
pdfg.AddPage(wkhtml.NewPageReader(&b))
if err := pdfg.Create(); err != nil {
return []byte{}, err
}
return pdfg.Bytes(), nil
}