chore: build
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"gestion/db"
|
||||
"gestion/models"
|
||||
"gestion/utils"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// GetMyPointsRewards retourne les points et les récompenses disponibles du client connecté.
|
||||
// La récompense est globale : son seuil s'applique indépendamment à chaque pool.
|
||||
func GetMyPointsRewards(c *gin.Context) {
|
||||
username := c.GetString("username")
|
||||
if username == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
||||
return
|
||||
}
|
||||
|
||||
database := c.MustGet("database").(*db.Database)
|
||||
|
||||
settings, err := database.GetSettings()
|
||||
if err != nil {
|
||||
utils.ServerErr(c, "Erreur lecture paramètres", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !settings.PointsEnabled || len(settings.PointsPools) == 0 {
|
||||
c.JSON(http.StatusOK, gin.H{"enabled": false, "pools": []gin.H{}, "reward": nil})
|
||||
return
|
||||
}
|
||||
|
||||
pointsExtra, pointsRedeemed, err := database.GetClientPointsAndRewards(username)
|
||||
if err != nil {
|
||||
utils.ServerErr(c, "Erreur lecture points", err)
|
||||
return
|
||||
}
|
||||
|
||||
reward := settings.PointsReward
|
||||
|
||||
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"`
|
||||
EligibleConfigs []models.RewardCategoryConfig `json:"eligible_configs"`
|
||||
}
|
||||
|
||||
pools := make([]PoolInfo, 0, len(settings.PointsPools))
|
||||
for _, pool := range settings.PointsPools {
|
||||
pts := pointsExtra[pool.Key]
|
||||
redeemed := pointsRedeemed[pool.Key]
|
||||
|
||||
var earned, available int
|
||||
if reward != nil && reward.Threshold > 0 {
|
||||
earned = pts / reward.Threshold
|
||||
available = earned - redeemed
|
||||
if available < 0 {
|
||||
available = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Filtrer les category_configs aux seules catégories du pool
|
||||
poolCats := make(map[string]bool, len(pool.Categories))
|
||||
for _, c := range pool.Categories {
|
||||
poolCats[c] = true
|
||||
}
|
||||
eligibleConfigs := make([]models.RewardCategoryConfig, 0)
|
||||
if reward != nil {
|
||||
for _, cfg := range reward.CategoryConfigs {
|
||||
if poolCats[cfg.Category] {
|
||||
eligibleConfigs = append(eligibleConfigs, cfg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pools = append(pools, PoolInfo{
|
||||
Key: pool.Key,
|
||||
Name: pool.Name,
|
||||
Points: pts,
|
||||
RewardsEarned: earned,
|
||||
RewardsClaimed: redeemed,
|
||||
RewardsAvailable: available,
|
||||
EligibleConfigs: eligibleConfigs,
|
||||
})
|
||||
}
|
||||
|
||||
// Retourner la récompense sans category_configs (les configs sont par pool)
|
||||
var rewardMeta gin.H
|
||||
if reward != nil {
|
||||
rewardMeta = gin.H{
|
||||
"threshold": reward.Threshold,
|
||||
"type": reward.Type,
|
||||
"description": reward.Description,
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"enabled": true, "pools": pools, "reward": rewardMeta})
|
||||
}
|
||||
|
||||
// ClaimMyReward réclame une récompense sur un pool donné si le client a atteint le seuil.
|
||||
func ClaimMyReward(c *gin.Context) {
|
||||
username := c.GetString("username")
|
||||
if username == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
PoolKey string `json:"pool_key" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "pool_key requis"})
|
||||
return
|
||||
}
|
||||
|
||||
database := c.MustGet("database").(*db.Database)
|
||||
|
||||
settings, err := database.GetSettings()
|
||||
if err != nil {
|
||||
utils.ServerErr(c, "Erreur lecture paramètres", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !settings.PointsEnabled {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "Système de points désactivé"})
|
||||
return
|
||||
}
|
||||
|
||||
reward := settings.PointsReward
|
||||
if reward == nil || reward.Threshold <= 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Aucune récompense configurée"})
|
||||
return
|
||||
}
|
||||
|
||||
// Vérifier que le pool existe
|
||||
poolExists := false
|
||||
for _, p := range settings.PointsPools {
|
||||
if p.Key == req.PoolKey {
|
||||
poolExists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !poolExists {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Pool introuvable"})
|
||||
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
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"success": true,
|
||||
"description": reward.Description,
|
||||
"remaining_rewards": remaining,
|
||||
})
|
||||
}
|
||||
|
||||
// AdminResetClientRedeemed remet à zéro les récompenses réclamées d'un client (admin).
|
||||
func AdminResetClientRedeemed(c *gin.Context) {
|
||||
username := c.Param("username")
|
||||
poolKey := c.Query("pool_key")
|
||||
|
||||
database := c.MustGet("database").(*db.Database)
|
||||
if err := database.ResetClientRedeemed(username, poolKey); err != nil {
|
||||
utils.ServerErr(c, "Erreur reset récompenses", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"success": true})
|
||||
}
|
||||
Reference in New Issue
Block a user