blob: 03dcd7757f008236e5561e390bbedb66c73feae9 [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 (
Sergiusz Bazanskia818ef22019-06-07 10:37:22 +020016 invTmpl map[string]*template.Template
17
18 languages = []string{"en", "pl"}
19 defaultLanguage = "en"
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020020)
21
22func init() {
Sergiusz Bazanskia818ef22019-06-07 10:37:22 +020023 invTmpl = make(map[string]*template.Template)
24 for _, language := range languages {
25 filename := fmt.Sprintf("invoice_%s.html", language)
26 a, err := templates.Asset(filename)
27 if err != nil {
28 panic(err)
29 }
30 invTmpl[language] = template.Must(template.New(filename).Parse(string(a)))
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020031 }
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020032}
33
Sergiusz Bazanskia818ef22019-06-07 10:37:22 +020034func renderInvoicePDF(i *pb.Invoice, language string) ([]byte, error) {
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020035 type item struct {
36 Title string
37 UnitPrice string
38 Qty string
39 VATRate string
40 TotalNet string
41 Total string
42 }
43
44 data := struct {
45 InvoiceNumber string
46 InvoicerBilling []string
47 InvoicerVAT string
48 InvoicerCompanyNumber string
49 InvoiceeBilling []string
50 InvoiceeVAT string
51 Date time.Time
52 DueDate time.Time
53 IBAN string
54 SWIFT string
55 Proforma bool
56 ReverseVAT bool
57 USCustomer bool
58 Items []item
59 TotalNet string
60 VATTotal string
61 Total string
62 DeliveryCharge string
63 }{
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020064 InvoiceNumber: i.FinalUid,
65 Date: time.Unix(0, i.Date),
66 DueDate: time.Unix(0, i.DueDate),
67 IBAN: i.Data.Iban,
68 SWIFT: i.Data.Swift,
69 InvoicerVAT: i.Data.InvoicerVatId,
70 InvoicerCompanyNumber: i.Data.InvoicerCompanyNumber,
71 InvoiceeVAT: i.Data.CustomerVatId,
72 Proforma: i.State == pb.Invoice_STATE_PROFORMA,
73 ReverseVAT: i.Data.ReverseVat,
74 USCustomer: i.Data.UsCustomer,
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020075
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020076 InvoicerBilling: make([]string, len(i.Data.InvoicerBilling)),
77 InvoiceeBilling: make([]string, len(i.Data.CustomerBilling)),
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020078 }
79
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020080 for d, s := range i.Data.InvoicerBilling {
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020081 data.InvoicerBilling[d] = s
82 }
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020083 for d, s := range i.Data.CustomerBilling {
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020084 data.InvoiceeBilling[d] = s
85 }
86
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020087 unit := i.Unit
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020088
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020089 for _, it := range i.Data.Item {
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020090 data.Items = append(data.Items, item{
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +020091 Title: it.Title,
92 Qty: fmt.Sprintf("%d", it.Count),
93 UnitPrice: fmt.Sprintf(unit+"%.2f", float64(it.UnitPrice)/100),
94 VATRate: fmt.Sprintf("%.2f%%", float64(it.Vat)/1000),
95 TotalNet: fmt.Sprintf(unit+"%.2f", float64(it.TotalNet)/100),
96 Total: fmt.Sprintf(unit+"%.2f", float64(it.Total)/100),
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +020097 })
98 }
99
Sergiusz Bazanski3976e3c2019-05-01 15:27:49 +0200100 data.TotalNet = fmt.Sprintf(unit+"%.2f", float64(i.TotalNet)/100)
101 data.VATTotal = fmt.Sprintf(unit+"%.2f", float64(i.Total-i.TotalNet)/100)
102 data.Total = fmt.Sprintf(unit+"%.2f", float64(i.Total)/100)
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +0200103 data.DeliveryCharge = fmt.Sprintf(unit+"%.2f", float64(0))
104
Sergiusz Bazanskia818ef22019-06-07 10:37:22 +0200105 if _, ok := invTmpl[language]; !ok {
106 language = defaultLanguage
107 }
108
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +0200109 var b bytes.Buffer
Sergiusz Bazanskia818ef22019-06-07 10:37:22 +0200110 err := invTmpl[language].Execute(&b, &data)
Sergiusz Bazanskifb18c992019-05-01 12:27:03 +0200111 if err != nil {
112 return []byte{}, err
113 }
114
115 pdfg, err := wkhtml.NewPDFGenerator()
116 if err != nil {
117 return []byte{}, err
118 }
119 pdfg.Dpi.Set(600)
120 pdfg.NoCollate.Set(false)
121 pdfg.PageSize.Set(wkhtml.PageSizeA4)
122
123 pdfg.AddPage(wkhtml.NewPageReader(&b))
124
125 if err := pdfg.Create(); err != nil {
126 return []byte{}, err
127 }
128 return pdfg.Bytes(), nil
129}