// ============================================ // db/commands_history.go // ============================================ // Fonctions pour l'historique des commandes terminées package db import ( "database/sql" "fmt" "log" "maps" "time" ) // GetCompletedCommandsByUsername récupère toutes les commandes terminées (approved) d'un utilisateur func (d *Database) GetCompletedCommandsByUsername(username string) ([]map[string]any, error) { query := ` SELECT id, username, status, adresse, total_prix, livreur_assign, created_at, updated_at FROM commandes WHERE username = $1 AND status = 'approved' ORDER BY created_at DESC ` rows, err := d.Query(query, username) if err != nil { log.Printf("❌ [GetCompletedCommands] Erreur query: %v", err) return nil, fmt.Errorf("erreur lors de la récupération des commandes terminées: %w", err) } defer rows.Close() var commands []map[string]any for rows.Next() { var id int var username, status, adresse string var livreurAssign sql.NullString var totalPrix float64 var createdAt, updatedAt time.Time err := rows.Scan( &id, &username, &status, &adresse, &totalPrix, &livreurAssign, &createdAt, &updatedAt, ) if err != nil { log.Printf("❌ [GetCompletedCommands] Erreur scan: %v", err) return nil, fmt.Errorf("erreur lors du scan de la commande: %w", err) } command := map[string]any{ "id": id, "username": username, "status": status, "adresse": adresse, "total_prix": totalPrix, "created_at": createdAt, "updated_at": updatedAt, } if livreurAssign.Valid { command["livreur_assign"] = livreurAssign.String } else { command["livreur_assign"] = nil } commands = append(commands, command) } if err = rows.Err(); err != nil { log.Printf("❌ [GetCompletedCommands] Erreur itération: %v", err) return nil, fmt.Errorf("erreur lors de l'itération des résultats: %w", err) } return commands, nil } // GetCompletedCommandsWithItems récupère les commandes terminées avec leurs items func (d *Database) GetCompletedCommandsWithItems(username string) ([]map[string]any, error) { commands, err := d.GetCompletedCommandsByUsername(username) if err != nil { return nil, err } var enrichedCommands []map[string]any for _, command := range commands { commandID, ok := command["id"].(int) if !ok { continue } // Récupérer les items items, err := d.GetCommandItems(commandID) if err != nil { log.Printf("⚠️ [GetCompletedWithItems] Erreur items pour cmd %d: %v", commandID, err) items = []map[string]any{} } enrichedCommand := make(map[string]any) maps.Copy(enrichedCommand, command) enrichedCommand["items"] = items enrichedCommand["items_count"] = len(items) enrichedCommands = append(enrichedCommands, enrichedCommand) } return enrichedCommands, nil } // GetCommandsStatsByUsername récupère les statistiques des commandes d'un utilisateur func (d *Database) GetCommandsStatsByUsername(username string) (map[string]any, error) { query := ` SELECT COUNT(*) FILTER (WHERE status = 'approved') as approved_count, COUNT(*) FILTER (WHERE status = 'pending') as pending_count, COUNT(*) FILTER (WHERE status = 'assigned') as assigned_count, COUNT(*) FILTER (WHERE status = 'en_route') as en_route_count, COUNT(*) FILTER (WHERE status = 'livre') as livre_count, COUNT(*) FILTER (WHERE status = 'cancelled') as cancelled_count, COUNT(*) as total_count, COALESCE(SUM(total_prix) FILTER (WHERE status = 'approved'), 0) as total_spent FROM commandes WHERE username = $1 ` var approvedCount, pendingCount, assignedCount, enRouteCount, livreCount, cancelledCount, totalCount int var totalSpent float64 err := d.QueryRow(query, username).Scan( &approvedCount, &pendingCount, &assignedCount, &enRouteCount, &livreCount, &cancelledCount, &totalCount, &totalSpent, ) if err != nil { log.Printf("❌ [GetCommandsStats] Erreur: %v", err) return nil, fmt.Errorf("erreur lors de la récupération des statistiques: %w", err) } stats := map[string]any{ "approved_count": approvedCount, "pending_count": pendingCount, "assigned_count": assignedCount, "en_route_count": enRouteCount, "livre_count": livreCount, "cancelled_count": cancelledCount, "total_count": totalCount, "total_spent": totalSpent, } return stats, nil } // GetCommandsByStatus récupère les commandes d'un utilisateur par statut func (d *Database) GetCommandsByStatus(username, status string) ([]map[string]any, error) { log.Printf("📋 [GetCommandsByStatus] START - username=%s, status=%s", username, status) query := ` SELECT id, username, status, adresse, total_prix, livreur_assign, created_at, updated_at FROM commandes WHERE username = $1 AND status = $2 ORDER BY created_at DESC ` rows, err := d.Query(query, username, status) if err != nil { return nil, fmt.Errorf("erreur lors de la récupération des commandes: %w", err) } defer rows.Close() var commands []map[string]any for rows.Next() { var id int var username, status, adresse string var livreurAssign sql.NullString var totalPrix float64 var createdAt, updatedAt time.Time err := rows.Scan( &id, &username, &status, &adresse, &totalPrix, &livreurAssign, &createdAt, &updatedAt, ) if err != nil { log.Printf("❌ [GetCommandsByStatus] Erreur scan: %v", err) return nil, fmt.Errorf("erreur lors du scan: %w", err) } command := map[string]any{ "id": id, "username": username, "status": status, "adresse": adresse, "total_prix": totalPrix, "created_at": createdAt, "updated_at": updatedAt, } if livreurAssign.Valid { command["livreur_assign"] = livreurAssign.String } else { command["livreur_assign"] = nil } commands = append(commands, command) } if err = rows.Err(); err != nil { return nil, fmt.Errorf("erreur lors de l'itération: %w", err) } return commands, nil } // GetRecentCompletedOrders récupère les N dernières commandes terminées d'un utilisateur func (d *Database) GetRecentCompletedOrders(username string, limit int) ([]map[string]any, error) { query := ` SELECT id, username, status, adresse, total_prix, livreur_assign, created_at, updated_at FROM commandes WHERE username = $1 AND status = 'approved' ORDER BY created_at DESC LIMIT $2 ` rows, err := d.Query(query, username, limit) if err != nil { log.Printf("❌ [GetRecentCompleted] Erreur query: %v", err) return nil, fmt.Errorf("erreur lors de la récupération: %w", err) } defer rows.Close() var commands []map[string]any for rows.Next() { var id int var username, status, adresse string var livreurAssign sql.NullString var totalPrix float64 var createdAt, updatedAt time.Time err := rows.Scan( &id, &username, &status, &adresse, &totalPrix, &livreurAssign, &createdAt, &updatedAt, ) if err != nil { log.Printf("❌ [GetRecentCompleted] Erreur scan: %v", err) return nil, fmt.Errorf("erreur lors du scan: %w", err) } command := map[string]any{ "id": id, "username": username, "status": status, "adresse": adresse, "total_prix": totalPrix, "created_at": createdAt, "updated_at": updatedAt, } if livreurAssign.Valid { command["livreur_assign"] = livreurAssign.String } else { command["livreur_assign"] = nil } commands = append(commands, command) } if err = rows.Err(); err != nil { return nil, fmt.Errorf("erreur lors de l'itération: %w", err) } return commands, nil }