-
Notifications
You must be signed in to change notification settings - Fork 0
Финальное задание 15го спринта #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
5580db4
Финальное задание 15го спринта с доработками
NadezhdaTA f10a614
Финальное задание 15го спринта с доработками
NadezhdaTA 547ca0b
Delete db/shareit.trace.db
NadezhdaTA a41ce91
Финальное задание 15го спринта с доработками
NadezhdaTA 1d705fb
Merge remote-tracking branch 'origin/add-bookings' into add-bookings
NadezhdaTA a5e4465
Финальное задание 15го спринта с доработками
NadezhdaTA 4c6df91
Финальное задание 15го спринта с доработками
NadezhdaTA dd49cd9
Финальное задание 15го спринта с доработками
NadezhdaTA e9fb541
Финальное задание 15го (доработано согласно замечаниям)
NadezhdaTA 697315b
Финальное задание 15го (доработано согласно замечаниям)
NadezhdaTA File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 contains hidden or 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,66 @@ | ||
| package ru.practicum.shareit; | ||
|
|
||
| import jakarta.persistence.EntityManagerFactory; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.core.env.Environment; | ||
| import org.springframework.data.jpa.repository.config.EnableJpaRepositories; | ||
| import org.springframework.jdbc.datasource.DriverManagerDataSource; | ||
| import org.springframework.orm.jpa.JpaTransactionManager; | ||
| import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; | ||
| import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; | ||
| import org.springframework.transaction.annotation.EnableTransactionManagement; | ||
|
|
||
| import javax.sql.DataSource; | ||
| import java.util.Properties; | ||
|
|
||
| @Configuration | ||
| @RequiredArgsConstructor | ||
| @EnableTransactionManagement | ||
| @EnableJpaRepositories(basePackages = "ru.practicum") | ||
| public class PersistenceConfig { | ||
| private final Environment environment; | ||
|
|
||
| @Bean | ||
| public DataSource dataSource() { | ||
| DriverManagerDataSource dataSource = new DriverManagerDataSource(); | ||
| dataSource.setDriverClassName(environment.getRequiredProperty("spring.datasource.driverClassName")); | ||
| dataSource.setUrl(environment.getRequiredProperty("spring.datasource.url")); | ||
| dataSource.setUsername(environment.getRequiredProperty("spring.datasource.username")); | ||
| dataSource.setPassword(environment.getRequiredProperty("spring.datasource.password")); | ||
| return dataSource; | ||
| } | ||
|
|
||
| private Properties hibernateProperties() { | ||
| Properties properties = new Properties(); | ||
| properties.put("spring.jpa.properties.hibernate.jdbc.time_zone", | ||
| environment.getRequiredProperty("spring.jpa.properties.hibernate.jdbc.time_zone")); | ||
| properties.put("spring.jpa.properties.hibernate.format_sql", | ||
| environment.getProperty("spring.jpa.properties.hibernate.format_sql", "false")); | ||
| return properties; | ||
| } | ||
|
|
||
| @Bean | ||
| public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { | ||
| final HibernateJpaVendorAdapter vendorAdapter = | ||
| new HibernateJpaVendorAdapter(); | ||
|
|
||
| final LocalContainerEntityManagerFactoryBean emf = | ||
| new LocalContainerEntityManagerFactoryBean(); | ||
|
|
||
| emf.setDataSource(dataSource); | ||
| emf.setJpaVendorAdapter(vendorAdapter); | ||
| emf.setPackagesToScan("ru.practicum"); | ||
| emf.setJpaProperties(hibernateProperties()); | ||
|
|
||
| return emf; | ||
| } | ||
|
|
||
| @Bean | ||
| public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { | ||
| JpaTransactionManager transactionManager = new JpaTransactionManager(); | ||
| transactionManager.setEntityManagerFactory(entityManagerFactory); | ||
| return transactionManager; | ||
| } | ||
| } | ||
This file was deleted.
Oops, something went wrong.
47 changes: 42 additions & 5 deletions
47
src/main/java/ru/practicum/shareit/booking/BookingController.java
This file contains hidden or 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,49 @@ | ||
| package ru.practicum.shareit.booking; | ||
|
|
||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| import jakarta.validation.Valid; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.*; | ||
| import ru.practicum.shareit.booking.dto.BookingRequestDto; | ||
| import ru.practicum.shareit.booking.dto.BookingResponseDto; | ||
| import ru.practicum.shareit.booking.intrfaces.BookingServiceInterface; | ||
|
|
||
| import java.util.Collection; | ||
|
|
||
| /** | ||
| * TODO Sprint add-bookings. | ||
| */ | ||
| @RestController | ||
| @RequestMapping(path = "/bookings") | ||
| @RequiredArgsConstructor | ||
| public class BookingController { | ||
| private final BookingServiceInterface bookingService; | ||
| public static final String USER_ID = "X-Sharer-User-Id"; | ||
|
|
||
| @PostMapping | ||
| public BookingResponseDto addBooking(@RequestBody @Valid BookingRequestDto booking, | ||
| @RequestHeader(USER_ID) Long bookerId) { | ||
| return bookingService.addBooking(booking, bookerId); | ||
| } | ||
|
|
||
| @PatchMapping("/{bookingId}") | ||
| public BookingResponseDto bookingApprove(@PathVariable Long bookingId, | ||
| @RequestHeader (USER_ID) Long ownerId, | ||
| @RequestParam Boolean approved) { | ||
| return bookingService.bookingApprove(bookingId, ownerId, approved); | ||
| } | ||
|
|
||
| @GetMapping("/{bookingId}") | ||
| public BookingResponseDto getBooking(@PathVariable Long bookingId, | ||
| @RequestHeader(USER_ID) Long userId) { | ||
| return bookingService.getBookingByBookingId(bookingId, userId); | ||
| } | ||
|
|
||
| @GetMapping | ||
| public Collection<BookingResponseDto> getBookingsByUser(@RequestHeader (USER_ID) Long userId, | ||
| @RequestParam(name = "state", defaultValue = "all") String state) { | ||
| return bookingService.getBookingsByUser(userId, state); | ||
| } | ||
|
|
||
| @GetMapping("/owner") | ||
| public Collection<BookingResponseDto> getBookingsByOwner(@RequestHeader (USER_ID) Long userId, | ||
| @RequestParam(name = "state", defaultValue = "all") String state) { | ||
| return bookingService.getBookingsByOwner(userId, state); | ||
| } | ||
| } | ||
|
NadezhdaTA marked this conversation as resolved.
|
||
198 changes: 198 additions & 0 deletions
198
src/main/java/ru/practicum/shareit/booking/BookingServiceImpl.java
This file contains hidden or 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,198 @@ | ||
| package ru.practicum.shareit.booking; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import ru.practicum.shareit.booking.dto.BookingRequestDto; | ||
| import ru.practicum.shareit.booking.dto.BookingResponseDto; | ||
| import ru.practicum.shareit.booking.intrfaces.BookingRepository; | ||
| import ru.practicum.shareit.booking.intrfaces.BookingServiceInterface; | ||
| import ru.practicum.shareit.booking.mapper.BookingMapper; | ||
| import ru.practicum.shareit.booking.model.Booking; | ||
| import ru.practicum.shareit.booking.model.BookingStatus; | ||
| import ru.practicum.shareit.exception.AnotherUserException; | ||
| import ru.practicum.shareit.exception.NotFoundException; | ||
| import ru.practicum.shareit.exception.ValidationException; | ||
| import ru.practicum.shareit.item.interfaces.ItemRepository; | ||
| import ru.practicum.shareit.item.mapper.ItemMapper; | ||
| import ru.practicum.shareit.item.model.Item; | ||
| import ru.practicum.shareit.user.interfaces.UserRepository; | ||
| import ru.practicum.shareit.user.mapper.UserMapper; | ||
| import ru.practicum.shareit.user.model.User; | ||
|
|
||
| import java.time.LocalDateTime; | ||
| import java.util.ArrayList; | ||
| import java.util.Collection; | ||
| import java.util.Comparator; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class BookingServiceImpl implements BookingServiceInterface { | ||
| private final BookingRepository storage; | ||
| private final UserRepository userStorage; | ||
| private final ItemRepository itemStorage; | ||
|
|
||
| private final ItemMapper itemMapper; | ||
| private final UserMapper userMapper; | ||
| private final BookingRepository bookingRepository; | ||
| private final BookingMapper bookingMapper; | ||
|
|
||
|
|
||
| @Override | ||
| public BookingResponseDto addBooking(BookingRequestDto booking, Long bookerId) { | ||
| Item item = itemStorage.findById(booking.getItemId()) | ||
| .orElseThrow(() -> new NotFoundException("Item not found")); | ||
|
|
||
| User booker = userStorage.getUserByUserId(bookerId) | ||
| .orElseThrow(() -> new NotFoundException("User not found")); | ||
|
|
||
| Booking saved = bookingMapper.bookingRequestDtoToBooking(booking); | ||
| saved.setBooker(booker); | ||
| saved.setItem(item); | ||
|
|
||
| if (item.getIsAvailable().equals(false)) { | ||
| saved.setStatus(BookingStatus.REJECTED); | ||
| storage.save(saved); | ||
| throw new RuntimeException("Booking is rejected, item is not available"); | ||
| } else { | ||
| saved.setStatus(BookingStatus.WAITING); | ||
| storage.save(saved); | ||
| } | ||
|
|
||
| return mapBookerAndItemToBooking(saved); | ||
| } | ||
|
|
||
| @Override | ||
| public BookingResponseDto bookingApprove(Long bookingId, Long ownerId, Boolean isAvailable) { | ||
| Booking booking = bookingRepository.getBookingByBookingId(bookingId) | ||
| .orElseThrow(() -> new NotFoundException("Booking not found")); | ||
|
|
||
| Item item = itemStorage.getItemByItemId(booking.getItem().getItemId()) | ||
| .orElseThrow(() -> new NotFoundException("Item not found")); | ||
|
|
||
| if (!item.getOwner().getUserId().equals(ownerId)) { | ||
| throw new AnotherUserException("You are not allowed to approve this booking"); | ||
| } | ||
|
|
||
| if (item.getIsAvailable().equals(false)) { | ||
| booking.setStatus(BookingStatus.REJECTED); | ||
| throw new ValidationException("Booking item is rejected"); | ||
| } else { | ||
| booking.setStatus(BookingStatus.APPROVED); | ||
| bookingRepository.save(booking); | ||
| } | ||
|
|
||
| return mapBookerAndItemToBooking(booking); | ||
| } | ||
|
|
||
| @Override | ||
| public BookingResponseDto getBookingByBookingId(Long bookingId, Long userId) { | ||
| Booking booking = bookingRepository.getBookingByBookingId(bookingId) | ||
| .orElseThrow(() -> new NotFoundException("Booking not found")); | ||
|
|
||
| if (booking.getBooker().getUserId().equals(userId) || | ||
| booking.getItem().getOwner().getUserId().equals(userId)) { | ||
| return mapBookerAndItemToBooking(booking); | ||
| } else { | ||
| throw new AnotherUserException("You are not allowed to view this booking"); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public Collection<BookingResponseDto> getBookingsByUser(Long userId, String state) { | ||
| User user = userStorage.getUserByUserId(userId) | ||
| .orElseThrow(() -> new NotFoundException("User not found")); | ||
|
|
||
| LocalDateTime date = LocalDateTime.now(); | ||
|
|
||
| Collection<Booking> bookings = new ArrayList<>(); | ||
|
|
||
| if (state.equalsIgnoreCase("ALL")) { | ||
| bookings = bookingRepository.getBookingsByBooker_UserId(userId); | ||
|
|
||
| } else if (state.equalsIgnoreCase("CURRENT") || | ||
| state.equalsIgnoreCase("PAST") || | ||
| state.equalsIgnoreCase("FUTURE")) { | ||
|
|
||
| bookings = getBookingsByTimeState(date, state).stream() | ||
| .filter(booking -> booking.getBooker().getUserId().equals(userId)) | ||
| .toList(); | ||
|
|
||
| } else if (state.equalsIgnoreCase("WAITING") || | ||
| state.equalsIgnoreCase("REJECTED")) { | ||
|
|
||
| if (state.equalsIgnoreCase("WAITING")) { | ||
| bookings = bookingRepository.getBookingsByBooker_UserIdAndStatus(userId, BookingStatus.WAITING); | ||
| } else { | ||
| bookings = bookingRepository.getBookingsByBooker_UserIdAndStatus(userId, BookingStatus.REJECTED); | ||
| } | ||
| } | ||
|
|
||
| return bookings.stream() | ||
| .map(this::mapBookerAndItemToBooking) | ||
| .sorted(Comparator.comparing(BookingResponseDto::getStart)) | ||
| .toList() | ||
| .reversed(); | ||
| } | ||
|
|
||
| @Override | ||
| public Collection<BookingResponseDto> getBookingsByOwner(Long userId, String state) { | ||
| User user = userStorage.getUserByUserId(userId) | ||
| .orElseThrow(() -> new NotFoundException("User not found")); | ||
|
|
||
| Item item = itemStorage.getItemsByOwner_UserId(userId).stream() | ||
| .findFirst() | ||
| .orElseThrow(() -> new NotFoundException("User with userId = " + userId + " has no Item")); | ||
|
|
||
| LocalDateTime date = LocalDateTime.now(); | ||
|
|
||
| Collection<Booking> bookings = new ArrayList<>(); | ||
|
|
||
| if (state.equalsIgnoreCase("ALL")) { | ||
| bookings = bookingRepository.getBookingsByOwnerId(userId); | ||
| } else if (state.equalsIgnoreCase("CURRENT") || | ||
| state.equalsIgnoreCase("PAST") || | ||
| state.equalsIgnoreCase("FUTURE")) { | ||
|
|
||
| bookings = getBookingsByTimeState(date, state).stream() | ||
| .filter(booking -> booking.getItem().getOwner().getUserId().equals(userId)) | ||
| .toList(); | ||
|
|
||
| } else if (state.equalsIgnoreCase("WAITING") || | ||
| state.equalsIgnoreCase("REJECTED")) { | ||
|
|
||
| if (state.equalsIgnoreCase("WAITING")) { | ||
| bookings = bookingRepository.getBookingsByStatus(BookingStatus.WAITING).stream() | ||
| .filter(booking -> booking.getItem().getOwner().getUserId().equals(userId)) | ||
| .toList(); | ||
| } else { | ||
| bookings = bookingRepository.getBookingsByStatus(BookingStatus.REJECTED).stream() | ||
| .filter(booking -> booking.getItem().getOwner().getUserId().equals(userId)) | ||
| .toList(); | ||
| } | ||
| } | ||
| return bookings.stream() | ||
| .map(this::mapBookerAndItemToBooking) | ||
| .sorted(Comparator.comparing(BookingResponseDto::getStart)) | ||
| .toList() | ||
| .reversed(); | ||
| } | ||
|
|
||
|
|
||
| private BookingResponseDto mapBookerAndItemToBooking(Booking booking) { | ||
| BookingResponseDto bookingDto = bookingMapper.bookingToBookingResponseDto(booking); | ||
| bookingDto.setBooker(userMapper.toUserBookingDto(booking.getBooker())); | ||
| bookingDto.setItem(itemMapper.toItemBookerDto(booking.getItem())); | ||
| return bookingDto; | ||
| } | ||
|
|
||
| private Collection<Booking> getBookingsByTimeState(LocalDateTime date, String state) { | ||
| Collection<Booking> bookings = new ArrayList<>(); | ||
| switch (state.toUpperCase()) { | ||
| case "CURRENT" -> bookings = bookingRepository.getBookingsByBooker_UserIdCurrent(date); | ||
| case "PAST" -> bookings = bookingRepository.getBookingsByBooker_UserIdPast(date); | ||
| case "FUTURE" -> bookings = bookingRepository.getBookingsByBooker_UserIdFuture(date); | ||
| } | ||
| return bookings; | ||
| } | ||
| } | ||
|
|
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.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Хорошо что попробовала сделать конфиг, но все это плюс-минус сделается по умолчанию, если в зависимостях добавлен spring-boot-starter-data-jpa (а у тебя он добавлен). Можешь оставить.