chore: update
This commit is contained in:
@@ -53,7 +53,6 @@ func validateCommandStatus(status string) error {
|
||||
"approved": true,
|
||||
"cancelled": true,
|
||||
"disabled": true,
|
||||
"support": true,
|
||||
}
|
||||
|
||||
if !validStatuses[status] {
|
||||
@@ -423,10 +422,15 @@ func (d *Database) GetCommandCount() (int, error) {
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (d *Database) SetCommandReferralUsed(commandID int, amount float64) error {
|
||||
_, err := d.Exec(`UPDATE commandes SET referral_used = $1 WHERE id = $2`, amount, commandID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) GetCommandByID(id int) (map[string]interface{}, error) {
|
||||
// ✅ Déjà sécurisé avec paramètre $1
|
||||
query := `SELECT id, username, status, adresse, total_prix, livreur_assign, created_at, updated_at,
|
||||
proposed_address, address_proposal_status
|
||||
proposed_address, address_proposal_status, referral_used
|
||||
FROM commandes WHERE id = $1`
|
||||
|
||||
var commandID int
|
||||
@@ -434,7 +438,7 @@ func (d *Database) GetCommandByID(id int) (map[string]interface{}, error) {
|
||||
var livreurAssign sql.NullString
|
||||
var proposedAddress sql.NullString
|
||||
var addressProposalStatus string
|
||||
var totalPrix float64
|
||||
var totalPrix, referralUsed float64
|
||||
var createdAt, updatedAt time.Time
|
||||
|
||||
err := d.QueryRow(query, id).Scan(
|
||||
@@ -448,6 +452,7 @@ func (d *Database) GetCommandByID(id int) (map[string]interface{}, error) {
|
||||
&updatedAt,
|
||||
&proposedAddress,
|
||||
&addressProposalStatus,
|
||||
&referralUsed,
|
||||
)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
@@ -466,6 +471,7 @@ func (d *Database) GetCommandByID(id int) (map[string]interface{}, error) {
|
||||
"created_at": createdAt,
|
||||
"updated_at": updatedAt,
|
||||
"address_proposal_status": addressProposalStatus,
|
||||
"referral_used": referralUsed,
|
||||
}
|
||||
|
||||
if livreurAssign.Valid {
|
||||
@@ -595,7 +601,7 @@ func (d *Database) RespondToAddressProposal(commandID int, clientUsername string
|
||||
// UpdateCommandStatus met à jour le statut d'une commande
|
||||
func (d *Database) UpdateCommandStatus(commandID int, status string) error {
|
||||
// ✅ SÉCURITÉ: Validation du statut
|
||||
validStatuses := []string{"pending", "assigned", "en_route", "arrived", "livre", "approved", "cancelled", "disabled", "support"}
|
||||
validStatuses := []string{"pending", "assigned", "en_route", "arrived", "livre", "approved", "cancelled", "disabled"}
|
||||
isValid := false
|
||||
for _, vs := range validStatuses {
|
||||
if status == vs {
|
||||
@@ -706,7 +712,7 @@ func (d *Database) GetCommandsWithFilter(status, username string, excludeApprove
|
||||
|
||||
// ✅ Filtrer par status si fourni avec validation
|
||||
if status != "" {
|
||||
validStatuses := []string{"pending", "assigned", "en_route", "arrived", "livre", "approved", "cancelled", "disabled", "support"}
|
||||
validStatuses := []string{"pending", "assigned", "en_route", "arrived", "livre", "approved", "cancelled", "disabled"}
|
||||
isValid := false
|
||||
for _, vs := range validStatuses {
|
||||
if status == vs {
|
||||
@@ -832,7 +838,7 @@ func (d *Database) ValidateDeliveryAtomic(commandID int, adminUsername string) (
|
||||
currentStatus, cmdUsername, livreurAssign)
|
||||
|
||||
// ✅ ÉTAPE 3: Vérifier que le statut permet la validation
|
||||
validStatuses := []string{"assigned", "en_route", "pending", "support", "livre"}
|
||||
validStatuses := []string{"assigned", "en_route", "pending", "livre"}
|
||||
isValid := false
|
||||
for _, s := range validStatuses {
|
||||
if currentStatus == s {
|
||||
@@ -878,7 +884,7 @@ func (d *Database) ValidateDeliveryAtomic(commandID int, adminUsername string) (
|
||||
log.Printf("🔍 [ValidateAtomic] Calcul points pour client: %s", cmdUsername)
|
||||
|
||||
// Utiliser la version transactionnelle du calcul de points
|
||||
points, err := d.CalculateAndAddPointsForCommandTx(tx, commandID, cmdUsername)
|
||||
points, _, err := d.CalculateAndAddPointsForCommandTx(tx, commandID, cmdUsername)
|
||||
if err != nil {
|
||||
log.Printf("❌ [ValidateAtomic] Erreur calcul/ajout points: %v", err)
|
||||
return 0, fmt.Errorf("erreur attribution points: %w", err)
|
||||
@@ -957,14 +963,14 @@ func (d *Database) ValidateDeliveryAtomic(commandID int, adminUsername string) (
|
||||
}
|
||||
|
||||
// ApproveDeliveryAtomic - Version atomique pour approbation client
|
||||
func (d *Database) ApproveDeliveryAtomic(commandID int, username string) (int, error) {
|
||||
func (d *Database) ApproveDeliveryAtomic(commandID int, username string) (int, string, error) {
|
||||
log.Printf("🔒 [ApproveAtomic] START - cmd=%d, client=%s", commandID, username)
|
||||
|
||||
// ✅ ÉTAPE 1: Démarrer une transaction
|
||||
tx, err := d.Begin()
|
||||
if err != nil {
|
||||
log.Printf("❌ [ApproveAtomic] Erreur début transaction: %v", err)
|
||||
return 0, fmt.Errorf("erreur transaction: %w", err)
|
||||
return 0, "", fmt.Errorf("erreur transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
@@ -979,11 +985,11 @@ func (d *Database) ApproveDeliveryAtomic(commandID int, username string) (int, e
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
log.Printf("❌ [ApproveAtomic] Commande %d non trouvée", commandID)
|
||||
return 0, fmt.Errorf("commande non trouvée")
|
||||
return 0, "", fmt.Errorf("commande non trouvée")
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("❌ [ApproveAtomic] Erreur SELECT: %v", err)
|
||||
return 0, fmt.Errorf("erreur lecture commande: %w", err)
|
||||
return 0, "", fmt.Errorf("erreur lecture commande: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("📋 [ApproveAtomic] Commande trouvée - status=%s, owner=%s", currentStatus, cmdUsername)
|
||||
@@ -992,13 +998,13 @@ func (d *Database) ApproveDeliveryAtomic(commandID int, username string) (int, e
|
||||
if cmdUsername != username {
|
||||
log.Printf("❌ [ApproveAtomic] Commande n'appartient pas à %s (propriétaire: %s)",
|
||||
username, cmdUsername)
|
||||
return 0, fmt.Errorf("cette commande ne vous appartient pas")
|
||||
return 0, "", fmt.Errorf("cette commande ne vous appartient pas")
|
||||
}
|
||||
|
||||
// ✅ ÉTAPE 4: Vérifier le statut
|
||||
if currentStatus != "livre" {
|
||||
log.Printf("❌ [ApproveAtomic] Statut invalide: %s (attendu: livre)", currentStatus)
|
||||
return 0, fmt.Errorf("commande doit être en statut 'livre' (statut actuel: %s)", currentStatus)
|
||||
return 0, "", fmt.Errorf("commande doit être en statut 'livre' (statut actuel: %s)", currentStatus)
|
||||
}
|
||||
|
||||
// ✅ ÉTAPE 5: UPDATE avec vérification du statut
|
||||
@@ -1010,25 +1016,25 @@ func (d *Database) ApproveDeliveryAtomic(commandID int, username string) (int, e
|
||||
|
||||
if err != nil {
|
||||
log.Printf("❌ [ApproveAtomic] Erreur UPDATE: %v", err)
|
||||
return 0, fmt.Errorf("erreur mise à jour statut: %w", err)
|
||||
return 0, "", fmt.Errorf("erreur mise à jour statut: %w", err)
|
||||
}
|
||||
|
||||
rows, _ := result.RowsAffected()
|
||||
if rows == 0 {
|
||||
log.Printf("❌ [ApproveAtomic] Commande %d déjà modifiée (race condition évitée)", commandID)
|
||||
return 0, fmt.Errorf("commande déjà approuvée ou modifiée")
|
||||
return 0, "", fmt.Errorf("commande déjà approuvée ou modifiée")
|
||||
}
|
||||
|
||||
log.Printf("✅ [ApproveAtomic] Statut mis à jour: livre → approved")
|
||||
|
||||
// ✅ ÉTAPE 6: Calculer et ajouter les points
|
||||
totalPoints, err := d.CalculateAndAddPointsForCommandTx(tx, commandID, username)
|
||||
totalPoints, pointCategory, err := d.CalculateAndAddPointsForCommandTx(tx, commandID, username)
|
||||
if err != nil {
|
||||
log.Printf("❌ [ApproveAtomic] Erreur calcul points: %v", err)
|
||||
return 0, fmt.Errorf("erreur attribution points: %w", err)
|
||||
return 0, "", fmt.Errorf("erreur attribution points: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("✅ [ApproveAtomic] %d points attribués à %s", totalPoints, username)
|
||||
log.Printf("✅ [ApproveAtomic] %d points [%s] attribués à %s", totalPoints, pointCategory, username)
|
||||
|
||||
// ✅ ÉTAPE 7: Incrémenter le compteur de commandes
|
||||
_, err = tx.Exec(`
|
||||
@@ -1046,7 +1052,7 @@ func (d *Database) ApproveDeliveryAtomic(commandID int, username string) (int, e
|
||||
INSERT INTO command_logs (command_id, status, message, author, created_at)
|
||||
VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP)
|
||||
`, commandID, "approved",
|
||||
fmt.Sprintf("Livraison confirmée par le client %s - %d points attribués", username, totalPoints),
|
||||
fmt.Sprintf("Livraison confirmée par le client %s - %d points [%s] attribués", username, totalPoints, pointCategory),
|
||||
username)
|
||||
|
||||
if err != nil {
|
||||
@@ -1056,11 +1062,11 @@ func (d *Database) ApproveDeliveryAtomic(commandID int, username string) (int, e
|
||||
// ✅ ÉTAPE 9: Commit
|
||||
if err := tx.Commit(); err != nil {
|
||||
log.Printf("❌ [ApproveAtomic] Erreur COMMIT: %v", err)
|
||||
return 0, fmt.Errorf("erreur commit transaction: %w", err)
|
||||
return 0, "", fmt.Errorf("erreur commit transaction: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("🎉 [ApproveAtomic] SUCCÈS - Commande %d approuvée, %d points attribués",
|
||||
commandID, totalPoints)
|
||||
log.Printf("🎉 [ApproveAtomic] SUCCÈS - Commande %d approuvée, %d points [%s] attribués",
|
||||
commandID, totalPoints, pointCategory)
|
||||
|
||||
// ✅ ÉTAPE 10: Optimiser queue livreur (async, après commit)
|
||||
if livreurAssign != "" {
|
||||
@@ -1087,16 +1093,16 @@ func (d *Database) ApproveDeliveryAtomic(commandID int, username string) (int, e
|
||||
log.Printf("✅ [ApproveAtomic] Caches invalidés")
|
||||
}()
|
||||
|
||||
return totalPoints, nil
|
||||
return totalPoints, pointCategory, nil
|
||||
}
|
||||
|
||||
// ApproveDeliveryAtomicByStaff - Confirmation de réception par admin ou cabine à la place du client
|
||||
func (d *Database) ApproveDeliveryAtomicByStaff(commandID int, staffUsername string) (int, string, error) {
|
||||
func (d *Database) ApproveDeliveryAtomicByStaff(commandID int, staffUsername string) (int, string, string, error) {
|
||||
log.Printf("🔒 [ApproveAtomicStaff] START - cmd=%d, staff=%s", commandID, staffUsername)
|
||||
|
||||
tx, err := d.Begin()
|
||||
if err != nil {
|
||||
return 0, "", fmt.Errorf("erreur transaction: %w", err)
|
||||
return 0, "", "", fmt.Errorf("erreur transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
@@ -1109,14 +1115,14 @@ func (d *Database) ApproveDeliveryAtomicByStaff(commandID int, staffUsername str
|
||||
`, commandID).Scan(¤tStatus, &clientUsername, &livreurAssign)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return 0, "", fmt.Errorf("commande non trouvée")
|
||||
return 0, "", "", fmt.Errorf("commande non trouvée")
|
||||
}
|
||||
if err != nil {
|
||||
return 0, "", fmt.Errorf("erreur lecture commande: %w", err)
|
||||
return 0, "", "", fmt.Errorf("erreur lecture commande: %w", err)
|
||||
}
|
||||
|
||||
if currentStatus != "livre" {
|
||||
return 0, "", fmt.Errorf("commande doit être en statut 'livre' (statut actuel: %s)", currentStatus)
|
||||
return 0, "", "", fmt.Errorf("commande doit être en statut 'livre' (statut actuel: %s)", currentStatus)
|
||||
}
|
||||
|
||||
result, err := tx.Exec(`
|
||||
@@ -1125,17 +1131,17 @@ func (d *Database) ApproveDeliveryAtomicByStaff(commandID int, staffUsername str
|
||||
WHERE id = $1 AND status = 'livre'
|
||||
`, commandID)
|
||||
if err != nil {
|
||||
return 0, "", fmt.Errorf("erreur mise à jour statut: %w", err)
|
||||
return 0, "", "", fmt.Errorf("erreur mise à jour statut: %w", err)
|
||||
}
|
||||
|
||||
rows, _ := result.RowsAffected()
|
||||
if rows == 0 {
|
||||
return 0, "", fmt.Errorf("commande déjà approuvée ou modifiée")
|
||||
return 0, "", "", fmt.Errorf("commande déjà approuvée ou modifiée")
|
||||
}
|
||||
|
||||
totalPoints, err := d.CalculateAndAddPointsForCommandTx(tx, commandID, clientUsername)
|
||||
totalPoints, pointCategory, err := d.CalculateAndAddPointsForCommandTx(tx, commandID, clientUsername)
|
||||
if err != nil {
|
||||
return 0, "", fmt.Errorf("erreur attribution points: %w", err)
|
||||
return 0, "", "", fmt.Errorf("erreur attribution points: %w", err)
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`
|
||||
@@ -1158,7 +1164,7 @@ func (d *Database) ApproveDeliveryAtomicByStaff(commandID int, staffUsername str
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return 0, "", fmt.Errorf("erreur commit: %w", err)
|
||||
return 0, "", "", fmt.Errorf("erreur commit: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("🎉 [ApproveAtomicStaff] SUCCÈS - cmd=%d approuvée par %s, %d points → client %s",
|
||||
@@ -1178,5 +1184,5 @@ func (d *Database) ApproveDeliveryAtomicByStaff(commandID int, staffUsername str
|
||||
Redis.Del(RedisCtx, fmt.Sprintf("client:%s:commands", clientUsername))
|
||||
}()
|
||||
|
||||
return totalPoints, clientUsername, nil
|
||||
return totalPoints, pointCategory, clientUsername, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user