mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-21 16:20:22 +00:00
guardando presupuestos anonimos
This commit is contained in:
@ -8,10 +8,11 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Locale;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -38,6 +39,8 @@ import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||
import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoCubierta;
|
||||
import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionMatricesRepository;
|
||||
import com.imprimelibros.erp.presupuesto.marcapaginas.MarcapaginasRepository;
|
||||
import com.imprimelibros.erp.users.UserDao;
|
||||
import com.imprimelibros.erp.users.UserDetailsImpl;
|
||||
import com.imprimelibros.erp.externalApi.skApiClient;
|
||||
|
||||
@Service
|
||||
@ -65,13 +68,15 @@ public class PresupuestoService {
|
||||
private final PresupuestoFormatter presupuestoFormatter;
|
||||
private final skApiClient apiClient;
|
||||
private final GeoIpService geoIpService;
|
||||
private final UserDao userRepo;
|
||||
|
||||
public PresupuestoService(PresupuestadorItems presupuestadorItems, PresupuestoFormatter presupuestoFormatter,
|
||||
skApiClient apiClient, GeoIpService geoIpService) {
|
||||
skApiClient apiClient, GeoIpService geoIpService, UserDao userRepo) {
|
||||
this.presupuestadorItems = presupuestadorItems;
|
||||
this.presupuestoFormatter = presupuestoFormatter;
|
||||
this.apiClient = apiClient;
|
||||
this.geoIpService = geoIpService;
|
||||
this.userRepo = userRepo;
|
||||
}
|
||||
|
||||
public boolean validateDatosGenerales(int[] tiradas) {
|
||||
@ -439,9 +444,8 @@ public class PresupuestoService {
|
||||
presupuesto.getSelectedTirada() != null ? presupuesto.getSelectedTirada() : tirada_min);
|
||||
Double precio_retractilado = apiClient.getRetractilado(requestBody);
|
||||
return precio_retractilado != null
|
||||
? NumberFormat.getNumberInstance(locale)
|
||||
.format(Math.round(precio_retractilado * 100.0) / 100.0)
|
||||
: "0,00";
|
||||
? String.valueOf(Math.round(precio_retractilado * 100.0) / 100.0)
|
||||
: "0.00";
|
||||
}
|
||||
|
||||
public Map<String, Object> obtenerServiciosExtras(Presupuesto presupuesto, Locale locale) {
|
||||
@ -517,7 +521,7 @@ public class PresupuestoService {
|
||||
put("priceUnit", "");
|
||||
} else {
|
||||
put("price",
|
||||
NumberFormat.getNumberInstance(locale).format(Math.round(price_prototipo * 100.0) / 100.0));
|
||||
String.valueOf(Math.round(price_prototipo * 100.0) / 100.0));
|
||||
put("priceUnit", messageSource.getMessage("app.currency-symbol", null, locale));
|
||||
}
|
||||
}
|
||||
@ -723,7 +727,8 @@ public class PresupuestoService {
|
||||
* Calcula el resumen (SIN persistir cambios de estado).
|
||||
* Mantiene firma para no romper llamadas existentes.
|
||||
*/
|
||||
public Map<String, Object> getResumen(Presupuesto presupuesto, List<Map<String, Object>> servicios, Locale locale) {
|
||||
public Map<String, Object> getTextosResumen(Presupuesto presupuesto, List<Map<String, Object>> servicios,
|
||||
Locale locale) {
|
||||
Map<String, Object> resumen = new HashMap<>();
|
||||
resumen.put("titulo", presupuesto.getTitulo());
|
||||
|
||||
@ -798,25 +803,88 @@ public class PresupuestoService {
|
||||
* Se invoca al entrar en la pestaña "Resumen" del presupuestador público.
|
||||
*/
|
||||
// PresupuestoService.java
|
||||
|
||||
@Transactional
|
||||
public Map<String, Object> getResumenPublico(
|
||||
public Map<String, Object> getResumen(
|
||||
Presupuesto presupuesto,
|
||||
List<Map<String, Object>> servicios,
|
||||
Boolean save,
|
||||
String mode,
|
||||
Locale locale,
|
||||
String sessionId,
|
||||
String ip) {
|
||||
|
||||
// 1) Calcula el resumen (como ya haces)
|
||||
Map<String, Object> resumen = getResumen(presupuesto, servicios, locale);
|
||||
Map<String, Object> resumen = getTextosResumen(presupuesto, servicios, locale);
|
||||
if (resumen.containsKey("error"))
|
||||
return resumen;
|
||||
|
||||
// 2) Totales a partir del resumen
|
||||
// - precio_unitario: primer precio devuelto por la API
|
||||
// - cantidad: selected_tirada
|
||||
// - precio_total_tirada
|
||||
// - servicios_total (si hay)
|
||||
presupuesto = generateTotalizadores(presupuesto, servicios, resumen, locale);
|
||||
|
||||
// 3) Enriquecer el Presupuesto a persistir
|
||||
presupuesto.setEstado(Presupuesto.Estado.borrador);
|
||||
if (mode.equals("public")) {
|
||||
presupuesto.setOrigen(Presupuesto.Origen.publico);
|
||||
presupuesto.setSessionId(sessionId);
|
||||
// IP: guarda hash y trunc (si tienes campos). Si no, guarda tal cual en
|
||||
// ip_trunc/ip_hash según tu modelo.
|
||||
String ipTrunc = anonymizeIp(ip);
|
||||
presupuesto.setIpTrunc(ipTrunc);
|
||||
presupuesto.setIpHash(Integer.toHexString(ip.hashCode()));
|
||||
|
||||
// ubicación (si tienes un servicio GeoIP disponible; si no, omite estas tres
|
||||
// líneas)
|
||||
try {
|
||||
GeoIpService.GeoData geo = geoIpService.lookup(ip).orElse(null);
|
||||
presupuesto.setPais(geo.getPais());
|
||||
presupuesto.setRegion(geo.getRegion());
|
||||
presupuesto.setCiudad(geo.getCiudad());
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
} else
|
||||
presupuesto.setOrigen(Presupuesto.Origen.privado);
|
||||
|
||||
// 4) UPSERT: si viene id -> actualiza; si no, reusa el último borrador de la
|
||||
// sesión
|
||||
Presupuesto entidad;
|
||||
if (presupuesto.getId() != null) {
|
||||
entidad = presupuestoRepository.findById(presupuesto.getId()).orElse(presupuesto);
|
||||
} else {
|
||||
entidad = presupuestoRepository
|
||||
.findTopBySessionIdAndEstadoOrderByCreatedAtDesc(sessionId, Presupuesto.Estado.borrador)
|
||||
.orElse(presupuesto);
|
||||
// Si se reutiliza un borrador existente, copia el ID a nuestro objeto para
|
||||
// hacer merge
|
||||
presupuesto.setId(entidad.getId());
|
||||
}
|
||||
|
||||
// 5) Guardar/actualizar
|
||||
entidad = mergePresupuesto(entidad, presupuesto);
|
||||
|
||||
if (save != null && save) {
|
||||
// Si NO es para guardar (solo calcular resumen), devolver sin persistir
|
||||
this.guardarPresupuesto(presupuesto);
|
||||
}
|
||||
|
||||
// Opcional: devolver el id guardado al frontend para que lo envíe en llamadas
|
||||
// siguientes
|
||||
resumen.put("presupuesto_id", entidad.getId());
|
||||
resumen.put("precio_unitario", presupuesto.getPrecioUnitario());
|
||||
resumen.put("precio_total_tirada", presupuesto.getPrecioTotalTirada());
|
||||
resumen.put("servicios_total", presupuesto.getServiciosTotal());
|
||||
resumen.put("base_imponible", presupuesto.getBaseImponible());
|
||||
resumen.put("iva_tipo", presupuesto.getIvaTipo());
|
||||
resumen.put("iva_importe", presupuesto.getIvaImporte());
|
||||
resumen.put("total_con_iva", presupuesto.getTotalConIva());
|
||||
|
||||
return resumen;
|
||||
}
|
||||
|
||||
public Presupuesto generateTotalizadores(
|
||||
Presupuesto presupuesto,
|
||||
List<Map<String, Object>> servicios,
|
||||
Map<String, Object> resumen,
|
||||
Locale locale) {
|
||||
|
||||
// Genera los totalizadores (precio unitario, total tirada, etc.) sin guardar
|
||||
double precioUnit = 0.0;
|
||||
int cantidad = presupuesto.getSelectedTirada() != null ? presupuesto.getSelectedTirada() : 0;
|
||||
try {
|
||||
@ -871,27 +939,6 @@ public class PresupuestoService {
|
||||
RoundingMode.HALF_UP);
|
||||
BigDecimal totalConIva = baseImponible.add(ivaImporte);
|
||||
|
||||
// 3) Enriquecer el Presupuesto a persistir
|
||||
presupuesto.setEstado(Presupuesto.Estado.borrador);
|
||||
presupuesto.setOrigen(Presupuesto.Origen.publico);
|
||||
presupuesto.setSessionId(sessionId);
|
||||
|
||||
// IP: guarda hash y trunc (si tienes campos). Si no, guarda tal cual en
|
||||
// ip_trunc/ip_hash según tu modelo.
|
||||
String ipTrunc = anonymizeIp(ip);
|
||||
presupuesto.setIpTrunc(ipTrunc);
|
||||
presupuesto.setIpHash(Integer.toHexString(ip.hashCode()));
|
||||
|
||||
// ubicación (si tienes un servicio GeoIP disponible; si no, omite estas tres
|
||||
// líneas)
|
||||
try {
|
||||
GeoIpService.GeoData geo = geoIpService.lookup(ip).orElse(null);
|
||||
presupuesto.setPais(geo.getPais());
|
||||
presupuesto.setRegion(geo.getRegion());
|
||||
presupuesto.setCiudad(geo.getCiudad());
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
// precios y totales
|
||||
presupuesto.setPrecioUnitario(BigDecimal.valueOf(precioUnit).setScale(6, RoundingMode.HALF_UP));
|
||||
presupuesto.setPrecioTotalTirada(precioTotalTirada);
|
||||
@ -901,46 +948,33 @@ public class PresupuestoService {
|
||||
presupuesto.setIvaImporte(ivaImporte);
|
||||
presupuesto.setTotalConIva(totalConIva);
|
||||
|
||||
// 4) UPSERT: si viene id -> actualiza; si no, reusa el último borrador de la
|
||||
// sesión
|
||||
Presupuesto entidad;
|
||||
if (presupuesto.getId() != null) {
|
||||
entidad = presupuestoRepository.findById(presupuesto.getId()).orElse(presupuesto);
|
||||
} else {
|
||||
entidad = presupuestoRepository
|
||||
.findTopBySessionIdAndEstadoOrderByCreatedAtDesc(sessionId, Presupuesto.Estado.borrador)
|
||||
.orElse(presupuesto);
|
||||
// Si se reutiliza un borrador existente, copia el ID a nuestro objeto para
|
||||
// hacer merge
|
||||
presupuesto.setId(entidad.getId());
|
||||
return presupuesto;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public HashMap<String, Object> guardarPresupuesto(Presupuesto presupuesto) {
|
||||
|
||||
HashMap<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
|
||||
Presupuesto p = presupuestoRepository.saveAndFlush(presupuesto);
|
||||
|
||||
result.put("success", true);
|
||||
result.put("presupuesto_id", p.getId());
|
||||
|
||||
return result;
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error guardando presupuesto: " + e.getMessage());
|
||||
result.put("success", false);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 5) Guardar/actualizar
|
||||
entidad = mergePresupuesto(entidad, presupuesto);
|
||||
presupuestoRepository.saveAndFlush(entidad);
|
||||
|
||||
// Opcional: devolver el id guardado al frontend para que lo envíe en llamadas
|
||||
// siguientes
|
||||
resumen.put("presupuesto_id", entidad.getId());
|
||||
resumen.put("precio_unitario", presupuesto.getPrecioUnitario());
|
||||
resumen.put("precio_total_tirada", presupuesto.getPrecioTotalTirada());
|
||||
resumen.put("servicios_total", presupuesto.getServiciosTotal());
|
||||
resumen.put("base_imponible", presupuesto.getBaseImponible());
|
||||
resumen.put("iva_tipo", presupuesto.getIvaTipo());
|
||||
resumen.put("iva_importe", presupuesto.getIvaImporte());
|
||||
resumen.put("total_con_iva", presupuesto.getTotalConIva());
|
||||
|
||||
return resumen;
|
||||
}
|
||||
|
||||
/**
|
||||
* PRIVADO (futuro botón "Guardar"): persiste el presupuesto como borrador.
|
||||
*/
|
||||
@Transactional
|
||||
public Presupuesto guardarPrivado(Presupuesto presupuesto) {
|
||||
presupuesto.setEstado(Presupuesto.Estado.borrador);
|
||||
return presupuestoRepository.saveAndFlush(presupuesto);
|
||||
}
|
||||
|
||||
public HashMap<String, Object> calcularPresupuesto(Presupuesto presupuesto, Locale locale) {
|
||||
HashMap<String, Object> price = new HashMap<>();
|
||||
@ -957,9 +991,8 @@ public class PresupuestoService {
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
public Boolean canAccessPresupuesto(Presupuesto presupuesto, Authentication authentication) {
|
||||
|
||||
|
||||
boolean isUser = authentication.getAuthorities().stream()
|
||||
.anyMatch(a -> a.getAuthority().equals("ROLE_USER"));
|
||||
|
||||
@ -972,7 +1005,6 @@ public class PresupuestoService {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// Métodos privados
|
||||
@ -1095,5 +1127,4 @@ public class PresupuestoService {
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user