terminado margenes presupuesto e incluido en la api

This commit is contained in:
2025-10-02 20:50:39 +02:00
parent 460d2cfc01
commit 1e24065fb7
18 changed files with 663 additions and 101 deletions

View File

@ -5,15 +5,21 @@ import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.PersistenceUnit;
import jakarta.persistence.criteria.*;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.stereotype.Component;
@Component
public class NoRangeOverlapValidator implements ConstraintValidator<NoRangeOverlap, Object> {
@PersistenceContext
private EntityManager em;
@PersistenceUnit
private EntityManagerFactory emf;
private String minField;
private String maxField;
@ -38,22 +44,28 @@ public class NoRangeOverlapValidator implements ConstraintValidator<NoRangeOverl
@Override
public boolean isValid(Object bean, ConstraintValidatorContext ctx) {
if (bean == null) return true;
if (bean == null)
return true;
EntityManager em = null;
try {
// EM aislado para evitar auto-flush durante la validación
em = emf.createEntityManager();
em.setFlushMode(FlushModeType.COMMIT);
Class<?> entityClass = bean.getClass();
Number min = (Number) read(bean, minField);
Number max = (Number) read(bean, maxField);
Object id = safeRead(bean, idField); // puede ser null en INSERT
if (min == null || max == null) return true;
if (min == null || max == null)
return true;
if (min.longValue() > max.longValue()) {
ctx.disableDefaultConstraintViolation();
ctx.buildConstraintViolationWithTemplate(invalidRangeMessage)
.addPropertyNode(maxField)
.addConstraintViolation();
.addPropertyNode(maxField)
.addConstraintViolation();
return false;
}
@ -82,9 +94,8 @@ public class NoRangeOverlapValidator implements ConstraintValidator<NoRangeOverl
Expression<Number> eMax = root.get(maxField);
Predicate noOverlap = cb.or(
cb.lt(eMax.as(Long.class), min.longValue()),
cb.gt(eMin.as(Long.class), max.longValue())
);
cb.lt(eMax.as(Long.class), min.longValue()),
cb.gt(eMin.as(Long.class), max.longValue()));
Predicate overlap = cb.not(noOverlap);
cq.where(cb.and(pred, overlap));
@ -93,9 +104,9 @@ public class NoRangeOverlapValidator implements ConstraintValidator<NoRangeOverl
if (count != null && count > 0) {
ctx.disableDefaultConstraintViolation();
ctx.buildConstraintViolationWithTemplate(message)
.addPropertyNode(minField).addConstraintViolation();
.addPropertyNode(minField).addConstraintViolation();
ctx.buildConstraintViolationWithTemplate(message)
.addPropertyNode(maxField).addConstraintViolation();
.addPropertyNode(maxField).addConstraintViolation();
return false;
}