chore: fix bug
Backend - Build & Lint / build (push) Has been cancelled

This commit is contained in:
Nuxgrid
2026-07-11 11:45:13 +02:00
parent f531ddcda8
commit f674b6ef80
29 changed files with 3621 additions and 313 deletions
+4 -12
View File
@@ -1145,19 +1145,11 @@ func UpdateCommandStatusAdmin(c *gin.Context) {
}
if req.Status == "cancelled" {
current, errCmd := database.GetCommandByID(commandID)
if errCmd == nil {
currentStatus, _ := current["status"].(string)
alreadyDone := currentStatus == "cancelled" || currentStatus == "approved" || currentStatus == "livre"
if !alreadyDone {
if err := database.RestoreCommandStock(commandID); err != nil {
log.Printf("⚠️ [STATUS_ADMIN] Erreur restauration stock cmd %d: %v", commandID, err)
}
}
if err := database.CancelCommandByAdminAtomic(commandID); err != nil {
utils.ServerErr(c, "Impossible d'annuler la commande", err)
return
}
}
if err := database.UpdateCommandStatus(commandID, req.Status); err != nil {
} else if err := database.UpdateCommandStatus(commandID, req.Status); err != nil {
utils.ServerErr(c, "Impossible de mettre à jour le statut", err)
return
}
+30 -28
View File
@@ -49,12 +49,12 @@ func GetMyPointsRewards(c *gin.Context) {
}
type PoolInfo struct {
Key string `json:"key"`
Name string `json:"name"`
Points int `json:"points"`
RewardsEarned int `json:"rewards_earned"`
RewardsClaimed int `json:"rewards_claimed"`
RewardsAvailable int `json:"rewards_available"`
Key string `json:"key"`
Name string `json:"name"`
Points int `json:"points"`
RewardsEarned int `json:"rewards_earned"`
RewardsClaimed int `json:"rewards_claimed"`
RewardsAvailable int `json:"rewards_available"`
EligibleConfigs []EligibleConfigResponse `json:"eligible_configs"`
}
@@ -207,16 +207,6 @@ func ClaimMyReward(c *gin.Context) {
return
}
remaining, err := database.ClaimPoolReward(username, req.PoolKey, reward.Threshold)
if err != nil {
if strings.Contains(err.Error(), "pas de récompense disponible") {
c.JSON(http.StatusConflict, gin.H{"error": "Pas assez de points pour réclamer une récompense"})
return
}
utils.ServerErr(c, "Erreur réclamation récompense", err)
return
}
// Si le client a sélectionné un produit spécifique parmi plusieurs, ne donner que celui-là
itemsToAdd := reward.RewardItems
if req.ProductID > 0 && len(reward.RewardItems) > 1 {
@@ -228,19 +218,31 @@ func ClaimMyReward(c *gin.Context) {
}
}
// Ajouter les produits récompense au panier si configurés
productAdded := false
var productNames []string
if len(itemsToAdd) > 0 {
if added, addErr := database.AddRewardsToBasket(username, itemsToAdd, req.PoolKey); addErr == nil && len(added) > 0 {
productAdded = true
for _, item := range added {
productNames = append(productNames, item.ProductName)
}
log.Printf("✅ [CLAIM] %d produit(s) récompense ajoutés au panier de %s", len(added), username)
} else if addErr != nil {
log.Printf("⚠️ [CLAIM] Impossible d'ajouter produits récompense: %v", addErr)
// Réclamation + ajout au panier dans une seule transaction : si l'ajout
// échoue (produit récompense supprimé/introuvable), la récompense n'est
// pas consommée non plus — pas de perte sèche pour le client.
remaining, added, err := database.ClaimPoolRewardAndAddToBasket(username, req.PoolKey, reward.Threshold, itemsToAdd)
if err != nil {
if strings.Contains(err.Error(), "pas de récompense disponible") {
c.JSON(http.StatusConflict, gin.H{"error": "Pas assez de points pour réclamer une récompense"})
return
}
if strings.Contains(err.Error(), "produit récompense introuvable") {
log.Printf("❌ [CLAIM] Configuration récompense invalide pour %s: %v", username, err)
c.JSON(http.StatusConflict, gin.H{"error": "Récompense momentanément indisponible, contactez le support"})
return
}
utils.ServerErr(c, "Erreur réclamation récompense", err)
return
}
productAdded := len(added) > 0
var productNames []string
for _, item := range added {
productNames = append(productNames, item.ProductName)
}
if productAdded {
log.Printf("✅ [CLAIM] %d produit(s) récompense ajoutés au panier de %s", len(added), username)
}
c.JSON(http.StatusOK, gin.H{
+22 -14
View File
@@ -307,19 +307,22 @@ func GetDeliverymanLocationForCommand(c *gin.Context) {
}
// ✅ 6. Récupérer l'ETA de la commande depuis Redis (si disponible)
// La clé est un hash (HSet), jamais une simple valeur — Redis.Get renvoie
// une erreur WRONGTYPE dessus, silencieusement ignorée ici auparavant,
// ce qui faisait toujours renvoyer etaMinutes=0.
etaKey := fmt.Sprintf("command:eta:%d", commandID)
etaData, _ := db.Redis.Get(db.RedisCtx, etaKey).Result()
eta, _ := db.Redis.HGetAll(db.RedisCtx, etaKey).Result()
var etaMinutes int = 0
var etaSetAt int64 = 0
if etaData != "" {
var eta map[string]interface{}
json.Unmarshal([]byte(etaData), &eta)
if minutes, ok := eta["minutes"].(float64); ok {
etaMinutes = int(minutes)
if minutesStr, ok := eta["eta_minutes"]; ok {
if minutes, err := strconv.Atoi(minutesStr); err == nil {
etaMinutes = minutes
}
if timestamp, ok := eta["set_at"].(float64); ok {
etaSetAt = int64(timestamp)
}
if updatedAtStr, ok := eta["updated_at"]; ok {
if timestamp, err := strconv.ParseInt(updatedAtStr, 10, 64); err == nil {
etaSetAt = timestamp
}
}
@@ -1017,12 +1020,17 @@ func refreshETAForActivDelivery(username string, lat, lon float64) {
etaKey := fmt.Sprintf("command:eta:%d", commandID)
db.Redis.HSet(db.RedisCtx, etaKey, map[string]interface{}{
"command_id": commandID,
"eta_minutes": etaMinutes,
"updated_at": now.Unix(),
"arrival_time": arrivalTime.Unix(),
"distance_km": distanceKm,
"with_traffic": err == nil,
"command_id": commandID,
// eta_minutes ET total_eta_minutes doivent tous les deux être présents
// (voir le commentaire de SetCommandETAWithDetails) — sans quoi les
// lecteurs qui attendent l'un ou l'autre nom de champ ne trouvent rien.
"eta_minutes": etaMinutes,
"total_eta_minutes": etaMinutes,
"updated_at": now.Unix(),
"arrival_time": arrivalTime.Unix(),
"estimated_arrival": arrivalTime.Format(time.RFC3339),
"distance_km": distanceKm,
"with_traffic": err == nil,
})
db.Redis.Expire(db.RedisCtx, etaKey, 4*time.Hour)
}