chore: fix

This commit is contained in:
2026-05-03 19:38:29 +02:00
parent 4075ae2568
commit f8473b9a54
27 changed files with 608 additions and 115 deletions
+5
View File
@@ -256,6 +256,11 @@ func (d *Database) ClearBasket(username string) error {
})
}
// ClearBasketOnCheckout vide le panier après commande validée SANS restituer le stock.
func (d *Database) ClearBasketOnCheckout(username string) error {
return d.GDB.Exec(`DELETE FROM baskets WHERE username = ?`, username).Error
}
// GetBasketTotal calcule le montant total du panier d'un utilisateur
func (d *Database) GetBasketTotal(username string) (float64, error) {
var result struct {
+8 -9
View File
@@ -231,14 +231,7 @@ func (d *Database) CreateCommandWithAddress(username, deliveryAddress string) (*
return nil, fmt.Errorf("erreur insertion items: %w", err)
}
result := d.GDB.Model(&models.Product{}).Where("id = ? AND stock >= ?", item.ProductID, item.Quantity).UpdateColumn("stock", gorm.Expr("stock - ?", item.Quantity))
if result.Error != nil {
log.Printf("⚠️ Erreur décrémentation stock produit %d: %v", item.ProductID, result.Error)
return nil, fmt.Errorf("erreur mise à jour stock: %w", result.Error)
}
if result.RowsAffected == 0 {
log.Printf("⚠️ [CHECKOUT] Stock déjà réservé pour produit %d (double réservation panier/checkout)", item.ProductID)
}
// Stock déjà déduit à l'ajout au panier — ne pas déduire une seconde fois ici.
}
if err := d.GDB.Delete(&models.Panier{}, "username = ?", username).Error; err != nil {
@@ -296,13 +289,17 @@ func (d *Database) GetAllCommands(status, username string) ([]map[string]any, er
ProposedAddress *string `gorm:"column:proposed_address"`
AddressProposalStatus string `gorm:"column:address_proposal_status"`
ClientOrderNumber int `gorm:"column:client_order_number"`
ReferralUsed float64 `gorm:"column:referral_used"`
CancelReason string `gorm:"column:cancel_reason"`
}
gdb := d.GDB.Table("commandes c").
Select(`c.id, c.username, c.status, c.adresse, c.total_prix,
c.livreur_assign, c.created_at, c.updated_at,
c.proposed_address, c.address_proposal_status,
c.client_order_id AS client_order_number`)
c.client_order_id AS client_order_number,
COALESCE(c.referral_used, 0) AS referral_used,
COALESCE(c.cancel_reason, '') AS cancel_reason`)
if status == "" {
gdb = gdb.Where("c.status IN ?", []string{"pending", "assigned", "en_route", "arrived", "livre"})
@@ -330,6 +327,8 @@ func (d *Database) GetAllCommands(status, username string) ([]map[string]any, er
"updated_at": row.UpdatedAt,
"address_proposal_status": row.AddressProposalStatus,
"client_order_number": row.ClientOrderNumber,
"referral_used": row.ReferralUsed,
"cancel_reason": row.CancelReason,
}
if row.LivreurAssign != nil {
+11
View File
@@ -48,6 +48,17 @@ func (d *Database) DebitReferralBalance(username string, amount float64) error {
})
}
func (d *Database) ResetClientReferralBalance(username string) error {
result := d.GDB.Model(&models.Client{}).Where("username = ?", username).Update("referral_balance", 0)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("client non trouvé")
}
return nil
}
func (d *Database) UseClientReferralBalance(tx *gorm.DB, username string, amount float64) error {
if amount <= 0 {
return nil
+1 -1
View File
@@ -631,7 +631,7 @@ func ForceValidateDelivery(c *gin.Context) {
livreurAssign, _ := command["livreur_assign"].(string)
if clientUsername != "" {
clientMsg := fmt.Sprintf("Ta commande #%d a bien été livrée ! Bonne dégustation l'ami et à bientôt 😊", database.GetClientOrderID(commandID))
clientMsg := fmt.Sprintf("Ta commande #%d a bien été livrée ! Bonne dégustation l'ami et à bientôt 😊\n\n<b>⚠️ VALIDE LA RÉCEPTION DE TA COMMANDE DANS LA RUBRIQUE SUIVI POUR RÉCUPÉRER TES POINTS DE FIDÉLITÉ ⚠️</b>", database.GetClientOrderID(commandID))
database.NotifyClient(clientUsername, commandID, "livre", clientMsg)
}
+1 -1
View File
@@ -375,7 +375,7 @@ func UpdateDeliveryStatus(c *gin.Context) {
case "arrived":
clientMsg = fmt.Sprintf("Descend, le livreur est là dans 3min (commande #%d) 🛵", database.GetClientOrderID(commandID))
case "livre":
clientMsg = fmt.Sprintf("Ta commande #%d a bien été livrée ! Bonne dégustation l'ami et à bientôt 😊", database.GetClientOrderID(commandID))
clientMsg = fmt.Sprintf("Ta commande #%d a bien été livrée ! Bonne dégustation l'ami et à bientôt 😊\n\n<b>⚠️ VALIDE LA RÉCEPTION DE TA COMMANDE DANS LA RUBRIQUE SUIVI POUR RÉCUPÉRER TES POINTS DE FIDÉLITÉ ⚠️</b>", database.GetClientOrderID(commandID))
case "cancelled":
clientMsg = fmt.Sprintf("Votre commande #%d a été annulée par le livreur", database.GetClientOrderID(commandID))
}
+2 -2
View File
@@ -483,9 +483,9 @@ func ValidateBasket(c *gin.Context) {
go database.NotifyAllAdminCabine(commandID, usernameStr, req.DeliveryAddress)
// ============================================
// 3️⃣ Vider le panier
// 3️⃣ Vider le panier (sans restituer le stock — déjà déduit à l'ajout)
// ============================================
err = database.ClearBasket(usernameStr)
err = database.ClearBasketOnCheckout(usernameStr)
if err != nil {
utils.ServerErr(c, "Impossible de vider le panier", err)
return
+17
View File
@@ -61,6 +61,23 @@ func CreditClientReferralAdmin(c *gin.Context) {
})
}
// ResetClientReferralAdmin — DELETE /api/v2/admin/protected/client/:username/referral/reset (admin)
func ResetClientReferralAdmin(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
targetUsername := c.Param("username")
if err := database.ResetClientReferralBalance(targetUsername); err != nil {
utils.ServerErr(c, "Impossible de réinitialiser le solde", err)
return
}
log.Printf("✅ [REFERRAL] Solde parrainage remis à zéro pour %s", targetUsername)
c.JSON(http.StatusOK, gin.H{
"message": "Solde parrainage réinitialisé",
"balance": 0,
})
}
// GetClientReferralAdmin — GET /api/v2/admin/protected/client/:username/referral (admin)
func GetClientReferralAdmin(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
+1
View File
@@ -265,6 +265,7 @@ func SetupRoutes(router *gin.Engine, database *db.Database, geoService *services
// 🎁 PARRAINAGE ADMIN
adminGroupV2.GET("/client/:username/referral", handlers.GetClientReferralAdmin)
adminGroupV2.POST("/client/:username/referral/credit", handlers.CreditClientReferralAdmin)
adminGroupV2.DELETE("/client/:username/referral/reset", handlers.ResetClientReferralAdmin)
adminGroupV2.POST("/client/:username/parrain/set", handlers.SetClientParrainAdmin)
adminGroupV2.GET("/client/:username/parrain", handlers.GetClientParrainAdmin)
adminGroupV2.GET("/parrain/stats", handlers.GetParrainStatsAdmin)