go/svc/invoice: refactor

We unify calculation logic, move the existing Invoice proto message into
InvoiceData, and create other messages/fields around it to hold
denormalized data.
diff --git a/go/svc/invoice/render.go b/go/svc/invoice/render.go
index a433fa8..68e3472 100644
--- a/go/svc/invoice/render.go
+++ b/go/svc/invoice/render.go
@@ -24,9 +24,7 @@
 	invTmpl = template.Must(template.New("invoice.html").Parse(string(a)))
 }
 
-func renderInvoicePDF(i *pb.Invoice, number string, proforma bool) ([]byte, error) {
-	now := time.Now()
-
+func renderInvoicePDF(i *pb.Invoice) ([]byte, error) {
 	type item struct {
 		Title     string
 		UnitPrice string
@@ -56,55 +54,45 @@
 		Total                 string
 		DeliveryCharge        string
 	}{
-		InvoiceNumber:         number,
-		Date:                  now,
-		DueDate:               now.AddDate(0, 0, int(i.DaysDue)),
-		IBAN:                  i.Iban,
-		SWIFT:                 i.Swift,
-		InvoicerVAT:           i.InvoicerVatId,
-		InvoicerCompanyNumber: i.InvoicerCompanyNumber,
-		InvoiceeVAT:           i.CustomerVatId,
-		Proforma:              proforma,
-		ReverseVAT:            i.ReverseVat,
-		USCustomer:            i.UsCustomer,
+		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.InvoicerBilling)),
-		InvoiceeBilling: make([]string, len(i.CustomerBilling)),
+		InvoicerBilling: make([]string, len(i.Data.InvoicerBilling)),
+		InvoiceeBilling: make([]string, len(i.Data.CustomerBilling)),
 	}
 
-	unit := i.Unit
-	if unit == "" {
-		unit = "€"
-	}
-
-	for d, s := range i.InvoicerBilling {
+	for d, s := range i.Data.InvoicerBilling {
 		data.InvoicerBilling[d] = s
 	}
-	for d, s := range i.CustomerBilling {
+	for d, s := range i.Data.CustomerBilling {
 		data.InvoiceeBilling[d] = s
 	}
 
-	totalNet := 0
-	total := 0
-	for _, i := range i.Item {
-		rowTotalNet := int(i.UnitPrice * i.Count)
-		rowTotal := int(float64(rowTotalNet) * (float64(1) + float64(i.Vat)/100000))
+	unit := i.Unit
 
-		totalNet += rowTotalNet
-		total += rowTotal
+	for _, it := range i.Data.Item {
 		data.Items = append(data.Items, item{
-			Title:     i.Title,
-			Qty:       fmt.Sprintf("%d", i.Count),
-			UnitPrice: fmt.Sprintf(unit+"%.2f", float64(i.UnitPrice)/100),
-			VATRate:   fmt.Sprintf("%.2f%%", float64(i.Vat)/1000),
-			TotalNet:  fmt.Sprintf(unit+"%.2f", float64(rowTotalNet)/100),
-			Total:     fmt.Sprintf(unit+"%.2f", float64(rowTotal)/100),
+			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(totalNet)/100)
-	data.VATTotal = fmt.Sprintf(unit+"%.2f", float64(total-totalNet)/100)
-	data.Total = fmt.Sprintf(unit+"%.2f", float64(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))
 
 	var b bytes.Buffer