package main import ( "sort" "time" pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto" ) // calculateInvoiceData applies all business logic to populate an Invoice's // denormalized fields from its InvoiceData. func calculateInvoiceData(p *pb.Invoice) { // Populate default unit. // TODO(q3k): this really should be done on invoice submit instead. p.Unit = p.Data.Unit if p.Unit == "" { p.Unit = "€" } // Calculate totals. p.TotalNet = 0 p.Total = 0 for _, i := range p.Data.Item { rowTotalNet := uint64(i.UnitPrice * i.Count) rowTotal := uint64(float64(rowTotalNet) * (float64(1) + float64(i.Vat)/100000)) p.TotalNet += rowTotalNet p.Total += rowTotal i.TotalNet = rowTotalNet i.Total = rowTotal } // Calculate due date. due := int64(time.Hour*24) * p.Data.DaysDue p.DueDate = time.Unix(0, p.Date).Add(time.Duration(due)).UnixNano() // Denormalize Items' GTUCodes into the Invoice's summary GTU codes. codeSet := make(map[pb.GTUCode]bool) for _, item := range p.Data.Item { for _, code := range item.GtuCode { codeSet[code] = true } } var codes []pb.GTUCode for c, _ := range codeSet { codes = append(codes, c) } sort.Slice(codes, func(i, j int) bool { return codes[i] < codes[j] }) p.GtuCode = codes }