Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pbs 43 view room detail #126

Merged
merged 4 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
@EnableMethodSecurity
public class SecurityConfig {
private final String[] PUBLIC_ENDPOINTS = {"/accounts", "/accounts/me",
"/auth/login", "/auth/introspect", "/auth/refresh-token", "/auth/logout", "/auth/login/google"
"/auth/login", "/auth/introspect", "/auth/refresh-token",
"/auth/logout", "/auth/login/google",
"/rooms/slots-by-rooms-and-date","/rooms/available-by-type-and-date"
};

private final String[] ADMIN_ENDPOINTS = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.swp.PodBookingSystem.controller;

import com.swp.PodBookingSystem.dto.request.Room.RoomAvailabilityDTO;
import com.swp.PodBookingSystem.dto.request.Slot.SlotCreationRequest;
import com.swp.PodBookingSystem.dto.request.Slot.SlotDTO;
import com.swp.PodBookingSystem.dto.respone.ApiResponse;
import com.swp.PodBookingSystem.dto.request.Room.RoomCreationRequest;
import com.swp.PodBookingSystem.dto.request.Room.RoomPaginationDTO;
import com.swp.PodBookingSystem.dto.respone.Calendar.DateResponse;
import com.swp.PodBookingSystem.dto.respone.PaginationResponse;
import com.swp.PodBookingSystem.dto.respone.Room.BookedRoomDto;
import com.swp.PodBookingSystem.dto.respone.Room.RoomResponse;
Expand Down Expand Up @@ -87,13 +86,13 @@ PaginationResponse<List<Room>> getFilteredRoom(@RequestParam(required = false) S
@GetMapping("/available-rooms")
ApiResponse<List<Room>> getAvailableRoomsByRoomTypeId(@RequestParam Integer typeId,
@RequestParam(required = false) List<String> slots) {
List<SlotCreationRequest> slotList = new ArrayList<>();
List<SlotDTO> slotList = new ArrayList<>();
if(slots!=null) {
for(String slot: slots) {
String[] parts = slot.split("_");
LocalDateTime startTime = LocalDateTime.parse(parts[0]);
LocalDateTime endTime = LocalDateTime.parse(parts[1]);
slotList.add(new SlotCreationRequest(startTime,endTime));
slotList.add(new SlotDTO(startTime,endTime));
}
}
return ApiResponse.<List<Room>>builder()
Expand All @@ -102,24 +101,13 @@ ApiResponse<List<Room>> getAvailableRoomsByRoomTypeId(@RequestParam Integer typ
.build();
}

@GetMapping("/calendar")
ApiResponse<List<DateResponse>> getCalendar(@RequestParam List<Integer> roomIds,
@RequestParam(required = false) Integer servicePackageId,
@RequestParam LocalDate selectedDate,
@RequestParam List<String> slots
) {
return ApiResponse.<List<DateResponse>>builder()
.data(roomService.getCalendar(roomIds,servicePackageId,selectedDate,slots))
.message("Get calendar successfully")
.build();
}

@GetMapping("/unavailable")
ApiResponse<List<RoomAvailabilityDTO>> getUnavailableRooms(@RequestParam LocalDateTime startTime,
ApiResponse<List<RoomAvailabilityDTO>> getUnavailableRooms(@RequestParam List<Integer> roomIds,
@RequestParam LocalDateTime startTime,
@RequestParam LocalDateTime endTime
) {
return ApiResponse.<List<RoomAvailabilityDTO>>builder()
.data(roomService.getUnavailableRooms(startTime,endTime))
.data(roomService.getUnavailableRooms(roomIds,startTime,endTime))
.message("Get unavailable rooms successfully")
.build();
}
Expand Down Expand Up @@ -164,4 +152,22 @@ ApiResponse<Integer> countCurrentlyServedRooms() {
.data(roomService.countCurrentlyServedRooms())
.build();
}
@GetMapping("/available-by-type-and-date")
ApiResponse<List<Room>> getRoomsByTypeAndDate(@RequestParam Integer typeId, @RequestParam String date) {
LocalDate selectedDate = LocalDate.parse(date);
return ApiResponse.<List<Room>>builder()
.data(roomService.getRoomsByTypeAndDate(typeId, selectedDate))
.message("Get rooms by typeId and date successfully")
.build();
}

@GetMapping("/slots-by-rooms-and-date")
ApiResponse<List<SlotDTO>> getSlotsByRoomsAndDate(@RequestParam(required = false) List<Integer> roomIds, @RequestParam(required = false) String date) {
return ApiResponse.<List<SlotDTO>>builder()
.data(roomService.getSlotsByRoomsAndDate(roomIds, date))
.message("Get slots by rooms and date successfully")
.build();
}


}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.swp.PodBookingSystem.dto.request.Room;

import com.swp.PodBookingSystem.dto.request.Slot.SlotDTO;
import lombok.*;
import lombok.experimental.FieldDefaults;

import java.time.LocalDateTime;
import java.util.List;

@Data
@NoArgsConstructor
Expand All @@ -13,6 +14,5 @@
public class RoomAvailabilityDTO {
Integer roomId;
String name;
LocalDateTime startTime;
LocalDateTime endTime;
List<SlotDTO> slots;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.swp.PodBookingSystem.dto.respone.Calendar;
package com.swp.PodBookingSystem.dto.request.Slot;

import lombok.*;
import lombok.experimental.FieldDefaults;

import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
Expand All @@ -13,5 +12,4 @@
public class SlotDTO {
LocalDateTime startTime;
LocalDateTime endTime;
boolean available;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.swp.PodBookingSystem.dto.respone.Calendar;

import com.swp.PodBookingSystem.dto.request.Slot.SlotCreationRequest;
import lombok.*;
import lombok.experimental.FieldDefaults;

Expand All @@ -14,5 +13,5 @@
public class RoomDTO {
int roomId;
String roomName;
List<SlotDTO> slots;
List<SlotCustomDTO> slots;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package com.swp.PodBookingSystem.dto.request.Slot;
package com.swp.PodBookingSystem.dto.respone.Calendar;

import lombok.*;
import lombok.experimental.FieldDefaults;

import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class SlotCreationRequest {
public class SlotCustomDTO {
LocalDateTime startTime;
LocalDateTime endTime;
boolean available;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.swp.PodBookingSystem.repository;

import com.swp.PodBookingSystem.dto.request.Slot.SlotDTO;
import com.swp.PodBookingSystem.dto.respone.Room.BookedRoomDto;
import com.swp.PodBookingSystem.entity.OrderDetail;
import com.swp.PodBookingSystem.entity.Room;
Expand Down Expand Up @@ -62,4 +63,35 @@ List<OrderDetail> findRoomAvailabilityWithinDateRange(
"WHERE :currentTime BETWEEN od.startTime AND od.endTime " +
"AND od.status = com.swp.PodBookingSystem.enums.OrderStatus.Successfully")
int countCurrentlyServedRooms(@Param("currentTime") LocalDateTime currentTime);

@Query("SELECT r FROM Room r " +
"JOIN OrderDetail od ON r.id = od.room.id " +
"WHERE r.roomType.id = :typeId " +
"AND r.status = com.swp.PodBookingSystem.enums.RoomStatus.Available " +
"AND od.startTime >= :startTime " +
"AND od.endTime <= :endTime " +
"AND (od.status = com.swp.PodBookingSystem.enums.OrderStatus.Successfully " +
"OR od.status = com.swp.PodBookingSystem.enums.OrderStatus.Pending) "
)
List<Room> getRoomsByTypeAndDate(@Param("typeId") Integer typeId,
@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);

@Query("SELECT DISTINCT NEW com.swp.PodBookingSystem.dto.request.Slot.SlotDTO(od.startTime,od.endTime) " +
"FROM OrderDetail od " +
"WHERE od.room.id = :roomId " +
"AND od.room.status = com.swp.PodBookingSystem.enums.RoomStatus.Available " +
"AND od.startTime >= :startTime " +
"AND od.endTime <= :endTime " +
"AND (od.status = com.swp.PodBookingSystem.enums.OrderStatus.Successfully " +
"OR od.status = com.swp.PodBookingSystem.enums.OrderStatus.Pending) "
)
List<SlotDTO> getSlotsByRoomAndDate(@Param("roomId")Integer roomId,
@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);

@Query("SELECT r FROM Room r " +
"JOIN r.roomType rt " +
"WHERE rt.id = :typeId")
List<Room> findAllByTypeId(@Param("typeId") Integer typeId);
}
142 changes: 79 additions & 63 deletions src/main/java/com/swp/PodBookingSystem/service/RoomService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@

import com.swp.PodBookingSystem.dto.request.Room.RoomAvailabilityDTO;
import com.swp.PodBookingSystem.dto.request.Room.RoomCreationRequest;
import com.swp.PodBookingSystem.dto.request.Slot.SlotCreationRequest;
import com.swp.PodBookingSystem.dto.respone.Calendar.DateResponse;
import com.swp.PodBookingSystem.dto.respone.Calendar.RoomDTO;
import com.swp.PodBookingSystem.dto.respone.Calendar.SlotDTO;
import com.swp.PodBookingSystem.dto.request.Slot.SlotDTO;
import com.swp.PodBookingSystem.dto.respone.Room.BookedRoomDto;
import com.swp.PodBookingSystem.dto.respone.Room.RoomResponse;
import com.swp.PodBookingSystem.entity.OrderDetail;
import com.swp.PodBookingSystem.entity.Room;
import com.swp.PodBookingSystem.entity.RoomType;
import com.swp.PodBookingSystem.exception.AppException;
Expand All @@ -29,7 +25,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -86,13 +81,13 @@ public boolean isRoomAvailable(Integer roomId, LocalDateTime startTime, LocalDat
return roomRepository.isRoomAvailable(roomId, startTime, endTime);
}

public List<Room> getRoomByTypeAndSlot(Integer typeId,List<SlotCreationRequest> slots ) {
public List<Room> getRoomByTypeAndSlot(Integer typeId,List<SlotDTO> slots ) {
List<Room> roomList = roomRepository.findRoomsByTypeId(typeId);
List<Room> availableRooms = new ArrayList<>();
for (Room room : roomList) {
boolean isAvailableForAllSlots = true;

for (SlotCreationRequest slot : slots) {
for (SlotDTO slot : slots) {

if (!isRoomAvailable(room.getId(), slot.getStartTime(), slot.getEndTime())) {
isAvailableForAllSlots = false;
Expand Down Expand Up @@ -144,64 +139,27 @@ public String deleteRoom(int roomId) {
return "Delete room " + roomId + " successfully";
}

public List<DateResponse> getCalendar(List<Integer> roomIds, Integer servicePackageId, LocalDate selectedDate, List<String> slots)
{
List<DateResponse> response = new ArrayList<>();
List<LocalDate> dates = new ArrayList<>();

if(servicePackageId!= null && servicePackageId == 1) {
LocalDateTime currentDate = selectedDate.atStartOfDay();
int count = 1;
do {
dates.add(currentDate.toLocalDate());
currentDate.plusDays(7);
} while(count++<=3);
} else if (servicePackageId!= null && servicePackageId == 2) {
LocalDateTime currentDate = selectedDate.atStartOfDay();
int count = 1;
do {
dates.add(currentDate.toLocalDate());
currentDate.plusDays(1);
} while(count++<=29);
} else {
LocalDateTime currentDate = selectedDate.atStartOfDay();
dates.add(currentDate.toLocalDate());


public List<RoomAvailabilityDTO> getUnavailableRooms(List<Integer> roomIds,LocalDateTime startTime, LocalDateTime endTime) {
if(roomIds == null || roomIds.isEmpty()) {
return new ArrayList<>();
}
for(LocalDate date: dates) {
List<RoomDTO> rooms = roomIds.parallelStream().map(roomId -> {
RoomDTO room = new RoomDTO();
Optional<Room> findRoom = roomRepository.findById((roomId));
Room roomFromDB = findRoom.orElseThrow(() -> new RuntimeException("Room not found"));
room.setRoomId(roomFromDB.getId());
room.setRoomName(roomFromDB.getName());
LocalDateTime currentDate = date.atStartOfDay();

List<SlotDTO> slotResponse = slots.parallelStream().map(slot->{
String[] parts = slot.split("-");
LocalDateTime startTime = currentDate.withHour(Integer.parseInt(parts[0].split(":")[0].trim()));
LocalDateTime endTime = currentDate.withHour(Integer.parseInt(parts[1].split(":")[0].trim()));
return new SlotDTO(startTime, endTime, roomRepository.isRoomAvailable(roomFromDB.getId(),startTime, endTime));
}).collect(Collectors.toList());
room.setSlots(slotResponse);
return room;
}).collect(Collectors.toList());
response.add(new DateResponse(date,rooms));
if(startTime == null || endTime == null) {
throw new RuntimeException("Invalid date");
}
return response;
}


public List<RoomAvailabilityDTO> getUnavailableRooms(LocalDateTime startTime, LocalDateTime endTime) {
List<OrderDetail> orders = roomRepository.findRoomAvailabilityWithinDateRange(startTime, endTime);
System.out.println(orders.toString());
return orders.stream()
.map(order -> RoomAvailabilityDTO.builder()
.roomId(order.getRoom().getId()) // Assuming Room has an 'id' field
.name(order.getRoom().getName()) // Assuming Room has a 'name' field
.startTime(order.getStartTime())
.endTime(order.getEndTime())
.build())
.collect(Collectors.toList());
List<RoomAvailabilityDTO> roomAvailabilityDTOList = new ArrayList<>();
for(Integer roomId: roomIds) {
List<SlotDTO> slotList = roomRepository.getSlotsByRoomAndDate(roomId, startTime, endTime);
Room room = roomRepository.findById(roomId).orElseThrow(() -> new RuntimeException("Room not found"));
roomAvailabilityDTOList.add(RoomAvailabilityDTO.builder()
.roomId(roomId)
.name(room.getName())
.slots(slotList)
.build());
}
return roomAvailabilityDTOList;
}

public List<BookedRoomDto> getBookedRooms(String customerId) {
Expand All @@ -215,4 +173,62 @@ public List<BookedRoomDto> getBookedRooms(String customerId) {
public int countCurrentlyServedRooms() {
return roomRepository.countCurrentlyServedRooms(LocalDateTime.now());
}

public List<Room> getRoomsByTypeAndDate(Integer typeId, LocalDate date) {
List<Room> result = new ArrayList<>();
List<SlotDTO> listSlotConstants = new ArrayList<>();
LocalDateTime current = date.atTime(7, 0, 0);
while (current.isBefore(date.atTime(21, 0, 0))) {
if(current.isBefore(LocalDateTime.now())) {
current = current.plusHours(2);
continue;
}
listSlotConstants.add(new SlotDTO(current, current.plusHours(2)));
current = current.plusHours(2);
}
LocalDateTime startTime = date.atStartOfDay();
LocalDateTime endTime = date.atTime(23, 59, 59);
List<Room> rooms =roomRepository.findAllByTypeId(typeId);
for(Room room: rooms) {
List<SlotDTO> slotList = roomRepository.getSlotsByRoomAndDate(room.getId(), startTime, endTime);
List<SlotDTO> tmp = new ArrayList<>(listSlotConstants);
tmp.removeAll(slotList);
if(!tmp.isEmpty()) {
result.add(room);
}
}

return result;
}

public List<SlotDTO> getSlotsByRoomsAndDate(List<Integer> roomIds, String date) {
LocalDate selectedDate = date == null? LocalDate.now() : LocalDate.parse(date);
if(selectedDate.isBefore(LocalDate.now())) {
throw new RuntimeException("Invalid date");
}
if(selectedDate.isEqual(LocalDate.now()) && LocalDateTime.now().getHour() >= 21) {
throw new RuntimeException("Invalid date");
}

LocalDateTime startTime = LocalDateTime.now().toLocalDate().equals(selectedDate) ? LocalDateTime.now() : selectedDate.atStartOfDay();
LocalDateTime endTime = selectedDate.atTime(23, 59, 59);
List<SlotDTO> listSlotConstants = new ArrayList<>();
LocalDateTime current = selectedDate.atTime(7, 0, 0);
while (current.isBefore(selectedDate.atTime(21, 0, 0))) {
if(current.isBefore(LocalDateTime.now())) {
current = current.plusHours(2);
continue;
}
listSlotConstants.add(new SlotDTO(current, current.plusHours(2)));
current = current.plusHours(2);
}
if(roomIds == null || roomIds.isEmpty()) {
return listSlotConstants;
}
for (Integer roomId : roomIds) {
List<SlotDTO> listSlotDateTime = roomRepository.getSlotsByRoomAndDate(roomId, startTime, endTime);
listSlotConstants.removeAll(listSlotDateTime);
}
return listSlotConstants;
}
}