order validation

This commit is contained in:
bronku 2026-11-08 19:05:53 +01:00
parent 2a4110ee8c
commit de22166113
6 changed files with 164 additions and 7 deletions

74
orders/order.go Normal file
View file

@ -0,0 +1,74 @@
package orders
import (
"errors"
"fmt"
"log"
"math"
"net/http"
"piekarnikgosipl/data"
"strconv"
)
type listItem struct {
id string
count int // count multiplied by 100 to allow for half item purchases
}
type order struct {
name string
phone string
items []listItem
}
func parseFloat(input string) (int, error) {
val, err := strconv.ParseFloat(input, 64)
if err != nil {
return 0, fmt.Errorf("Invalid float format")
}
if val < 0 || val > 100 {
return 0, fmt.Errorf("Value must be between 0 and 100")
}
doubled := val * 2
if math.Abs(doubled-math.Round(doubled)) > 1e-9 {
return 0, fmt.Errorf("Value must be a multiple of 0.5")
}
return int(math.Round(val * 100)), nil
}
func parseOrder(r *http.Request) (order, error) {
var o order
var err error
var errorList []error
o.name = r.PostFormValue("name")
if o.name == "" {
errorList = append(errorList, fmt.Errorf("Invalid name"))
}
o.phone, err = parseAndValidatePolishMobile(r.PostFormValue("phone"))
if err != nil {
errorList = append(errorList, err)
}
for _, item := range data.Swieta {
count, err := parseFloat(r.PostFormValue(item.Id))
if err != nil {
errorList = append(errorList, fmt.Errorf("Can't parse the count for %v: %e", item.Name, err))
continue
}
if count%10 == 5 && !item.Halveable {
errorList = append(errorList, fmt.Errorf("This item can't be bought in fractions %v", item.Name))
continue
}
o.items = append(o.items, listItem{item.Id, count})
}
return o, errors.Join(errorList...)
}
func OrderHandler(w http.ResponseWriter, r *http.Request) {
o, err := parseOrder(r)
log.Println(o, err)
fmt.Fprintf(w, "%v, %v", o, err)
}

View file

@ -0,0 +1,57 @@
package orders
import (
"fmt"
"regexp"
"strings"
)
func isValidPolishMobile(nineDigitNum string) bool {
if len(nineDigitNum) != 9 {
return false
}
firstDigit := nineDigitNum[0]
if firstDigit < '4' || firstDigit > '8' {
return false
}
prefix2 := nineDigitNum[:2]
validPrefixes := map[string]bool{
"45": true,
"50": true, "51": true, "53": true, "57": true,
"60": true, "66": true, "69": true,
"72": true, "73": true, "78": true, "79": true,
"88": true,
}
return validPrefixes[prefix2]
}
func parseAndValidatePolishMobile(input string) (string, error) {
input = strings.TrimSpace(input)
if strings.HasPrefix(input, "+48") {
input = strings.TrimPrefix(input, "+48")
} else if strings.HasPrefix(input, "0048") {
input = strings.TrimPrefix(input, "0048")
}
re := regexp.MustCompile(`\D`)
cleaned := re.ReplaceAllString(input, "")
if len(cleaned) == 11 && strings.HasPrefix(cleaned, "48") {
cleaned = cleaned[2:]
}
if len(cleaned) != 9 {
return "", fmt.Errorf("invalid length: expected 9 digits, got %d", len(cleaned))
}
if !isValidPolishMobile(cleaned) {
return "", fmt.Errorf("invalid mobile prefix: %s does not match Polish mobile allocations", cleaned[:2])
}
return cleaned, nil
}