diff --git a/src/main/java/com/marketingconfort/mydressin/repositories/CartRepository.java b/src/main/java/com/marketingconfort/mydressin/repositories/CartRepository.java index a73c5d9eb30358314f94c4a8665a0ca5160cec8d..71eecf3b25b2bf51fd7f5e648a1f258ab539be4d 100644 --- a/src/main/java/com/marketingconfort/mydressin/repositories/CartRepository.java +++ b/src/main/java/com/marketingconfort/mydressin/repositories/CartRepository.java @@ -98,4 +98,7 @@ public interface CartRepository extends JpaRepository<Cart, Long>, JpaSpecificat @Param("clientId") Long clientId, @Param("status") Status status); + @Lock(LockModeType.PESSIMISTIC_WRITE) + List<Cart> findAllByClientIdAndStatus(Long clientId, Status status); + } diff --git a/src/main/java/com/marketingconfort/mydressin/services/impl/CartServiceImp.java b/src/main/java/com/marketingconfort/mydressin/services/impl/CartServiceImp.java index 5f374acc91d00c8318df1f2472cb95edbf0e90c1..c6aca4a51acc36f25c97c79b71cb1d54069c77f3 100644 --- a/src/main/java/com/marketingconfort/mydressin/services/impl/CartServiceImp.java +++ b/src/main/java/com/marketingconfort/mydressin/services/impl/CartServiceImp.java @@ -41,6 +41,7 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; @@ -78,13 +79,72 @@ public class CartServiceImp implements CartService { } - @Transactional + @Transactional(isolation = Isolation.SERIALIZABLE) @Override public Cart findOrCreateCartByClientId(Long clientId) { + List<Cart> existingCarts = cartRepository.findAllByClientIdAndStatus(clientId, Status.open); + + if (existingCarts.size() > 1) { + Cart latestCart = existingCarts.stream() + .sorted(Comparator.comparing(Cart::getCreatedDate).reversed()) + .findFirst() + .orElse(null); + + for (Cart cart : existingCarts) { + if (!cart.getId().equals(latestCart.getId())) { + try { + mergeCartItems(cart, latestCart); + cartRepository.delete(cart); + logger.warn("Duplicate cart deleted: ID={} for clientId={}", cart.getId(), clientId); + } catch (Exception e) { + logger.error("Error while deleting a duplicate cart: {}", e.getMessage()); + } + } + } + + return latestCart; + } + Optional<Cart> optionalCart = cartRepository.findByClientIdAndStatus(clientId, Status.open); return optionalCart.orElseGet(() -> createNewCartClient(clientId)); } + // Ajouter cette méthode pour fusionner les éléments de panier + private void mergeCartItems(Cart sourceCart, Cart targetCart) { + if (sourceCart.getItems() != null && !sourceCart.getItems().isEmpty()) { + sourceCart.getItems().forEach(item -> { + if (!item.isExpired() && !item.isPayed() && + item.getStatus() != ItemCartStatus.DELETED_BO && + item.getStatus() != ItemCartStatus.DELETED_SITE) { + + // Vérifier si l'élément existe déjà dans le panier cible + Optional<ItemCart> existingItem = targetCart.getItems().stream() + .filter(targetItem -> targetItem.getProductId().equals(item.getProductId()) && + targetItem.getSource() == item.getSource()) + .findFirst(); + + if (existingItem.isPresent()) { + // Mettre à jour la quantité + existingItem.get().setQuantity(existingItem.get().getQuantity() + item.getQuantity()); + } else { + // Transférer l'élément + item.setCart(targetCart); + targetCart.getItems().add(item); + } + } + }); + } + + // Fusionner les codes promo et cartes cadeaux si nécessaire + if (sourceCart.getPromoCodeIds() != null) { + targetCart.getPromoCodeIds().addAll(sourceCart.getPromoCodeIds()); + } + + if (sourceCart.getGiftCardIds() != null) { + targetCart.getGiftCardIds().addAll(sourceCart.getGiftCardIds()); + } + } + @Override public Cart createNewCartClient(Long clientId) { Cart cart = new Cart();