mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 00:48:49 +00:00
listado de pedidos admin hecho
This commit is contained in:
5604
logs/erp.log
5604
logs/erp.log
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,9 @@ import java.math.BigDecimal;
|
|||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -12,6 +14,7 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
@ -357,4 +360,54 @@ public class Utils {
|
|||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm", locale);
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm", locale);
|
||||||
return dateTime.format(formatter);
|
return dateTime.format(formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String formatInstant(Instant instant, Locale locale) {
|
||||||
|
if (instant == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
ZoneId zone = zoneIdForLocale(locale);
|
||||||
|
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter
|
||||||
|
.ofPattern("dd/MM/yyyy HH:mm", locale)
|
||||||
|
.withZone(zone);
|
||||||
|
|
||||||
|
return formatter.format(instant);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* Metodos auxiliares
|
||||||
|
*/
|
||||||
|
private static ZoneId zoneIdForLocale(Locale locale) {
|
||||||
|
if (locale == null || locale.getCountry().isEmpty()) {
|
||||||
|
return ZoneId.of("UTC");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buscar timezones cuyo ID termine con el country code
|
||||||
|
// Ej: ES -> Europe/Madrid
|
||||||
|
String country = locale.getCountry();
|
||||||
|
|
||||||
|
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
|
||||||
|
for (String id : zoneIds) {
|
||||||
|
// TimeZone# getID() no funciona por país, pero sí el prefijo + país
|
||||||
|
if (id.endsWith("/" + country) || id.contains("/" + country)) {
|
||||||
|
return ZoneId.of(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback por regiones comunes (manual pero muy útil)
|
||||||
|
Map<String, String> fallback = Map.of(
|
||||||
|
"ES", "Europe/Madrid",
|
||||||
|
"MX", "America/Mexico_City",
|
||||||
|
"AR", "America/Argentina/Buenos_Aires",
|
||||||
|
"US", "America/New_York",
|
||||||
|
"GB", "Europe/London",
|
||||||
|
"FR", "Europe/Paris");
|
||||||
|
|
||||||
|
if (fallback.containsKey(country)) {
|
||||||
|
return ZoneId.of(fallback.get(country));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZoneId.systemDefault(); // último fallback
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
package com.imprimelibros.erp.pedidos;
|
package com.imprimelibros.erp.pedidos;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.imprimelibros.erp.common.jpa.AbstractAuditedEntity;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "pedidos")
|
@Table(name = "pedidos")
|
||||||
public class Pedido {
|
public class Pedido extends AbstractAuditedEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@ -37,27 +41,8 @@ public class Pedido {
|
|||||||
@Column(name = "proveedor_ref", length = 100)
|
@Column(name = "proveedor_ref", length = 100)
|
||||||
private String proveedorRef;
|
private String proveedorRef;
|
||||||
|
|
||||||
// Auditoría básica (coincidiendo con las columnas que se ven en la captura)
|
@OneToMany(mappedBy = "pedido", cascade = CascadeType.ALL, orphanRemoval = false)
|
||||||
@Column(name = "created_by")
|
private List<PedidoLinea> lineas = new ArrayList<>();
|
||||||
private Long createdBy;
|
|
||||||
|
|
||||||
@Column(name = "updated_by")
|
|
||||||
private Long updatedBy;
|
|
||||||
|
|
||||||
@Column(name = "deleted_by")
|
|
||||||
private Long deletedBy;
|
|
||||||
|
|
||||||
@Column(name = "deleted", nullable = false)
|
|
||||||
private boolean deleted = false;
|
|
||||||
|
|
||||||
@Column(name = "created_at", updatable = false)
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
|
|
||||||
@Column(name = "updated_at")
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
|
|
||||||
@Column(name = "deleted_at")
|
|
||||||
private LocalDateTime deletedAt;
|
|
||||||
|
|
||||||
// --- Getters y setters ---
|
// --- Getters y setters ---
|
||||||
|
|
||||||
@ -132,60 +117,4 @@ public class Pedido {
|
|||||||
public void setProveedorRef(String proveedorRef) {
|
public void setProveedorRef(String proveedorRef) {
|
||||||
this.proveedorRef = proveedorRef;
|
this.proveedorRef = proveedorRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getCreatedBy() {
|
|
||||||
return createdBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedBy(Long createdBy) {
|
|
||||||
this.createdBy = createdBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getUpdatedBy() {
|
|
||||||
return updatedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdatedBy(Long updatedBy) {
|
|
||||||
this.updatedBy = updatedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getDeletedBy() {
|
|
||||||
return deletedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeletedBy(Long deletedBy) {
|
|
||||||
this.deletedBy = deletedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDeleted() {
|
|
||||||
return deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeleted(boolean deleted) {
|
|
||||||
this.deleted = deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getCreatedAt() {
|
|
||||||
return createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedAt(LocalDateTime createdAt) {
|
|
||||||
this.createdAt = createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getUpdatedAt() {
|
|
||||||
return updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
|
||||||
this.updatedAt = updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getDeletedAt() {
|
|
||||||
return deletedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeletedAt(LocalDateTime deletedAt) {
|
|
||||||
this.deletedAt = deletedAt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,21 +10,27 @@ import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
|||||||
public class PedidoLinea {
|
public class PedidoLinea {
|
||||||
|
|
||||||
public enum Estado {
|
public enum Estado {
|
||||||
aprobado("pedido.estado.aprobado"),
|
aprobado("pedido.estado.aprobado", 1),
|
||||||
maquetacion("pedido.estado.maquetacion"),
|
maquetacion("pedido.estado.maquetacion", 2),
|
||||||
haciendo_ferro("pedido.estado.haciendo_ferro"),
|
haciendo_ferro("pedido.estado.haciendo_ferro", 3),
|
||||||
produccion("pedido.estado.produccion"),
|
produccion("pedido.estado.produccion", 4),
|
||||||
cancelado("pedido.estado.cancelado");
|
cancelado("pedido.estado.cancelado", 5);
|
||||||
|
|
||||||
private final String messageKey;
|
private final String messageKey;
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
Estado(String messageKey) {
|
Estado(String messageKey, int priority) {
|
||||||
this.messageKey = messageKey;
|
this.messageKey = messageKey;
|
||||||
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessageKey() {
|
public String getMessageKey() {
|
||||||
return messageKey;
|
return messageKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.imprimelibros.erp.pedidos;
|
package com.imprimelibros.erp.pedidos;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -11,6 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import com.imprimelibros.erp.direcciones.Direccion;
|
import com.imprimelibros.erp.direcciones.Direccion;
|
||||||
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
||||||
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||||
|
import com.imprimelibros.erp.users.UserService;
|
||||||
import com.imprimelibros.erp.direcciones.DireccionService;
|
import com.imprimelibros.erp.direcciones.DireccionService;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -21,15 +23,17 @@ public class PedidoService {
|
|||||||
private final PresupuestoRepository presupuestoRepository;
|
private final PresupuestoRepository presupuestoRepository;
|
||||||
private final PedidoDireccionRepository pedidoDireccionRepository;
|
private final PedidoDireccionRepository pedidoDireccionRepository;
|
||||||
private final DireccionService direccionService;
|
private final DireccionService direccionService;
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
public PedidoService(PedidoRepository pedidoRepository, PedidoLineaRepository pedidoLineaRepository,
|
public PedidoService(PedidoRepository pedidoRepository, PedidoLineaRepository pedidoLineaRepository,
|
||||||
PresupuestoRepository presupuestoRepository, PedidoDireccionRepository pedidoDireccionRepository,
|
PresupuestoRepository presupuestoRepository, PedidoDireccionRepository pedidoDireccionRepository,
|
||||||
DireccionService direccionService) {
|
DireccionService direccionService, UserService userService) {
|
||||||
this.pedidoRepository = pedidoRepository;
|
this.pedidoRepository = pedidoRepository;
|
||||||
this.pedidoLineaRepository = pedidoLineaRepository;
|
this.pedidoLineaRepository = pedidoLineaRepository;
|
||||||
this.presupuestoRepository = presupuestoRepository;
|
this.presupuestoRepository = presupuestoRepository;
|
||||||
this.pedidoDireccionRepository = pedidoDireccionRepository;
|
this.pedidoDireccionRepository = pedidoDireccionRepository;
|
||||||
this.direccionService = direccionService;
|
this.direccionService = direccionService;
|
||||||
|
this.userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDescuentoFidelizacion() {
|
public int getDescuentoFidelizacion() {
|
||||||
@ -84,11 +88,11 @@ public class PedidoService {
|
|||||||
pedido.setProveedorRef(proveedorRef);
|
pedido.setProveedorRef(proveedorRef);
|
||||||
|
|
||||||
// Auditoría mínima
|
// Auditoría mínima
|
||||||
pedido.setCreatedBy(userId);
|
pedido.setCreatedBy(userService.findById(userId));
|
||||||
pedido.setCreatedAt(LocalDateTime.now());
|
pedido.setCreatedAt(Instant.now());
|
||||||
pedido.setDeleted(false);
|
pedido.setDeleted(false);
|
||||||
pedido.setUpdatedAt(LocalDateTime.now());
|
pedido.setUpdatedAt(Instant.now());
|
||||||
pedido.setUpdatedBy(userId);
|
pedido.setUpdatedBy(userService.findById(userId));
|
||||||
|
|
||||||
// Guardamos el pedido
|
// Guardamos el pedido
|
||||||
Pedido saved = pedidoRepository.save(pedido);
|
Pedido saved = pedidoRepository.save(pedido);
|
||||||
|
|||||||
@ -4,10 +4,10 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
import java.util.Comparator;
|
||||||
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.Optional;
|
|
||||||
|
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
@ -18,16 +18,12 @@ import com.imprimelibros.erp.datatables.DataTable;
|
|||||||
import com.imprimelibros.erp.datatables.DataTablesParser;
|
import com.imprimelibros.erp.datatables.DataTablesParser;
|
||||||
import com.imprimelibros.erp.datatables.DataTablesRequest;
|
import com.imprimelibros.erp.datatables.DataTablesRequest;
|
||||||
import com.imprimelibros.erp.datatables.DataTablesResponse;
|
import com.imprimelibros.erp.datatables.DataTablesResponse;
|
||||||
import com.imprimelibros.erp.payments.model.Payment;
|
|
||||||
import com.imprimelibros.erp.payments.model.PaymentTransaction;
|
|
||||||
import com.imprimelibros.erp.payments.model.PaymentTransactionStatus;
|
|
||||||
import com.imprimelibros.erp.payments.model.PaymentTransactionType;
|
|
||||||
import com.imprimelibros.erp.users.User;
|
|
||||||
import com.imprimelibros.erp.users.UserDao;
|
import com.imprimelibros.erp.users.UserDao;
|
||||||
|
|
||||||
|
import jakarta.persistence.criteria.Join;
|
||||||
|
import jakarta.persistence.criteria.JoinType;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ -37,11 +33,14 @@ public class PedidosController {
|
|||||||
private final PedidoRepository repoPedido;
|
private final PedidoRepository repoPedido;
|
||||||
private final UserDao repoUser;
|
private final UserDao repoUser;
|
||||||
private final MessageSource messageSource;
|
private final MessageSource messageSource;
|
||||||
|
private final PedidoLineaRepository repoPedidoLinea;
|
||||||
|
|
||||||
public PedidosController(PedidoRepository repoPedido, UserDao repoUser, MessageSource messageSource) {
|
public PedidosController(PedidoRepository repoPedido, UserDao repoUser, MessageSource messageSource,
|
||||||
|
PedidoLineaRepository repoPedidoLinea) {
|
||||||
this.repoPedido = repoPedido;
|
this.repoPedido = repoPedido;
|
||||||
this.repoUser = repoUser;
|
this.repoUser = repoUser;
|
||||||
this.messageSource = messageSource;
|
this.messageSource = messageSource;
|
||||||
|
this.repoPedidoLinea = repoPedidoLinea;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@ -65,16 +64,15 @@ public class PedidosController {
|
|||||||
Long currentUserId = Utils.currentUserId(principal);
|
Long currentUserId = Utils.currentUserId(principal);
|
||||||
|
|
||||||
List<String> searchable = List.of(
|
List<String> searchable = List.of(
|
||||||
"id",
|
"id"
|
||||||
"estado"
|
|
||||||
// "client" no, porque lo calculas a posteriori
|
// "client" no, porque lo calculas a posteriori
|
||||||
);
|
);
|
||||||
|
|
||||||
// Campos ordenables
|
// Campos ordenables
|
||||||
List<String> orderable = List.of(
|
List<String> orderable = List.of(
|
||||||
"id",
|
"id",
|
||||||
"client",
|
"createdBy.fullName",
|
||||||
"created_at",
|
"createdAt",
|
||||||
"total",
|
"total",
|
||||||
"estado");
|
"estado");
|
||||||
|
|
||||||
@ -83,6 +81,7 @@ public class PedidosController {
|
|||||||
base = base.and((root, query, cb) -> cb.equal(root.get("userId"), currentUserId));
|
base = base.and((root, query, cb) -> cb.equal(root.get("userId"), currentUserId));
|
||||||
}
|
}
|
||||||
String clientSearch = dt.getColumnSearch("cliente");
|
String clientSearch = dt.getColumnSearch("cliente");
|
||||||
|
String estadoSearch = dt.getColumnSearch("estado");
|
||||||
|
|
||||||
// 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) {
|
||||||
@ -92,7 +91,26 @@ public class PedidosController {
|
|||||||
// Ningún usuario coincide → forzamos 0 resultados
|
// Ningún usuario coincide → forzamos 0 resultados
|
||||||
base = base.and((root, query, cb) -> cb.disjunction());
|
base = base.and((root, query, cb) -> cb.disjunction());
|
||||||
} else {
|
} else {
|
||||||
base = base.and((root, query, cb) -> root.get("created_by").in(userIds));
|
base = base.and((root, query, cb) -> root.get("createdBy").in(userIds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (estadoSearch != null && !estadoSearch.isBlank()) {
|
||||||
|
try {
|
||||||
|
PedidoLinea.Estado estadoEnum = PedidoLinea.Estado.valueOf(estadoSearch.trim());
|
||||||
|
|
||||||
|
base = base.and((root, query, cb) -> {
|
||||||
|
// Evitar duplicados de pedidos si el provider usa joins
|
||||||
|
if (Pedido.class.equals(query.getResultType())) {
|
||||||
|
query.distinct(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Join<Pedido, PedidoLinea> lineas = root.join("lineas", JoinType.INNER);
|
||||||
|
return cb.equal(lineas.get("estado"), estadoEnum);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// Valor de estado no válido → forzamos 0 resultados
|
||||||
|
base = base.and((root, query, cb) -> cb.disjunction());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Long total = repoPedido.count(base);
|
Long total = repoPedido.count(base);
|
||||||
@ -101,11 +119,10 @@ public class PedidosController {
|
|||||||
.of(repoPedido, Pedido.class, dt, searchable)
|
.of(repoPedido, Pedido.class, dt, searchable)
|
||||||
.orderable(orderable)
|
.orderable(orderable)
|
||||||
.add("id", Pedido::getId)
|
.add("id", Pedido::getId)
|
||||||
.add("created_at", pedido -> Utils.formatDateTime(pedido.getCreatedAt(), locale))
|
.add("created_at", pedido -> Utils.formatInstant(pedido.getCreatedAt(), locale))
|
||||||
.add("client", pedido -> {
|
.add("cliente", pedido -> {
|
||||||
if (pedido.getCreatedBy() != null) {
|
if (pedido.getCreatedBy() != null) {
|
||||||
Optional<User> user = repoUser.findById(pedido.getCreatedBy());
|
return pedido.getCreatedBy().getFullName();
|
||||||
return user.map(User::getFullName).orElse("");
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
})
|
})
|
||||||
@ -116,9 +133,30 @@ public class PedidosController {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.add("estado", pedido -> {
|
||||||
|
List<PedidoLinea> lineas = repoPedidoLinea.findByPedidoId(pedido.getId());
|
||||||
|
if (lineas.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// concatenar los estados de las líneas, ordenados por prioridad
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
lineas.stream()
|
||||||
|
.map(PedidoLinea::getEstado)
|
||||||
|
.distinct()
|
||||||
|
.sorted(Comparator.comparingInt(PedidoLinea.Estado::getPriority))
|
||||||
|
.forEach(estado -> {
|
||||||
|
if (sb.length() > 0) {
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
sb.append(messageSource.getMessage(estado.getMessageKey(), null, locale));
|
||||||
|
});
|
||||||
|
String text = sb.toString();
|
||||||
|
return text;
|
||||||
|
})
|
||||||
.add("actions", pedido -> {
|
.add("actions", pedido -> {
|
||||||
return "<span class=\'badge bg-success btn-view \' data-id=\'" + pedido.getId() + "\' style=\'cursor: pointer;\'>"
|
return "<span class=\'badge bg-success btn-view \' data-id=\'" + pedido.getId()
|
||||||
+ messageSource.getMessage("app.view", null, locale) + "</span>";
|
+ "\' style=\'cursor: pointer;\'>"
|
||||||
|
+ messageSource.getMessage("app.view", null, locale) + "</span>";
|
||||||
})
|
})
|
||||||
.where(base)
|
.where(base)
|
||||||
.toJson(total);
|
.toJson(total);
|
||||||
|
|||||||
@ -17,4 +17,5 @@ public interface UserService extends UserDetailsService {
|
|||||||
* @return página de usuarios
|
* @return página de usuarios
|
||||||
*/
|
*/
|
||||||
Page<User> findByRoleAndSearch(String role, String query, Pageable pageable);
|
Page<User> findByRoleAndSearch(String role, String query, Pageable pageable);
|
||||||
|
User findById(Long id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,4 +31,8 @@ public class UserServiceImpl implements UserService {
|
|||||||
if (query == null || query.isBlank()) query = null;
|
if (query == null || query.isBlank()) query = null;
|
||||||
return userDao.searchUsers(role, query, pageable);
|
return userDao.searchUsers(role, query, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public User findById(Long id) {
|
||||||
|
return userDao.findById(id).orElse(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
databaseChangeLog:
|
||||||
|
- changeSet:
|
||||||
|
id: 0016-fix-enum-estado-pedidos-lineas
|
||||||
|
author: jjo
|
||||||
|
changes:
|
||||||
|
|
||||||
|
# 1) Convertir valores existentes "maquetación" → "maquetacion"
|
||||||
|
- update:
|
||||||
|
tableName: pedidos_lineas
|
||||||
|
columns:
|
||||||
|
- column:
|
||||||
|
name: estado
|
||||||
|
value: "maquetacion"
|
||||||
|
where: "estado = 'maquetación'"
|
||||||
|
|
||||||
|
# 2) Cambiar ENUM quitando tilde
|
||||||
|
- modifyDataType:
|
||||||
|
tableName: pedidos_lineas
|
||||||
|
columnName: estado
|
||||||
|
newDataType: "ENUM('aprobado','maquetacion','haciendo_ferro','producción','terminado','cancelado')"
|
||||||
|
|
||||||
|
rollback:
|
||||||
|
|
||||||
|
# 1) Volver a convertir "maquetacion" → "maquetación"
|
||||||
|
- update:
|
||||||
|
tableName: pedidos_lineas
|
||||||
|
columns:
|
||||||
|
- column:
|
||||||
|
name: estado
|
||||||
|
value: "maquetación"
|
||||||
|
where: "estado = 'maquetacion'"
|
||||||
|
|
||||||
|
# 2) Restaurar ENUM original
|
||||||
|
- modifyDataType:
|
||||||
|
tableName: pedidos_lineas
|
||||||
|
columnName: estado
|
||||||
|
newDataType: "ENUM('aprobado','maquetación','haciendo_ferro','producción','terminado','cancelado')"
|
||||||
@ -28,4 +28,6 @@ databaseChangeLog:
|
|||||||
- include:
|
- include:
|
||||||
file: db/changelog/changesets/0014-create-pedidos-direcciones.yml
|
file: db/changelog/changesets/0014-create-pedidos-direcciones.yml
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/changesets/0015-alter-pedidos-lineas-and-presupuesto-estados.yml
|
file: db/changelog/changesets/0015-alter-pedidos-lineas-and-presupuesto-estados.yml
|
||||||
|
- include:
|
||||||
|
file: db/changelog/changesets/0016-fix-enum-estado-pedidos-lineas.yml
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { normalizeNumericFilter } from '../utils.js';
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
|
|
||||||
const csrfToken = document.querySelector('meta[name="_csrf"]')?.getAttribute('content');
|
const csrfToken = document.querySelector('meta[name="_csrf"]')?.getAttribute('content');
|
||||||
@ -12,7 +14,7 @@ $(() => {
|
|||||||
|
|
||||||
const language = document.documentElement.lang || 'es-ES';
|
const language = document.documentElement.lang || 'es-ES';
|
||||||
|
|
||||||
const tablePedidos = $('#table-pedidos').DataTable({
|
const tablePedidos = $('#pedidos-datatable').DataTable({
|
||||||
processing: true,
|
processing: true,
|
||||||
serverSide: true,
|
serverSide: true,
|
||||||
orderCellsTop: true,
|
orderCellsTop: true,
|
||||||
@ -41,14 +43,31 @@ $(() => {
|
|||||||
url: '/pedidos/datatable',
|
url: '/pedidos/datatable',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
},
|
},
|
||||||
order: [[0, 'desc']],
|
order: [[0, 'desc']],
|
||||||
columns: [
|
columns: [
|
||||||
{ data: 'id', name: 'id', orderable: true },
|
{ data: 'id', name: 'id', orderable: true },
|
||||||
{ data: 'cliente', name: 'cliente', orderable: true },
|
{ data: 'cliente', name: 'createdBy.fullName', orderable: true },
|
||||||
{ data: 'created_at', name: 'created_at', orderable: true },
|
{ data: 'created_at', name: 'createdAt', orderable: true },
|
||||||
{ data: 'total', name: 'total', orderable: true },
|
{ data: 'total', name: 'total', orderable: true },
|
||||||
|
{ data: 'estado', name: 'estado', orderable: true },
|
||||||
{ data: 'actions', name: 'actions', orderable: false, searchable: false }
|
{ data: 'actions', name: 'actions', orderable: false, searchable: false }
|
||||||
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tablePedidos.on("keyup change", ".input-filter", function () {
|
||||||
|
const colName = $(this).data("col");
|
||||||
|
const colIndex = tablePedidos.settings()[0].aoColumns.findIndex(c => c.name === colName);
|
||||||
|
|
||||||
|
if (colIndex >= 0) {
|
||||||
|
tablePedidos
|
||||||
|
.column(colIndex)
|
||||||
|
.search(normalizeNumericFilter(this.value))
|
||||||
|
.draw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('.btn-view').on('click', function () {
|
||||||
|
});
|
||||||
})
|
})
|
||||||
@ -32,20 +32,32 @@
|
|||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|
||||||
<table id="pagos-redsys-datatable" class="table table-striped table-nowrap responsive w-100">
|
<table id="pedidos-datatable" class="table table-striped table-nowrap responsive w-100">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th 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 scope="col" th:text="#{pedido.table.cliente}">Cliente</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.cliente}">Cliente</th>
|
||||||
<th scope="col" th:text="#{pedido.table.fecha}">Fecha</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.fecha}">Fecha</th>
|
||||||
<th scope="col" th:text="#{pedido.table.importe}">Importe</th>
|
<th class="text-start" scope="col" th:text="#{pedido.table.importe}">Importe</th>
|
||||||
<th scope="col" th:text="#{pedido.table.acciones}">Acciones</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>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><input type="text" class="form-control form-control-sm input-filter" /></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" /></th>
|
<th><input type="text" class="form-control form-control-sm input-filter" data-col="createdBy.fullName" /></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<th>
|
||||||
|
<select class="form-select form-select-sm input-filter" data-col="estado">
|
||||||
|
<option value=""></option>
|
||||||
|
<option th:text="#{pedido.estado.aprobado}" value="aprobado"></option>
|
||||||
|
<option th:text="#{pedido.estado.maquetacion}" value="maquetacion"></option>
|
||||||
|
<option th:text="#{pedido.estado.haciendo_ferro}" value="haciendo_ferro"></option>
|
||||||
|
<option th:text="#{pedido.estado.produccion}" value="produccion"></option>
|
||||||
|
<option th:text="#{pedido.estado.terminado}" value="terminado"></option>
|
||||||
|
<option th:text="#{pedido.estado.cancelado}" value="cancelado"></option>
|
||||||
|
</select>
|
||||||
|
</th>
|
||||||
<th></th> <!-- Acciones (sin filtro) -->
|
<th></th> <!-- Acciones (sin filtro) -->
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user