Skip to content
Snippets Groups Projects
Commit 39eba64a authored by hugcubi's avatar hugcubi
Browse files

Hotel controller mas o menos terminado, añadidas request a repositorios y...

Hotel controller mas o menos terminado, añadidas request a repositorios y creada carpeta de excepciones
parent 1632b54c
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...
package com.uva.roomBooking.Controllers; package com.uva.roomBooking.Controllers;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.time.LocalDate; import java.time.LocalDate;
import com.uva.roomBooking.Exceptions.HotelNotFoundException;
import com.uva.roomBooking.Models.Hotel; import com.uva.roomBooking.Models.Hotel;
import com.uva.roomBooking.Models.Room; import com.uva.roomBooking.Models.Room;
import com.uva.roomBooking.Repositories.HotelRepository; import com.uva.roomBooking.Repositories.HotelRepository;
import com.uva.roomBooking.Repositories.RoomRepository; import com.uva.roomBooking.Repositories.RoomRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
// TODO incluir excepciones y procesado de respuestas con entidad y código de estado
@RestController @RestController
@RequestMapping("hotels") @RequestMapping("hotels")
@CrossOrigin(origins = "*") @CrossOrigin(origins = "*")
...@@ -27,66 +26,83 @@ public class HotelController { ...@@ -27,66 +26,83 @@ public class HotelController {
this.roomRepository = roomRepository; this.roomRepository = roomRepository;
} }
// Obtener todos los hoteles
@GetMapping @GetMapping
public List<Hotel> getAllHotels() { public ResponseEntity<List<Hotel>> getAllHotels() {
return hotelRepository.findAll(); List<Hotel> hotels = hotelRepository.findAll();
return new ResponseEntity<>(hotels, HttpStatus.OK);
} }
// Añadir un hotel con sus habitaciones
@PostMapping @PostMapping
public Hotel addHotel(@RequestBody Hotel hotel) { public ResponseEntity<Hotel> addHotel(@RequestBody Hotel hotel) {
// TODO comprobar y asegurar que se agregan todas sus habitaciones también if (hotel.getRooms() != null) {
return hotelRepository.save(hotel); 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}") @GetMapping("/{id}")
public Hotel getHotelById(@PathVariable int id) { public ResponseEntity<Hotel> getHotelById(@PathVariable int id) {
return hotelRepository.findById(id).orElse(null); 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}") @DeleteMapping("/{id}")
public Hotel deleteHotel(@PathVariable Integer id) { public ResponseEntity<Void> deleteHotel(@PathVariable Integer id) {
Hotel target; Optional<Hotel> target = hotelRepository.findById(id);
if ((target = hotelRepository.findById(id).orElse(null)) != null) { if (target.isPresent()) {
// TODO asegurarse de que el borrado es en CASCADA -> Hotel y habitaciones // Borramos habitaciones asociadas
roomRepository.deleteAllByHotelId(id);
hotelRepository.deleteById(id); hotelRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} }
return target; throw new HotelNotFoundException(id); // Lanzamos excepción personalizada
} }
// TODO completar controllers de rooms // Obtener habitaciones de un hotel según disponibilidad y fechas
@GetMapping("/{id}/rooms") @GetMapping("/{hotelId}/rooms")
// Dejo un esqueleto, a lo mejor sería mejor otra forma de plantear el manejo y public ResponseEntity<List<Room>> getRoomsFromHotel(
// recogida de query params @PathVariable int hotelId,
public List<Room> getRoomsFromHotel(@PathVariable int hotelId, @RequestParam LocalDate date1, @RequestParam(required = false) LocalDate date1,
@RequestParam LocalDate date2) { @RequestParam(required = false) LocalDate date2) {
throw new IllegalStateException("Not implemented yet");
List<Room> rooms;
if (date1 != null && date2 != null) {
rooms = roomRepository.findAvailableRoomsByHotelAndDates(hotelId, date1, date2);
} else {
rooms = roomRepository.findByHotelId(hotelId);
} }
return new ResponseEntity<>(rooms, HttpStatus.OK);
@PatchMapping("/{id}/rooms")
public List<Room> updateRoomAvailabilityFromHotel(@PathVariable int hotelId) {
throw new IllegalStateException("Not implemented yet");
} }
@GetMapping("/{hotelId}/rooms/{roomId}") // Actualizar disponibilidad de habitaciones de un hotel
public List<Room> getRoomByIdFromHotel(@PathVariable int hotelId, @PathVariable int roomId) { @PatchMapping("/{hotelId}/rooms")
throw new IllegalStateException("Not implemented yet"); public ResponseEntity<List<Room>> updateRoomAvailabilityFromHotel(
@PathVariable int hotelId, @RequestBody List<Room> updatedRooms) {
List<Room> existingRooms = roomRepository.findByHotelId(hotelId);
for (Room updatedRoom : updatedRooms) {
existingRooms.stream()
.filter(room -> Integer.valueOf(room.getId()).equals(updatedRoom.getId())) // Conversión a Integer
.findFirst()
.ifPresent(room -> room.setAvailable(updatedRoom.isAvailable()));
}
roomRepository.saveAll(existingRooms);
return new ResponseEntity<>(existingRooms, HttpStatus.OK);
} }
// Te dejo esto de la otra clase comentado por si te sirve algo // Obtener los detalles de una habitación específica en un hotel
@GetMapping("/{hotelId}/rooms/{roomId}")
// @GetMapping public ResponseEntity<Room> getRoomByIdFromHotel(
// public List<Room> getAllRooms() { @PathVariable int hotelId, @PathVariable int roomId) {
// return roomRepository.findAll();
// }
// @PostMapping
// public Room addRoom(@RequestBody Room room) {
// return roomRepository.save(room);
// }
// @DeleteMapping("/{id}")
// public void deleteRoom(@PathVariable Integer id) {
// roomRepository.deleteById(id);
// }
Optional<Room> room = roomRepository.findByHotelIdAndRoomId(hotelId, roomId);
return room.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
.orElseThrow(() -> new HotelNotFoundException(hotelId)); // Lanzamos excepción personalizada
}
} }
package com.uva.roomBooking.exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HotelNotFoundException.class)
public ResponseEntity<Map<String, Object>> handleHotelNotFound(HotelNotFoundException ex) {
Map<String, Object> body = new HashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", ex.getMessage());
return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(InvalidRequestException.class)
public ResponseEntity<Map<String, Object>> handleInvalidRequest(InvalidRequestException ex) {
Map<String, Object> body = new HashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", ex.getMessage());
return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
Map<String, Object> body = new HashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", "An unexpected error occurred: " + ex.getMessage());
return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
package com.uva.roomBooking.Exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND) // Devuelve un 404 cuando se lanza la excepción
public class HotelNotFoundException extends RuntimeException {
public HotelNotFoundException(int id) {
super("Hotel not found with id: " + id);
}
}
package com.uva.roomBooking.Exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class InvalidRequestException extends RuntimeException {
public InvalidRequestException(String message) {
super(message);
}
}
...@@ -78,7 +78,7 @@ public class Hotel { ...@@ -78,7 +78,7 @@ public class Hotel {
public void setRooms(List<Room> rooms) { public void setRooms(List<Room> rooms) {
this.rooms = rooms; this.rooms = rooms;
rooms.forEach(room -> room.setHotelId(this)); rooms.forEach(room -> room.setHotel(this));
} }
} }
...@@ -63,11 +63,11 @@ public class Room { ...@@ -63,11 +63,11 @@ public class Room {
return this.id; return this.id;
} }
public void setHotelId(Hotel hotelId) { public void setHotel(Hotel hotelId) {
this.hotelId = hotelId; this.hotelId = hotelId;
} }
public Hotel getHotelId() { public Hotel getHotel() {
return this.hotelId; return this.hotelId;
} }
...@@ -91,7 +91,7 @@ public class Room { ...@@ -91,7 +91,7 @@ public class Room {
this.available = available; this.available = available;
} }
public boolean getAvailable() { public boolean isAvailable() {
return this.available; return this.available;
} }
......
// RoomRepository.java
package com.uva.roomBooking.Repositories; package com.uva.roomBooking.Repositories;
import com.uva.roomBooking.Models.Room; import com.uva.roomBooking.Models.Room;
import org.springframework.data.jpa.repository.JpaRepository; 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;
public interface RoomRepository extends JpaRepository<Room, Integer> { public interface RoomRepository extends JpaRepository<Room, Integer> {
// Encontrar todas las habitaciones de un hotel
List<Room> findByHotelId(int hotelId);
// Borrar todas las habitaciones asociadas a un hotel
@Transactional
void deleteAllByHotelId(int hotelId);
// Encontrar habitaciones disponibles de un hotel en un rango de fechas
@Query("""
SELECT r FROM Room r
WHERE r.hotel.id = :hotelId
AND r.available = true
AND NOT EXISTS (
SELECT b FROM Booking b
WHERE b.room.id = r.id
AND (b.startDate <= :endDate AND b.endDate >= :startDate)
)
""")
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);
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment