| 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 |
| } |