Files
erp-imprimelibros/src/main/java/com/imprimelibros/erp/presupuesto/dto/Presupuesto.java

924 lines
25 KiB
Java

package com.imprimelibros.erp.presupuesto.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import com.imprimelibros.erp.presupuesto.validation.ConsistentTiradas;
import com.imprimelibros.erp.presupuesto.validation.PaginasCosidoGrapado;
import com.imprimelibros.erp.presupuesto.validation.Par;
import com.imprimelibros.erp.presupuesto.validation.PresupuestoValidationGroups;
import com.imprimelibros.erp.presupuesto.validation.Tamanio;
import com.imprimelibros.erp.common.HtmlStripConverter;
import com.imprimelibros.erp.common.jpa.AbstractAuditedEntity;
import jakarta.persistence.*;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.math.BigDecimal;
import com.imprimelibros.erp.users.User;
@ConsistentTiradas(groups = PresupuestoValidationGroups.DatosGenerales.class)
@PaginasCosidoGrapado(groups = PresupuestoValidationGroups.DatosGenerales.class)
@Tamanio(groups = PresupuestoValidationGroups.DatosGenerales.class)
@EntityListeners(AuditingEntityListener.class)
@Entity
@Table(name = "presupuesto", indexes = {
@Index(name = "idx_presupuesto_origen_estado", columnList = "origen, estado"),
@Index(name = "idx_presupuesto_session", columnList = "session_id"),
@Index(name = "idx_presupuesto_user", columnList = "user_id"),
@Index(name = "idx_presupuesto_deleted", columnList = "deleted"),
@Index(name = "idx_presupuesto_geo", columnList = "pais, region, ciudad")
})
@SQLDelete(sql = "UPDATE presupuesto SET deleted = 1, deleted_at = NOW(3) WHERE id = ?")
@SQLRestriction("deleted = 0")
public class Presupuesto extends AbstractAuditedEntity implements Cloneable {
public enum TipoEncuadernacion {
fresado("presupuesto.fresado"),
cosido("presupuesto.cosido"),
grapado("presupuesto.grapado"),
espiral("presupuesto.espiral"),
wireo("presupuesto.wireo");
private final String messageKey;
TipoEncuadernacion(String messageKey) {
this.messageKey = messageKey;
}
public String getMessageKey() {
return messageKey;
}
}
public enum TipoImpresion {
negro("presupuesto.blanco-negro"),
negrohq("presupuesto.blanco-negro-premium"),
color("presupuesto.color"),
colorhq("presupuesto.color-premium");
private final String messageKey;
TipoImpresion(String messageKey) {
this.messageKey = messageKey;
}
public String getMessageKey() {
return messageKey;
}
}
public enum TipoCubierta {
tapaBlanda("presupuesto.tapa-blanda"),
tapaDura("presupuesto.tapa-dura"),
tapaDuraLomoRedondo("presupuesto.tapa-dura-lomo-redondo");
private final String messageKey;
TipoCubierta(String messageKey) {
this.messageKey = messageKey;
}
public String getMessageKey() {
return messageKey;
}
}
public enum Origen {
publico, privado
}
public enum Estado {
borrador("presupuesto.estado.borrador"),
aceptado("presupuesto.estado.aceptado"),
modificado("presupuesto.estado.modificado");
private final String messageKey;
Estado(String messageKey) {
this.messageKey = messageKey;
}
public String getMessageKey() {
return messageKey;
}
}
public enum Entrega{
peninsula("presupuesto.entrega.peninsula"),
canarias("presupuesto.entrega.canarias"),
paises_ue("presupuesto.entrega.paises-ue");
private final String messageKey;
Entrega(String messageKey) {
this.messageKey = messageKey;
}
public String getMessageKey() {
return messageKey;
}
}
@Override
public Presupuesto clone() {
try {
return (Presupuesto) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
// ====== NUEVOS: Origen/Estado/Usuario/Session/Geo/IP/Totales/JSONs ======
@Enumerated(EnumType.STRING)
@Column(name = "origen", nullable = false)
private Origen origen = Origen.publico;
@Enumerated(EnumType.STRING)
@Column(name = "estado", nullable = false)
private Estado estado = Estado.borrador;
// Usuario autenticado (nullable en público)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
// Continuidad en público
@Column(name = "session_id", length = 64)
private String sessionId;
@Column(name = "visitor_id", length = 64)
private String visitorId;
// IP anonimizada / truncada + geolocalización resumida (para estadísticas)
@Column(name = "ip_hash", length = 88) // SHA-256 base64 ≈ 44 chars; dejamos margen
private String ipHash;
@Column(name = "ip_trunc", length = 64)
private String ipTrunc; // p.ej. "192.168.0.0" o "2a02:xxxx::"
@Column(name = "pais", length = 64)
private String pais;
@Column(name = "region", length = 128)
private String region;
@Column(name = "ciudad", length = 128)
private String ciudad;
// Totales de la tirada seleccionada y del presupuesto
@Column(name = "precio_unitario", precision = 12, scale = 4)
private BigDecimal precioUnitario;
@Column(name = "precio_total_tirada", precision = 12, scale = 2)
private BigDecimal precioTotalTirada;
@Column(name = "servicios_total", precision = 12, scale = 2)
private BigDecimal serviciosTotal;
@Column(name = "base_imponible", precision = 12, scale = 2)
private BigDecimal baseImponible;
@Column(name = "iva_reducido")
private Boolean ivaReducido;
@Column(name = "entrega_tipo")
@Enumerated(EnumType.STRING)
private Entrega entregaTipo;
@Column(name = "iva_importe_4", precision = 12, scale = 2)
private BigDecimal ivaImporte4;
@Column(name = "iva_importe_21", precision = 12, scale = 2)
private BigDecimal ivaImporte21;
@Column(name = "total_con_iva", precision = 12, scale = 2)
private BigDecimal totalConIva;
// JSONs de apoyo (todas las tiradas, servicios, bloques de
// maquetación/marcapáginas y snapshot)
@Lob
@Column(name = "precios_por_tirada_json", columnDefinition = "json")
private String preciosPorTiradaJson; // [{tirada, precio_unitario, precio_total_tirada}, ...]
@Lob
@Column(name = "servicios_json", columnDefinition = "json")
private String serviciosJson;
@Lob
@Column(name = "datos_maquetacion_json", columnDefinition = "json")
private String datosMaquetacionJson;
@Lob
@Column(name = "datos_marcapaginas_json", columnDefinition = "json")
private String datosMarcapaginasJson;
@Lob
@Column(name = "pricing_snapshot", columnDefinition = "json")
private String pricingSnapshotJson;
// ====== TUS CAMPOS ORIGINALES ======
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@NotNull(message = "{presupuesto.errores.tipo-encuadernacion}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@Enumerated(EnumType.STRING)
@Column(name = "tipo_encuadernacion")
private TipoEncuadernacion tipoEncuadernacion = TipoEncuadernacion.fresado;
@Convert(converter = HtmlStripConverter.class)
@NotBlank(message = "{presupuesto.errores.titulo}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@Column(name = "titulo")
private String titulo;
@Convert(converter = HtmlStripConverter.class)
@Column(name = "autor")
private String autor;
@Convert(converter = HtmlStripConverter.class)
@Column(name = "isbn")
private String isbn;
@NotNull(message = "{presupuesto.errores.tirada1}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@Column(name = "tirada1")
private Integer tirada1;
@Column(name = "tirada2")
private Integer tirada2;
@Column(name = "tirada3")
private Integer tirada3;
@Column(name = "tirada4")
private Integer tirada4;
@Column(name = "selected_tirada")
private Integer selectedTirada;
@NotNull(message = "{presupuesto.errores.ancho}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@Column(name = "ancho")
private Integer ancho;
@NotNull(message = "{presupuesto.errores.alto}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@Column(name = "alto")
private Integer alto;
@Column(name = "formatoPersonalizado")
private Boolean formatoPersonalizado;
@Par(message = "{presupuesto.errores.paginasNegro.par}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@NotNull(message = "{presupuesto.errores.paginasNegro.required}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@Column(name = "paginas_negro")
private Integer paginasNegro;
@Par(message = "{presupuesto.errores.paginasColor.par}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@NotNull(message = "{presupuesto.errores.paginasColor.required}", groups = PresupuestoValidationGroups.DatosGenerales.class)
@Column(name = "paginas_color")
private Integer paginasColor;
@Column(name = "posicion_paginas_color")
private String posicionPaginasColor;
@Column(name = "paginas_color_total")
private Integer paginasColorTotal;
@NotNull(message = "{presupuesto.errores.tipo-impresion}", groups = PresupuestoValidationGroups.Interior.class)
@Enumerated(EnumType.STRING)
@Column(name = "tipo_impresion")
private TipoImpresion tipoImpresion = TipoImpresion.negro;
@NotNull(message = "{presupuesto.errores.papel-interior}", groups = PresupuestoValidationGroups.Interior.class)
@Column(name = "papel_interior_id")
private Integer papelInteriorId;
@NotNull(message = "{presupuesto.errores.gramaje-interior}", groups = PresupuestoValidationGroups.Interior.class)
@Column(name = "gramaje_interior")
private Integer gramajeInterior;
@NotNull(message = "{presupuesto.errores.tipo-cubierta}", groups = PresupuestoValidationGroups.Cubierta.class)
@Enumerated(EnumType.STRING)
@Column(name = "tipo_cubierta")
private TipoCubierta tipoCubierta = TipoCubierta.tapaBlanda;
@Column(name = "solapas_cubierta")
private Boolean solapasCubierta = false;
@Column(name = "tamanio_solapas_cubierta")
private Integer tamanioSolapasCubierta;
@Column(name = "cubierta_caras")
private Integer cubiertaCaras;
@Column(name = "papel_guardas_id")
private Integer papelGuardasId;
@Column(name = "gramaje_guardas")
private Integer gramajeGuardas;
@Column(name = "guardas_impresas")
private Integer guardasImpresas;
@Column(name = "cabezada")
private String cabezada;
@NotNull(message = "{presupuesto.errores.papel-cubierta}", groups = PresupuestoValidationGroups.Cubierta.class)
@Column(name = "papel_cubierta_id")
private Integer papelCubiertaId = 2;
@NotNull(message = "{presupuesto.errores.gramaje-cubierta}", groups = PresupuestoValidationGroups.Cubierta.class)
@Column(name = "gramaje_cubierta")
private Integer gramajeCubierta = 240;
@NotNull(message = "{presupuesto.errores.acabado-cubierta}", groups = PresupuestoValidationGroups.Cubierta.class)
@Column(name = "acabado")
private Integer acabado = 1;
@Column(name = "sobrecubierta")
private Boolean sobrecubierta = false;
@Column(name = "papel_sobrecubierta_id")
private Integer papelSobrecubiertaId = 2;
@Column(name = "gramaje_sobrecubierta")
private Integer gramajeSobrecubierta = 170;
@Column(name = "tamanio_solapas_sobrecubierta")
private Integer tamanioSolapasSobrecubierta = 80;
@Column(name = "acabado_sobrecubierta")
private Integer acabadoSobrecubierta = 0;
@Column(name = "faja")
private Boolean faja = false;
@Column(name = "papel_faja_id")
private Integer papelFajaId = 2;
@Column(name = "gramaje_faja")
private Integer gramajeFaja = 170;
@Column(name = "tamanio_solapas_faja")
private Integer tamanioSolapasFaja = 80;
@Column(name = "acabado_faja")
private Integer acabadoFaja = 0;
@Column(name = "alto_faja")
private Integer altoFaja = 0;
// ====== MÉTODOS AUX ======
public String resumenPresupuesto() {
return String.format("%s - %s - %dx%d mm - %d Páginas (N:%d C:%d) - Tira:%d",
this.titulo,
this.tipoEncuadernacion,
this.ancho,
this.alto,
(this.paginasNegro != null ? this.paginasNegro : 0)
+ (this.paginasColorTotal != null ? this.paginasColorTotal : 0),
this.paginasNegro != null ? this.paginasNegro : 0,
this.paginasColorTotal != null ? this.paginasColorTotal : 0,
this.selectedTirada != null ? this.selectedTirada : 0);
}
public Integer[] getTiradas() {
return new Integer[] { tirada1, tirada2, tirada3, tirada4 };
}
// ====== GETTERS/SETTERS (incluye nuevos y existentes) ======
public Origen getOrigen() {
return origen;
}
public void setOrigen(Origen origen) {
this.origen = origen;
}
public Estado getEstado() {
return estado;
}
public void setEstado(Estado estado) {
this.estado = estado;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getVisitorId() {
return visitorId;
}
public void setVisitorId(String visitorId) {
this.visitorId = visitorId;
}
public String getIpHash() {
return ipHash;
}
public void setIpHash(String ipHash) {
this.ipHash = ipHash;
}
public String getIpTrunc() {
return ipTrunc;
}
public void setIpTrunc(String ipTrunc) {
this.ipTrunc = ipTrunc;
}
public String getPais() {
return pais;
}
public void setPais(String pais) {
this.pais = pais;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getCiudad() {
return ciudad;
}
public void setCiudad(String ciudad) {
this.ciudad = ciudad;
}
public BigDecimal getPrecioUnitario() {
return precioUnitario;
}
public void setPrecioUnitario(BigDecimal precioUnitario) {
this.precioUnitario = precioUnitario;
}
public BigDecimal getPrecioTotalTirada() {
return precioTotalTirada;
}
public void setPrecioTotalTirada(BigDecimal precioTotalTirada) {
this.precioTotalTirada = precioTotalTirada;
}
public BigDecimal getServiciosTotal() {
return serviciosTotal;
}
public void setServiciosTotal(BigDecimal serviciosTotal) {
this.serviciosTotal = serviciosTotal;
}
public BigDecimal getBaseImponible() {
return baseImponible;
}
public void setBaseImponible(BigDecimal baseImponible) {
this.baseImponible = baseImponible;
}
public Boolean getIvaReducido() {
return ivaReducido;
}
public void setIvaReducido(Boolean ivaReducido) {
this.ivaReducido = ivaReducido;
}
public Entrega getEntregaTipo() {
return entregaTipo;
}
public void setEntregaTipo(Entrega entregaTipo) {
this.entregaTipo = entregaTipo;
}
public BigDecimal getIvaImporte4() {
return ivaImporte4;
}
public void setIvaImporte4(BigDecimal ivaImporte4) {
this.ivaImporte4 = ivaImporte4;
}
public BigDecimal getIvaImporte21() {
return ivaImporte21;
}
public void setIvaImporte21(BigDecimal ivaImporte21) {
this.ivaImporte21 = ivaImporte21;
}
public BigDecimal getTotalConIva() {
return totalConIva;
}
public void setTotalConIva(BigDecimal totalConIva) {
this.totalConIva = totalConIva;
}
public String getPreciosPorTiradaJson() {
return preciosPorTiradaJson;
}
public void setPreciosPorTiradaJson(String preciosPorTiradaJson) {
this.preciosPorTiradaJson = preciosPorTiradaJson;
}
public String getServiciosJson() {
return serviciosJson;
}
public void setServiciosJson(String serviciosJson) {
this.serviciosJson = serviciosJson;
}
public String getDatosMaquetacionJson() {
return datosMaquetacionJson;
}
public void setDatosMaquetacionJson(String datosMaquetacionJson) {
this.datosMaquetacionJson = datosMaquetacionJson;
}
public String getDatosMarcapaginasJson() {
return datosMarcapaginasJson;
}
public void setDatosMarcapaginasJson(String datosMarcapaginasJson) {
this.datosMarcapaginasJson = datosMarcapaginasJson;
}
public String getPricingSnapshotJson() {
return pricingSnapshotJson;
}
public void setPricingSnapshotJson(String pricingSnapshotJson) {
this.pricingSnapshotJson = pricingSnapshotJson;
}
public TipoEncuadernacion getTipoEncuadernacion() {
return tipoEncuadernacion;
}
public void setTipoEncuadernacion(TipoEncuadernacion tipoEncuadernacion) {
this.tipoEncuadernacion = tipoEncuadernacion;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getAutor() {
return autor;
}
public void setAutor(String autor) {
this.autor = autor;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public Integer getTirada1() {
return tirada1;
}
public void setTirada1(Integer tirada1) {
this.tirada1 = tirada1;
}
public Integer getTirada2() {
return tirada2;
}
public void setTirada2(Integer tirada2) {
this.tirada2 = tirada2;
}
public Integer getTirada3() {
return tirada3;
}
public void setTirada3(Integer tirada3) {
this.tirada3 = tirada3;
}
public Integer getTirada4() {
return tirada4;
}
public void setTirada4(Integer tirada4) {
this.tirada4 = tirada4;
}
public Integer getSelectedTirada() {
return selectedTirada;
}
public void setSelectedTirada(Integer selectedTirada) {
this.selectedTirada = selectedTirada;
}
public Integer getAncho() {
return ancho;
}
public void setAncho(Integer ancho) {
this.ancho = ancho;
}
public Integer getAlto() {
return alto;
}
public void setAlto(Integer alto) {
this.alto = alto;
}
public Boolean getFormatoPersonalizado() {
return formatoPersonalizado;
}
public void setFormatoPersonalizado(Boolean formatoPersonalizado) {
this.formatoPersonalizado = formatoPersonalizado;
}
public Integer getPaginasNegro() {
return paginasNegro;
}
public void setPaginasNegro(Integer paginasNegro) {
this.paginasNegro = paginasNegro;
}
public Integer getPaginasColor() {
return paginasColor;
}
public void setPaginasColor(Integer paginasColor) {
this.paginasColor = paginasColor;
}
public String getPosicionPaginasColor() {
return posicionPaginasColor;
}
public void setPosicionPaginasColor(String posicionPaginasColor) {
this.posicionPaginasColor = posicionPaginasColor;
}
public Integer getPaginasColorTotal() {
return paginasColorTotal;
}
public void setPaginasColorTotal(Integer paginasColorTotal) {
this.paginasColorTotal = paginasColorTotal;
}
public TipoImpresion getTipoImpresion() {
return tipoImpresion;
}
public void setTipoImpresion(TipoImpresion tipoImpresion) {
this.tipoImpresion = tipoImpresion;
}
public Integer getPapelInteriorId() {
return papelInteriorId;
}
public void setPapelInteriorId(Integer papelInteriorId) {
this.papelInteriorId = papelInteriorId;
}
public Integer getGramajeInterior() {
return gramajeInterior;
}
public void setGramajeInterior(Integer gramajeInterior) {
this.gramajeInterior = gramajeInterior;
}
public TipoCubierta getTipoCubierta() {
return tipoCubierta;
}
public void setTipoCubierta(TipoCubierta tipoCubierta) {
this.tipoCubierta = tipoCubierta;
}
public Boolean getSolapasCubierta() {
return solapasCubierta;
}
public void setSolapasCubierta(Boolean solapasCubierta) {
this.solapasCubierta = solapasCubierta;
}
public Integer getTamanioSolapasCubierta() {
return tamanioSolapasCubierta;
}
public void setTamanioSolapasCubierta(Integer tamanioSolapasCubierta) {
this.tamanioSolapasCubierta = tamanioSolapasCubierta;
}
public Integer getCubiertaCaras() {
return cubiertaCaras;
}
public void setCubiertaCaras(Integer cubiertaCaras) {
this.cubiertaCaras = cubiertaCaras;
}
public Integer getPapelGuardasId() {
return papelGuardasId;
}
public void setPapelGuardasId(Integer papelGuardasId) {
this.papelGuardasId = papelGuardasId;
}
public Integer getGramajeGuardas() {
return gramajeGuardas;
}
public void setGramajeGuardas(Integer gramajeGuardas) {
this.gramajeGuardas = gramajeGuardas;
}
public Integer getGuardasImpresas() {
return guardasImpresas;
}
public void setGuardasImpresas(Integer guardasImpresas) {
this.guardasImpresas = guardasImpresas;
}
public String getCabezada() {
return cabezada;
}
public void setCabezada(String cabezada) {
this.cabezada = cabezada;
}
public Integer getPapelCubiertaId() {
return papelCubiertaId;
}
public void setPapelCubiertaId(Integer papelCubiertaId) {
this.papelCubiertaId = papelCubiertaId;
}
public Integer getGramajeCubierta() {
return gramajeCubierta;
}
public void setGramajeCubierta(Integer gramajeCubierta) {
this.gramajeCubierta = gramajeCubierta;
}
public Integer getAcabado() {
return acabado;
}
public void setAcabado(Integer acabado) {
this.acabado = acabado;
}
public Boolean getSobrecubierta() {
return sobrecubierta;
}
public void setSobrecubierta(Boolean sobrecubierta) {
this.sobrecubierta = sobrecubierta;
}
public Integer getPapelSobrecubiertaId() {
return papelSobrecubiertaId;
}
public void setPapelSobrecubiertaId(Integer papelSobrecubiertaId) {
this.papelSobrecubiertaId = papelSobrecubiertaId;
}
public Integer getGramajeSobrecubierta() {
return gramajeSobrecubierta;
}
public void setGramajeSobrecubierta(Integer gramajeSobrecubierta) {
this.gramajeSobrecubierta = gramajeSobrecubierta;
}
public Integer getTamanioSolapasSobrecubierta() {
return tamanioSolapasSobrecubierta;
}
public void setTamanioSolapasSobrecubierta(Integer tamanioSolapasSobrecubierta) {
this.tamanioSolapasSobrecubierta = tamanioSolapasSobrecubierta;
}
public Integer getAcabadoSobrecubierta() {
return acabadoSobrecubierta;
}
public void setAcabadoSobrecubierta(Integer acabadoSobrecubierta) {
this.acabadoSobrecubierta = acabadoSobrecubierta;
}
public Boolean getFaja() {
return faja;
}
public void setFaja(Boolean faja) {
this.faja = faja;
}
public Integer getPapelFajaId() {
return papelFajaId;
}
public void setPapelFajaId(Integer papelFajaId) {
this.papelFajaId = papelFajaId;
}
public Integer getGramajeFaja() {
return gramajeFaja;
}
public void setGramajeFaja(Integer gramajeFaja) {
this.gramajeFaja = gramajeFaja;
}
public Integer getTamanioSolapasFaja() {
return tamanioSolapasFaja;
}
public void setTamanioSolapasFaja(Integer tamanioSolapasFaja) {
this.tamanioSolapasFaja = tamanioSolapasFaja;
}
public Integer getAcabadoFaja() {
return acabadoFaja;
}
public void setAcabadoFaja(Integer acabadoFaja) {
this.acabadoFaja = acabadoFaja;
}
public Integer getAltoFaja() {
return altoFaja;
}
public void setAltoFaja(Integer altoFaja) {
this.altoFaja = altoFaja;
}
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
}