haciendo pagos pendientes

This commit is contained in:
2025-12-22 20:41:21 +01:00
parent 4cc47b4249
commit d4120bb486
18 changed files with 1312 additions and 572 deletions

View File

@ -11,6 +11,10 @@ import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.imprimelibros.erp.cart.Cart;
import com.imprimelibros.erp.cart.CartDireccion;
import com.imprimelibros.erp.cart.CartItem;
import com.imprimelibros.erp.cart.CartService;
import com.imprimelibros.erp.common.Utils;
import com.imprimelibros.erp.direcciones.Direccion;
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
@ -30,10 +34,11 @@ public class PedidoService {
private final DireccionService direccionService;
private final UserService userService;
private final PresupuestoService presupuestoService;
private final CartService cartService;
public PedidoService(PedidoRepository pedidoRepository, PedidoLineaRepository pedidoLineaRepository,
PresupuestoRepository presupuestoRepository, PedidoDireccionRepository pedidoDireccionRepository,
DireccionService direccionService, UserService userService, PresupuestoService presupuestoService) {
DireccionService direccionService, UserService userService, PresupuestoService presupuestoService, CartService cartService) {
this.pedidoRepository = pedidoRepository;
this.pedidoLineaRepository = pedidoLineaRepository;
this.presupuestoRepository = presupuestoRepository;
@ -41,48 +46,22 @@ public class PedidoService {
this.direccionService = direccionService;
this.userService = userService;
this.presupuestoService = presupuestoService;
this.cartService = cartService;
}
public int getDescuentoFidelizacion(Long userId) {
// descuento entre el 1% y el 6% para clientes fidelidad (mas de 1500€ en el
// ultimo año)
Instant haceUnAno = Instant.now().minusSeconds(365 * 24 * 60 * 60);
double totalGastado = pedidoRepository.sumTotalByCreatedByAndCreatedAtAfter(userId, haceUnAno);
if (totalGastado < 1200) {
return 0;
} else if (totalGastado >= 1200 && totalGastado < 1999) {
return 1;
} else if (totalGastado >= 2000 && totalGastado < 2999) {
return 2;
} else if (totalGastado >= 3000 && totalGastado < 3999) {
return 3;
} else if (totalGastado >= 4000 && totalGastado < 4999) {
return 4;
} else if (totalGastado >= 5000) {
return 5;
}
return 0;
}
/**
* Crea un pedido a partir de:
* - lista de IDs de presupuesto
* - resumen numérico del carrito (getCartSummaryRaw)
* - datos de proveedor
* - usuario que crea el pedido
*/
@Transactional
public Pedido crearPedido(
List<Long> presupuestoIds,
Map<String, Object> presupuestoDirecciones,
Long cartId,
Long direccionFacturacionId,
Map<String, Object> cartSummaryRaw,
String proveedor,
String proveedorRef,
Long userId) {
String proveedorRef) {
Pedido pedido = new Pedido();
Cart cart = cartService.getCartById(cartId);
Map<String, Object> cartSummaryRaw = cartService.getCartSummaryRaw(cart, Locale.getDefault());
// Datos económicos (ojo con las claves, son las del summaryRaw)
pedido.setBase((Double) cartSummaryRaw.getOrDefault("base", 0.0d));
pedido.setEnvio((Double) cartSummaryRaw.getOrDefault("shipment", 0.0d));
@ -92,10 +71,13 @@ public class PedidoService {
pedido.setTotal((Double) cartSummaryRaw.getOrDefault("total", 0.0d));
// Proveedor
pedido.setProveedor(proveedor);
pedido.setProveedorRef(proveedorRef);
if(proveedor != null && proveedorRef != null) {
pedido.setProveedor(proveedor);
pedido.setProveedorRef(proveedorRef);
}
// Auditoría mínima
Long userId = cart.getUserId();
pedido.setCreatedBy(userService.findById(userId));
pedido.setCreatedAt(Instant.now());
pedido.setDeleted(false);
@ -103,8 +85,36 @@ public class PedidoService {
pedido.setUpdatedBy(userService.findById(userId));
// Guardamos el pedido
Pedido saved = pedidoRepository.save(pedido);
Pedido pedidoGuardado = pedidoRepository.save(pedido);
List<CartItem> items = cart.getItems();
for (Integer i = 0; i < items.size(); i++) {
CartItem item = items.get(i);
Presupuesto pCart = item.getPresupuesto();
// Asegurarnos de trabajar con la entidad gestionada por JPA
Presupuesto p = presupuestoRepository.findById(pCart.getId())
.orElseThrow(() -> new IllegalStateException("Presupuesto no encontrado: " + pCart.getId()));
p.setEstado(Presupuesto.Estado.aceptado);
presupuestoRepository.save(p);
PedidoLinea linea = new PedidoLinea();
linea.setPedido(pedidoGuardado);
linea.setPresupuesto(p);
linea.setCreatedBy(userId);
linea.setCreatedAt(LocalDateTime.now());
linea.setEstado(PedidoLinea.Estado.pendiente_pago);
linea.setEstadoManual(false);
pedidoLineaRepository.save(linea);
// Guardar las direcciones asociadas a la línea del pedido
Map<String, Object> direcciones_presupuesto = this.getDireccionesPresupuesto(cart, p);
saveDireccionesPedidoLinea(direcciones_presupuesto, pedidoGuardado, linea, direccionFacturacionId);
}
/*
// Crear líneas del pedido
for (Long presupuestoId : presupuestoIds) {
Presupuesto presupuesto = presupuestoRepository.getReferenceById(presupuestoId);
@ -114,7 +124,11 @@ public class PedidoService {
linea.setPresupuesto(presupuesto);
linea.setCreatedBy(userId);
linea.setCreatedAt(LocalDateTime.now());
linea.setEstado(getEstadoInicial(presupuesto));
if(estadoInicial != null){
linea.setEstado(estadoInicial);
} else {
linea.setEstado(getEstadoInicial(presupuesto));
}
linea.setEstadoManual(false);
pedidoLineaRepository.save(linea);
@ -125,10 +139,175 @@ public class PedidoService {
saveDireccionesPedidoLinea(direcciones, saved, linea, direccionFacturacionId);
}
}
*/
return saved;
return pedidoGuardado;
}
public Boolean markPedidoAsProcesingPayment(Long pedidoId){
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
if(pedido == null){
return false;
}
List<PedidoLinea> lineas = pedidoLineaRepository.findByPedidoId(pedidoId);
for (PedidoLinea linea : lineas) {
linea.setEstado(PedidoLinea.Estado.procesando_pago);
pedidoLineaRepository.save(linea);
}
return true;
}
public Boolean markPedidoAsPaymentDenied(Long pedidoId){
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
if(pedido == null){
return false;
}
List<PedidoLinea> lineas = pedidoLineaRepository.findByPedidoId(pedidoId);
for (PedidoLinea linea : lineas) {
linea.setEstado(PedidoLinea.Estado.denegado_pago);
pedidoLineaRepository.save(linea);
}
return true;
}
public Boolean markPedidoAsPaid(Long pedidoId){
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
if(pedido == null){
return false;
}
List<PedidoLinea> lineas = pedidoLineaRepository.findByPedidoId(pedidoId);
for (PedidoLinea linea : lineas) {
linea.setEstado(this.getEstadoInicial(linea.getPresupuesto()));
pedidoLineaRepository.save(linea);
// Save presupuesto in SK
}
// Save pedido in SK
return true;
}
public Pedido findById(Long pedidoId){
return pedidoRepository.findById(pedidoId).orElse(null);
}
/*
@Transactional
public Long crearPedido(Long cartId, Long dirFactId, Locale locale) {
return crearPedido(cartId, dirFactId, locale, null);
}
@Transactional
// Crear pedido interno (no en el proveedor) a partir del carrito
public Long crearPedido(Long cartId, Long dirFactId, Locale locale, PedidoLinea.Estado estadoInicial) {
Cart cart = cartService.getCartById(cartId);
List<CartItem> items = cart.getItems();
List<Map<String, Object>> presupuestoRequests = new ArrayList<>();
Map<String, Object> presupuestoDireccionesRequest = new HashMap<>();
List<Long> presupuestoIds = new ArrayList<>();
for (Integer i = 0; i < items.size(); i++) {
CartItem item = items.get(i);
Presupuesto pCart = item.getPresupuesto();
// Asegurarnos de trabajar con la entidad gestionada por JPA
Presupuesto p = presupuestoRepository.findById(pCart.getId())
.orElseThrow(() -> new IllegalStateException("Presupuesto no encontrado: " + pCart.getId()));
/*Map<String, Object> data_to_send = presupuestoService.toSkApiRequest(p, true);
data_to_send.put("createPedido", 0);
// Recuperar el mapa anidado datosCabecera
@SuppressWarnings("unchecked")
Map<String, Object> datosCabecera = (Map<String, Object>) data_to_send.get("datosCabecera");
if (datosCabecera != null) {
Object tituloOriginal = datosCabecera.get("titulo");
datosCabecera.put(
"titulo",
"[" + (i + 1) + "/" + items.size() + "] " + (tituloOriginal != null ? tituloOriginal : ""));
}
Map<String, Object> direcciones_presupuesto = this.getDireccionesPresupuesto(cart, p);
data_to_send.put("direcciones", direcciones_presupuesto.get("direcciones"));
data_to_send.put("direccionesFP1", direcciones_presupuesto.get("direccionesFP1"));
presupuestoDireccionesRequest.put(p.getId().toString(), direcciones_presupuesto);
Map<String, Object> result = skApiClient.savePresupuesto(data_to_send);
if (result.containsKey("error")) {
System.out.println("Error al guardar presupuesto en SK");
System.out.println("-------------------------");
System.out.println(result.get("error"));
// decide si seguir con otros items o abortar:
// continue; o bien throw ...
continue;
}
Object dataObj = result.get("data");
if (!(dataObj instanceof Map<?, ?> dataRaw)) {
System.out.println("Formato inesperado de 'data' en savePresupuesto: " + result);
continue;
}
@SuppressWarnings("unchecked")
Map<String, Object> dataMap = (Map<String, Object>) dataRaw;
Long presId = ((Number) dataMap.get("id")).longValue();
String skin = ((String) dataMap.get("iskn")).toString();
p.setProveedor("Safekat");
p.setProveedorRef1(skin);
p.setProveedorRef2(presId);
p.setEstado(Presupuesto.Estado.aceptado);
presupuestoRepo.save(p);
presupuestoIds.add(p.getId());
presupuestoRequests.add(dataMap);
}
// Crear el pedido en base a los presupuestos guardados
if (presupuestoRequests.isEmpty()) {
throw new IllegalStateException("No se pudieron guardar los presupuestos en SK.");
} else {
ArrayList<Long> presupuestoSkIds = new ArrayList<>();
for (Map<String, Object> presData : presupuestoRequests) {
Long presId = ((Number) presData.get("id")).longValue();
presupuestoSkIds.add(presId);
}
Map<String, Object> ids = new HashMap<>();
ids.put("presupuesto_ids", presupuestoSkIds);
Long pedidoId = skApiClient.crearPedido(ids);
if (pedidoId == null) {
throw new IllegalStateException("No se pudo crear el pedido en SK.");
}
Pedido pedidoInterno = pedidoService.crearPedido(
presupuestoIds,
presupuestoDireccionesRequest,
dirFactId,
this.getCartSummaryRaw(cart, locale),
"Safekat",
String.valueOf(pedidoId),
cart.getUserId(),
estadoInicial);
return pedidoInterno.getId();
}
}
*/
/** Lista de los items del pedido preparados para la vista*/
@Transactional
public List<Map<String, Object>> getLineas(Long pedidoId, Locale locale) {
@ -160,17 +339,119 @@ public class PedidoService {
return pedidoDireccionRepository.findByPedidoLinea_Id(pedidoLineaId);
}
public Boolean setOrderAsPaid(Long pedidoId) {
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
if (pedido == null) {
return false;
}
List<PedidoLinea> lineas = pedidoLineaRepository.findByPedidoId(pedidoId);
for (PedidoLinea linea : lineas) {
if (linea.getEstado() == Estado.pendiente_pago) {
Presupuesto presupuesto = linea.getPresupuesto();
linea.setEstado(getEstadoInicial(presupuesto));
pedidoLineaRepository.save(linea);
}
}
return true;
}
/***************************
* MÉTODOS PRIVADOS
***************************/
// Obtener las direcciones de envío asociadas a un presupuesto en el carrito
private Map<String, Object> getDireccionesPresupuesto(Cart cart, Presupuesto presupuesto) {
List<Map<String, Object>> direccionesPresupuesto = new ArrayList<>();
List<Map<String, Object>> direccionesPrueba = new ArrayList<>();
if (cart.getOnlyOneShipment()) {
List<CartDireccion> direcciones = cart.getDirecciones().stream().limit(1).toList();
if (!direcciones.isEmpty()) {
if (presupuesto.getServiciosJson() != null
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
presupuesto.getSelectedTirada(),
presupuesto.getPeso(),
direcciones.get(0).getIsPalets(),
false));
direccionesPresupuesto.add(direcciones.get(0).toSkMapDepositoLegal());
}
else {
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
presupuesto.getSelectedTirada(),
presupuesto.getPeso(),
direcciones.get(0).getIsPalets(),
false));
}
if (presupuesto.getServiciosJson() != null
&& presupuesto.getServiciosJson().contains("ejemplar-prueba")) {
direccionesPrueba.add(direcciones.get(0).toSkMap(
1,
presupuesto.getPeso(),
false,
true));
}
Map<String, Object> direccionesRet = new HashMap<>();
direccionesRet.put("direcciones", direccionesPresupuesto);
if (!direccionesPrueba.isEmpty())
direccionesRet.put("direccionesFP1", direccionesPrueba.get(0));
else {
direccionesRet.put("direccionesFP1", new ArrayList<>());
}
return direccionesRet;
}
} else {
List<CartDireccion> direcciones = cart.getDirecciones().stream()
.filter(d -> d.getPresupuesto() != null && d.getPresupuesto().getId().equals(presupuesto.getId()))
.toList();
for (CartDireccion cd : direcciones) {
// direccion de ejemplar de prueba
if (cd.getPresupuesto() == null || !cd.getPresupuesto().getId().equals(presupuesto.getId())) {
continue;
}
if (cd.getUnidades() == null || cd.getUnidades() <= 0) {
direccionesPrueba.add(cd.toSkMap(
1,
presupuesto.getPeso(),
false,
true));
} else {
direccionesPresupuesto.add(cd.toSkMap(
cd.getUnidades(),
presupuesto.getPeso(),
cd.getIsPalets(),
false));
}
}
if (presupuesto.getServiciosJson() != null
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
CartDireccion cd = new CartDireccion();
direccionesPresupuesto.add(cd.toSkMapDepositoLegal());
}
}
Map<String, Object> direccionesRet = new HashMap<>();
direccionesRet.put("direcciones", direccionesPresupuesto);
if (!direccionesPrueba.isEmpty())
direccionesRet.put("direccionesFP1", direccionesPrueba.get(0));
else {
direccionesRet.put("direccionesFP1", new ArrayList<>());
}
return direccionesRet;
}
@Transactional
private void saveDireccionesPedidoLinea(
Map<String, Map<String, Object>> direcciones,
Map<String, Object> direcciones,
Pedido pedido,
PedidoLinea linea, Long direccionFacturacionId) {
// direccion prueba
if (direcciones.containsKey("direccionesFP1")) {
try {
@SuppressWarnings("unchecked")
Map<String, Object> fp1 = (Map<String, Object>) direcciones.get("direccionesFP1");
@SuppressWarnings("unchecked")
PedidoDireccion direccion = saveDireccion(