diff --git a/backend/renders/renders.go b/backend/renders/renders.go index 30d87ac..0fb2c78 100644 --- a/backend/renders/renders.go +++ b/backend/renders/renders.go @@ -462,6 +462,75 @@ func Dashboard(db *gorm.DB) http.HandlerFunc { renderTemplate(w, "dashboard", data) } } +// func ClientConsumptionPage(db *gorm.DB) http.HandlerFunc { +// return func(w http.ResponseWriter, r *http.Request) { +// val := r.Context().Value("ssoid") +// ssoid, ok := val.(string) +// if !ok || ssoid == "" { +// http.Error(w, "Non authentifié", http.StatusUnauthorized) +// return +// } + +// var currentUser models.User +// if err := db.Where("sso_id = ?", ssoid).First(¤tUser).Error; err != nil { +// http.Error(w, "Utilisateur introuvable", http.StatusUnauthorized) +// return +// } + +// period := r.URL.Query().Get("period") +// clientIDStr := r.URL.Query().Get("client") +// var clientID uint + +// if clientIDStr != "" { +// idParsed, _ := strconv.Atoi(clientIDStr) +// clientID = uint(idParsed) +// } + +// var fromDate time.Time +// now := time.Now() +// switch period { +// case "today": +// fromDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) +// case "week": +// fromDate = now.AddDate(0, 0, -7) +// case "month": +// fromDate = now.AddDate(0, -1, 0) +// case "year": +// fromDate = now.AddDate(-1, 0, 0) +// default: +// fromDate = time.Time{} +// } + +// query := db.Model(&models.Consumption{}) +// if currentUser.Role == models.ROLE_ADMIN { +// if clientID > 0 { +// query = query.Where("user_id = ?", clientID) +// } +// } else { +// query = query.Where("user_id = ?", currentUser.ID) +// } +// if !fromDate.IsZero() { +// query = query.Where("created_at >= ?", fromDate) +// } + +// var consumptions []models.Consumption +// query.Order("created_at desc").Find(&consumptions) + +// data := map[string]interface{}{ +// "Consumptions": consumptions, +// "User": currentUser, +// "SelectedClientID": clientID, +// } + +// if currentUser.Role == models.ROLE_ADMIN { +// var clients []models.User +// db.Where("role = ?", "CLIENT").Find(&clients) +// data["Clients"] = clients +// } + +// renderTemplate(w, "client_consumption", data) +// } +// } func ClientConsumptionPage(db *gorm.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { val := r.Context().Value("ssoid") @@ -480,7 +549,6 @@ func ClientConsumptionPage(db *gorm.DB) http.HandlerFunc { period := r.URL.Query().Get("period") clientIDStr := r.URL.Query().Get("client") var clientID uint - if clientIDStr != "" { idParsed, _ := strconv.Atoi(clientIDStr) clientID = uint(idParsed) @@ -501,6 +569,7 @@ func ClientConsumptionPage(db *gorm.DB) http.HandlerFunc { fromDate = time.Time{} } + // Préparation des filtres query := db.Model(&models.Consumption{}) if currentUser.Role == models.ROLE_ADMIN { if clientID > 0 { @@ -513,13 +582,42 @@ func ClientConsumptionPage(db *gorm.DB) http.HandlerFunc { query = query.Where("created_at >= ?", fromDate) } - var consumptions []models.Consumption - query.Order("created_at desc").Find(&consumptions) + // Regroupement par date + type DailySummary struct { + Date time.Time + TotalCredits uint + } + var summaries []DailySummary + query.Select("DATE(created_at) as date, SUM(credits_used) as total_credits"). + Group("DATE(created_at)").Order("date desc"). + Scan(&summaries) + + // Détail par jour + details := make(map[string][]models.Consumption) + for _, s := range summaries { + var daily []models.Consumption + start := time.Date(s.Date.Year(), s.Date.Month(), s.Date.Day(), 0, 0, 0, 0, s.Date.Location()) + end := start.Add(24 * time.Hour) + + detailQuery := db.Model(&models.Consumption{}).Where("created_at >= ? AND created_at < ?", start, end) + if currentUser.Role == models.ROLE_ADMIN { + if clientID > 0 { + detailQuery = detailQuery.Where("user_id = ?", clientID) + } + } else { + detailQuery = detailQuery.Where("user_id = ?", currentUser.ID) + } + detailQuery.Order("created_at desc").Find(&daily) + + details[s.Date.Format("2006-01-02")] = daily + } data := map[string]interface{}{ - "Consumptions": consumptions, - "User": currentUser, - "SelectedClientID": clientID, + "User": currentUser, + "Summaries": summaries, + "DetailsByDate": details, + "SelectedClientID": clientID, + "Period": period, } if currentUser.Role == models.ROLE_ADMIN { @@ -531,98 +629,7 @@ func ClientConsumptionPage(db *gorm.DB) http.HandlerFunc { renderTemplate(w, "client_consumption", data) } } -func ConsumptionPageGrouped(db *gorm.DB) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - ssoid, ok := r.Context().Value("ssoid").(string) - if !ok || ssoid == "" { - http.Error(w, "Non authentifié", http.StatusUnauthorized) - return - } - // Récupération de l'utilisateur courant - var currentUser models.User - if err := db.Where("sso_id = ?", ssoid).First(¤tUser).Error; err != nil { - http.Error(w, "Utilisateur introuvable", http.StatusUnauthorized) - return - } - - // Filtrage admin / client ciblé - clientIDStr := r.URL.Query().Get("client") - var clientID uint - if currentUser.Role == models.ROLE_ADMIN && clientIDStr != "" { - if id, err := strconv.Atoi(clientIDStr); err == nil { - clientID = uint(id) - } - } else { - clientID = currentUser.ID - } - - // Période - period := r.URL.Query().Get("period") - var fromDate time.Time - now := time.Now() - switch period { - case "today": - fromDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) - case "week": - fromDate = now.AddDate(0, 0, -7) - case "month": - fromDate = now.AddDate(0, -1, 0) - case "year": - fromDate = now.AddDate(-1, 0, 0) - default: - fromDate = time.Time{} - } - - // Récupération des consommations - var consumptions []models.Consumption - query := db.Where("user_id = ?", clientID) - if !fromDate.IsZero() { - query = query.Where("created_at >= ?", fromDate) - } - query.Order("created_at desc").Find(&consumptions) - - // Groupe par jour - type DailyGroup struct { - Date string - Total uint - Lines []models.Consumption - } - grouped := map[string]*DailyGroup{} - for _, c := range consumptions { - day := c.CreatedAt.Format("2006-01-02") - if _, exists := grouped[day]; !exists { - grouped[day] = &DailyGroup{Date: day} - } - grouped[day].Total += c.CreditsUsed - grouped[day].Lines = append(grouped[day].Lines, c) - } - - // Conversion en slice et tri - var groupedSlice []*DailyGroup - for _, v := range grouped { - groupedSlice = append(groupedSlice, v) - } - sort.Slice(groupedSlice, func(i, j int) bool { - return groupedSlice[i].Date > groupedSlice[j].Date - }) - - data := map[string]interface{}{ - "User": currentUser, - "GroupedConsumptions": groupedSlice, - "SelectedClientID": clientID, - } - - // Pour ADMIN : liste des clients - if currentUser.Role == models.ROLE_ADMIN { - var clients []models.User - db.Where("role = ?", models.ROLE_CLIENT).Find(&clients) - data["Clients"] = clients - } - - renderTemplate(w, "client_consumption", data) - } -} // pour un rendu complet de la page diff --git a/backend/routes/routes.go b/backend/routes/routes.go index 363abe4..ac3e435 100644 --- a/backend/routes/routes.go +++ b/backend/routes/routes.go @@ -76,8 +76,8 @@ func RoutesPublic(r *mux.Router, db *gorm.DB) { r.HandleFunc("/test/send2", renders.TestMessagesPages2) r.HandleFunc("/admin/user/{id}/conversation-thread", renders.AdminConversationThread(db)).Methods("GET") r.HandleFunc("/api/message/send2", handlers.HandleTemplateTest(db)).Methods("POST") - // r.HandleFunc("/admin/consumption", renders.ClientConsumptionPage(db)) - r.HandleFunc("/admin/consumption", renders.ConsumptionPageGrouped(db)) + r.HandleFunc("/admin/consumption", renders.ClientConsumptionPage(db)) + // r.HandleFunc("/admin/consumption", renders.ConsumptionPageGrouped(db)) r.HandleFunc("/logout", func(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, &http.Cookie{