chore: refacto

This commit is contained in:
2026-04-20 19:41:52 +02:00
parent 5fc52c72ee
commit 2e9827af98
46 changed files with 497 additions and 648 deletions
+6 -5
View File
@@ -2,6 +2,7 @@ package handlers
import (
"gestion/db"
"gestion/utils"
"net/http"
"github.com/gin-gonic/gin"
@@ -21,12 +22,12 @@ func AddAddress(c *gin.Context) {
InvalidAddress string `json:"invalid_address" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
utils.BindErr(c, err)
return
}
if err := database.AddAddress(req.CorrectAddress, req.InvalidAddress); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible d'ajouter l'adresse", err)
return
}
@@ -46,12 +47,12 @@ func DeleteAddress(c *gin.Context) {
InvalidAddress string `json:"invalid_address" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
utils.BindErr(c, err)
return
}
if err := database.DeleteAddress(req.InvalidAddress, req.CorrectAddress); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible de supprimer l'adresse", err)
return
}
@@ -68,7 +69,7 @@ func GetAllAddress(c *gin.Context) {
getAddress, err := database.AllAddress()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible de récupérer les adresses", err)
return
}
+13 -16
View File
@@ -2,6 +2,7 @@ package handlers
import (
"gestion/db"
"gestion/utils"
"net/http"
"strconv"
@@ -32,14 +33,13 @@ func AlertPolice(c *gin.Context) {
usernameStr := username.(string)
alert, err := database.CreateAlert(usernameStr, req.Message)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible de créer l'alerte", err)
return
}
// Notifier tous les admins/cabines en temps réel
go database.NotifyAllAdminCabineAlert(alert.ID, usernameStr, req.Message)
c.JSON(200, gin.H{
c.JSON(http.StatusCreated, gin.H{
"success": true,
"message": "Police alert created",
"alert_id": alert.ID,
@@ -61,13 +61,12 @@ func DeleteAlert(c *gin.Context) {
c.JSON(http.StatusForbidden, gin.H{"error": "Accès réservé aux livreurs"})
return
}
err = database.DeleteAlertPolicy(alertID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
if err = database.DeleteAlertPolicy(alertID); err != nil {
utils.ServerErr(c, "Impossible de supprimer l'alerte", err)
return
}
c.JSON(200, gin.H{
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Alert deleted",
})
@@ -89,11 +88,11 @@ func GetAlert(c *gin.Context) {
}
alert, err := database.GetAlertPolicy(alertID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
c.JSON(http.StatusNotFound, gin.H{"error": "Alerte non trouvée"})
return
}
c.JSON(200, gin.H{
c.JSON(http.StatusOK, gin.H{
"success": true,
"alert": alert,
})
@@ -124,7 +123,6 @@ func EndAlert(c *gin.Context) {
usernameStr := username.(string)
// Vérifier que l'alerte appartient bien à ce livreur
alert, err := database.GetAlertPolicy(alertID)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Alerte non trouvée"})
@@ -136,9 +134,8 @@ func EndAlert(c *gin.Context) {
return
}
err = database.EndAlert(alertID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de mettre fin à l'alerte", "details": err.Error()})
if err = database.EndAlert(alertID); err != nil {
utils.ServerErr(c, "Impossible de mettre fin à l'alerte", err)
return
}
@@ -169,7 +166,7 @@ func GetMyAlerts(c *gin.Context) {
alerts, err := database.GetAlertsByUsername(usernameStr)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de récupérer les alertes", "details": err.Error()})
utils.ServerErr(c, "Impossible de récupérer les alertes", err)
return
}
@@ -192,7 +189,7 @@ func GetAllAlerts(c *gin.Context) {
alerts, err := database.GetAllAlerts()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de récupérer les alertes", "details": err.Error()})
utils.ServerErr(c, "Impossible de récupérer les alertes", err)
return
}
@@ -214,7 +211,7 @@ func GetActiveAlerts(c *gin.Context) {
alerts, err := database.GetActiveAlerts()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de récupérer les alertes", "details": err.Error()})
utils.ServerErr(c, "Impossible de récupérer les alertes", err)
return
}
+1 -2
View File
@@ -77,7 +77,6 @@ func RegisterClient(c *gin.Context) {
log.Printf("❌ [REGISTER_CLIENT] Erreur binding: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
})
return
}
@@ -301,7 +300,7 @@ func ChangePassword(c *gin.Context) {
NewPassword string `json:"new_password" binding:"required,min=8"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Données invalides", "details": err.Error()})
utils.BindErr(c, err)
return
}
+1 -11
View File
@@ -85,7 +85,6 @@ func SetCommandDestinationCoordinates(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur stockage Redis",
"details": err.Error(),
})
return
}
@@ -217,7 +216,6 @@ func UpdateCommandAddressCabine(c *gin.Context) {
if err := database.UpdateCommandAddress(commandID, req.DeliveryAddress); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la mise à jour de l'adresse",
"details": err.Error(),
})
return
}
@@ -264,7 +262,6 @@ func GetLivreurPosition(c *gin.Context) {
"success": false,
"livreur": livreurUsername,
"message": "Position non disponible (GPS désactivé ou livraison terminée)",
"details": err.Error(),
})
return
}
@@ -394,7 +391,6 @@ func GetDeliveryIssues(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération problèmes",
"details": err.Error(),
})
return
}
@@ -431,7 +427,6 @@ func CreateDeliveryIssue(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur création problème",
"details": err.Error(),
})
return
}
@@ -468,7 +463,6 @@ func UpdateDeliveryIssue(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur mise à jour",
"details": err.Error(),
})
return
}
@@ -516,7 +510,6 @@ func AddDeliverySupport(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur ajout support",
"details": err.Error(),
})
return
}
@@ -540,7 +533,6 @@ func GetCommandLogs(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération logs",
"details": err.Error(),
})
return
}
@@ -580,7 +572,6 @@ func ForceValidateDelivery(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Raison requise pour validation forcée",
"details": err.Error(),
"example": gin.H{
"reason": "Client confirmé par téléphone",
},
@@ -632,7 +623,6 @@ func ForceValidateDelivery(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la validation forcée",
"details": err.Error(),
})
return
}
@@ -641,7 +631,7 @@ func ForceValidateDelivery(c *gin.Context) {
livreurAssign, _ := command["livreur_assign"].(string)
if clientUsername != "" {
clientMsg := fmt.Sprintf("Votre commande #%d a été livrée. Merci !", commandID)
clientMsg := fmt.Sprintf("Ta commande #%d a bien été livrée ! Bonne dégustation l'ami et à bientôt 😊", database.GetClientOrderID(commandID))
database.NotifyClient(clientUsername, commandID, "livre", clientMsg)
}
+9 -6
View File
@@ -339,19 +339,22 @@ func GetAllCancelledOrders(c *gin.Context) {
}
}
cancelReason, _ := order["cancel_reason"].(string)
enrichedOrder := map[string]any{
"id": order["id"],
"username": order["username"],
"total_prix": order["total_prix"],
"created_at": order["created_at"],
"updated_at": order["updated_at"],
"items_count": len(items),
"id": order["id"],
"username": order["username"],
"total_prix": order["total_prix"],
"created_at": order["created_at"],
"updated_at": order["updated_at"],
"items_count": len(items),
"cancel_reason": cancelReason,
}
if cancellationLog != nil {
enrichedOrder["cancellation"] = gin.H{
"cancelled_at": cancellationLog["created_at"],
"cancelled_by": cancellationLog["author"],
"reason": cancelReason,
}
}
+3 -3
View File
@@ -46,7 +46,7 @@ func CreateCategory(c *gin.Context) {
}
if err := db.ValidateCategoryColor(req.Color); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "Couleur invalide (format hex requis, ex: #ff0000)"})
return
}
@@ -91,7 +91,7 @@ func UpdateCategory(c *gin.Context) {
}
if err := db.ValidateCategoryColor(req.Color); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "Couleur invalide (format hex requis, ex: #ff0000)"})
return
}
@@ -121,7 +121,7 @@ func DeleteCategory(c *gin.Context) {
if err := database.DeleteCategory(id); err != nil {
log.Printf("❌ [CATEGORIES] Suppression erreur: %v", err)
if strings.Contains(err.Error(), "utilisée par") {
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
c.JSON(http.StatusConflict, gin.H{"error": "Catégorie utilisée par des produits existants"})
} else {
c.JSON(http.StatusNotFound, gin.H{"error": "Catégorie non trouvée"})
}
+2 -1
View File
@@ -6,6 +6,7 @@ import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
@@ -90,7 +91,6 @@ func GetMyCommandsWithTracking(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération",
"details": err.Error(),
})
return
}
@@ -118,6 +118,7 @@ func GetMyCommandsWithTracking(c *gin.Context) {
enrichedCommands[i] = gin.H{
"id": cmd["id"],
"client_order_number": cmd["client_order_number"],
"status": cmd["status"],
"status_message": getStatusMessage(cmd["status"].(string)),
"adresse": cmd["adresse"],
+18 -30
View File
@@ -81,7 +81,7 @@ func UpdateCommandAddress(c *gin.Context) {
// ✅ Récupération sécurisée du username
adminUsername, err := safeGetUsername(c)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
return
}
@@ -161,7 +161,7 @@ func ProposeAddressChange(c *gin.Context) {
staffUsername, err := safeGetUsername(c)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
return
}
@@ -198,15 +198,14 @@ func ProposeAddressChange(c *gin.Context) {
}
if err := database.ProposeAddressChange(commandID, req.ProposedAddress, staffUsername); err != nil {
log.Printf("❌ [PROPOSE_ADDR] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible de proposer l'adresse", err)
return
}
// Notifier le client
clientUsername, _ := command["username"].(string)
if clientUsername != "" {
msg := fmt.Sprintf("📍 Une nouvelle adresse de livraison vous est proposée pour la commande #%d : %s. Veuillez l'accepter ou la refuser dans le suivi de commande.", commandID, req.ProposedAddress)
msg := fmt.Sprintf("📍 Une nouvelle adresse de livraison vous est proposée pour votre commande #%d : %s. Veuillez l'accepter ou la refuser dans le suivi de commande.", database.GetClientOrderID(commandID), req.ProposedAddress)
database.NotifyClient(clientUsername, commandID, "address_proposal", msg)
}
@@ -248,8 +247,7 @@ func RespondToAddressProposal(c *gin.Context) {
}
if err := database.RespondToAddressProposal(commandID, clientUsername, req.Accepted); err != nil {
log.Printf("❌ [RESPOND_ADDR] Erreur: %v", err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible de traiter la réponse", err)
return
}
@@ -296,7 +294,6 @@ func GetAllCommands(c *gin.Context) {
log.Printf("❌ [GET_CMDS] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération des commandes",
"details": err.Error(),
})
return
}
@@ -444,7 +441,7 @@ func StaffApproveDelivery(c *gin.Context) {
totalPoints, pointCategory, clientUsername, err := database.ApproveDeliveryAtomicByStaff(commandID, staffUsername)
if err != nil {
log.Printf("❌ [STAFF_APPROVE] Erreur: %v", err)
c.JSON(http.StatusBadRequest, gin.H{"error": "Impossible de confirmer la réception: " + err.Error()})
utils.ServerErr(c, "Impossible de confirmer la réception", err)
return
}
@@ -474,7 +471,7 @@ func ValidateDelivery(c *gin.Context) {
adminUsername, err := safeGetUsername(c)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
return
}
@@ -604,7 +601,6 @@ func GetAvailableDeliveryPersons(c *gin.Context) {
log.Printf("❌ [GET_LIVREURS] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération des livreurs",
"details": err.Error(),
})
return
}
@@ -651,7 +647,6 @@ func AssignDeliveryPerson(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
})
return
}
@@ -665,7 +660,6 @@ func AssignDeliveryPerson(c *gin.Context) {
log.Printf("❌ [ASSIGN] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur assignation livreur",
"details": err.Error(),
})
return
}
@@ -704,7 +698,6 @@ func GetClientCommandsHistory(c *gin.Context) {
log.Printf("❌ [HISTORY] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération historique",
"details": err.Error(),
})
return
}
@@ -805,7 +798,7 @@ func NotifyClientToDescend(c *gin.Context) {
}
staffUsername, _ := c.Get("username")
msg := fmt.Sprintf("Votre commande #%d est prête ! Vous pouvez descendre la récupérer.", commandID)
msg := fmt.Sprintf("Votre commande #%d est prête ! Vous pouvez descendre la récupérer.", database.GetClientOrderID(commandID))
database.NotifyClient(clientUsername, commandID, "ready_pickup", msg)
database.AddCommandLog(commandID, "notification", fmt.Sprintf("Client notifié de descendre par %s", staffUsername), staffUsername.(string))
@@ -859,7 +852,6 @@ func ShowItems(c *gin.Context) {
log.Printf("❌ [ITEMS] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération des items",
"details": err.Error(),
})
return
}
@@ -951,7 +943,6 @@ func GetCommandItemsWithDetails(c *gin.Context) {
log.Printf("❌ [ITEMS_DETAILED] Erreur DB: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération items",
"details": err.Error(),
})
return
}
@@ -964,12 +955,13 @@ func GetCommandItemsWithDetails(c *gin.Context) {
}
commandInfo := map[string]interface{}{
"id": items[0]["command_id"],
"command_status": items[0]["command_status"],
"command_address": items[0]["command_address"],
"total_prix": items[0]["total_prix"],
"livreur_assign": items[0]["livreur_assign"],
"command_created_at": items[0]["command_created_at"],
"id": items[0]["command_id"],
"command_status": items[0]["command_status"],
"command_address": items[0]["command_address"],
"total_prix": items[0]["total_prix"],
"livreur_assign": items[0]["livreur_assign"],
"command_created_at": items[0]["command_created_at"],
"client_order_number": items[0]["client_order_number"],
}
c.JSON(http.StatusOK, gin.H{
@@ -1007,7 +999,6 @@ func UpdateItemStatus(c *gin.Context) {
log.Printf("❌ [UPD_ITEM] Erreur JSON: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Status requis",
"details": err.Error(),
})
return
}
@@ -1038,7 +1029,6 @@ func UpdateItemStatus(c *gin.Context) {
log.Printf("❌ [UPD_ITEM] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la mise à jour",
"details": err.Error(),
})
return
}
@@ -1065,7 +1055,7 @@ func DeleteCommandItem(c *gin.Context) {
adminUsername, err := safeGetUsername(c)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
return
}
@@ -1084,8 +1074,7 @@ func DeleteCommandItem(c *gin.Context) {
log.Printf("🗑️ [DEL_ITEM] Admin %s supprime item %d de cmd %d", adminUsername, itemID, commandID)
if err := database.DeleteCommandItem(commandID, itemID); err != nil {
log.Printf("❌ [DEL_ITEM] Erreur: %v", err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible de supprimer l'item", err)
return
}
@@ -1137,8 +1126,7 @@ func UpdateCommandStatusAdmin(c *gin.Context) {
}
if err := database.UpdateCommandStatus(commandID, req.Status); err != nil {
log.Printf("❌ [STATUS_ADMIN] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible de mettre à jour le statut", err)
return
}
+5 -8
View File
@@ -34,7 +34,6 @@ func GetMyDeliveries(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération",
"details": err.Error(),
})
return
}
@@ -190,7 +189,6 @@ func UpdateDeliveryStatus(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
})
return
}
@@ -261,7 +259,6 @@ func UpdateDeliveryStatus(c *gin.Context) {
if err := database.UpdateCommandStatus(commandID, req.Status); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur mise à jour",
"details": err.Error(),
})
return
}
@@ -361,16 +358,16 @@ func UpdateDeliveryStatus(c *gin.Context) {
} else {
etaStr = fmt.Sprintf("%d min", etaMinutes)
}
clientMsg = fmt.Sprintf("🛵 Votre commande #%d est en route ! Arrivée dans ~%s", commandID, etaStr)
clientMsg = fmt.Sprintf("Un livreur vient de prendre en charge ta commande #%d, il est en route (~%s)", database.GetClientOrderID(commandID), etaStr)
} else {
clientMsg = fmt.Sprintf("🛵 Votre commande #%d est en route !", commandID)
clientMsg = fmt.Sprintf("Un livreur vient de prendre en charge ta commande #%d, il est en route.", database.GetClientOrderID(commandID))
}
case "arrived":
clientMsg = fmt.Sprintf("🛵 Votre livreur est là ! Il sera chez vous dans 5 minutes (commande #%d)", commandID)
clientMsg = fmt.Sprintf("Descend, le livreur est là dans 3min (commande #%d) 🛵", database.GetClientOrderID(commandID))
case "livre":
clientMsg = fmt.Sprintf("Votre commande #%d a été livrée. Merci !", commandID)
clientMsg = fmt.Sprintf("Ta commande #%d a bien été livrée ! Bonne dégustation l'ami et à bientôt 😊", database.GetClientOrderID(commandID))
case "cancelled":
clientMsg = fmt.Sprintf("Votre commande #%d a été annulée par le livreur", commandID)
clientMsg = fmt.Sprintf("Votre commande #%d a été annulée par le livreur", database.GetClientOrderID(commandID))
}
if clientMsg != "" {
database.NotifyClient(clientUsername, commandID, req.Status, clientMsg)
@@ -40,7 +40,6 @@ func GetDeliveryPersonDetails(c *gin.Context) {
log.Printf("❌ [GET_DELIVERY_DETAILS] Livreur non trouvé: %v", err)
c.JSON(http.StatusNotFound, gin.H{
"error": "Livreur non trouvé",
"details": err.Error(),
})
return
}
@@ -118,7 +117,6 @@ func UpdateDeliveryPersonStatusAdmin(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Statut requis",
"details": err.Error(),
})
return
}
@@ -163,7 +161,6 @@ func UpdateDeliveryPersonStatusAdmin(c *gin.Context) {
log.Printf("❌ [UPDATE_DELIVERY_STATUS] Erreur mise à jour: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur mise à jour statut",
"details": err.Error(),
})
return
}
@@ -325,7 +322,6 @@ func GetDeliveryPersonHistory(c *gin.Context) {
log.Printf("❌ [GET_DELIVERY_HISTORY] Erreur récupération: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération historique",
"details": err.Error(),
})
return
}
@@ -373,7 +369,6 @@ func UpdateDeliveryPersonLocationAdmin(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Coordonnées GPS requises",
"details": err.Error(),
})
return
}
@@ -421,7 +416,6 @@ func UpdateDeliveryPersonLocationAdmin(c *gin.Context) {
log.Printf("❌ [UPDATE_DELIVERY_LOCATION] Erreur mise à jour: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur mise à jour position",
"details": err.Error(),
})
return
}
@@ -515,7 +509,6 @@ func RemoveCommandFromQueue(c *gin.Context) {
log.Printf("❌ [REMOVE_FROM_QUEUE] Erreur suppression: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur suppression de la queue",
"details": err.Error(),
})
return
}
+23 -77
View File
@@ -21,34 +21,24 @@ import (
// GÉOCODAGE D'ADRESSES
// ============================================
// GeocodeAddress convertit une adresse en coordonnées GPS
func GeocodeAddress(c *gin.Context) {
geoService := c.MustGet("geoService").(*services.GeoService)
var req struct {
Address string `json:"address" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Adresse requise",
"details": err.Error(),
})
c.JSON(http.StatusBadRequest, gin.H{"error": "Adresse requise"})
return
}
location, err := geoService.GeocodeAddress(req.Address)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Impossible de géocoder cette adresse",
"details": err.Error(),
})
c.JSON(http.StatusNotFound, gin.H{"error": "Impossible de géocoder cette adresse"})
return
}
log.Printf("📍 Adresse géocodée: %s -> (%.6f, %.6f)",
req.Address, location.Latitude, location.Longitude)
log.Printf("📍 Adresse géocodée: %s -> (%.6f, %.6f)", req.Address, location.Latitude, location.Longitude)
c.JSON(http.StatusOK, gin.H{
"success": true,
"latitude": location.Latitude,
@@ -76,8 +66,7 @@ func FindNearestDeliveryPerson(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
"error": "Données invalides",
})
return
}
@@ -89,8 +78,7 @@ func FindNearestDeliveryPerson(c *gin.Context) {
location, err := geoService.GeocodeAddress(req.Address)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Impossible de géocoder l'adresse",
"details": err.Error(),
"error": "Impossible de géocoder l'adresse",
})
return
}
@@ -110,8 +98,7 @@ func FindNearestDeliveryPerson(c *gin.Context) {
// Valider les coordonnées
if err := services.ValidateCoordinates(targetCoords); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Coordonnées invalides",
"details": err.Error(),
"error": "Coordonnées invalides",
})
return
}
@@ -135,8 +122,7 @@ func FindNearestDeliveryPerson(c *gin.Context) {
nearest, err := geoService.FindNearestDeliveryPersonFast(targetCoords, usernames)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Aucun livreur avec position GPS valide",
"details": err.Error(),
"error": "Aucun livreur avec position GPS valide",
})
return
}
@@ -193,8 +179,7 @@ func GetAllDeliveryDistances(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
"error": "Données invalides",
})
return
}
@@ -205,8 +190,7 @@ func GetAllDeliveryDistances(c *gin.Context) {
location, err := geoService.GeocodeAddress(req.Address)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Impossible de géocoder l'adresse",
"details": err.Error(),
"error": "Impossible de géocoder l'adresse",
})
return
}
@@ -224,8 +208,7 @@ func GetAllDeliveryDistances(c *gin.Context) {
if err := services.ValidateCoordinates(targetCoords); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Coordonnées invalides",
"details": err.Error(),
"error": "Coordonnées invalides",
})
return
}
@@ -246,8 +229,7 @@ func GetAllDeliveryDistances(c *gin.Context) {
distances, err := geoService.GetAllDeliveryDistances(targetCoords, usernames)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur calcul des distances",
"details": err.Error(),
"error": "Erreur calcul des distances",
})
return
}
@@ -317,7 +299,6 @@ func AutoAssignNearestDeliveryPerson(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Impossible de géocoder l'adresse de livraison",
"address": address,
"details": err.Error(),
})
return
}
@@ -375,8 +356,7 @@ func AutoAssignNearestDeliveryPerson(c *gin.Context) {
travelTime, distance, err := calculateTravelTimeWithTomTom(geoService, singleDeliveryman, location.Latitude, location.Longitude)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur calcul ETA",
"details": err.Error(),
"error": "Erreur calcul ETA",
})
return
}
@@ -385,8 +365,7 @@ func AutoAssignNearestDeliveryPerson(c *gin.Context) {
err = database.AssignCommandToDeliverymanQueueWithCoords(commandID, singleDeliveryman, travelTime, location.Latitude, location.Longitude, address)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de l'assignation",
"details": err.Error(),
"error": "Erreur lors de l'assignation",
})
return
}
@@ -440,8 +419,7 @@ func AutoAssignNearestDeliveryPerson(c *gin.Context) {
travelTime, distance, err := calculateTravelTimeWithTomTom(geoService, leastLoaded, location.Latitude, location.Longitude)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur calcul ETA",
"details": err.Error(),
"error": "Erreur calcul ETA",
})
return
}
@@ -450,8 +428,7 @@ func AutoAssignNearestDeliveryPerson(c *gin.Context) {
err = database.ForceAssignCommandToDeliverymanWithCoords(commandID, leastLoaded, travelTime, location.Latitude, location.Longitude, address)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de l'assignation forcée",
"details": err.Error(),
"error": "Erreur lors de l'assignation forcée",
})
return
}
@@ -506,8 +483,7 @@ func AutoAssignNearestDeliveryPerson(c *gin.Context) {
nearest, err := geoService.FindNearestDeliveryPersonFast(targetCoords, usernames)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Aucun livreur avec position GPS valide",
"details": err.Error(),
"error": "Aucun livreur avec position GPS valide",
})
return
}
@@ -527,8 +503,7 @@ func AutoAssignNearestDeliveryPerson(c *gin.Context) {
err = database.AssignCommandToDeliverymanQueueWithCoords(commandID, nearest.Username, travelTime, location.Latitude, location.Longitude, address)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de l'assignation",
"details": err.Error(),
"error": "Erreur lors de l'assignation",
})
return
}
@@ -582,8 +557,7 @@ func AutoAssignAllPendingCommands(c *gin.Context) {
commands, err := database.GetAllCommands("pending", "")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération des commandes",
"details": err.Error(),
"error": "Erreur récupération des commandes",
})
return
}
@@ -742,8 +716,7 @@ func GetAllDeliveryQueues(c *gin.Context) {
overview, err := database.GetAllQueuesOverview()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération des queues",
"details": err.Error(),
"error": "Erreur récupération des queues",
})
return
}
@@ -802,8 +775,7 @@ func GetDeliverymanQueue(c *gin.Context) {
queueInfo, err := database.GetDeliverymanQueueInfo(username)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération de la queue",
"details": err.Error(),
"error": "Erreur récupération de la queue",
})
return
}
@@ -814,41 +786,23 @@ func GetDeliverymanQueue(c *gin.Context) {
})
}
// ============================================
// VALIDATION D'ADRESSE
// ============================================
// ValidateAddress vérifie si une adresse peut être géocodée
// POST /api/v1/validate-address
// Body: {"address": "123 Main St, Paris"}
func ValidateAddress(c *gin.Context) {
geoService := c.MustGet("geoService").(*services.GeoService)
var req struct {
Address string `json:"address" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Adresse requise",
"details": err.Error(),
})
c.JSON(http.StatusBadRequest, gin.H{"error": "Adresse requise"})
return
}
isValid := geoService.IsValidAddress(req.Address)
if !isValid {
c.JSON(http.StatusOK, gin.H{
"valid": false,
"message": "Adresse introuvable ou invalide",
})
if !geoService.IsValidAddress(req.Address) {
c.JSON(http.StatusOK, gin.H{"valid": false, "message": "Adresse introuvable ou invalide"})
return
}
// Récupérer les détails
location, _ := geoService.GeocodeAddress(req.Address)
c.JSON(http.StatusOK, gin.H{
"valid": true,
"message": "Adresse valide",
@@ -858,13 +812,7 @@ func ValidateAddress(c *gin.Context) {
})
}
// ============================================
// HELPER FUNCTION - CALCUL ETA AVEC TOMTOM
// ============================================
// calculateTravelTimeWithTomTom calcule l'ETA avec TomTom ou fallback local
func calculateTravelTimeWithTomTom(geoService *services.GeoService, deliverymanUsername string, targetLat, targetLon float64) (int, float64, error) {
// Récupérer position du livreur
deliverymanLoc, err := geoService.GetDeliveryPersonLocation(deliverymanUsername)
if err != nil {
return 0, 0, fmt.Errorf("position du livreur introuvable: %w", err)
@@ -875,10 +823,8 @@ func calculateTravelTimeWithTomTom(geoService *services.GeoService, deliverymanU
Longitude: targetLon,
}
// Calculer ETA avec TomTom (avec fallback automatique intégré)
travelTime, distance, err := services.GetETAWithTraffic(*deliverymanLoc, targetCoords)
if err != nil {
// Fallback sur calcul local
distance = services.CalculateDistance(*deliverymanLoc, targetCoords)
travelTime = services.CalculateETA(distance)
log.Printf("⚠️ TomTom indisponible pour %s, fallback: %.2f km -> %d min",
+1 -2
View File
@@ -13,6 +13,7 @@ import (
"net/url"
"strconv"
"github.com/gin-gonic/gin"
)
@@ -43,7 +44,6 @@ func GetDeliveryPersonMapLinks(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
"error": "Position GPS non disponible pour ce livreur",
"details": err.Error(),
"message": "Le livreur n'a pas encore partagé sa position ou est hors ligne",
})
return
@@ -117,7 +117,6 @@ func GetCommandNavigationLinks(c *gin.Context) {
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur génération des liens",
"details": err.Error(),
})
return
}
+1 -2
View File
@@ -12,6 +12,7 @@ import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
@@ -41,7 +42,6 @@ func GetMyCompletedOrders(c *gin.Context) {
log.Printf("❌ [HISTORY] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération de l'historique",
"details": err.Error(),
})
return
}
@@ -120,7 +120,6 @@ func GetMyCompletedOrdersWithItems(c *gin.Context) {
log.Printf("❌ [HISTORY_DETAILED] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération de l'historique",
"details": err.Error(),
})
return
}
+23 -38
View File
@@ -9,6 +9,7 @@ import (
"gestion/db"
"gestion/models"
"gestion/services"
"gestion/utils"
"log"
"net/http"
@@ -32,7 +33,7 @@ func AddProductsBasket(c *gin.Context) {
var req BasketsRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Requête invalide", "details": err.Error()})
utils.BindErr(c, err)
return
}
@@ -62,17 +63,17 @@ func AddProductsBasket(c *gin.Context) {
}
if err := database.DecrementProductStockByID(req.ProductID, req.Quantity); err != nil {
log.Printf("❌ [ADD_PANIER] Erreur décrement stock product_id=%d: %v", req.ProductID, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible d'ajouter le produit au panier", "details": err.Error()})
utils.ServerErr(c, "Impossible d'ajouter le produit au panier", err)
return
}
panier, err := database.AddProductInBasketByID(req.Username, req.ProductID, req.Quantity)
if err != nil {
log.Printf("❌ [ADD_PANIER] Erreur ajout product_id=%d qty=%.3f: %v", req.ProductID, req.Quantity, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible d'ajouter le produit au panier", "details": err.Error()})
utils.ServerErr(c, "Impossible d'ajouter le produit au panier", err)
return
}
c.JSON(http.StatusCreated, gin.H{"success": true, "message": "Produit ajouté au panier avec succès", "panier": panier})
c.JSON(http.StatusOK, gin.H{"success": true, "message": "Produit ajouté au panier avec succès", "panier": panier})
return
}
@@ -128,11 +129,7 @@ func GetAllBaskets(c *gin.Context) {
baskets, err := database.GetAllProductsInBasket(username)
if err != nil {
log.Printf("❌ [GET_PANIER] Erreur récupération: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération du panier",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la récupération du panier", err)
return
}
@@ -165,11 +162,7 @@ func DeleteProductFromBasket(c *gin.Context) {
}
if err := c.ShouldBindJSON(&req); err != nil {
log.Printf("❌ [DEL_PANIER] Erreur JSON: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données requises manquantes",
"details": err.Error(),
})
utils.BindErr(c, err)
return
}
@@ -211,11 +204,7 @@ func DeleteProductFromBasket(c *gin.Context) {
// Supprimer l'article
err = database.DeleteProductFromBasket(req.ID)
if err != nil {
log.Printf("❌ [DEL_PANIER] Erreur suppression: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la suppression",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la suppression", err)
return
}
@@ -259,11 +248,7 @@ func ClearBasket(c *gin.Context) {
err = database.ClearBasket(authUsernameStr)
if err != nil {
log.Printf("❌ [CLEAR_PANIER] Erreur vidage: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors du vidage du panier",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors du vidage du panier", err)
return
}
@@ -305,7 +290,7 @@ func ValidateBasket(c *gin.Context) {
cmd := &models.Command{DeliveryAddress: req.DeliveryAddress}
if err := database.CheckAddress(cmd); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(), "corrected_address": cmd.DeliveryAddress})
c.JSON(http.StatusBadRequest, gin.H{"error": "Adresse non reconnue", "corrected_address": cmd.DeliveryAddress})
return
}
req.DeliveryAddress = cmd.DeliveryAddress
@@ -323,8 +308,7 @@ func ValidateBasket(c *gin.Context) {
// ============================================
items, err := database.GetBasketItems(usernameStr)
if err != nil {
log.Printf("❌ [CHECKOUT] Erreur récupération panier: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de récupérer le panier", "details": err.Error()})
utils.ServerErr(c, "Impossible de récupérer le panier", err)
return
}
@@ -487,7 +471,7 @@ func ValidateBasket(c *gin.Context) {
_, _ = database.CreateCryptoPayment(commandID, payResp.PaymentID.String(), payResp.Status, payResp.PriceCurrency, payResp.PayCurrency, payResp.PayAddress, priceAmt, payAmt)
log.Printf("✅ [CHECKOUT] Commande %d en attente paiement crypto (%s)", commandID, req.PayCurrency)
c.JSON(http.StatusOK, gin.H{
c.JSON(http.StatusCreated, gin.H{
"success": true,
"command_id": commandID,
"payment_method": "crypto",
@@ -510,8 +494,7 @@ func ValidateBasket(c *gin.Context) {
// ============================================
err = database.ClearBasket(usernameStr)
if err != nil {
log.Printf("❌ [CHECKOUT] Erreur vidage panier: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de vider le panier", "details": err.Error()})
utils.ServerErr(c, "Impossible de vider le panier", err)
return
}
log.Printf("🧹 [CHECKOUT] Panier vidé")
@@ -585,7 +568,8 @@ func ValidateBasket(c *gin.Context) {
}
// Notifier le client
clientMsg := fmt.Sprintf("Votre commande #%d est confirmée ! Un livreur est en route.", commandID)
clientOrderID := database.GetClientOrderID(commandID)
clientMsg := fmt.Sprintf("Ta commande #%d est prise en compte ! Merci de rester branché et vigilant sur les notifs à venir.", clientOrderID)
database.NotifyClient(usernameStr, commandID, "assigned", clientMsg)
assigned = true
@@ -611,12 +595,13 @@ func ValidateBasket(c *gin.Context) {
// ============================================
newBalance, _ := database.GetClientReferralBalance(usernameStr)
resp := gin.H{
"success": true,
"command_id": commandID,
"delivery_address": req.DeliveryAddress,
"status": "pending",
"referral_used": referralUsed,
"referral_balance": newBalance,
"success": true,
"command_id": commandID,
"client_order_number": command.ClientOrderID,
"delivery_address": req.DeliveryAddress,
"status": "pending",
"referral_used": referralUsed,
"referral_balance": newBalance,
}
if assigned {
@@ -631,7 +616,7 @@ func ValidateBasket(c *gin.Context) {
log.Printf("✅ [CHECKOUT] Réponse 200 - Commande %d en attente", commandID)
}
c.JSON(http.StatusOK, resp)
c.JSON(http.StatusCreated, resp)
}
// getBaseURL construit l'URL de base depuis la requête en cours
+18 -68
View File
@@ -10,6 +10,7 @@ import (
"fmt"
"gestion/db"
"gestion/services"
"gestion/utils"
"log"
"net/http"
"strconv"
@@ -94,10 +95,7 @@ func AutoAssignNextCommand(c *gin.Context) {
err = database.AutoAssignCommand(nextCommand.CommandID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de l'assignation automatique",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de l'assignation automatique", err)
return
}
@@ -137,12 +135,8 @@ func UpdateLivreurLocation(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides - latitude et longitude requises",
"details": err.Error(),
"format": gin.H{
"latitude": "number (required)",
"longitude": "number (required)",
},
"error": "Données invalides - latitude et longitude requises",
"format": gin.H{"latitude": "number (required)", "longitude": "number (required)"},
})
return
}
@@ -169,10 +163,7 @@ func UpdateLivreurLocation(c *gin.Context) {
// ✅ 1. Mettre à jour la position GPS dans Redis
err := database.UpdateDeliveryPersonLocation(usernameStr, req.Latitude, req.Longitude)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la mise à jour de la position",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la mise à jour de la position", err)
return
}
@@ -251,7 +242,6 @@ func GetMyLocation(c *gin.Context) {
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Position non disponible",
"details": err.Error(),
"message": "Veuillez d'abord mettre à jour votre position",
})
return
@@ -286,10 +276,7 @@ func GetDeliveryPersonLocation(c *gin.Context) {
position, err := database.GetLivreurPosition(username)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Position non trouvée pour ce livreur",
"details": err.Error(),
})
c.JSON(http.StatusNotFound, gin.H{"error": "Position non trouvée pour ce livreur"})
return
}
@@ -373,7 +360,6 @@ func GetDeliverymanLocationForCommand(c *gin.Context) {
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Position du livreur non disponible",
"details": err.Error(),
"message": "Le livreur n'a pas encore partagé sa position",
"command_info": gin.H{
"command_id": commandID,
@@ -501,10 +487,7 @@ func UpdateDeliveryPersonStatus(c *gin.Context) {
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
})
utils.BindErr(c, err)
return
}
@@ -531,10 +514,7 @@ func UpdateDeliveryPersonStatus(c *gin.Context) {
err := database.SetDeliveryPersonStatus(usernameStr, req.Status, 0)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la mise à jour du statut",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la mise à jour du statut", err)
return
}
@@ -613,10 +593,7 @@ func GetMyQueue(c *gin.Context) {
queueInfo, err := database.GetDeliverymanQueueInfo(usernameStr)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur récupération de la queue",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur récupération de la queue", err)
return
}
@@ -640,10 +617,7 @@ func GetAvailableDeliveryPersonsRealtime(c *gin.Context) {
livreurs, err := database.GetAvailableDeliveryPersonsRedis()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération des livreurs",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la récupération des livreurs", err)
return
}
@@ -687,10 +661,7 @@ func SetCommandETAHandler(c *gin.Context) {
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
})
utils.BindErr(c, err)
return
}
@@ -724,10 +695,7 @@ func SetCommandETAHandler(c *gin.Context) {
// Mettre à jour l'ETA dans Redis
err = database.SetCommandETA(commandID, req.ETAMinutes)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la mise à jour de l'ETA",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la mise à jour de l'ETA", err)
return
}
@@ -830,10 +798,7 @@ func GetMyPenalties(c *gin.Context) {
// ✅ UTILISE LA MÉTHODE DÉDIÉE GetClientPenaltiesInfo
penaltiesInfo, err := database.GetClientPenaltiesInfo(usernameStr)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération des pénalités",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la récupération des pénalités", err)
return
}
@@ -869,10 +834,7 @@ func GetClientPenaltiesAdmin(c *gin.Context) {
// ✅ UTILISE GetClientPenaltiesInfo
penaltiesInfo, err := database.GetClientPenaltiesInfo(username)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération des pénalités",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la récupération des pénalités", err)
return
}
@@ -896,10 +858,7 @@ func GetAllClientsWithPenalties(c *gin.Context) {
// ✅ UTILISE GetAllClientsWithPenalties
clients, err := database.GetAllClientsWithPenalties()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération des clients",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la récupération des clients", err)
return
}
@@ -926,10 +885,7 @@ func GetPenaltiesStats(c *gin.Context) {
// ✅ UTILISE GetClientPenaltiesStats
stats, err := database.GetClientPenaltiesStats()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la récupération des statistiques",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la récupération des statistiques", err)
return
}
@@ -970,10 +926,7 @@ func ResetClientPointAdmin(c *gin.Context) {
err := database.ResetClientPoint(username, req.Pool, extraPoolKey)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la réinitialisation",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la réinitialisation", err)
return
}
@@ -1008,10 +961,7 @@ func ResetClientPenaltiesAdmin(c *gin.Context) {
// ✅ UTILISE ResetClientPenalties
err := database.ResetClientPenalties(username, req.ResetCancellationsCount)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur lors de la réinitialisation",
"details": err.Error(),
})
utils.ServerErr(c, "Erreur lors de la réinitialisation", err)
return
}
+4 -4
View File
@@ -2,6 +2,7 @@ package handlers
import (
"gestion/db"
"gestion/utils"
"log"
"net/http"
@@ -26,7 +27,7 @@ func GetMyReferralBalance(c *gin.Context) {
balance, err := database.GetClientReferralBalance(username.(string))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
c.JSON(http.StatusNotFound, gin.H{"error": "Solde de parrainage introuvable"})
return
}
@@ -47,8 +48,7 @@ func CreditClientReferralAdmin(c *gin.Context) {
}
if err := database.CreditClientReferral(targetUsername, req.Amount); err != nil {
log.Printf("❌ [REFERRAL] Crédit échoué pour %s: %v", targetUsername, err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
utils.ServerErr(c, "Impossible de créditer le solde", err)
return
}
@@ -68,7 +68,7 @@ func GetClientReferralAdmin(c *gin.Context) {
balance, err := database.GetClientReferralBalance(targetUsername)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
c.JSON(http.StatusNotFound, gin.H{"error": "Client introuvable"})
return
}
+1
View File
@@ -38,6 +38,7 @@ func GetPublicSettings(c *gin.Context) {
"pool_names": poolNames,
"pool_keys": poolKeys,
"referral_enabled": settings.ReferralEnabled,
"referral_amount": settings.ReferralAmount,
"delivery_schedule": settings.DeliverySchedule,
"crypto_payment_enabled": settings.CryptoPaymentEnabled,
"crypto_only": settings.CryptoOnly,
@@ -34,7 +34,6 @@ func UpdateMyProfile(c *gin.Context) {
log.Printf("❌ [UPDATE_MY_PROFILE] Erreur binding: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
})
return
}
@@ -186,7 +185,6 @@ func UpdateClientByAdmin(c *gin.Context) {
log.Printf("❌ [UPDATE_CLIENT_ADMIN] Erreur binding: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
"details": err.Error(),
})
return
}
@@ -9,6 +9,7 @@ import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
@@ -56,7 +57,6 @@ func ValidateDeliveryByLivreur(c *gin.Context) {
log.Printf("❌ [VALIDATE_LIVREUR] Erreur JSON: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Coordonnées GPS requises",
"details": err.Error(),
})
return
}
@@ -99,7 +99,6 @@ func ValidateDeliveryByLivreur(c *gin.Context) {
log.Printf("❌ [VALIDATE_LIVREUR] Erreur update statut: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur validation",
"details": err.Error(),
})
return
}
@@ -299,7 +298,6 @@ func StartDelivery(c *gin.Context) {
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Coordonnées GPS requises",
"details": err.Error(),
})
return
}
@@ -336,7 +334,6 @@ func StartDelivery(c *gin.Context) {
if err := database.UpdateCommandStatus(commandID, "en_route"); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur mise à jour statut",
"details": err.Error(),
})
return
}
@@ -354,7 +351,7 @@ func StartDelivery(c *gin.Context) {
// Notifier le client
if clientUsername, _ := command["username"].(string); clientUsername != "" {
msg := fmt.Sprintf("🛵 Votre commande #%d est en route !", commandID)
msg := fmt.Sprintf("Un livreur vient de prendre en charge ta commande #%d, il est en route.", database.GetClientOrderID(commandID))
database.NotifyClient(clientUsername, commandID, "en_route", msg)
}