11package ru .practicum .shareit .booking .service ;
22
33import lombok .RequiredArgsConstructor ;
4+ import org .springframework .data .domain .Sort ;
45import org .springframework .stereotype .Service ;
6+ import ru .practicum .shareit .booking .dto .*;
57import ru .practicum .shareit .booking .model .Booking ;
68import ru .practicum .shareit .booking .model .BookingStatus ;
7- import ru .practicum .shareit .booking .dto .BookingCreateRequest ;
8- import ru .practicum .shareit .booking .dto .BookingResponseDto ;
9- import ru .practicum .shareit .booking .dto .BookingUpdateRequest ;
10- import ru .practicum .shareit .booking .dto .BookingMapper ;
11- import ru .practicum .shareit .booking .storage .InMemoryBookingStorage ;
9+ import ru .practicum .shareit .booking .storage .BookingRepository ;
10+ import ru .practicum .shareit .exception .AccessDeniedException ;
1211import ru .practicum .shareit .exception .NotFoundException ;
1312import ru .practicum .shareit .exception .ValidationException ;
14- import ru .practicum .shareit .exception .AccessDeniedException ;
1513import ru .practicum .shareit .item .model .Item ;
16- import ru .practicum .shareit .item .storage .InMemoryItemStorage ;
14+ import ru .practicum .shareit .item .storage .ItemRepository ;
1715import ru .practicum .shareit .user .model .User ;
18- import ru .practicum .shareit .user .storage .InMemoryUserStorage ;
16+ import ru .practicum .shareit .user .storage .UserRepository ;
17+
18+ import java .time .LocalDateTime ;
19+ import java .util .List ;
20+ import java .util .stream .Collectors ;
1921
2022@ Service
2123@ RequiredArgsConstructor
2224public class BookingServiceImpl implements BookingService {
23- private final InMemoryBookingStorage bookingStorage ;
24- private final InMemoryUserStorage userStorage ;
25- private final InMemoryItemStorage itemStorage ;
25+ private final BookingRepository bookingRepository ;
26+ private final UserRepository userRepository ;
27+ private final ItemRepository itemRepository ;
2628
2729 @ Override
2830 public BookingResponseDto createBooking (BookingCreateRequest createRequest , Long bookerId ) {
29- User booker = userStorage .findById (bookerId )
31+ if (createRequest .getEnd ().isBefore (createRequest .getStart ()) || createRequest .getEnd ().equals (createRequest .getStart ())) {
32+ throw new ValidationException ("Дата окончания должна быть после даты начала" );
33+ }
34+
35+ User booker = userRepository .findById (bookerId )
3036 .orElseThrow (() -> new NotFoundException ("Пользователь с id " + bookerId + " не найден" ));
3137
32- Item item = itemStorage .findById (createRequest .getItemId ())
38+ Item item = itemRepository .findById (createRequest .getItemId ())
3339 .orElseThrow (() -> new NotFoundException ("Вещь с id " + createRequest .getItemId () + " не найдена" ));
3440
3541 if (!Boolean .TRUE .equals (item .getAvailable ())) {
@@ -42,25 +48,111 @@ public BookingResponseDto createBooking(BookingCreateRequest createRequest, Long
4248
4349 Booking booking = BookingMapper .fromCreateRequest (createRequest , item , booker );
4450 booking .setStatus (BookingStatus .WAITING );
45- Booking createdBooking = bookingStorage . create (booking );
46- return BookingMapper .toResponseDto (createdBooking );
51+ Booking saved = bookingRepository . save (booking );
52+ return BookingMapper .toResponseDto (saved );
4753 }
4854
4955 @ Override
50- public BookingResponseDto updateBooking (Long bookingId , BookingUpdateRequest updateRequest ) {
51- Booking existingBooking = bookingStorage .findById (bookingId )
56+ public BookingResponseDto getBookingById (Long bookingId , Long userId ) {
57+ Booking booking = bookingRepository .findById (bookingId )
5258 .orElseThrow (() -> new NotFoundException ("Бронирование с id " + bookingId + " не найдено" ));
5359
54- BookingMapper .updateBookingFromRequest (updateRequest , existingBooking );
60+ if (!booking .getBooker ().getId ().equals (userId ) && !booking .getItem ().getOwner ().getId ().equals (userId )) {
61+ throw new AccessDeniedException ("Просмотр бронирования доступен только автору или владельцу вещи" );
62+ }
5563
56- Booking updatedBooking = bookingStorage .update (existingBooking );
57- return BookingMapper .toResponseDto (updatedBooking );
64+ return BookingMapper .toResponseDto (booking );
5865 }
5966
6067 @ Override
61- public BookingResponseDto getBookingById (Long bookingId ) {
62- Booking booking = bookingStorage .findById (bookingId )
68+ public BookingResponseDto approveBooking (Long bookingId , boolean approved , Long userId ) {
69+ Booking booking = bookingRepository .findById (bookingId )
6370 .orElseThrow (() -> new NotFoundException ("Бронирование с id " + bookingId + " не найдено" ));
64- return BookingMapper .toResponseDto (booking );
71+
72+ if (!booking .getItem ().getOwner ().getId ().equals (userId )) {
73+ throw new AccessDeniedException ("Только владелец вещи может подтвердить или отклонить бронирование" );
74+ }
75+
76+ if (booking .getStatus () != BookingStatus .WAITING ) {
77+ throw new ValidationException ("Бронирование уже обработано" );
78+ }
79+
80+ booking .setStatus (approved ? BookingStatus .APPROVED : BookingStatus .REJECTED );
81+ Booking updated = bookingRepository .save (booking );
82+ return BookingMapper .toResponseDto (updated );
83+ }
84+
85+ @ Override
86+ public List <BookingResponseDto > getUserBookings (Long userId , BookingState state ) {
87+ userRepository .findById (userId )
88+ .orElseThrow (() -> new NotFoundException ("Пользователь с id " + userId + " не найден" ));
89+
90+ LocalDateTime now = LocalDateTime .now ();
91+ Sort sort = Sort .by (Sort .Direction .DESC , "start" );
92+ List <Booking > bookings ;
93+
94+ switch (state ) {
95+ case ALL :
96+ bookings = bookingRepository .findByBookerId (userId , sort );
97+ break ;
98+ case CURRENT :
99+ bookings = bookingRepository .findCurrentByBooker (userId , now , sort );
100+ break ;
101+ case PAST :
102+ bookings = bookingRepository .findByBookerIdAndEndBefore (userId , now , sort );
103+ break ;
104+ case FUTURE :
105+ bookings = bookingRepository .findByBookerIdAndStartAfter (userId , now , sort );
106+ break ;
107+ case WAITING :
108+ bookings = bookingRepository .findByBookerIdAndStatus (userId , BookingStatus .WAITING , sort );
109+ break ;
110+ case REJECTED :
111+ bookings = bookingRepository .findByBookerIdAndStatus (userId , BookingStatus .REJECTED , sort );
112+ break ;
113+ default :
114+ throw new IllegalArgumentException ("Неизвестный state: " + state );
115+ }
116+
117+ return bookings .stream ()
118+ .map (BookingMapper ::toResponseDto )
119+ .collect (Collectors .toList ());
120+ }
121+
122+ @ Override
123+ public List <BookingResponseDto > getOwnerBookings (Long ownerId , BookingState state ) {
124+ userRepository .findById (ownerId )
125+ .orElseThrow (() -> new NotFoundException ("Пользователь с id " + ownerId + " не найден" ));
126+
127+ LocalDateTime now = LocalDateTime .now ();
128+ Sort sort = Sort .by (Sort .Direction .DESC , "start" );
129+ List <Booking > bookings ;
130+
131+ switch (state ) {
132+ case ALL :
133+ bookings = bookingRepository .findByItemOwnerId (ownerId , sort );
134+ break ;
135+ case CURRENT :
136+ bookings = bookingRepository .findCurrentByOwner (ownerId , now , sort );
137+ break ;
138+ case PAST :
139+ bookings = bookingRepository .findByItemOwnerIdAndEndBefore (ownerId , now , sort );
140+ break ;
141+ case FUTURE :
142+ bookings = bookingRepository .findByItemOwnerIdAndStartAfter (ownerId , now , sort );
143+ break ;
144+ case WAITING :
145+ bookings = bookingRepository .findByItemOwnerIdAndStatus (ownerId , BookingStatus .WAITING , sort );
146+ break ;
147+ case REJECTED :
148+ bookings = bookingRepository .findByItemOwnerIdAndStatus (ownerId , BookingStatus .REJECTED , sort );
149+ break ;
150+ default :
151+ throw new IllegalArgumentException ("Неизвестный state: " + state );
152+ }
153+
154+ return bookings .stream ()
155+ .map (BookingMapper ::toResponseDto )
156+ .collect (Collectors .toList ());
65157 }
66- }
158+ }
0 commit comments