1 | package com.example.rezevirajmasa.demo.service.impl;
|
---|
2 |
|
---|
3 | import com.example.rezevirajmasa.demo.dto.PreorderedItemDto;
|
---|
4 | import com.example.rezevirajmasa.demo.dto.ReservationDTO;
|
---|
5 | import com.example.rezevirajmasa.demo.mappers.UserMapper;
|
---|
6 | import com.example.rezevirajmasa.demo.model.*;
|
---|
7 | import com.example.rezevirajmasa.demo.model.exceptions.InvalidReservationException;
|
---|
8 | import com.example.rezevirajmasa.demo.model.exceptions.InvalidReservationIdException;
|
---|
9 | import com.example.rezevirajmasa.demo.repository.ReservationRepository;
|
---|
10 | import com.example.rezevirajmasa.demo.repository.TableRepository;
|
---|
11 | import com.example.rezevirajmasa.demo.service.MenuService;
|
---|
12 | import com.example.rezevirajmasa.demo.service.ReservationHistoryService;
|
---|
13 | import com.example.rezevirajmasa.demo.service.ReservationService;
|
---|
14 | import com.example.rezevirajmasa.demo.service.UserService;
|
---|
15 | import org.springframework.beans.factory.annotation.Autowired;
|
---|
16 | import org.springframework.context.annotation.Lazy;
|
---|
17 | import org.springframework.stereotype.Service;
|
---|
18 |
|
---|
19 | import java.time.LocalDateTime;
|
---|
20 | import java.util.ArrayList;
|
---|
21 | import java.util.List;
|
---|
22 | import java.util.Optional;
|
---|
23 |
|
---|
24 | @Service
|
---|
25 | public class ReservationImpl implements ReservationService {
|
---|
26 |
|
---|
27 | @Autowired
|
---|
28 | private TableRepository tableRepository;
|
---|
29 | @Autowired
|
---|
30 | private ReservationHistoryService reservationHistoryService;
|
---|
31 | private final UserMapper userMapper;
|
---|
32 | @Autowired
|
---|
33 | private UserService userService;
|
---|
34 | @Autowired
|
---|
35 | private ReservationRepository reservationRepository;
|
---|
36 | @Autowired
|
---|
37 | @Lazy
|
---|
38 | private MenuService menuService;
|
---|
39 |
|
---|
40 | public ReservationImpl(UserMapper userMapper) {
|
---|
41 | this.userMapper = userMapper;
|
---|
42 | }
|
---|
43 |
|
---|
44 | @Override
|
---|
45 | public Reservation findById(Long id) {
|
---|
46 | return reservationRepository.findById(id).orElseThrow(InvalidReservationIdException::new);
|
---|
47 | }
|
---|
48 |
|
---|
49 | @Override
|
---|
50 | public Reservation makeReservationRest(ReservationDTO reservationDTO, User user, Restaurant restaurant) {
|
---|
51 | Reservation reservation = new Reservation();
|
---|
52 |
|
---|
53 | Optional<TableEntity> optionalTable = tableRepository.findById(reservationDTO.getTableNumber());
|
---|
54 |
|
---|
55 | if (optionalTable.isPresent()) {
|
---|
56 | TableEntity table = optionalTable.get();
|
---|
57 |
|
---|
58 | LocalDateTime startTime = reservationDTO.getReservationDateTime().plusHours(1);
|
---|
59 | LocalDateTime endTime = reservationDTO.getReservationDateTime().plusHours(3);
|
---|
60 |
|
---|
61 | boolean hasConflict = table.getReservations().stream()
|
---|
62 | .anyMatch(existingReservation -> {
|
---|
63 | LocalDateTime existingStartTime = existingReservation.getCheckInTime();
|
---|
64 | LocalDateTime existingEndTime = existingReservation.getCheckOutTime();
|
---|
65 |
|
---|
66 | boolean scenario1 = existingStartTime.isBefore(startTime) && existingEndTime.isAfter(startTime);
|
---|
67 |
|
---|
68 | boolean scenario2 = existingStartTime.isBefore(endTime) && existingEndTime.isAfter(startTime);
|
---|
69 |
|
---|
70 | boolean scenario3 = existingStartTime.isAfter(startTime) && existingEndTime.isBefore(endTime);
|
---|
71 |
|
---|
72 | boolean scenario4 = existingStartTime.isBefore(startTime) && existingEndTime.isAfter(endTime);
|
---|
73 |
|
---|
74 | return scenario1 || scenario2 || scenario3 || scenario4;
|
---|
75 | });
|
---|
76 | if (hasConflict) {
|
---|
77 | throw new InvalidReservationException("Unsuccessful reservation -> time slot not available");
|
---|
78 | }
|
---|
79 |
|
---|
80 | reservation.setTable(table);
|
---|
81 | reservation.setReservationDateTime(LocalDateTime.now());
|
---|
82 | reservation.setSpecialRequests(reservationDTO.getSpecialRequests());
|
---|
83 | reservation.setPartySize(reservationDTO.getPartySize());
|
---|
84 | reservation.setReservationStatus(reservationDTO.getStatus() != null ? reservationDTO.getStatus() : "Pending");
|
---|
85 | reservation.setPaymentStatus(reservationDTO.getPaymentStatus() != null ? reservationDTO.getPaymentStatus() : "Unpaid");
|
---|
86 | reservation.setUser(user);
|
---|
87 |
|
---|
88 | List<PreorderedItem> preOrderedItems = new ArrayList<>();
|
---|
89 |
|
---|
90 | for (PreorderedItemDto dtoItem : reservationDTO.getPreOrderedItems()) {
|
---|
91 | PreorderedItem item = new PreorderedItem();
|
---|
92 | item.setPreorderedItemName(dtoItem.getPreorderedItemName());
|
---|
93 | item.setQuantity(dtoItem.getQuantity());
|
---|
94 | item.setPrice(dtoItem.getPrice());
|
---|
95 | item.setReservation(reservation);
|
---|
96 |
|
---|
97 | Menu menu = menuService.getMenuById(dtoItem.getMenuID());
|
---|
98 | item.setMenu(menu);
|
---|
99 |
|
---|
100 | preOrderedItems.add(item);
|
---|
101 | }
|
---|
102 |
|
---|
103 | reservation.setPreOrderedItems(preOrderedItems);
|
---|
104 | reservation.setRestaurant(restaurant);
|
---|
105 | reservation.setCheckInTime(reservationDTO.getReservationDateTime().plusHours(1));
|
---|
106 | reservation.setReservationDateTime(LocalDateTime.now());
|
---|
107 | reservation.setCheckOutTime(reservationDTO.getReservationDateTime().plusHours(3));
|
---|
108 |
|
---|
109 | return reservationRepository.save(reservation);
|
---|
110 | } else {
|
---|
111 | throw new InvalidReservationException("Invalid table number -> table not found");
|
---|
112 | }
|
---|
113 | }
|
---|
114 |
|
---|
115 | @Override
|
---|
116 | public Reservation updateReservation(Long reservationId, ReservationDTO reservationDTO, User user) {
|
---|
117 | Reservation existingReservation = findById(reservationId);
|
---|
118 |
|
---|
119 | if (!existingReservation.getCheckInTime().equals(reservationDTO.getReservationDateTime())) {
|
---|
120 | TableEntity table = existingReservation.getTable();
|
---|
121 | table.removeReservation(existingReservation);
|
---|
122 |
|
---|
123 | LocalDateTime newStartTime = reservationDTO.getReservationDateTime().minusHours(2);
|
---|
124 | LocalDateTime newEndTime = reservationDTO.getReservationDateTime().plusHours(2);
|
---|
125 | boolean hasConflict = table.getReservations().stream()
|
---|
126 | .anyMatch(r -> r.getCheckInTime().isAfter(newStartTime) && r.getCheckInTime().isBefore(newEndTime));
|
---|
127 |
|
---|
128 | if (hasConflict) {
|
---|
129 | throw new InvalidReservationException("New time slot is not available.");
|
---|
130 | }
|
---|
131 |
|
---|
132 | table.addReservation(existingReservation);
|
---|
133 | }
|
---|
134 |
|
---|
135 | existingReservation.setCheckInTime(reservationDTO.getReservationDateTime());
|
---|
136 | existingReservation.setCheckOutTime(reservationDTO.getReservationDateTime().plusHours(2));
|
---|
137 | existingReservation.setReservationDateTime(LocalDateTime.now());
|
---|
138 | existingReservation.setPartySize(reservationDTO.getPartySize());
|
---|
139 | existingReservation.setSpecialRequests(reservationDTO.getSpecialRequests());
|
---|
140 | existingReservation.setReservationStatus(reservationDTO.getStatus() != null ? reservationDTO.getStatus() : existingReservation.getReservationStatus());
|
---|
141 | existingReservation.setPaymentStatus(reservationDTO.getPaymentStatus() != null ? reservationDTO.getPaymentStatus() : existingReservation.getPaymentStatus());
|
---|
142 |
|
---|
143 | return reservationRepository.save(existingReservation);
|
---|
144 | }
|
---|
145 |
|
---|
146 | @Override
|
---|
147 | public List<Reservation> listAll() {
|
---|
148 | return reservationRepository.findAll();
|
---|
149 | }
|
---|
150 |
|
---|
151 | @Override
|
---|
152 | public List<Reservation> reservationsForTable(TableEntity table) {
|
---|
153 | return reservationRepository.findAllByTableAndCheckInTime(table, LocalDateTime.now());
|
---|
154 | }
|
---|
155 |
|
---|
156 | @Override
|
---|
157 | public Reservation getReservationById(Long reservationId) {
|
---|
158 | return reservationRepository.findById(reservationId).orElseThrow(InvalidReservationIdException::new);
|
---|
159 | }
|
---|
160 |
|
---|
161 | @Override
|
---|
162 | public boolean cancelReservation(Long reservationId) {
|
---|
163 | Optional<Reservation> optionalReservation = reservationRepository.findById(reservationId);
|
---|
164 | if (optionalReservation.isPresent()) {
|
---|
165 | Reservation reservation = optionalReservation.get();
|
---|
166 | TableEntity table = reservation.getTable();
|
---|
167 |
|
---|
168 | table.removeReservation(reservation);
|
---|
169 |
|
---|
170 | reservationHistoryService.moveReservationToHistory(reservation, "Canceled", "Canceled by user");
|
---|
171 | reservationRepository.delete(reservation);
|
---|
172 |
|
---|
173 | return true;
|
---|
174 | } else {
|
---|
175 | return false;
|
---|
176 | }
|
---|
177 | }
|
---|
178 |
|
---|
179 | @Override
|
---|
180 | public List<Reservation> findReservationByUser(User user) {
|
---|
181 | LocalDateTime now = LocalDateTime.now();
|
---|
182 | return reservationRepository.findAllByUserAndCheckInTimeAfter(user, now);
|
---|
183 | }
|
---|
184 |
|
---|
185 | @Override
|
---|
186 | public List<Reservation> findAllByUser(User user) {
|
---|
187 | return reservationRepository.findAllByUser(user);
|
---|
188 | }
|
---|
189 |
|
---|
190 | @Override
|
---|
191 | public List<Reservation> findReservationsByUserPast(User user) {
|
---|
192 | LocalDateTime now = LocalDateTime.now();
|
---|
193 | return reservationRepository.findAllByUserAndCheckInTimeBefore(user, now);
|
---|
194 | }
|
---|
195 |
|
---|
196 | @Override
|
---|
197 | public List<Reservation> findReservationsByTableAndDateRange(TableEntity table, LocalDateTime startDateTime, LocalDateTime endDateTime) {
|
---|
198 | return reservationRepository.findByTableAndCheckInTimeBetween(table, startDateTime, endDateTime);
|
---|
199 | }
|
---|
200 |
|
---|
201 | @Override
|
---|
202 | public void findReservationsToMove() {
|
---|
203 | List<Reservation> pastReservations = reservationRepository.findAllByCheckInTimeBefore(LocalDateTime.now());
|
---|
204 | for(Reservation reservation : pastReservations) {
|
---|
205 | reservationHistoryService.moveReservationToHistory(reservation, "successful", "/");
|
---|
206 | reservationRepository.delete(reservation);
|
---|
207 | }
|
---|
208 | }
|
---|
209 |
|
---|
210 | @Override
|
---|
211 | public void deleteReservation(Long reservationID) {
|
---|
212 | Reservation reservation = findById(reservationID);
|
---|
213 | reservationRepository.delete(reservation);
|
---|
214 | }
|
---|
215 |
|
---|
216 | @Override
|
---|
217 | public List<Reservation> findAllByRestaurant(Restaurant restaurant) {
|
---|
218 | return reservationRepository.findAllByRestaurantAndCheckInTimeAfter(restaurant, LocalDateTime.now());
|
---|
219 | }
|
---|
220 | }
|
---|