chore: fix prices
This commit is contained in:
@@ -10,9 +10,9 @@ import (
|
||||
|
||||
// AddProductInBasket ajoute un produit au panier de l'utilisateur
|
||||
func (d *Database) AddProductInBasket(username, nameProduct string, quantity float64, category string) (*models.Panier, error) {
|
||||
// Rechercher le produit par son nom et catégorie
|
||||
// Rechercher le produit par son nom et catégorie (case-insensitive)
|
||||
var productID int
|
||||
productQuery := `SELECT id FROM products WHERE name = $1 AND category = $2`
|
||||
productQuery := `SELECT id FROM products WHERE LOWER(name) = LOWER($1) AND LOWER(category) = LOWER($2)`
|
||||
err := d.QueryRow(productQuery, nameProduct, category).Scan(&productID)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, fmt.Errorf("produit '%s' non trouvé dans la catégorie '%s'", nameProduct, category)
|
||||
@@ -29,18 +29,19 @@ func (d *Database) AddProductInBasket(username, nameProduct string, quantity flo
|
||||
|
||||
// Vérifier si le produit existe déjà dans le panier
|
||||
var existingID int
|
||||
var existingQuantity float64
|
||||
checkQuery := `SELECT id, quantity FROM baskets WHERE username = $1 AND product_id = $2`
|
||||
err = d.QueryRow(checkQuery, username, productID).Scan(&existingID, &existingQuantity)
|
||||
var existingQuantity, existingPrice float64
|
||||
checkQuery := `SELECT id, quantity, price FROM baskets WHERE username = $1 AND product_id = $2`
|
||||
err = d.QueryRow(checkQuery, username, productID).Scan(&existingID, &existingQuantity, &existingPrice)
|
||||
|
||||
if err == nil {
|
||||
// Produit déjà dans le panier : mettre à jour quantité et prix
|
||||
// Produit déjà dans le panier : cumuler quantité et prix total de la ligne
|
||||
newQuantity := existingQuantity + quantity
|
||||
newPrice := existingPrice + price
|
||||
updateQuery := `UPDATE baskets SET quantity = $1, price = $2, created_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $3 RETURNING id, username, product_id, quantity, price, created_at`
|
||||
|
||||
var basket models.Panier
|
||||
err = d.QueryRow(updateQuery, newQuantity, price, existingID).Scan(
|
||||
err = d.QueryRow(updateQuery, newQuantity, newPrice, existingID).Scan(
|
||||
&basket.ID,
|
||||
&basket.Username,
|
||||
&basket.ProductID,
|
||||
@@ -75,7 +76,85 @@ func (d *Database) AddProductInBasket(username, nameProduct string, quantity flo
|
||||
return &basket, nil
|
||||
}
|
||||
|
||||
// GetProductPrice récupère le prix réel d'un produit pour une quantité donnée
|
||||
// GetProductPriceByID récupère le prix d'un produit par son ID et quantité (NUMERIC exact)
|
||||
func (d *Database) GetProductPriceByID(productID int, quantity float64) (float64, error) {
|
||||
var price float64
|
||||
|
||||
// Comparaison NUMERIC précise : évite les problèmes float64 vs NUMERIC(10,3)
|
||||
exactQuery := `
|
||||
SELECT price FROM product_prices
|
||||
WHERE product_id = $1 AND quantity = ROUND($2::NUMERIC, 3)
|
||||
LIMIT 1
|
||||
`
|
||||
err := d.QueryRow(exactQuery, productID, quantity).Scan(&price)
|
||||
if err == nil {
|
||||
return price, nil
|
||||
}
|
||||
|
||||
// Fallback : palier inférieur le plus proche
|
||||
tierQuery := `
|
||||
SELECT price FROM product_prices
|
||||
WHERE product_id = $1 AND quantity <= ROUND($2::NUMERIC, 3)
|
||||
ORDER BY quantity DESC LIMIT 1
|
||||
`
|
||||
err = d.QueryRow(tierQuery, productID, quantity).Scan(&price)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("aucun prix trouvé pour product_id=%d qty=%.3f: %w", productID, quantity, err)
|
||||
}
|
||||
return price, nil
|
||||
}
|
||||
|
||||
// GetProductStockByID récupère le stock d'un produit par son ID
|
||||
func (d *Database) GetProductStockByID(productID int) (float64, error) {
|
||||
var stock float64
|
||||
err := d.QueryRow(`SELECT stock FROM products WHERE id = $1`, productID).Scan(&stock)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("produit %d non trouvé: %w", productID, err)
|
||||
}
|
||||
return stock, nil
|
||||
}
|
||||
|
||||
// AddProductInBasketByID ajoute un produit au panier en utilisant son ID directement
|
||||
func (d *Database) AddProductInBasketByID(username string, productID int, quantity float64) (*models.Panier, error) {
|
||||
price, err := d.GetProductPriceByID(productID, quantity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("erreur récupération prix: %w", err)
|
||||
}
|
||||
|
||||
var existingID int
|
||||
var existingQuantity, existingPrice float64
|
||||
checkQuery := `SELECT id, quantity, price FROM baskets WHERE username = $1 AND product_id = $2`
|
||||
err = d.QueryRow(checkQuery, username, productID).Scan(&existingID, &existingQuantity, &existingPrice)
|
||||
|
||||
if err == nil {
|
||||
newQuantity := existingQuantity + quantity
|
||||
newPrice := existingPrice + price
|
||||
updateQuery := `UPDATE baskets SET quantity = $1, price = $2, created_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $3 RETURNING id, username, product_id, quantity, price, created_at`
|
||||
var basket models.Panier
|
||||
err = d.QueryRow(updateQuery, newQuantity, newPrice, existingID).Scan(
|
||||
&basket.ID, &basket.Username, &basket.ProductID, &basket.Quantity, &basket.Price, &basket.CreatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("erreur lors de la mise à jour du panier: %w", err)
|
||||
}
|
||||
return &basket, nil
|
||||
}
|
||||
|
||||
insertQuery := `INSERT INTO baskets (username, product_id, quantity, price, created_at)
|
||||
VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP)
|
||||
RETURNING id, username, product_id, quantity, price, created_at`
|
||||
var basket models.Panier
|
||||
err = d.QueryRow(insertQuery, username, productID, quantity, price).Scan(
|
||||
&basket.ID, &basket.Username, &basket.ProductID, &basket.Quantity, &basket.Price, &basket.CreatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("erreur lors de l'ajout au panier: %w", err)
|
||||
}
|
||||
return &basket, nil
|
||||
}
|
||||
|
||||
// GetProductPrice récupère le prix réel d'un produit pour une quantité donnée (legacy)
|
||||
func (d *Database) GetProductPrice(name, category string, quantity float64) (float64, error) {
|
||||
var price float64
|
||||
|
||||
@@ -100,7 +179,7 @@ func (d *Database) GetProductPrice(name, category string, quantity float64) (flo
|
||||
|
||||
func (d *Database) GetProductStock(name, category string) (float64, error) {
|
||||
var stock float64
|
||||
query := `SELECT stock FROM products WHERE name = $1 AND category = $2`
|
||||
query := `SELECT stock FROM products WHERE LOWER(name) = LOWER($1) AND LOWER(category) = LOWER($2)`
|
||||
err := d.QueryRow(query, name, category).Scan(&stock)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("produit non trouvé: %w", err)
|
||||
@@ -109,7 +188,7 @@ func (d *Database) GetProductStock(name, category string) (float64, error) {
|
||||
}
|
||||
|
||||
func (d *Database) DecrementProductStock(name, category string, quantity float64) error {
|
||||
query := `UPDATE products SET stock = stock - $1 WHERE name = $2 AND category = $3 AND stock >= $1`
|
||||
query := `UPDATE products SET stock = stock - $1 WHERE LOWER(name) = LOWER($2) AND LOWER(category) = LOWER($3) AND stock >= $1`
|
||||
result, err := d.Exec(query, quantity, name, category)
|
||||
if err != nil {
|
||||
return fmt.Errorf("erreur mise à jour stock: %w", err)
|
||||
@@ -223,8 +302,9 @@ func (d *Database) ClearBasket(username string) error {
|
||||
}
|
||||
|
||||
// GetBasketTotal calcule le montant total du panier d'un utilisateur
|
||||
// price dans baskets = prix total de la ligne (cumul des ajouts)
|
||||
func (d *Database) GetBasketTotal(username string) (float64, error) {
|
||||
query := `SELECT COALESCE(SUM(quantity * price), 0) as total
|
||||
query := `SELECT COALESCE(SUM(price), 0) as total
|
||||
FROM baskets
|
||||
WHERE username = $1`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user