Skip to content
Snippets Groups Projects
Commit 163a22cf authored by migudel's avatar migudel :speech_balloon:
Browse files

Mejoras y algunos cambios en los endpoints y relacionados

parent ab5af357
No related branches found
No related tags found
2 merge requests!10Add ts types and json mocks, remove poblate scripts and fix the cascade...,!3Hotel controller mas o menos terminado, añadidas request a repositorios y...
......@@ -2,7 +2,12 @@
package com.uva.roomBooking.Controllers;
import com.uva.roomBooking.Models.Booking;
import com.uva.roomBooking.Models.Room;
import com.uva.roomBooking.Models.User;
import com.uva.roomBooking.Repositories.BookingRepository;
import com.uva.roomBooking.Repositories.RoomRepository;
import com.uva.roomBooking.Repositories.UserRepository;
import org.springframework.web.bind.annotation.*;
import java.util.List;
......@@ -13,9 +18,14 @@ import java.util.List;
public class BookingController {
private final BookingRepository bookingRepository;
private final UserRepository userRepository;
private final RoomRepository roomRepository;
public BookingController(BookingRepository bookingRepository) {
public BookingController(BookingRepository bookingRepository, UserRepository userRepository,
RoomRepository roomRepository) {
this.bookingRepository = bookingRepository;
this.userRepository = userRepository;
this.roomRepository = roomRepository;
}
@GetMapping
......@@ -25,6 +35,10 @@ public class BookingController {
@PostMapping
public Booking createBooking(@RequestBody Booking booking) {
User user = userRepository.findById(booking.getUserId().getId()).orElseThrow();
Room room = roomRepository.findById(booking.getRoomId().getId()).orElseThrow();
booking.setUserId(user);
booking.setRoomId(room);
return bookingRepository.save(booking);
}
......
......
package com.uva.roomBooking.Controllers;
import java.util.List;
import java.util.Optional;
import java.time.LocalDate;
import com.uva.roomBooking.Exceptions.HotelNotFoundException;
......@@ -28,67 +27,62 @@ public class HotelController {
// Obtener todos los hoteles
@GetMapping
public ResponseEntity<List<Hotel>> getAllHotels() {
List<Hotel> hotels = hotelRepository.findAll();
return new ResponseEntity<>(hotels, HttpStatus.OK);
public List<Hotel> getAllHotels() {
return hotelRepository.findAll();
}
// Añadir un hotel con sus habitaciones
@PostMapping
public ResponseEntity<Hotel> addHotel(@RequestBody Hotel hotel) {
if (hotel.getRooms() != null) {
hotel.getRooms().forEach(room -> room.setHotel(hotel)); // Aseguramos la relación bidireccional
}
Hotel savedHotel = hotelRepository.save(hotel);
return new ResponseEntity<>(savedHotel, HttpStatus.CREATED);
}
// Obtener un hotel por su ID
@GetMapping("/{id}")
public ResponseEntity<Hotel> getHotelById(@PathVariable int id) {
public Hotel getHotelById(@PathVariable int id) {
return hotelRepository.findById(id)
.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
.orElseThrow(() -> new HotelNotFoundException(id));
}
// Borrar un hotel junto con sus habitaciones (borrado en cascada)
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteHotel(@PathVariable Integer id) {
Optional<Hotel> target = hotelRepository.findById(id);
if (target.isPresent()) {
// Borramos habitaciones asociadas
roomRepository.deleteAllByHotelId(id);
hotelRepository.deleteById(id);
Hotel target = hotelRepository.findById(id).orElseThrow(() -> new HotelNotFoundException(id));
hotelRepository.delete(target);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
throw new HotelNotFoundException(id); // Lanzamos excepción personalizada
}
// Obtener habitaciones de un hotel según disponibilidad y fechas
@GetMapping("/{hotelId}/rooms")
public ResponseEntity<List<Room>> getRoomsFromHotel(
@PathVariable int hotelId,
@PathVariable(required = true) int hotelId,
@RequestParam(required = false) LocalDate date1,
@RequestParam(required = false) LocalDate date2) {
List<Room> rooms;
if (date1 != null && date2 != null) {
if (!date1.isBefore(date2)) {
// TODO cambiar por una excepción adecuada
throw new IllegalArgumentException("date1 should be before than date2");
}
rooms = roomRepository.findAvailableRoomsByHotelAndDates(hotelId, date1, date2);
} else {
rooms = roomRepository.findByHotelId(hotelId);
rooms = roomRepository.findAllByHotelId(hotelId);
}
return new ResponseEntity<>(rooms, HttpStatus.OK);
}
// Actualizar disponibilidad de habitaciones de un hotel
@PatchMapping("/{hotelId}/rooms")
@PatchMapping("/{hotelId}/rooms/")
// TODO incluir tratamiento por id de habitación
public ResponseEntity<List<Room>> updateRoomAvailabilityFromHotel(
@PathVariable int hotelId, @RequestBody List<Room> updatedRooms) {
List<Room> existingRooms = roomRepository.findByHotelId(hotelId);
List<Room> existingRooms = roomRepository.findAllByHotelId(hotelId);
for (Room updatedRoom : updatedRooms) {
existingRooms.stream()
.filter(room -> Integer.valueOf(room.getId()).equals(updatedRoom.getId())) // Conversión a Integer
.filter(room -> room.getId() == updatedRoom.getId()) // Conversión a Integer
.findFirst()
.ifPresent(room -> room.setAvailable(updatedRoom.isAvailable()));
}
......@@ -96,13 +90,28 @@ public class HotelController {
return new ResponseEntity<>(existingRooms, HttpStatus.OK);
}
// Mi propuesta para el anterior
// // Actualizar disponibilidad de habitaciones de un hotel
// @PatchMapping("/{hotelId}/rooms/{roomId}")
// // TODO incluir tratamiento por id de habitación
// public ResponseEntity<Room> updateRoomAvailabilityFromHotel(
// @PathVariable int hotelId, @PathVariable int roomId, @RequestBody Map<String,
// Boolean> roomPatch) {
// Room target = roomRepository.findByIdAndHotelId(roomId, hotelId)
// .orElseThrow(() -> new IllegalArgumentException("No founds"));
// if (roomPatch.containsKey("available")) {
// throw new InvalidRequestException("no available field in body request");
// }
// target.setAvailable(roomPatch.get("available"));
// roomRepository.save(target);
// return new ResponseEntity<>(target, HttpStatus.OK);
// }
// Obtener los detalles de una habitación específica en un hotel
@GetMapping("/{hotelId}/rooms/{roomId}")
public ResponseEntity<Room> getRoomByIdFromHotel(
public Room getRoomByIdFromHotel(
@PathVariable int hotelId, @PathVariable int roomId) {
Optional<Room> room = roomRepository.findByHotelIdAndRoomId(hotelId, roomId);
return room.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
.orElseThrow(() -> new HotelNotFoundException(hotelId)); // Lanzamos excepción personalizada
return roomRepository.findByIdAndHotelId(roomId, hotelId)
.orElseThrow(() -> new HotelNotFoundException(hotelId));
}
}
......@@ -22,22 +22,25 @@ public class Booking {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
private int id;
// TODO revisar si lo de cascade es estrictamente necesario
@JoinColumn(name = "user_id", referencedColumnName = "id")
@ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
@ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
private User userId;
@JoinColumn(name = "room_id", referencedColumnName = "id")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Room roomID;
@ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
private Room roomId;
@Column(name = "start_date", nullable = false)
private Date startDate;
private LocalDate startDate;
@Column(name = "end_date", nullable = false)
private Date endDate;
private LocalDate endDate;
public Booking() {
}
public Booking (int id, User userId, Room roomID, Date startDate, Date endDate) {
public Booking(int id, User userId, Room roomID, LocalDate startDate, LocalDate endDate) {
this.id = id;
this.userId = userId;
this.roomID = roomID;
this.roomId = roomID;
this.startDate = startDate;
this.endDate = endDate;
}
......@@ -50,38 +53,36 @@ public class Booking {
return this.id;
}
public void setUser (User userId) {
public void setUserId(User userId) {
this.userId = userId;
}
public User getUser () {
public User getUserId() {
return this.userId;
}
public void setRoom (Room roomID) {
this.roomID = roomID;
public void setRoomId(Room roomID) {
this.roomId = roomID;
}
public Room getRoom () {
return this.roomID;
public Room getRoomId() {
return this.roomId;
}
public void setStartDate (Date startDate) {
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
public Date getStartDate () {
public LocalDate getStartDate() {
return this.startDate;
}
public void setEndDate (Date endDate) {
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
public Date getEndDate () {
public LocalDate getEndDate() {
return this.endDate;
}
}
......@@ -40,7 +40,7 @@ public class Room {
@Column(name = "available", nullable = false)
private boolean available;
@JsonIgnore
@OneToMany(mappedBy = "roomID", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
@OneToMany(mappedBy = "roomId", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
private List<Booking> bookings;
public Room() {
......
......
......@@ -2,9 +2,7 @@ package com.uva.roomBooking.Repositories;
import com.uva.roomBooking.Models.Room;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.util.List;
......@@ -12,29 +10,23 @@ import java.util.Optional;
public interface RoomRepository extends JpaRepository<Room, Integer> {
// Encontrar todas las habitaciones de un hotel
List<Room> findByHotelId(int hotelId);
Optional<Room> findByIdAndHotelId(int id, int hotelId);
// Borrar todas las habitaciones asociadas a un hotel
@Transactional
@Modifying
void deleteAllByHotelId(int hotelId);
// Encontrar todas las habitaciones de un hotel
List<Room> findAllByHotelId(int hotelId);
// Encontrar habitaciones disponibles de un hotel en un rango de fechas
// TODO revisar los límites en las fechas
@Query("""
SELECT r FROM Room r
WHERE r.hotel.id = :hotelId
WHERE r.hotel.id = ?1
AND r.available = true
AND NOT EXISTS (
SELECT b FROM Booking b
WHERE b.roomID.id = r.id
AND (b.startDate <= :endDate AND b.endDate >= :startDate)
WHERE b.roomId.id = r.id
AND (b.startDate < ?3 AND b.endDate > ?2)
)
""")
List<Room> findAvailableRoomsByHotelAndDates(
int hotelId, LocalDate startDate, LocalDate endDate);
// Encontrar una habitación específica por hotel y su ID
@Query("SELECT r FROM Room r WHERE r.hotel.id = :hotelId AND r.id = :roomId")
Optional<Room> findByHotelIdAndRoomId(int hotelId, int roomId);
}
......@@ -5,3 +5,6 @@ spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/RoomsBooking?cre
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Usar esto para alternar entre las exposición del room repository ya que no es necesario su uso pero por defecto, al no cubrir su ruta, se expone
spring.data.rest.base-path=false
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment