Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Antonio Rueda
/
reserva-hoteles
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
5fbba8ae
authored
Dec 17, 2024
by
Antonio Rueda
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Añadido endpoint para obtener las reservas en un periodo dado de un
usuario o totales
parent
48eaf4ef
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
149 additions
and
16 deletions
src/main/java/es/ujaen/dae/reservahoteles/entidades/Hotel.java
src/main/java/es/ujaen/dae/reservahoteles/repositorios/RepositorioHoteles.java
src/main/java/es/ujaen/dae/reservahoteles/rest/ControladorReservas.java
src/main/java/es/ujaen/dae/reservahoteles/servicios/ServicioReservas.java
src/test/java/es/ujaen/dae/reservahoteles/rest/TestControladorReservas.java
src/main/java/es/ujaen/dae/reservahoteles/entidades/Hotel.java
View file @
5fbba8ae
...
...
@@ -167,7 +167,7 @@ public class Hotel {
* @return la lista de reservas
*/
public
List
<
Reserva
>
reservasEntre
(
LocalDate
fechaInicio
,
LocalDate
fechaFin
)
{
return
reservas
.
stream
().
filter
(
r
->
r
.
fechaInicio
().
isBefore
(
fechaFin
)
return
reservas
.
stream
().
filter
(
r
->
(
r
.
fechaInicio
().
isBefore
(
fechaFin
)
)
&&
r
.
fechaFin
().
isAfter
(
fechaInicio
)).
toList
();
}
...
...
src/main/java/es/ujaen/dae/reservahoteles/repositorios/RepositorioHoteles.java
View file @
5fbba8ae
...
...
@@ -6,7 +6,6 @@ import static es.ujaen.dae.reservahoteles.util.UtilString.normalizar;
import
jakarta.persistence.EntityManager
;
import
jakarta.persistence.LockModeType
;
import
jakarta.persistence.PersistenceContext
;
import
java.time.LocalDate
;
import
java.util.List
;
import
java.util.Optional
;
import
org.springframework.cache.annotation.CacheEvict
;
...
...
src/main/java/es/ujaen/dae/reservahoteles/rest/ControladorReservas.java
View file @
5fbba8ae
...
...
@@ -2,6 +2,7 @@
package
es
.
ujaen
.
dae
.
reservahoteles
.
rest
;
import
es.ujaen.dae.reservahoteles.entidades.Hotel
;
import
es.ujaen.dae.reservahoteles.entidades.Reserva
;
import
es.ujaen.dae.reservahoteles.entidades.Usuario
;
import
es.ujaen.dae.reservahoteles.excepciones.HotelNoRegistrado
;
import
es.ujaen.dae.reservahoteles.excepciones.NoDisponibilidadReserva
;
...
...
@@ -13,8 +14,10 @@ import es.ujaen.dae.reservahoteles.rest.dto.DHotel;
import
es.ujaen.dae.reservahoteles.rest.dto.DReserva
;
import
es.ujaen.dae.reservahoteles.rest.dto.DUsuario
;
import
es.ujaen.dae.reservahoteles.rest.dto.Mapeador
;
import
es.ujaen.dae.reservahoteles.seguridad.ServicioCredencialesUsuario
;
import
es.ujaen.dae.reservahoteles.servicios.ServicioReservas
;
import
jakarta.validation.ConstraintViolationException
;
import
java.security.Principal
;
import
java.time.LocalDate
;
import
java.util.List
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -43,6 +46,9 @@ public class ControladorReservas {
@Autowired
ServicioReservas
servicioReservas
;
@Autowired
ServicioCredencialesUsuario
servicioCredencialesUsuario
;
// Definir un mapeado global para cualquier excepción de validación de beans
@ResponseStatus
(
HttpStatus
.
UNPROCESSABLE_ENTITY
)
@ExceptionHandler
(
ConstraintViolationException
.
class
)
...
...
@@ -94,7 +100,7 @@ public class ControladorReservas {
List
<
Hotel
>
hoteles
;
if
(
nombre
!=
null
)
{
hoteles
=
servicioReservas
.
buscarHotel
(
nombre
,
localidad
).
stream
()
.
filter
(
h
->
h
.
disponible
(
desdeFinal
,
hastaFinal
,
numHabSimple
,
numHabDoble
)).
toList
();
.
filter
(
h
->
servicioReservas
.
disponible
(
h
,
desdeFinal
,
hastaFinal
,
numHabSimple
,
numHabDoble
)).
toList
();
}
else
{
hoteles
=
servicioReservas
.
buscarHotelesDisponiblesPorLocalidad
(
localidad
,
desdeFinal
,
hastaFinal
,
numHabSimple
,
numHabDoble
);
...
...
@@ -103,11 +109,11 @@ public class ControladorReservas {
return
ResponseEntity
.
ok
(
hoteles
.
stream
().
map
(
h
->
mapeador
.
dto
(
h
)).
toList
());
}
@GetMapping
(
"/hoteles/{id}"
)
public
ResponseEntity
<
DHotel
>
buscarHotel
(
@PathVariable
int
id
)
{
@GetMapping
(
"/hoteles/{id
Hotel
}"
)
public
ResponseEntity
<
DHotel
>
buscarHotel
(
@PathVariable
int
id
Hotel
)
{
try
{
Hotel
hotel
=
servicioReservas
.
buscarHotel
(
id
).
orElseThrow
(
HotelNoRegistrado:
:
new
);
Hotel
hotel
=
servicioReservas
.
buscarHotel
(
id
Hotel
).
orElseThrow
(
HotelNoRegistrado:
:
new
);
return
ResponseEntity
.
ok
(
mapeador
.
dto
(
hotel
));
}
catch
(
HotelNoRegistrado
e
)
{
...
...
@@ -115,26 +121,26 @@ public class ControladorReservas {
}
}
@GetMapping
(
"/hoteles/{id}/disponibilidad"
)
public
ResponseEntity
<
DDisponibilidad
>
verDisponibilidadHotel
(
@PathVariable
int
id
,
@GetMapping
(
"/hoteles/{id
Hotel
}/disponibilidad"
)
public
ResponseEntity
<
DDisponibilidad
>
verDisponibilidadHotel
(
@PathVariable
int
id
Hotel
,
@RequestParam
LocalDate
desde
,
@RequestParam
LocalDate
hasta
)
{
final
var
desdeFinal
=
desde
!=
null
?
desde
:
LocalDate
.
now
();
final
var
hastaFinal
=
hasta
!=
null
?
hasta
:
LocalDate
.
MAX
;
try
{
Hotel
hotel
=
servicioReservas
.
buscarHotel
(
id
).
orElseThrow
(
HotelNoRegistrado:
:
new
);
return
ResponseEntity
.
ok
(
mapeador
.
dto
(
hotel
.
disponibilidad
(
desdeFinal
,
hastaFinal
)));
Hotel
hotel
=
servicioReservas
.
buscarHotel
(
id
Hotel
).
orElseThrow
(
HotelNoRegistrado:
:
new
);
return
ResponseEntity
.
ok
(
mapeador
.
dto
(
servicioReservas
.
disponibilidad
(
hotel
,
desdeFinal
,
hastaFinal
)));
}
catch
(
HotelNoRegistrado
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
}
}
@PostMapping
(
"/hoteles/{id}/reservas"
)
public
ResponseEntity
<
DReserva
>
reserva
(
@PathVariable
int
id
,
@RequestBody
DReserva
reserva
)
{
@PostMapping
(
"/hoteles/{id
Hotel
}/reservas"
)
public
ResponseEntity
<
DReserva
>
reserva
(
@PathVariable
int
id
Hotel
,
@RequestBody
DReserva
reserva
)
{
try
{
Hotel
hotel
=
servicioReservas
.
buscarHotel
(
id
).
orElseThrow
(
HotelNoRegistrado:
:
new
);
Hotel
hotel
=
servicioReservas
.
buscarHotel
(
id
Hotel
).
orElseThrow
(
HotelNoRegistrado:
:
new
);
Usuario
usuario
=
servicioReservas
.
buscarUsuario
(
reserva
.
emailUsuario
()).
orElseThrow
(
UsuarioNoRegistrado:
:
new
);
return
ResponseEntity
.
status
(
HttpStatus
.
CREATED
).
body
(
mapeador
.
dto
(
servicioReservas
.
reserva
(
...
...
@@ -156,4 +162,34 @@ public class ControladorReservas {
return
ResponseEntity
.
status
(
HttpStatus
.
CONFLICT
).
build
();
}
}
@GetMapping
(
"/hoteles/{idHotel}/reservas"
)
public
ResponseEntity
<
List
<
DReserva
>>
verReservas
(
@PathVariable
int
idHotel
,
@RequestParam
(
required
=
false
)
LocalDate
desde
,
@RequestParam
(
required
=
false
)
LocalDate
hasta
,
Principal
usuarioAutenticado
)
{
final
var
desdeFinal
=
desde
!=
null
?
desde
:
LocalDate
.
now
();
final
var
hastaFinal
=
hasta
!=
null
?
hasta
:
LocalDate
.
MAX
;
List
<
Reserva
>
reservas
;
try
{
Hotel
hotel
=
servicioReservas
.
buscarHotel
(
idHotel
).
orElseThrow
(
HotelNoRegistrado:
:
new
);
var
esDireccion
=
servicioCredencialesUsuario
.
loadUserByUsername
(
usuarioAutenticado
.
getName
())
.
getAuthorities
().
stream
().
anyMatch
(
a
->
a
.
getAuthority
().
equals
(
"DIRECCION"
));
if
(
esDireccion
)
reservas
=
servicioReservas
.
verReservas
(
hotel
,
desdeFinal
,
hastaFinal
);
else
{
var
usuario
=
servicioReservas
.
buscarUsuario
(
usuarioAutenticado
.
getName
()).
get
();
reservas
=
servicioReservas
.
verReservas
(
hotel
,
desdeFinal
,
hastaFinal
,
usuario
);
}
}
catch
(
HotelNoRegistrado
e
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
NOT_FOUND
).
build
();
}
return
ResponseEntity
.
ok
(
reservas
.
stream
().
map
(
reserva
->
mapeador
.
dto
(
reserva
)).
toList
());
}
}
src/main/java/es/ujaen/dae/reservahoteles/servicios/ServicioReservas.java
View file @
5fbba8ae
package
es
.
ujaen
.
dae
.
reservahoteles
.
servicios
;
import
es.ujaen.dae.reservahoteles.excepciones.OperacionDeDireccion
;
import
es.ujaen.dae.reservahoteles.entidades.Usuario
;
import
es.ujaen.dae.reservahoteles.entidades.Hotel
;
import
es.ujaen.dae.reservahoteles.entidades.Reserva
;
...
...
@@ -10,7 +9,6 @@ import es.ujaen.dae.reservahoteles.repositorios.RepositorioHoteles;
import
es.ujaen.dae.reservahoteles.repositorios.RepositorioUsuarios
;
import
es.ujaen.dae.reservahoteles.util.UtilString
;
import
jakarta.validation.Valid
;
import
jakarta.validation.constraints.Email
;
import
jakarta.validation.constraints.Future
;
import
jakarta.validation.constraints.FutureOrPresent
;
import
jakarta.validation.constraints.NotBlank
;
...
...
@@ -69,6 +67,11 @@ public class ServicioReservas {
return repositorioClientes.buscar(email).filter(cliente -> cliente.clave().equals(clave));
}
*/
/**
* Devolver el usuario asociado al e-mail dado
* @param email el e-mail del usuario
* @return un optional con el usuario asociado al e-mail
*/
public
Optional
<
Usuario
>
buscarUsuario
(
String
email
)
{
if
(
email
.
equals
(
direccion
.
email
()))
return
Optional
.
of
(
direccion
);
...
...
@@ -146,6 +149,27 @@ public class ServicioReservas {
hotel
=
repositorioHoteles
.
actualizar
(
hotel
);
return
hotel
.
disponibilidad
(
fechaInicio
,
fechaFin
);
}
/**
* Indica si el hotel está disponible en las fechas indicadas
* @param hotel hotel donde se compreuba la disponibilidad
* @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 el hotel está disponible en las fechas indicadas; false en caso contrario
*/
@Transactional
public
boolean
disponible
(
Hotel
hotel
,
@FutureOrPresent
LocalDate
fechaInicio
,
@FutureOrPresent
LocalDate
fechaFin
,
@PositiveOrZero
int
numHabSimple
,
@PositiveOrZero
int
numHabDoble
)
{
hotel
=
repositorioHoteles
.
actualizar
(
hotel
);
var
disponibilidad
=
hotel
.
disponibilidad
(
fechaInicio
,
fechaFin
);
return
disponibilidad
.
numHabSimple
()
>=
numHabSimple
&&
disponibilidad
.
numHabDoble
()
>=
numHabDoble
;
}
/**
* Realiza una reserva en un hotel. La reserva debe ser correcta y haber disponibilidad.
...
...
@@ -205,6 +229,32 @@ public class ServicioReservas {
return
reserva
;
}
/**
* Devuelve las reservas del hotel indicado entre dos fechas
* @param hotel el hotel a consultar
* @param fechaInicio fecha de inicio
* @param fechaFin fecha final
* @return una lista con las reservas del hotel en el periodo indicado
*/
@Transactional
public
List
<
Reserva
>
verReservas
(
Hotel
hotel
,
LocalDate
fechaInicio
,
LocalDate
fechaFin
)
{
hotel
=
repositorioHoteles
.
actualizar
(
hotel
);
return
hotel
.
reservasEntre
(
fechaInicio
,
fechaFin
);
}
/**
* Devuelve las reservas en el hotel del usuario indicado entre dos fechas
* @param hotel el hotel a consultar
* @param fechaInicio fecha de inicio
* @param fechaFin fecha final
* @param usuario el usuario que realiza la reserva
* @return una lista con las reservas del usuario en el hotel y en el periodo indicado
*/
@Transactional
public
List
<
Reserva
>
verReservas
(
Hotel
hotel
,
LocalDate
fechaInicio
,
LocalDate
fechaFin
,
Usuario
usuario
)
{
return
verReservas
(
hotel
,
fechaInicio
,
fechaFin
).
stream
().
filter
(
reserva
->
reserva
.
cliente
().
equals
(
usuario
)).
toList
();
}
@Transactional
@Scheduled
(
cron
=
"0 0 0 1 * ?"
)
public
void
eliminarReservasAntiguas
()
{
...
...
src/test/java/es/ujaen/dae/reservahoteles/rest/TestControladorReservas.java
View file @
5fbba8ae
...
...
@@ -226,4 +226,51 @@ public class TestControladorReservas {
assertThat
(
respuestaReserva
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
CREATED
);
}
}
@Test
@DirtiesContext
void
testConsultaReservasHotel
()
{
var
hotel
=
new
DHotel
(
0
,
"Bed and Breakfast Almería"
,
"Almería"
,
"Almería"
,
"04001"
,
2
,
2
,
60
,
100
);
restTemplate
.
withBasicAuth
(
"direccion@hotelxyz.es"
,
"SeCrEtO"
).
postForEntity
(
"/hoteles"
,
hotel
,
DHotel
.
class
);
var
usuario
=
new
DUsuario
(
"Pedro"
,
"Jaén Jaén"
,
"611203025"
,
"pjaen@gmail.com"
,
"miClAvE"
);
restTemplate
.
postForEntity
(
"/usuarios"
,
usuario
,
Void
.
class
);
var
hotelGuardado
=
restTemplate
.
getForEntity
(
"/hoteles?nombre={nombre}&localidad={localidad}"
,
DHotel
[].
class
,
"bed and breakfast"
,
" almeria"
).
getBody
()[
0
];
var
reserva
=
new
DReserva
(
0
,
LocalDate
.
now
().
plusDays
(
7
),
LocalDate
.
now
().
plusDays
(
10
),
0
,
1
,
usuario
.
email
());
restTemplate
.
withBasicAuth
(
usuario
.
email
(),
usuario
.
clave
()).
postForEntity
(
"/hoteles/{id}/reservas"
,
reserva
,
DReserva
.
class
,
hotelGuardado
.
id
()
);
var
respuestaConsultaReservas
=
restTemplate
.
withBasicAuth
(
usuario
.
email
(),
usuario
.
clave
()).
getForEntity
(
"/hoteles/{id}/reservas"
,
DReserva
[].
class
,
hotelGuardado
.
id
()
);
assertThat
(
respuestaConsultaReservas
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
assertThat
(
respuestaConsultaReservas
.
getBody
()).
hasSize
(
1
);
assertThat
(
respuestaConsultaReservas
.
getBody
()[
0
].
numHabDoble
()).
isEqualTo
(
1
);
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment