diff --git a/backend/gestion/db/db_command_items.go b/backend/gestion/db/db_command_items.go index 61ef85a5..379848b4 100644 --- a/backend/gestion/db/db_command_items.go +++ b/backend/gestion/db/db_command_items.go @@ -8,6 +8,33 @@ import ( "time" ) +// commandItemFull mappe toutes les colonnes de command_items pour les insertions batch avec infos client. +type commandItemFull struct { + CommandID int `gorm:"column:command_id"` + Produit string `gorm:"column:produit"` + ProductID int `gorm:"column:product_id"` + Quantite float64 `gorm:"column:quantite"` + Prix float64 `gorm:"column:prix"` + IsReward bool `gorm:"column:is_reward"` + RewardPoolKey string `gorm:"column:reward_pool_key"` + ClientUsername string `gorm:"column:client_username"` + ClientNom string `gorm:"column:client_nom"` + ClientPrenom string `gorm:"column:client_prenom"` + ClientTelephone string `gorm:"column:client_telephone"` + DeliveryAddress string `gorm:"column:delivery_address"` + Status string `gorm:"column:status"` +} + +func (commandItemFull) TableName() string { return "command_items" } + +// InsertCommandItemsBatch insère plusieurs items en une seule requête. +func (d *Database) InsertCommandItemsBatch(items []commandItemFull) error { + if len(items) == 0 { + return nil + } + return d.GDB.Create(&items).Error +} + // ============================================ // VALIDATION HELPERS // ============================================ diff --git a/backend/gestion/db/db_commands.go b/backend/gestion/db/db_commands.go index d42e8868..38b69f46 100644 --- a/backend/gestion/db/db_commands.go +++ b/backend/gestion/db/db_commands.go @@ -128,13 +128,13 @@ func (d *Database) CreateCommand(username string) (*models.Command, error) { } productNames, _ := d.GetProductNamesByIDs(productIDs) + cmdItems := make([]models.CommandItem, 0, len(basketItems)) for _, item := range basketItems { productName := productNames[item.ProductID] if productName == "" { productName = "Produit inconnu" } - - cmdItem := models.CommandItem{ + cmdItems = append(cmdItems, models.CommandItem{ CommandID: commandID, Produit: productName, ProductID: item.ProductID, @@ -142,11 +142,10 @@ func (d *Database) CreateCommand(username string) (*models.Command, error) { Price: item.Price, IsReward: item.IsReward, RewardPoolKey: item.RewardPoolKey, - } - if err := d.GDB.Create(&cmdItem).Error; err != nil { - return nil, fmt.Errorf("erreur lors de l'insertion des items: %w", err) - } - + }) + } + if err := d.GDB.Create(&cmdItems).Error; err != nil { + return nil, fmt.Errorf("erreur lors de l'insertion des items: %w", err) } if err := d.GDB.Exec(`DELETE FROM baskets WHERE username = ?`, username).Error; err != nil { @@ -229,33 +228,33 @@ func (d *Database) CreateCommandWithAddress(username, deliveryAddress string) (* } productNames2, _ := d.GetProductNamesByIDs(productIDs2) + batchItems := make([]commandItemFull, 0, len(basketItems)) for _, item := range basketItems { productName := productNames2[item.ProductID] if productName == "" { productName = fmt.Sprintf("Produit #%d", item.ProductID) } - - err = d.InsertCommandItemWithClientInfo( - commandID, - productName, - item.ProductID, - item.Quantity, - item.Price, - item.IsReward, - item.RewardPoolKey, - username, - clientNom, - clientPrenom, - clientTelephone, - deliveryAddress, - ) - if err != nil { - log.Printf("❌ Erreur INSERT command_items: %v", err) - return nil, fmt.Errorf("erreur insertion items: %w", err) - } - + batchItems = append(batchItems, commandItemFull{ + CommandID: commandID, + Produit: productName, + ProductID: item.ProductID, + Quantite: item.Quantity, + Prix: item.Price, + IsReward: item.IsReward, + RewardPoolKey: item.RewardPoolKey, + ClientUsername: username, + ClientNom: clientNom, + ClientPrenom: clientPrenom, + ClientTelephone: clientTelephone, + DeliveryAddress: deliveryAddress, + Status: "pending", + }) // Stock déjà déduit à l'ajout au panier — ne pas déduire une seconde fois ici. } + if err := d.InsertCommandItemsBatch(batchItems); err != nil { + log.Printf("❌ Erreur INSERT command_items batch: %v", err) + return nil, fmt.Errorf("erreur insertion items: %w", err) + } if err := d.GDB.Exec(`DELETE FROM baskets WHERE username = ?`, username).Error; err != nil { log.Printf("⚠️ Erreur vidage panier: %v", err) diff --git a/backend/gestion/db/db_product.go b/backend/gestion/db/db_product.go index f339b57c..cca77256 100644 --- a/backend/gestion/db/db_product.go +++ b/backend/gestion/db/db_product.go @@ -73,14 +73,21 @@ func (d *Database) CreateProduct(product any) error { p.SetCreatedAt(result.CreatedAt) p.SetUpdatedAt(result.UpdatedAt) - for i, price := range p.GetPrices() { - err := d.GDB.Exec(`INSERT INTO product_prices (product_id, quantity, price, active_price) VALUES (?, ?, ?, ?)`, - result.ID, price.Quantity, price.Price, price.ActivePrice).Error - if err != nil { - log.Printf("❌ [DB CreateProduct] Erreur insertion prix[%d]: %v", i, err) + if rawPrices := p.GetPrices(); len(rawPrices) > 0 { + priceRows := make([]models.ProductPrice, len(rawPrices)) + for i, price := range rawPrices { + priceRows[i] = models.ProductPrice{ + ProductID: result.ID, + Quantity: price.Quantity, + Price: price.Price, + ActivePrice: price.ActivePrice, + } + } + if err := d.GDB.Create(&priceRows).Error; err != nil { + log.Printf("❌ [DB CreateProduct] Erreur insertion prix batch: %v", err) return fmt.Errorf("erreur insertion prix: %v", err) } - log.Printf("✅ [DB CreateProduct] Prix[%d] inséré: quantity=%g, price=%.2f", i, price.Quantity, price.Price) + log.Printf("✅ [DB CreateProduct] %d prix insérés", len(priceRows)) } log.Printf("🎉 [DB CreateProduct] Produit créé avec succès! ID=%d", result.ID) @@ -216,9 +223,17 @@ func (d *Database) UpdateProduct(productID int, name, category, description, uni d.GDB.Exec(`DELETE FROM product_prices WHERE product_id = ?`, productID) - for _, price := range prices { - if err := d.GDB.Exec(`INSERT INTO product_prices (product_id, quantity, price, active_price) VALUES (?, ?, ?, ?)`, - productID, price.Quantity, price.Price, price.ActivePrice).Error; err != nil { + if len(prices) > 0 { + priceRows := make([]models.ProductPrice, len(prices)) + for i, price := range prices { + priceRows[i] = models.ProductPrice{ + ProductID: productID, + Quantity: price.Quantity, + Price: price.Price, + ActivePrice: price.ActivePrice, + } + } + if err := d.GDB.Create(&priceRows).Error; err != nil { return fmt.Errorf("erreur insertion prix: %w", err) } }