mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-02-28 05:39:13 +00:00
Merge branch 'feat/titulos_en_pedidoslist' into 'main'
Feat/titulos en pedidoslist See merge request jjimenez/erp-imprimelibros!47
This commit is contained in:
@ -13,7 +13,7 @@ public interface PedidoDireccionRepository extends JpaRepository<PedidoDireccion
|
|||||||
// Si en tu código sueles trabajar con el objeto:
|
// Si en tu código sueles trabajar con el objeto:
|
||||||
List<PedidoDireccion> findByPedidoLinea(PedidoLinea pedidoLinea);
|
List<PedidoDireccion> findByPedidoLinea(PedidoLinea pedidoLinea);
|
||||||
|
|
||||||
PedidoDireccion findByPedidoIdAndFacturacionTrue(Long pedidoId);
|
PedidoDireccion findFirstByPedidoIdAndFacturacionTrue(Long pedidoId);
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
select distinct d
|
select distinct d
|
||||||
|
|||||||
@ -69,7 +69,7 @@ public class PedidoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PedidoDireccion getPedidoDireccionFacturacionByPedidoId(Long pedidoId) {
|
public PedidoDireccion getPedidoDireccionFacturacionByPedidoId(Long pedidoId) {
|
||||||
return pedidoDireccionRepository.findByPedidoIdAndFacturacionTrue(pedidoId);
|
return pedidoDireccionRepository.findFirstByPedidoIdAndFacturacionTrue(pedidoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@ -206,7 +206,7 @@ public class PedidoService {
|
|||||||
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
|
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
|
||||||
if (pedido != null) {
|
if (pedido != null) {
|
||||||
|
|
||||||
PedidoDireccion direccionPedido = pedidoDireccionRepository.findByPedidoIdAndFacturacionTrue(pedidoId);
|
PedidoDireccion direccionPedido = pedidoDireccionRepository.findFirstByPedidoIdAndFacturacionTrue(pedidoId);
|
||||||
|
|
||||||
if (direccionPedido == null) {
|
if (direccionPedido == null) {
|
||||||
// crear
|
// crear
|
||||||
@ -253,7 +253,7 @@ public class PedidoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PedidoDireccion getDireccionFacturacionPedido(Long pedidoId) {
|
public PedidoDireccion getDireccionFacturacionPedido(Long pedidoId) {
|
||||||
return pedidoDireccionRepository.findByPedidoIdAndFacturacionTrue(pedidoId);
|
return pedidoDireccionRepository.findFirstByPedidoIdAndFacturacionTrue(pedidoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PedidoDireccion> getDireccionesEntregaPedidoLinea(Long pedidoLineaId) {
|
public List<PedidoDireccion> getDireccionesEntregaPedidoLinea(Long pedidoLineaId) {
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.core.io.ByteArrayResource;
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
@ -33,11 +34,14 @@ import com.imprimelibros.erp.users.UserDao;
|
|||||||
|
|
||||||
import jakarta.persistence.criteria.Join;
|
import jakarta.persistence.criteria.Join;
|
||||||
import jakarta.persistence.criteria.JoinType;
|
import jakarta.persistence.criteria.JoinType;
|
||||||
|
import jakarta.persistence.criteria.Subquery;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/pedidos")
|
@RequestMapping("/pedidos")
|
||||||
public class PedidosController {
|
public class PedidosController {
|
||||||
@ -106,6 +110,7 @@ public class PedidosController {
|
|||||||
"id",
|
"id",
|
||||||
"createdBy.fullName",
|
"createdBy.fullName",
|
||||||
"createdAt",
|
"createdAt",
|
||||||
|
"titulos",
|
||||||
"total",
|
"total",
|
||||||
"estado");
|
"estado");
|
||||||
|
|
||||||
@ -113,8 +118,10 @@ public class PedidosController {
|
|||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
base = base.and((root, query, cb) -> cb.equal(root.get("createdBy").get("id"), currentUserId));
|
base = base.and((root, query, cb) -> cb.equal(root.get("createdBy").get("id"), currentUserId));
|
||||||
}
|
}
|
||||||
|
|
||||||
String clientSearch = dt.getColumnSearch("cliente");
|
String clientSearch = dt.getColumnSearch("cliente");
|
||||||
String estadoSearch = dt.getColumnSearch("estado");
|
String estadoSearch = dt.getColumnSearch("estado");
|
||||||
|
String titulosSearch = dt.getColumnSearch("titulos");
|
||||||
|
|
||||||
// 2) Si hay filtro, traducirlo a userIds y añadirlo al Specification
|
// 2) Si hay filtro, traducirlo a userIds y añadirlo al Specification
|
||||||
if (clientSearch != null) {
|
if (clientSearch != null) {
|
||||||
@ -146,11 +153,45 @@ public class PedidosController {
|
|||||||
base = base.and((root, query, cb) -> cb.disjunction());
|
base = base.and((root, query, cb) -> cb.disjunction());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (titulosSearch != null && !titulosSearch.isBlank()) {
|
||||||
|
String like = "%" + titulosSearch.trim().toLowerCase() + "%";
|
||||||
|
base = base.and((root, query, cb) -> {
|
||||||
|
Subquery<Long> minLineaIdSq = query.subquery(Long.class);
|
||||||
|
var plMin = minLineaIdSq.from(PedidoLinea.class);
|
||||||
|
minLineaIdSq.select(cb.min(plMin.get("id")));
|
||||||
|
minLineaIdSq.where(cb.equal(plMin.get("pedido"), root));
|
||||||
|
|
||||||
|
Subquery<String> firstTitleSq = query.subquery(String.class);
|
||||||
|
var plFirst = firstTitleSq.from(PedidoLinea.class);
|
||||||
|
var prFirst = plFirst.join("presupuesto", JoinType.LEFT);
|
||||||
|
firstTitleSq.select(cb.lower(cb.coalesce(prFirst.get("titulo"), "")));
|
||||||
|
firstTitleSq.where(
|
||||||
|
cb.equal(plFirst.get("pedido"), root),
|
||||||
|
cb.equal(plFirst.get("id"), minLineaIdSq));
|
||||||
|
|
||||||
|
return cb.like(firstTitleSq, like);
|
||||||
|
});
|
||||||
|
}
|
||||||
Long total = repoPedido.count(base);
|
Long total = repoPedido.count(base);
|
||||||
|
|
||||||
return DataTable
|
return DataTable
|
||||||
.of(repoPedido, Pedido.class, dt, searchable)
|
.of(repoPedido, Pedido.class, dt, searchable)
|
||||||
.orderable(orderable)
|
.orderable(orderable)
|
||||||
|
.orderable("titulos", (root, query, cb) -> {
|
||||||
|
Subquery<Long> minLineaIdSq = query.subquery(Long.class);
|
||||||
|
var plMin = minLineaIdSq.from(PedidoLinea.class);
|
||||||
|
minLineaIdSq.select(cb.min(plMin.get("id")));
|
||||||
|
minLineaIdSq.where(cb.equal(plMin.get("pedido"), root));
|
||||||
|
|
||||||
|
Subquery<String> firstTitleSq = query.subquery(String.class);
|
||||||
|
var plFirst = firstTitleSq.from(PedidoLinea.class);
|
||||||
|
var prFirst = plFirst.join("presupuesto", JoinType.LEFT);
|
||||||
|
firstTitleSq.select(cb.lower(cb.coalesce(prFirst.get("titulo"), "")));
|
||||||
|
firstTitleSq.where(
|
||||||
|
cb.equal(plFirst.get("pedido"), root),
|
||||||
|
cb.equal(plFirst.get("id"), minLineaIdSq));
|
||||||
|
return firstTitleSq;
|
||||||
|
})
|
||||||
.add("id", Pedido::getId)
|
.add("id", Pedido::getId)
|
||||||
.add("created_at", pedido -> Utils.formatInstant(pedido.getCreatedAt(), locale))
|
.add("created_at", pedido -> Utils.formatInstant(pedido.getCreatedAt(), locale))
|
||||||
.add("cliente", pedido -> {
|
.add("cliente", pedido -> {
|
||||||
@ -166,6 +207,38 @@ public class PedidosController {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.add("titulos", pedido -> {
|
||||||
|
List<PedidoLinea> lineas = repoPedidoLinea.findByPedidoIdOrderByIdAsc(pedido.getId());
|
||||||
|
if (lineas.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Presupuesto> presupuestos = lineas.stream()
|
||||||
|
.map(PedidoLinea::getPresupuesto)
|
||||||
|
.filter(presupuesto -> presupuesto != null)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (presupuestos.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String primerTitulo = presupuestos.get(0).getTitulo();
|
||||||
|
if (primerTitulo == null) {
|
||||||
|
primerTitulo = "";
|
||||||
|
} else {
|
||||||
|
primerTitulo = primerTitulo.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
int extras = presupuestos.size() - 1;
|
||||||
|
if (extras <= 0) {
|
||||||
|
return primerTitulo;
|
||||||
|
}
|
||||||
|
|
||||||
|
String suffix = messageSource.getMessage(
|
||||||
|
"pedido.table.titulos.and-more",
|
||||||
|
new Object[] { extras },
|
||||||
|
locale);
|
||||||
|
return primerTitulo + " " + suffix;
|
||||||
|
})
|
||||||
.add("estado", pedido -> {
|
.add("estado", pedido -> {
|
||||||
List<PedidoLinea> lineas = repoPedidoLinea.findByPedidoId(pedido.getId());
|
List<PedidoLinea> lineas = repoPedidoLinea.findByPedidoId(pedido.getId());
|
||||||
if (lineas.isEmpty()) {
|
if (lineas.isEmpty()) {
|
||||||
|
|||||||
@ -47,6 +47,8 @@ pedido.prueba=Prueba
|
|||||||
pedido.table.id=Num. Pedido
|
pedido.table.id=Num. Pedido
|
||||||
pedido.table.cliente=Cliente
|
pedido.table.cliente=Cliente
|
||||||
pedido.table.fecha=Fecha
|
pedido.table.fecha=Fecha
|
||||||
|
pedido.table.titulos=Títulos
|
||||||
|
pedido.table.titulos.and-more=y {0} más
|
||||||
pedido.table.importe=Importe
|
pedido.table.importe=Importe
|
||||||
pedido.table.estado=Estado
|
pedido.table.estado=Estado
|
||||||
pedido.table.acciones=Acciones
|
pedido.table.acciones=Acciones
|
||||||
|
|||||||
@ -48,6 +48,7 @@ $(() => {
|
|||||||
{ data: 'id', name: 'id', orderable: true },
|
{ data: 'id', name: 'id', orderable: true },
|
||||||
{ data: 'cliente', name: 'createdBy.fullName', orderable: true },
|
{ data: 'cliente', name: 'createdBy.fullName', orderable: true },
|
||||||
{ data: 'created_at', name: 'createdAt', orderable: true },
|
{ data: 'created_at', name: 'createdAt', orderable: true },
|
||||||
|
{ data: 'titulos', name: 'titulos', orderable: true },
|
||||||
{ data: 'total', name: 'total', orderable: true },
|
{ data: 'total', name: 'total', orderable: true },
|
||||||
{ data: 'estado', name: 'estado', orderable: true },
|
{ data: 'estado', name: 'estado', orderable: true },
|
||||||
{ data: 'actions', name: 'actions', orderable: false, searchable: false }
|
{ data: 'actions', name: 'actions', orderable: false, searchable: false }
|
||||||
|
|||||||
@ -47,6 +47,7 @@ $(() => {
|
|||||||
columns: [
|
columns: [
|
||||||
{ data: 'id', name: 'id', orderable: true },
|
{ data: 'id', name: 'id', orderable: true },
|
||||||
{ data: 'created_at', name: 'createdAt', orderable: true },
|
{ data: 'created_at', name: 'createdAt', orderable: true },
|
||||||
|
{ data: 'titulos', name: 'titulos', orderable: true },
|
||||||
{ data: 'total', name: 'total', orderable: true },
|
{ data: 'total', name: 'total', orderable: true },
|
||||||
{ data: 'estado', name: 'estado', orderable: true },
|
{ data: 'estado', name: 'estado', orderable: true },
|
||||||
{ data: 'actions', name: 'actions', orderable: false, searchable: false }
|
{ data: 'actions', name: 'actions', orderable: false, searchable: false }
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.id}">Num. Pedido</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.id}">Num. Pedido</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.fecha}">Fecha</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.fecha}">Fecha</th>
|
||||||
|
<th class="text-start" scope="col" th:text="#{pedido.table.titulos}">Títulos</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.importe}">Importe</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.importe}">Importe</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.estado}">Estado</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.estado}">Estado</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.acciones}">Acciones</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.acciones}">Acciones</th>
|
||||||
@ -44,6 +45,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th><input type="text" class="form-control form-control-sm input-filter" data-col="id" /></th>
|
<th><input type="text" class="form-control form-control-sm input-filter" data-col="id" /></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<th><input type="text" class="form-control form-control-sm input-filter" data-col="titulos" /></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th>
|
<th>
|
||||||
<select class="form-select form-select-sm input-filter" data-col="estado">
|
<select class="form-select form-select-sm input-filter" data-col="estado">
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
<th class="text-start" scope="col" th:text="#{pedido.table.id}">Num. Pedido</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.id}">Num. Pedido</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.cliente}">Cliente</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.cliente}">Cliente</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.fecha}">Fecha</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.fecha}">Fecha</th>
|
||||||
|
<th class="text-start" scope="col" th:text="#{pedido.table.titulos}">Títulos</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.importe}">Importe</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.importe}">Importe</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.estado}">Estado</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.estado}">Estado</th>
|
||||||
<th class="text-start" scope="col" th:text="#{pedido.table.acciones}">Acciones</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.acciones}">Acciones</th>
|
||||||
@ -46,6 +47,7 @@
|
|||||||
<th><input type="text" class="form-control form-control-sm input-filter" data-col="id" /></th>
|
<th><input type="text" class="form-control form-control-sm input-filter" data-col="id" /></th>
|
||||||
<th><input type="text" class="form-control form-control-sm input-filter" data-col="createdBy.fullName" /></th>
|
<th><input type="text" class="form-control form-control-sm input-filter" data-col="createdBy.fullName" /></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<th><input type="text" class="form-control form-control-sm input-filter" data-col="titulos" /></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th>
|
<th>
|
||||||
<select class="form-select form-select-sm input-filter" data-col="estado">
|
<select class="form-select form-select-sm input-filter" data-col="estado">
|
||||||
|
|||||||
Reference in New Issue
Block a user