blob: 68e34723d0cf24c5978be26e8504ab06060d0be2 [file] [log] [blame]
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +02001package main
2
3import (
4 "bytes"
5 "fmt"
6 "html/template"
7 "time"
8
9 wkhtml "github.com/sebastiaanklippert/go-wkhtmltopdf"
10
11 "code.hackerspace.pl/hscloud/go/svc/invoice/templates"
12 pb "code.hackerspace.pl/hscloud/proto/invoice"
13)
14
15var (
16 invTmpl *template.Template
17)
18
19func init() {
20 a, err := templates.Asset("invoice.html")
21 if err != nil {
22 panic(err)
23 }
24 invTmpl = template.Must(template.New("invoice.html").Parse(string(a)))
25}
26
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020027func renderInvoicePDF(i *pb.Invoice) ([]byte, error) {
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020028 type item struct {
29 Title string
30 UnitPrice string
31 Qty string
32 VATRate string
33 TotalNet string
34 Total string
35 }
36
37 data := struct {
38 InvoiceNumber string
39 InvoicerBilling []string
40 InvoicerVAT string
41 InvoicerCompanyNumber string
42 InvoiceeBilling []string
43 InvoiceeVAT string
44 Date time.Time
45 DueDate time.Time
46 IBAN string
47 SWIFT string
48 Proforma bool
49 ReverseVAT bool
50 USCustomer bool
51 Items []item
52 TotalNet string
53 VATTotal string
54 Total string
55 DeliveryCharge string
56 }{
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020057 InvoiceNumber: i.FinalUid,
58 Date: time.Unix(0, i.Date),
59 DueDate: time.Unix(0, i.DueDate),
60 IBAN: i.Data.Iban,
61 SWIFT: i.Data.Swift,
62 InvoicerVAT: i.Data.InvoicerVatId,
63 InvoicerCompanyNumber: i.Data.InvoicerCompanyNumber,
64 InvoiceeVAT: i.Data.CustomerVatId,
65 Proforma: i.State == pb.Invoice_STATE_PROFORMA,
66 ReverseVAT: i.Data.ReverseVat,
67 USCustomer: i.Data.UsCustomer,
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020068
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020069 InvoicerBilling: make([]string, len(i.Data.InvoicerBilling)),
70 InvoiceeBilling: make([]string, len(i.Data.CustomerBilling)),
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020071 }
72
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020073 for d, s := range i.Data.InvoicerBilling {
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020074 data.InvoicerBilling[d] = s
75 }
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020076 for d, s := range i.Data.CustomerBilling {
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020077 data.InvoiceeBilling[d] = s
78 }
79
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020080 unit := i.Unit
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020081
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020082 for _, it := range i.Data.Item {
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020083 data.Items = append(data.Items, item{
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020084 Title: it.Title,
85 Qty: fmt.Sprintf("%d", it.Count),
86 UnitPrice: fmt.Sprintf(unit+"%.2f", float64(it.UnitPrice)/100),
87 VATRate: fmt.Sprintf("%.2f%%", float64(it.Vat)/1000),
88 TotalNet: fmt.Sprintf(unit+"%.2f", float64(it.TotalNet)/100),
89 Total: fmt.Sprintf(unit+"%.2f", float64(it.Total)/100),
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020090 })
91 }
92
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020093 data.TotalNet = fmt.Sprintf(unit+"%.2f", float64(i.TotalNet)/100)
94 data.VATTotal = fmt.Sprintf(unit+"%.2f", float64(i.Total-i.TotalNet)/100)
95 data.Total = fmt.Sprintf(unit+"%.2f", float64(i.Total)/100)
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020096 data.DeliveryCharge = fmt.Sprintf(unit+"%.2f", float64(0))
97
98 var b bytes.Buffer
99 err := invTmpl.Execute(&b, &data)
100 if err != nil {
101 return []byte{}, err
102 }
103
104 pdfg, err := wkhtml.NewPDFGenerator()
105 if err != nil {
106 return []byte{}, err
107 }
108 pdfg.Dpi.Set(600)
109 pdfg.NoCollate.Set(false)
110 pdfg.PageSize.Set(wkhtml.PageSizeA4)
111
112 pdfg.AddPage(wkhtml.NewPageReader(&b))
113
114 if err := pdfg.Create(); err != nil {
115 return []byte{}, err
116 }
117 return pdfg.Bytes(), nil
118}