Files
erp-imprimelibros/src/main/java/com/imprimelibros/erp/cart/CartService.java

149 lines
5.5 KiB
Java

package com.imprimelibros.erp.cart;
import jakarta.transaction.Transactional;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import com.imprimelibros.erp.presupuesto.classes.PresupuestoFormatter;
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
import com.imprimelibros.erp.common.Utils;
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
@Service
public class CartService {
private final CartRepository cartRepo;
private final CartItemRepository itemRepo;
private final MessageSource messageSource;
private final PresupuestoFormatter presupuestoFormatter;
private final PresupuestoRepository presupuestoRepo;
private final Utils utils;
public CartService(CartRepository cartRepo, CartItemRepository itemRepo,
MessageSource messageSource, PresupuestoFormatter presupuestoFormatter,
PresupuestoRepository presupuestoRepo, Utils utils) {
this.cartRepo = cartRepo;
this.itemRepo = itemRepo;
this.messageSource = messageSource;
this.presupuestoFormatter = presupuestoFormatter;
this.presupuestoRepo = presupuestoRepo;
this.utils = utils;
}
/** Devuelve el carrito activo o lo crea si no existe. */
@Transactional
public Cart getOrCreateActiveCart(Long userId) {
return cartRepo.findByUserIdAndStatus(userId, Cart.Status.ACTIVE)
.orElseGet(() -> {
Cart c = new Cart();
c.setUserId(userId);
c.setStatus(Cart.Status.ACTIVE);
return cartRepo.save(c);
});
}
/** Lista items (presupuestos) del carrito activo del usuario. */
@Transactional
public List<Map<String, Object>> listItems(Long userId, Locale locale) {
Cart cart = getOrCreateActiveCart(userId);
List<Map<String, Object>> resultados = new ArrayList<>();
List<CartItem> items = itemRepo.findByCartId(cart.getId());
for (CartItem item : items) {
Presupuesto p = presupuestoRepo.findById(item.getPresupuestoId())
.orElseThrow(() -> new IllegalStateException("Presupuesto no encontrado: " + item.getPresupuestoId()));
Map<String, Object> elemento = getElementoCart(p, locale);
elemento.put("cartItemId", item.getId());
resultados.add(elemento);
}
//System.out.println("Cart items: " + resultados);
return resultados;
}
/** Añade un presupuesto al carrito. Si ya está, no hace nada (idempotente). */
@Transactional
public void addPresupuesto(Long userId, Long presupuestoId) {
Cart cart = getOrCreateActiveCart(userId);
boolean exists = itemRepo.existsByCartIdAndPresupuestoId(cart.getId(), presupuestoId);
if (!exists) {
CartItem ci = new CartItem();
ci.setCart(cart);
ci.setPresupuestoId(presupuestoId);
itemRepo.save(ci);
}
}
/** Elimina una línea del carrito por ID de item (validando pertenencia). */
@Transactional
public void removeItem(Long userId, Long itemId) {
Cart cart = getOrCreateActiveCart(userId);
CartItem item = itemRepo.findById(itemId).orElseThrow(() -> new IllegalArgumentException("Item no existe"));
if (!item.getCart().getId().equals(cart.getId()))
throw new IllegalStateException("El item no pertenece a tu carrito");
itemRepo.delete(item);
}
/** Elimina una línea del carrito buscando por presupuesto_id. */
@Transactional
public void removeByPresupuesto(Long userId, Long presupuestoId) {
Cart cart = getOrCreateActiveCart(userId);
itemRepo.findByCartIdAndPresupuestoId(cart.getId(), presupuestoId)
.ifPresent(itemRepo::delete);
}
/** Vacía todo el carrito activo. */
@Transactional
public void clear(Long userId) {
Cart cart = getOrCreateActiveCart(userId);
itemRepo.deleteByCartId(cart.getId());
}
/** Marca el carrito como bloqueado (por ejemplo, antes de crear un pedido). */
@Transactional
public void lockCart(Long userId) {
Cart cart = getOrCreateActiveCart(userId);
cart.setStatus(Cart.Status.LOCKED);
cartRepo.save(cart);
}
@Transactional
public long countItems(Long userId) {
Cart cart = getOrCreateActiveCart(userId);
return itemRepo.findByCartId(cart.getId()).size();
}
private Map<String, Object> getElementoCart(Presupuesto presupuesto, Locale locale) {
Map<String, Object> resumen = new HashMap<>();
resumen.put("titulo", presupuesto.getTitulo());
resumen.put("imagen",
"/assets/images/imprimelibros/presupuestador/" + presupuesto.getTipoEncuadernacion() + ".png");
resumen.put("imagen_alt",
messageSource.getMessage("presupuesto." + presupuesto.getTipoEncuadernacion(), null, locale));
resumen.put("presupuestoId", presupuesto.getId());
Map<String, Object> detalles = utils.getTextoPresupuesto(presupuesto, locale);
resumen.put("baseTotal", Utils.formatCurrency(presupuesto.getBaseImponible(), locale));
resumen.put("base", presupuesto.getBaseImponible());
resumen.put("iva4", presupuesto.getIvaImporte4());
resumen.put("iva21", presupuesto.getIvaImporte21());
resumen.put("resumen", detalles);
return resumen;
}
}