242 lines
6.2 KiB
Go
242 lines
6.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"gestion/db"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// GetCommandStatus - Statut temps réel d'une commande
|
|
func GetCommandStatus(c *gin.Context) {
|
|
database := c.MustGet("database").(*db.Database)
|
|
|
|
username, exists := c.Get("username")
|
|
if !exists {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Authentification requise"})
|
|
return
|
|
}
|
|
|
|
usernameStr := username.(string)
|
|
|
|
commandID, err := strconv.Atoi(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "ID invalide"})
|
|
return
|
|
}
|
|
|
|
command, err := database.GetCommandByID(commandID)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Commande non trouvée"})
|
|
return
|
|
}
|
|
|
|
cmdUsername, _ := command["username"].(string)
|
|
if cmdUsername != usernameStr {
|
|
log.Printf("❌ [STATUS] Accès refusé - cmd de %s demandée par %s", cmdUsername, usernameStr)
|
|
c.JSON(http.StatusForbidden, gin.H{
|
|
"error": "Cette commande ne vous appartient pas",
|
|
})
|
|
return
|
|
}
|
|
|
|
etaData, _ := database.GetCommandETA(commandID)
|
|
|
|
livreurInfo := gin.H{
|
|
"assigned": false,
|
|
}
|
|
if livreurAssign, ok := command["livreur_assign"].(string); ok && livreurAssign != "" {
|
|
queueInfo, _ := database.GetDeliverymanQueueInfo(livreurAssign)
|
|
livreurInfo = gin.H{
|
|
"assigned": true,
|
|
"livreur_name": livreurAssign,
|
|
"queue_position": queueInfo["queue_size"],
|
|
}
|
|
}
|
|
|
|
statusMessage := getStatusMessage(command["status"].(string))
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"command_id": commandID,
|
|
"status": command["status"],
|
|
"status_message": statusMessage,
|
|
"adresse": command["adresse"],
|
|
"total_prix": command["total_prix"],
|
|
"created_at": command["created_at"],
|
|
"livreur": livreurInfo,
|
|
"eta": etaData,
|
|
})
|
|
}
|
|
|
|
// GetMyCommandsWithTracking - Liste des commandes avec suivi
|
|
func GetMyCommandsWithTracking(c *gin.Context) {
|
|
database := c.MustGet("database").(*db.Database)
|
|
|
|
username, exists := c.Get("username")
|
|
if !exists {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Authentification requise"})
|
|
return
|
|
}
|
|
|
|
usernameStr := username.(string)
|
|
status := c.Query("status")
|
|
|
|
log.Printf("📋 [MY_CMDS] Client %s demande ses commandes (status=%s)", usernameStr, status)
|
|
|
|
commands, err := database.GetAllCommands(status, usernameStr)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"error": "Erreur récupération",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Enrichir avec tracking
|
|
enrichedCommands := make([]gin.H, len(commands))
|
|
for i, cmd := range commands {
|
|
commandID, _ := cmd["id"].(int)
|
|
|
|
// ETA
|
|
etaData, _ := database.GetCommandETA(commandID)
|
|
|
|
// Infos livreur
|
|
livreurInfo := gin.H{
|
|
"assigned": false,
|
|
}
|
|
if livreurAssign, ok := cmd["livreur_assign"].(string); ok && livreurAssign != "" {
|
|
queueInfo, _ := database.GetDeliverymanQueueInfo(livreurAssign)
|
|
livreurInfo = gin.H{
|
|
"assigned": true,
|
|
"livreur_name": livreurAssign,
|
|
"queue_position": queueInfo["queue_size"],
|
|
}
|
|
}
|
|
|
|
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"],
|
|
"total_prix": cmd["total_prix"],
|
|
"referral_used": cmd["referral_used"],
|
|
"created_at": cmd["created_at"],
|
|
"livreur": livreurInfo,
|
|
"eta": etaData,
|
|
"proposed_address": cmd["proposed_address"],
|
|
"address_proposal_status": cmd["address_proposal_status"],
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"commands": enrichedCommands,
|
|
"count": len(enrichedCommands),
|
|
})
|
|
}
|
|
|
|
// GetCommandTracking - Suivi détaillé d'une commande
|
|
func GetCommandTracking(c *gin.Context) {
|
|
database := c.MustGet("database").(*db.Database)
|
|
|
|
username := c.GetString("username")
|
|
commandID, err := strconv.Atoi(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "ID invalide"})
|
|
return
|
|
}
|
|
|
|
// Récupérer commande
|
|
command, err := database.GetCommandByID(commandID)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Commande non trouvée"})
|
|
return
|
|
}
|
|
|
|
// Vérifier propriété
|
|
cmdUsername, _ := command["username"].(string)
|
|
if cmdUsername != username {
|
|
c.JSON(http.StatusForbidden, gin.H{
|
|
"error": "Cette commande ne vous appartient pas",
|
|
})
|
|
return
|
|
}
|
|
|
|
logs, _ := database.GetCommandLogs(commandID)
|
|
|
|
etaData, _ := database.GetCommandETA(commandID)
|
|
|
|
timeline := buildTimeline(logs)
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"command_id": commandID,
|
|
"status": command["status"],
|
|
"status_message": getStatusMessage(command["status"].(string)),
|
|
"eta": etaData,
|
|
"timeline": timeline,
|
|
"logs": logs,
|
|
})
|
|
}
|
|
|
|
func getStatusMessage(status string) string {
|
|
messages := map[string]string{
|
|
"pending": "⏳ En attente d'assignation",
|
|
"assigned": "✅ Livreur assigné",
|
|
"en_route": "🚗 En cours de livraison",
|
|
"arrived": "📍 Livreur arrivé",
|
|
"livre": "📦 Livré - En attente de confirmation",
|
|
"delivered": "✅ Livré",
|
|
"approved": "🎉 Livraison confirmée",
|
|
"cancelled": "🚫 Annulée",
|
|
"disabled": "⚠️ Désactivée",
|
|
}
|
|
|
|
if msg, ok := messages[status]; ok {
|
|
return msg
|
|
}
|
|
return "📋 " + status
|
|
}
|
|
|
|
// buildTimeline construit une timeline depuis les logs
|
|
func buildTimeline(logs []map[string]any) []gin.H {
|
|
timeline := make([]gin.H, 0)
|
|
|
|
for _, logEntry := range logs {
|
|
status, _ := logEntry["status"].(string)
|
|
message, _ := logEntry["message"].(string)
|
|
createdAt, _ := logEntry["created_at"]
|
|
|
|
timeline = append(timeline, gin.H{
|
|
"status": status,
|
|
"message": message,
|
|
"icon": getStatusIcon(status),
|
|
"created_at": createdAt,
|
|
})
|
|
}
|
|
|
|
return timeline
|
|
}
|
|
|
|
// getStatusIcon retourne une icône pour la timeline
|
|
func getStatusIcon(status string) string {
|
|
icons := map[string]string{
|
|
"created": "🛒",
|
|
"assigned": "👤",
|
|
"en_route": "🚗",
|
|
"arrived": "📍",
|
|
"livre": "✅",
|
|
"approved": "🎉",
|
|
"cancelled": "🚫",
|
|
}
|
|
|
|
if icon, ok := icons[status]; ok {
|
|
return icon
|
|
}
|
|
return "📋"
|
|
}
|