Files
beelloo/internal/invoice/quantity.go
2026-02-11 11:13:26 +01:00

71 lines
1.5 KiB
Go

package invoice
import (
"errors"
"fmt"
"strings"
)
// Quantity stores hundredths (e.g. 0.5 => 50).
func ParseQuantity(input string) (Quantity, error) {
clean := strings.TrimSpace(input)
if clean == "" {
return 0, errors.New("empty quantity")
}
clean = strings.ReplaceAll(clean, " ", "")
clean = strings.ReplaceAll(clean, ",", ".")
if strings.HasPrefix(clean, ".") || strings.HasSuffix(clean, ".") {
return 0, fmt.Errorf("invalid quantity: %q", input)
}
parts := strings.Split(clean, ".")
if len(parts) > 2 {
return 0, fmt.Errorf("invalid quantity: %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 quantity: %q", input)
}
}
for _, r := range frac {
if r < '0' || r > '9' {
return 0, fmt.Errorf("invalid quantity: %q", input)
}
}
if len(frac) > 2 {
return 0, fmt.Errorf("invalid quantity: %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 Quantity(wholeValue*100 + fracValue), nil
}
func FormatQuantity(q Quantity) string {
value := int64(q)
whole := value / 100
frac := value % 100
if frac == 0 {
return fmt.Sprintf("%d", whole)
}
if frac%10 == 0 {
return fmt.Sprintf("%d.%d", whole, frac/10)
}
return fmt.Sprintf("%d.%02d", whole, frac)
}