Commit ecc90d78 by Antonio Rueda

Implementación de operaciones de disponibilidad de un hotel y de hoteles

disponibles en una localidad
parent f285aa39
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
package es.ujaen.dae.reservahoteles.entidades; package es.ujaen.dae.reservahoteles.entidades;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Map; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
/** /**
...@@ -16,7 +16,7 @@ public class Hotel { ...@@ -16,7 +16,7 @@ public class Hotel {
// Dirección // Dirección
String localidad; String localidad;
String provincia; String provincia;
int cp; String cp;
// Disponibilidad habitaciones // Disponibilidad habitaciones
int numHabSimple; int numHabSimple;
...@@ -26,9 +26,9 @@ public class Hotel { ...@@ -26,9 +26,9 @@ public class Hotel {
int precioHabSimple; int precioHabSimple;
int precioHabDoble; int precioHabDoble;
Map<LocalDate, Reserva> reservas; SortedMap<LocalDate, Reserva> reservas;
public Hotel(int id, String nombre, String localidad, String provincia, int cp, int numHabSimple, int numHabDoble, int precioHabSimple, int precioHabDoble) { public Hotel(int id, String nombre, String localidad, String provincia, String cp, int numHabSimple, int numHabDoble, int precioHabSimple, int precioHabDoble) {
this.id = id; this.id = id;
this.nombre = nombre; this.nombre = nombre;
this.localidad = localidad; this.localidad = localidad;
...@@ -42,6 +42,46 @@ public class Hotel { ...@@ -42,6 +42,46 @@ public class Hotel {
reservas = new TreeMap<>(); reservas = new TreeMap<>();
} }
/**
* Comprueba si hay disponibilidad en las fechas indicadas
* @param fechaInicio fecha de inicio de la reserva
* @param fechaFin fecha de final de la reserva
* @param numHabSimple número de habitaciones simples solicitadas
* @param numHabDoble número de habitaciones dobles solicitadas
* @return true si hay disponibilidad, false en caso contrario
*/
public boolean disponible(LocalDate fechaInicio, LocalDate fechaFin, int numHabSimple, int numHabDoble) {
for (var fecha = fechaInicio.plusDays(0); fecha.isBefore(fechaFin); fecha = fecha.plusDays(1))
if (!disponible(fecha, numHabSimple, numHabDoble))
return false;
return true;
}
/**
* Comprueba si hay disponibilidad en un día concreto
* @param fecha día a comprobar
* @param numHabSimple número de habitaciones simples solicitadas
* @param numHabDoble número de habitaciones dobles solicitadas
* @return true si hay disponibilidad, false en caso contrario
*/
public boolean disponible(LocalDate fecha, int numHabSimple, int numHabDoble) {
int numHabSimpleDisponibles = numHabSimple;
int numHabDobleDisponibles = numHabDoble;
for (var reserva: reservas.values()) {
if (reserva.fechaInicio().isAfter(fecha))
break;
if (fechaEnIntervalo(fecha, reserva.fechaInicio(), reserva.fechaFin())) {
numHabSimpleDisponibles -= reserva.numHabSimple();
numHabDobleDisponibles -= reserva.numHabDoble();
}
}
return numHabSimpleDisponibles >= numHabSimple && numHabDobleDisponibles >= numHabDoble;
}
public int id() { public int id() {
return id; return id;
} }
...@@ -53,4 +93,20 @@ public class Hotel { ...@@ -53,4 +93,20 @@ public class Hotel {
public String localidad() { public String localidad() {
return localidad; return localidad;
} }
public void nombre(String nombre) {
this.nombre = nombre;
}
/**
* Operación auxiliar para comprobar si una fecha están dentro de un intervalo dado
* (incluyendo extremos)
* @param fecha la fecha a comprobar
* @param fechaInicio la fecha de inicio del intervalo
* @param fechaFin la fecha de fin del intervalo
* @return true si la fecha está en el intervalo dado, false en caso contrario
*/
private static boolean fechaEnIntervalo(LocalDate fecha, LocalDate fechaInicio, LocalDate fechaFin) {
return fecha.isAfter(fechaInicio.minusDays(1)) && fecha.isBefore(fechaFin.plusDays(1));
}
} }
...@@ -29,4 +29,20 @@ public class Reserva { ...@@ -29,4 +29,20 @@ public class Reserva {
this.numHabSimple = numHabSimple; this.numHabSimple = numHabSimple;
this.numHabDoble = numHabDoble; this.numHabDoble = numHabDoble;
} }
public LocalDate fechaInicio() {
return fechaInicio;
}
public LocalDate fechaFin() {
return fechaFin;
}
public int numHabSimple() {
return numHabSimple;
}
public int numHabDoble() {
return numHabDoble;
}
} }
...@@ -7,6 +7,7 @@ import es.ujaen.dae.reservahoteles.entidades.Reserva; ...@@ -7,6 +7,7 @@ import es.ujaen.dae.reservahoteles.entidades.Reserva;
import es.ujaen.dae.reservahoteles.excepciones.ClienteYaRegistrado; import es.ujaen.dae.reservahoteles.excepciones.ClienteYaRegistrado;
import es.ujaen.dae.reservahoteles.util.UtilString; import es.ujaen.dae.reservahoteles.util.UtilString;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
...@@ -46,17 +47,30 @@ public class ServicioReservas { ...@@ -46,17 +47,30 @@ public class ServicioReservas {
Cliente cliente = clientes.get(email); Cliente cliente = clientes.get(email);
return (cliente != null && cliente.clave().equals(clave)) ? Optional.of(cliente): Optional.empty(); return (cliente != null && cliente.clave().equals(clave)) ? Optional.of(cliente): Optional.empty();
} }
public List<Hotel> buscarPorLocalidad(String localidad, /**
* Búsqueda de hoteles disponibles en una localidad
* @param localidad el nombre total o parcial de la localidad
* @param fechaInicio fecha de inicio de la estancia
* @param fechaFin fecha de final de la estancia
* @param numHabSimple número de habitaciones simples solicitadas
* @param numHabDoble número de habitaciones dobles solicitadas
* @return la lista de hoteles candidatos
*/
public List<Hotel> buscarHotelesDisponiblesPorLocalidad(String localidad,
LocalDate fechaInicio, LocalDate fechaFin, LocalDate fechaInicio, LocalDate fechaFin,
int numHabSimple, int numHabDoble) { int numHabSimple, int numHabDoble) {
var localidadNorm = UtilString.normalizar(localidad);
// Por implementar
throw new UnsupportedOperationException(); return hoteles.values().stream().filter(h ->
UtilString.normalizar(h.localidad()).contains(localidadNorm) &&
h.disponible(fechaInicio, fechaFin, numHabSimple, numHabDoble)
).toList();
} }
/** /**
* Búsqueda de hoteles por nombre o localidad aproximados * Búsqueda de hoteles por nombre o localidad aproximados (sin comprobar
* disponibilidad)
* @param nombre el nombre total o parcial del hotel * @param nombre el nombre total o parcial del hotel
* @param localidad el nombre total o parcial de la localidad * @param localidad el nombre total o parcial de la localidad
* @return la lista de hoteles candidatos * @return la lista de hoteles candidatos
...@@ -70,6 +84,18 @@ public class ServicioReservas { ...@@ -70,6 +84,18 @@ public class ServicioReservas {
UtilString.normalizar(h.nombre()).contains(nombreNorm)) UtilString.normalizar(h.nombre()).contains(nombreNorm))
.toList(); .toList();
} }
/**
* Comprueba si hay disponibilidad en las fechas indicadas
* @param fechaInicio fecha de inicio de la reserva
* @param fechaFin fecha de final de la reserva
* @param numHabSimple número de habitaciones simples solicitadas
* @param numHabDoble número de habitaciones dobles solicitadas
* @return true si hay disponibilidad, false en caso contrario
*/
public boolean disponible(Hotel h, LocalDate fechaInicio, LocalDate fechaFin, int numHabSimple, int numHabDoble) {
return h.disponible(fechaInicio, fechaFin, numHabSimple, numHabDoble);
}
public Reserva reserva(Cliente cliente, Hotel hotel, public Reserva reserva(Cliente cliente, Hotel hotel,
LocalDate fechaInicio, LocalDate fechaFin, LocalDate fechaInicio, LocalDate fechaFin,
......
...@@ -3,6 +3,7 @@ package es.ujaen.dae.reservahoteles.servicios; ...@@ -3,6 +3,7 @@ package es.ujaen.dae.reservahoteles.servicios;
import es.ujaen.dae.reservahoteles.entidades.Cliente; import es.ujaen.dae.reservahoteles.entidades.Cliente;
import es.ujaen.dae.reservahoteles.entidades.Hotel; import es.ujaen.dae.reservahoteles.entidades.Hotel;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -35,13 +36,36 @@ public class TestServicioReservas { ...@@ -35,13 +36,36 @@ public class TestServicioReservas {
@Test @Test
@DirtiesContext @DirtiesContext
void testBuscarHotel() { void testBuscarHotel() {
var hotel1 = new Hotel(1, "Gran Hotel Almería", "Almería", "Almería", 04001, 25, 50, 100, 180); var hotel1 = new Hotel(1, "Gran Hotel Almería", "Almería", "Almería", "04001", 25, 50, 100, 180);
var hotel2 = new Hotel(2, "Hotel Infanta Cristina", "Jaén", "Jaén", 23009, 30, 60, 120, 200); var hotel2 = new Hotel(2, "Hotel Infanta Cristina", "Jaén", "Jaén", "23009", 30, 60, 120, 200);
servicio.nuevoHotel(hotel1); servicio.nuevoHotel(hotel1);
servicio.nuevoHotel(hotel2); servicio.nuevoHotel(hotel2);
List<Hotel> hoteles = servicio.buscarHotel("gran hotel", "almeria"); List<Hotel> hoteles = servicio.buscarHotel("gran hotel", " almeria");
assertThat(hoteles).containsOnly(hotel1);
assertThat(hoteles).hasSize(1);
assertThat(hoteles.getFirst().id()).isEqualTo(1);
} }
@Test
@DirtiesContext
void testBuscarPorLocalidad() {
var hotel1 = new Hotel(1, "Gran Hotel Almería", "Almería", "Almería", "04001", 25, 50, 100, 180);
var hotel2 = new Hotel(2, "Hotel Espejo del Mar", "Almería", "Almería", "04001", 15, 35, 80, 110);
var hotel3 = new Hotel(3, "Hotel Infanta Cristina", "Jaén", "Jaén", "23009", 30, 60, 120, 200);
servicio.nuevoHotel(hotel1);
servicio.nuevoHotel(hotel2);
servicio.nuevoHotel(hotel3);
List<Hotel> hoteles = servicio.buscarPorLocalidad("almeria",
LocalDate.now().plusWeeks(2),
LocalDate.now().plusWeeks(2).plusDays(2),
0, 2);
assertThat(hoteles).hasSize(2);
assertThat(hoteles.getFirst().id()).isEqualTo(1);
assertThat(hoteles.getLast().id()).isEqualTo(2);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment