generated from yandex-praktikum/java-shareit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from Nikolaev-Java/add-bookings
Add bookings
- Loading branch information
Showing
48 changed files
with
1,092 additions
and
571 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
services: | ||
db: | ||
image: postgres:16.1 | ||
ports: | ||
- "6432:5432" | ||
volumes: | ||
- ./volumes/postgres:/var/lib/postgresql/data/ | ||
environment: | ||
- POSTGRES_DB=shareit | ||
- POSTGRES_USER=shareit | ||
- POSTGRES_PASSWORD=12345 | ||
healthcheck: | ||
test: pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER | ||
timeout: 5s | ||
interval: 5s | ||
retries: 10 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
59 changes: 59 additions & 0 deletions
59
src/main/java/ru/practicum/shareit/booking/BookingController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,71 @@ | ||
package ru.practicum.shareit.booking; | ||
|
||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PatchMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestHeader; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import ru.practicum.shareit.booking.dto.BookingDtoResponse; | ||
import ru.practicum.shareit.booking.dto.NewBookingDtoRequest; | ||
import ru.practicum.shareit.booking.model.BookingState; | ||
import ru.practicum.shareit.booking.service.BookingService; | ||
import ru.practicum.shareit.validationMarker.Marker; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* TODO Sprint add-bookings. | ||
*/ | ||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping(path = "/bookings") | ||
@Validated | ||
public class BookingController { | ||
private final BookingService bookingService; | ||
private static final String USER_ID = "X-Sharer-User-Id"; | ||
|
||
@PostMapping | ||
@Validated(Marker.OnCreate.class) | ||
public BookingDtoResponse createBooking(@RequestBody @Valid NewBookingDtoRequest dto, | ||
@RequestHeader(USER_ID) long userId) { | ||
dto.setBookerId(userId); | ||
return bookingService.createBooking(dto); | ||
} | ||
|
||
@PatchMapping("/{bookingId}") | ||
public BookingDtoResponse decideRent(@PathVariable long bookingId, | ||
@RequestHeader(USER_ID) long userId, | ||
@RequestParam boolean approved) { | ||
if (approved) { | ||
return bookingService.approveBooking(bookingId, userId); | ||
} else | ||
return bookingService.rejectBooking(bookingId, userId); | ||
} | ||
|
||
@GetMapping("/{bookingId}") | ||
public BookingDtoResponse getBookingByIdOfBookerOrOwner(@PathVariable long bookingId, | ||
@RequestHeader(USER_ID) long userId) { | ||
return bookingService.getBookingByIdOfBookerOrOwner(bookingId, userId); | ||
} | ||
|
||
@GetMapping | ||
public List<BookingDtoResponse> getAllBookingsByBooker(@RequestHeader(USER_ID) long userId, | ||
@RequestParam(name = "state", defaultValue = "ALL") String stateParam) { | ||
BookingState state = BookingState.parseString(stateParam); | ||
return bookingService.getAllBookingsByBooker(userId, state); | ||
} | ||
|
||
@GetMapping("/owner") | ||
public List<BookingDtoResponse> getAllBookingsByOwner(@RequestHeader(USER_ID) long userId, | ||
@RequestParam(name = "state", defaultValue = "ALL") String stateParam) { | ||
BookingState state = BookingState.parseString(stateParam); | ||
return bookingService.getAllBookingsByOwner(userId, state); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/main/java/ru/practicum/shareit/booking/BookingRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package ru.practicum.shareit.booking; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.querydsl.QuerydslPredicateExecutor; | ||
import ru.practicum.shareit.booking.model.Booking; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
public interface BookingRepository extends JpaRepository<Booking, Long>, QuerydslPredicateExecutor<Booking> { | ||
@Query(value = """ | ||
select b from Booking as b where b.id=?1 and (b.booker.id=?2 or b.item.owner.id=?2) | ||
""") | ||
Optional<Booking> findById(long bookingId, long userId); | ||
|
||
@Query(value = """ | ||
select b from Booking as b where b.item.id in ?1 | ||
and b.status='APPROVED' | ||
and b.startTime < ?2 | ||
order by b.startTime desc | ||
limit 1 | ||
""") | ||
Optional<Booking> findByItemLastBooking(Long itemId, LocalDateTime now); | ||
|
||
@Query(value = """ | ||
select b from Booking as b where b.item.id in ?1 | ||
and b.status='APPROVED' | ||
and b.startTime > ?2 | ||
order by b.startTime asc | ||
limit 1 | ||
""") | ||
Optional<Booking> findByItemNextBooking(Long itemId, LocalDateTime now); | ||
|
||
@Query(value = """ | ||
select b from Booking as b | ||
join(select b.item.id as item, max(b.startTime) as firstStartTime | ||
from Booking as b | ||
where b.startTime < ?2 and b.status='APPROVED' | ||
group by b.item.id) as subquery on b.item.id=subquery.item and b.startTime = subquery.firstStartTime | ||
where b.item.id in ?1 | ||
""") | ||
List<Booking> findAllByItemsLastBooking(List<Long> itemIds, LocalDateTime now); | ||
|
||
@Query(value = """ | ||
select b from Booking as b | ||
join(select b.item.id as item, min(b.startTime) as firstStartTime | ||
from Booking as b | ||
where b.startTime > ?2 and b.status='APPROVED' | ||
group by b.item.id) as subquery on b.item.id=subquery.item and b.startTime = subquery.firstStartTime | ||
where b.item.id in ?1 | ||
""") | ||
List<Booking> findAllByItemsNextBooking(List<Long> itemIds, LocalDateTime now); | ||
|
||
List<Booking> findAllByItemId(Long itemId); | ||
} | ||
|
7 changes: 0 additions & 7 deletions
7
src/main/java/ru/practicum/shareit/booking/dto/BookingDto.java
This file was deleted.
Oops, something went wrong.
38 changes: 38 additions & 0 deletions
38
src/main/java/ru/practicum/shareit/booking/dto/BookingDtoResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package ru.practicum.shareit.booking.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
/** | ||
* TODO Sprint add-bookings. | ||
*/ | ||
@Getter | ||
@Setter | ||
@Builder | ||
public class BookingDtoResponse { | ||
private long id; | ||
private ItemDtoResponse item; | ||
private UserDtoResponse booker; | ||
private LocalDateTime start; | ||
private LocalDateTime end; | ||
private String status; | ||
|
||
@Setter | ||
@Getter | ||
@Builder | ||
static class ItemDtoResponse { | ||
private long id; | ||
private String name; | ||
} | ||
|
||
@Setter | ||
@Getter | ||
@AllArgsConstructor | ||
static class UserDtoResponse { | ||
private long id; | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/main/java/ru/practicum/shareit/booking/dto/BookingMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package ru.practicum.shareit.booking.dto; | ||
|
||
import org.springframework.stereotype.Component; | ||
import ru.practicum.shareit.booking.model.Booking; | ||
import ru.practicum.shareit.booking.model.Status; | ||
import ru.practicum.shareit.item.Item; | ||
import ru.practicum.shareit.user.User; | ||
|
||
import java.util.List; | ||
|
||
@Component | ||
public class BookingMapper { | ||
|
||
public Booking toNewBooking(NewBookingDtoRequest dto, Item item, User booker) { | ||
if (dto == null) return null; | ||
return Booking.builder() | ||
.item(item) | ||
.booker(booker) | ||
.startTime(dto.getStart()) | ||
.endTime(dto.getEnd()) | ||
.status(Status.WAITING) | ||
.build(); | ||
} | ||
|
||
public BookingDtoResponse toBookingDtoResponse(Booking booking) { | ||
if (booking == null) return null; | ||
return BookingDtoResponse.builder() | ||
.id(booking.getId()) | ||
.item(BookingDtoResponse.ItemDtoResponse.builder() | ||
.id(booking.getItem().getId()) | ||
.name(booking.getItem().getName()) | ||
.build()) | ||
.booker(new BookingDtoResponse.UserDtoResponse(booking.getBooker().getId())) | ||
.start(booking.getStartTime()) | ||
.end(booking.getEndTime()) | ||
.status(booking.getStatus().toString()) | ||
.build(); | ||
} | ||
|
||
public List<BookingDtoResponse> toBookingDtoResponse(List<Booking> bookings) { | ||
return bookings.stream().map(this::toBookingDtoResponse).toList(); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/ru/practicum/shareit/booking/dto/NewBookingDtoRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package ru.practicum.shareit.booking.dto; | ||
|
||
import jakarta.validation.constraints.Future; | ||
import jakarta.validation.constraints.FutureOrPresent; | ||
import jakarta.validation.constraints.NotNull; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
import ru.practicum.shareit.booking.validation.StartBeforeEnd; | ||
import ru.practicum.shareit.validationMarker.Marker; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Getter | ||
@Setter | ||
@Builder | ||
@StartBeforeEnd | ||
public class NewBookingDtoRequest { | ||
@NotNull(message = "Item id must not be null") | ||
private Long itemId; | ||
private long bookerId; | ||
@NotNull(message = "Start time booking must not be null", groups = Marker.OnCreate.class) | ||
@FutureOrPresent(message = "Start time cannot be in the past", groups = Marker.OnCreate.class) | ||
private LocalDateTime start; | ||
@NotNull(message = "End time booking must not be null", groups = Marker.OnCreate.class) | ||
@Future(message = "End time cannot be in the past", groups = Marker.OnCreate.class) | ||
private LocalDateTime end; | ||
} |
52 changes: 52 additions & 0 deletions
52
src/main/java/ru/practicum/shareit/booking/model/Booking.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package ru.practicum.shareit.booking.model; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import jakarta.persistence.Table; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import ru.practicum.shareit.item.Item; | ||
import ru.practicum.shareit.user.User; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
/** | ||
* TODO Sprint add-bookings. | ||
*/ | ||
@Getter | ||
@Setter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@EqualsAndHashCode(of = "id") | ||
@Entity | ||
@Table(name = "bookings") | ||
public class Booking { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "item_id") | ||
private Item item; | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user_id") | ||
private User booker; | ||
@Column(name = "start_time") | ||
private LocalDateTime startTime; | ||
@Column(name = "end_time") | ||
private LocalDateTime endTime; | ||
@Enumerated(EnumType.STRING) | ||
private Status status; | ||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/ru/practicum/shareit/booking/model/BookingState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package ru.practicum.shareit.booking.model; | ||
|
||
public enum BookingState { | ||
ALL, CURRENT, PAST, FUTURE, WAITING, REJECTED; | ||
|
||
public static BookingState parseString(String state) { | ||
try { | ||
return valueOf(state.toUpperCase()); | ||
} catch (IllegalArgumentException e) { | ||
throw new IllegalArgumentException("Unknown state: " + state); | ||
} | ||
} | ||
} |
Oops, something went wrong.