chore: fix prices
This commit is contained in:
@@ -9,6 +9,54 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// RegisterPushToken enregistre le push token Expo d'un client
|
||||
// POST /api/v1/push-token
|
||||
func RegisterPushToken(c *gin.Context) {
|
||||
clientID := c.GetInt("client_id")
|
||||
if clientID == 0 {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
PushToken string `json:"push_token" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "push_token requis"})
|
||||
return
|
||||
}
|
||||
|
||||
database := c.MustGet("database").(*db.Database)
|
||||
if err := database.SaveClientPushToken(clientID, req.PushToken); err != nil {
|
||||
log.Printf("❌ [PUSH_TOKEN] Erreur sauvegarde token pour client %d: %v", clientID, err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur enregistrement push token"})
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("✅ [PUSH_TOKEN] Token enregistré pour client %d", clientID)
|
||||
c.JSON(http.StatusOK, gin.H{"success": true})
|
||||
}
|
||||
|
||||
// UnregisterPushToken supprime le push token d'un client (au logout)
|
||||
// DELETE /api/v1/push-token
|
||||
func UnregisterPushToken(c *gin.Context) {
|
||||
clientID := c.GetInt("client_id")
|
||||
if clientID == 0 {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
||||
return
|
||||
}
|
||||
|
||||
database := c.MustGet("database").(*db.Database)
|
||||
if err := database.DeleteClientPushToken(clientID); err != nil {
|
||||
log.Printf("❌ [PUSH_TOKEN] Erreur suppression token pour client %d: %v", clientID, err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur suppression push token"})
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("✅ [PUSH_TOKEN] Token supprimé pour client %d", clientID)
|
||||
c.JSON(http.StatusOK, gin.H{"success": true})
|
||||
}
|
||||
|
||||
// GetClientNotifications retourne les notifications du client connecté
|
||||
// GET /api/v1/notifications
|
||||
func GetClientNotifications(c *gin.Context) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
type BasketsRequest struct {
|
||||
Username string `json:"username"`
|
||||
ProductID int `json:"product_id"`
|
||||
NameProduct string `json:"name_product"`
|
||||
Category string `json:"category"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
@@ -26,16 +27,14 @@ type BasketsRequest struct {
|
||||
// ============================================
|
||||
// POST /api/v1/panier/add
|
||||
func AddProductsBasket(c *gin.Context) {
|
||||
db := c.MustGet("database").(*db.Database)
|
||||
database := c.MustGet("database").(*db.Database)
|
||||
|
||||
// Liaison JSON
|
||||
var req BasketsRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Requête invalide", "details": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Récupérer le username depuis JWT ou contexte
|
||||
username, ok := c.Get("username")
|
||||
if !ok {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Authentification requise"})
|
||||
@@ -43,45 +42,65 @@ func AddProductsBasket(c *gin.Context) {
|
||||
}
|
||||
req.Username = username.(string)
|
||||
|
||||
// Validation des champs
|
||||
if req.NameProduct == "" || req.Category == "" || req.Quantity <= 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Champs invalides"})
|
||||
if req.Quantity <= 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Quantité invalide"})
|
||||
return
|
||||
}
|
||||
|
||||
// Vérifier le stock
|
||||
stock, err := db.GetProductStock(req.NameProduct, req.Category)
|
||||
// Si product_id fourni par le mobile, on l'utilise directement (plus fiable)
|
||||
if req.ProductID > 0 {
|
||||
stock, err := database.GetProductStockByID(req.ProductID)
|
||||
if err != nil {
|
||||
log.Printf("❌ [ADD_PANIER] Produit %d non trouvé: %v", req.ProductID, err)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Produit non trouvé"})
|
||||
return
|
||||
}
|
||||
if stock < req.Quantity {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Stock insuffisant", "available": stock})
|
||||
return
|
||||
}
|
||||
panier, err := database.AddProductInBasketByID(req.Username, req.ProductID, req.Quantity)
|
||||
if err != nil {
|
||||
log.Printf("❌ [ADD_PANIER] Erreur ajout product_id=%d qty=%.3f: %v", req.ProductID, req.Quantity, err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible d'ajouter le produit au panier", "details": err.Error()})
|
||||
return
|
||||
}
|
||||
if err := database.DecrementProductStockByID(req.ProductID, req.Quantity); err != nil {
|
||||
log.Printf("❌ [ADD_PANIER] Erreur décrement stock product_id=%d: %v", req.ProductID, err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de réserver le stock"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusCreated, gin.H{"success": true, "message": "Produit ajouté au panier avec succès", "panier": panier})
|
||||
return
|
||||
}
|
||||
|
||||
// Fallback : recherche par nom+catégorie (compatibilité)
|
||||
if req.NameProduct == "" || req.Category == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "product_id ou name_product+category requis"})
|
||||
return
|
||||
}
|
||||
|
||||
stock, err := database.GetProductStock(req.NameProduct, req.Category)
|
||||
if err != nil {
|
||||
log.Printf("❌ [ADD_PANIER] Produit '%s'/'%s' non trouvé: %v", req.NameProduct, req.Category, err)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Produit non trouvé"})
|
||||
return
|
||||
}
|
||||
|
||||
if stock < req.Quantity {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "Stock insuffisant",
|
||||
"available": stock,
|
||||
})
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Stock insuffisant", "available": stock})
|
||||
return
|
||||
}
|
||||
|
||||
// Ajouter au panier (ou mettre à jour si déjà présent)
|
||||
panier, err := db.AddProductInBasket(req.Username, req.NameProduct, req.Quantity, req.Category)
|
||||
panier, err := database.AddProductInBasket(req.Username, req.NameProduct, req.Quantity, req.Category)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible d'ajouter le produit au panier"})
|
||||
log.Printf("❌ [ADD_PANIER] Erreur ajout '%s': %v", req.NameProduct, err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible d'ajouter le produit au panier", "details": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Décrémenter le stock
|
||||
if err := db.DecrementProductStock(req.NameProduct, req.Category, req.Quantity); err != nil {
|
||||
if err := database.DecrementProductStock(req.NameProduct, req.Category, req.Quantity); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de réserver le stock"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{
|
||||
"success": true,
|
||||
"message": "Produit ajouté au panier avec succès",
|
||||
"panier": panier,
|
||||
})
|
||||
c.JSON(http.StatusCreated, gin.H{"success": true, "message": "Produit ajouté au panier avec succès", "panier": panier})
|
||||
}
|
||||
|
||||
// ============================================
|
||||
@@ -144,7 +163,7 @@ func GetAllBaskets(c *gin.Context) {
|
||||
|
||||
var totalAmount float64
|
||||
for _, item := range baskets {
|
||||
totalAmount += item.Price * item.Quantity
|
||||
totalAmount += item.Price // price = prix total de la ligne (cumul des ajouts)
|
||||
}
|
||||
|
||||
log.Printf("✅ [GET_PANIER] Panier %s: %d articles, total=%.2f€", username, len(baskets), totalAmount)
|
||||
|
||||
Reference in New Issue
Block a user