package db import ( "encoding/json" "fmt" "gestion/models" "log" "strconv" "time" ) func (d *Database) UpdateDeliveryPersonLocation(username string, lat, lon float64) error { key := fmt.Sprintf("delivery:location:%s", username) location := map[string]any{ "latitude": lat, "longitude": lon, "last_update": time.Now().Unix(), } data, _ := json.Marshal(location) err := Redis.Set(RedisCtx, key, data, 1*time.Hour).Err() if err != nil { return fmt.Errorf("erreur mise à jour position: %w", err) } log.Printf("📍 Position GPS mise à jour pour %s: (%.6f, %.6f)", username, lat, lon) statusKey := fmt.Sprintf("delivery:status:%s", username) statusData, err := Redis.Get(RedisCtx, statusKey).Result() if err != nil || statusData == "" { log.Printf("🆕 [INIT_STATUS] Création statut 'available' pour %s (première position GPS)", username) d.SetDeliveryPersonStatus(username, "available", 0) } else { var status models.DeliveryPersonStatus json.Unmarshal([]byte(statusData), &status) if status.Status == "offline" { log.Printf("🔄 [REACTIVATE] %s passe de 'offline' à 'available' (position GPS reçue)", username) d.SetDeliveryPersonStatus(username, "available", 0) } else { go d.UpdateDeliverymanStatusBasedOnQueue(username) } } // 3️⃣ Publier l'événement de mise à jour de position d.PublishDeliveryPersonLocationUpdate(username, lat, lon) return nil } // GetDeliveryPersonLocation récupère la position d'un livreur func (d *Database) GetDeliveryPersonLocation(username string) (float64, float64, error) { key := fmt.Sprintf("delivery:location:%s", username) data, err := Redis.Get(RedisCtx, key).Result() if err != nil { return 0, 0, fmt.Errorf("position non trouvée pour %s: %w", username, err) } if data == "" { return 0, 0, fmt.Errorf("aucune donnée de position pour %s", username) } var location map[string]any if err := json.Unmarshal([]byte(data), &location); err != nil { return 0, 0, fmt.Errorf("erreur parsing JSON Redis: %w", err) } var lat, lon float64 if v, ok := location["latitude"]; ok && v != nil { switch val := v.(type) { case float64: lat = val case float32: lat = float64(val) case int: lat = float64(val) case int64: lat = float64(val) case string: lat, _ = strconv.ParseFloat(val, 64) } } if v, ok := location["longitude"]; ok && v != nil { switch val := v.(type) { case float64: lon = val case float32: lon = float64(val) case int: lon = float64(val) case int64: lon = float64(val) case string: lon, _ = strconv.ParseFloat(val, 64) } } if lat == 0 && lon == 0 { return 0, 0, fmt.Errorf("coordonnées invalides (0,0) pour %s", username) } return lat, lon, nil }