mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 00:48:49 +00:00
tabla anonimos terminado
This commit is contained in:
@ -2,23 +2,13 @@ package com.imprimelibros.erp.presupuesto;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
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.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;
|
||||
@ -28,13 +18,13 @@ 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.datatables.*;
|
||||
import com.imprimelibros.erp.externalApi.skApiClient;
|
||||
import com.imprimelibros.erp.i18n.TranslationService;
|
||||
@ -42,7 +32,6 @@ 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;
|
||||
@ -63,13 +52,13 @@ public class PresupuestoController {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private final TranslationService translationService;
|
||||
private final PresupuestoRepository repo;
|
||||
private final PresupuestoDatatableService dtService;
|
||||
|
||||
public PresupuestoController(ObjectMapper objectMapper, TranslationService translationService,
|
||||
PresupuestoRepository repo) {
|
||||
PresupuestoDatatableService dtService) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.translationService = translationService;
|
||||
this.repo = repo;
|
||||
this.dtService = dtService;
|
||||
}
|
||||
|
||||
@PostMapping("/public/validar/datos-generales")
|
||||
@ -444,85 +433,11 @@ public class PresupuestoController {
|
||||
|
||||
@GetMapping(value = "/datatable/anonimos", produces = "application/json")
|
||||
@ResponseBody
|
||||
public DataTablesResponse<Map<String, Object>> datatable(
|
||||
HttpServletRequest request,
|
||||
Authentication authentication,
|
||||
Locale locale) {
|
||||
public DataTablesResponse<Map<String,Object>> datatableAnonimos(
|
||||
HttpServletRequest request, Authentication auth, Locale locale) {
|
||||
|
||||
DataTablesRequest dt = DataTablesParser.from(request);
|
||||
|
||||
// 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() : "";
|
||||
|
||||
// Pageable y Sort desde DataTables (usarás 'name' completos en el front)
|
||||
int page = dt.length > 0 ? dt.start / dt.length : 0;
|
||||
List<Sort.Order> 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();
|
||||
|
||||
// Query DTO
|
||||
Page<PresupuestoDTAnonimo> pageDTO = repo.datatableAnonimos(fEstado, term, pageable);
|
||||
long total = repo.count();
|
||||
|
||||
// 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<Map<String, Object>> rows = pageDTO.getContent().stream().map(r -> {
|
||||
Map<String, Object> 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",
|
||||
"<div class=\"hstack gap-3 flex-wrap\">" +
|
||||
" <a href=\"javascript:void(0);\" data-id=\"" + r.id()
|
||||
+ "\" class=\"link-success btn-edit-anonimo"
|
||||
+ " fs-15\"><i class=\"ri-edit-2-line\"></i></a>" +
|
||||
" <a href=\"javascript:void(0);\" data-id=\"" + r.id()
|
||||
+ "\" class=\"link-danger btn-delete-anonimo"
|
||||
+ " fs-15\"><i class=\"ri-delete-bin-5-line\"></i></a>" +
|
||||
"</div>");
|
||||
return m;
|
||||
}).toList();
|
||||
|
||||
return new DataTablesResponse<>(dt.draw, total, pageDTO.getTotalElements(), rows);
|
||||
|
||||
return dtService.datatableAnonimos(dt, locale);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,233 @@
|
||||
package com.imprimelibros.erp.presupuesto;
|
||||
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.domain.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.imprimelibros.erp.datatables.*;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||
|
||||
@Service
|
||||
public class PresupuestoDatatableService {
|
||||
|
||||
private final MessageSource messageSource;
|
||||
private final PresupuestoRepository repo;
|
||||
|
||||
public PresupuestoDatatableService(MessageSource messageSource, PresupuestoRepository repo) {
|
||||
this.messageSource = messageSource;
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
/* ---------- API pública ---------- */
|
||||
|
||||
public DataTablesResponse<Map<String, Object>> datatableAnonimos(DataTablesRequest dt, Locale locale) {
|
||||
String term = extractSearch(dt);
|
||||
Pageable pageable = pageableFrom(dt);
|
||||
|
||||
EnumMatches matches = buildEnumMatches(term, locale);
|
||||
|
||||
Specification<Presupuesto> spec = baseSpec(term, matches, dt);
|
||||
Page<Presupuesto> page = repo.findAll(spec, pageable);
|
||||
|
||||
var rows = page.getContent().stream()
|
||||
.map(p -> mapAnonimoRow(p, locale)) // 👈 mapper específico “anonimos”
|
||||
.toList();
|
||||
|
||||
return new DataTablesResponse<>(dt.draw, repo.count(), page.getTotalElements(), rows);
|
||||
}
|
||||
|
||||
public DataTablesResponse<Map<String, Object>> datatableNoAnonimos(DataTablesRequest dt, Locale locale) {
|
||||
String term = extractSearch(dt);
|
||||
Pageable pageable = pageableFrom(dt);
|
||||
|
||||
EnumMatches matches = buildEnumMatches(term, locale);
|
||||
|
||||
Specification<Presupuesto> spec = baseSpec(term, matches, dt);
|
||||
Page<Presupuesto> page = repo.findAll(spec, pageable);
|
||||
|
||||
var rows = page.getContent().stream()
|
||||
.map(p -> mapNoAnonimoRow(p, locale)) // 👈 otro mapper con más/otros campos
|
||||
.toList();
|
||||
|
||||
return new DataTablesResponse<>(dt.draw, repo.count(), page.getTotalElements(), rows);
|
||||
}
|
||||
|
||||
/* ---------- Helpers reutilizables ---------- */
|
||||
|
||||
private String extractSearch(DataTablesRequest dt) {
|
||||
return (dt.search != null && dt.search.value != null) ? dt.search.value.trim().toLowerCase() : "";
|
||||
}
|
||||
|
||||
private Pageable pageableFrom(DataTablesRequest dt) {
|
||||
int page = dt.length > 0 ? dt.start / dt.length : 0;
|
||||
List<Sort.Order> orders = new ArrayList<>();
|
||||
for (var o : dt.order) {
|
||||
String field = dt.columns.get(o.column).name; // usa columns[i][name] en el front
|
||||
if (field == null || field.isBlank())
|
||||
continue;
|
||||
orders.add(
|
||||
new Sort.Order("desc".equalsIgnoreCase(o.dir) ? Sort.Direction.DESC : Sort.Direction.ASC, field));
|
||||
}
|
||||
Sort sort = orders.isEmpty() ? Sort.by(Sort.Order.desc("updatedAt")) : Sort.by(orders);
|
||||
return dt.length > 0 ? PageRequest.of(page, dt.length, sort) : Pageable.unpaged();
|
||||
}
|
||||
|
||||
private EnumMatches buildEnumMatches(String term, Locale locale) {
|
||||
Function<String, String> tr = key -> {
|
||||
try {
|
||||
return messageSource.getMessage(key, null, locale).toLowerCase();
|
||||
} catch (Exception e) {
|
||||
return key.toLowerCase();
|
||||
}
|
||||
};
|
||||
|
||||
var enc = Arrays.stream(Presupuesto.TipoEncuadernacion.values())
|
||||
.filter(e -> tr.apply(e.getMessageKey()).contains(term))
|
||||
.collect(() -> EnumSet.noneOf(Presupuesto.TipoEncuadernacion.class), EnumSet::add, EnumSet::addAll);
|
||||
|
||||
var cub = Arrays.stream(Presupuesto.TipoCubierta.values())
|
||||
.filter(e -> tr.apply(e.getMessageKey()).contains(term))
|
||||
.collect(() -> EnumSet.noneOf(Presupuesto.TipoCubierta.class), EnumSet::add, EnumSet::addAll);
|
||||
|
||||
var imp = Arrays.stream(Presupuesto.TipoImpresion.values())
|
||||
.filter(e -> tr.apply(e.getMessageKey()).contains(term))
|
||||
.collect(() -> EnumSet.noneOf(Presupuesto.TipoImpresion.class), EnumSet::add, EnumSet::addAll);
|
||||
|
||||
var est = Arrays.stream(Presupuesto.Estado.values())
|
||||
.filter(e -> tr.apply(e.getMessageKey()).contains(term))
|
||||
.collect(() -> EnumSet.noneOf(Presupuesto.Estado.class), EnumSet::add, EnumSet::addAll);
|
||||
|
||||
return new EnumMatches(enc, cub, imp, est);
|
||||
}
|
||||
|
||||
/**
|
||||
* WHERE + ORDER dinámico (paginas/estado) reutilizable para ambos datatables
|
||||
*/
|
||||
private Specification<Presupuesto> baseSpec(String term, EnumMatches m, DataTablesRequest dt) {
|
||||
return (root, query, cb) -> {
|
||||
List<Predicate> ors = new ArrayList<>();
|
||||
|
||||
if (!term.isBlank()) {
|
||||
String like = "%" + term + "%";
|
||||
ors.add(cb.like(cb.lower(root.get("titulo")), like));
|
||||
ors.add(cb.like(cb.lower(root.get("ciudad")), like));
|
||||
ors.add(cb.like(cb.lower(root.get("region")), like));
|
||||
ors.add(cb.like(cb.lower(root.get("pais")), like));
|
||||
}
|
||||
if (!m.enc.isEmpty())
|
||||
ors.add(root.get("tipoEncuadernacion").in(m.enc));
|
||||
if (!m.cub.isEmpty())
|
||||
ors.add(root.get("tipoCubierta").in(m.cub));
|
||||
if (!m.imp.isEmpty())
|
||||
ors.add(root.get("tipoImpresion").in(m.imp));
|
||||
if (!m.est.isEmpty())
|
||||
ors.add(root.get("estado").in(m.est));
|
||||
|
||||
// ORDER BY especial si en columns[i][name] viene 'paginas' o 'estado'
|
||||
if (query != null && !query.getOrderList().isEmpty()) {
|
||||
var jpaOrders = new ArrayList<jakarta.persistence.criteria.Order>();
|
||||
for (var ob : query.getOrderList()) {
|
||||
String prop = ob.getExpression().toString();
|
||||
boolean asc = ob.isAscending();
|
||||
if ("paginas".equals(prop)) {
|
||||
var totalPag = cb.sum(cb.coalesce(root.get("paginasColor"), 0),
|
||||
cb.coalesce(root.get("paginasNegro"), 0));
|
||||
jpaOrders.add(asc ? cb.asc(totalPag) : cb.desc(totalPag));
|
||||
} else if ("estado".equals(prop)) {
|
||||
var estadoStr = cb.function("str", String.class, root.get("estado"));
|
||||
jpaOrders.add(asc ? cb.asc(estadoStr) : cb.desc(estadoStr));
|
||||
} else {
|
||||
jpaOrders.add(asc ? cb.asc(root.get(prop)) : cb.desc(root.get(prop)));
|
||||
}
|
||||
}
|
||||
query.orderBy(jpaOrders);
|
||||
}
|
||||
|
||||
return ors.isEmpty() ? cb.conjunction() : cb.or(ors.toArray(new Predicate[0]));
|
||||
};
|
||||
}
|
||||
|
||||
/* ---------- Mappers de filas (puedes tener tantos como vistas) ---------- */
|
||||
|
||||
private Map<String, Object> mapAnonimoRow(Presupuesto p, Locale locale) {
|
||||
int paginas = n(p.getPaginasColor()) + n(p.getPaginasNegro());
|
||||
Map<String, Object> m = new HashMap<>();
|
||||
m.put("id", p.getId());
|
||||
m.put("titulo", p.getTitulo());
|
||||
m.put("tipoEncuadernacion", msg(p.getTipoEncuadernacion().getMessageKey(), locale));
|
||||
m.put("tipoCubierta", msg(p.getTipoCubierta().getMessageKey(), locale));
|
||||
m.put("tipoImpresion", msg(p.getTipoImpresion().getMessageKey(), locale));
|
||||
m.put("tirada", p.getSelectedTirada());
|
||||
m.put("paginas", paginas);
|
||||
m.put("estado", msg(p.getEstado().getMessageKey(), locale));
|
||||
m.put("totalConIva", formatCurrency(p.getTotalConIva(), locale));
|
||||
m.put("pais", p.getPais());
|
||||
m.put("region", p.getRegion());
|
||||
m.put("ciudad", p.getCiudad());
|
||||
m.put("updatedAt", formatDate(p.getUpdatedAt(), locale));
|
||||
m.put("actions",
|
||||
"<div class=\"hstack gap-3 flex-wrap\">" +
|
||||
"<a href=\"javascript:void(0);\" data-id=\"" + p.getId()
|
||||
+ "\" class=\"link-success btn-edit-anonimo fs-15\"><i class=\"ri-edit-2-line\"></i></a>" +
|
||||
"<a href=\"javascript:void(0);\" data-id=\"" + p.getId()
|
||||
+ "\" class=\"link-danger btn-delete-anonimo fs-15\"><i class=\"ri-delete-bin-5-line\"></i></a>"
|
||||
+
|
||||
"</div>");
|
||||
return m;
|
||||
}
|
||||
|
||||
private Map<String, Object> mapNoAnonimoRow(Presupuesto p, Locale locale) {
|
||||
Map<String, Object> m = mapAnonimoRow(p, locale); // base común
|
||||
// añade/remueve campos específicos de “no anónimos”
|
||||
// m.put("cliente", p.getCliente().getNombre()); // ejemplo
|
||||
return m;
|
||||
}
|
||||
|
||||
/* ---------- utilidades ---------- */
|
||||
|
||||
private String msg(String key, Locale locale) {
|
||||
try {
|
||||
return messageSource.getMessage(key, null, locale);
|
||||
} catch (Exception e) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
private int n(Integer v) {
|
||||
return v == null ? 0 : v;
|
||||
}
|
||||
|
||||
private String formatDate(Instant instant, Locale locale) {
|
||||
if (instant == null)
|
||||
return "";
|
||||
ZoneId zone = (locale != null && locale.getCountry() != null && !locale.getCountry().isEmpty())
|
||||
? TimeZone.getTimeZone(locale.toLanguageTag()).toZoneId()
|
||||
: ZoneId.systemDefault();
|
||||
var df = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm").withZone(zone);
|
||||
return df.format(instant);
|
||||
}
|
||||
|
||||
private String formatCurrency(BigDecimal value, Locale locale) {
|
||||
if (value == null)
|
||||
return "";
|
||||
NumberFormat nf = NumberFormat.getCurrencyInstance(locale);
|
||||
return nf.format(value);
|
||||
}
|
||||
|
||||
/* record para agrupar matches */
|
||||
private record EnumMatches(
|
||||
EnumSet<Presupuesto.TipoEncuadernacion> enc,
|
||||
EnumSet<Presupuesto.TipoCubierta> cub,
|
||||
EnumSet<Presupuesto.TipoImpresion> imp,
|
||||
EnumSet<Presupuesto.Estado> est) {
|
||||
}
|
||||
}
|
||||
@ -5,60 +5,24 @@ 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.presupuesto.dto.Presupuesto;
|
||||
import com.imprimelibros.erp.presupuesto.dto.PresupuestoDTAnonimo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Repository
|
||||
public interface PresupuestoRepository extends JpaRepository<Presupuesto, Long>, JpaSpecificationExecutor<Presupuesto> {
|
||||
|
||||
Optional<Presupuesto> findFirstBySessionIdAndOrigenAndEstadoInOrderByUpdatedAtDesc(
|
||||
String sessionId,
|
||||
Presupuesto.Origen origen,
|
||||
Collection<Presupuesto.Estado> estados);
|
||||
Optional<Presupuesto> findFirstBySessionIdAndOrigenAndEstadoInOrderByUpdatedAtDesc(
|
||||
String sessionId,
|
||||
Presupuesto.Origen origen,
|
||||
Collection<Presupuesto.Estado> estados);
|
||||
|
||||
List<Presupuesto> findByOrigenAndEstado(Presupuesto.Origen origen, Presupuesto.Estado estado);
|
||||
List<Presupuesto> findByOrigenAndEstado(Presupuesto.Origen origen, Presupuesto.Estado estado);
|
||||
|
||||
// Incluye borrados (ignora @Where) usando native
|
||||
@Query(value = "SELECT * FROM presupuesto WHERE id = :id", nativeQuery = true)
|
||||
Optional<Presupuesto> findAnyById(@Param("id") Long id);
|
||||
// Incluye borrados (ignora @Where) usando native
|
||||
@Query(value = "SELECT * FROM presupuesto WHERE id = :id", nativeQuery = true)
|
||||
Optional<Presupuesto> findAnyById(@Param("id") Long id);
|
||||
|
||||
Optional<Presupuesto> 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<PresupuestoDTAnonimo> datatableAnonimos(
|
||||
@Param("estado") String estado, // '', 'borrador', 'aceptado', 'modificado'
|
||||
@Param("term") String term,
|
||||
Pageable pageable
|
||||
);
|
||||
Optional<Presupuesto> findTopBySessionIdAndEstadoOrderByCreatedAtDesc(String sessionId, Presupuesto.Estado estado);
|
||||
}
|
||||
|
||||
@ -954,6 +954,8 @@ public class PresupuestoService {
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// Métodos privados
|
||||
// =======================================================================
|
||||
@ -1075,17 +1077,5 @@ public class PresupuestoService {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -92,7 +92,17 @@ public class Presupuesto extends AbstractAuditedEntity implements Cloneable {
|
||||
}
|
||||
|
||||
public enum Estado {
|
||||
borrador, aceptado, modificado
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
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
|
||||
) {}
|
||||
Reference in New Issue
Block a user