diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoController.java b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoController.java index 65308b6..3106521 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoController.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoController.java @@ -26,6 +26,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.imprimelibros.erp.externalApi.skApiClient; import com.imprimelibros.erp.presupuesto.classes.ImagenPresupuesto; import com.imprimelibros.erp.presupuesto.classes.PresupuestoMaquetacion; +import com.imprimelibros.erp.presupuesto.classes.PresupuestoMarcapaginas; import com.imprimelibros.erp.presupuesto.validation.PresupuestoValidationGroups; import jakarta.validation.Valid; @@ -344,4 +345,34 @@ public class PresupuestoController { return ResponseEntity.ok(resultado); } + @GetMapping(value = "/public/marcapaginas/form", produces = MediaType.TEXT_HTML_VALUE) + public String getMarcapaginasForm(Model model) { + model.addAttribute("presupuestoMarcapaginas", new PresupuestoMarcapaginas()); + return "imprimelibros/presupuestos/presupuesto-marcapaginas-form :: marcapaginasForm"; + } + + @GetMapping("/public/marcapaginas") + public ResponseEntity getPresupuestoMarcapaginas( + @Valid @ModelAttribute PresupuestoMarcapaginas presupuestoMarcapaginas, + BindingResult result, + Locale locale) { + + if (result.hasErrors()) { + // Construimos un mapa field -> mensaje para tu AJAX + Map errores = result.getFieldErrors().stream() + .collect(java.util.stream.Collectors.toMap( + fe -> fe.getField(), + fe -> fe.getDefaultMessage(), + (a, b) -> a)); + return ResponseEntity.badRequest().body(errores); + } + + Map resultado = presupuestoService.getPrecioMarcapaginas(presupuestoMarcapaginas, locale); + if ((Double) resultado.get("precio_total") == 0.0 && (Double) resultado.get("precio_unitario") == 0.0) { + return ResponseEntity.badRequest() + .body(messageSource.getMessage("presupuesto.errores.presupuesto-marcapaginas", null, locale)); + } + return ResponseEntity.ok(resultado); + } + } diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoService.java b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoService.java index 415572c..8850973 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoService.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoService.java @@ -27,9 +27,11 @@ import com.imprimelibros.erp.presupuesto.classes.ImagenPresupuesto; import com.imprimelibros.erp.presupuesto.classes.PresupuestadorItems; import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionPrecios; import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionPreciosRepository; +import com.imprimelibros.erp.presupuesto.marcapaginas.Marcapaginas; import com.imprimelibros.erp.presupuesto.classes.PresupuestoMaquetacion; -import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionMatrices; +import com.imprimelibros.erp.presupuesto.classes.PresupuestoMarcapaginas; import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionMatricesRepository; +import com.imprimelibros.erp.presupuesto.marcapaginas.MarcapaginasRepository; import com.imprimelibros.erp.externalApi.skApiClient; @Service @@ -50,6 +52,9 @@ public class PresupuestoService { @Autowired protected MaquetacionMatricesRepository maquetacionMatricesRepository; + @Autowired + protected MarcapaginasRepository marcapaginasRepository; + private final PresupuestadorItems presupuestadorItems; public PresupuestoService(PresupuestadorItems presupuestadorItems) { @@ -607,7 +612,8 @@ public class PresupuestoService { BigDecimal precio = BigDecimal.ZERO; // millar_maquetacion * (numCaracteres / 1000.0) - BigDecimal millares = BigDecimal.valueOf(presupuestoMaquetacion.getNumCaracteres()).divide(BigDecimal.valueOf(1000), 6, + BigDecimal millares = BigDecimal.valueOf(presupuestoMaquetacion.getNumCaracteres()).divide( + BigDecimal.valueOf(1000), 6, RoundingMode.HALF_UP); precio = precio.add(millares.multiply(BigDecimal.valueOf(price.apply("millar_maquetacion")))); @@ -630,11 +636,14 @@ public class PresupuestoService { // tabla, columna, foto precio = precio - .add(BigDecimal.valueOf(presupuestoMaquetacion.getNumTablas()).multiply(BigDecimal.valueOf(price.apply("tabla")))); + .add(BigDecimal.valueOf(presupuestoMaquetacion.getNumTablas()) + .multiply(BigDecimal.valueOf(price.apply("tabla")))); precio = precio.add( - BigDecimal.valueOf(presupuestoMaquetacion.getNumColumnas()).multiply(BigDecimal.valueOf(price.apply("columnas")))); + BigDecimal.valueOf(presupuestoMaquetacion.getNumColumnas()) + .multiply(BigDecimal.valueOf(price.apply("columnas")))); precio = precio - .add(BigDecimal.valueOf(presupuestoMaquetacion.getNumFotos()).multiply(BigDecimal.valueOf(price.apply("foto")))); + .add(BigDecimal.valueOf(presupuestoMaquetacion.getNumFotos()) + .multiply(BigDecimal.valueOf(price.apply("foto")))); if (presupuestoMaquetacion.isCorreccionOrtotipografica()) { precio = precio @@ -658,7 +667,12 @@ public class PresupuestoService { out.put("numPaginasEstimadas", numPaginas); out.put("precioPaginaEstimado", precioPaginaEstimado); HashMap language = new HashMap<>(); - language.put("add_to_presupuesto", messageSource.getMessage("presupuesto.add-to-presupuesto", null, locale)); + language.put("num_paginas_estimadas", + messageSource.getMessage("presupuesto.maquetacion.num-paginas-estimadas", null, locale)); + language.put("precio_por_pagina_estimado", + messageSource.getMessage("presupuesto.maquetacion.precio-por-pagina-estimado", null, locale)); + language.put("add_to_presupuesto", + messageSource.getMessage("presupuesto.add-to-presupuesto", null, locale)); language.put("cancel", messageSource.getMessage("app.cancelar", null, locale)); language.put("presupuesto_maquetacion", messageSource.getMessage("presupuesto.maquetacion", null, locale)); out.put("language", language); @@ -675,4 +689,92 @@ public class PresupuestoService { return out; } + public HashMap getPrecioMarcapaginas(PresupuestoMarcapaginas presupuestoMarcapaginas, + Locale locale) { + + try { + + List m = marcapaginasRepository.findPrecios(presupuestoMarcapaginas); + if (m.isEmpty() || m.get(0) == null) { + HashMap out = new HashMap<>(); + out.put("precio_unidad", 0.0); + out.put("precio_total", 0.0); + return out; + } + + Marcapaginas marcapaginas = m.get(0); + + Double precio = 0.0; + Double margen = 0.0; + Double pvp = 0.0; + BigDecimal data = BigDecimal.ZERO; + + if (marcapaginas.getUnidades_max() >= presupuestoMarcapaginas.getUnidades()) { + + precio = marcapaginas.getPrecio_unidades_min() + + (presupuestoMarcapaginas.getUnidades() - marcapaginas.getUnidades_min()) + * (marcapaginas.getPrecio_unidades_max() - marcapaginas.getPrecio_unidades_min()) + / (marcapaginas.getUnidades_max() - marcapaginas.getUnidades_min()); + + data = new BigDecimal(precio); + precio = data.setScale(2, RoundingMode.HALF_UP).doubleValue(); + + margen = 1.0 * marcapaginas.getMargen_unidades_min() + + (1.0 * presupuestoMarcapaginas.getUnidades() - 1.0 * marcapaginas.getUnidades_min()) + * (1.0 * marcapaginas.getMargen_unidades_max() + - 1.0 * marcapaginas.getMargen_unidades_min()) + / (1.0 * marcapaginas.getUnidades_max() - 1.0 * marcapaginas.getUnidades_min()); + + data = new BigDecimal(margen); + margen = data.setScale(2, RoundingMode.HALF_UP).doubleValue(); + + pvp = precio + (precio * margen / 100); + + data = new BigDecimal(pvp); + pvp = data.setScale(2, RoundingMode.HALF_UP).doubleValue(); + + } else { + + // precio unidad para el máximo de unidades + precio = marcapaginas.getPrecio_unidades_max() / marcapaginas.getUnidades_max(); + precio = precio * presupuestoMarcapaginas.getUnidades(); + data = new BigDecimal(precio); + precio = data.setScale(2, RoundingMode.HALF_UP).doubleValue(); + + margen = 1.0 * marcapaginas.getMargen_unidades_max(); + data = new BigDecimal(margen); + margen = data.setScale(2, RoundingMode.HALF_UP).doubleValue(); + + pvp = precio + (precio * margen / 100); + data = new BigDecimal(pvp); + pvp = data.setScale(2, RoundingMode.HALF_UP).doubleValue(); + + } + + Double precio_unidad = pvp / presupuestoMarcapaginas.getUnidades(); + data = new BigDecimal(precio_unidad); + precio_unidad = data.setScale(6, RoundingMode.HALF_UP).doubleValue(); + + HashMap resultado; + resultado = new HashMap<>(); + resultado.put("precio_unitario", precio_unidad); + resultado.put("precio_total", pvp); + HashMap language = new HashMap<>(); + language.put("precio_unidad", messageSource.getMessage("presupuesto.marcapaginas.precio-unidad", null, locale)); + language.put("precio_total", messageSource.getMessage("presupuesto.marcapaginas.precio-total", null, locale)); + language.put("add_to_presupuesto", + messageSource.getMessage("presupuesto.add-to-presupuesto", null, locale)); + language.put("cancel", messageSource.getMessage("app.cancelar", null, locale)); + language.put("presupuesto_marcapaginas", messageSource.getMessage("presupuesto.marcapaginas", null, locale)); + resultado.put("language", language); + return resultado; + + } catch (Exception e) { + System.out.println("Error procesando presupuesto marcapaginas: " + e.getMessage()); + } + HashMap out = new HashMap<>(); + out.put("precio_unidad", 0.0); + out.put("precio_total", 0.0); + return out; + } } diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/classes/PresupuestoMarcapaginas.java b/src/main/java/com/imprimelibros/erp/presupuesto/classes/PresupuestoMarcapaginas.java new file mode 100644 index 0000000..28fa75c --- /dev/null +++ b/src/main/java/com/imprimelibros/erp/presupuesto/classes/PresupuestoMarcapaginas.java @@ -0,0 +1,57 @@ +package com.imprimelibros.erp.presupuesto.classes; + +import static com.imprimelibros.erp.presupuesto.marcapaginas.Marcapaginas.Papeles; +import static com.imprimelibros.erp.presupuesto.marcapaginas.Marcapaginas.Acabado; +import static com.imprimelibros.erp.presupuesto.marcapaginas.Marcapaginas.Tamanios; +import static com.imprimelibros.erp.presupuesto.marcapaginas.Marcapaginas.Caras_Impresion; + +import jakarta.validation.constraints.Min; + +public class PresupuestoMarcapaginas { + + @Min(value = 100, message = "{validation.min}") + private Integer unidades = 100; + private Tamanios tamanio = Tamanios._50x140_; + private Caras_Impresion carasImpresion = Caras_Impresion.una_cara; + private Papeles papel = Papeles.cartulina_grafica; + private Integer gramaje = 300; + private Acabado acabado = Acabado.ninguno; + + + public Integer getUnidades() { + return unidades; + } + public void setUnidades(Integer unidades) { + this.unidades = unidades; + } + public Tamanios getTamanio() { + return tamanio; + } + public void setTamanio(Tamanios tamanio) { + this.tamanio = tamanio; + } + public Caras_Impresion getCarasImpresion() { + return carasImpresion; + } + public void setCarasImpresion(Caras_Impresion carasImpresion) { + this.carasImpresion = carasImpresion; + } + public Papeles getPapel() { + return papel; + } + public void setPapel(Papeles papel) { + this.papel = papel; + } + public Integer getGramaje() { + return gramaje; + } + public void setGramaje(Integer gramaje) { + this.gramaje = gramaje; + } + public Acabado getAcabado() { + return acabado; + } + public void setAcabado(Acabado acabado) { + this.acabado = acabado; + } +} diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/marcapaginas/Marcapaginas.java b/src/main/java/com/imprimelibros/erp/presupuesto/marcapaginas/Marcapaginas.java new file mode 100644 index 0000000..4eaef57 --- /dev/null +++ b/src/main/java/com/imprimelibros/erp/presupuesto/marcapaginas/Marcapaginas.java @@ -0,0 +1,154 @@ +package com.imprimelibros.erp.presupuesto.marcapaginas; + +import jakarta.validation.constraints.NotNull; +import jakarta.persistence.*; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; + +@Entity +@Table(name = "marcapaginas") +public class Marcapaginas { + + public enum Acabado{ + ninguno, + plastificado_brillo_1c, + plastificado_brillo_2c, + plastificado_mate_1c, + plastificado_mate_2c + }; + + public enum Tamanios{ + _50x140_, _50x170_, _50x210_ + }; + + public enum Papeles{ + cartulina_grafica, estucado_mate + }; + + public enum Caras_Impresion{ + una_cara, dos_caras + }; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull(message = "{validation.required}") + @Enumerated(EnumType.STRING) + private Caras_Impresion carasImpresion = Caras_Impresion.una_cara; + + @NotNull(message = "{validation.required}") + @Enumerated(EnumType.STRING) + private Tamanios tamanio = Tamanios._50x140_; + + @NotNull(message = "{validation.required}") + @Enumerated(EnumType.STRING) + private Papeles papel = Papeles.cartulina_grafica; + + @NotNull(message = "{validation.required}") + private Integer gramaje = 300; + + @NotNull(message = "{validation.required}") + @Enumerated(EnumType.STRING) + private Acabado acabado = Acabado.ninguno; + + @Min(value = 100, message = "{validation.min}") + @NotNull(message = "{validation.required}") + private Integer unidades_min = 100; + + @Min(value = 101, message = "{validation.min}") + @NotNull(message = "{validation.required}") + private Integer unidades_max = 5000; + + @NotNull(message = "{validation.required}") + private Double precio_unidades_min; + + @NotNull(message = "{validation.required}") + private Double precio_unidades_max; + + @NotNull(message = "{validation.required}") + @Min(value = 0, message = "{validation.min}") + @Max(value = 300, message = "{validation.max}") + + private Integer margen_unidades_min = 0; + + @NotNull(message = "{validation.required}") + @Min(value = 0, message = "{validation.min}") + @Max(value = 300, message = "{validation.max}") + private Integer margen_unidades_max = 0; + + /* Getters and Setters */ + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public Caras_Impresion getCarasImpresion() { + return carasImpresion; + } + public void setCarasImpresion(Caras_Impresion carasImpresion) { + this.carasImpresion = carasImpresion; + } + public Tamanios getTamanio() { + return tamanio; + } + public void setTamanio(Tamanios tamanio) { + this.tamanio = tamanio; + } + public Papeles getPapel() { + return papel; + } + public void setPapel(Papeles papel) { + this.papel = papel; + } + public Integer getGramaje() { + return gramaje; + } + public void setGramaje(Integer gramaje) { + this.gramaje = gramaje; + } + public Acabado getAcabado() { + return acabado; + } + public void setAcabado(Acabado acabado) { + this.acabado = acabado; + } + public Integer getUnidades_min() { + return unidades_min; + } + public void setUnidades_min(Integer unidades_min) { + this.unidades_min = unidades_min; + } + public Integer getUnidades_max() { + return unidades_max; + } + public void setUnidades_max(Integer unidades_max) { + this.unidades_max = unidades_max; + } + public Double getPrecio_unidades_min() { + return precio_unidades_min; + } + public void setPrecio_unidades_min(Double precio_unidades_min) { + this.precio_unidades_min = precio_unidades_min; + } + public Double getPrecio_unidades_max() { + return precio_unidades_max; + } + public void setPrecio_unidades_max(Double precio_unidades_max) { + this.precio_unidades_max = precio_unidades_max; + } + public Integer getMargen_unidades_min() { + return margen_unidades_min; + } + public void setMargen_unidades_min(Integer margen_unidades_min) { + this.margen_unidades_min = margen_unidades_min; + } + public Integer getMargen_unidades_max() { + return margen_unidades_max; + } + public void setMargen_unidades_max(Integer margen_unidades_max) { + this.margen_unidades_max = margen_unidades_max; + } + +} diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/marcapaginas/MarcapaginasRepository.java b/src/main/java/com/imprimelibros/erp/presupuesto/marcapaginas/MarcapaginasRepository.java new file mode 100644 index 0000000..33a6482 --- /dev/null +++ b/src/main/java/com/imprimelibros/erp/presupuesto/marcapaginas/MarcapaginasRepository.java @@ -0,0 +1,32 @@ +package com.imprimelibros.erp.presupuesto.marcapaginas; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.imprimelibros.erp.presupuesto.classes.PresupuestoMarcapaginas; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import java.util.List; + +@Repository +public interface MarcapaginasRepository extends JpaRepository { + + @Query(""" + SELECT m + FROM Marcapaginas m + WHERE m.tamanio = :#{#p.tamanio} + AND m.carasImpresion = :#{#p.carasImpresion} + AND m.papel = :#{#p.papel} + AND m.gramaje = :#{#p.gramaje} + AND m.acabado = :#{#p.acabado} + AND m.unidades_min <= :#{#p.unidades} + ORDER BY + CASE + WHEN :#{#p.unidades} BETWEEN m.unidades_min AND m.unidades_max THEN 0 + ELSE 1 + END, + m.unidades_max DESC + """) + List findPrecios(@Param("p") PresupuestoMarcapaginas p); +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8ace703..6ffb606 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,6 +4,13 @@ logging.level.org.springframework.security=DEBUG logging.level.root=WARN logging.level.org.springframework=ERROR +#debug JPA / Hibernate +#spring.jpa.show-sql=true +#logging.level.org.hibernate.SQL=DEBUG +#logging.level.org.hibernate.orm.jdbc.bind=TRACE +#spring.jpa.properties.hibernate.format_sql=true + + spring.datasource.url=jdbc:mysql://localhost:3309/imprimelibros #spring.datasource.url=jdbc:mysql://127.0.0.1:3309/imprimelibros?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Europe/Madrid&characterEncoding=utf8 spring.datasource.username=imprimelibros_user diff --git a/src/main/resources/i18n/presupuesto_es.properties b/src/main/resources/i18n/presupuesto_es.properties index 1e34b44..222b3c6 100644 --- a/src/main/resources/i18n/presupuesto_es.properties +++ b/src/main/resources/i18n/presupuesto_es.properties @@ -11,6 +11,7 @@ presupuesto.datos-generales-descripcion=Datos generales del presupuesto presupuesto.titulo=Título* presupuesto.autor=Autor presupuesto.isbn=ISBN +presupuesto.tirada=Tirada presupuesto.tirada1=Tirada 1* presupuesto.tirada2=Tirada 2 presupuesto.tirada3=Tirada 3 @@ -88,6 +89,7 @@ presupuesto.cabezada-roja-amarilla=Roja-Amarilla presupuesto.papel-cubierta=Papel cubierta presupuesto.papel-cubierta-descripcion=Seleccione el papel para la cubierta presupuesto.cartulina-grafica-cubierta=Cartulina gráfica estucada a una cara +presupuesto.cartulina-grafica=Cartulina gráfica presupuesto.estucado-mate-cubierta=Estucado mate presupuesto.gramaje-cubierta=Gramaje cubierta presupuesto.gramaje-cubierta-descripcion=Seleccione el gramaje para la cubierta @@ -103,7 +105,9 @@ presupuesto.acabado-cubierta-descripcion=Seleccione el acabado para la cubierta presupuesto.acabado-cubierta-aviso=La falta de plastificado en la cubierta puede comprometer su calidad, ya que aumenta el riesgo de agrietamiento en los pliegues o hendidos, afectando su apariencia y resistencia. presupuesto.acabado-ninguno=Sin acabado presupuesto.acabado-plastificado-brillo-1c=Plastificado Brillo 1/C +presupuesto.acabado-plastificado-brillo-2c=Plastificado Brillo 2/C presupuesto.acabado-plastificado-mate-1c=Plastificado Mate 1/C +presupuesto.acabado-plastificado-mate-2c=Plastificado Mate 2/C presupuesto.acabado-plastificado-mate-1c-antirrayado=Plastificado Mate 1/C Antirrayado presupuesto.acabado-plastificado-mate-uvi=Plastificado Mate 1/C + Reserva UVI presupuesto.acabado-plastificado-mate-uvi3d=Plastificado Mate 1/C + Reserva UVI 3D @@ -181,6 +185,27 @@ presupuesto.maquetacion.correccion-ortotipografica=Corrección ortotipográfica presupuesto.maquetacion.texto-mecanografiado=Texto mecanografiado presupuesto.maquetacion.diseno-portada=Diseño de portada presupuesto.maquetacion.epub=Generación Epub +presupuesto.maquetacion.num-paginas-estimadas=Páginas estimadas +presupuesto.maquetacion.precio-por-pagina-estimado=Precio por página estimado + +# Presupuesto de marcapáginas +presupuesto.marcapaginas=Presupuesto de marcapáginas +presupuesto.marcapaginas.tamanio=Tamaño de los marcapáginas +presupuesto.marcapaginas.caras-impresion=Caras impresas +presupuesto.marcapaginas.caras-impresion-1=Una cara +presupuesto.marcapaginas.caras-impresion-2=Dos caras +presupuesto.marcapaginas.papel=Papel marcapáginas +presupuesto.marcapaginas.papel.cartulina-grafica=Cartulina gráfica +presupuesto.marcapaginas.papel.estucado-mate=Estucado mate +presupuesto.marcapaginas.gramaje=Gramaje papel marcapáginas +presupuesto.marcapaginas.acabado=Acabado marcapáginas +presupuesto.marcapaginas.acabado.ninguno=Sin acabado +presupuesto.marcapaginas.acabado.plastificado-brillo-1c=Plastificado brillo 1/C +presupuesto.marcapaginas.acabado.plastificado-mate-1c=Plastificado mate 1/C +presupuesto.marcapaginas.acabado.plastificado-brillo-2c=Plastificado brillo 2/C +presupuesto.marcapaginas.acabado.plastificado-mate-2c=Plastificado mate 2/C +presupuesto.marcapaginas.precio-unidad=Precio por unidad +presupuesto.marcapaginas.precio-total=Precio total # Errores presupuesto.errores-title=Corrija los siguientes errores: @@ -205,4 +230,5 @@ presupuesto.errores.papel-cubierta=Seleccione el tipo de papel para la cubierta presupuesto.errores.gramaje-cubierta=Seleccione el gramaje del papel para la cubierta presupuesto.errores.acabado-cubierta=Seleccione el acabado de la cubierta -presupuesto.errores.presupuesto-maquetacion=No se pudo calcular el presupuesto de maquetación. \ No newline at end of file +presupuesto.errores.presupuesto-maquetacion=No se pudo calcular el presupuesto de maquetación. +presupuesto.errores.presupuesto-marcapaginas=No se pudo calcular el presupuesto de marcapáginas. \ No newline at end of file diff --git a/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/presupuesto-maquetacion.js b/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/presupuesto-maquetacion.js index efc2f65..91987d8 100644 --- a/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/presupuesto-maquetacion.js +++ b/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/presupuesto-maquetacion.js @@ -1,4 +1,6 @@ import * as Summary from "./summary.js"; +import { formateaMoneda } from "../utils.js"; + $(document).on('change', '#maquetacion', function (e) { e.preventDefault(); @@ -35,8 +37,8 @@ $(document).on("submit", "#maquetacionForm", function (e) { const resumenHtml = `
-

Páginas calculadas: ${json.numPaginasEstimadas ?? "-"}

-

Precio por página estimado: ${formateaMoneda(json.precioPaginaEstimado) || "-"}

+

${json.language.num_paginas_estimadas || 'Páginas calculadas'}: ${json.numPaginasEstimadas ?? "-"}

+

${json.language.precio_por_pagina_estimado || 'Precio por página estimado'}: ${formateaMoneda(json.precioPaginaEstimado) || "-"}


${json.precio ? `

Precio: ${formateaMoneda(json.precio)}

` : ""} @@ -97,6 +99,7 @@ $(document).on("submit", "#maquetacionForm", function (e) { }); }); + $(document).on('hidden.bs.modal', '#maquetacionModal', function () { const calcularStr = $('#div-extras').data('language-calcular'); @@ -105,11 +108,3 @@ $(document).on('hidden.bs.modal', '#maquetacionModal', function () { $('label[for="maquetacion"] .service-price').text(calcularStr); }); -function formateaMoneda(valor) { - try { - return new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'EUR' }).format(valor); - } catch { - return valor; - } -} - diff --git a/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/presupuesto-marcapaginas.js b/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/presupuesto-marcapaginas.js new file mode 100644 index 0000000..94349f5 --- /dev/null +++ b/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/presupuesto-marcapaginas.js @@ -0,0 +1,143 @@ +import * as Summary from "./summary.js"; +import { formateaMoneda, formateaMoneda6Decimales } from "../utils.js"; + +$(document).on('change', '#marcapaginas', function (e) { + e.preventDefault(); + if ($('#marcapaginas').is(':checked')) { + $.get("/presupuesto/public/marcapaginas/form", function (data) { + $("#marcapaginasModalBody").html(data); + + // init marcapaginas form + filtrarAcabados(); + $("#marcapaginasModal").modal("show"); + }); + } else { + const calcularStr = $('#div-extras').data('language-calcular'); + $('#marcapaginas').data('price', calcularStr); + $('label[for="marcapaginas"] .service-price') + .text(calcularStr); + $('#marcapaginas').prop('checked', false); + } +}); + +$(document).on("submit", "#marcapaginasForm", function (e) { + e.preventDefault(); + + const $form = $(this); + + $.ajax({ + url: $form.attr("action"), + type: $form.attr("method"), + data: $form.serialize(), + dataType: "json", + success: function (json) { + + const modalEl = document.getElementById("marcapaginasModal"); + const modal = bootstrap.Modal.getInstance(modalEl) || new bootstrap.Modal(modalEl); + modal.hide(); + + + const resumenHtml = ` +
+

${json.language.precio_unidad || 'Precio por unidad'}: ${formateaMoneda6Decimales(json.precio_unitario) || "-"}

+

${json.language.precio_total || 'Precio total'}: ${formateaMoneda(json.precio_total) || "-"}

+
+ `; + + Swal.fire({ + title: json.language.presupuesto_marcapaginas || 'Presupuesto Marcapáginas', + html: resumenHtml, + icon: 'info', + showCancelButton: true, + confirmButtonText: json.language.add_to_presupuesto || 'Añadir al presupuesto', + cancelButtonText: json.language.cancel || 'Cancelar', + customClass: { + confirmButton: 'btn btn-secondary me-2', // clases para el botón confirmar + cancelButton: 'btn btn-light' // clases para cancelar + }, + buttonsStyling: false, + reverseButtons: false, + allowOutsideClick: false + }).then((result) => { + if (result.isConfirmed) { + $('#marcapaginas').prop('checked', true); + $('#marcapaginas').data('price', json.precio_total); + $('label[for="marcapaginas"] .service-price') + .text(formateaMoneda(json.precio_total)); + Summary.updateExtras(); + } + else { + const calcularStr = $('#div-extras').data('language-calcular'); + $('#marcapaginas').prop('checked', false); + $('#marcapaginas').data('price', calcularStr); + $('label[for="marcapaginas"] .service-price').text(calcularStr); + } + }); + }, + error: function (xhr, status, error) { + try { + const errs = JSON.parse(xhr.responseText); // { numCaracteres: "…" , … } + // limpia errores previos + $form.find(".is-invalid").removeClass("is-invalid"); + $form.find(".invalid-feedback").text(""); + + // recorre los errores y los muestra + Object.entries(errs).forEach(([field, msg]) => { + const $input = $form.find(`[name="${field}"]`); + if ($input.length) { + $input.addClass("is-invalid"); + $input.siblings(".invalid-feedback").text(msg); + } + }); + } catch { + $("#marcapaginasModalBody").html( + "
" + xhr.responseText + "
" + ); + } + } + }); +}); + + +$(document).on("change", "#caras-impresion", function (e) { + e.preventDefault(); + filtrarAcabados(); +}); + + +$(document).on('hidden.bs.modal', '#marcapaginasModal', function () { + + const calcularStr = $('#div-extras').data('language-calcular'); + $('#marcapaginas').prop('checked', false); + $('#marcapaginas').data('price', calcularStr); + $('label[for="marcapaginas"] .service-price').text(calcularStr); +}); + + +function filtrarAcabados() { + const $select = $("#acabado-marcapaginas"); + const caras = $("#caras-impresion").val(); // "una_cara" o "dos_caras" + + $select.find("option") + .prop("disabled", true) + .attr("hidden", true); + + if (caras === "una_cara") { + $select.find("option.marcapaginas-1cara") + .prop("disabled", false) + .attr("hidden", false); + } else { + $select.find("option.marcapaginas-2caras") + .prop("disabled", false) + .attr("hidden", false); + } + + if ($select.find("option:selected").prop("disabled")) { + const firstEnabled = $select.find("option:not([disabled]):first").val(); + $select.val(firstEnabled).trigger("change"); + } +} + + + + diff --git a/src/main/resources/static/assets/js/pages/imprimelibros/utils.js b/src/main/resources/static/assets/js/pages/imprimelibros/utils.js new file mode 100644 index 0000000..4872496 --- /dev/null +++ b/src/main/resources/static/assets/js/pages/imprimelibros/utils.js @@ -0,0 +1,26 @@ +function formateaMoneda(valor) { + try { + return new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'EUR' }).format(valor); + } catch { + return valor; + } +} +export { formateaMoneda }; + +function formateaMoneda4Decimales(valor) { + try { + return new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'EUR', minimumFractionDigits: 4 }).format(valor); + } catch { + return valor; + } +} +export { formateaMoneda4Decimales }; + +function formateaMoneda6Decimales(valor) { + try { + return new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'EUR', minimumFractionDigits: 6 }).format(valor); + } catch { + return valor; + } +} +export { formateaMoneda6Decimales }; \ No newline at end of file diff --git a/src/main/resources/templates/imprimelibros/home.html b/src/main/resources/templates/imprimelibros/home.html index d1816c9..a5be360 100644 --- a/src/main/resources/templates/imprimelibros/home.html +++ b/src/main/resources/templates/imprimelibros/home.html @@ -37,6 +37,7 @@ +