46 lines
1.2 KiB
Go
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)
|
|
}
|