68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
package invoice
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
func ParseMoney(input string) (Money, error) {
|
|
clean := strings.TrimSpace(input)
|
|
if clean == "" {
|
|
return 0, errors.New("empty money value")
|
|
}
|
|
sign := int64(1)
|
|
if strings.HasPrefix(clean, "-") {
|
|
sign = -1
|
|
clean = strings.TrimSpace(strings.TrimPrefix(clean, "-"))
|
|
}
|
|
clean = strings.ReplaceAll(clean, " ", "")
|
|
clean = strings.ReplaceAll(clean, ",", ".")
|
|
if strings.HasPrefix(clean, ".") || strings.HasSuffix(clean, ".") {
|
|
return 0, fmt.Errorf("invalid money value: %q", input)
|
|
}
|
|
parts := strings.Split(clean, ".")
|
|
if len(parts) > 2 {
|
|
return 0, fmt.Errorf("invalid money value: %q", input)
|
|
}
|
|
whole := parts[0]
|
|
frac := ""
|
|
if len(parts) == 2 {
|
|
frac = parts[1]
|
|
}
|
|
if whole == "" {
|
|
whole = "0"
|
|
}
|
|
for _, r := range whole {
|
|
if r < '0' || r > '9' {
|
|
return 0, fmt.Errorf("invalid money value: %q", input)
|
|
}
|
|
}
|
|
for _, r := range frac {
|
|
if r < '0' || r > '9' {
|
|
return 0, fmt.Errorf("invalid money value: %q", input)
|
|
}
|
|
}
|
|
if len(frac) > 2 {
|
|
return 0, fmt.Errorf("invalid money value: %q", input)
|
|
}
|
|
for len(frac) < 2 {
|
|
frac += "0"
|
|
}
|
|
var wholeValue int64
|
|
for _, r := range whole {
|
|
wholeValue = wholeValue*10 + int64(r-'0')
|
|
}
|
|
var fracValue int64
|
|
for _, r := range frac {
|
|
fracValue = fracValue*10 + int64(r-'0')
|
|
}
|
|
return Money(sign * (wholeValue*100 + fracValue)), nil
|
|
}
|
|
|
|
func formatCents(cents int64) string {
|
|
whole := cents / 100
|
|
frac := cents % 100
|
|
return fmt.Sprintf("%d.%02d", whole, frac)
|
|
}
|