Files
sultan/pkg/accountant/money.go
T

46 lines
1.2 KiB
Go

package accountant
import (
"fmt"
"strconv"
"strings"
)
// ParseMoney liest einen Betrag in Euro (z. B. "89", "89,00", "89.5",
// "1.234,56") und liefert Cent. Mehr als zwei Nachkommastellen und negative
// Beträge sind Fehler.
func ParseMoney(s string) (int64, error) {
s = strings.TrimSpace(s)
orig := s
if strings.Contains(s, ",") {
s = strings.ReplaceAll(s, ".", "") // Tausenderpunkte
s = strings.Replace(s, ",", ".", 1)
}
whole, frac, _ := strings.Cut(s, ".")
if whole == "" || len(frac) > 2 || strings.ContainsAny(frac, ".,") {
return 0, fmt.Errorf("Betrag %q nicht lesbar (z. B. 89,00)", orig)
}
for len(frac) < 2 {
frac += "0"
}
euros, err := strconv.ParseUint(whole, 10, 40)
if err != nil {
return 0, fmt.Errorf("Betrag %q nicht lesbar (z. B. 89,00)", orig)
}
cents, err := strconv.ParseUint(frac, 10, 8)
if err != nil {
return 0, fmt.Errorf("Betrag %q nicht lesbar (z. B. 89,00)", orig)
}
return int64(euros)*100 + int64(cents), nil
}
// FormatMoney formatiert Cent als Euro mit Dezimalkomma ("89,00"), wie
// Lexware Office es beim Import erwartet.
func FormatMoney(cents int64) string {
sign := ""
if cents < 0 {
sign, cents = "-", -cents
}
return fmt.Sprintf("%s%d,%02d", sign, cents/100, cents%100)
}