chore: update id order
This commit is contained in:
+139
-244
@@ -1,46 +1,24 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GetAvailableDeliveryPersons récupère tous les livreurs disponibles
|
||||
func (d *Database) GetAvailableDeliveryPersons() ([]map[string]any, error) {
|
||||
query := `SELECT id, username, total, livraison
|
||||
FROM users
|
||||
WHERE role = 'livreur'
|
||||
ORDER BY username`
|
||||
|
||||
rows, err := d.Query(query)
|
||||
var livreurs []map[string]any
|
||||
err := d.GDB.Raw(`
|
||||
SELECT id, username, total, livraison
|
||||
FROM users
|
||||
WHERE role = 'livreur'
|
||||
ORDER BY username`).Scan(&livreurs).Error
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("erreur lors de la récupération des livreurs: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var livreurs []map[string]any
|
||||
for rows.Next() {
|
||||
var id int
|
||||
var username string
|
||||
var total, livraison float64
|
||||
|
||||
err := rows.Scan(&id, &username, &total, &livraison)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("erreur lors du scan du livreur: %w", err)
|
||||
}
|
||||
|
||||
livreur := map[string]any{
|
||||
"id": id,
|
||||
"username": username,
|
||||
"total": total,
|
||||
"livraison": livraison,
|
||||
}
|
||||
livreurs = append(livreurs, livreur)
|
||||
}
|
||||
|
||||
return livreurs, nil
|
||||
}
|
||||
|
||||
@@ -48,255 +26,172 @@ func (d *Database) GetAvailableDeliveryPersons() ([]map[string]any, error) {
|
||||
func (d *Database) AssignDeliveryPerson(commandID int, livreurUsername string) error {
|
||||
log.Printf("📦 [AssignDeliveryPerson] START - commandID=%d, livreur=%s", commandID, livreurUsername)
|
||||
|
||||
tx, err := d.Begin()
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur démarrage transaction: %v", err)
|
||||
return fmt.Errorf("erreur démarrage transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return d.GDB.Transaction(func(tx *gorm.DB) error {
|
||||
var roleResult struct {
|
||||
Role string `gorm:"column:role"`
|
||||
}
|
||||
err := tx.Raw(`SELECT role FROM users WHERE username = ? FOR UPDATE`, livreurUsername).Scan(&roleResult).Error
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur vérification livreur: %v", err)
|
||||
return fmt.Errorf("erreur lors de la vérification du livreur: %w", err)
|
||||
}
|
||||
if roleResult.Role == "" {
|
||||
log.Printf("❌ Livreur '%s' non trouvé", livreurUsername)
|
||||
return fmt.Errorf("livreur non trouvé")
|
||||
}
|
||||
if roleResult.Role != "livreur" {
|
||||
log.Printf("❌ L'utilisateur '%s' n'est pas un livreur (role=%s)", livreurUsername, roleResult.Role)
|
||||
return fmt.Errorf("l'utilisateur n'est pas un livreur")
|
||||
}
|
||||
|
||||
var role string
|
||||
checkQuery := `SELECT role FROM users WHERE username = $1 FOR UPDATE`
|
||||
err = tx.QueryRow(checkQuery, livreurUsername).Scan(&role)
|
||||
if err == sql.ErrNoRows {
|
||||
log.Printf("❌ Livreur '%s' non trouvé", livreurUsername)
|
||||
return fmt.Errorf("livreur non trouvé")
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur vérification livreur: %v", err)
|
||||
return fmt.Errorf("erreur lors de la vérification du livreur: %w", err)
|
||||
}
|
||||
if role != "livreur" {
|
||||
log.Printf("❌ L'utilisateur '%s' n'est pas un livreur (role=%s)", livreurUsername, role)
|
||||
return fmt.Errorf("l'utilisateur n'est pas un livreur")
|
||||
}
|
||||
var cmdResult struct {
|
||||
Status string `gorm:"column:status"`
|
||||
LivreurAssign *string `gorm:"column:livreur_assign"`
|
||||
}
|
||||
err = tx.Raw(`SELECT status, livreur_assign FROM commandes WHERE id = ? FOR UPDATE`, commandID).Scan(&cmdResult).Error
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur vérification commande: %v", err)
|
||||
return fmt.Errorf("erreur lors de la vérification de la commande: %w", err)
|
||||
}
|
||||
if cmdResult.Status == "" {
|
||||
log.Printf("❌ Commande %d non trouvée", commandID)
|
||||
return fmt.Errorf("commande non trouvée")
|
||||
}
|
||||
|
||||
var currentStatus string
|
||||
var currentLivreur sql.NullString
|
||||
statusQuery := `SELECT status, livreur_assign
|
||||
FROM commandes
|
||||
WHERE id = $1
|
||||
FOR UPDATE`
|
||||
validStatusesForAssignment := []string{"pending", "assigned"}
|
||||
if !slices.Contains(validStatusesForAssignment, cmdResult.Status) {
|
||||
log.Printf("❌ Statut invalide pour assignation: %s", cmdResult.Status)
|
||||
return fmt.Errorf("commande en statut '%s', impossible d'assigner un livreur", cmdResult.Status)
|
||||
}
|
||||
|
||||
err = tx.QueryRow(statusQuery, commandID).Scan(¤tStatus, ¤tLivreur)
|
||||
if err == sql.ErrNoRows {
|
||||
log.Printf("❌ Commande %d non trouvée", commandID)
|
||||
return fmt.Errorf("commande non trouvée")
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur vérification commande: %v", err)
|
||||
return fmt.Errorf("erreur lors de la vérification de la commande: %w", err)
|
||||
}
|
||||
result := tx.Exec(`
|
||||
UPDATE commandes
|
||||
SET livreur_assign = ?,
|
||||
status = 'assigned',
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
AND status IN ('pending', 'assigned')`, livreurUsername, commandID)
|
||||
if result.Error != nil {
|
||||
log.Printf("❌ Erreur UPDATE: %v", result.Error)
|
||||
return fmt.Errorf("erreur lors de l'assignation du livreur: %w", result.Error)
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
log.Printf("❌ Impossible d'assigner: conditions non remplies")
|
||||
return fmt.Errorf("impossible d'assigner la commande (déjà assignée ou statut changé)")
|
||||
}
|
||||
|
||||
validStatusesForAssignment := []string{"pending", "assigned"}
|
||||
isValidStatus := slices.Contains(validStatusesForAssignment, currentStatus)
|
||||
if err := tx.Exec(`
|
||||
INSERT INTO command_logs (command_id, status, message, author, created_at)
|
||||
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)`,
|
||||
commandID, "assigned",
|
||||
fmt.Sprintf("Livraison assignée au livreur %s", livreurUsername),
|
||||
"admin",
|
||||
).Error; err != nil {
|
||||
log.Printf("⚠️ Erreur ajout log: %v", err)
|
||||
// Non bloquant
|
||||
}
|
||||
|
||||
if !isValidStatus {
|
||||
log.Printf("❌ Statut invalide pour assignation: %s", currentStatus)
|
||||
return fmt.Errorf("commande en statut '%s', impossible d'assigner un livreur", currentStatus)
|
||||
}
|
||||
|
||||
updateQuery := `UPDATE commandes
|
||||
SET livreur_assign = $1,
|
||||
status = 'assigned',
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $2
|
||||
AND status IN ('pending', 'assigned')`
|
||||
|
||||
result, err := tx.Exec(updateQuery, livreurUsername, commandID)
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur UPDATE: %v", err)
|
||||
return fmt.Errorf("erreur lors de l'assignation du livreur: %w", err)
|
||||
}
|
||||
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur RowsAffected: %v", err)
|
||||
return fmt.Errorf("erreur lors de la vérification: %w", err)
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
log.Printf("❌ Impossible d'assigner: conditions non remplies")
|
||||
return fmt.Errorf("impossible d'assigner la commande (déjà assignée ou statut changé)")
|
||||
}
|
||||
|
||||
logQuery := `INSERT INTO command_logs (command_id, status, message, author, created_at)
|
||||
VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP)`
|
||||
|
||||
_, err = tx.Exec(logQuery, commandID, "assigned",
|
||||
fmt.Sprintf("Livraison assignée au livreur %s", livreurUsername),
|
||||
"admin")
|
||||
if err != nil {
|
||||
log.Printf("⚠️ Erreur ajout log: %v", err)
|
||||
// Non bloquant
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur COMMIT: %v", err)
|
||||
return fmt.Errorf("erreur commit transaction: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetDeliveryPersonCommands récupère les commandes assignées à un livreur
|
||||
func (d *Database) GetDeliveryPersonCommands(livreurUsername string, status string) ([]map[string]any, error) {
|
||||
query := `SELECT id, username, status, adresse, total_prix, livreur_assign, created_at, updated_at
|
||||
query := `SELECT id, username, status, adresse, total_prix::float8 as total_prix, livreur_assign, created_at, updated_at
|
||||
FROM commandes
|
||||
WHERE livreur_assign = $1`
|
||||
WHERE livreur_assign = ?`
|
||||
|
||||
args := []any{livreurUsername}
|
||||
|
||||
if status != "" {
|
||||
query += " AND status = $2"
|
||||
query += " AND status = ?"
|
||||
args = append(args, status)
|
||||
}
|
||||
|
||||
query += " ORDER BY created_at DESC"
|
||||
|
||||
rows, err := d.Query(query, args...)
|
||||
if err != nil {
|
||||
var commands []map[string]any
|
||||
if err := d.GDB.Raw(query, args...).Scan(&commands).Error; 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 {
|
||||
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,
|
||||
"livreur_assign": livreurAssign.String,
|
||||
"created_at": createdAt,
|
||||
"updated_at": updatedAt,
|
||||
}
|
||||
commands = append(commands, command)
|
||||
}
|
||||
|
||||
return commands, nil
|
||||
}
|
||||
|
||||
func (d *Database) IncrementLivreurDeliveryCount(livreurUsername string) error {
|
||||
query := `UPDATE users
|
||||
SET livraison = livraison + 1,
|
||||
total = total + 1,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE username = $1 AND role = 'livreur'`
|
||||
|
||||
result, err := d.Exec(query, livreurUsername)
|
||||
if err != nil {
|
||||
return fmt.Errorf("erreur lors de l'incrémentation des livraisons: %w", err)
|
||||
result := d.GDB.Exec(`
|
||||
UPDATE users
|
||||
SET livraison = livraison + 1,
|
||||
total = total + 1,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE username = ? AND role = 'livreur'`, livreurUsername)
|
||||
if result.Error != nil {
|
||||
return fmt.Errorf("erreur lors de l'incrémentation des livraisons: %w", result.Error)
|
||||
}
|
||||
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("erreur lors de la vérification: %w", err)
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
if result.RowsAffected == 0 {
|
||||
return fmt.Errorf("livreur non trouvé")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Database) ApproveDelivery(commandID int, clientUsername string) error {
|
||||
tx, err := d.Begin()
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur démarrage transaction: %v", err)
|
||||
return fmt.Errorf("erreur démarrage transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var commandUsername, currentStatus string
|
||||
var livreurAssign sql.NullString
|
||||
|
||||
checkQuery := `SELECT username, status, livreur_assign
|
||||
FROM commandes
|
||||
WHERE id = $1
|
||||
FOR UPDATE`
|
||||
|
||||
err = tx.QueryRow(checkQuery, commandID).Scan(&commandUsername, ¤tStatus, &livreurAssign)
|
||||
if err == sql.ErrNoRows {
|
||||
return fmt.Errorf("commande non trouvée")
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("erreur lors de la vérification de la commande: %w", err)
|
||||
}
|
||||
|
||||
if commandUsername != clientUsername {
|
||||
return fmt.Errorf("cette commande ne vous appartient pas")
|
||||
}
|
||||
|
||||
if currentStatus != "livre" {
|
||||
return fmt.Errorf("cette commande n'est pas encore livrée (statut actuel: %s)", currentStatus)
|
||||
}
|
||||
|
||||
updateQuery := `UPDATE commandes
|
||||
SET status = 'approved',
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $1
|
||||
AND status = 'livre'
|
||||
AND username = $2`
|
||||
|
||||
result, err := tx.Exec(updateQuery, commandID, clientUsername)
|
||||
if err != nil {
|
||||
return fmt.Errorf("erreur lors de l'approbation de la livraison: %w", err)
|
||||
}
|
||||
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("erreur lors de la vérification: %w", err)
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
return fmt.Errorf("impossible d'approuver: statut changé ou commande introuvable")
|
||||
}
|
||||
|
||||
if livreurAssign.Valid && livreurAssign.String != "" {
|
||||
incrementQuery := `UPDATE users
|
||||
SET livraison = livraison + 1,
|
||||
total = total + 1,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE username = $1 AND role = 'livreur'`
|
||||
|
||||
result, err := tx.Exec(incrementQuery, livreurAssign.String)
|
||||
return d.GDB.Transaction(func(tx *gorm.DB) error {
|
||||
var cmdResult struct {
|
||||
Username string `gorm:"column:username"`
|
||||
Status string `gorm:"column:status"`
|
||||
LivreurAssign *string `gorm:"column:livreur_assign"`
|
||||
}
|
||||
err := tx.Raw(`
|
||||
SELECT username, status, livreur_assign
|
||||
FROM commandes WHERE id = ? FOR UPDATE`, commandID).Scan(&cmdResult).Error
|
||||
if err != nil {
|
||||
log.Printf("⚠️ Erreur incrémentation livreur: %v", err)
|
||||
} else {
|
||||
rows, _ := result.RowsAffected()
|
||||
if rows > 0 {
|
||||
log.Printf(" ✅ Compteur livreur incrémenté: %s", livreurAssign.String)
|
||||
return fmt.Errorf("erreur lors de la vérification de la commande: %w", err)
|
||||
}
|
||||
if cmdResult.Username == "" {
|
||||
return fmt.Errorf("commande non trouvée")
|
||||
}
|
||||
|
||||
if cmdResult.Username != clientUsername {
|
||||
return fmt.Errorf("cette commande ne vous appartient pas")
|
||||
}
|
||||
if cmdResult.Status != "livre" {
|
||||
return fmt.Errorf("cette commande n'est pas encore livrée (statut actuel: %s)", cmdResult.Status)
|
||||
}
|
||||
|
||||
result := tx.Exec(`
|
||||
UPDATE commandes
|
||||
SET status = 'approved', updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ? AND status = 'livre' AND username = ?`, commandID, clientUsername)
|
||||
if result.Error != nil {
|
||||
return fmt.Errorf("erreur lors de l'approbation de la livraison: %w", result.Error)
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return fmt.Errorf("impossible d'approuver: statut changé ou commande introuvable")
|
||||
}
|
||||
|
||||
if cmdResult.LivreurAssign != nil && *cmdResult.LivreurAssign != "" {
|
||||
res := tx.Exec(`
|
||||
UPDATE users
|
||||
SET livraison = livraison + 1,
|
||||
total = total + 1,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE username = ? AND role = 'livreur'`, *cmdResult.LivreurAssign)
|
||||
if res.Error != nil {
|
||||
log.Printf("⚠️ Erreur incrémentation livreur: %v", res.Error)
|
||||
} else if res.RowsAffected > 0 {
|
||||
log.Printf(" ✅ Compteur livreur incrémenté: %s", *cmdResult.LivreurAssign)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logQuery := `INSERT INTO command_logs (command_id, status, message, author, created_at)
|
||||
VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP)`
|
||||
if err := tx.Exec(`
|
||||
INSERT INTO command_logs (command_id, status, message, author, created_at)
|
||||
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)`,
|
||||
commandID, "approved",
|
||||
fmt.Sprintf("Livraison approuvée par le client %s", clientUsername),
|
||||
clientUsername,
|
||||
).Error; err != nil {
|
||||
log.Printf("⚠️ Erreur ajout log: %v", err)
|
||||
}
|
||||
|
||||
_, err = tx.Exec(logQuery, commandID, "approved",
|
||||
fmt.Sprintf("Livraison approuvée par le client %s", clientUsername),
|
||||
clientUsername)
|
||||
if err != nil {
|
||||
log.Printf("⚠️ Erreur ajout log: %v", err)
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
log.Printf("❌ Erreur COMMIT: %v", err)
|
||||
return fmt.Errorf("erreur commit transaction: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user