mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 00:48:49 +00:00
terminado (provisional) modulo de facturas
This commit is contained in:
@ -3,20 +3,26 @@ package com.imprimelibros.erp.facturacion.service;
|
||||
import com.imprimelibros.erp.common.Utils;
|
||||
import com.imprimelibros.erp.configurationERP.VariableService;
|
||||
import com.imprimelibros.erp.facturacion.*;
|
||||
import com.imprimelibros.erp.facturacion.dto.DireccionFacturacionDto;
|
||||
import com.imprimelibros.erp.facturacion.dto.FacturaDireccionMapper;
|
||||
import com.imprimelibros.erp.facturacion.dto.FacturaGuardarDto;
|
||||
import com.imprimelibros.erp.facturacion.dto.FacturaLineaUpsertDto;
|
||||
import com.imprimelibros.erp.facturacion.dto.FacturaPagoUpsertDto;
|
||||
import com.imprimelibros.erp.facturacion.repo.FacturaDireccionRepository;
|
||||
import com.imprimelibros.erp.facturacion.repo.FacturaLineaRepository;
|
||||
import com.imprimelibros.erp.facturacion.repo.FacturaPagoRepository;
|
||||
import com.imprimelibros.erp.facturacion.repo.FacturaRepository;
|
||||
import com.imprimelibros.erp.facturacion.repo.SerieFacturaRepository;
|
||||
import com.imprimelibros.erp.pedidos.Pedido;
|
||||
import com.imprimelibros.erp.pedidos.PedidoDireccion;
|
||||
import com.imprimelibros.erp.pedidos.PedidoLinea;
|
||||
import com.imprimelibros.erp.pedidos.PedidoLineaRepository;
|
||||
import com.imprimelibros.erp.pedidos.PedidoService;
|
||||
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||
import com.imprimelibros.erp.users.User;
|
||||
import com.imprimelibros.erp.users.UserService;
|
||||
import com.imprimelibros.erp.direcciones.Direccion;
|
||||
import com.imprimelibros.erp.direcciones.DireccionRepository;
|
||||
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
|
||||
@ -25,12 +31,17 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Locale;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.security.Principal;
|
||||
import java.text.Collator;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
@ -42,6 +53,7 @@ public class FacturacionService {
|
||||
private final SerieFacturaRepository serieRepo;
|
||||
private final FacturaPagoRepository pagoRepo;
|
||||
private final FacturaLineaRepository lineaFacturaRepository;
|
||||
private final DireccionRepository direccionRepo;
|
||||
private final PedidoLineaRepository pedidoLineaRepo;
|
||||
private final UserService userService;
|
||||
private final Utils utils;
|
||||
@ -54,6 +66,7 @@ public class FacturacionService {
|
||||
FacturaLineaRepository lineaFacturaRepository,
|
||||
SerieFacturaRepository serieRepo,
|
||||
FacturaPagoRepository pagoRepo,
|
||||
DireccionRepository direccionRepo,
|
||||
PedidoLineaRepository pedidoLineaRepo,
|
||||
UserService userService,
|
||||
Utils utils,
|
||||
@ -64,6 +77,7 @@ public class FacturacionService {
|
||||
this.lineaFacturaRepository = lineaFacturaRepository;
|
||||
this.serieRepo = serieRepo;
|
||||
this.pagoRepo = pagoRepo;
|
||||
this.direccionRepo = direccionRepo;
|
||||
this.pedidoLineaRepo = pedidoLineaRepo;
|
||||
this.userService = userService;
|
||||
this.utils = utils;
|
||||
@ -87,6 +101,14 @@ public class FacturacionService {
|
||||
.orElseThrow(() -> new EntityNotFoundException("Factura no encontrada: " + facturaId));
|
||||
}
|
||||
|
||||
public Long getFacturaIdFromPedidoId(Long pedidoId) {
|
||||
Factura factura = facturaRepo.findByPedidoId(pedidoId);
|
||||
if (factura == null) {
|
||||
throw new EntityNotFoundException("Factura no encontrada para el pedido: " + pedidoId);
|
||||
}
|
||||
return factura.getId();
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Nueva factura
|
||||
// -----------------------
|
||||
@ -147,6 +169,13 @@ public class FacturacionService {
|
||||
lineaEnvio.setFactura(factura);
|
||||
lineasFactura.add(lineaEnvio);
|
||||
}
|
||||
PedidoDireccion direccionPedido = pedidoService.getDireccionFacturacionPedido(pedido.getId());
|
||||
if(direccionPedido == null){
|
||||
throw new IllegalStateException("El pedido no tiene una dirección de facturación asociada.");
|
||||
}
|
||||
FacturaDireccion fd = FacturaDireccionMapper.fromPedidoDireccion(direccionPedido);
|
||||
|
||||
factura.addDireccion(fd);
|
||||
factura.setLineas(lineasFactura);
|
||||
|
||||
factura = facturaRepo.save(factura);
|
||||
@ -166,6 +195,46 @@ public class FacturacionService {
|
||||
return factura;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Factura crearNuevaFactura(Long userId, Long serieId, Long direccionId, Long facturaRectificadaId) {
|
||||
User cliente = userService.findById(userId);
|
||||
if (cliente == null) {
|
||||
throw new EntityNotFoundException("Cliente no encontrado: " + userId);
|
||||
}
|
||||
|
||||
SerieFactura serie = serieRepo.findById(serieId)
|
||||
.orElseThrow(() -> new EntityNotFoundException("Serie no encontrada: " + serieId));
|
||||
|
||||
Factura factura = new Factura();
|
||||
factura.setCliente(cliente);
|
||||
factura.setPedidoId(null);
|
||||
factura.setSerie(serie);
|
||||
factura.setEstado(EstadoFactura.borrador);
|
||||
factura.setEstadoPago(EstadoPagoFactura.pendiente);
|
||||
factura.setFechaEmision(LocalDateTime.now());
|
||||
factura.setCreatedAt(Instant.now());
|
||||
factura.setUpdatedAt(Instant.now());
|
||||
factura.setNumeroFactura(null);
|
||||
factura.setBaseImponible(BigDecimal.ZERO);
|
||||
factura.setIva4(BigDecimal.ZERO);
|
||||
factura.setIva21(BigDecimal.ZERO);
|
||||
factura.setTotalFactura(BigDecimal.ZERO);
|
||||
factura.setTotalPagado(BigDecimal.ZERO);
|
||||
factura.setLineas(new ArrayList<>());
|
||||
factura.setPagos(new ArrayList<>());
|
||||
Direccion direccion = direccionRepo.findById(direccionId)
|
||||
.orElseThrow(() -> new EntityNotFoundException("Dirección de factura no encontrada: " + direccionId));
|
||||
FacturaDireccion facturaDireccion = FacturaDireccionMapper.fromDireccion(direccion);
|
||||
factura.addDireccion(facturaDireccion);
|
||||
if(facturaRectificadaId != null){
|
||||
Factura facturaRectificada = facturaRepo.findById(facturaRectificadaId)
|
||||
.orElseThrow(() -> new EntityNotFoundException("Factura rectificada no encontrada: " + facturaRectificadaId));
|
||||
factura.setFacturaRectificativa(facturaRectificada);
|
||||
facturaRectificada.setFacturaRectificada(factura);
|
||||
}
|
||||
return facturaRepo.save(factura);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Estado / Numeración
|
||||
// -----------------------
|
||||
@ -225,6 +294,7 @@ public class FacturacionService {
|
||||
pedidoService.upsertDireccionFacturacion(pedidoId, dto.getDireccionFacturacion());
|
||||
|
||||
}
|
||||
upsertDireccionFacturacion(facturaId, dto.getDireccionFacturacion());
|
||||
|
||||
facturaRepo.save(factura);
|
||||
}
|
||||
@ -281,12 +351,79 @@ public class FacturacionService {
|
||||
return facturaRepo.save(factura);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Boolean upsertDireccionFacturacion(Long facturaId, DireccionFacturacionDto direccionData) {
|
||||
try {
|
||||
Factura factura = facturaRepo.findById(facturaId)
|
||||
.orElseThrow(() -> new EntityNotFoundException("Factura no encontrada: " + facturaId));
|
||||
|
||||
// ✅ Solo editable si borrador (tu regla actual para cabecera/dirección)
|
||||
if (factura.getEstado() != EstadoFactura.borrador) {
|
||||
throw new IllegalStateException("Solo se puede guardar dirección en borrador.");
|
||||
}
|
||||
|
||||
factura.getDirecciones().clear();
|
||||
factura.addDireccion(direccionData.toFacturaDireccion());
|
||||
facturaRepo.save(factura);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> getForSelectFacturasRectificables(String q1, String q2, Long userId) {
|
||||
try {
|
||||
String search = Optional.ofNullable(q1).orElse(q2);
|
||||
if (search != null) {
|
||||
search = search.trim();
|
||||
}
|
||||
final String q = (search == null || search.isEmpty())
|
||||
? null
|
||||
: search.toLowerCase();
|
||||
|
||||
List<Factura> all = facturaRepo.findByClienteIdAndEstadoAndEstadoPagoAndSerieId(
|
||||
userId,
|
||||
EstadoFactura.validada,
|
||||
EstadoPagoFactura.pagada,
|
||||
variableService.getValorEntero("serie_facturacion_default").longValue());
|
||||
|
||||
// Mapear a opciones id/text con i18n y filtrar por búsqueda si llega
|
||||
List<Map<String, String>> options = all.stream()
|
||||
.map(f -> {
|
||||
String id = f.getId().toString();
|
||||
String text = f.getNumeroFactura();
|
||||
Map<String, String> m = new HashMap<>();
|
||||
m.put("id", id); // lo normal en Select2: id = valor que guardarás (code3)
|
||||
m.put("text", text); // texto mostrado, i18n con fallback a keyword
|
||||
return m;
|
||||
})
|
||||
.filter(opt -> {
|
||||
if (q == null || q.isEmpty())
|
||||
return true;
|
||||
String text = opt.get("text").toLowerCase();
|
||||
return text.contains(q);
|
||||
})
|
||||
.sorted(Comparator.comparing(m -> m.get("text"), Collator.getInstance()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Estructura Select2
|
||||
Map<String, Object> resp = new HashMap<>();
|
||||
resp.put("results", options);
|
||||
return resp;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Map.of("results", List.of());
|
||||
}
|
||||
}
|
||||
|
||||
private String buildNumeroFactura(String prefijo, long numero) {
|
||||
String pref = (prefijo == null) ? "" : prefijo.trim();
|
||||
String num = String.format("%05d", numero);
|
||||
return pref.isBlank() ? num : (pref + " " + num + "/" + LocalDate.now().getYear());
|
||||
}
|
||||
|
||||
|
||||
// -----------------------
|
||||
// Líneas
|
||||
// -----------------------
|
||||
|
||||
Reference in New Issue
Block a user