MIF_E31222379_BE/internal/repositories/trashcart_repo.go

167 lines
4.3 KiB
Go

package repositories
import (
"context"
"errors"
"fmt"
"rijig/config"
"rijig/model"
"gorm.io/gorm"
)
type CartRepository interface {
FindOrCreateCart(ctx context.Context, userID string) (*model.Cart, error)
AddOrUpdateCartItem(ctx context.Context, cartID, trashCategoryID string, amount float64, estimatedPrice float64) error
DeleteCartItem(ctx context.Context, cartID, trashCategoryID string) error
GetCartByUser(ctx context.Context, userID string) (*model.Cart, error)
UpdateCartTotals(ctx context.Context, cartID string) error
DeleteCart(ctx context.Context, userID string) error
// New method for batch cart creation
CreateCartWithItems(ctx context.Context, cart *model.Cart) error
// Check if user already has a cart
HasExistingCart(ctx context.Context, userID string) (bool, error)
}
type cartRepository struct{}
func NewCartRepository() CartRepository {
return &cartRepository{}
}
func (r *cartRepository) FindOrCreateCart(ctx context.Context, userID string) (*model.Cart, error) {
var cart model.Cart
db := config.DB.WithContext(ctx)
err := db.
Preload("CartItems.TrashCategory").
Where("user_id = ?", userID).
First(&cart).Error
if err == nil {
return &cart, nil
}
if errors.Is(err, gorm.ErrRecordNotFound) {
newCart := model.Cart{
UserID: userID,
TotalAmount: 0,
EstimatedTotalPrice: 0,
}
if err := db.Create(&newCart).Error; err != nil {
return nil, err
}
return &newCart, nil
}
return nil, err
}
func (r *cartRepository) AddOrUpdateCartItem(ctx context.Context, cartID, trashCategoryID string, amount float64, estimatedPrice float64) error {
db := config.DB.WithContext(ctx)
var item model.CartItem
err := db.
Where("cart_id = ? AND trash_category_id = ?", cartID, trashCategoryID).
First(&item).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
newItem := model.CartItem{
CartID: cartID,
TrashCategoryID: trashCategoryID,
Amount: amount,
SubTotalEstimatedPrice: amount * estimatedPrice,
}
return db.Create(&newItem).Error
}
if err != nil {
return err
}
item.Amount = amount
item.SubTotalEstimatedPrice = amount * estimatedPrice
return db.Save(&item).Error
}
func (r *cartRepository) DeleteCartItem(ctx context.Context, cartID, trashCategoryID string) error {
db := config.DB.WithContext(ctx)
return db.Where("cart_id = ? AND trash_category_id = ?", cartID, trashCategoryID).
Delete(&model.CartItem{}).Error
}
func (r *cartRepository) GetCartByUser(ctx context.Context, userID string) (*model.Cart, error) {
var cart model.Cart
db := config.DB.WithContext(ctx)
err := db.
Preload("CartItems.TrashCategory").
Where("user_id = ?", userID).
First(&cart).Error
if err != nil {
return nil, err
}
return &cart, nil
}
func (r *cartRepository) UpdateCartTotals(ctx context.Context, cartID string) error {
db := config.DB.WithContext(ctx)
var items []model.CartItem
if err := db.Where("cart_id = ?", cartID).Find(&items).Error; err != nil {
return err
}
var totalAmount float64
var totalPrice float64
for _, item := range items {
totalAmount += item.Amount
totalPrice += item.SubTotalEstimatedPrice
}
return db.Model(&model.Cart{}).
Where("id = ?", cartID).
Updates(map[string]interface{}{
"total_amount": totalAmount,
"estimated_total_price": totalPrice,
}).Error
}
func (r *cartRepository) DeleteCart(ctx context.Context, userID string) error {
db := config.DB.WithContext(ctx)
var cart model.Cart
if err := db.Where("user_id = ?", userID).First(&cart).Error; err != nil {
return err
}
return db.Delete(&cart).Error
}
// New method for batch cart creation with transaction
func (r *cartRepository) CreateCartWithItems(ctx context.Context, cart *model.Cart) error {
db := config.DB.WithContext(ctx)
// Use transaction to ensure data consistency
return db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(cart).Error; err != nil {
return fmt.Errorf("failed to create cart: %w", err)
}
return nil
})
}
// Check if user already has a cart
func (r *cartRepository) HasExistingCart(ctx context.Context, userID string) (bool, error) {
db := config.DB.WithContext(ctx)
var count int64
err := db.Model(&model.Cart{}).Where("user_id = ?", userID).Count(&count).Error
if err != nil {
return false, err
}
return count > 0, nil
}