Autocomplete disponibles en base a rango de dos fechas seleccionadas e excluir la ediciòn excluyendo el mismo registro
Video:
Necesitamos filtrar los entity para un autocomplete en base a la disponibilidad de datos que se encuentren disponibles entre dos fechas.
Boolean isAvailableBetweenDateHour(Bson filter, String namefieldOfStart, Date valueStart, String namefieldOfEnd, Date valueEnd)
Devuelve true si no hay registros con la condición fechay hora de inicio y fin y el filtro que se pasa como parámetro
List<T> notAvailableBetweenDateHour(Bson filter, String namefieldOfStart, Date valueStart, String namefieldOfEnd, Date valueEnd)
Devuelve una lista de los elementos que estan en ese rango de fechas y que cumplan la condición del filtro que se pasa como parámetro
Deseamos que al seleccionar la fecha y hora de inicio y de fin desde <p:calendar>, mostrar en un autocomplete los vehículos disponibles entre ese intervalo.
Cuando tenemos un autocomplete basado en filtro de fechas, muchas veces necesitamos editar los datos, y comom el filtro que se aplica en el ejemplo para vehículos nunca devolverá el vehículo seleccionado previamente necesitamos agregarlo a la lista para que el usuario puede trabajar con el , si por error lo cambia a otro vehículo.
Contamos con una lista, seleccionamos editar.
Se usa para formularios de edición de fecha hora que estan en rangos
Al cambiar la fecha y hora tener presente que puede caer en otro rango
Por ejemplo si editamos las fechas y horas del ferrari, que esta entre 16.00 y 23.00 si tratamos de editar el segundo registro colocando lo en un intervalo que este entre 1.50 7 15.00 horas no lo pemitira
El formulario permite editar fechas y vehiculos y conductores validando el rango.
Si observa el viaje seleccionado tenia el vehiculo Ferrary
Cuando se aplica el filtro del autocomplete no lo devolvería, por lo cual hay que agregarlo en el método public List<Vehiculo> completeVehiculo(String query)
Debemos definir un nuevo atributo _editable
Crear un atributo Vehiculo vehiculoSelected que contendra el vehiiculo original.
En el init() lo inicializamos dependiendo de la condición
En el método completeVehiculo() validamos si es true o false.
Los autocomplete deben excluir los registros actuales
Copy <extensionviaje:autocompletevehiculos id="vehiculo"/>
Componente
Copy <?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<composite:interface >
<composite:attribute name="value" />
<composite:attribute name="disabled" default="false" />
<composite:attribute name="itemLabel" />
<composite:attribute name="multiple" default="false" />
<composite:attribute name="dropdown" default="false"/>
<composite:attribute name="minQueryLength" default="1"/>
<composite:attribute name="update" />
<composite:attribute name="rendered"/>
<composite:attribute name="required" default="false" />
<composite:attribute name="field"/>
<composite:attribute name="fromstart" default="true"/>
<composite:attribute name="size" default="25"/>
<composite:attribute name="listener"
method-signature="void handleSelect(org.primefaces.event.SelectEvent)" />
</composite:interface>
<composite:implementation>
<p:autoComplete dropdown="true"
id="vehiculo"
multiple="false"
scrollHeight="250"
size="25"
emptyMessage="#{app['info.nohayregistros']}"
value="#{viajeController.viaje.vehiculo}"
completeMethod="#{viajeController.completeVehiculo}"
var="p"
required="true"
requiredMessage="#{msg['field.vehiculo']}"
itemLabel=" #{p.marca} #{p.modelo} #{p.placa}"
itemValue="#{p}" forceSelection="true">
<f:converter binding="#{vehiculoConverter}"/>
<f:attribute name="field" value="marca"/>
<f:attribute name="fielddropdown" value="false"/>
<f:attribute name="fieldquerylenth" value="0"/>
<p:ajax event="itemSelect" listener="#{viajeController.handleSelect}"
update="" />
<p:ajax event="itemUnselect" listener="#{viajeController.handleSelect}"
update=""
/>
<f:facet name="itemtip">
<h:panelGrid columns="2" cellpadding="5">
<h:outputText value="#{msg['field.idvehiculo']}" />
<h:outputText value="#{p.idvehiculo}" />
<h:outputText value="#{msg['field.marca']}" />
<h:outputText value="#{p.marca}" />
<h:outputText value="#{msg['field.modelo']}" />
<h:outputText value="#{p.modelo}" />
<h:outputText value="#{msg['field.placa']}" />
<h:outputText value="#{p.placa}" />
</h:panelGrid>
</f:facet>
</p:autoComplete>
</composite:implementation>
</html>
ViajeController.java
Copy Boolean iseditable = false;
handleSelect()
Copy public void handleSelect(SelectEvent event) {
try {
} catch (Exception e) {
errorServices.errorMessage(nameOfClass(), nameOfMethod(), e.getLocalizedMessage());
}
}
init()
Copy @PostConstruct
public void init() {
try {
iseditable = false;
vehiculoSelected = new Vehiculo();
conductorSelected = new Conductor();
String action = loginController.get("viaje");
String id = loginController.get("idviaje");
String pageSession = loginController.get("pageviaje");
//Search
if (loginController.get("searchviaje") == null || loginController.get("searchviaje").equals("")) {
loginController.put("searchviaje", "_init");
}
writable = false;
viajeList = new ArrayList<>();
viajeFiltered = new ArrayList<>();
viaje = new Viaje();
viajeDataModel = new ViajeDataModel(viajeList);
if (pageSession != null) {
page = Integer.parseInt(pageSession);
}
Integer c = viajeRepository.sizeOfPage(rowPage);
page = page > c ? c : page;
if (action != null) {
switch (action) {
case "gonew":
viaje = new Viaje();
viaje.setFechahorainicioreserva(DateUtil.getFechaHoraActual());
viaje.setFechahorafinreserva(DateUtil.getFechaHoraActual());
viaje.setActivo("si");
viaje.setLugarpartida("UTP-AZUERO");
viajeSelected = viaje;
writable = false;
break;
case "view":
if (id != null) {
Optional<Viaje> optional = viajeRepository.find("idviaje", Integer.parseInt(id));
if (optional.isPresent()) {
viaje = optional.get();
viajeSelected = viaje;
vehiculoSelected = viaje.getVehiculo();
conductorSelected = viaje.getConductor();
fechaHoraInicioReservaanterior = viaje.getFechahorainicioreserva();
fechaHoraFinReservaAnterior = viaje.getFechahorafinreserva();
iseditable = true;
writable = true;
}
}
break;
case "golist":
move();
break;
}
} else {
move();
}
} catch (Exception e) {
errorServices.errorMessage(nameOfClass(), nameOfMethod(), e.getLocalizedMessage());
}
}// </editor-fold>
Método completeVehiculo()
Verificamos si hay cambios en fechas horas
Copy public List<Vehiculo> completeVehiculo(String query) {
List<Vehiculo> suggestions = new ArrayList<>();
List<Vehiculo> temp = new ArrayList<>();
try {
Boolean found = false;
query = query.trim();
if (iseditable && noHayCambioFechaHoras()) {
suggestions.add(vehiculoSelected);
}
String field = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes().get("field");
temp = vehiculoRepository.findRegex(field, query, true, new Document(field, 1));
if (!temp.isEmpty()) {
List<Vehiculo> validos = new ArrayList<>();
if (noHayCambioFechaHoras()) {
validos = temp.stream()
.filter(x -> isVehiculoActivoDisponible(x)).collect(Collectors.toList());
} else {
validos = temp.stream()
.filter(x -> isVehiculoActivoDisponibleExcluyendoMismoViaje(x)).collect(Collectors.toList());
//si cambia el vehiculo
}
if (validos.isEmpty()) {
return suggestions;
}
if (vehiculoList == null || vehiculoList.isEmpty()) {
validos.forEach((v) -> {
suggestions.add(v);
}); // validos.add(vehiculoSelected);
// return validos;
} else {
// REMOVERLOS SI YA ESTAN EN EL LISTADO
validos.forEach((v) -> {
Optional<Vehiculo> optional = vehiculoList.stream()
.filter(v2 -> v2.getIdvehiculo() == v.getIdvehiculo())
.findAny();
if (!optional.isPresent()) {
suggestions.add(v);
}
});
}
}
} catch (Exception e) {
errorServices.errorMessage(nameOfClass(), nameOfMethod(), e.getLocalizedMessage());
}
return suggestions;
}
Verifica si cambio la fecha y hora
Copy private Boolean noHayCambioFechaHoras() {
return fechaHoraInicioReservaanterior.equals(viaje.getFechahorainicioreserva()) && fechaHoraFinReservaAnterior.equals(viaje.getFechahorafinreserva());
}
isVehiculoActivoDisponible()
Copy public Boolean isVehiculoActivoDisponible(Vehiculo vehiculo) {
Boolean valid = false;
try {
if (vehiculo.getActivo().equals("no") && vehiculo.getEnreparacion().equals("si")) {
} else {
if (viajeServices.vehiculoDisponible(vehiculo, viaje.getFechahorainicioreserva(), viaje.getFechahorafinreserva())) {
valid = true;
}
}
} catch (Exception e) {
errorServices.errorDialog(nameOfClass(), nameOfMethod(), nameOfMethod(), e.getLocalizedMessage());
}
return valid;
}
isVehiculoActivoDisponibleExcluyendoMismoViaje(Vehiculo vehiculo)
Busca el vehiculo y excluye el actual
Copy public Boolean isVehiculoActivoDisponibleExcluyendoMismoViaje(Vehiculo vehiculo) {
Boolean valid = false;
try {
if (vehiculo.getActivo().equals("no") && vehiculo.getEnreparacion().equals("si")) {
} else {
if (viajeServices.vehiculoDisponibleExcluyendoMismoViaje(vehiculo, viaje.getFechahorainicioreserva(), viaje.getFechahorafinreserva(), viaje.getIdviaje())) {
valid = true;
}
}
} catch (Exception e) {
errorServices.errorDialog(nameOfClass(), nameOfMethod(), "isVehiculoValid()", e.getLocalizedMessage());
}
return valid;
}
save()
Copy public String save() {
try {
if (!viajeServices.isValid(viaje)) {
return "";
}
if (!viajeServices.vehiculoDisponible(viaje)) {
JsfUtil.warningMessage(rf.getMessage("warning.vehiculoenviajefechas"));
return null;
}
if (viaje.getConductor().getEscontrol().equals("no")) {
if (!viajeServices.conductorDisponible(viaje)) {
JsfUtil.warningMessage(rf.getMessage("warning.conductoresenviajefechas"));
return null;
}
}
Integer idviaje = autoincrementableTransporteejbServices.getContador("viaje");
viaje.setIdviaje(idviaje);
viaje.setRealizado("no");
viaje.setActivo("si");
//Lo datos del usuario
viaje.setUserInfo(userInfoServices.generateListUserinfo(loginController.getUsername(), "create"));
if (viajeRepository.save(viaje)) {
//guarda el contenido anterior
revisionHistoryTransporteejbRepository.save(revisionHistoryServices.getRevisionHistory(viaje.getIdviaje().toString(), loginController.getUsername(),
"create", "viaje", viajeRepository.toDocument(viaje).toString()));
JsfUtil.successMessage(rf.getAppMessage("info.save"));
reset();
} else {
JsfUtil.successMessage("save() " + viajeRepository.getException().toString());
}
} catch (Exception e) {
errorServices.errorMessage(nameOfClass(), nameOfMethod(), e.getLocalizedMessage());
}
return "";
}// </editor-fold>
edit()
Validar si cambio la fecha y hora
Copy public String edit() {
try {
if (!viajeServices.isValid(viaje)) {
return "";
}
if (noHayCambioFechaHoras()) {
//si cambia el vehiculo
if (!viaje.getVehiculo().getIdvehiculo().equals(vehiculoSelected.getIdvehiculo())) {
if (!viajeServices.vehiculoDisponible(viaje)) {
JsfUtil.warningMessage(rf.getMessage("warning.vehiculoenviajefechas"));
return null;
}
}
// si cambio el conductor
if (!viaje.getConductor().getIdconductor().equals(conductorSelected.getIdconductor())) {
if (viaje.getConductor().getEscontrol().equals("no")) {
if (!viajeServices.conductorDisponible(viaje)) {
JsfUtil.warningMessage(rf.getMessage("warning.conductoresenviajefechas"));
return null;
}
}
}
} else {
//si cambia el vehiculo
if (!viajeServices.vehiculoDisponibleExcluyendoMismoViaje(viaje)) {
JsfUtil.warningMessage(rf.getMessage("warning.vehiculoenviajefechas"));
return null;
}
// si cambio el conductor
if (viaje.getConductor().getEscontrol().equals("no")) {
if (!viajeServices.conductorDisponibleExcluyendoMismoViaje(viaje)) {
JsfUtil.warningMessage(rf.getMessage("warning.conductoresenviajefechas"));
return null;
}
}
}
viaje.getUserInfo().add(userInfoServices.generateUserinfo(loginController.getUsername(), "update"));
//guarda el contenido actualizado
revisionHistoryTransporteejbRepository.save(revisionHistoryServices.getRevisionHistory(viaje.getIdviaje().toString(), loginController.getUsername(),
"update", "viaje", viajeRepository.toDocument(viaje).toString()));
viajeRepository.update(viaje);
JsfUtil.successMessage(rf.getAppMessage("info.update"));
} catch (Exception e) {
errorServices.errorMessage(nameOfClass(), nameOfMethod(), e.getLocalizedMessage());
}
return "";
}// </editor-fold>
ViajesServices.java
vehiculoDisponible()
Verifica si esta disponible el vehiculo
Copy public Boolean vehiculoDisponible(Vehiculo vehiculo, Date fechahorainicioreserva, Date fechahorafinreserva) {
try {
Bson filter= Filters.and(eq("vehiculo.idvehiculo",vehiculo.getIdvehiculo()),eq("activo","si"));
//
return repository.isAvailableBetweenDateHour(filter,
"fechahorainicioreserva", fechahorainicioreserva, "fechahorafinreserva", fechahorafinreserva);
} catch (Exception e) {
JsfUtil.errorDialog("vehiculoDisponible() ", e.getLocalizedMessage().toString());
}
return false;
}
vehiculoDisponibleExcluyendoMismoViaje()
Verifica si esta disponible excluyendo el mismo viaje para edición.
Copy public Boolean vehiculoDisponibleExcluyendoMismoViaje(Vehiculo vehiculo, Date fechahorainicioreserva, Date fechahorafinreserva,Integer idviaje) {
try {
Bson filter= Filters.and(eq("vehiculo.idvehiculo",vehiculo.getIdvehiculo()),eq("activo","si"),ne("idviaje",idviaje));
return repository.isAvailableBetweenDateHour(filter,
"fechahorainicioreserva", fechahorainicioreserva, "fechahorafinreserva", fechahorafinreserva);
} catch (Exception e) {
JsfUtil.errorDialog("vehiculoDisponible() ", e.getLocalizedMessage().toString());
}
return false;
}