Skip to content

Commit 782ea67

Browse files
committed
fix2
1 parent ac95de3 commit 782ea67

9 files changed

Lines changed: 123 additions & 118 deletions

File tree

src/main/java/ru/practicum/shareit/booking/dto/BookingMapper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,13 @@ public static Booking fromCreateRequest(BookingCreateRequest bookingCreateReques
2727
booking.setBooker(booker);
2828
return booking;
2929
}
30+
31+
public static BookingShortDto toShortDto(Booking booking) {
32+
BookingShortDto dto = new BookingShortDto();
33+
dto.setId(booking.getId());
34+
dto.setStart(booking.getStart());
35+
dto.setEnd(booking.getEnd());
36+
dto.setBookerId(booking.getBooker().getId());
37+
return dto;
38+
}
3039
}

src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ public BookingResponseDto createBooking(BookingCreateRequest createRequest, Long
4646
throw new AccessDeniedException("Пользователь не может бронировать свою собственную вещь");
4747
}
4848

49+
if (bookingRepository.existsOverlappingBookings(item.getId(),
50+
createRequest.getStart(),
51+
createRequest.getEnd(),
52+
List.of(BookingStatus.APPROVED, BookingStatus.WAITING))) {
53+
throw new ValidationException("Вещь уже забронирована на указанные даты");
54+
}
55+
4956
Booking booking = BookingMapper.fromCreateRequest(createRequest, item, booker);
5057
booking.setStatus(BookingStatus.WAITING);
5158
Booking saved = bookingRepository.save(booking);
@@ -54,6 +61,9 @@ public BookingResponseDto createBooking(BookingCreateRequest createRequest, Long
5461

5562
@Override
5663
public BookingResponseDto getBookingById(Long bookingId, Long userId) {
64+
userRepository.findById(userId)
65+
.orElseThrow(() -> new NotFoundException("Пользователь с id " + userId + " не найден"));
66+
5767
Booking booking = bookingRepository.findById(bookingId)
5868
.orElseThrow(() -> new NotFoundException("Бронирование с id " + bookingId + " не найдено"));
5969

src/main/java/ru/practicum/shareit/booking/storage/BookingRepository.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import ru.practicum.shareit.booking.model.BookingStatus;
99

1010
import java.time.LocalDateTime;
11+
import java.util.Collection;
1112
import java.util.List;
1213

1314
public interface BookingRepository extends JpaRepository<Booking, Long> {
@@ -41,4 +42,20 @@ public interface BookingRepository extends JpaRepository<Booking, Long> {
4142
List<Booking> findNextBooking(@Param("itemId") Long itemId, @Param("now") LocalDateTime now);
4243

4344
List<Booking> findByBookerIdAndItemIdAndStatus(Long bookerId, Long itemId, BookingStatus status);
45+
46+
@Query("SELECT CASE WHEN COUNT(b) > 0 THEN true ELSE false END FROM Booking b " +
47+
"WHERE b.item.id = :itemId AND b.status IN :statuses " +
48+
"AND b.start < :end AND b.end > :start")
49+
boolean existsOverlappingBookings(@Param("itemId") Long itemId,
50+
@Param("start") LocalDateTime start,
51+
@Param("end") LocalDateTime end,
52+
@Param("statuses") Collection<BookingStatus> statuses);
53+
54+
@Query("SELECT b FROM Booking b WHERE b.item.id IN :itemIds AND b.status = 'APPROVED' AND b.end < :now ORDER BY b.end DESC")
55+
List<Booking> findAllLastBookings(@Param("itemIds") List<Long> itemIds, @Param("now") LocalDateTime now);
56+
57+
@Query("SELECT b FROM Booking b WHERE b.item.id IN :itemIds AND b.status = 'APPROVED' AND b.start > :now ORDER BY b.start ASC")
58+
List<Booking> findAllNextBookings(@Param("itemIds") List<Long> itemIds, @Param("now") LocalDateTime now);
59+
60+
List<Booking> findByBookerIdAndItemIdAndStatusIn(Long bookerId, Long itemId, Collection<BookingStatus> statuses);
4461
}

src/main/java/ru/practicum/shareit/booking/storage/BookingStorage.java

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/main/java/ru/practicum/shareit/item/dto/CommentMapper.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package ru.practicum.shareit.item.dto;
22

33
import ru.practicum.shareit.item.model.Comment;
4+
import ru.practicum.shareit.item.model.Item;
5+
import ru.practicum.shareit.user.model.User;
6+
7+
import java.time.LocalDateTime;
48

59
public class CommentMapper {
610
public static CommentResponseDto toResponseDto(Comment comment) {
@@ -11,4 +15,13 @@ public static CommentResponseDto toResponseDto(Comment comment) {
1115
dto.setCreated(comment.getCreated());
1216
return dto;
1317
}
18+
19+
public static Comment fromCreateRequest(CommentCreateRequest request, Item item, User author, LocalDateTime created) {
20+
Comment comment = new Comment();
21+
comment.setText(request.getText());
22+
comment.setItem(item);
23+
comment.setAuthor(author);
24+
comment.setCreated(created);
25+
return comment;
26+
}
1427
}

src/main/java/ru/practicum/shareit/item/dto/ItemMapper.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package ru.practicum.shareit.item.dto;
22

3+
import ru.practicum.shareit.booking.dto.BookingShortDto;
34
import ru.practicum.shareit.item.model.Item;
45
import ru.practicum.shareit.request.model.ItemRequest;
56
import ru.practicum.shareit.user.model.User;
67

8+
import java.util.List;
9+
710
public class ItemMapper {
811

912
public static ItemResponseDto toResponseDto(Item item) {
@@ -37,4 +40,33 @@ public static void updateItemFromRequest(ItemUpdateRequest request, Item item) {
3740
item.setAvailable(request.getAvailable());
3841
}
3942
}
43+
44+
public static ItemDetailedDto toDetailedDto(Item item, BookingShortDto lastBooking, BookingShortDto nextBooking, List<CommentResponseDto> comments) {
45+
ItemDetailedDto dto = new ItemDetailedDto();
46+
dto.setId(item.getId());
47+
dto.setName(item.getName());
48+
dto.setDescription(item.getDescription());
49+
dto.setAvailable(item.getAvailable());
50+
dto.setRequestId(item.getRequest() != null ? item.getRequest().getId() : null);
51+
dto.setLastBooking(lastBooking);
52+
dto.setNextBooking(nextBooking);
53+
dto.setComments(comments);
54+
return dto;
55+
}
56+
57+
public static ItemWithBookingsDto toWithBookingsDto(Item item,
58+
BookingShortDto lastBooking,
59+
BookingShortDto nextBooking,
60+
List<CommentResponseDto> comments) {
61+
ItemWithBookingsDto dto = new ItemWithBookingsDto();
62+
dto.setId(item.getId());
63+
dto.setName(item.getName());
64+
dto.setDescription(item.getDescription());
65+
dto.setAvailable(item.getAvailable());
66+
dto.setRequestId(item.getRequest() != null ? item.getRequest().getId() : null);
67+
dto.setLastBooking(lastBooking);
68+
dto.setNextBooking(nextBooking);
69+
dto.setComments(comments);
70+
return dto;
71+
}
4072
}

src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java

Lines changed: 42 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import lombok.RequiredArgsConstructor;
44
import org.springframework.stereotype.Service;
5+
import ru.practicum.shareit.booking.dto.BookingMapper;
56
import ru.practicum.shareit.booking.dto.BookingShortDto;
67
import ru.practicum.shareit.booking.model.Booking;
78
import ru.practicum.shareit.booking.model.BookingStatus;
@@ -64,49 +65,29 @@ public ItemResponseDto updateItem(Long itemId, Long ownerId, ItemUpdateRequest u
6465
public ItemDetailedDto getItemById(Long itemId, Long userId) {
6566
Item item = itemRepository.findById(itemId)
6667
.orElseThrow(() -> new NotFoundException("Вещь не найдена"));
67-
ItemDetailedDto dto = new ItemDetailedDto();
68-
dto.setId(item.getId());
69-
dto.setName(item.getName());
70-
dto.setDescription(item.getDescription());
71-
dto.setAvailable(item.getAvailable());
72-
dto.setRequestId(item.getRequest() != null ? item.getRequest().getId() : null);
7368

7469
LocalDateTime now = LocalDateTime.now();
7570
boolean isOwner = item.getOwner().getId().equals(userId);
7671

72+
BookingShortDto lastBooking = null;
73+
BookingShortDto nextBooking = null;
74+
7775
if (isOwner) {
7876
List<Booking> lastBookings = bookingRepository.findLastBooking(itemId, now);
7977
if (!lastBookings.isEmpty()) {
80-
Booking last = lastBookings.get(0);
81-
BookingShortDto lastDto = new BookingShortDto();
82-
lastDto.setId(last.getId());
83-
lastDto.setStart(last.getStart());
84-
lastDto.setEnd(last.getEnd());
85-
lastDto.setBookerId(last.getBooker().getId());
86-
dto.setLastBooking(lastDto);
78+
lastBooking = BookingMapper.toShortDto(lastBookings.get(0));
8779
}
88-
8980
List<Booking> nextBookings = bookingRepository.findNextBooking(itemId, now);
9081
if (!nextBookings.isEmpty()) {
91-
Booking next = nextBookings.get(0);
92-
BookingShortDto nextDto = new BookingShortDto();
93-
nextDto.setId(next.getId());
94-
nextDto.setStart(next.getStart());
95-
nextDto.setEnd(next.getEnd());
96-
nextDto.setBookerId(next.getBooker().getId());
97-
dto.setNextBooking(nextDto);
82+
nextBooking = BookingMapper.toShortDto(nextBookings.get(0));
9883
}
99-
} else {
100-
dto.setLastBooking(null);
101-
dto.setNextBooking(null);
10284
}
10385

10486
List<CommentResponseDto> comments = commentRepository.findByItemIdOrderByCreatedDesc(itemId).stream()
10587
.map(CommentMapper::toResponseDto)
10688
.collect(Collectors.toList());
107-
dto.setComments(comments);
10889

109-
return dto;
90+
return ItemMapper.toDetailedDto(item, lastBooking, nextBooking, comments);
11091
}
11192

11293
@Override
@@ -116,9 +97,33 @@ public List<ItemWithBookingsDto> getItemsByOwner(Long ownerId) {
11697
}
11798

11899
List<Item> items = itemRepository.findByOwnerId(ownerId);
119-
LocalDateTime now = LocalDateTime.now();
100+
if (items.isEmpty()) {
101+
return Collections.emptyList();
102+
}
120103

104+
LocalDateTime now = LocalDateTime.now();
121105
List<Long> itemIds = items.stream().map(Item::getId).collect(Collectors.toList());
106+
107+
List<Booking> lastBookings = bookingRepository.findAllLastBookings(itemIds, now);
108+
Map<Long, BookingShortDto> lastBookingMap = lastBookings.stream()
109+
.collect(Collectors.groupingBy(
110+
b -> b.getItem().getId(),
111+
Collectors.collectingAndThen(
112+
Collectors.toList(),
113+
list -> BookingMapper.toShortDto(list.get(0))
114+
)
115+
));
116+
117+
List<Booking> nextBookings = bookingRepository.findAllNextBookings(itemIds, now);
118+
Map<Long, BookingShortDto> nextBookingMap = nextBookings.stream()
119+
.collect(Collectors.groupingBy(
120+
b -> b.getItem().getId(),
121+
Collectors.collectingAndThen(
122+
Collectors.toList(),
123+
list -> BookingMapper.toShortDto(list.get(0))
124+
)
125+
));
126+
122127
List<Comment> comments = commentRepository.findByItemIdIn(itemIds);
123128
Map<Long, List<CommentResponseDto>> commentsByItemId = comments.stream()
124129
.collect(Collectors.groupingBy(
@@ -127,40 +132,12 @@ public List<ItemWithBookingsDto> getItemsByOwner(Long ownerId) {
127132
));
128133

129134
return items.stream()
130-
.map(item -> {
131-
ItemWithBookingsDto dto = new ItemWithBookingsDto();
132-
dto.setId(item.getId());
133-
dto.setName(item.getName());
134-
dto.setDescription(item.getDescription());
135-
dto.setAvailable(item.getAvailable());
136-
dto.setRequestId(item.getRequest() != null ? item.getRequest().getId() : null);
137-
138-
List<Booking> lastBookings = bookingRepository.findLastBooking(item.getId(), now);
139-
if (!lastBookings.isEmpty()) {
140-
Booking last = lastBookings.get(0);
141-
BookingShortDto lastDto = new BookingShortDto();
142-
lastDto.setId(last.getId());
143-
lastDto.setStart(last.getStart());
144-
lastDto.setEnd(last.getEnd());
145-
lastDto.setBookerId(last.getBooker().getId());
146-
dto.setLastBooking(lastDto);
147-
}
148-
149-
List<Booking> nextBookings = bookingRepository.findNextBooking(item.getId(), now);
150-
if (!nextBookings.isEmpty()) {
151-
Booking next = nextBookings.get(0);
152-
BookingShortDto nextDto = new BookingShortDto();
153-
nextDto.setId(next.getId());
154-
nextDto.setStart(next.getStart());
155-
nextDto.setEnd(next.getEnd());
156-
nextDto.setBookerId(next.getBooker().getId());
157-
dto.setNextBooking(nextDto);
158-
}
159-
160-
dto.setComments(commentsByItemId.getOrDefault(item.getId(), Collections.emptyList()));
161-
162-
return dto;
163-
})
135+
.map(item -> ItemMapper.toWithBookingsDto(
136+
item,
137+
lastBookingMap.get(item.getId()),
138+
nextBookingMap.get(item.getId()),
139+
commentsByItemId.getOrDefault(item.getId(), Collections.emptyList())
140+
))
164141
.collect(Collectors.toList());
165142
}
166143

@@ -182,20 +159,16 @@ public CommentResponseDto addComment(Long itemId, Long authorId, CommentCreateRe
182159
.orElseThrow(() -> new NotFoundException("Пользователь с id " + authorId + " не найден"));
183160

184161
LocalDateTime now = LocalDateTime.now();
185-
List<Booking> completed = bookingRepository.findByBookerIdAndItemIdAndStatus(authorId, itemId, BookingStatus.APPROVED);
186-
boolean hasCompletedBooking = completed.stream()
162+
List<Booking> relevantBookings = bookingRepository.findByBookerIdAndItemIdAndStatusIn(
163+
authorId, itemId, List.of(BookingStatus.APPROVED, BookingStatus.WAITING));
164+
boolean hasCompletedBooking = relevantBookings.stream()
187165
.anyMatch(b -> !b.getEnd().isAfter(now));
188166

189167
if (!hasCompletedBooking) {
190168
throw new ValidationException("Пользователь не может оставить отзыв, так как не брал вещь в аренду или аренда ещё не завершена");
191169
}
192170

193-
Comment comment = new Comment();
194-
comment.setText(request.getText());
195-
comment.setItem(item);
196-
comment.setAuthor(author);
197-
comment.setCreated(now);
198-
171+
Comment comment = CommentMapper.fromCreateRequest(request, item, author, now);
199172
Comment saved = commentRepository.save(comment);
200173
return CommentMapper.toResponseDto(saved);
201174
}

src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/main/java/ru/practicum/shareit/user/storage/UserStorage.java

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)