mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 00:48:49 +00:00
317 lines
19 KiB
Java
317 lines
19 KiB
Java
package com.imprimelibros.erp.common;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.math.RoundingMode;
|
|
import java.security.Principal;
|
|
import java.text.NumberFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
import java.util.function.BiFunction;
|
|
|
|
import org.springframework.context.MessageSource;
|
|
import org.springframework.security.core.Authentication;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.imprimelibros.erp.datatables.DataTablesRequest;
|
|
import com.imprimelibros.erp.presupuesto.classes.PresupuestoFormatter;
|
|
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
|
import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionMatrices;
|
|
import com.imprimelibros.erp.presupuesto.marcapaginas.Marcapaginas;
|
|
import com.imprimelibros.erp.users.User;
|
|
import com.imprimelibros.erp.users.UserDetailsImpl;
|
|
|
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
|
import jakarta.persistence.criteria.Path;
|
|
import jakarta.persistence.criteria.Predicate;
|
|
import java.util.function.Function;
|
|
|
|
@Component
|
|
public class Utils {
|
|
|
|
private final PresupuestoFormatter presupuestoFormatter;
|
|
private final MessageSource messageSource;
|
|
|
|
public Utils(PresupuestoFormatter presupuestoFormatter,
|
|
MessageSource messageSource) {
|
|
this.presupuestoFormatter = presupuestoFormatter;
|
|
this.messageSource = messageSource;
|
|
}
|
|
|
|
public static Long currentUserId(Principal principal) {
|
|
|
|
if (principal == null) {
|
|
throw new IllegalStateException("Usuario no autenticado");
|
|
}
|
|
|
|
if (principal instanceof Authentication auth) {
|
|
Object principalObj = auth.getPrincipal();
|
|
|
|
if (principalObj instanceof UserDetailsImpl udi) {
|
|
return udi.getId();
|
|
} else if (principalObj instanceof User u && u.getId() != null) {
|
|
return u.getId();
|
|
}
|
|
}
|
|
throw new IllegalStateException("No se pudo obtener el ID del usuario actual");
|
|
}
|
|
|
|
public static String formatCurrency(BigDecimal amount, Locale locale) {
|
|
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);
|
|
return currencyFormatter.format(amount);
|
|
}
|
|
|
|
public static String formatCurrency(Double amount, Locale locale) {
|
|
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);
|
|
return currencyFormatter.format(amount);
|
|
}
|
|
|
|
public static String formatNumber(BigDecimal amount, Locale locale) {
|
|
NumberFormat numberFormatter = NumberFormat.getNumberInstance(locale);
|
|
return numberFormatter.format(amount);
|
|
}
|
|
|
|
public static String formatNumber(Double amount, Locale locale) {
|
|
NumberFormat numberFormatter = NumberFormat.getNumberInstance(locale);
|
|
return numberFormatter.format(amount);
|
|
}
|
|
|
|
public static Optional<BiFunction<Path<BigDecimal>, CriteriaBuilder, Predicate>> parseNumericFilter(
|
|
DataTablesRequest dt, String colName, Locale locale) {
|
|
String raw = dt.getColumnSearch(colName); // usa el "name" del DataTable (snake_case)
|
|
if (raw == null || raw.isBlank())
|
|
return Optional.empty();
|
|
|
|
String s = raw.trim();
|
|
// normaliza número con coma o punto
|
|
Function<String, BigDecimal> toBig = x -> {
|
|
String t = x.replace(".", "").replace(",", "."); // 1.234,56 -> 1234.56
|
|
return new BigDecimal(t);
|
|
};
|
|
|
|
try {
|
|
if (s.matches("(?i)^>=?\\s*[-\\d.,]+$")) {
|
|
BigDecimal v = toBig.apply(s.replace(">=", "").replace(">", "").trim());
|
|
return Optional.of((path, cb) -> cb.greaterThanOrEqualTo(path, v));
|
|
}
|
|
if (s.matches("(?i)^<=?\\s*[-\\d.,]+$")) {
|
|
BigDecimal v = toBig.apply(s.replace("<=", "").replace("<", "").trim());
|
|
return Optional.of((path, cb) -> cb.lessThanOrEqualTo(path, v));
|
|
}
|
|
if (s.contains("-")) { // rango "a-b"
|
|
String[] p = s.split("-");
|
|
if (p.length == 2) {
|
|
BigDecimal a = toBig.apply(p[0].trim());
|
|
BigDecimal b = toBig.apply(p[1].trim());
|
|
BigDecimal min = a.min(b), max = a.max(b);
|
|
return Optional.of((path, cb) -> cb.between(path, min, max));
|
|
}
|
|
}
|
|
// exacto/like numérico
|
|
BigDecimal v = toBig.apply(s);
|
|
return Optional.of((path, cb) -> cb.equal(path, v));
|
|
} catch (Exception ignore) {
|
|
return Optional.empty();
|
|
}
|
|
}
|
|
|
|
public Map<String, Object> getTextoPresupuesto(Presupuesto presupuesto, Locale locale) {
|
|
|
|
Map<String, Object> resumen = new HashMap<>();
|
|
|
|
resumen.put("titulo", presupuesto.getTitulo());
|
|
|
|
resumen.put("imagen",
|
|
"/assets/images/imprimelibros/presupuestador/" + presupuesto.getTipoEncuadernacion()
|
|
+ ".png");
|
|
resumen.put("imagen_alt",
|
|
messageSource.getMessage("presupuesto." + presupuesto.getTipoEncuadernacion(), null,
|
|
locale));
|
|
|
|
resumen.put("presupuestoId", presupuesto.getId());
|
|
|
|
ObjectMapper mapper = new ObjectMapper();
|
|
List<Map<String, Object>> servicios = new ArrayList<>();
|
|
if (presupuesto.getServiciosJson() != null && !presupuesto.getServiciosJson().isBlank())
|
|
try {
|
|
servicios = mapper.readValue(presupuesto.getServiciosJson(), new TypeReference<>() {
|
|
});
|
|
} catch (JsonProcessingException e) {
|
|
// Manejar la excepción
|
|
}
|
|
|
|
boolean hayDepositoLegal = servicios != null && servicios.stream()
|
|
.map(m -> java.util.Objects.toString(m.get("id"), ""))
|
|
.map(String::trim)
|
|
.anyMatch("deposito-legal"::equals);
|
|
|
|
List<HashMap<String, Object>> lineas = new ArrayList<>();
|
|
HashMap<String, Object> linea = new HashMap<>();
|
|
Double precio_unitario = 0.0;
|
|
Double precio_total = 0.0;
|
|
BigDecimal total = BigDecimal.ZERO;
|
|
linea.put("descripcion", presupuestoFormatter.resumen(presupuesto, servicios, locale));
|
|
linea.put("cantidad", presupuesto.getSelectedTirada() != null ? presupuesto.getSelectedTirada() : 0);
|
|
precio_unitario = (presupuesto.getPrecioUnitario() != null
|
|
? presupuesto.getPrecioUnitario().doubleValue()
|
|
: 0.0);
|
|
precio_total = (presupuesto.getPrecioTotalTirada() != null
|
|
? presupuesto.getPrecioTotalTirada().doubleValue()
|
|
: 0.0);
|
|
linea.put("precio_unitario", precio_unitario);
|
|
linea.put("precio_total", BigDecimal.valueOf(precio_total).setScale(2, RoundingMode.HALF_UP));
|
|
total = total.add(BigDecimal.valueOf(precio_total));
|
|
lineas.add(linea);
|
|
|
|
if (hayDepositoLegal) {
|
|
linea = new HashMap<>();
|
|
linea.put("descripcion",
|
|
messageSource.getMessage("pdf.ejemplares-deposito-legal", new Object[] { 4 },
|
|
locale));
|
|
lineas.add(linea);
|
|
}
|
|
|
|
String serviciosExtras = "";
|
|
if (servicios != null) {
|
|
for (Map<String, Object> servicio : servicios) {
|
|
if ("deposito-legal".equals(servicio.get("id")) ||
|
|
"service-isbn".equals(servicio.get("id"))) {
|
|
serviciosExtras += messageSource.getMessage(
|
|
"presupuesto.extras-" + servicio.get("id"), null, locale)
|
|
+ ", ";
|
|
} else {
|
|
serviciosExtras += messageSource.getMessage(
|
|
"presupuesto.extras-" + servicio.get("id"), null, locale)
|
|
.toLowerCase() + ", ";
|
|
}
|
|
}
|
|
if (!serviciosExtras.isEmpty()) {
|
|
serviciosExtras = serviciosExtras.substring(0, serviciosExtras.length() - 2);
|
|
;
|
|
}
|
|
if (servicios.stream().anyMatch(service -> "marcapaginas".equals(service.get("id")))) {
|
|
ObjectMapper mapperServicio = new ObjectMapper();
|
|
Object raw = presupuesto.getDatosMarcapaginasJson();
|
|
Map<String, Object> datosMarcapaginas;
|
|
String descripcion = "";
|
|
try {
|
|
if (raw instanceof String s) {
|
|
datosMarcapaginas = mapperServicio.readValue(s,
|
|
new TypeReference<Map<String, Object>>() {
|
|
});
|
|
} else if (raw instanceof Map<?, ?> m) {
|
|
datosMarcapaginas = mapperServicio.convertValue(m,
|
|
new TypeReference<Map<String, Object>>() {
|
|
});
|
|
} else {
|
|
throw new IllegalArgumentException(
|
|
"Tipo no soportado para datosMarcapaginas: "
|
|
+ raw);
|
|
}
|
|
} catch (JsonProcessingException e) {
|
|
throw new RuntimeException("Error parsing datosMarcapaginasJson", e);
|
|
}
|
|
descripcion += "<br/><ul><li>";
|
|
descripcion += Marcapaginas.Tamanios
|
|
.valueOf(datosMarcapaginas.get("tamanio").toString()).getLabel()
|
|
+ ", ";
|
|
descripcion += Marcapaginas.Caras_Impresion
|
|
.valueOf(datosMarcapaginas.get("carasImpresion").toString())
|
|
.getMessageKey() + ", ";
|
|
descripcion += messageSource
|
|
.getMessage(Marcapaginas.Papeles
|
|
.valueOf(datosMarcapaginas.get("papel")
|
|
.toString())
|
|
.getMessageKey(), null, locale)
|
|
+ " - " +
|
|
datosMarcapaginas.get("gramaje").toString() + " gr, ";
|
|
descripcion += messageSource.getMessage(
|
|
Marcapaginas.Acabado.valueOf(
|
|
datosMarcapaginas.get("acabado").toString())
|
|
.getMessageKey(),
|
|
null, locale);
|
|
descripcion += "</li></ul>";
|
|
resumen.put("datosMarcapaginas", descripcion);
|
|
}
|
|
if (servicios.stream().anyMatch(service -> "maquetacion".equals(service.get("id")))) {
|
|
ObjectMapper mapperServicio = new ObjectMapper();
|
|
Object raw = presupuesto.getDatosMaquetacionJson();
|
|
Map<String, Object> datosMaquetacion;
|
|
String descripcion = "";
|
|
try {
|
|
if (raw instanceof String s) {
|
|
datosMaquetacion = mapperServicio.readValue(s,
|
|
new TypeReference<Map<String, Object>>() {
|
|
});
|
|
} else if (raw instanceof Map<?, ?> m) {
|
|
datosMaquetacion = mapperServicio.convertValue(m,
|
|
new TypeReference<Map<String, Object>>() {
|
|
});
|
|
} else {
|
|
throw new IllegalArgumentException(
|
|
"Tipo no soportado para datosMaquetacion: "
|
|
+ raw);
|
|
}
|
|
} catch (JsonProcessingException e) {
|
|
throw new RuntimeException("Error parsing datosMaquetacionJson", e);
|
|
}
|
|
descripcion += "<br/><ul><li>";
|
|
descripcion += (datosMaquetacion.get("num_caracteres") + " "
|
|
+ messageSource.getMessage("presupuesto.maquetacion.caracteres",
|
|
null, locale))
|
|
+ ", ";
|
|
descripcion += MaquetacionMatrices.Formato
|
|
.valueOf(datosMaquetacion.get("formato_maquetacion").toString())
|
|
.getLabel() + ", ";
|
|
descripcion += messageSource.getMessage(MaquetacionMatrices.FontSize
|
|
.valueOf(datosMaquetacion.get("cuerpo_texto").toString())
|
|
.getMessageKey(), null, locale)
|
|
+ ", ";
|
|
descripcion += messageSource.getMessage("presupuesto.maquetacion.num-columnas",
|
|
null, locale) + ": "
|
|
+ datosMaquetacion.get("num_columnas").toString() + ", ";
|
|
descripcion += messageSource.getMessage("presupuesto.maquetacion.num-tablas",
|
|
null, locale) + ": "
|
|
+ datosMaquetacion.get("num_tablas").toString() + ", ";
|
|
descripcion += messageSource.getMessage("presupuesto.maquetacion.num-fotos",
|
|
null, locale) + ": "
|
|
+ datosMaquetacion.get("num_fotos").toString();
|
|
if ((boolean) datosMaquetacion.get("correccion_ortotipografica")) {
|
|
descripcion += ", " + messageSource
|
|
.getMessage("presupuesto.maquetacion.correccion-ortotipografica",
|
|
null, locale);
|
|
}
|
|
if ((boolean) datosMaquetacion.get("texto_mecanografiado")) {
|
|
descripcion += ", " + messageSource.getMessage(
|
|
"presupuesto.maquetacion.texto-mecanografiado",
|
|
null, locale);
|
|
}
|
|
if ((boolean) datosMaquetacion.get("disenio_portada")) {
|
|
descripcion += ", "
|
|
+ messageSource.getMessage(
|
|
"presupuesto.maquetacion.diseno-portada",
|
|
null, locale);
|
|
}
|
|
if ((boolean) datosMaquetacion.get("epub")) {
|
|
descripcion += ", " + messageSource.getMessage(
|
|
"presupuesto.maquetacion.epub", null, locale);
|
|
}
|
|
descripcion += "</li></ul>";
|
|
resumen.put("datosMaquetacion", descripcion);
|
|
}
|
|
}
|
|
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(locale);
|
|
String formattedString = currencyFormat.format(total.setScale(2, RoundingMode.HALF_UP).doubleValue());
|
|
resumen.put("total", formattedString);
|
|
resumen.put("lineas", lineas);
|
|
resumen.put("servicios", serviciosExtras);
|
|
return resumen;
|
|
}
|
|
}
|