CartService.java
// ==============================================
// GRUPP 3: SERVICE & CONTROLLER - Kör efter modellerna
// ==============================================
// FILE: src/main/java/com/ctrlbuy/webshop/service/CartService.java
package com.ctrlbuy.webshop.service;
import com.ctrlbuy.webshop.model.Cart;
import com.ctrlbuy.webshop.model.CartItem;
import com.ctrlbuy.webshop.model.Product;
import com.ctrlbuy.webshop.repository.CartRepository;
import com.ctrlbuy.webshop.security.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Optional;
@Service
@Slf4j
@Transactional
public class CartService {
private final CartRepository cartRepository;
private final ProductService productService;
public CartService(CartRepository cartRepository, ProductService productService) {
this.cartRepository = cartRepository;
this.productService = productService;
}
// Hämta eller skapa kundvagn för inloggad användare
public Cart getOrCreateCartForUser(User user) {
Optional<Cart> existingCart = cartRepository.findByUserWithItems(user);
if (existingCart.isPresent()) {
log.debug("Found existing cart for user: {}", user.getEmail());
return existingCart.get();
}
log.debug("Creating new cart for user: {}", user.getEmail());
Cart newCart = Cart.builder()
.user(user)
.build();
return cartRepository.save(newCart);
}
// Hämta eller skapa kundvagn för session (icke-inloggad användare)
public Cart getOrCreateCartForSession(String sessionId) {
Optional<Cart> existingCart = cartRepository.findBySessionIdWithItems(sessionId);
if (existingCart.isPresent()) {
log.debug("Found existing cart for session: {}", sessionId);
return existingCart.get();
}
log.debug("Creating new cart for session: {}", sessionId);
Cart newCart = Cart.builder()
.sessionId(sessionId)
.build();
return cartRepository.save(newCart);
}
// Lägg till produkt i kundvagn
public Cart addProductToCart(Cart cart, Long productId, Integer quantity) {
Product product = productService.findById(productId)
.orElseThrow(() -> new RuntimeException("Product not found with id: " + productId));
// Kontrollera om produkten redan finns i kundvagnen
CartItem existingItem = cart.findItemByProduct(product);
if (existingItem != null) {
// Öka kvantiteten för befintlig produkt
existingItem.increaseQuantity(quantity);
log.debug("Updated quantity for product {} in cart. New quantity: {}",
product.getName(), existingItem.getQuantity());
} else {
// Skapa ny cart item
CartItem newItem = CartItem.builder()
.product(product)
.quantity(quantity)
.unitPrice(product.getPrice())
.cart(cart)
.build();
cart.addItem(newItem);
log.debug("Added new product {} to cart with quantity: {}",
product.getName(), quantity);
}
return cartRepository.save(cart);
}
// Uppdatera kvantitet för en produkt i kundvagnen
public Cart updateCartItemQuantity(Cart cart, Long productId, Integer newQuantity) {
Product product = productService.findById(productId)
.orElseThrow(() -> new RuntimeException("Product not found with id: " + productId));
CartItem item = cart.findItemByProduct(product);
if (item == null) {
throw new RuntimeException("Product not found in cart: " + productId);
}
if (newQuantity <= 0) {
cart.removeItem(item);
log.debug("Removed product {} from cart", product.getName());
} else {
item.updateQuantity(newQuantity);
log.debug("Updated quantity for product {} to {}", product.getName(), newQuantity);
}
return cartRepository.save(cart);
}
// Ta bort produkt från kundvagn
public Cart removeProductFromCart(Cart cart, Long productId) {
Product product = productService.findById(productId)
.orElseThrow(() -> new RuntimeException("Product not found with id: " + productId));
CartItem item = cart.findItemByProduct(product);
if (item != null) {
cart.removeItem(item);
log.debug("Removed product {} from cart", product.getName());
}
return cartRepository.save(cart);
}
// Rensa hela kundvagnen
public void clearCart(Cart cart) {
cart.clear();
cartRepository.save(cart);
log.debug("Cleared cart with id: {}", cart.getId());
}
// Slå ihop session-cart med användar-cart vid inloggning
public Cart mergeSessionCartWithUserCart(String sessionId, User user) {
Optional<Cart> sessionCart = cartRepository.findBySessionIdWithItems(sessionId);
if (sessionCart.isEmpty() || sessionCart.get().isEmpty()) {
log.debug("No session cart to merge for user: {}", user.getEmail());
return getOrCreateCartForUser(user);
}
Cart userCart = getOrCreateCartForUser(user);
Cart sessionCartEntity = sessionCart.get();
// Flytta över alla items från session-cart till user-cart
for (CartItem sessionItem : sessionCartEntity.getItems()) {
CartItem existingUserItem = userCart.findItemByProduct(sessionItem.getProduct());
if (existingUserItem != null) {
// Lägg ihop kvantiteterna
existingUserItem.increaseQuantity(sessionItem.getQuantity());
} else {
// Skapa ny item i user-cart
CartItem newItem = CartItem.builder()
.product(sessionItem.getProduct())
.quantity(sessionItem.getQuantity())
.unitPrice(sessionItem.getUnitPrice())
.cart(userCart)
.build();
userCart.addItem(newItem);
}
}
// Ta bort session-cart
cartRepository.delete(sessionCartEntity);
Cart savedCart = cartRepository.save(userCart);
log.debug("Merged session cart with user cart for user: {}", user.getEmail());
return savedCart;
}
// Hämta kundvagn baserat på användare eller session
public Cart getCurrentCart(User user, String sessionId) {
if (user != null) {
return getOrCreateCartForUser(user);
} else {
return getOrCreateCartForSession(sessionId);
}
}
// Räkna totalt antal items i kundvagn (för navigation badge)
public Integer getCartItemCount(User user, String sessionId) {
Cart cart = getCurrentCart(user, sessionId);
return cart.getTotalItems();
}
// Hämta total summa för kundvagn
public BigDecimal getCartTotal(User user, String sessionId) {
Cart cart = getCurrentCart(user, sessionId);
return cart.getTotalAmount();
}
}