package db
import (
"encoding/json"
"fmt"
"gestion/services"
"log"
"time"
)
func (d *Database) NotifyClient(username string, commandID int, notifType, message string) error {
// Sauvegarder la notification dans Redis
notifKey := fmt.Sprintf("notifications:%s", username)
notification := map[string]any{
"command_id": commandID,
"type": notifType,
"message": message,
"created_at": time.Now().Format(time.RFC3339),
"read": false,
}
notifJSON, _ := json.Marshal(notification)
Redis.LPush(RedisCtx, notifKey, notifJSON)
Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
// Diffusion Telegram si le client a lié son compte
if services.TelegramBot != nil && services.TelegramBot.IsConfigured() {
if chatID, ok, err := d.GetClientTelegramChatID(username); err == nil && ok {
go services.TelegramBot.SendMessage(chatID, fmt.Sprintf("🔔 Notification\n\n%s", message))
}
}
log.Printf("📬 Notification envoyée à %s: %s", username, message)
return nil
}
// NotifyLivreur envoie une notification in-app (Redis) à un livreur
func (d *Database) NotifyLivreur(username string, commandID int, notifType, message string) error {
notifKey := fmt.Sprintf("notifications:%s", username)
notification := map[string]any{
"command_id": commandID,
"type": notifType,
"message": message,
"created_at": time.Now().Format(time.RFC3339),
"read": false,
}
notifJSON, _ := json.Marshal(notification)
Redis.LPush(RedisCtx, notifKey, notifJSON)
Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
// Diffusion Telegram si le livreur a lié son compte
if services.TelegramBot != nil && services.TelegramBot.IsConfigured() {
if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok {
go services.TelegramBot.SendMessage(chatID, fmt.Sprintf("🔔 Notification\n\n%s", message))
}
}
log.Printf("📬 [LIVREUR_NOTIF] Notification envoyée à %s: %s", username, message)
return nil
}
// NotifyAllAdminCabine stocke une notification Redis pour tous les admins/cabines
// et envoie un push aux ceux qui ont un token. Appelé dès qu'une nouvelle commande est créée.
func (d *Database) NotifyAllAdminCabine(commandID int, clientUsername, deliveryAddr string) {
rows, err := d.Query(
`SELECT username FROM users WHERE role IN ('admin','cabine')`,
)
if err != nil {
log.Printf("❌ [ADMIN_NOTIF] Erreur lecture users admin/cabine: %v", err)
return
}
defer rows.Close()
msg := fmt.Sprintf("Nouvelle commande #%d de %s — %s", commandID, clientUsername, deliveryAddr)
notification := map[string]any{
"command_id": commandID,
"type": "new_order",
"message": msg,
"created_at": time.Now().Format(time.RFC3339),
"read": false,
}
notifJSON, _ := json.Marshal(notification)
count := 0
for rows.Next() {
var username string
if err := rows.Scan(&username); err != nil {
continue
}
notifKey := fmt.Sprintf("notifications:%s", username)
Redis.LPush(RedisCtx, notifKey, notifJSON)
Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
// Diffusion Telegram individuelle
if services.TelegramBot != nil && services.TelegramBot.IsConfigured() {
if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok {
capturedChatID := chatID
capturedMsg := msg
go services.TelegramBot.SendMessage(capturedChatID, fmt.Sprintf("🔔 Nouvelle commande\n\n%s", capturedMsg))
}
}
count++
}
log.Printf("📬 [ADMIN_NOTIF] Notif Redis (%d users) pour commande #%d", count, commandID)
}
// NotifyAllAdminCabineAlert envoie une notification Redis + push à tous les admins/cabines
// lors du déclenchement d'une alerte par un livreur.
func (d *Database) NotifyAllAdminCabineAlert(alertID int, livreurUsername, alertMessage string) {
rows, err := d.Query(
`SELECT username FROM users WHERE role IN ('admin','cabine')`,
)
if err != nil {
log.Printf("❌ [ALERT_NOTIF] Erreur lecture users admin/cabine: %v", err)
return
}
defer rows.Close()
body := fmt.Sprintf("%s — livreur : %s", alertMessage, livreurUsername)
notification := map[string]any{
"alert_id": alertID,
"type": "alert",
"message": body,
"created_at": time.Now().Format(time.RFC3339),
"read": false,
}
notifJSON, _ := json.Marshal(notification)
count := 0
for rows.Next() {
var username string
if err := rows.Scan(&username); err != nil {
continue
}
notifKey := fmt.Sprintf("notifications:%s", username)
Redis.LPush(RedisCtx, notifKey, notifJSON)
Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
// Diffusion Telegram individuelle
if services.TelegramBot != nil && services.TelegramBot.IsConfigured() {
if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok {
capturedChatID := chatID
capturedBody := body
go services.TelegramBot.SendMessage(capturedChatID, fmt.Sprintf("🚨 Alerte livreur\n\n%s", capturedBody))
}
}
count++
}
log.Printf("🚨 [ALERT_NOTIF] Notif Redis (%d users) pour alerte #%d de %s", count, alertID, livreurUsername)
}
// AddDeliveryRating ajoute une note pour un livreur
func (d *Database) AddDeliveryRating(livreurUsername string, commandID, rating int, comment string) error {
query := `
INSERT INTO delivery_ratings (livreur_username, command_id, rating, comment, created_at)
VALUES (?, ?, ?, ?, NOW())
`
_, err := d.Exec(query, livreurUsername, commandID, rating, comment)
if err != nil {
log.Printf("⚠️ Erreur sauvegarde note livreur: %v", err)
return err
}
log.Printf("⭐ Note %d/5 ajoutée pour livreur %s (commande %d)", rating, livreurUsername, commandID)
return nil
}