From 389ac22b68ad3728235da9ef4d0f117fb0a00314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Tue, 7 Oct 2025 10:44:32 +0200 Subject: [PATCH] ya obtengo los datos de los anonimos, falta formatear esos datos y buscar --- .../MargenPresupuesto.java | 5 +- .../MargenPresupuestoController.java | 4 +- .../MargenPresupuestoDao.java | 4 +- .../MargenPresupuestoService.java | 4 +- .../erp/datatables/DataTable.java | 8 +- .../erp/externalApi/skApiClient.java | 4 +- .../erp/i18n/TranslationService.java | 6 +- .../com/imprimelibros/erp/presupuesto.zip | Bin 0 -> 39150 bytes .../presupuesto/PresupuestoController.java | 134 +++++++++++------- .../presupuesto/PresupuestoRepository.java | 39 ++++- .../erp/presupuesto/PresupuestoService.java | 3 +- .../classes/PresupuestoFormatter.java | 3 +- .../presupuesto/{ => dto}/Presupuesto.java | 18 ++- .../presupuesto/dto/PresupuestoDTAnonimo.java | 20 +++ .../ConsistentTiradasValidator.java | 2 +- .../validation/TamanioValidator.java | 2 +- .../pages/imprimelibros/presupuestos/list.js | 31 ++-- .../tabla-anonimos.html | 7 +- .../erp/presupuesto/skApiClientTest.java | 4 +- 19 files changed, 205 insertions(+), 93 deletions(-) create mode 100644 src/main/java/com/imprimelibros/erp/presupuesto.zip rename src/main/java/com/imprimelibros/erp/presupuesto/{ => dto}/Presupuesto.java (98%) create mode 100644 src/main/java/com/imprimelibros/erp/presupuesto/dto/PresupuestoDTAnonimo.java diff --git a/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuesto.java b/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuesto.java index c0c52f2..257bcab 100644 --- a/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuesto.java +++ b/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuesto.java @@ -9,8 +9,9 @@ import java.time.LocalDateTime; import org.hibernate.annotations.SQLDelete; import org.hibernate.annotations.SQLRestriction; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoEncuadernacion; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; + +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoEncuadernacion; import com.imprimelibros.erp.shared.validation.NoRangeOverlap; diff --git a/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoController.java b/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoController.java index 9b55d34..a1a14dc 100644 --- a/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoController.java +++ b/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoController.java @@ -28,8 +28,8 @@ import com.imprimelibros.erp.datatables.DataTablesParser; import com.imprimelibros.erp.datatables.DataTablesRequest; import com.imprimelibros.erp.datatables.DataTablesResponse; import com.imprimelibros.erp.i18n.TranslationService; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoEncuadernacion; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoEncuadernacion; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoDao.java b/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoDao.java index a85e679..309dffc 100644 --- a/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoDao.java +++ b/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoDao.java @@ -5,8 +5,8 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoEncuadernacion; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoEncuadernacion; public interface MargenPresupuestoDao extends JpaRepository, JpaSpecificationExecutor { diff --git a/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoService.java b/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoService.java index b87f4c1..a88e5f6 100644 --- a/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoService.java +++ b/src/main/java/com/imprimelibros/erp/configuracion/margenes_presupuestos/MargenPresupuestoService.java @@ -6,8 +6,8 @@ import java.util.Optional; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoEncuadernacion; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoEncuadernacion; @Service @Transactional diff --git a/src/main/java/com/imprimelibros/erp/datatables/DataTable.java b/src/main/java/com/imprimelibros/erp/datatables/DataTable.java index 6af6ba3..05251ca 100644 --- a/src/main/java/com/imprimelibros/erp/datatables/DataTable.java +++ b/src/main/java/com/imprimelibros/erp/datatables/DataTable.java @@ -33,6 +33,12 @@ public class DataTable { .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); private List orderable = null; + private boolean onlyAdded = false; + public DataTable onlyAddedColumns(){ + this.onlyAdded = true; + return this; + } + private DataTable(JpaSpecificationExecutor repo, Class entityClass, DataTablesRequest dt, List searchable) { this.repo = repo; @@ -148,7 +154,7 @@ public class DataTable { // Mapear entidad -> Map base (via Jackson) + add/edit List> data = new ArrayList<>(); for (T e : p.getContent()) { - Map row = om.convertValue(e, Map.class); + Map row = onlyAdded ? new HashMap<>() : om.convertValue(e, Map.class); row.put("__entity", e); // para editores que necesiten la entidad for (var ad : adders) row.putAll(ad.apply(e)); diff --git a/src/main/java/com/imprimelibros/erp/externalApi/skApiClient.java b/src/main/java/com/imprimelibros/erp/externalApi/skApiClient.java index 5f5cfb4..37f8089 100644 --- a/src/main/java/com/imprimelibros/erp/externalApi/skApiClient.java +++ b/src/main/java/com/imprimelibros/erp/externalApi/skApiClient.java @@ -13,8 +13,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.imprimelibros.erp.configuracion.margenes_presupuestos.MargenPresupuesto; import com.imprimelibros.erp.configuracion.margenes_presupuestos.MargenPresupuestoDao; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoEncuadernacion; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoEncuadernacion; import java.util.Map; import java.util.HashMap; diff --git a/src/main/java/com/imprimelibros/erp/i18n/TranslationService.java b/src/main/java/com/imprimelibros/erp/i18n/TranslationService.java index e46de46..a2a8198 100644 --- a/src/main/java/com/imprimelibros/erp/i18n/TranslationService.java +++ b/src/main/java/com/imprimelibros/erp/i18n/TranslationService.java @@ -4,9 +4,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.stereotype.Component; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoEncuadernacion; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoImpresion; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoEncuadernacion; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoImpresion; import java.util.*; diff --git a/src/main/java/com/imprimelibros/erp/presupuesto.zip b/src/main/java/com/imprimelibros/erp/presupuesto.zip new file mode 100644 index 0000000000000000000000000000000000000000..f40202eff7cd44b0124a58267bc8efdd8d8b1aa1 GIT binary patch literal 39150 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 literal 0 HcmV?d00001 diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoController.java b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoController.java index 944dd3f..1e89a7e 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoController.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoController.java @@ -3,16 +3,22 @@ package com.imprimelibros.erp.presupuesto; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import java.util.Arrays; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Optional; +import java.util.TimeZone; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; -import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.validation.BindingResult; @@ -22,24 +28,21 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.http.MediaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.type.TypeReference; -import com.imprimelibros.erp.configuracion.margenes_presupuestos.MargenPresupuesto; -import com.imprimelibros.erp.datatables.DataTable; -import com.imprimelibros.erp.datatables.DataTablesParser; -import com.imprimelibros.erp.datatables.DataTablesRequest; -import com.imprimelibros.erp.datatables.DataTablesResponse; +import com.imprimelibros.erp.datatables.*; import com.imprimelibros.erp.externalApi.skApiClient; import com.imprimelibros.erp.i18n.TranslationService; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoEncuadernacion; 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.dto.Presupuesto; +import com.imprimelibros.erp.presupuesto.dto.PresupuestoDTAnonimo; import com.imprimelibros.erp.presupuesto.validation.PresupuestoValidationGroups; import jakarta.servlet.http.HttpServletRequest; @@ -439,54 +442,87 @@ public class PresupuestoController { return "imprimelibros/presupuestos/presupuesto-list"; } - @GetMapping(value = "/datatable/{tipo}", produces = "application/json") + @GetMapping(value = "/datatable/anonimos", produces = "application/json") @ResponseBody - public DataTablesResponse> datatable(@RequestParam("tipo") String tipo, - HttpServletRequest request, Authentication authentication, + public DataTablesResponse> datatable( + HttpServletRequest request, + Authentication authentication, Locale locale) { - DataTablesRequest dt = DataTablesParser.from(request); - List searchable = List.of( - "id", - "titulo", - "cliente", - "tipoEncuadernacion", - "tipoCubierta", - "tipoImpresion", - "tirada", - "paginas", - "estado", "total", "pais", "region", "ciudad", "updatedAt"); + // Filtros (opcional): p.ej. estado desde select extra + String fEstado = Optional.ofNullable(dt.raw.get("f_estado")).orElse(""); // '', 'borrador', ... + String term = (dt.search != null && dt.search.value != null) ? dt.search.value.trim() : ""; - List orderable = List.of(/* - * "id", - * "tipoEncuadernacion", - * "tipoCubierta", - * "tiradaMin", - * "tiradaMax", - * "margenMin", - * "margenMax" - */); + // Pageable y Sort desde DataTables (usarás 'name' completos en el front) + int page = dt.length > 0 ? dt.start / dt.length : 0; + List orders = new ArrayList<>(); + for (var o : dt.order) { + String field = dt.columns.get(o.column).name; // EJ: "cliente.nombre", "tipoImpresion", "pais" + // Whitelist de campos ordenables: + switch (field) { + case "id", "titulo", + "tipoEncuadernacion", "tipoCubierta", "tipoImpresion", + "selectedTirada", "paginas", "estado", + "totalConIva", + "pais", "region", "ciudad", + "updatedAt" -> + orders.add(new Sort.Order( + "desc".equalsIgnoreCase(o.dir) ? Sort.Direction.DESC : Sort.Direction.ASC, + field)); + default -> { + /* ignora */ } + } + } + Sort sort = orders.isEmpty() ? Sort.by(Sort.Order.asc("id")) : Sort.by(orders); + Pageable pageable = dt.length > 0 ? PageRequest.of(page, dt.length, sort) : Pageable.unpaged(); - Specification base = (root, query, cb) -> cb.conjunction(); + // Query DTO + Page pageDTO = repo.datatableAnonimos(fEstado, term, pageable); long total = repo.count(); - return DataTable - .of(repo, MargenPresupuesto.class, dt, searchable) // 'searchable' en DataTable.java - // edita columnas "reales": - .orderable(orderable) - .add("actions", (presupuesto) -> { - return "
\n" + - " \n" - + " \n" - + "
"; - }) - .where(base) - .toJson(total); + // para formatear la fecha + ZoneId zone = null; + if (locale != null && locale.getCountry() != null && !locale.getCountry().isEmpty()) { + zone = TimeZone.getTimeZone(locale.toLanguageTag()).toZoneId(); + } else { + zone = ZoneId.systemDefault(); // fallback + } + DateTimeFormatter df = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm").withZone(zone); + + // Mapear DTO -> Map para DataTables + acciones + List> rows = pageDTO.getContent().stream().map(r -> { + Map m = new HashMap<>(); + m.put("id", r.id()); + m.put("titulo", r.titulo()); + m.put("tipoEncuadernacion", r.tipoEncuadernacion().name()); // o etiqueta i18n si quieres + m.put("tipoCubierta", r.tipoCubierta().name()); + m.put("tipoImpresion", r.tipoImpresion().name()); + m.put("tirada", r.selectedTirada()); + m.put("paginas", r.paginas()); + m.put("estado", r.estado().name()); + m.put("totalConIva", r.totalConIva()); + m.put("pais", r.pais()); + m.put("region", r.region()); + m.put("ciudad", r.ciudad()); + m.put("updatedAt", r.updatedAt() == null ? "" : df.format(r.updatedAt())); + + + // Mantén aquí tu “actions” como antes (puedes usar `tipo` en el css) + m.put("actions", + "
" + + " " + + " " + + "
"); + return m; + }).toList(); + + return new DataTablesResponse<>(dt.draw, total, pageDTO.getTotalElements(), rows); + } } diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoRepository.java b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoRepository.java index a9d42f4..e9fbf69 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoRepository.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoRepository.java @@ -5,13 +5,16 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; -import com.imprimelibros.erp.configuracion.margenes_presupuestos.MargenPresupuesto; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto; +import com.imprimelibros.erp.presupuesto.dto.PresupuestoDTAnonimo; import java.util.*; @Repository -public interface PresupuestoRepository extends JpaRepository, JpaSpecificationExecutor { +public interface PresupuestoRepository extends JpaRepository, JpaSpecificationExecutor { Optional findFirstBySessionIdAndOrigenAndEstadoInOrderByUpdatedAtDesc( String sessionId, @@ -26,4 +29,36 @@ public interface PresupuestoRepository extends JpaRepository, Optional findTopBySessionIdAndEstadoOrderByCreatedAtDesc(String sessionId, Presupuesto.Estado estado); + @Query(""" + select new com.imprimelibros.erp.presupuesto.dto.PresupuestoDTAnonimo( + p.id, + p.titulo, + p.tipoEncuadernacion, + p.tipoCubierta, + p.tipoImpresion, + p.selectedTirada, + cast(coalesce(p.paginasColor,0) + coalesce(p.paginasNegro,0) as integer), + p.estado, + p.totalConIva, + p.pais, + p.region, + p.ciudad, + p.updatedAt + ) + from Presupuesto p + where + (:estado = '' or str(p.estado) = :estado) + and ( + :term = '' or + lower(p.titulo) like concat('%', lower(:term), '%') or + lower(p.ciudad) like concat('%', lower(:term), '%') or + lower(p.region) like concat('%', lower(:term), '%') or + lower(p.pais) like concat('%', lower(:term), '%') + ) + """) + Page datatableAnonimos( + @Param("estado") String estado, // '', 'borrador', 'aceptado', 'modificado' + @Param("term") String term, + Pageable pageable + ); } diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoService.java b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoService.java index 4bb77bc..57e1f74 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoService.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/PresupuestoService.java @@ -23,7 +23,6 @@ import java.math.BigDecimal; import java.math.RoundingMode; import com.imprimelibros.erp.configurationERP.VariableService; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; import com.imprimelibros.erp.presupuesto.classes.ImagenPresupuesto; import com.imprimelibros.erp.presupuesto.classes.PresupuestadorItems; import com.imprimelibros.erp.presupuesto.classes.PresupuestoFormatter; @@ -32,6 +31,8 @@ import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionPreciosRepositor import com.imprimelibros.erp.presupuesto.marcapaginas.Marcapaginas; import com.imprimelibros.erp.presupuesto.classes.PresupuestoMaquetacion; import com.imprimelibros.erp.presupuesto.classes.PresupuestoMarcapaginas; +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.externalApi.skApiClient; diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/classes/PresupuestoFormatter.java b/src/main/java/com/imprimelibros/erp/presupuesto/classes/PresupuestoFormatter.java index a01c41f..a796175 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/classes/PresupuestoFormatter.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/classes/PresupuestoFormatter.java @@ -3,7 +3,8 @@ package com.imprimelibros.erp.presupuesto.classes; import org.springframework.stereotype.Component; import com.imprimelibros.erp.i18n.TranslationService; -import com.imprimelibros.erp.presupuesto.Presupuesto; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto; + import org.springframework.context.MessageSource; import java.util.Locale; diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/Presupuesto.java b/src/main/java/com/imprimelibros/erp/presupuesto/dto/Presupuesto.java similarity index 98% rename from src/main/java/com/imprimelibros/erp/presupuesto/Presupuesto.java rename to src/main/java/com/imprimelibros/erp/presupuesto/dto/Presupuesto.java index 972ca44..8faa4ef 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/Presupuesto.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/dto/Presupuesto.java @@ -1,4 +1,4 @@ -package com.imprimelibros.erp.presupuesto; +package com.imprimelibros.erp.presupuesto.dto; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -188,6 +188,11 @@ public class Presupuesto extends AbstractAuditedEntity implements Cloneable { // ====== 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") @@ -858,4 +863,15 @@ public class Presupuesto extends AbstractAuditedEntity implements Cloneable { this.altoFaja = altoFaja; } + public Long getId(){ + + return id; + } + + public void setId(Long id){ + this.id = id; + } + + + } diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/dto/PresupuestoDTAnonimo.java b/src/main/java/com/imprimelibros/erp/presupuesto/dto/PresupuestoDTAnonimo.java new file mode 100644 index 0000000..832ead5 --- /dev/null +++ b/src/main/java/com/imprimelibros/erp/presupuesto/dto/PresupuestoDTAnonimo.java @@ -0,0 +1,20 @@ +package com.imprimelibros.erp.presupuesto.dto; + +import java.math.BigDecimal; +import java.time.Instant; + +public record PresupuestoDTAnonimo( + Long id, + String titulo, // c.nombre + Presupuesto.TipoEncuadernacion tipoEncuadernacion, + Presupuesto.TipoCubierta tipoCubierta, + Presupuesto.TipoImpresion tipoImpresion, + Integer selectedTirada, + Integer paginas, + Presupuesto.Estado estado, + BigDecimal totalConIva, + String pais, + String region, + String ciudad, + Instant updatedAt +) {} diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/validation/ConsistentTiradasValidator.java b/src/main/java/com/imprimelibros/erp/presupuesto/validation/ConsistentTiradasValidator.java index 3989806..896767e 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/validation/ConsistentTiradasValidator.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/validation/ConsistentTiradasValidator.java @@ -1,7 +1,7 @@ package com.imprimelibros.erp.presupuesto.validation; import com.imprimelibros.erp.configurationERP.VariableService; -import com.imprimelibros.erp.presupuesto.Presupuesto; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; diff --git a/src/main/java/com/imprimelibros/erp/presupuesto/validation/TamanioValidator.java b/src/main/java/com/imprimelibros/erp/presupuesto/validation/TamanioValidator.java index 31389d0..3ca3dcc 100644 --- a/src/main/java/com/imprimelibros/erp/presupuesto/validation/TamanioValidator.java +++ b/src/main/java/com/imprimelibros/erp/presupuesto/validation/TamanioValidator.java @@ -1,7 +1,7 @@ package com.imprimelibros.erp.presupuesto.validation; import com.imprimelibros.erp.configurationERP.VariableService; -import com.imprimelibros.erp.presupuesto.Presupuesto; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; diff --git a/src/main/resources/static/assets/js/pages/imprimelibros/presupuestos/list.js b/src/main/resources/static/assets/js/pages/imprimelibros/presupuestos/list.js index 5ebe0c7..ca58cf5 100644 --- a/src/main/resources/static/assets/js/pages/imprimelibros/presupuestos/list.js +++ b/src/main/resources/static/assets/js/pages/imprimelibros/presupuestos/list.js @@ -52,24 +52,23 @@ }, order: [[0, 'asc']], columns: [ - { data: 'id', name: 'id', orderable: true }, - { data: 'cliente', name: 'cliente', orderable: true }, - { data: 'tipoEncuadernacion', name: 'tipoEncuadernacion', orderable: true }, - { data: 'tipoCubierta', name: 'tipoCubierta', orderable: true }, - { data: 'tipoImpresion', name: 'tipoImpresion', orderable: true }, - { data: 'tirada', name: 'tirada', orderable: true }, - { data: 'paginas', name: 'paginas', orderable: true }, - { data: 'estado', name: 'estado', orderable: true }, - { data: 'total', name: 'total', orderable: true }, - { data: 'pais', name: 'pais', orderable: true }, - { data: 'region', name: 'region', orderable: true }, - { data: 'ciudad', name: 'ciudad', orderable: true }, - { data: 'updatedAt', name: 'updatedAt', orderable: true }, - { data: 'actions', name: 'actions' } + { data: 'id', name: 'id', title: 'ID', orderable: true }, + { data: 'titulo', name: 'titulo', title: 'Título', orderable: true }, + { data: 'tipoEncuadernacion', name: 'tipoEncuadernacion', title: 'Encuadernación', orderable: true }, + { data: 'tipoCubierta', name: 'tipoCubierta', title: 'Cubierta', orderable: true }, + { data: 'tipoImpresion', name: 'tipoImpresion', title: 'Tipo de impresión', orderable: true }, + { data: 'tirada', name: 'selectedTirada', title: 'Tirada', orderable: true }, + { data: 'paginas', name: 'paginas', title: 'Páginas', orderable: true }, + { data: 'estado', name: 'estado', title: 'Estado', orderable: true }, + { data: 'totalConIva', name: 'totalConIva', title: 'Total con IVA', orderable: true }, + { data: 'pais', name: 'pais', title: 'País', orderable: true }, + { data: 'region', name: 'region', title: 'Región', orderable: true }, + { data: 'ciudad', name: 'ciudad', title: 'Ciudad', orderable: true }, + { data: 'updatedAt', name: 'updatedAt', title: 'Actualizado el', orderable: true }, + { data: 'actions', title: 'Acciones', orderable: false, searchable: false } ], - columnDefs: [{ targets: -1, orderable: false, searchable: false }] }); - + })(); diff --git a/src/main/resources/templates/imprimelibros/presupuestos/presupuesto-list-items/tabla-anonimos.html b/src/main/resources/templates/imprimelibros/presupuestos/presupuesto-list-items/tabla-anonimos.html index 88e65a8..4e70789 100644 --- a/src/main/resources/templates/imprimelibros/presupuestos/presupuesto-list-items/tabla-anonimos.html +++ b/src/main/resources/templates/imprimelibros/presupuestos/presupuesto-list-items/tabla-anonimos.html @@ -1,10 +1,9 @@
- +
- @@ -18,9 +17,7 @@ - - - + diff --git a/src/test/java/com/imprimelibros/erp/presupuesto/skApiClientTest.java b/src/test/java/com/imprimelibros/erp/presupuesto/skApiClientTest.java index 87ecb0d..2943133 100644 --- a/src/test/java/com/imprimelibros/erp/presupuesto/skApiClientTest.java +++ b/src/test/java/com/imprimelibros/erp/presupuesto/skApiClientTest.java @@ -11,8 +11,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import com.imprimelibros.erp.externalApi.skApiClient; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; -import com.imprimelibros.erp.presupuesto.Presupuesto.TipoEncuadernacion; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoCubierta; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto.TipoEncuadernacion; @SpringBootTest class skApiClientTest {
ID TítuloCliente Encuadernación Cubierta Tipo de impresiónActualizado el Acciones