Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame] | 1 | package main |
| 2 | |
| 3 | import ( |
Serge Bazanski | b456c18 | 2020-11-16 22:46:15 +0100 | [diff] [blame] | 4 | "sort" |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame] | 5 | "time" |
| 6 | |
Sergiusz Bazanski | 1446e98 | 2019-07-21 16:04:23 +0200 | [diff] [blame] | 7 | pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto" |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame] | 8 | ) |
| 9 | |
Serge Bazanski | b456c18 | 2020-11-16 22:46:15 +0100 | [diff] [blame] | 10 | // calculateInvoiceData applies all business logic to populate an Invoice's |
| 11 | // denormalized fields from its InvoiceData. |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame] | 12 | func calculateInvoiceData(p *pb.Invoice) { |
Serge Bazanski | b456c18 | 2020-11-16 22:46:15 +0100 | [diff] [blame] | 13 | // Populate default unit. |
| 14 | // TODO(q3k): this really should be done on invoice submit instead. |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame] | 15 | p.Unit = p.Data.Unit |
| 16 | if p.Unit == "" { |
| 17 | p.Unit = "€" |
| 18 | } |
| 19 | |
Serge Bazanski | b456c18 | 2020-11-16 22:46:15 +0100 | [diff] [blame] | 20 | // Calculate totals. |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame] | 21 | p.TotalNet = 0 |
| 22 | p.Total = 0 |
| 23 | for _, i := range p.Data.Item { |
| 24 | rowTotalNet := uint64(i.UnitPrice * i.Count) |
| 25 | rowTotal := uint64(float64(rowTotalNet) * (float64(1) + float64(i.Vat)/100000)) |
| 26 | |
| 27 | p.TotalNet += rowTotalNet |
| 28 | p.Total += rowTotal |
| 29 | i.TotalNet = rowTotalNet |
| 30 | i.Total = rowTotal |
| 31 | } |
| 32 | |
Serge Bazanski | b456c18 | 2020-11-16 22:46:15 +0100 | [diff] [blame] | 33 | // Calculate due date. |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame] | 34 | due := int64(time.Hour*24) * p.Data.DaysDue |
| 35 | p.DueDate = time.Unix(0, p.Date).Add(time.Duration(due)).UnixNano() |
Serge Bazanski | b456c18 | 2020-11-16 22:46:15 +0100 | [diff] [blame] | 36 | |
| 37 | // Denormalize Items' GTUCodes into the Invoice's summary GTU codes. |
| 38 | codeSet := make(map[pb.GTUCode]bool) |
| 39 | for _, item := range p.Data.Item { |
| 40 | for _, code := range item.GtuCode { |
| 41 | codeSet[code] = true |
| 42 | } |
| 43 | } |
| 44 | var codes []pb.GTUCode |
| 45 | for c, _ := range codeSet { |
| 46 | codes = append(codes, c) |
| 47 | } |
| 48 | sort.Slice(codes, func(i, j int) bool { return codes[i] < codes[j] }) |
| 49 | p.GtuCode = codes |
Sergiusz Bazanski | 3976e3c | 2019-05-01 15:27:49 +0200 | [diff] [blame] | 50 | } |