mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-12 16:38:48 +00:00
se guardan los presupuestos publicos
This commit is contained in:
@ -1,35 +1,42 @@
|
||||
// JpaAuditConfig.java
|
||||
package com.imprimelibros.erp.config;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import com.imprimelibros.erp.users.User;
|
||||
|
||||
import java.util.Optional;
|
||||
import com.imprimelibros.erp.users.UserDao;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
|
||||
public class JpaAuditConfig {
|
||||
|
||||
@Bean
|
||||
public AuditorAware<User> auditorAware() {
|
||||
public AuditorAware<User> auditorAware(UserDao userDao) {
|
||||
return () -> {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth == null || !auth.isAuthenticated()) return Optional.empty();
|
||||
var auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth == null || !auth.isAuthenticated())
|
||||
return Optional.empty();
|
||||
|
||||
Object principal = auth.getPrincipal();
|
||||
if (principal instanceof User u) return Optional.of(u);
|
||||
|
||||
if (principal instanceof User u)
|
||||
return Optional.of(u);
|
||||
|
||||
if (principal instanceof UserDetails ud) {
|
||||
// Si tu principal es UserDetails y no la entidad User,
|
||||
// aquí podrías cargar User por username si lo necesitas.
|
||||
return Optional.empty();
|
||||
return userDao.findByUserNameIgnoreCase(ud.getUsername());
|
||||
}
|
||||
|
||||
if (principal instanceof String username && !"anonymousUser".equals(username)) {
|
||||
return userDao.findByUserNameIgnoreCase(username);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
};
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ public class SecurityConfig {
|
||||
.authenticationProvider(provider)
|
||||
|
||||
.sessionManagement(session -> session
|
||||
.invalidSessionUrl("/login?expired")
|
||||
//.invalidSessionUrl("/login?expired")
|
||||
.maximumSessions(1))
|
||||
|
||||
// Ignora CSRF para tu recurso público (sin Ant/Mvc matchers)
|
||||
|
||||
@ -17,10 +17,11 @@ import org.hibernate.annotations.SQLDelete;
|
||||
import org.hibernate.annotations.SQLRestriction;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Instant;
|
||||
|
||||
import com.imprimelibros.erp.users.User;
|
||||
|
||||
@ -336,19 +337,6 @@ public class Presupuesto extends AbstractAuditedSoftDeleteEntity implements Clon
|
||||
@Column(name = "alto_faja")
|
||||
private Integer altoFaja = 0;
|
||||
|
||||
// ====== AUDIT ======
|
||||
|
||||
@CreatedDate
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@CreatedBy
|
||||
@Column(name = "created_by", updatable = false) // BIGINT o VARCHAR: ajusta el tipo del campo
|
||||
private Long createdBy; // o String si tu columna es texto
|
||||
|
||||
|
||||
|
||||
|
||||
// ====== MÉTODOS AUX ======
|
||||
|
||||
public String resumenPresupuesto() {
|
||||
@ -874,5 +862,4 @@ public class Presupuesto extends AbstractAuditedSoftDeleteEntity implements Clon
|
||||
this.altoFaja = altoFaja;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -540,35 +540,6 @@ public class PresupuestoService {
|
||||
return response;
|
||||
}
|
||||
|
||||
private Double obtenerPrototipo(Presupuesto presupuesto) {
|
||||
// Obtenemos el precio de 1 unidad para el ejemplar de prueba
|
||||
HashMap<String, Object> price = new HashMap<>();
|
||||
Presupuesto presupuestoTemp = presupuesto.clone();
|
||||
presupuestoTemp.setTirada1(1);
|
||||
presupuestoTemp.setTirada2(null);
|
||||
presupuestoTemp.setTirada3(null);
|
||||
presupuestoTemp.setTirada4(null);
|
||||
if (presupuestoTemp.getTipoImpresion() == Presupuesto.TipoImpresion.color) {
|
||||
presupuestoTemp.setTipoImpresion(Presupuesto.TipoImpresion.colorhq);
|
||||
} else if (presupuestoTemp.getTipoImpresion() == Presupuesto.TipoImpresion.negro) {
|
||||
presupuestoTemp.setTipoImpresion(Presupuesto.TipoImpresion.negrohq);
|
||||
}
|
||||
String priceStr = apiClient.getPrice(this.toSkApiRequest(presupuestoTemp),
|
||||
presupuestoTemp.getTipoEncuadernacion(), presupuestoTemp.getTipoCubierta());
|
||||
Double price_prototipo = 0.0;
|
||||
try {
|
||||
price = new ObjectMapper().readValue(priceStr, new TypeReference<>() {
|
||||
});
|
||||
price_prototipo = ((List<Double>) ((Map<String, Object>) price.get("data")).get("precios")).get(0);
|
||||
if (price_prototipo < 25) {
|
||||
price_prototipo = 25.0;
|
||||
}
|
||||
} catch (JsonProcessingException e) {
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
return price_prototipo;
|
||||
}
|
||||
|
||||
public HashMap<String, Object> getPrecioMaquetacion(PresupuestoMaquetacion presupuestoMaquetacion, Locale locale) {
|
||||
try {
|
||||
List<MaquetacionPrecios> lista = maquetacionPreciosRepository.findAll();
|
||||
@ -903,7 +874,8 @@ public class PresupuestoService {
|
||||
|
||||
// IP: guarda hash y trunc (si tienes campos). Si no, guarda tal cual en
|
||||
// ip_trunc/ip_hash según tu modelo.
|
||||
presupuesto.setIpTrunc(ip);
|
||||
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
|
||||
@ -957,6 +929,33 @@ public class PresupuestoService {
|
||||
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<>();
|
||||
String priceStr = apiClient.getPrice(this.toSkApiRequest(presupuesto), presupuesto.getTipoEncuadernacion(),
|
||||
presupuesto.getTipoCubierta());
|
||||
|
||||
try {
|
||||
price = new ObjectMapper().readValue(priceStr, new TypeReference<>() {
|
||||
});
|
||||
} catch (JsonProcessingException e) {
|
||||
price = new HashMap<>();
|
||||
price.put("error", messageSource.getMessage("presupuesto.error-obtener-precio", null, locale));
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// Métodos privados
|
||||
// =======================================================================
|
||||
/**
|
||||
* Copia de campos "actualizables" para no machacar otros (created_at, etc.)
|
||||
*/
|
||||
@ -1016,27 +1015,76 @@ public class PresupuestoService {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
private Double obtenerPrototipo(Presupuesto presupuesto) {
|
||||
// Obtenemos el precio de 1 unidad para el ejemplar de prueba
|
||||
HashMap<String, Object> price = new HashMap<>();
|
||||
String priceStr = apiClient.getPrice(this.toSkApiRequest(presupuesto), presupuesto.getTipoEncuadernacion(),
|
||||
presupuesto.getTipoCubierta());
|
||||
|
||||
Presupuesto presupuestoTemp = presupuesto.clone();
|
||||
presupuestoTemp.setTirada1(1);
|
||||
presupuestoTemp.setTirada2(null);
|
||||
presupuestoTemp.setTirada3(null);
|
||||
presupuestoTemp.setTirada4(null);
|
||||
if (presupuestoTemp.getTipoImpresion() == Presupuesto.TipoImpresion.color) {
|
||||
presupuestoTemp.setTipoImpresion(Presupuesto.TipoImpresion.colorhq);
|
||||
} else if (presupuestoTemp.getTipoImpresion() == Presupuesto.TipoImpresion.negro) {
|
||||
presupuestoTemp.setTipoImpresion(Presupuesto.TipoImpresion.negrohq);
|
||||
}
|
||||
String priceStr = apiClient.getPrice(this.toSkApiRequest(presupuestoTemp),
|
||||
presupuestoTemp.getTipoEncuadernacion(), presupuestoTemp.getTipoCubierta());
|
||||
Double price_prototipo = 0.0;
|
||||
try {
|
||||
price = new ObjectMapper().readValue(priceStr, new TypeReference<>() {
|
||||
});
|
||||
price_prototipo = ((List<Double>) ((Map<String, Object>) price.get("data")).get("precios")).get(0);
|
||||
if (price_prototipo < 25) {
|
||||
price_prototipo = 25.0;
|
||||
}
|
||||
} catch (JsonProcessingException e) {
|
||||
price = new HashMap<>();
|
||||
price.put("error", messageSource.getMessage("presupuesto.error-obtener-precio", null, locale));
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
return price;
|
||||
return price_prototipo;
|
||||
}
|
||||
|
||||
// Utilidad local (puedes moverla a una clase Utils si quieres)
|
||||
private static String anonymizeIp(String ip) {
|
||||
if (ip == null)
|
||||
return null;
|
||||
// IPv4
|
||||
if (ip.contains(".") && !ip.contains(":")) {
|
||||
String[] p = ip.split("\\.");
|
||||
if (p.length == 4) {
|
||||
return p[0] + "." + p[1] + "." + p[2] + ".0";
|
||||
}
|
||||
}
|
||||
// IPv6: quedarnos con /64 -> primera mitad y rellenar
|
||||
if (ip.contains(":")) {
|
||||
String[] parts = ip.split(":", -1);
|
||||
// expand no estricta, nos quedamos con primeros 4 bloques y completamos
|
||||
int blocks = Math.min(parts.length, 4);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < blocks; i++) {
|
||||
if (i > 0)
|
||||
sb.append(":");
|
||||
sb.append(parts[i].isEmpty() ? "0" : parts[i]);
|
||||
}
|
||||
// completar a /64 con ceros
|
||||
for (int i = blocks; i < 8; i++)
|
||||
sb.append(":0");
|
||||
return sb.toString();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
private static String sha256Hex(String input) {
|
||||
try {
|
||||
var md = java.security.MessageDigest.getInstance("SHA-256");
|
||||
byte[] digest = md.digest(input.getBytes(java.nio.charset.StandardCharsets.UTF_8));
|
||||
StringBuilder sb = new StringBuilder(digest.length * 2);
|
||||
for (byte b : digest)
|
||||
sb.append(String.format("%02x", b));
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -81,3 +81,9 @@ server.servlet.session.persistent=false
|
||||
geoip.enabled=true
|
||||
geoip.maxmind.enabled=true
|
||||
geoip.http.enabled=true
|
||||
|
||||
|
||||
#
|
||||
# Hibernate Timezone
|
||||
#
|
||||
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
|
||||
|
||||
@ -1418,8 +1418,8 @@ class PresupuestoCliente {
|
||||
data: JSON.stringify(body)
|
||||
}).then((data) => {
|
||||
$('#resumen-titulo').text(data.titulo);
|
||||
if (resumen.presupuesto_id) {
|
||||
window.PRESUPUESTO_ID = resumen.presupuesto_id;
|
||||
if (data.presupuesto_id) {
|
||||
window.PRESUPUESTO_ID = data.presupuesto_id;
|
||||
}
|
||||
body.presupuesto.id = window.PRESUPUESTO_ID || body.presupuesto.id || null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user