trabajando en el datatables de los presupuestos

This commit is contained in:
2025-10-06 15:32:50 +02:00
parent b2f3ef042e
commit 1e8f9cafb3
27 changed files with 513 additions and 36 deletions

View File

@ -13,7 +13,7 @@ import com.imprimelibros.erp.users.User;
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditedSoftDeleteEntity {
public abstract class AbstractAuditedEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

View File

@ -16,7 +16,6 @@ import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;

View File

@ -48,6 +48,6 @@ public class HomeController {
Map<String, String> translations = Map.of();
model.addAttribute("languageBundle", translations);
}
return "imprimelibros/home";
return "imprimelibros/home/home";
}
}

View File

@ -9,19 +9,15 @@ import com.imprimelibros.erp.presupuesto.validation.PresupuestoValidationGroups;
import com.imprimelibros.erp.presupuesto.validation.Tamanio;
import com.imprimelibros.erp.common.HtmlStripConverter;
import com.imprimelibros.erp.common.jpa.AbstractAuditedSoftDeleteEntity;
import com.imprimelibros.erp.common.jpa.AbstractAuditedEntity;
import jakarta.persistence.*;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.math.BigDecimal;
import java.time.Instant;
import com.imprimelibros.erp.users.User;
@ -38,7 +34,7 @@ import com.imprimelibros.erp.users.User;
})
@SQLDelete(sql = "UPDATE presupuesto SET deleted = 1, deleted_at = NOW(3) WHERE id = ?")
@SQLRestriction("deleted = 0")
public class Presupuesto extends AbstractAuditedSoftDeleteEntity implements Cloneable {
public class Presupuesto extends AbstractAuditedEntity implements Cloneable {
public enum TipoEncuadernacion {
fresado("presupuesto.fresado"),

View File

@ -3,18 +3,23 @@ package com.imprimelibros.erp.presupuesto;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
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.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
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.PostMapping;
@ -23,7 +28,15 @@ 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.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;
@ -46,9 +59,14 @@ public class PresupuestoController {
protected MessageSource messageSource;
private final ObjectMapper objectMapper;
private final TranslationService translationService;
private final PresupuestoRepository repo;
public PresupuestoController(ObjectMapper objectMapper) {
public PresupuestoController(ObjectMapper objectMapper, TranslationService translationService,
PresupuestoRepository repo) {
this.objectMapper = objectMapper;
this.translationService = translationService;
this.repo = repo;
}
@PostMapping("/public/validar/datos-generales")
@ -407,4 +425,68 @@ public class PresupuestoController {
return ResponseEntity.ok(resumen);
}
// =============================================
// MÉTODOS PARA USUARIOS AUTENTICADOS
// =============================================
@GetMapping
public String getPresupuestoView(Model model, Authentication authentication, Locale locale) {
List<String> keys = List.of();
Map<String, String> translations = translationService.getTranslations(locale, keys);
model.addAttribute("languageBundle", translations);
return "imprimelibros/presupuestos/presupuesto-list";
}
@GetMapping(value = "/datatable/{tipo}", produces = "application/json")
@ResponseBody
public DataTablesResponse<Map<String, Object>> datatable(@RequestParam("tipo") String tipo,
HttpServletRequest request, Authentication authentication,
Locale locale) {
DataTablesRequest dt = DataTablesParser.from(request);
List<String> searchable = List.of(
"id",
"titulo",
"cliente",
"tipoEncuadernacion",
"tipoCubierta",
"tipoImpresion",
"tirada",
"paginas",
"estado", "total", "pais", "region", "ciudad", "updatedAt");
List<String> orderable = List.of(/*
* "id",
* "tipoEncuadernacion",
* "tipoCubierta",
* "tiradaMin",
* "tiradaMax",
* "margenMin",
* "margenMax"
*/);
Specification<MargenPresupuesto> base = (root, query, cb) -> cb.conjunction();
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 "<div class=\"hstack gap-3 flex-wrap\">\n" +
" <a href=\"javascript:void(0);\" data-id=\"" + presupuesto.getId()
+ "\" class=\"link-success btn-edit-" + tipo
+ " fs-15\"><i class=\"ri-edit-2-line\"></i></a>\n"
+ " <a href=\"javascript:void(0);\" data-id=\"" + presupuesto.getId()
+ "\" class=\"link-danger btn-delete-" + tipo
+ " fs-15\"><i class=\"ri-delete-bin-5-line\"></i></a>\n"
+ " </div>";
})
.where(base)
.toJson(total);
}
}

View File

@ -1,14 +1,17 @@
package com.imprimelibros.erp.presupuesto;
import org.springframework.data.jpa.repository.JpaRepository;
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 com.imprimelibros.erp.configuracion.margenes_presupuestos.MargenPresupuesto;
import java.util.*;
@Repository
public interface PresupuestoRepository extends JpaRepository<Presupuesto, Long> {
public interface PresupuestoRepository extends JpaRepository<Presupuesto, Long>, JpaSpecificationExecutor<MargenPresupuesto> {
Optional<Presupuesto> findFirstBySessionIdAndOrigenAndEstadoInOrderByUpdatedAtDesc(
String sessionId,