Files
projet_gestion_commande/backend/gestion/handlers/zones.go
T
2026-03-03 23:42:23 +01:00

125 lines
3.0 KiB
Go

package handlers
import "regexp"
// ============================================================
// Zones de livraison — minimum de commande par code postal
// ============================================================
// Remplis les listes de codes postaux quand tu les as.
// Un code postal absent de toutes les zones → commande refusée.
// ============================================================
type deliveryZone struct {
Name string
MinAmount float64
codes map[string]struct{}
}
var deliveryZones = []deliveryZone{
{
Name: "Zone 30€",
MinAmount: 30.0,
codes: postalSet([]string{
"44000",
"44100",
"44200",
"44300",
}),
},
{
Name: "Zone 50€",
MinAmount: 50.0,
codes: postalSet([]string{
"44400", // Rezé
"44880", // Les Sorinières / Sautron
"44120", // Vertou
"44230", // Saint-Sébastien-sur-Loire
"44115", // Basse-Goulaine / Haute-Goulaine
"44980", // Sainte-Luce-sur-Loire
"44470", // Carquefou
"44240", // La Chapelle-sur-Erdre
"44700", // Orvault
"44800", // Saint-Herblain
"44340", // Bouguenais
"44620", // La Montagne
"44830", // Bouaye
}),
},
{
Name: "Zone 100€",
MinAmount: 100.0,
codes: postalSet([]string{
"44860", // Pont-Saint-Martin / Saint-Aignan-Grandlieu
"44220", // Couëron
"44118", // La Chevrolière
"44830", // Brains
"44710", // Saint-Léger-les-Vignes
"44690", // La Haie-Fouassière
"44470", // Mauves-sur-Loire
"44240", // Sucé-sur-Erdre
"44119", // Grandchamp-des-Fontaines
}),
},
}
var postalCodeRe = regexp.MustCompile(`\b(\d{5})\b`)
// postalSet convertit une slice de codes en set pour lookup O(1).
func postalSet(codes []string) map[string]struct{} {
m := make(map[string]struct{}, len(codes))
for _, c := range codes {
m[c] = struct{}{}
}
return m
}
// extractPostalCode extrait le premier code postal à 5 chiffres d'une adresse.
func extractPostalCode(address string) string {
m := postalCodeRe.FindStringSubmatch(address)
if len(m) < 2 {
return ""
}
return m[1]
}
// zoneCheckResult est le résultat de la vérification de zone.
type zoneCheckResult struct {
PostalCode string
ZoneName string
MinAmount float64
OK bool
}
// checkDeliveryZone vérifie si le total respecte le minimum de la zone de l'adresse.
// Code postal introuvable → OK = false (refus).
// Code postal hors de toutes les zones → OK = false (refus).
func checkDeliveryZone(deliveryAddress string, total float64) zoneCheckResult {
code := extractPostalCode(deliveryAddress)
if code == "" {
return zoneCheckResult{
PostalCode: "",
ZoneName: "inconnue",
MinAmount: 0,
OK: false,
}
}
for _, zone := range deliveryZones {
if _, found := zone.codes[code]; found {
return zoneCheckResult{
PostalCode: code,
ZoneName: zone.Name,
MinAmount: zone.MinAmount,
OK: total >= zone.MinAmount,
}
}
}
return zoneCheckResult{
PostalCode: code,
ZoneName: "hors zone",
MinAmount: 0,
OK: false,
}
}