mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-12 16:38:48 +00:00
133 lines
6.1 KiB
Java
133 lines
6.1 KiB
Java
package com.imprimelibros.erp.presupuesto;
|
|
|
|
import com.imprimelibros.erp.common.Utils;
|
|
import com.imprimelibros.erp.datatables.*;
|
|
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
|
|
|
import jakarta.persistence.criteria.Expression;
|
|
|
|
import org.springframework.context.MessageSource;
|
|
import org.springframework.data.jpa.domain.Specification;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import java.security.Principal;
|
|
import java.time.*;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.*;
|
|
|
|
@Service
|
|
public class PresupuestoDatatableService {
|
|
|
|
private final MessageSource messageSource;
|
|
private final PresupuestoRepository repo;
|
|
|
|
public PresupuestoDatatableService(MessageSource messageSource, PresupuestoRepository repo) {
|
|
this.messageSource = messageSource;
|
|
this.repo = repo;
|
|
}
|
|
|
|
@Transactional(readOnly = true)
|
|
public DataTablesResponse<Map<String, Object>> datatablePublicos(DataTablesRequest dt, Locale locale,
|
|
Principal principal) {
|
|
return commonDataTable(dt, locale, "publico", true, principal);
|
|
}
|
|
|
|
@Transactional(readOnly = true)
|
|
public DataTablesResponse<Map<String, Object>> datatablePrivados(DataTablesRequest dt, Locale locale,
|
|
Principal principal) {
|
|
return commonDataTable(dt, locale, "privado", false, principal);
|
|
}
|
|
|
|
private DataTablesResponse<Map<String, Object>> commonDataTable(DataTablesRequest dt, Locale locale, String origen,
|
|
boolean publico, Principal principal) {
|
|
|
|
Specification<Presupuesto> base = Specification.allOf(
|
|
(root, query, cb) -> cb.equal(root.get("origen"), Presupuesto.Origen.valueOf(origen)));
|
|
|
|
Boolean isAdmin = Utils.isCurrentUserAdmin();
|
|
if (!isAdmin) {
|
|
base = base.and((root, query, cb) -> cb.equal(root.get("user").get("id"), Utils.currentUserId(principal)));
|
|
}
|
|
|
|
Long count = repo.count(base);
|
|
|
|
List<String> orderable = List.of(
|
|
"id", "titulo", "user.fullName", "tipoEncuadernacion", "tipoCubierta", "tipoImpresion",
|
|
"selectedTirada", "estado", "totalConIva", "paginas", "pais", "region", "ciudad", "updatedAt");
|
|
|
|
return DataTable.of(repo, Presupuesto.class, dt,
|
|
List.of("")) // búsqueda global solo por campos simples
|
|
.orderable(orderable)
|
|
.where((root, query, cb) -> cb.equal(root.get("origen"), Presupuesto.Origen.valueOf(origen)))
|
|
.onlyAddedColumns()
|
|
.add("id", Presupuesto::getId)
|
|
.add("titulo", Presupuesto::getTitulo)
|
|
.add("tipoEncuadernacion", p -> msg(p.getTipoEncuadernacion().getMessageKey(), locale))
|
|
.add("tipoCubierta", p -> msg(p.getTipoCubierta().getMessageKey(), locale))
|
|
.add("tipoImpresion", p -> msg(p.getTipoImpresion().getMessageKey(), locale))
|
|
.add("selectedTirada", Presupuesto::getSelectedTirada)
|
|
.add("paginas", p -> n(p.getPaginasColor()) + n(p.getPaginasNegro()))
|
|
.filter("paginas", (root, q, cb, value) -> {
|
|
Expression<Integer> sum = cb.sum(
|
|
cb.coalesce(root.get("paginasColor"), cb.literal(0)),
|
|
cb.coalesce(root.get("paginasNegro"), cb.literal(0)));
|
|
Expression<String> asStr = cb.function("CONCAT", String.class, cb.literal(""), sum);
|
|
return cb.like(asStr, "%" + value.trim() + "%");
|
|
})
|
|
.orderable("paginas", (root, q, cb) -> cb.sum(
|
|
cb.coalesce(root.get("paginasColor"), cb.literal(0)),
|
|
cb.coalesce(root.get("paginasNegro"), cb.literal(0))))
|
|
|
|
.add("estado", p -> msg(p.getEstado().getMessageKey(), locale))
|
|
.add("totalConIva", p -> Utils.formatCurrency(p.getTotalConIva(), locale))
|
|
.addIf(publico, "pais", Presupuesto::getPais)
|
|
.addIf(publico, "region", Presupuesto::getRegion)
|
|
.addIf(publico, "ciudad", Presupuesto::getCiudad)
|
|
.add("updatedAt", p -> formatDate(p.getUpdatedAt(), locale))
|
|
.addIf(!publico, "user", p -> p.getUser() != null ? p.getUser().getFullName() : "")
|
|
.add("actions", this::generarBotones)
|
|
.where(base)
|
|
.toJson(count);
|
|
}
|
|
|
|
/* ---------- helpers ---------- */
|
|
|
|
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 generarBotones(Presupuesto p) {
|
|
boolean borrador = p.getEstado() == Presupuesto.Estado.borrador;
|
|
String id = String.valueOf(p.getId());
|
|
String editBtn = "<a href=\"javascript:void(0);\" data-id=\"" + id + "\" class=\"link-success btn-edit-" +
|
|
(p.getOrigen().equals(Presupuesto.Origen.publico) ? "anonimo" : "privado") + " fs-15\"><i class=\"ri-" +
|
|
(p.getOrigen().equals(Presupuesto.Origen.publico) || p.getEstado() == Presupuesto.Estado.aceptado ? "eye" : "pencil") + "-line\"></i></a>";
|
|
|
|
String deleteBtn = borrador ? "<a href=\"javascript:void(0);\" data-id=\"" + id
|
|
+ "\" class=\"link-danger btn-delete-"
|
|
+ (p.getOrigen().equals(Presupuesto.Origen.publico) ? "anonimo" : "privado")
|
|
+ " fs-15\"><i class=\"ri-delete-bin-5-line\"></i></a>" : "";
|
|
|
|
return "<div class=\"hstack gap-3 flex-wrap\">" + editBtn + deleteBtn + "</div>";
|
|
}
|
|
}
|