From bd483bb28195b9356ebf9d31a4e446e6459b8a41 Mon Sep 17 00:00:00 2001 From: HuyDiCode Date: Wed, 30 Oct 2024 21:53:19 +0700 Subject: [PATCH 1/4] [PBS-43][HuyNBQ] feat: finish getRoomsByTypeAndDate api --- .../PodBookingSystem/controller/RoomController.java | 9 +++++++++ .../PodBookingSystem/repository/RoomRepository.java | 11 +++++++++++ .../com/swp/PodBookingSystem/service/RoomService.java | 6 ++++++ 3 files changed, 26 insertions(+) diff --git a/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java b/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java index 9890646f..ccc0063f 100644 --- a/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java +++ b/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java @@ -6,6 +6,7 @@ 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.Calendar.SlotDTO; import com.swp.PodBookingSystem.dto.respone.PaginationResponse; import com.swp.PodBookingSystem.dto.respone.Room.BookedRoomDto; import com.swp.PodBookingSystem.dto.respone.Room.RoomResponse; @@ -164,4 +165,12 @@ ApiResponse countCurrentlyServedRooms() { .data(roomService.countCurrentlyServedRooms()) .build(); } + @GetMapping("/available-by-type-and-date") + ApiResponse> getAvailableRoomsByRoomTypeId(@RequestParam Integer typeId, @RequestParam String date) { + LocalDate selectedDate = LocalDate.parse(date); + return ApiResponse.>builder() + .data(roomService.getRoomsByTypeAndDate(typeId, selectedDate)) + .message("Get rooms by typeId and date successfully") + .build(); + } } diff --git a/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java b/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java index c09cb37b..5847af0e 100644 --- a/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java +++ b/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java @@ -62,4 +62,15 @@ List 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 od.startTime >= :startTime " + + "AND od.endTime <= :endTime " + + "And od.status = com.swp.PodBookingSystem.enums.OrderStatus.Successfully " + ) + List getRoomsByTypeAndDate(@Param("typeId") Integer typeId, + @Param("startTime") LocalDateTime startTime, + @Param("endTime") LocalDateTime endTime); } diff --git a/src/main/java/com/swp/PodBookingSystem/service/RoomService.java b/src/main/java/com/swp/PodBookingSystem/service/RoomService.java index 7e272b45..8861d5f3 100644 --- a/src/main/java/com/swp/PodBookingSystem/service/RoomService.java +++ b/src/main/java/com/swp/PodBookingSystem/service/RoomService.java @@ -215,4 +215,10 @@ public List getBookedRooms(String customerId) { public int countCurrentlyServedRooms() { return roomRepository.countCurrentlyServedRooms(LocalDateTime.now()); } + + public List getRoomsByTypeAndDate(Integer typeId, LocalDate date) { + LocalDateTime startTime = date.atStartOfDay(); + LocalDateTime endTime = date.atTime(23, 59, 59); + return roomRepository.getRoomsByTypeAndDate(typeId, startTime, endTime); + } } From 341dcfe853c1bbf20a37f6dd97610b75472dc869 Mon Sep 17 00:00:00 2001 From: HuyDiCode Date: Thu, 31 Oct 2024 17:05:10 +0700 Subject: [PATCH 2/4] [PBS-43][HuyNBQ] feat: finish api to get slot filter by rooms and date --- .../controller/RoomController.java | 13 +++++++++++- .../repository/RoomRepository.java | 14 +++++++++++++ .../PodBookingSystem/service/RoomService.java | 20 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java b/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java index ccc0063f..d9e43a3c 100644 --- a/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java +++ b/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java @@ -166,11 +166,22 @@ ApiResponse countCurrentlyServedRooms() { .build(); } @GetMapping("/available-by-type-and-date") - ApiResponse> getAvailableRoomsByRoomTypeId(@RequestParam Integer typeId, @RequestParam String date) { + ApiResponse> getRoomsByTypeAndDate(@RequestParam Integer typeId, @RequestParam String date) { LocalDate selectedDate = LocalDate.parse(date); return ApiResponse.>builder() .data(roomService.getRoomsByTypeAndDate(typeId, selectedDate)) .message("Get rooms by typeId and date successfully") .build(); } + + @GetMapping("/slots-by-rooms-and-date") + ApiResponse> getSlotsByRoomsAndDate(@RequestParam List roomIds, @RequestParam String date) { + LocalDate selectedDate = LocalDate.parse(date); + return ApiResponse.>builder() + .data(roomService.getSlotsByRoomsAndDate(roomIds, selectedDate)) + .message("Get slots by rooms and date successfully") + .build(); + } + + } diff --git a/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java b/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java index 5847af0e..48871bce 100644 --- a/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java +++ b/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java @@ -1,5 +1,6 @@ package com.swp.PodBookingSystem.repository; +import com.swp.PodBookingSystem.dto.request.Slot.SlotCreationRequest; import com.swp.PodBookingSystem.dto.respone.Room.BookedRoomDto; import com.swp.PodBookingSystem.entity.OrderDetail; import com.swp.PodBookingSystem.entity.Room; @@ -66,6 +67,7 @@ List findRoomAvailabilityWithinDateRange( @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 " @@ -73,4 +75,16 @@ List findRoomAvailabilityWithinDateRange( List getRoomsByTypeAndDate(@Param("typeId") Integer typeId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); + + @Query("SELECT DISTINCT NEW com.swp.PodBookingSystem.dto.request.Slot.SlotCreationRequest(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) " + + "ORDER BY od.startTime" + ) + List getSlotsByRoomAndDate(Integer roomId, LocalDateTime startTime, LocalDateTime endTime); } diff --git a/src/main/java/com/swp/PodBookingSystem/service/RoomService.java b/src/main/java/com/swp/PodBookingSystem/service/RoomService.java index 8861d5f3..9d710d13 100644 --- a/src/main/java/com/swp/PodBookingSystem/service/RoomService.java +++ b/src/main/java/com/swp/PodBookingSystem/service/RoomService.java @@ -221,4 +221,24 @@ public List getRoomsByTypeAndDate(Integer typeId, LocalDate date) { LocalDateTime endTime = date.atTime(23, 59, 59); return roomRepository.getRoomsByTypeAndDate(typeId, startTime, endTime); } + + public List getSlotsByRoomsAndDate(List roomIds, LocalDate selectedDate) { + LocalDateTime startTime = LocalDateTime.now().toLocalDate().equals(selectedDate) ? LocalDateTime.now() : selectedDate.atStartOfDay(); + LocalDateTime endTime = selectedDate.atTime(23, 59, 59); + List 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 SlotCreationRequest(current, current.plusHours(2))); + current = current.plusHours(2); + } + for (Integer roomId : roomIds) { + List listSlotDateTime = roomRepository.getSlotsByRoomAndDate(roomId, startTime, endTime); + listSlotConstants.removeAll(listSlotDateTime); + } + return listSlotConstants; + } } From ab7c801ab0540b9bab738b1f1b76946d471e873c Mon Sep 17 00:00:00 2001 From: Huynh Nguyen Date: Thu, 31 Oct 2024 21:09:04 +0700 Subject: [PATCH 3/4] [NguyenHCP] feat: send order to mail of customer --- .../controller/AccountController.java | 13 ++ .../request/Account/SendMailOrderRequest.java | 14 +++ .../service/SendEmailService.java | 58 +++++++++ .../resources/templates/emailTemplate.html | 118 ++++++++++++++++++ 4 files changed, 203 insertions(+) create mode 100644 src/main/java/com/swp/PodBookingSystem/dto/request/Account/SendMailOrderRequest.java create mode 100644 src/main/resources/templates/emailTemplate.html diff --git a/src/main/java/com/swp/PodBookingSystem/controller/AccountController.java b/src/main/java/com/swp/PodBookingSystem/controller/AccountController.java index d262a980..8c73fe05 100644 --- a/src/main/java/com/swp/PodBookingSystem/controller/AccountController.java +++ b/src/main/java/com/swp/PodBookingSystem/controller/AccountController.java @@ -6,6 +6,7 @@ import com.swp.PodBookingSystem.dto.respone.Account.AccountOrderResponse; import com.swp.PodBookingSystem.dto.respone.ApiResponse; import com.swp.PodBookingSystem.dto.respone.AccountResponse; +import com.swp.PodBookingSystem.dto.respone.Order.OrderManagementResponse; import com.swp.PodBookingSystem.dto.respone.PaginationResponse; import com.swp.PodBookingSystem.entity.Account; import com.swp.PodBookingSystem.enums.AccountRole; @@ -13,6 +14,7 @@ import com.swp.PodBookingSystem.exception.ErrorCode; import com.swp.PodBookingSystem.mapper.AccountMapper; import com.swp.PodBookingSystem.service.AccountService; +import com.swp.PodBookingSystem.service.OrderService; import com.swp.PodBookingSystem.service.SendEmailService; import jakarta.mail.MessagingException; import jakarta.servlet.http.HttpServletRequest; @@ -45,6 +47,7 @@ public class AccountController { AccountMapper accountMapper; SendEmailService sendEmailService; JwtDecoder jwtDecoder; + OrderService orderService; @PostMapping ApiResponse createAccount(@RequestBody @Valid AccountCreationRequest request) { @@ -124,6 +127,16 @@ ApiResponse sendEmail(@RequestBody SendMailRequest request) throws MessagingExce .build(); } + @PostMapping("/send-email-order") + ApiResponse sendEmailOrder(@RequestBody SendMailOrderRequest request) throws MessagingException, IOException { + OrderManagementResponse order = orderService.getInfoOrder(request.getOrderId()); + sendEmailService.sendMailTemplate(request.getEmail(), order, "Hóa đơn tại FlexiPod"); + return ApiResponse.builder() + .message("Gửi lời mời đặt lịch thành công") + .code(200) + .build(); + } + @GetMapping("/staff") public ResponseEntity> getAllStaffAccounts() { return ResponseEntity.status(HttpStatus.OK).body(accountService.getAllStaffAccounts()); diff --git a/src/main/java/com/swp/PodBookingSystem/dto/request/Account/SendMailOrderRequest.java b/src/main/java/com/swp/PodBookingSystem/dto/request/Account/SendMailOrderRequest.java new file mode 100644 index 00000000..fb744d04 --- /dev/null +++ b/src/main/java/com/swp/PodBookingSystem/dto/request/Account/SendMailOrderRequest.java @@ -0,0 +1,14 @@ +package com.swp.PodBookingSystem.dto.request.Account; + +import lombok.*; +import lombok.experimental.FieldDefaults; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@FieldDefaults(level = AccessLevel.PRIVATE) +public class SendMailOrderRequest { + String email; + String orderId; +} diff --git a/src/main/java/com/swp/PodBookingSystem/service/SendEmailService.java b/src/main/java/com/swp/PodBookingSystem/service/SendEmailService.java index abee8e57..dd4028ed 100644 --- a/src/main/java/com/swp/PodBookingSystem/service/SendEmailService.java +++ b/src/main/java/com/swp/PodBookingSystem/service/SendEmailService.java @@ -6,6 +6,7 @@ import biweekly.property.Method; import biweekly.util.Duration; import com.swp.PodBookingSystem.dto.request.CalendarRequest; +import com.swp.PodBookingSystem.dto.respone.Order.OrderManagementResponse; import com.swp.PodBookingSystem.entity.OrderDetail; import jakarta.activation.DataHandler; import jakarta.activation.DataSource; @@ -21,18 +22,25 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ClassPathResource; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -57,6 +65,56 @@ public void sendEmail(String recipient, String body, String subject) throws Mess helper.setSubject(subject); helper.setText(body, true); + javaMailSender.send(mimeMessage); + } + + public void sendMailTemplate(String recipient, OrderManagementResponse order, String subject) throws MessagingException, IOException { + MimeMessage mimeMessage = javaMailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8"); + ClassPathResource resource = new ClassPathResource("templates/emailTemplate.html"); + String content; + try (var inputStream = resource.getInputStream()) { + content = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + } + var roomHaveAmenities = order.getOrderDetails().stream() + .filter(od -> !od.getAmenities().isEmpty()) + .collect(Collectors.toList()); + double totalPriceRoom = order.getOrderDetails().stream() + .mapToDouble(orderDetail -> orderDetail.getRoomPrice()) + .sum(); + double totalPriceAmenity = order.getOrderDetails().stream() + .mapToDouble(orderDetail -> orderDetail.getAmenities().stream() + .mapToDouble(amenity -> amenity.getPrice() * amenity.getQuantity()) + .sum() + ) + .sum(); + + double priceBeforeDiscount = totalPriceRoom + totalPriceAmenity; + double discountPercentage = order.getOrderDetails().get(0).getServicePackage().getDiscountPercentage(); + double finalPrice = priceBeforeDiscount * (1 - discountPercentage / 100); + int integerAmount = (int) Math.round(finalPrice); + String formattedAmount = String.format("%,d", integerAmount).replace(",", "."); + String status; + if (order.getOrderDetails().getFirst().getStatus().equals("Successfully")) { + status = "Đã thanh toán"; + } else if (order.getOrderDetails().getFirst().getStatus().equals("Rejected")) { + status = "Đã hủy"; + } else { + status = "Đang chờ xử lí"; + } + + content = content.replace("{{orderId}}", order.getId()) + .replace("{{orderStartTime}}", order.getCreatedAt().format(DateTimeFormatter.ofPattern("HH:mm:ss dd-MM-yyyy"))) + .replace("{{roomName}}", order.getOrderDetails().getFirst().getRoomTypeName()) + .replace("{{status}}", status) + .replace("{{amenity}}", roomHaveAmenities.isEmpty() ? "Không có" : "Có") + .replace("{{totalPrice}}", formattedAmount + " VND"); + + helper.setFrom(fromEmailId); + helper.setTo(recipient); + helper.setSubject(subject); + helper.setText(content, true); + javaMailSender.send(mimeMessage); log.info("Send email successfully"); } diff --git a/src/main/resources/templates/emailTemplate.html b/src/main/resources/templates/emailTemplate.html new file mode 100644 index 00000000..f2d11a97 --- /dev/null +++ b/src/main/resources/templates/emailTemplate.html @@ -0,0 +1,118 @@ + + + + + + FlexiPod Email + + + + + + + +
+ + + + + +
+

FlexiPod

+
+ + + + + + +
+

Hóa đơn của bạn tại + FlexiPod

+

+ Mã đơn: {{orderId}} +

+

+ Ngày đặt: {{orderStartTime}} +

+

+ Trạng thái: {{status}} +

+

+ Loại phòng đặt: {{roomName}} +

+

+ Tiện tích đặt thêm: {{amenity}} +

+

+ Tổng tiền: {{totalPrice}} +

+

+ Cảm ơn vì đã chọn FlexiPod! +

+
+ + + + + + + +
+ + + + + + + +
+ FlexiPod +
Copyright © 2024
+
+ Điều khoản và chính sách + Liên hệ + +
+
+ + From 5bd79a79c04b77435254aa19ccf11ee6e25978ac Mon Sep 17 00:00:00 2001 From: HuyDiCode Date: Thu, 31 Oct 2024 22:22:33 +0700 Subject: [PATCH 4/4] [PBS-43][HuyNBQ] refactor: fix logic getUnavailable api and getRoomsByTypeAndDate api --- .../configuration/SecurityConfig.java | 4 +- .../controller/RoomController.java | 32 ++--- .../dto/request/Room/RoomAvailabilityDTO.java | 6 +- .../Calendar => request/Slot}/SlotDTO.java | 4 +- .../dto/respone/Calendar/RoomDTO.java | 3 +- .../Calendar/SlotCustomDTO.java} | 6 +- .../repository/RoomRepository.java | 19 ++- .../PodBookingSystem/service/RoomService.java | 126 ++++++++---------- 8 files changed, 92 insertions(+), 108 deletions(-) rename src/main/java/com/swp/PodBookingSystem/dto/{respone/Calendar => request/Slot}/SlotDTO.java (77%) rename src/main/java/com/swp/PodBookingSystem/dto/{request/Slot/SlotCreationRequest.java => respone/Calendar/SlotCustomDTO.java} (69%) diff --git a/src/main/java/com/swp/PodBookingSystem/configuration/SecurityConfig.java b/src/main/java/com/swp/PodBookingSystem/configuration/SecurityConfig.java index 27aa8a7f..fe500f69 100644 --- a/src/main/java/com/swp/PodBookingSystem/configuration/SecurityConfig.java +++ b/src/main/java/com/swp/PodBookingSystem/configuration/SecurityConfig.java @@ -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 = { diff --git a/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java b/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java index d9e43a3c..e3bf6a38 100644 --- a/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java +++ b/src/main/java/com/swp/PodBookingSystem/controller/RoomController.java @@ -1,12 +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.Calendar.SlotDTO; import com.swp.PodBookingSystem.dto.respone.PaginationResponse; import com.swp.PodBookingSystem.dto.respone.Room.BookedRoomDto; import com.swp.PodBookingSystem.dto.respone.Room.RoomResponse; @@ -88,13 +86,13 @@ PaginationResponse> getFilteredRoom(@RequestParam(required = false) S @GetMapping("/available-rooms") ApiResponse> getAvailableRoomsByRoomTypeId(@RequestParam Integer typeId, @RequestParam(required = false) List slots) { - List slotList = new ArrayList<>(); + List 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.>builder() @@ -103,24 +101,13 @@ ApiResponse> getAvailableRoomsByRoomTypeId(@RequestParam Integer typ .build(); } - @GetMapping("/calendar") - ApiResponse> getCalendar(@RequestParam List roomIds, - @RequestParam(required = false) Integer servicePackageId, - @RequestParam LocalDate selectedDate, - @RequestParam List slots - ) { - return ApiResponse.>builder() - .data(roomService.getCalendar(roomIds,servicePackageId,selectedDate,slots)) - .message("Get calendar successfully") - .build(); - } - @GetMapping("/unavailable") - ApiResponse> getUnavailableRooms(@RequestParam LocalDateTime startTime, + ApiResponse> getUnavailableRooms(@RequestParam List roomIds, + @RequestParam LocalDateTime startTime, @RequestParam LocalDateTime endTime ) { return ApiResponse.>builder() - .data(roomService.getUnavailableRooms(startTime,endTime)) + .data(roomService.getUnavailableRooms(roomIds,startTime,endTime)) .message("Get unavailable rooms successfully") .build(); } @@ -175,10 +162,9 @@ ApiResponse> getRoomsByTypeAndDate(@RequestParam Integer typeId, @Re } @GetMapping("/slots-by-rooms-and-date") - ApiResponse> getSlotsByRoomsAndDate(@RequestParam List roomIds, @RequestParam String date) { - LocalDate selectedDate = LocalDate.parse(date); - return ApiResponse.>builder() - .data(roomService.getSlotsByRoomsAndDate(roomIds, selectedDate)) + ApiResponse> getSlotsByRoomsAndDate(@RequestParam(required = false) List roomIds, @RequestParam(required = false) String date) { + return ApiResponse.>builder() + .data(roomService.getSlotsByRoomsAndDate(roomIds, date)) .message("Get slots by rooms and date successfully") .build(); } diff --git a/src/main/java/com/swp/PodBookingSystem/dto/request/Room/RoomAvailabilityDTO.java b/src/main/java/com/swp/PodBookingSystem/dto/request/Room/RoomAvailabilityDTO.java index 5cbc836a..373a8a9b 100644 --- a/src/main/java/com/swp/PodBookingSystem/dto/request/Room/RoomAvailabilityDTO.java +++ b/src/main/java/com/swp/PodBookingSystem/dto/request/Room/RoomAvailabilityDTO.java @@ -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 @@ -13,6 +14,5 @@ public class RoomAvailabilityDTO { Integer roomId; String name; - LocalDateTime startTime; - LocalDateTime endTime; + List slots; } diff --git a/src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/SlotDTO.java b/src/main/java/com/swp/PodBookingSystem/dto/request/Slot/SlotDTO.java similarity index 77% rename from src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/SlotDTO.java rename to src/main/java/com/swp/PodBookingSystem/dto/request/Slot/SlotDTO.java index 2aeafe17..b106bb1b 100644 --- a/src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/SlotDTO.java +++ b/src/main/java/com/swp/PodBookingSystem/dto/request/Slot/SlotDTO.java @@ -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 @@ -13,5 +12,4 @@ public class SlotDTO { LocalDateTime startTime; LocalDateTime endTime; - boolean available; } diff --git a/src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/RoomDTO.java b/src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/RoomDTO.java index 29f47162..82a100da 100644 --- a/src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/RoomDTO.java +++ b/src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/RoomDTO.java @@ -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; @@ -14,5 +13,5 @@ public class RoomDTO { int roomId; String roomName; - List slots; + List slots; } diff --git a/src/main/java/com/swp/PodBookingSystem/dto/request/Slot/SlotCreationRequest.java b/src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/SlotCustomDTO.java similarity index 69% rename from src/main/java/com/swp/PodBookingSystem/dto/request/Slot/SlotCreationRequest.java rename to src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/SlotCustomDTO.java index 5492f624..e898da45 100644 --- a/src/main/java/com/swp/PodBookingSystem/dto/request/Slot/SlotCreationRequest.java +++ b/src/main/java/com/swp/PodBookingSystem/dto/respone/Calendar/SlotCustomDTO.java @@ -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; } diff --git a/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java b/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java index 48871bce..60038b0e 100644 --- a/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java +++ b/src/main/java/com/swp/PodBookingSystem/repository/RoomRepository.java @@ -1,6 +1,6 @@ package com.swp.PodBookingSystem.repository; -import com.swp.PodBookingSystem.dto.request.Slot.SlotCreationRequest; +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; @@ -70,21 +70,28 @@ List findRoomAvailabilityWithinDateRange( "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 " + "AND (od.status = com.swp.PodBookingSystem.enums.OrderStatus.Successfully " + + "OR od.status = com.swp.PodBookingSystem.enums.OrderStatus.Pending) " ) List getRoomsByTypeAndDate(@Param("typeId") Integer typeId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); - @Query("SELECT DISTINCT NEW com.swp.PodBookingSystem.dto.request.Slot.SlotCreationRequest(od.startTime,od.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) " + - "ORDER BY od.startTime" + "OR od.status = com.swp.PodBookingSystem.enums.OrderStatus.Pending) " ) - List getSlotsByRoomAndDate(Integer roomId, LocalDateTime startTime, LocalDateTime endTime); + List 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 findAllByTypeId(@Param("typeId") Integer typeId); } diff --git a/src/main/java/com/swp/PodBookingSystem/service/RoomService.java b/src/main/java/com/swp/PodBookingSystem/service/RoomService.java index 9d710d13..23d5be73 100644 --- a/src/main/java/com/swp/PodBookingSystem/service/RoomService.java +++ b/src/main/java/com/swp/PodBookingSystem/service/RoomService.java @@ -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; @@ -29,7 +25,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -86,13 +81,13 @@ public boolean isRoomAvailable(Integer roomId, LocalDateTime startTime, LocalDat return roomRepository.isRoomAvailable(roomId, startTime, endTime); } - public List getRoomByTypeAndSlot(Integer typeId,List slots ) { + public List getRoomByTypeAndSlot(Integer typeId,List slots ) { List roomList = roomRepository.findRoomsByTypeId(typeId); List 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; @@ -144,64 +139,27 @@ public String deleteRoom(int roomId) { return "Delete room " + roomId + " successfully"; } - public List getCalendar(List roomIds, Integer servicePackageId, LocalDate selectedDate, List slots) - { - List response = new ArrayList<>(); - List 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 getUnavailableRooms(List roomIds,LocalDateTime startTime, LocalDateTime endTime) { + if(roomIds == null || roomIds.isEmpty()) { + return new ArrayList<>(); } - for(LocalDate date: dates) { - List rooms = roomIds.parallelStream().map(roomId -> { - RoomDTO room = new RoomDTO(); - Optional 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 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 getUnavailableRooms(LocalDateTime startTime, LocalDateTime endTime) { - List 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 roomAvailabilityDTOList = new ArrayList<>(); + for(Integer roomId: roomIds) { + List 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 getBookedRooms(String customerId) { @@ -217,26 +175,58 @@ public int countCurrentlyServedRooms() { } public List getRoomsByTypeAndDate(Integer typeId, LocalDate date) { + List result = new ArrayList<>(); + List 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); - return roomRepository.getRoomsByTypeAndDate(typeId, startTime, endTime); + List rooms =roomRepository.findAllByTypeId(typeId); + for(Room room: rooms) { + List slotList = roomRepository.getSlotsByRoomAndDate(room.getId(), startTime, endTime); + List tmp = new ArrayList<>(listSlotConstants); + tmp.removeAll(slotList); + if(!tmp.isEmpty()) { + result.add(room); + } + } + + return result; } - public List getSlotsByRoomsAndDate(List roomIds, LocalDate selectedDate) { + public List getSlotsByRoomsAndDate(List 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 listSlotConstants = new ArrayList<>(); + List 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 SlotCreationRequest(current, current.plusHours(2))); + listSlotConstants.add(new SlotDTO(current, current.plusHours(2))); current = current.plusHours(2); } + if(roomIds == null || roomIds.isEmpty()) { + return listSlotConstants; + } for (Integer roomId : roomIds) { - List listSlotDateTime = roomRepository.getSlotsByRoomAndDate(roomId, startTime, endTime); + List listSlotDateTime = roomRepository.getSlotsByRoomAndDate(roomId, startTime, endTime); listSlotConstants.removeAll(listSlotDateTime); } return listSlotConstants;