Sergiusz Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 1 | package main |
| 2 | |
| 3 | import ( |
| 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 | |
| 15 | var ( |
| 16 | invTmpl *template.Template |
| 17 | ) |
| 18 | |
| 19 | func 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 Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 27 | func renderInvoicePDF(i *pb.Invoice) ([]byte, error) { |
Sergiusz Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 28 | 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 Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 57 | 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 Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 68 | |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 69 | InvoicerBilling: make([]string, len(i.Data.InvoicerBilling)), |
| 70 | InvoiceeBilling: make([]string, len(i.Data.CustomerBilling)), |
Sergiusz Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 71 | } |
| 72 | |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 73 | for d, s := range i.Data.InvoicerBilling { |
Sergiusz Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 74 | data.InvoicerBilling[d] = s |
| 75 | } |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 76 | for d, s := range i.Data.CustomerBilling { |
Sergiusz Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 77 | data.InvoiceeBilling[d] = s |
| 78 | } |
| 79 | |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 80 | unit := i.Unit |
Sergiusz Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 81 | |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 82 | for _, it := range i.Data.Item { |
Sergiusz Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 83 | data.Items = append(data.Items, item{ |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 84 | 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 Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 90 | }) |
| 91 | } |
| 92 | |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame^] | 93 | 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 Bazanski | fb18c99 | 2019-05-01 12:27:03 +0200 | [diff] [blame] | 96 | 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 | } |