Files
projet_gestion_commande/backend/gestion/handlers/validation_deleviry.go
T
2026-05-14 19:33:39 +02:00

153 lines
4.3 KiB
Go

package handlers
import (
"fmt"
"gestion/db"
"log"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
// ============================================
// CONSTANTES DE CONFIGURATION
// ============================================
const (
// Distance maximale en mètres pour valider une livraison
MAX_DELIVERY_VALIDATION_DISTANCE_METERS = 100 // 100 mètres
// Distance maximale en kilomètres
MAX_DELIVERY_VALIDATION_DISTANCE_KM = 0.1 // 100 mètres = 0.1 km
)
// ============================================
// 3️⃣ DÉMARRER UNE LIVRAISON (PASSER EN IN_ROUTE)
// ============================================
// StartDelivery permet au livreur de démarrer une livraison (passage en in_transit)
// POST /api/v1/deliveries/:id/start
func StartDelivery(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
username, exists := c.Get("username")
if !exists || c.GetString("role") != "livreur" {
c.JSON(http.StatusForbidden, gin.H{"error": "Accès réservé aux livreurs"})
return
}
usernameStr := username.(string)
commandID, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "ID invalide"})
return
}
var req struct {
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Coordonnées GPS requises",
})
return
}
log.Printf("🚗 [START] %s démarre livraison cmd %d", usernameStr, commandID)
command, err := database.GetCommandByID(commandID)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Commande non trouvée"})
return
}
// Vérifier propriété
livreurAssign, _ := command["livreur_assign"].(string)
if livreurAssign != usernameStr {
c.JSON(http.StatusForbidden, gin.H{
"error": "Cette commande ne vous est pas assignée",
})
return
}
// Vérifier le statut actuel
currentStatus, _ := command["status"].(string)
if currentStatus != "assigned" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Impossible de démarrer cette livraison",
"current_status": currentStatus,
"message": "La commande doit être en statut 'assigned'",
})
return
}
// Mettre à jour le statut en "en_route"
if err := database.UpdateCommandStatus(commandID, "en_route"); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Erreur mise à jour statut",
})
return
}
// Mettre à jour la position du livreur
database.UpdateLivreurPosition(usernameStr, req.Latitude, req.Longitude, "busy")
// Mettre à jour le statut du livreur
database.SetDeliveryPersonStatus(usernameStr, "busy", commandID)
// Ajouter un log
database.AddCommandLog(commandID, "en_route",
fmt.Sprintf("Livraison démarrée par %s", usernameStr),
usernameStr)
// Notifier le client
if clientUsername, _ := command["username"].(string); clientUsername != "" {
var msg string
etaMinutes := 0
if etaData, err := database.GetCommandETA(commandID); err == nil {
if v, ok := etaData["total_eta_minutes"]; ok {
if n, err2 := strconv.Atoi(v); err2 == nil && n > 0 {
etaMinutes = n
}
}
}
if etaMinutes == 0 && req.Latitude != 0 && req.Longitude != 0 {
destLat, _ := command["dest_latitude"].(float64)
destLon, _ := command["dest_longitude"].(float64)
if destLat != 0 && destLon != 0 {
etaMinutes = database.CalculateETAForDeliveryman(usernameStr, destLat, destLon)
}
}
if etaMinutes > 0 {
var etaStr string
if etaMinutes >= 60 {
h := etaMinutes / 60
m := etaMinutes % 60
if m > 0 {
etaStr = fmt.Sprintf("%dh%02d", h, m)
} else {
etaStr = fmt.Sprintf("%dh", h)
}
} else {
etaStr = fmt.Sprintf("%d min", etaMinutes)
}
msg = fmt.Sprintf("Un livreur vient de prendre en charge ta commande #%d, il est en route (~%s)", database.GetClientOrderID(commandID), etaStr)
} else {
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)
}
log.Printf("✅ [START] Livraison %d démarrée", commandID)
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Livraison démarrée",
"command_id": commandID,
"status": "en_route",
})
}