From 718545b4edd6133d4b052624f8404227a787eaf8 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 16 Sep 2022 21:13:29 +0300 Subject: [PATCH 01/11] add all files --- .../shareit/booking/BookingMapper.java | 61 ++++++++++ .../shareit/booking/BookingStatus.java | 6 + .../shareit/booking/dto/BookingDTO.java | 48 ++++++++ .../shareit/booking/model/Booking.java | 26 +++++ .../shareit/exceptions/NotFoundException.java | 11 ++ .../exceptions/ValidationException.java | 11 ++ .../shareit/item/ItemController.java | 48 +++++++- .../ru/practicum/shareit/item/ItemMapper.java | 28 +++++ .../practicum/shareit/item/dto/ItemDTO.java | 19 ++++ .../ru/practicum/shareit/item/model/Item.java | 14 ++- .../item/repository/ItemRepository.java | 28 +++++ .../item/repository/ItemRepositoryImpl.java | 87 ++++++++++++++ .../shareit/item/service/ItemService.java | 25 ++++ .../shareit/item/service/ItemServiceImpl.java | 107 ++++++++++++++++++ .../request/ItemRequestController.java | 2 +- .../shareit/request/RequestMapper.java | 35 ++++++ .../shareit/request/dto/ItemRequestDTO.java | 27 +++++ .../shareit/request/model/ItemRequest.java | 20 ++++ .../shareit/user/UserController.java | 41 ++++++- .../ru/practicum/shareit/user/UserMapper.java | 17 +++ .../practicum/shareit/user/dto/UserDTO.java | 15 +++ .../ru/practicum/shareit/user/model/User.java | 15 +++ .../user/repository/UserRepository.java | 25 ++++ .../user/repository/UserRepositoryImpl.java | 80 +++++++++++++ .../shareit/user/service/UserService.java | 24 ++++ .../shareit/user/service/UserServiceImpl.java | 69 +++++++++++ 26 files changed, 883 insertions(+), 6 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/booking/BookingMapper.java create mode 100644 src/main/java/ru/practicum/shareit/booking/BookingStatus.java create mode 100644 src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java create mode 100644 src/main/java/ru/practicum/shareit/booking/model/Booking.java create mode 100644 src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java create mode 100644 src/main/java/ru/practicum/shareit/exceptions/ValidationException.java create mode 100644 src/main/java/ru/practicum/shareit/item/ItemMapper.java create mode 100644 src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java create mode 100644 src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java create mode 100644 src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java create mode 100644 src/main/java/ru/practicum/shareit/item/service/ItemService.java create mode 100644 src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java create mode 100644 src/main/java/ru/practicum/shareit/request/RequestMapper.java create mode 100644 src/main/java/ru/practicum/shareit/request/dto/ItemRequestDTO.java create mode 100644 src/main/java/ru/practicum/shareit/request/model/ItemRequest.java create mode 100644 src/main/java/ru/practicum/shareit/user/UserMapper.java create mode 100644 src/main/java/ru/practicum/shareit/user/dto/UserDTO.java create mode 100644 src/main/java/ru/practicum/shareit/user/model/User.java create mode 100644 src/main/java/ru/practicum/shareit/user/repository/UserRepository.java create mode 100644 src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java create mode 100644 src/main/java/ru/practicum/shareit/user/service/UserService.java create mode 100644 src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java new file mode 100644 index 000000000..9dfd022a1 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -0,0 +1,61 @@ +package ru.practicum.shareit.booking; + +import org.springframework.stereotype.Service; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.user.model.User; + +@Service +public class BookingMapper { + + public BookingDTO toBookingDto(Booking booking) { + return BookingDTO.builder() + .id(booking.getId()) + .start(booking.getStart()) + .end(booking.getEnd()) + .item(toBookingItem(booking.getItem())) + .booker(toUserBooking(booking.getBooker())) + .bookingStatus(booking.getBookingStatus()) + .build(); + } + + public Booking toBooking(BookingDTO bookingDto) { + return Booking.builder() + .id(bookingDto.getId()) + .start(bookingDto.getStart()) + .end(bookingDto.getEnd()) + .item(toItem(bookingDto.getItem())) + .booker(toUser(bookingDto.getBooker())) + .bookingStatus(bookingDto.getBookingStatus()) + .build(); + } + + private BookingDTO.Item toBookingItem(Item item) { + return BookingDTO.Item.builder() + .id(item.getId()) + .name(item.getName()) + .description(item.getDescription()) + .available(item.getAvailable()) + .request(item.getRequest()) + .build(); + } + + private Item toItem(BookingDTO.Item bookingItem) { + return Item.builder() + .id(bookingItem.getId()) + .name(bookingItem.getName()) + .description(bookingItem.getDescription()) + .available(bookingItem.isAvailable()) + .request(bookingItem.getRequest()) + .build(); + } + + private BookingDTO.User toUserBooking(User user) { + return BookingDTO.User.builder().id(user.getId()).name(user.getName()).email(user.getEmail()).build(); + } + + private User toUser(BookingDTO.User bookingUser) { + return User.builder().id(bookingUser.getId()).name(bookingUser.getName()).email(bookingUser.getEmail()).build(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/BookingStatus.java b/src/main/java/ru/practicum/shareit/booking/BookingStatus.java new file mode 100644 index 000000000..f0a4788ce --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/BookingStatus.java @@ -0,0 +1,6 @@ +package ru.practicum.shareit.booking; + + +public enum BookingStatus { + AVAILABLE, IN_USE, WAITING +} diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java new file mode 100644 index 000000000..6db7edb03 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java @@ -0,0 +1,48 @@ +package ru.practicum.shareit.booking.dto; + +/** + * TODO Sprint add-bookings. + */ +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import ru.practicum.shareit.booking.BookingStatus; + +import java.time.LocalDateTime; + +@Data +@Builder +@Getter +@Setter +public class BookingDTO { + private Long id; + private LocalDateTime start; + private LocalDateTime end; + private Item item; + private User booker; + private User owner; + private BookingStatus bookingStatus; + + @Data + @Builder + @Getter + @Setter + public static class Item { + private Long id; + private String name; + private String description; + private boolean available; + private String request; + } + + @Data + @Builder + @Getter + @Setter + public static class User { + private Long id; + private String name; + private String email; + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java new file mode 100644 index 000000000..adadec51e --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -0,0 +1,26 @@ +package ru.practicum.shareit.booking.model; + +/** + * TODO Sprint add-bookings. + */ + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import ru.practicum.shareit.booking.BookingStatus; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; + +@AllArgsConstructor +@Data +@Builder +public class Booking { + private Long id; + private LocalDateTime start; + private LocalDateTime end; + private Item item; + private User booker; + private BookingStatus bookingStatus; +} diff --git a/src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java b/src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java new file mode 100644 index 000000000..4067d0f84 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java @@ -0,0 +1,11 @@ +package ru.practicum.shareit.exceptions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NotFoundException extends RuntimeException { + public NotFoundException(String message, String className) { + super(message); + log.error("{}. {}", className, message); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/exceptions/ValidationException.java b/src/main/java/ru/practicum/shareit/exceptions/ValidationException.java new file mode 100644 index 000000000..6e884beb2 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exceptions/ValidationException.java @@ -0,0 +1,11 @@ +package ru.practicum.shareit.exceptions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ValidationException extends RuntimeException { + public ValidationException(String message, String className) { + super(message); + log.error("{}. {}", className, message); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index bb17668ba..99c501394 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -1,12 +1,54 @@ package ru.practicum.shareit.item; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.item.service.ItemService; + +import javax.validation.Valid; +import javax.validation.ValidationException; +import java.util.Collection; +import java.util.List; /** * TODO Sprint add-controllers. */ @RestController @RequestMapping("/items") +@RequiredArgsConstructor public class ItemController { -} + private static final String HEADER_USER_ID = "X-Sharer-User-Id"; + private final ItemService iService; + + @PostMapping + public ItemDTO createItem(@RequestHeader(HEADER_USER_ID) String userId, @Valid @RequestBody ItemDTO iDto) throws ValidationException, NotFoundException { + return iService.createItem(Long.valueOf(userId), iDto); + } + + @GetMapping("/{itemId}") + public ItemDTO findItemById(@PathVariable String itemId) throws NotFoundException { + return iService.findById(Long.valueOf(itemId)); + } + + @GetMapping + public Collection findAll(@RequestHeader(HEADER_USER_ID) String userId) throws NotFoundException { + return iService.findByUser(Long.valueOf(userId)); + } + + @PatchMapping("/{itemId}") + public ItemDTO updateItem(@RequestHeader(HEADER_USER_ID) String userId, @PathVariable String itemId, @Valid @RequestBody ItemDTO iDto) throws NotFoundException { + return iService.update(Long.valueOf(userId), Long.valueOf(itemId), iDto); + } + + @DeleteMapping("/{itemId}") + public Long deleteItem(@RequestHeader(HEADER_USER_ID) String userId, @PathVariable String itemId) throws NotFoundException { + return iService.deleteItem(Long.valueOf(userId), Long.valueOf(itemId)); + } + + @GetMapping("/search") + public List searchItemByText(@RequestParam String text) { + return iService.search(text); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/ItemMapper.java new file mode 100644 index 000000000..1b299741c --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/ItemMapper.java @@ -0,0 +1,28 @@ +package ru.practicum.shareit.item; + +import org.springframework.stereotype.Service; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.model.Item; + +@Service +public class ItemMapper { + public ItemDTO toIDto(Item item) { + return ItemDTO.builder() + .id(item.getId()) + .name(item.getName()) + .description(item.getDescription()) + .available(item.getAvailable()) + .request(item.getRequest() != null ? item.getRequest() : null) + .build(); + } + + public Item toItem(ItemDTO itemDto) { + return Item.builder() + .id(itemDto.getId()) + .name(itemDto.getName()) + .description(itemDto.getDescription()) + .available(itemDto.getAvailable()) + .request(itemDto.getRequest() != null ? itemDto.getRequest() : null) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java new file mode 100644 index 000000000..929b5f72f --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java @@ -0,0 +1,19 @@ +package ru.practicum.shareit.item.dto; + +/** + * TODO Sprint add-controllers. + */ +import lombok.Builder; +import lombok.Data; +import ru.practicum.shareit.user.model.User; + +@Data +@Builder +public class ItemDTO { + private Long id; + private String name; + private String description; + private Boolean available; + private User owner; + private String request; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index 44eb73ddc..70badc16e 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -3,5 +3,17 @@ /** * TODO Sprint add-controllers. */ +import lombok.Builder; +import lombok.Data; +import ru.practicum.shareit.user.model.User; + +@Data +@Builder public class Item { -} + private Long id; + private String name; + private String description; + private Boolean available; + private String request; + private User owner; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java new file mode 100644 index 000000000..f534352b3 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java @@ -0,0 +1,28 @@ +package ru.practicum.shareit.item.repository; + +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.util.Collection; +import java.util.Map; + +public interface ItemRepository { + Item create(Long userId, Item item, User user); + + Item findById(Long itemId); + + Collection findByUserId(Long userId); + + Map findAll(); + + Item update(Long itemId, Item item); + + Long delete(Long itemId); + + Collection search(String text); + + boolean checkOwner(Long userId, Long itemId); + + void checkItemId(Long itemId) throws NotFoundException; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java b/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java new file mode 100644 index 000000000..9dc296b05 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java @@ -0,0 +1,87 @@ +package ru.practicum.shareit.item.repository; + +import org.springframework.stereotype.Service; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +@Service +public class ItemRepositoryImpl implements ItemRepository { + private static long iId = 0; + + private static Long generateId() { + return iId++; + } + + private final Map items = new HashMap<>(); + + @Override + public Item create(Long uId, Item item, User user) { + item.setId(generateId()); + item.setOwner(user); + items.put(item.getId(), item); + return item; + } + + @Override + public Item findById(Long id) { + return items.get(id); + } + + @Override + public Collection findByUserId(Long id) { + return findAll().values().stream().filter(i -> Objects.equals(i.getOwner().getId(), id)).collect(Collectors.toList()); + } + + @Override + public Map findAll() { + return items; + } + + @Override + public Item update(Long id, Item item) { + Item itemUpdated = findById(id); + + if (item.getName() != null) { + itemUpdated.setName(item.getName()); + } + + if (item.getDescription() != null) { + itemUpdated.setDescription(item.getDescription()); + } + + if (item.getAvailable() != null) { + itemUpdated.setAvailable(item.getAvailable()); + } + + return itemUpdated; + } + + @Override + public Long delete(Long id) { + return items.remove(id).getId(); + } + + @Override + public Collection search(String text) { + return findAll().values().stream().filter(i -> (i.getName().toLowerCase().contains(text.toLowerCase()) || i.getDescription().toLowerCase().contains(text.toLowerCase())) && i.getAvailable()).collect(Collectors.toList()); + } + + @Override + public boolean checkOwner(Long uId, Long iId) { + return !items.get(iId).getOwner().getId().equals(uId); + } + + @Override + public void checkItemId(Long itemId) throws NotFoundException { + if (!findAll().containsKey(itemId)) { + throw new NotFoundException("Пользователя с таким id не существует", "User"); + } + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java new file mode 100644 index 000000000..83fb97a7d --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -0,0 +1,25 @@ +package ru.practicum.shareit.item.service; + +import org.springframework.stereotype.Repository; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.exceptions.ValidationException; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.model.Item; + +import java.util.Collection; +import java.util.List; + +@Repository +public interface ItemService { + ItemDTO createItem(Long userId, ItemDTO itemDto) throws ValidationException, NotFoundException; + + ItemDTO findById(Long itemId) throws NotFoundException; + + Collection findByUser(Long userId) throws NotFoundException; + + ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws NotFoundException; + + Long deleteItem(Long userId, Long itemId) throws NotFoundException; + + List search(String text); +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java new file mode 100644 index 000000000..3ba71b929 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -0,0 +1,107 @@ +package ru.practicum.shareit.item.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.exceptions.ValidationException; +import ru.practicum.shareit.item.ItemMapper; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.item.repository.ItemRepository; +import ru.practicum.shareit.user.*; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.service.UserService; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ItemServiceImpl implements ItemService { + private final UserService uService; + private final UserMapper uMapper; + + private final ItemRepository iRepository; + private final ItemMapper iMapper; + + @Override + public ItemDTO createItem(Long uId, ItemDTO iDto) throws ValidationException, NotFoundException { + uService.checkId(uId); + + if (!StringUtils.hasText(iDto.getName())) { + throw new ValidationException("Имя не может быть пустым", "CreateItem"); + } + + if (iDto.getDescription() == null) { + throw new ValidationException("Описание не может быть пустым", "CreateItem"); + } + + if (iDto.getAvailable() == null) { + throw new ValidationException("Статус доступности не модет быть пустым", "CreateItem"); + } + + UserDTO uDto = uService.findById(uId); + Item item = iRepository.create(uId, iMapper.toItem(iDto), uMapper.toUser(uDto)); + + log.info("Товар id {} создан", item.getId()); + return iMapper.toIDto(item); + } + + @Override + public ItemDTO findById(Long id) throws NotFoundException { + iRepository.checkItemId(id); + Item item = iRepository.findById(id); + return iMapper.toIDto(item); + } + + @Override + public Collection findByUser(Long id) throws NotFoundException { + uService.checkId(id); + + return iRepository.findByUserId(id).stream().map(iMapper::toIDto).collect(Collectors.toList()); + } + + @Override + public ItemDTO update(Long userId, Long itemId, ItemDTO iDto) throws NotFoundException { + uService.checkId(userId); + iRepository.checkItemId(itemId); + + if (iRepository.checkOwner(userId, itemId)) { + throw new NotFoundException("Неправльный владелец", "user"); + } + + Item item = iRepository.update(itemId, iMapper.toItem(iDto)); + log.info("Обновлено id {}", item.getId()); + return iMapper.toIDto(item); + } + + @Override + public Long deleteItem(Long userId, Long itemId) throws NotFoundException { + uService.checkId(userId); + iRepository.checkItemId(itemId); + + Long itemDeletedId = iRepository.delete(itemId); + log.info("Удалено id {}", itemDeletedId); + return itemDeletedId; + } + + @Override + public List search(String text) { + List availableItems = new ArrayList<>(); + if (text.length() > 0 && !text.trim().equals("")) { + for (Item itemFromStorage : iRepository.findAll().values()) { + if (itemFromStorage.getAvailable() + && (itemFromStorage.getDescription().toLowerCase().contains(text.toLowerCase()) + || itemFromStorage.getName().toLowerCase().contains(text.toLowerCase()))) { + availableItems.add(itemFromStorage); + } + } + } + return availableItems; + } +} diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java index 064e2e9c6..35a97daf5 100644 --- a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java +++ b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java @@ -9,4 +9,4 @@ @RestController @RequestMapping(path = "/requests") public class ItemRequestController { -} +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/request/RequestMapper.java b/src/main/java/ru/practicum/shareit/request/RequestMapper.java new file mode 100644 index 000000000..3a51af580 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/RequestMapper.java @@ -0,0 +1,35 @@ +package ru.practicum.shareit.request; + +import org.springframework.stereotype.Component; +import ru.practicum.shareit.request.dto.ItemRequestDTO; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.model.User; + +@Component +public class RequestMapper { + public ItemRequestDTO toItemDto(ItemRequest item) { + return ItemRequestDTO.builder() + .id(item.getId()) + .description(item.getDescription()) + .requester(toUserItemRequest(item.getRequester())) + .created(item.getCreated()) + .build(); + } + + public ItemRequest toItem(ItemRequestDTO itemDto) { + return ItemRequest.builder() + .id(itemDto.getId()) + .description(itemDto.getDescription()) + .requester(toUser(itemDto.getRequester())) + .created(itemDto.getCreated()) + .build(); + } + + private ItemRequestDTO.User toUserItemRequest(User user) { + return ItemRequestDTO.User.builder().id(user.getId()).name(user.getName()).email(user.getEmail()).build(); + } + + private User toUser(ItemRequestDTO.User bookingUser) { + return User.builder().id(bookingUser.getId()).name(bookingUser.getName()).email(bookingUser.getEmail()).build(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDTO.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDTO.java new file mode 100644 index 000000000..ccd5a7650 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDTO.java @@ -0,0 +1,27 @@ +package ru.practicum.shareit.request.dto; + +/** + * TODO Sprint add-item-requests. + */ +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@Builder +public class ItemRequestDTO { + + private Long id; + private String description; + private User requester; + private LocalDateTime created; + + @Data + @Builder + public static class User { + private Long id; + private String name; + private String email; + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java new file mode 100644 index 000000000..fbde004d3 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -0,0 +1,20 @@ +package ru.practicum.shareit.request.model; + +/** + * TODO Sprint add-item-requests. + */ +import lombok.Builder; +import lombok.Data; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; + +@Data +@Builder +public class ItemRequest { + private Long id; + private String description; + private User requester; + private LocalDateTime created; +} + diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 03039b9da..848a00ed3 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -6,7 +6,46 @@ /** * TODO Sprint add-controllers. */ +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.exceptions.ValidationException; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.service.UserService; + +import javax.validation.Valid; +import java.util.Collection; + @RestController @RequestMapping(path = "/users") +@RequiredArgsConstructor public class UserController { -} + private final UserService userService; + + @PostMapping + public UserDTO create(@Valid @RequestBody UserDTO uDto) throws ValidationException { + return userService.create(uDto); + } + + @GetMapping("/{userId}") + public UserDTO findUserById(@PathVariable String userId) throws NotFoundException { + return userService.findById(Long.valueOf(userId)); + } + + @GetMapping + public Collection findAllUsers() { + return userService.findAll(); + } + + @PatchMapping("/{userId}") + public UserDTO update(@PathVariable String userId, @Valid @RequestBody UserDTO userDto) throws ValidationException, + NotFoundException { + return userService.update(Long.valueOf(userId), userDto); + } + + @DeleteMapping("/{userId}") + public Long deleteUser(@PathVariable String userId) throws NotFoundException { + return userService.delete(Long.valueOf(userId)); + } + +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java new file mode 100644 index 000000000..183a5e580 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.user; + +import org.springframework.stereotype.Component; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.model.User; + +@Component +public class UserMapper { + + public UserDTO toUserDTO(User user) { + return UserDTO.builder().id(user.getId()).name(user.getName()).email(user.getEmail()).build(); + } + + public User toUser(UserDTO userDto) { + return User.builder().id(userDto.getId()).name(userDto.getName()).email(userDto.getEmail()).build(); + } +} diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java new file mode 100644 index 000000000..82198eb8a --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java @@ -0,0 +1,15 @@ +package ru.practicum.shareit.user.dto; + +import lombok.Builder; +import lombok.Data; + +import javax.validation.constraints.Email; + +@Data +@Builder +public class UserDTO { + private Long id; + private String name; + @Email + private String email; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/model/User.java b/src/main/java/ru/practicum/shareit/user/model/User.java new file mode 100644 index 000000000..b3e70bd1a --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/model/User.java @@ -0,0 +1,15 @@ +package ru.practicum.shareit.user.model; + +/** + * TODO Sprint add-controllers. + */ +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class User { + private Long id; + private String email; + private String name; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/repository/UserRepository.java b/src/main/java/ru/practicum/shareit/user/repository/UserRepository.java new file mode 100644 index 000000000..b22863be0 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/repository/UserRepository.java @@ -0,0 +1,25 @@ +package ru.practicum.shareit.user.repository; + +import org.springframework.stereotype.Repository; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.user.model.User; + +import javax.validation.ValidationException; +import java.util.Map; + +@Repository +public interface UserRepository { + User create(User user); + + User findById(Long userId); + + Map findAll(); + + User update(Long userId, User user); + + Long delete(Long userId); + + void checkId(Long userId) throws NotFoundException; + + void checkEmail(String email) throws ValidationException; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java b/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java new file mode 100644 index 000000000..4e3a2accb --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java @@ -0,0 +1,80 @@ +package ru.practicum.shareit.user.repository; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.client.HttpClientErrorException; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.exceptions.ValidationException; +import ru.practicum.shareit.user.model.User; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +@Service +public class UserRepositoryImpl implements UserRepository { + + private static long id = 0; + + private static Long generateUserId() { + return ++id; + } + + private final Map users = new HashMap<>(); + + @Override + public User create(User user) { + user.setId(generateUserId()); + users.put(user.getId(), user); + return user; + } + + @Override + public User findById(Long id) { + return users.get(id); + } + + @Override + public Map findAll() { + return users; + } + + @Override + public User update(Long id, User user) { + User userUpd = findById(id); + + if (user.getEmail() != null) { + userUpd.setEmail(user.getEmail()); + } + + if (user.getName() != null) { + userUpd.setName(user.getName()); + } + + return userUpd; + } + + @Override + public Long delete(Long id) { + return users.remove(id).getId(); + } + + @Override + public void checkId(Long id) throws HttpClientErrorException.NotFound, NotFoundException { + if (!findAll().containsKey(id)) { + throw new NotFoundException((String.format("Пользователь id %d не найден�", id)), "User"); + } + } + + @Override + public void checkEmail(String email) throws ValidationException { + if (email == null || email.isBlank()) { + throw new ValidationException("Email не может быть пустым", "email"); + } + for (User user : findAll().values()) { + if (Objects.equals(user.getEmail(), email)) { + throw new ValidationException(String.format("Почта не модет быть пустой", email), "CheckEmail"); + } + } + } +} diff --git a/src/main/java/ru/practicum/shareit/user/service/UserService.java b/src/main/java/ru/practicum/shareit/user/service/UserService.java new file mode 100644 index 000000000..cce3acab4 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/service/UserService.java @@ -0,0 +1,24 @@ +package ru.practicum.shareit.user.service; + + +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.user.dto.UserDTO; + +import javax.validation.ValidationException; +import java.util.Collection; + +public interface UserService { + UserDTO create(UserDTO uDto) throws ValidationException; + + + UserDTO findById(Long id) throws NotFoundException; + + Collection findAll(); + + UserDTO update(Long id, UserDTO uDto) throws ValidationException, NotFoundException; + + Long delete(Long userId) throws NotFoundException; + + + void checkId(Long userId) throws NotFoundException; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java new file mode 100644 index 000000000..0563c46bb --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -0,0 +1,69 @@ +package ru.practicum.shareit.user.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.client.HttpClientErrorException; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.user.repository.UserRepository; + +import javax.validation.ValidationException; +import java.util.Collection; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class UserServiceImpl implements UserService { + private final UserRepository userRepository; + private final UserMapper userMapper; + + @Override + public UserDTO create(UserDTO uDto) throws ValidationException { + userRepository.checkEmail(uDto.getEmail()); + User user = userRepository.create(userMapper.toUser(uDto)); + log.info("Пользователь создан"); + return userMapper.toUserDTO(user); + } + + @Override + public UserDTO findById(Long id) throws NotFoundException { + checkId(id); + User user = userRepository.findById(id); + log.info("Получен пользователь"); + return userMapper.toUserDTO(user); + } + + @Override + public Collection findAll() { + return userRepository.findAll().values().stream().map(userMapper::toUserDTO).collect(Collectors.toList()); + } + + @Override + public UserDTO update(Long id, UserDTO uDto) throws ValidationException, NotFoundException { + checkId(id); + if (StringUtils.hasText(uDto.getEmail())) { + userRepository.checkEmail(uDto.getEmail()); + } + User user = userRepository.update(id, userMapper.toUser(uDto)); + log.info("Пользователь обновлен"); + return userMapper.toUserDTO(user); + } + + @Override + public Long delete(Long id) throws HttpClientErrorException.NotFound, NotFoundException { + checkId(id); + Long userDelId = userRepository.delete(id); + log.info("Пользователь удален"); + return userDelId; + } + + @Override + public void checkId(Long id) throws HttpClientErrorException.NotFound, NotFoundException { + userRepository.checkId(id); + } +} \ No newline at end of file From c511c931685a4271dfd909e9a055fb4aa851c725 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 16 Sep 2022 21:17:52 +0300 Subject: [PATCH 02/11] userRepoImpl update --- .../ru/practicum/shareit/user/repository/UserRepositoryImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java b/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java index 4e3a2accb..916617820 100644 --- a/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java +++ b/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java @@ -1,7 +1,6 @@ package ru.practicum.shareit.user.repository; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; import org.springframework.web.client.HttpClientErrorException; import ru.practicum.shareit.exceptions.NotFoundException; import ru.practicum.shareit.exceptions.ValidationException; From f67076c4dc72280223c9bb58efc600f357ea1cd9 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 16 Sep 2022 21:37:38 +0300 Subject: [PATCH 03/11] exceptions bugs fixed --- .../shareit/exceptions/ErrorHandler.java | 29 +++++++++++++++++++ .../shareit/exceptions/ErrorResponse.java | 14 +++++++++ .../exceptions/InvalidParameterException.java | 7 +++++ .../shareit/exceptions/NotFoundException.java | 4 +-- .../exceptions/ValidationException.java | 4 +-- .../shareit/item/ItemController.java | 9 ++++-- .../item/repository/ItemRepositoryImpl.java | 15 ++++++++-- .../shareit/item/service/ItemServiceImpl.java | 8 ++--- .../user/repository/UserRepositoryImpl.java | 7 +++-- 9 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/exceptions/ErrorHandler.java create mode 100644 src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java create mode 100644 src/main/java/ru/practicum/shareit/exceptions/InvalidParameterException.java diff --git a/src/main/java/ru/practicum/shareit/exceptions/ErrorHandler.java b/src/main/java/ru/practicum/shareit/exceptions/ErrorHandler.java new file mode 100644 index 000000000..210a70553 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exceptions/ErrorHandler.java @@ -0,0 +1,29 @@ +package ru.practicum.shareit.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + + +@RestControllerAdvice +public class ErrorHandler { + + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse handleUserNotFoundException(final NotFoundException e) { + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ErrorResponse handleValidationException(final ValidationException e) { + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleInvalidParameterException(final InvalidParameterException e) { + return new ErrorResponse(e.getMessage()); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java b/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java new file mode 100644 index 000000000..963030c10 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java @@ -0,0 +1,14 @@ +package ru.practicum.shareit.exceptions; + +public class ErrorResponse { + private String error; + + public ErrorResponse(String error) { + this.error = error; + } + + public String getError() { + return error; + } + +} diff --git a/src/main/java/ru/practicum/shareit/exceptions/InvalidParameterException.java b/src/main/java/ru/practicum/shareit/exceptions/InvalidParameterException.java new file mode 100644 index 000000000..20f3dadc2 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exceptions/InvalidParameterException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.exceptions; + +public class InvalidParameterException extends RuntimeException { + public InvalidParameterException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java b/src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java index 4067d0f84..c58fd6fda 100644 --- a/src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java +++ b/src/main/java/ru/practicum/shareit/exceptions/NotFoundException.java @@ -4,8 +4,8 @@ @Slf4j public class NotFoundException extends RuntimeException { - public NotFoundException(String message, String className) { + public NotFoundException(String message) { super(message); - log.error("{}. {}", className, message); + log.error("{}", message); } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/exceptions/ValidationException.java b/src/main/java/ru/practicum/shareit/exceptions/ValidationException.java index 6e884beb2..b9d3b3adf 100644 --- a/src/main/java/ru/practicum/shareit/exceptions/ValidationException.java +++ b/src/main/java/ru/practicum/shareit/exceptions/ValidationException.java @@ -4,8 +4,8 @@ @Slf4j public class ValidationException extends RuntimeException { - public ValidationException(String message, String className) { + public ValidationException(String message) { super(message); - log.error("{}. {}", className, message); + log.error("{}", message); } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index 99c501394..f93e9ba58 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -23,7 +23,8 @@ public class ItemController { private final ItemService iService; @PostMapping - public ItemDTO createItem(@RequestHeader(HEADER_USER_ID) String userId, @Valid @RequestBody ItemDTO iDto) throws ValidationException, NotFoundException { + public ItemDTO createItem(@RequestHeader(HEADER_USER_ID) String userId, @Valid @RequestBody ItemDTO iDto) + throws ValidationException, NotFoundException { return iService.createItem(Long.valueOf(userId), iDto); } @@ -38,12 +39,14 @@ public Collection findAll(@RequestHeader(HEADER_USER_ID) String userId) } @PatchMapping("/{itemId}") - public ItemDTO updateItem(@RequestHeader(HEADER_USER_ID) String userId, @PathVariable String itemId, @Valid @RequestBody ItemDTO iDto) throws NotFoundException { + public ItemDTO updateItem(@RequestHeader(HEADER_USER_ID) String userId, @PathVariable String itemId, + @Valid @RequestBody ItemDTO iDto) throws NotFoundException { return iService.update(Long.valueOf(userId), Long.valueOf(itemId), iDto); } @DeleteMapping("/{itemId}") - public Long deleteItem(@RequestHeader(HEADER_USER_ID) String userId, @PathVariable String itemId) throws NotFoundException { + public Long deleteItem(@RequestHeader(HEADER_USER_ID) String userId, @PathVariable String itemId) + throws NotFoundException { return iService.deleteItem(Long.valueOf(userId), Long.valueOf(itemId)); } diff --git a/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java b/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java index 9dc296b05..78b6baf4c 100644 --- a/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java @@ -36,7 +36,11 @@ public Item findById(Long id) { @Override public Collection findByUserId(Long id) { - return findAll().values().stream().filter(i -> Objects.equals(i.getOwner().getId(), id)).collect(Collectors.toList()); + return findAll() + .values() + .stream() + .filter(i -> Objects.equals(i.getOwner().getId(), id)) + .collect(Collectors.toList()); } @Override @@ -70,7 +74,12 @@ public Long delete(Long id) { @Override public Collection search(String text) { - return findAll().values().stream().filter(i -> (i.getName().toLowerCase().contains(text.toLowerCase()) || i.getDescription().toLowerCase().contains(text.toLowerCase())) && i.getAvailable()).collect(Collectors.toList()); + return findAll() + .values() + .stream() + .filter(i -> (i.getName().toLowerCase().contains(text.toLowerCase()) + || i.getDescription().toLowerCase().contains(text.toLowerCase())) + && i.getAvailable()).collect(Collectors.toList()); } @Override @@ -81,7 +90,7 @@ public boolean checkOwner(Long uId, Long iId) { @Override public void checkItemId(Long itemId) throws NotFoundException { if (!findAll().containsKey(itemId)) { - throw new NotFoundException("Пользователя с таким id не существует", "User"); + throw new NotFoundException("Пользователя с таким id не существует"); } } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 3ba71b929..fe94607a1 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -34,15 +34,15 @@ public ItemDTO createItem(Long uId, ItemDTO iDto) throws ValidationException, No uService.checkId(uId); if (!StringUtils.hasText(iDto.getName())) { - throw new ValidationException("Имя не может быть пустым", "CreateItem"); + throw new ValidationException("Имя не может быть пустым"); } if (iDto.getDescription() == null) { - throw new ValidationException("Описание не может быть пустым", "CreateItem"); + throw new ValidationException("Описание не может быть пустым"); } if (iDto.getAvailable() == null) { - throw new ValidationException("Статус доступности не модет быть пустым", "CreateItem"); + throw new ValidationException("Статус доступности не модет быть пустым"); } UserDTO uDto = uService.findById(uId); @@ -72,7 +72,7 @@ public ItemDTO update(Long userId, Long itemId, ItemDTO iDto) throws NotFoundExc iRepository.checkItemId(itemId); if (iRepository.checkOwner(userId, itemId)) { - throw new NotFoundException("Неправльный владелец", "user"); + throw new NotFoundException("Неправльный владелец"); } Item item = iRepository.update(itemId, iMapper.toItem(iDto)); diff --git a/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java b/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java index 916617820..6f003c8e9 100644 --- a/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java +++ b/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java @@ -2,6 +2,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.HttpClientErrorException; +import ru.practicum.shareit.exceptions.InvalidParameterException; import ru.practicum.shareit.exceptions.NotFoundException; import ru.practicum.shareit.exceptions.ValidationException; import ru.practicum.shareit.user.model.User; @@ -61,18 +62,18 @@ public Long delete(Long id) { @Override public void checkId(Long id) throws HttpClientErrorException.NotFound, NotFoundException { if (!findAll().containsKey(id)) { - throw new NotFoundException((String.format("Пользователь id %d не найден�", id)), "User"); + throw new NotFoundException("Пользователь id %d не найден"); } } @Override public void checkEmail(String email) throws ValidationException { if (email == null || email.isBlank()) { - throw new ValidationException("Email не может быть пустым", "email"); + throw new InvalidParameterException("Почта не может быть пустой"); } for (User user : findAll().values()) { if (Objects.equals(user.getEmail(), email)) { - throw new ValidationException(String.format("Почта не модет быть пустой", email), "CheckEmail"); + throw new ValidationException("Пользователь уже зарегистрирован"); } } } From d538dc018924d6bbabc7b7c252d549a97faf0b03 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 16 Sep 2022 21:47:05 +0300 Subject: [PATCH 04/11] Item id s fixwd --- src/main/java/ru/practicum/shareit/item/ItemController.java | 4 ++-- .../practicum/shareit/item/repository/ItemRepositoryImpl.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index f93e9ba58..e56ff3805 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -23,9 +23,9 @@ public class ItemController { private final ItemService iService; @PostMapping - public ItemDTO createItem(@RequestHeader(HEADER_USER_ID) String userId, @Valid @RequestBody ItemDTO iDto) + public ItemDTO createItem(@RequestHeader(HEADER_USER_ID) Long userId, @Valid @RequestBody ItemDTO iDto) throws ValidationException, NotFoundException { - return iService.createItem(Long.valueOf(userId), iDto); + return iService.createItem(userId, iDto); } @GetMapping("/{itemId}") diff --git a/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java b/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java index 78b6baf4c..8e1ce7e38 100644 --- a/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java @@ -16,7 +16,8 @@ public class ItemRepositoryImpl implements ItemRepository { private static long iId = 0; private static Long generateId() { - return iId++; + iId++; + return iId; } private final Map items = new HashMap<>(); From a9f556b42c12149e2148ec1be1f5cbb24635dcbc Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 16 Sep 2022 22:10:18 +0300 Subject: [PATCH 05/11] create Item with empty param bugs fixed --- src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java | 2 +- .../practicum/shareit/item/repository/ItemRepository.java | 3 ++- .../ru/practicum/shareit/item/service/ItemServiceImpl.java | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java index 929b5f72f..a89a7ab23 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java @@ -14,6 +14,6 @@ public class ItemDTO { private String name; private String description; private Boolean available; - private User owner; + private Long owner; private String request; } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java index f534352b3..32862b4f3 100644 --- a/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java @@ -1,6 +1,7 @@ package ru.practicum.shareit.item.repository; import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; @@ -8,7 +9,7 @@ import java.util.Map; public interface ItemRepository { - Item create(Long userId, Item item, User user); + Item create(Long uId, Item item, User user); Item findById(Long itemId); diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index fe94607a1..52019bf6b 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import ru.practicum.shareit.exceptions.InvalidParameterException; import ru.practicum.shareit.exceptions.NotFoundException; import ru.practicum.shareit.exceptions.ValidationException; import ru.practicum.shareit.item.ItemMapper; @@ -34,15 +35,15 @@ public ItemDTO createItem(Long uId, ItemDTO iDto) throws ValidationException, No uService.checkId(uId); if (!StringUtils.hasText(iDto.getName())) { - throw new ValidationException("Имя не может быть пустым"); + throw new InvalidParameterException("Имя не может быть пустым"); } if (iDto.getDescription() == null) { - throw new ValidationException("Описание не может быть пустым"); + throw new InvalidParameterException("Описание не может быть пустым"); } if (iDto.getAvailable() == null) { - throw new ValidationException("Статус доступности не модет быть пустым"); + throw new InvalidParameterException("Статус доступности не может быть пустым"); } UserDTO uDto = uService.findById(uId); From ef61b841cc50098eed46683664f910e091dcd002 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 16 Sep 2022 22:12:56 +0300 Subject: [PATCH 06/11] unused imports --- src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java | 1 - .../ru/practicum/shareit/item/repository/ItemRepository.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java index a89a7ab23..1a8744ead 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java @@ -5,7 +5,6 @@ */ import lombok.Builder; import lombok.Data; -import ru.practicum.shareit.user.model.User; @Data @Builder diff --git a/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java index 32862b4f3..6a1c68e84 100644 --- a/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java @@ -1,7 +1,6 @@ package ru.practicum.shareit.item.repository; import ru.practicum.shareit.exceptions.NotFoundException; -import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; From 640b78b9729f522c86afe4fe24b6585397fc2811 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sat, 17 Sep 2022 20:22:56 +0300 Subject: [PATCH 07/11] review --- .../shareit/booking/BookingController.java | 3 --- .../practicum/shareit/booking/dto/BookingDTO.java | 3 --- .../ru/practicum/shareit/item/ItemController.java | 3 --- .../ru/practicum/shareit/item/dto/ItemDTO.java | 3 --- .../ru/practicum/shareit/item/model/Item.java | 3 --- .../shareit/item/service/ItemServiceImpl.java | 15 ++++++++------- .../shareit/request/ItemRequestController.java | 3 --- .../shareit/request/dto/ItemRequestDTO.java | 3 --- .../ru/practicum/shareit/user/UserController.java | 3 --- .../ru/practicum/shareit/user/model/User.java | 3 --- 10 files changed, 8 insertions(+), 34 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index b94493d49..6fbd9a0a1 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -3,9 +3,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -/** - * TODO Sprint add-bookings. - */ @RestController @RequestMapping(path = "/bookings") public class BookingController { diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java index 6db7edb03..547a04c01 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java @@ -1,8 +1,5 @@ package ru.practicum.shareit.booking.dto; -/** - * TODO Sprint add-bookings. - */ import lombok.Builder; import lombok.Data; import lombok.Getter; diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index e56ff3805..123b2f907 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -12,9 +12,6 @@ import java.util.Collection; import java.util.List; -/** - * TODO Sprint add-controllers. - */ @RestController @RequestMapping("/items") @RequiredArgsConstructor diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java index 1a8744ead..0e0e524b2 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java @@ -1,8 +1,5 @@ package ru.practicum.shareit.item.dto; -/** - * TODO Sprint add-controllers. - */ import lombok.Builder; import lombok.Data; diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index 70badc16e..8e70899ca 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -1,8 +1,5 @@ package ru.practicum.shareit.item.model; -/** - * TODO Sprint add-controllers. - */ import lombok.Builder; import lombok.Data; import ru.practicum.shareit.user.model.User; diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 52019bf6b..633209f31 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -32,8 +32,15 @@ public class ItemServiceImpl implements ItemService { @Override public ItemDTO createItem(Long uId, ItemDTO iDto) throws ValidationException, NotFoundException { - uService.checkId(uId); + validation(uId,iDto); + UserDTO uDto = uService.findById(uId); + Item item = iRepository.create(uId, iMapper.toItem(iDto), uMapper.toUser(uDto)); + log.info("Товар id {} создан", item.getId()); + return iMapper.toIDto(item); + } + private void validation(Long uId, ItemDTO iDto) { + uService.checkId(uId); if (!StringUtils.hasText(iDto.getName())) { throw new InvalidParameterException("Имя не может быть пустым"); } @@ -45,12 +52,6 @@ public ItemDTO createItem(Long uId, ItemDTO iDto) throws ValidationException, No if (iDto.getAvailable() == null) { throw new InvalidParameterException("Статус доступности не может быть пустым"); } - - UserDTO uDto = uService.findById(uId); - Item item = iRepository.create(uId, iMapper.toItem(iDto), uMapper.toUser(uDto)); - - log.info("Товар id {} создан", item.getId()); - return iMapper.toIDto(item); } @Override diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java index 35a97daf5..f9e914e51 100644 --- a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java +++ b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java @@ -3,9 +3,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -/** - * TODO Sprint add-item-requests. - */ @RestController @RequestMapping(path = "/requests") public class ItemRequestController { diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDTO.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDTO.java index ccd5a7650..e98db74bc 100644 --- a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDTO.java +++ b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDTO.java @@ -1,8 +1,5 @@ package ru.practicum.shareit.request.dto; -/** - * TODO Sprint add-item-requests. - */ import lombok.Builder; import lombok.Data; diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 848a00ed3..9a2846ca0 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -3,9 +3,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -/** - * TODO Sprint add-controllers. - */ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.exceptions.NotFoundException; diff --git a/src/main/java/ru/practicum/shareit/user/model/User.java b/src/main/java/ru/practicum/shareit/user/model/User.java index b3e70bd1a..9a04c5856 100644 --- a/src/main/java/ru/practicum/shareit/user/model/User.java +++ b/src/main/java/ru/practicum/shareit/user/model/User.java @@ -1,8 +1,5 @@ package ru.practicum.shareit.user.model; -/** - * TODO Sprint add-controllers. - */ import lombok.Builder; import lombok.Data; From bf27a642bd0873017c9087c82e12db9a2e3d52e0 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sun, 18 Sep 2022 22:10:09 +0300 Subject: [PATCH 08/11] review 2 --- .../practicum/shareit/booking/BookingMapper.java | 16 ++++++++++++---- .../practicum/shareit/booking/model/Booking.java | 3 --- .../shareit/exceptions/ErrorResponse.java | 3 +-- .../practicum/shareit/item/ItemController.java | 3 ++- .../shareit/item/service/ItemServiceImpl.java | 8 +++----- .../practicum/shareit/request/RequestMapper.java | 12 ++++++++++-- .../shareit/request/model/ItemRequest.java | 3 --- .../ru/practicum/shareit/user/UserMapper.java | 12 ++++++++++-- .../shareit/user/service/UserServiceImpl.java | 14 +++++++++----- 9 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index 9dfd022a1..38d982bcb 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -42,8 +42,8 @@ private BookingDTO.Item toBookingItem(Item item) { } private Item toItem(BookingDTO.Item bookingItem) { - return Item.builder() - .id(bookingItem.getId()) + return Item.builder(). + id(bookingItem.getId()) .name(bookingItem.getName()) .description(bookingItem.getDescription()) .available(bookingItem.isAvailable()) @@ -52,10 +52,18 @@ private Item toItem(BookingDTO.Item bookingItem) { } private BookingDTO.User toUserBooking(User user) { - return BookingDTO.User.builder().id(user.getId()).name(user.getName()).email(user.getEmail()).build(); + return BookingDTO.User.builder() + .id(user.getId()) + .name(user.getName()) + .email(user.getEmail()) + .build(); } private User toUser(BookingDTO.User bookingUser) { - return User.builder().id(bookingUser.getId()).name(bookingUser.getName()).email(bookingUser.getEmail()).build(); + return User.builder() + .id(bookingUser.getId()) + .name(bookingUser.getName()) + .email(bookingUser.getEmail()) + .build(); } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java index adadec51e..4109ab671 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -1,8 +1,5 @@ package ru.practicum.shareit.booking.model; -/** - * TODO Sprint add-bookings. - */ import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java b/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java index 963030c10..51bc168bc 100644 --- a/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java +++ b/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java @@ -10,5 +10,4 @@ public ErrorResponse(String error) { public String getError() { return error; } - -} +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index 123b2f907..cf202d005 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -31,7 +31,8 @@ public ItemDTO findItemById(@PathVariable String itemId) throws NotFoundExceptio } @GetMapping - public Collection findAll(@RequestHeader(HEADER_USER_ID) String userId) throws NotFoundException { + public Collection findAll(@RequestHeader(HEADER_USER_ID) String userId) + throws NotFoundException { return iService.findByUser(Long.valueOf(userId)); } diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 633209f31..ec2388579 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -32,14 +32,14 @@ public class ItemServiceImpl implements ItemService { @Override public ItemDTO createItem(Long uId, ItemDTO iDto) throws ValidationException, NotFoundException { - validation(uId,iDto); + validate(uId, iDto); UserDTO uDto = uService.findById(uId); Item item = iRepository.create(uId, iMapper.toItem(iDto), uMapper.toUser(uDto)); log.info("Товар id {} создан", item.getId()); return iMapper.toIDto(item); } - private void validation(Long uId, ItemDTO iDto) { + private void validate(Long uId, ItemDTO iDto) { uService.checkId(uId); if (!StringUtils.hasText(iDto.getName())) { throw new InvalidParameterException("Имя не может быть пустым"); @@ -97,9 +97,7 @@ public List search(String text) { List availableItems = new ArrayList<>(); if (text.length() > 0 && !text.trim().equals("")) { for (Item itemFromStorage : iRepository.findAll().values()) { - if (itemFromStorage.getAvailable() - && (itemFromStorage.getDescription().toLowerCase().contains(text.toLowerCase()) - || itemFromStorage.getName().toLowerCase().contains(text.toLowerCase()))) { + if (itemFromStorage.getAvailable() && (itemFromStorage.getDescription().toLowerCase().contains(text.toLowerCase()) || itemFromStorage.getName().toLowerCase().contains(text.toLowerCase()))) { availableItems.add(itemFromStorage); } } diff --git a/src/main/java/ru/practicum/shareit/request/RequestMapper.java b/src/main/java/ru/practicum/shareit/request/RequestMapper.java index 3a51af580..0963aed95 100644 --- a/src/main/java/ru/practicum/shareit/request/RequestMapper.java +++ b/src/main/java/ru/practicum/shareit/request/RequestMapper.java @@ -26,10 +26,18 @@ public ItemRequest toItem(ItemRequestDTO itemDto) { } private ItemRequestDTO.User toUserItemRequest(User user) { - return ItemRequestDTO.User.builder().id(user.getId()).name(user.getName()).email(user.getEmail()).build(); + return ItemRequestDTO.User.builder() + .id(user.getId()) + .name(user.getName()) + .email(user.getEmail()) + .build(); } private User toUser(ItemRequestDTO.User bookingUser) { - return User.builder().id(bookingUser.getId()).name(bookingUser.getName()).email(bookingUser.getEmail()).build(); + return User.builder() + .id(bookingUser.getId()) + .name(bookingUser.getName()) + .email(bookingUser.getEmail()) + .build(); } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java index fbde004d3..240a2d2af 100644 --- a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java +++ b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -1,8 +1,5 @@ package ru.practicum.shareit.request.model; -/** - * TODO Sprint add-item-requests. - */ import lombok.Builder; import lombok.Data; import ru.practicum.shareit.user.model.User; diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index 183a5e580..398b62175 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -8,10 +8,18 @@ public class UserMapper { public UserDTO toUserDTO(User user) { - return UserDTO.builder().id(user.getId()).name(user.getName()).email(user.getEmail()).build(); + return UserDTO.builder() + .id(user.getId()) + .name(user.getName()) + .email(user.getEmail()) + .build(); } public User toUser(UserDTO userDto) { - return User.builder().id(userDto.getId()).name(userDto.getName()).email(userDto.getEmail()).build(); + return User.builder() + .id(userDto.getId()) + .name(userDto.getName()) + .email(userDto.getEmail()) + .build(); } } diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java index 0563c46bb..ce425be7d 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -26,7 +26,7 @@ public class UserServiceImpl implements UserService { public UserDTO create(UserDTO uDto) throws ValidationException { userRepository.checkEmail(uDto.getEmail()); User user = userRepository.create(userMapper.toUser(uDto)); - log.info("Пользователь создан"); + log.info("Пользователь id {} создан", user.getId()); return userMapper.toUserDTO(user); } @@ -34,13 +34,17 @@ public UserDTO create(UserDTO uDto) throws ValidationException { public UserDTO findById(Long id) throws NotFoundException { checkId(id); User user = userRepository.findById(id); - log.info("Получен пользователь"); + log.info("Получен пользователь id {}", user.getId()); return userMapper.toUserDTO(user); } @Override public Collection findAll() { - return userRepository.findAll().values().stream().map(userMapper::toUserDTO).collect(Collectors.toList()); + return userRepository.findAll() + .values() + .stream() + .map(userMapper::toUserDTO) + .collect(Collectors.toList()); } @Override @@ -50,7 +54,7 @@ public UserDTO update(Long id, UserDTO uDto) throws ValidationException, NotFoun userRepository.checkEmail(uDto.getEmail()); } User user = userRepository.update(id, userMapper.toUser(uDto)); - log.info("Пользователь обновлен"); + log.info("Пользователь id {} обновлен", user.getId()); return userMapper.toUserDTO(user); } @@ -58,7 +62,7 @@ public UserDTO update(Long id, UserDTO uDto) throws ValidationException, NotFoun public Long delete(Long id) throws HttpClientErrorException.NotFound, NotFoundException { checkId(id); Long userDelId = userRepository.delete(id); - log.info("Пользователь удален"); + log.info("Пользователь id {} удален", id); return userDelId; } From 1ddee6ae48801c32ded9a7a3d8fe4f54420787a9 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sun, 18 Sep 2022 22:12:14 +0300 Subject: [PATCH 09/11] checkstyle --- src/main/java/ru/practicum/shareit/booking/BookingMapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index 38d982bcb..76a94089f 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -42,8 +42,8 @@ private BookingDTO.Item toBookingItem(Item item) { } private Item toItem(BookingDTO.Item bookingItem) { - return Item.builder(). - id(bookingItem.getId()) + return Item.builder() + .id(bookingItem.getId()) .name(bookingItem.getName()) .description(bookingItem.getDescription()) .available(bookingItem.isAvailable()) From 832cd8f7cc83ce9ccb5875a410c6ecf3d5e4b4a6 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 19 Sep 2022 15:21:15 +0300 Subject: [PATCH 10/11] review 3 --- .../ru/practicum/shareit/item/service/ItemServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index ec2388579..a8b8c31f7 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -97,7 +97,9 @@ public List search(String text) { List availableItems = new ArrayList<>(); if (text.length() > 0 && !text.trim().equals("")) { for (Item itemFromStorage : iRepository.findAll().values()) { - if (itemFromStorage.getAvailable() && (itemFromStorage.getDescription().toLowerCase().contains(text.toLowerCase()) || itemFromStorage.getName().toLowerCase().contains(text.toLowerCase()))) { + if (itemFromStorage.getAvailable() && + (itemFromStorage.getDescription().toLowerCase().contains(text.toLowerCase()) + || itemFromStorage.getName().toLowerCase().contains(text.toLowerCase()))) { availableItems.add(itemFromStorage); } } From 2e19e0fa7112fe9e951b19316ced5cde375a9878 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 14 Oct 2022 21:26:08 +0300 Subject: [PATCH 11/11] add all items fixed --- .../shareit/booking/BookingController.java | 54 +++- .../shareit/booking/BookingMapper.java | 61 +---- .../shareit/booking/BookingStatus.java | 9 +- .../shareit/booking/dto/BookingDTO.java | 6 +- .../shareit/booking/model/Booking.java | 49 +++- .../booking/repository/BookingRepository.java | 56 ++++ .../booking/service/BookingService.java | 20 ++ .../booking/service/BookingServiceImpl.java | 192 ++++++++++++++ .../ru/practicum/shareit/comment/Comment.java | 50 ++++ .../practicum/shareit/comment/CommentDTO.java | 25 ++ .../shareit/comment/CommentMapper.java | 38 +++ .../shareit/comment/CommentRepository.java | 12 + .../shareit/exceptions/ErrorResponse.java | 14 +- .../shareit/item/ItemController.java | 62 +++-- .../ru/practicum/shareit/item/ItemMapper.java | 62 +++-- .../practicum/shareit/item/dto/ItemDTO.java | 70 ++++- .../shareit/item/dto/ItemDTOBooking.java | 25 ++ .../ru/practicum/shareit/item/model/Item.java | 65 ++++- .../item/repository/ItemRepository.java | 25 +- .../shareit/item/service/ItemService.java | 19 +- .../shareit/item/service/ItemServiceImpl.java | 247 +++++++++++++----- .../shareit/request/RequestMapper.java | 22 +- .../shareit/request/model/ItemRequest.java | 33 ++- .../shareit/user/UserController.java | 50 ++-- .../ru/practicum/shareit/user/UserMapper.java | 34 ++- .../practicum/shareit/user/dto/UserDTO.java | 8 +- .../ru/practicum/shareit/user/model/User.java | 40 ++- .../user/repository/UserRepository.java | 22 +- .../shareit/user/service/UserService.java | 18 +- .../shareit/user/service/UserServiceImpl.java | 102 ++++---- src/main/resources/application.properties | 16 +- src/main/resources/schema.sql | 43 +++ .../ru/practicum/shareit/ShareItTests.java | 2 + 33 files changed, 1165 insertions(+), 386 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/booking/repository/BookingRepository.java create mode 100644 src/main/java/ru/practicum/shareit/booking/service/BookingService.java create mode 100644 src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java create mode 100644 src/main/java/ru/practicum/shareit/comment/Comment.java create mode 100644 src/main/java/ru/practicum/shareit/comment/CommentDTO.java create mode 100644 src/main/java/ru/practicum/shareit/comment/CommentMapper.java create mode 100644 src/main/java/ru/practicum/shareit/comment/CommentRepository.java create mode 100644 src/main/java/ru/practicum/shareit/item/dto/ItemDTOBooking.java create mode 100644 src/main/resources/schema.sql diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index 6fbd9a0a1..82f9c41f2 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -1,9 +1,57 @@ package ru.practicum.shareit.booking; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.service.BookingServiceImpl; + +import java.util.List; @RestController -@RequestMapping(path = "/bookings") +@Slf4j +@RequestMapping("/bookings") public class BookingController { + + private final BookingServiceImpl bookingService; + + @Autowired + public BookingController(BookingServiceImpl bookingService) { + this.bookingService = bookingService; + } + + @PostMapping + public BookingDTO saveBooking(@RequestHeader("X-Sharer-User-Id") Long id, + @RequestBody BookingDTO bookingDto) { + return bookingService.create(id, bookingDto); + } + + @GetMapping("/{bookingId}") + public Booking findBookingById(@RequestHeader("X-Sharer-User-Id") Long id, + @PathVariable Long bookingId) { + return bookingService.findBookingById(id, bookingId); + } + + @GetMapping + public List findAllBookingsById(@RequestParam(defaultValue = "ALL") String state, + @RequestHeader("X-Sharer-User-Id") Long id) { + + return bookingService.findBookingByIdAndStatus(state, id); + } + + @PatchMapping("/{bookingId}") + public BookingDTO confirmOrRejectBooking(@RequestHeader("X-Sharer-User-Id") Long id, + @PathVariable Long bookingId, + @RequestParam Boolean approved) { + return bookingService.confirmOrRejectBooking(id, bookingId, approved); + } + + @GetMapping("/owner") + public List findAllOwnersBookings(@RequestParam(defaultValue = "ALL") String state, + @RequestHeader("X-Sharer-User-Id") Long id) { + + return bookingService.findAllOwnersBookings(state, id); + } + } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index 76a94089f..09a480f9d 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -1,69 +1,20 @@ package ru.practicum.shareit.booking; -import org.springframework.stereotype.Service; +import org.springframework.stereotype.Component; import ru.practicum.shareit.booking.model.Booking; -import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.booking.dto.BookingDTO; -import ru.practicum.shareit.user.model.User; -@Service +@Component public class BookingMapper { - public BookingDTO toBookingDto(Booking booking) { + public static BookingDTO toBookingDto(Booking booking) { return BookingDTO.builder() .id(booking.getId()) .start(booking.getStart()) .end(booking.getEnd()) - .item(toBookingItem(booking.getItem())) - .booker(toUserBooking(booking.getBooker())) - .bookingStatus(booking.getBookingStatus()) - .build(); - } - - public Booking toBooking(BookingDTO bookingDto) { - return Booking.builder() - .id(bookingDto.getId()) - .start(bookingDto.getStart()) - .end(bookingDto.getEnd()) - .item(toItem(bookingDto.getItem())) - .booker(toUser(bookingDto.getBooker())) - .bookingStatus(bookingDto.getBookingStatus()) - .build(); - } - - private BookingDTO.Item toBookingItem(Item item) { - return BookingDTO.Item.builder() - .id(item.getId()) - .name(item.getName()) - .description(item.getDescription()) - .available(item.getAvailable()) - .request(item.getRequest()) - .build(); - } - - private Item toItem(BookingDTO.Item bookingItem) { - return Item.builder() - .id(bookingItem.getId()) - .name(bookingItem.getName()) - .description(bookingItem.getDescription()) - .available(bookingItem.isAvailable()) - .request(bookingItem.getRequest()) - .build(); - } - - private BookingDTO.User toUserBooking(User user) { - return BookingDTO.User.builder() - .id(user.getId()) - .name(user.getName()) - .email(user.getEmail()) - .build(); - } - - private User toUser(BookingDTO.User bookingUser) { - return User.builder() - .id(bookingUser.getId()) - .name(bookingUser.getName()) - .email(bookingUser.getEmail()) + .item(booking.getItem()) + .booker(booking.getBooker()) + .bookingStatus(booking.getStatus()) .build(); } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/BookingStatus.java b/src/main/java/ru/practicum/shareit/booking/BookingStatus.java index f0a4788ce..e96eb527a 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingStatus.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingStatus.java @@ -2,5 +2,12 @@ public enum BookingStatus { - AVAILABLE, IN_USE, WAITING + WAITING, + APPROVED, + REJECTED, + CANCELED, + ALL, + CURRENT, + PAST, + FUTURE } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java index 547a04c01..a8fa68ba7 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java @@ -16,8 +16,8 @@ public class BookingDTO { private Long id; private LocalDateTime start; private LocalDateTime end; - private Item item; - private User booker; + private ru.practicum.shareit.item.model.Item item; + private ru.practicum.shareit.user.model.User booker; private User owner; private BookingStatus bookingStatus; @@ -30,7 +30,7 @@ public static class Item { private String name; private String description; private boolean available; - private String request; + private Long requestId; } @Data diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java index 4109ab671..ca7a34b3b 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -1,23 +1,56 @@ package ru.practicum.shareit.booking.model; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; +import lombok.*; +import org.hibernate.Hibernate; import ru.practicum.shareit.booking.BookingStatus; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; +import javax.persistence.*; import java.time.LocalDateTime; +import java.util.Objects; -@AllArgsConstructor -@Data -@Builder +@Entity +@Table(name = "bookings", schema = "PUBLIC") +@Getter +@Setter +@ToString +@RequiredArgsConstructor public class Booking { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "booking_id") private Long id; + + @Column(name = "start_date", nullable = false) private LocalDateTime start; + + @Column(name = "end_date", nullable = false) private LocalDateTime end; + + @ManyToOne + @JoinColumn(name = "item_id", nullable = false) private Item item; + + @ManyToOne + @JoinColumn(name = "booker_id", nullable = false) private User booker; - private BookingStatus bookingStatus; + + @Column(name = "status", nullable = false) + @Enumerated(EnumType.STRING) + private BookingStatus status = BookingStatus.WAITING; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Booking booking = (Booking) o; + return id != null && Objects.equals(id, booking.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } } diff --git a/src/main/java/ru/practicum/shareit/booking/repository/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/repository/BookingRepository.java new file mode 100644 index 000000000..ed167cd36 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/repository/BookingRepository.java @@ -0,0 +1,56 @@ +package ru.practicum.shareit.booking.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import ru.practicum.shareit.booking.BookingStatus; +import ru.practicum.shareit.booking.model.Booking; + +import java.util.List; + +public interface BookingRepository extends JpaRepository { + + @Query("SELECT b FROM Booking b WHERE b.booker.id = ?1") + List findBookingsByBookerId(Long id); + + @Query("SELECT b FROM Booking b WHERE b.booker.id = ?1 AND" + + " b.start < CURRENT_TIMESTAMP AND b.end > CURRENT_TIMESTAMP") + List findBookingsByBookerIdWithCurrentStatus(Long id); + + @Query("SELECT b FROM Booking b WHERE b.booker.id = ?1 AND" + + " b.start < CURRENT_TIMESTAMP AND b.end < CURRENT_TIMESTAMP") + List findBookingsByBookerIdWithPastStatus(Long id); + + @Query("SELECT b FROM Booking b WHERE b.booker.id = ?1 AND" + " b.start > CURRENT_TIMESTAMP ") + List findBookingsByBookerIdWithFutureStatus(Long id); + + @Query("SELECT b FROM Booking b WHERE b.booker.id = ?1 AND b.status = ?2") + List findBookingsByBookerIdWithWaitingOrRejectStatus(Long id, BookingStatus status); + + @Query(value = "SELECT b FROM Booking AS b WHERE b.item.id IN (SELECT it FROM Item AS it WHERE it.owner.id = ?1) " + + "AND b.status = ?2 ") + List findAllOwnersBookingsWithStatus(Long id, BookingStatus status); + + @Query(value = "SELECT b FROM Booking AS b WHERE b.item.id IN (SELECT it FROM Item AS it WHERE it.owner.id = ?1) ") + List findAllOwnersBookings(Long id); + + @Query(value = "SELECT b FROM Booking AS b WHERE b.item.id IN (SELECT it FROM Item AS it WHERE it.owner.id = ?1) " + + "AND b.start > CURRENT_TIMESTAMP ") + List findAllOwnersBookingsWithFutureStatus(Long id); + + @Query(value = "SELECT b FROM Booking AS b WHERE b.item.id IN (SELECT it FROM Item AS it WHERE it.owner.id = ?1) " + + "AND b.start < CURRENT_TIMESTAMP AND b.end > CURRENT_TIMESTAMP ") + List findAllOwnersBookingsWithCurrentStatus(Long id); + + @Query(value = "SELECT b FROM Booking AS b WHERE b.item.id IN (SELECT it FROM Item AS it WHERE it.owner.id = ?1) " + + "AND b.end < CURRENT_TIMESTAMP ") + List findAllOwnersBookingsWithPastStatus(Long id); + + @Query(value = "SELECT b FROM Booking AS b WHERE b.item.id = ?1") + List findAllItemBookings(Long id); + + @Query(value = "SELECT b FROM Booking AS b WHERE b.item.id = ?1 AND b.start < CURRENT_TIMESTAMP ") + List findAllItemBookingsPast(Long id); + + @Query(value = "SELECT b FROM Booking AS b WHERE b.item.id = ?1 AND b.start > CURRENT_TIMESTAMP ") + List findAllItemBookingsFuture(Long id); +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingService.java b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java new file mode 100644 index 000000000..b999fa523 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java @@ -0,0 +1,20 @@ +package ru.practicum.shareit.booking.service; + +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.booking.model.Booking; + +import java.util.List; + +public interface BookingService { + + BookingDTO create(Long id, BookingDTO dto); + + Booking findBookingById(Long id, Long bId); + + BookingDTO confirmOrRejectBooking(Long id, Long bId, Boolean approved); + + List findBookingByIdAndStatus(String state, Long id); + + List findAllOwnersBookings(String state, Long id); + +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java new file mode 100644 index 000000000..04b55f0e0 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -0,0 +1,192 @@ +package ru.practicum.shareit.booking.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.practicum.shareit.booking.BookingMapper; +import ru.practicum.shareit.booking.BookingStatus; +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.repository.BookingRepository; +import ru.practicum.shareit.exceptions.InvalidParameterException; +import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.exceptions.ValidationException; +import ru.practicum.shareit.item.repository.ItemRepository; +import ru.practicum.shareit.user.repository.UserRepository; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Service +public class BookingServiceImpl implements BookingService { + + private final BookingRepository bRepo; + private final ItemRepository iRepo; + private final UserRepository uRepo; + + @Autowired + public BookingServiceImpl(BookingRepository bRepo, ItemRepository iRepo, UserRepository uRepo) { + this.bRepo = bRepo; + this.iRepo = iRepo; + this.uRepo = uRepo; + } + + @Override + public BookingDTO create(Long id, BookingDTO dto) { + Booking booking = new Booking(); + if (validateItem(id, dto)) { + booking.setItem(iRepo.getReferenceById(dto.getItem().getId())); + booking.setStart(dto.getStart()); + booking.setEnd(dto.getEnd()); + booking.setBooker(uRepo.getReferenceById(id)); + } + return BookingMapper.toBookingDto(bRepo.save(booking)); + } + + private boolean validateItem(Long id, BookingDTO dto) { + + if (!iRepo.existsById(dto.getItem().getId())) { + throw new NotFoundException("Товар не найден"); + } + if (id.equals(iRepo.getReferenceById(dto.getItem().getId()).getOwner().getId())) { + throw new NotFoundException("Невозможно выполнить операцию"); + } + if (dto.getEnd().isBefore(LocalDateTime.now())) { + throw new InvalidParameterException("Дата завершения не может находиться в прошлом"); + } + if (dto.getEnd().isBefore(dto.getStart())) { + throw new InvalidParameterException("Дата завершения не может быть раньше даты начала"); + } + if (dto.getStart().isBefore(LocalDateTime.now())) { + throw new InvalidParameterException("Дата начала не может быть в прошлом"); + } + if (!uRepo.existsById(id)) { + throw new NotFoundException("Пользователь не найден"); + } + if (iRepo.existsById(dto.getItem().getId())) { + if (iRepo.getReferenceById(dto.getItem().getId()).getIsAvailable() == Boolean.FALSE) { + throw new InvalidParameterException("Товар не доступен"); + } + } + return true; + } + + private void validateUser(Long id) { + if (!uRepo.existsById(id)) { + throw new NotFoundException("Пользователь не найден"); + } + } + + private void validateBooking(Long bookingId) { + if (!bRepo.existsById(bookingId)) { + throw new NotFoundException("Бронирование не найдено"); + } + } + + private void validateState(String state) { + if (!state.equals(BookingStatus.ALL.name()) && !state.equals(BookingStatus.REJECTED.name()) + && !state.equals(BookingStatus.WAITING.name()) && !state.equals(BookingStatus.CURRENT.name()) + && !state.equals(BookingStatus.APPROVED.name()) && !state.equals(BookingStatus.CANCELED.name()) + && !state.equals(BookingStatus.PAST.name()) && !state.equals(BookingStatus.FUTURE.name())) { + throw new ValidationException("Неизвестный статус"); + } + } + + + @Override + public Booking findBookingById(Long id, Long bId) { + validateUser(id); + + Booking booking = bRepo.findById(bId).orElseThrow(() -> new NotFoundException("Бронирование не найдено")); + + if (!Objects.equals(booking.getBooker().getId(), id) + && !Objects.equals(booking.getItem().getOwner().getId(), id)) { + throw new InvalidParameterException("Ошибка доступа"); + } + + return booking; + } + + @Override + public BookingDTO confirmOrRejectBooking(Long id, Long bId, Boolean approved) { + + validateBooking(bId); + + if (bRepo.getReferenceById(bId).getBooker().getId().equals(id) + && approved && bRepo.getReferenceById(bId).getId().equals(bId)) { + throw new NotFoundException("Товар не найден"); + } + if (approved && bRepo.getReferenceById(bId).getStatus().equals(BookingStatus.APPROVED) + && iRepo.getReferenceById(bRepo.getReferenceById(bId) + .getItem().getId()).getOwner().getId().equals(id)) { + throw new InvalidParameterException("Бронирование уже было подтверждено"); + } + + Booking booking = bRepo.getReferenceById(bId); + + if (approved) { + booking.setStatus(BookingStatus.APPROVED); + } else { + booking.setStatus(BookingStatus.REJECTED); + } + bRepo.save(booking); + return BookingMapper.toBookingDto(booking); + } + + @Override + public List findBookingByIdAndStatus(String state, Long id) { + validateUser(id); + validateState(state); + + List result = new ArrayList<>(); + + BookingStatus status = BookingStatus.valueOf(state); + + if (status.equals(BookingStatus.ALL)) { + result.addAll(bRepo.findBookingsByBookerId(id)); + + } else if (status.equals(BookingStatus.CURRENT)) { + result.addAll(bRepo.findBookingsByBookerIdWithCurrentStatus(id)); + + } else if (status.equals(BookingStatus.PAST)) { + result.addAll(bRepo.findBookingsByBookerIdWithPastStatus(id)); + + } else if (status.equals(BookingStatus.FUTURE)) { + result.addAll(bRepo.findBookingsByBookerIdWithFutureStatus(id)); + + } else if (status.equals(BookingStatus.WAITING)) { + result.addAll(bRepo.findBookingsByBookerIdWithWaitingOrRejectStatus(id, BookingStatus.WAITING)); + + } else if (status.equals(BookingStatus.REJECTED)) { + result.addAll(bRepo.findBookingsByBookerIdWithWaitingOrRejectStatus(id, BookingStatus.REJECTED)); + } + return result; + } + + @Override + public List findAllOwnersBookings(String state, Long id) { + validateUser(id); + validateState(state); + + List result = new ArrayList<>(); + + BookingStatus status = BookingStatus.valueOf(state); + + switch (status) { + case ALL: + result.addAll(bRepo.findAllOwnersBookings(id)); + break; + case FUTURE: + result.addAll(bRepo.findAllOwnersBookingsWithFutureStatus(id)); + break; + case CURRENT: + result.addAll(bRepo.findAllOwnersBookingsWithCurrentStatus(id)); + break; + case PAST: + result.addAll(bRepo.findAllOwnersBookingsWithPastStatus(id)); + break; + } + return result; + } +} diff --git a/src/main/java/ru/practicum/shareit/comment/Comment.java b/src/main/java/ru/practicum/shareit/comment/Comment.java new file mode 100644 index 000000000..15e8ba6c1 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/comment/Comment.java @@ -0,0 +1,50 @@ +package ru.practicum.shareit.comment; + +import lombok.*; +import org.hibernate.Hibernate; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import javax.persistence.*; +import java.time.LocalDateTime; +import java.util.Objects; + +@Entity +@Table(name = "comments", schema = "PUBLIC") +@Getter +@Setter +@ToString +@RequiredArgsConstructor +public class Comment { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "comment_id") + private Long id; + + @Column(name = "text", nullable = false) + private String text; + + @ManyToOne + @JoinColumn(name = "item_id", nullable = false) + private Item item; + + @ManyToOne + @JoinColumn(name = "author_id", nullable = false) + private User author; + + @Column(name = "created", nullable = false) + private LocalDateTime created = LocalDateTime.now(); + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Comment comment = (Comment) o; + return id != null && Objects.equals(id, comment.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/comment/CommentDTO.java b/src/main/java/ru/practicum/shareit/comment/CommentDTO.java new file mode 100644 index 000000000..8061010b0 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/comment/CommentDTO.java @@ -0,0 +1,25 @@ +package ru.practicum.shareit.comment; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.*; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.user.dto.UserDTO; + +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommentDTO { + @JsonInclude(JsonInclude.Include.NON_NULL) + private Long id; + @JsonInclude(JsonInclude.Include.NON_NULL) + private String text; + @JsonInclude(JsonInclude.Include.NON_NULL) + private ItemDTO item; + @JsonInclude(JsonInclude.Include.NON_NULL) + private UserDTO author; + private String authorName; + @JsonInclude(JsonInclude.Include.NON_NULL) + private LocalDateTime created; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/comment/CommentMapper.java b/src/main/java/ru/practicum/shareit/comment/CommentMapper.java new file mode 100644 index 000000000..00101e7df --- /dev/null +++ b/src/main/java/ru/practicum/shareit/comment/CommentMapper.java @@ -0,0 +1,38 @@ +package ru.practicum.shareit.comment; + +import ru.practicum.shareit.item.ItemMapper; +import ru.practicum.shareit.user.UserMapper; + +import java.util.HashSet; +import java.util.Set; + +public class CommentMapper { + + public static Comment toComment(CommentDTO commentDto) { + Comment comment = new Comment(); + comment.setId(commentDto.getId()); + comment.setText(commentDto.getText()); + comment.setItem(ItemMapper.toItem(commentDto.getItem())); + comment.setCreated(commentDto.getCreated()); + comment.setAuthor(UserMapper.toUser(commentDto.getAuthor())); + return comment; + } + + public static CommentDTO toCommentDto(Comment comment) { + CommentDTO commentDto = new CommentDTO(); + commentDto.setId(comment.getId()); + commentDto.setText(comment.getText()); + commentDto.setItem(ItemMapper.toIDto(comment.getItem())); + commentDto.setCreated(comment.getCreated()); + commentDto.setAuthor(UserMapper.toUserDto(comment.getAuthor())); + return commentDto; + } + + public static Set toCommentDtos(Set comments) { + Set dtos = new HashSet<>(); + for (Comment comment : comments) { + dtos.add(toCommentDto(comment)); + } + return dtos; + } +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/comment/CommentRepository.java b/src/main/java/ru/practicum/shareit/comment/CommentRepository.java new file mode 100644 index 000000000..545aa9eff --- /dev/null +++ b/src/main/java/ru/practicum/shareit/comment/CommentRepository.java @@ -0,0 +1,12 @@ +package ru.practicum.shareit.comment; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.Set; + +public interface CommentRepository extends JpaRepository { + + @Query(value = "SELECT c FROM Comment AS c WHERE c.item.id = ?1") + Set findAllItemComments(Long id); +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java b/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java index 51bc168bc..b9de1b941 100644 --- a/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java +++ b/src/main/java/ru/practicum/shareit/exceptions/ErrorResponse.java @@ -1,13 +1,11 @@ package ru.practicum.shareit.exceptions; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor public class ErrorResponse { private String error; - public ErrorResponse(String error) { - this.error = error; - } - - public String getError() { - return error; - } -} \ No newline at end of file +} diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index cf202d005..55865c94a 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -1,55 +1,61 @@ package ru.practicum.shareit.item; -import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import ru.practicum.shareit.exceptions.NotFoundException; +import ru.practicum.shareit.comment.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.item.service.ItemService; +import ru.practicum.shareit.item.service.ItemServiceImpl; -import javax.validation.Valid; -import javax.validation.ValidationException; import java.util.Collection; import java.util.List; @RestController +@Slf4j @RequestMapping("/items") -@RequiredArgsConstructor public class ItemController { - private static final String HEADER_USER_ID = "X-Sharer-User-Id"; - private final ItemService iService; + private final ItemServiceImpl itemService; + + @Autowired + public ItemController(ItemServiceImpl itemService) { + this.itemService = itemService; + } @PostMapping - public ItemDTO createItem(@RequestHeader(HEADER_USER_ID) Long userId, @Valid @RequestBody ItemDTO iDto) - throws ValidationException, NotFoundException { - return iService.createItem(userId, iDto); + public ItemDTO createItem(@RequestHeader("X-Sharer-User-Id") Long id, + @RequestBody ItemDTO itemDto) { + return itemService.createItem(id, itemDto); + } + + @PatchMapping("/{itemId}") + public ItemDTO updateItem(@RequestHeader("X-Sharer-User-Id") Long id, @PathVariable Long itemId, + @RequestBody ItemDTO itemDto) { + return itemService.updateItem(itemService.patchItem(itemDto, itemId, id)); } @GetMapping("/{itemId}") - public ItemDTO findItemById(@PathVariable String itemId) throws NotFoundException { - return iService.findById(Long.valueOf(itemId)); + public ItemDTO findItemById(@RequestHeader("X-Sharer-User-Id") Long id, + @PathVariable Long itemId) { + return itemService.findItemById(id, itemId); } @GetMapping - public Collection findAll(@RequestHeader(HEADER_USER_ID) String userId) - throws NotFoundException { - return iService.findByUser(Long.valueOf(userId)); + public List findAllOwnersItems(@RequestHeader("X-Sharer-User-Id") Long id) { + return itemService.findAllItemsByOwner(id); } - @PatchMapping("/{itemId}") - public ItemDTO updateItem(@RequestHeader(HEADER_USER_ID) String userId, @PathVariable String itemId, - @Valid @RequestBody ItemDTO iDto) throws NotFoundException { - return iService.update(Long.valueOf(userId), Long.valueOf(itemId), iDto); + @GetMapping("/search") + public Collection findItemByString(@RequestParam String text) { + return itemService.getAllItemsByString(text); } - @DeleteMapping("/{itemId}") - public Long deleteItem(@RequestHeader(HEADER_USER_ID) String userId, @PathVariable String itemId) - throws NotFoundException { - return iService.deleteItem(Long.valueOf(userId), Long.valueOf(itemId)); + @PostMapping("/{itemId}/comment") + public CommentDTO postComment(@RequestHeader("X-Sharer-User-Id") Long id, + @PathVariable Long itemId, + @RequestBody CommentDTO commentDto) { + return itemService.postComment(id, itemId, commentDto); } - @GetMapping("/search") - public List searchItemByText(@RequestParam String text) { - return iService.search(text); - } + } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/ItemMapper.java index 1b299741c..c2df6a7fb 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/ItemMapper.java @@ -1,28 +1,54 @@ package ru.practicum.shareit.item; -import org.springframework.stereotype.Service; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.springframework.stereotype.Component; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.UserMapper; -@Service +@Component +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class ItemMapper { - public ItemDTO toIDto(Item item) { - return ItemDTO.builder() - .id(item.getId()) - .name(item.getName()) - .description(item.getDescription()) - .available(item.getAvailable()) - .request(item.getRequest() != null ? item.getRequest() : null) - .build(); + + public static Item toItem(ItemDTO itemDto) { + Item item = new Item(); + item.setId(itemDto.getId()); + item.setName(itemDto.getName()); + item.setDescription(itemDto.getDescription()); + item.setIsAvailable(itemDto.getIsAvailable()); + item.setOwner(UserMapper.toUser(itemDto.getOwner())); + item.setRequestId(itemDto.getRequestId()); + return item; + } + + public static ItemDTO toIDto(Item item) { + ItemDTO itemDto = new ItemDTO(); + itemDto.setId(item.getId()); + itemDto.setName(item.getName()); + itemDto.setDescription(item.getDescription()); + itemDto.setIsAvailable(item.getIsAvailable()); + itemDto.setOwner(UserMapper.toUserDto(item.getOwner())); + itemDto.setRequestId(item.getRequestId()); + return itemDto; } - public Item toItem(ItemDTO itemDto) { - return Item.builder() - .id(itemDto.getId()) - .name(itemDto.getName()) - .description(itemDto.getDescription()) - .available(itemDto.getAvailable()) - .request(itemDto.getRequest() != null ? itemDto.getRequest() : null) - .build(); + /* public static ItemDTOBooking toItemDtoBooking(Item item) { + ItemDTOBooking iDtoBooking = new ItemDTOBooking(); + iDtoBooking.setId(item.getId()); + iDtoBooking.setName(item.getName()); + iDtoBooking.setDescription(item.getDescription()); + iDtoBooking.setIsAvailable(item.getIsAvailable()); + return iDtoBooking; } + + public static List toItemBookingDtos(List items) { + List temp = new ArrayList<>(); + for (Item item : items) { + temp.add(toItemDtoBooking(item)); + } + return temp; + } + + */ } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java index 0e0e524b2..d94a121c2 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java @@ -1,15 +1,75 @@ package ru.practicum.shareit.item.dto; -import lombok.Builder; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.comment.CommentDTO; +import ru.practicum.shareit.user.dto.UserDTO; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.Set; @Data -@Builder +@AllArgsConstructor +@NoArgsConstructor public class ItemDTO { + @JsonInclude(JsonInclude.Include.NON_NULL) private Long id; + + @JsonInclude(JsonInclude.Include.NON_NULL) private String name; + + @JsonInclude(JsonInclude.Include.NON_NULL) private String description; - private Boolean available; - private Long owner; - private String request; + + @NotNull + @JsonProperty(value = "available") + @JsonInclude(JsonInclude.Include.NON_NULL) + private Boolean isAvailable; + + @JsonInclude(JsonInclude.Include.NON_NULL) + private UserDTO owner; + + @JsonInclude(JsonInclude.Include.NON_NULL) + private Long requestId; + + private BookingDTO lastBooking; + + private BookingDTO nextBooking; + + @JsonInclude(JsonInclude.Include.NON_NULL) + private Set comments = new HashSet<>(); + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class User { + private Long id; + private String name; + private String email; + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Booking { + private Long id; + private Long bookerId; + private LocalDateTime start; + private LocalDateTime end; + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Comment { + Long id; + String text; + String authorName; + } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOBooking.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOBooking.java new file mode 100644 index 000000000..8e435b6ae --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOBooking.java @@ -0,0 +1,25 @@ +package ru.practicum.shareit.item.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.booking.model.Booking; + +import javax.validation.constraints.NotNull; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ItemDTOBooking { + private Long id; + private String name; + private String description; + @NotNull + @JsonProperty(value = "available") + private Boolean isAvailable; + private Booking lastBooking; + private Booking nextBooking; +} diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index 8e70899ca..6765e8c08 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -1,16 +1,69 @@ package ru.practicum.shareit.item.model; -import lombok.Builder; -import lombok.Data; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.hibernate.Hibernate; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.comment.Comment; import ru.practicum.shareit.user.model.User; -@Data -@Builder +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Objects; + + +@Table(name = "items") +@Getter +@Setter +@ToString +@RequiredArgsConstructor +@Entity public class Item { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "item_id") private Long id; + + @Column(name = "name", nullable = false) private String name; + + @Column(name = "description", nullable = false) private String description; - private Boolean available; - private String request; + + @NotNull + @JsonProperty(value = "available") + @Column(name = "available", nullable = false) + private Boolean isAvailable; + + @ManyToOne + @JoinColumn(name = "owner_id", nullable = false) private User owner; + + @Column(name = "request_id") + private Long requestId; + + @Transient + private Booking lastBooking; + @Transient + private Booking nextBooking; + @OneToMany() + @JoinColumn(name = "item_id") + @ToString.Exclude + Collection comments = new ArrayList<>(); + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Item item = (Item) o; + return id != null && Objects.equals(id, item.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java index 6a1c68e84..5240276db 100644 --- a/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java @@ -1,28 +1,17 @@ package ru.practicum.shareit.item.repository; -import ru.practicum.shareit.exceptions.NotFoundException; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.user.model.User; import java.util.Collection; -import java.util.Map; -public interface ItemRepository { - Item create(Long uId, Item item, User user); +public interface ItemRepository extends JpaRepository { - Item findById(Long itemId); - - Collection findByUserId(Long userId); - - Map findAll(); - - Item update(Long itemId, Item item); - - Long delete(Long itemId); + @Query(value = "SELECT i FROM Item i WHERE i.owner.id = ?1") + Collection findAllItemsByOwner(Long id); + @Query("select i from Item i" + " where upper(i.name) like upper(concat('%', ?1, '%'))" + " or upper(i.description) like upper(concat('%', ?1, '%'))") Collection search(String text); - - boolean checkOwner(Long userId, Long itemId); - - void checkItemId(Long itemId) throws NotFoundException; } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java index 83fb97a7d..f6b33415e 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemService.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -1,25 +1,20 @@ package ru.practicum.shareit.item.service; -import org.springframework.stereotype.Repository; -import ru.practicum.shareit.exceptions.NotFoundException; -import ru.practicum.shareit.exceptions.ValidationException; +import ru.practicum.shareit.comment.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.model.Item; import java.util.Collection; import java.util.List; -@Repository public interface ItemService { - ItemDTO createItem(Long userId, ItemDTO itemDto) throws ValidationException, NotFoundException; + List findAllItemsByOwner(Long id); - ItemDTO findById(Long itemId) throws NotFoundException; + Collection getAllItemsByString(String someText); - Collection findByUser(Long userId) throws NotFoundException; + ItemDTO patchItem(ItemDTO itemDto, Long itemId, Long id); - ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws NotFoundException; + ItemDTO findItemById(Long userId, Long itemId); - Long deleteItem(Long userId, Long itemId) throws NotFoundException; - - List search(String text); -} \ No newline at end of file + CommentDTO postComment(Long userId, Long itemId, CommentDTO commentDto); + } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index a8b8c31f7..270dd7829 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -1,109 +1,224 @@ package ru.practicum.shareit.item.service; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import ru.practicum.shareit.booking.BookingMapper; +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.repository.BookingRepository; +import ru.practicum.shareit.comment.Comment; +import ru.practicum.shareit.comment.CommentDTO; +import ru.practicum.shareit.comment.CommentMapper; +import ru.practicum.shareit.comment.CommentRepository; import ru.practicum.shareit.exceptions.InvalidParameterException; import ru.practicum.shareit.exceptions.NotFoundException; -import ru.practicum.shareit.exceptions.ValidationException; import ru.practicum.shareit.item.ItemMapper; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.item.repository.ItemRepository; -import ru.practicum.shareit.user.*; -import ru.practicum.shareit.user.dto.UserDTO; -import ru.practicum.shareit.user.service.UserService; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.user.repository.UserRepository; +import ru.practicum.shareit.user.service.UserServiceImpl; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; +import java.time.LocalDateTime; +import java.util.*; -@Slf4j @Service -@RequiredArgsConstructor public class ItemServiceImpl implements ItemService { - private final UserService uService; - private final UserMapper uMapper; - private final ItemRepository iRepository; - private final ItemMapper iMapper; + private final ItemRepository itemRepository; + private final UserServiceImpl userService; + private final BookingRepository bookingRepository; + private final UserRepository userRepository; + private final CommentRepository commentRepository; + + @Autowired + public ItemServiceImpl(ItemRepository itemRepository, UserServiceImpl userService, BookingRepository bookingRepository, UserRepository userRepository, CommentRepository commentRepository) { + this.itemRepository = itemRepository; + this.userService = userService; + this.bookingRepository = bookingRepository; + this.userRepository = userRepository; + this.commentRepository = commentRepository; + } - @Override - public ItemDTO createItem(Long uId, ItemDTO iDto) throws ValidationException, NotFoundException { - validate(uId, iDto); - UserDTO uDto = uService.findById(uId); - Item item = iRepository.create(uId, iMapper.toItem(iDto), uMapper.toUser(uDto)); - log.info("Товар id {} создан", item.getId()); - return iMapper.toIDto(item); + public ItemDTO createItem(Long id, ItemDTO itemDto) { + validateItemDto(itemDto); + itemDto.setOwner(userService.findUserById(id)); + // return itemDto; + return ItemMapper.toIDto(itemRepository.save(ItemMapper.toItem(itemDto))); } - private void validate(Long uId, ItemDTO iDto) { - uService.checkId(uId); - if (!StringUtils.hasText(iDto.getName())) { - throw new InvalidParameterException("Имя не может быть пустым"); + public ItemDTO updateItem(ItemDTO itemDto) { + Item temp = itemRepository.getReferenceById(itemDto.getId()); + if (itemDto.getName() != null && !itemDto.getName().equals("")) { + temp.setName(itemDto.getName()); + } + if (itemDto.getIsAvailable() != null) { + temp.setIsAvailable(itemDto.getIsAvailable()); + } + if (itemDto.getDescription() != null && !itemDto.getDescription().equals("")) { + temp.setDescription(itemDto.getDescription()); + } + if (itemDto.getOwner().getId() != null && itemDto.getOwner().getId() != 0) { + temp.setOwner(UserMapper.toUser(itemDto.getOwner())); } + if (itemDto.getRequestId() != null && itemDto.getRequestId() != 0) { + temp.setRequestId(itemDto.getRequestId()); + } + return ItemMapper.toIDto(itemRepository.save(temp)); + } - if (iDto.getDescription() == null) { - throw new InvalidParameterException("Описание не может быть пустым"); + public ItemDTO findItemById(Long userId, Long itemId) { + validateItem(itemId); + ItemDTO itemDto = ItemMapper.toIDto(itemRepository.getReferenceById(itemId)); + Set comments = CommentMapper.toCommentDtos(commentRepository.findAllItemComments(itemId)); + for (CommentDTO commentDto : comments) { + itemDto.getComments().add(commentDto); + for (CommentDTO commentDtoName : itemDto.getComments()) { + commentDtoName.setAuthorName(commentDtoName.getAuthor().getName()); + } } - if (iDto.getAvailable() == null) { - throw new InvalidParameterException("Статус доступности не может быть пустым"); + if (Objects.equals(itemRepository.getReferenceById(itemId).getOwner().getId(), userId)) { + List bookingPast = bookingRepository.findAllItemBookingsPast(itemId); + if (bookingPast.size() != 0) { + bookingPast.sort(Comparator.comparing(Booking::getStart).reversed()); + BookingDTO bookingDtoPast = BookingMapper.toBookingDto(bookingPast.get(0)); + bookingDtoPast.setBooker(bookingDtoPast.getBooker()); + bookingDtoPast.setBooker(null); + itemDto.setLastBooking(bookingDtoPast); + } + List bookingFuture = bookingRepository.findAllItemBookingsFuture(itemId); + if (bookingFuture.size() != 0) { + bookingFuture.sort(Comparator.comparing(Booking::getStart)); + BookingDTO bookingDtoFuture = BookingMapper.toBookingDto(bookingFuture.get(0)); + bookingDtoFuture.setBooker(bookingDtoFuture.getBooker()); + bookingDtoFuture.setBooker(null); + itemDto.setNextBooking(bookingDtoFuture); + } } + return itemDto; } @Override - public ItemDTO findById(Long id) throws NotFoundException { - iRepository.checkItemId(id); - Item item = iRepository.findById(id); - return iMapper.toIDto(item); + public List findAllItemsByOwner(Long id) { + validateUser(id); + // List itemDtoList = (List) ItemMapper.toIDto((Item) itemRepository.findAllItemsByOwner(id)); + List itemDtoList = new ArrayList<>(); + itemDtoList.addAll(itemRepository.findAllItemsByOwner(id)); + + for (ItemDTO itemDto : itemDtoList) { + List bookingPast = bookingRepository.findAllItemBookingsPast(itemDto.getId()); + if (bookingPast.size() != 0) { + bookingPast.sort(Comparator.comparing(Booking::getStart).reversed()); + BookingDTO bookingDtoPast = BookingMapper.toBookingDto(bookingPast.get(0)); + bookingDtoPast.setBooker(bookingDtoPast.getBooker()); + bookingDtoPast.setBooker(null); + itemDto.setLastBooking(bookingDtoPast); + } + List bookingFuture = bookingRepository.findAllItemBookingsFuture(itemDto.getId()); + if (bookingFuture.size() != 0) { + bookingFuture.sort(Comparator.comparing(Booking::getStart)); + BookingDTO bookingDtoFuture = BookingMapper.toBookingDto(bookingFuture.get(0)); + bookingDtoFuture.setBooker(bookingDtoFuture.getBooker()); + bookingDtoFuture.setBooker(null); + itemDto.setNextBooking(bookingDtoFuture); + } + } + itemDtoList.sort(Comparator.comparing(ItemDTO::getId)); + return itemDtoList; } @Override - public Collection findByUser(Long id) throws NotFoundException { - uService.checkId(id); + public Collection getAllItemsByString(String text) { + if (!StringUtils.hasText(text)) { + return Collections.emptyList(); + } - return iRepository.findByUserId(id).stream().map(iMapper::toIDto).collect(Collectors.toList()); + return itemRepository.search(text); } @Override - public ItemDTO update(Long userId, Long itemId, ItemDTO iDto) throws NotFoundException { - uService.checkId(userId); - iRepository.checkItemId(itemId); + public ItemDTO patchItem(ItemDTO itemDto, Long itemId, Long id) { + if (findItemById(id, itemId) != null) { + if (!Objects.equals(findItemById(id, itemId).getOwner().getId(), id)) { + throw new NotFoundException("Данный товар принадлежит другому пользователю"); + } + } + itemDto.setId(itemId); - if (iRepository.checkOwner(userId, itemId)) { - throw new NotFoundException("Неправльный владелец"); + if (findItemById(id, itemDto.getId()) == null) { + throw new NotFoundException("Такого товара нет"); + } + ItemDTO patchedItem = findItemById(id, itemDto.getId()); + if (itemDto.getName() != null) { + patchedItem.setName(itemDto.getName()); } + if (itemDto.getDescription() != null) { + patchedItem.setDescription(itemDto.getDescription()); + } + if (itemDto.getIsAvailable() != null) { + patchedItem.setIsAvailable(itemDto.getIsAvailable()); + } + return patchedItem; + } - Item item = iRepository.update(itemId, iMapper.toItem(iDto)); - log.info("Обновлено id {}", item.getId()); - return iMapper.toIDto(item); + public CommentDTO postComment(Long userId, Long itemId, CommentDTO commentDto) { + validateComment(commentDto); + validateUser(userId); + validateItem(itemId); + + List bookings = bookingRepository.findAllItemBookings(itemId); + for (Booking booking : bookings) { + if (!Objects.equals(booking.getBooker().getId(), userId)) { + throw new InvalidParameterException("Проверьте заданные параметры"); + } else { + if (booking.getEnd().isBefore(LocalDateTime.now())) { + commentDto.setItem(ItemMapper.toIDto(itemRepository.getReferenceById(itemId))); + commentDto.setAuthor(UserMapper.toUserDto(userRepository.getReferenceById(userId))); + commentDto.setCreated(LocalDateTime.now()); + Comment commentTemp = commentRepository.save(CommentMapper.toComment(commentDto)); + CommentDTO commentTempDto = CommentMapper.toCommentDto(commentTemp); + User user = userRepository.getReferenceById(userId); + commentTempDto.setAuthorName(user.getName()); + commentTempDto.setAuthor(null); + commentTempDto.setItem(null); + return commentTempDto; + } else { + throw new InvalidParameterException("Проверьте заданные параметры"); + } + } + } + return null; } - @Override - public Long deleteItem(Long userId, Long itemId) throws NotFoundException { - uService.checkId(userId); - iRepository.checkItemId(itemId); + private void validateUser(Long id) { + if (!userRepository.existsById(id)) { + throw new NotFoundException("Пользователь не найден"); + } + } - Long itemDeletedId = iRepository.delete(itemId); - log.info("Удалено id {}", itemDeletedId); - return itemDeletedId; + private void validateItem(Long itemId) { + if (!itemRepository.existsById(itemId)) { + throw new NotFoundException("Товар не найден"); + } } - @Override - public List search(String text) { - List availableItems = new ArrayList<>(); - if (text.length() > 0 && !text.trim().equals("")) { - for (Item itemFromStorage : iRepository.findAll().values()) { - if (itemFromStorage.getAvailable() && - (itemFromStorage.getDescription().toLowerCase().contains(text.toLowerCase()) - || itemFromStorage.getName().toLowerCase().contains(text.toLowerCase()))) { - availableItems.add(itemFromStorage); - } - } + private void validateItemDto(ItemDTO itemDto) { + if (itemDto.getIsAvailable() == null) { + throw new InvalidParameterException("Укажите доступность товара"); + } else if (itemDto.getName() == null || itemDto.getName().equals("")) { + throw new InvalidParameterException("Название товара не может быть пустым"); + } else if (itemDto.getDescription() == null || itemDto.getDescription().equals("")) { + throw new InvalidParameterException("Описание товара не может юыть пустым"); + } + } + + private void validateComment(CommentDTO commentDto) { + if (commentDto.getText().isEmpty() || commentDto.getText().isBlank()) { + throw new InvalidParameterException("Комментарий не может юыть пусьым"); } - return availableItems; } -} +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/request/RequestMapper.java b/src/main/java/ru/practicum/shareit/request/RequestMapper.java index 0963aed95..ce20aa667 100644 --- a/src/main/java/ru/practicum/shareit/request/RequestMapper.java +++ b/src/main/java/ru/practicum/shareit/request/RequestMapper.java @@ -17,12 +17,12 @@ public ItemRequestDTO toItemDto(ItemRequest item) { } public ItemRequest toItem(ItemRequestDTO itemDto) { - return ItemRequest.builder() - .id(itemDto.getId()) - .description(itemDto.getDescription()) - .requester(toUser(itemDto.getRequester())) - .created(itemDto.getCreated()) - .build(); + return new ItemRequest( + itemDto.getId(), + itemDto.getDescription(), + toUser(itemDto.getRequester()), + itemDto.getCreated() + ); } private ItemRequestDTO.User toUserItemRequest(User user) { @@ -34,10 +34,10 @@ private ItemRequestDTO.User toUserItemRequest(User user) { } private User toUser(ItemRequestDTO.User bookingUser) { - return User.builder() - .id(bookingUser.getId()) - .name(bookingUser.getName()) - .email(bookingUser.getEmail()) - .build(); + User user = new User(); + user.setId(bookingUser.getId()); + user.setName(bookingUser.getName()); + user.setEmail(bookingUser.getEmail()); + return user; } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java index 240a2d2af..5bba11a66 100644 --- a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java +++ b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -1,17 +1,40 @@ package ru.practicum.shareit.request.model; -import lombok.Builder; -import lombok.Data; +import lombok.*; +import org.hibernate.Hibernate; import ru.practicum.shareit.user.model.User; +import javax.persistence.*; import java.time.LocalDateTime; +import java.util.Objects; -@Data -@Builder +@Entity +@Getter +@Setter +@ToString +@RequiredArgsConstructor +@Table(name = "requests") +@AllArgsConstructor public class ItemRequest { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String description; + @ManyToOne + @JoinColumn(name = "requester_id") private User requester; private LocalDateTime created; -} + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + ItemRequest that = (ItemRequest) o; + return id != null && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 9a2846ca0..182c725e1 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -1,48 +1,50 @@ package ru.practicum.shareit.user; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; -import ru.practicum.shareit.exceptions.NotFoundException; -import ru.practicum.shareit.exceptions.ValidationException; import ru.practicum.shareit.user.dto.UserDTO; -import ru.practicum.shareit.user.service.UserService; +import ru.practicum.shareit.user.service.UserServiceImpl; -import javax.validation.Valid; -import java.util.Collection; +import java.util.List; @RestController -@RequestMapping(path = "/users") -@RequiredArgsConstructor +@Slf4j +@RequestMapping("/users") public class UserController { - private final UserService userService; + + private final UserServiceImpl userService; + + @Autowired + public UserController(UserServiceImpl userService) { + this.userService = userService; + } @PostMapping - public UserDTO create(@Valid @RequestBody UserDTO uDto) throws ValidationException { - return userService.create(uDto); + public UserDTO createUser(@RequestBody UserDTO userDto) { + return userService.createUser(userDto); } - @GetMapping("/{userId}") - public UserDTO findUserById(@PathVariable String userId) throws NotFoundException { - return userService.findById(Long.valueOf(userId)); + @PatchMapping("/{userId}") + public UserDTO updateUser(@RequestBody UserDTO userDto, @PathVariable Long userId) { + return userService.updateUser(userService.patchUser(userDto, userId)); } @GetMapping - public Collection findAllUsers() { - return userService.findAll(); + public List getAllUsers() { + return userService.findAllUsers(); } - @PatchMapping("/{userId}") - public UserDTO update(@PathVariable String userId, @Valid @RequestBody UserDTO userDto) throws ValidationException, - NotFoundException { - return userService.update(Long.valueOf(userId), userDto); + @GetMapping("/{id}") + public UserDTO getUserById(@PathVariable Long id) { + return userService.findUserById(id); } - @DeleteMapping("/{userId}") - public Long deleteUser(@PathVariable String userId) throws NotFoundException { - return userService.delete(Long.valueOf(userId)); + @DeleteMapping("/{id}") + public void deleteUserById(@PathVariable Long id) { + userService.deleteUserById(id); } - } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index 398b62175..9022c277a 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -4,22 +4,32 @@ import ru.practicum.shareit.user.dto.UserDTO; import ru.practicum.shareit.user.model.User; +import java.util.ArrayList; +import java.util.List; + @Component public class UserMapper { + public static UserDTO toUserDto(User user) { + UserDTO userDto = new UserDTO(); + userDto.setId(user.getId()); + userDto.setName(user.getName()); + userDto.setEmail(user.getEmail()); + return userDto; + } - public UserDTO toUserDTO(User user) { - return UserDTO.builder() - .id(user.getId()) - .name(user.getName()) - .email(user.getEmail()) - .build(); + public static User toUser(UserDTO userDto) { + User user = new User(); + user.setId(userDto.getId()); + user.setName(userDto.getName()); + user.setEmail(userDto.getEmail()); + return user; } - public User toUser(UserDTO userDto) { - return User.builder() - .id(userDto.getId()) - .name(userDto.getName()) - .email(userDto.getEmail()) - .build(); + public static List toUserDTOs(List users) { + List tempUsers = new ArrayList<>(); + for (User user : users) { + tempUsers.add(toUserDto(user)); + } + return tempUsers; } } diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java index 82198eb8a..79e3c73ef 100644 --- a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java @@ -1,12 +1,16 @@ package ru.practicum.shareit.user.dto; -import lombok.Builder; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import javax.validation.constraints.Email; @Data -@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) public class UserDTO { private Long id; private String name; diff --git a/src/main/java/ru/practicum/shareit/user/model/User.java b/src/main/java/ru/practicum/shareit/user/model/User.java index 9a04c5856..466373555 100644 --- a/src/main/java/ru/practicum/shareit/user/model/User.java +++ b/src/main/java/ru/practicum/shareit/user/model/User.java @@ -1,12 +1,42 @@ package ru.practicum.shareit.user.model; -import lombok.Builder; -import lombok.Data; +import lombok.*; +import org.hibernate.Hibernate; -@Data -@Builder +import javax.persistence.*; +import javax.validation.constraints.Email; +import java.util.Objects; + +@Entity +@Table(name = "users") +@Getter +@Setter +@ToString +@RequiredArgsConstructor public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id") private Long id; - private String email; + + @Column(name = "name", nullable = false) private String name; + + @Column(name = "email", nullable = false) + @Email + private String email; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + User user = (User) o; + return id != null && Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/repository/UserRepository.java b/src/main/java/ru/practicum/shareit/user/repository/UserRepository.java index b22863be0..45dfa1fc7 100644 --- a/src/main/java/ru/practicum/shareit/user/repository/UserRepository.java +++ b/src/main/java/ru/practicum/shareit/user/repository/UserRepository.java @@ -1,25 +1,7 @@ package ru.practicum.shareit.user.repository; -import org.springframework.stereotype.Repository; -import ru.practicum.shareit.exceptions.NotFoundException; +import org.springframework.data.jpa.repository.JpaRepository; import ru.practicum.shareit.user.model.User; -import javax.validation.ValidationException; -import java.util.Map; - -@Repository -public interface UserRepository { - User create(User user); - - User findById(Long userId); - - Map findAll(); - - User update(Long userId, User user); - - Long delete(Long userId); - - void checkId(Long userId) throws NotFoundException; - - void checkEmail(String email) throws ValidationException; +public interface UserRepository extends JpaRepository { } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/service/UserService.java b/src/main/java/ru/practicum/shareit/user/service/UserService.java index cce3acab4..72946c17d 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserService.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserService.java @@ -1,24 +1,8 @@ package ru.practicum.shareit.user.service; - -import ru.practicum.shareit.exceptions.NotFoundException; import ru.practicum.shareit.user.dto.UserDTO; -import javax.validation.ValidationException; -import java.util.Collection; - public interface UserService { - UserDTO create(UserDTO uDto) throws ValidationException; - - - UserDTO findById(Long id) throws NotFoundException; - - Collection findAll(); - - UserDTO update(Long id, UserDTO uDto) throws ValidationException, NotFoundException; - - Long delete(Long userId) throws NotFoundException; - - void checkId(Long userId) throws NotFoundException; + UserDTO patchUser(UserDTO userDto, Long userId); } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java index ce425be7d..56a629043 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -1,73 +1,85 @@ package ru.practicum.shareit.user.service; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; -import org.springframework.web.client.HttpClientErrorException; +import ru.practicum.shareit.exceptions.InvalidParameterException; import ru.practicum.shareit.exceptions.NotFoundException; import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.dto.UserDTO; -import ru.practicum.shareit.user.model.User; import ru.practicum.shareit.user.repository.UserRepository; import javax.validation.ValidationException; -import java.util.Collection; -import java.util.stream.Collectors; +import java.util.List; -@Slf4j @Service -@RequiredArgsConstructor public class UserServiceImpl implements UserService { private final UserRepository userRepository; - private final UserMapper userMapper; - @Override - public UserDTO create(UserDTO uDto) throws ValidationException { - userRepository.checkEmail(uDto.getEmail()); - User user = userRepository.create(userMapper.toUser(uDto)); - log.info("Пользователь id {} создан", user.getId()); - return userMapper.toUserDTO(user); + @Autowired + public UserServiceImpl(UserRepository userRepository) { + this.userRepository = userRepository; } - @Override - public UserDTO findById(Long id) throws NotFoundException { - checkId(id); - User user = userRepository.findById(id); - log.info("Получен пользователь id {}", user.getId()); - return userMapper.toUserDTO(user); + public List findAllUsers() { + return UserMapper.toUserDTOs(userRepository.findAll()); } - @Override - public Collection findAll() { - return userRepository.findAll() - .values() - .stream() - .map(userMapper::toUserDTO) - .collect(Collectors.toList()); + public UserDTO findUserById(Long id) { + validateUser(id); + return UserMapper.toUserDto(userRepository.getReferenceById(id)); } - @Override - public UserDTO update(Long id, UserDTO uDto) throws ValidationException, NotFoundException { - checkId(id); - if (StringUtils.hasText(uDto.getEmail())) { - userRepository.checkEmail(uDto.getEmail()); + public UserDTO createUser(UserDTO userDto) { + validateEmail(userDto); + return UserMapper.toUserDto(userRepository.save(UserMapper.toUser(userDto))); + } + + public UserDTO updateUser(UserDTO userDto) { + UserDTO temp = UserMapper.toUserDto(userRepository.getReferenceById(userDto.getId())); + if (userDto.getName() != null && !userDto.getName().equals("")) { + temp.setName(userDto.getName()); + } + if (userDto.getEmail() != null && !userDto.getEmail().equals("")) { + temp.setEmail(userDto.getEmail()); } - User user = userRepository.update(id, userMapper.toUser(uDto)); - log.info("Пользователь id {} обновлен", user.getId()); - return userMapper.toUserDTO(user); + return UserMapper.toUserDto(userRepository.save(UserMapper.toUser(temp))); } - @Override - public Long delete(Long id) throws HttpClientErrorException.NotFound, NotFoundException { - checkId(id); - Long userDelId = userRepository.delete(id); - log.info("Пользователь id {} удален", id); - return userDelId; + public void deleteUserById(Long id) { + userRepository.deleteById(id); } @Override - public void checkId(Long id) throws HttpClientErrorException.NotFound, NotFoundException { - userRepository.checkId(id); + public UserDTO patchUser(UserDTO userDto, Long userId) { + userDto.setId(userId); + if (findUserById(userDto.getId()) == null) { + throw new NotFoundException("Пользователь не найден"); + } + UserDTO patchedUser = findUserById(userDto.getId()); + if (userDto.getName() != null) { + patchedUser.setName(userDto.getName()); + } + if (userDto.getEmail() != null) { + for (UserDTO storedUser : findAllUsers()) { + if (userDto.getEmail().equals(storedUser.getEmail())) { + throw new ValidationException("Пользователь с таекой почтой уже существует"); + } + } + patchedUser.setEmail(userDto.getEmail()); + } + return patchedUser; + } + + private void validateUser(Long id) { + if (!userRepository.existsById(id)) { + throw new NotFoundException("Пользователь не найден"); + } } + + private void validateEmail(UserDTO userDto) { + if (userDto.getEmail() == null || !userDto.getEmail().contains("@")) { + throw new InvalidParameterException("Почта не может быть пустой"); + } + } + } \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c359e8d7a..b8c1f8d28 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,22 +1,10 @@ spring.jpa.hibernate.ddl-auto=none -spring.jpa.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect -spring.jpa.hibernate.show_sql=true - +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.properties.hibernate.format_sql=true spring.sql.init.mode=always -# TODO Append connection to DB - - - -logging.level.org.springframework.orm.jpa=INFO -logging.level.org.springframework.transaction=INFO -logging.level.org.springframework.transaction.interceptor=TRACE -logging.level.org.springframework.orm.jpa.JpaTransactionManager=DEBUG -#--- spring.config.activate.on-profile=ci,test spring.datasource.driverClassName=org.h2.Driver spring.datasource.url=jdbc:h2:mem:shareit spring.datasource.username=test spring.datasource.password=test - -spring.h2.console.enabled=true \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 000000000..25347c901 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,43 @@ +CREATE TABLE IF NOT EXISTS users ( + user_id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL UNIQUE, + name VARCHAR(255) NOT NULL, + email VARCHAR(512) NOT NULL UNIQUE +); + + +CREATE TABLE IF NOT EXISTS requests ( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL UNIQUE, + description VARCHAR(512) NOT NULL, + requester_id BIGINT REFERENCES users (user_id), + created TIMESTAMP WITHOUT TIME ZONE CHECK NOT NULL + +); + +CREATE TABLE IF NOT EXISTS items ( + item_id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL UNIQUE, + name VARCHAR(255) NOT NULL, + description VARCHAR(512) NOT NULL, + available BOOLEAN NOT NULL, + owner_id BIGINT REFERENCES users (user_id), + request_id BIGINT REFERENCES requests (id) +); + +CREATE TABLE IF NOT EXISTS bookings ( + booking_id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL UNIQUE, + start_date TIMESTAMP WITHOUT TIME ZONE CHECK (start_date < end_date), + end_date TIMESTAMP WITHOUT TIME ZONE CHECK (end_date > start_date), + item_id BIGINT REFERENCES items (item_id), + booker_id BIGINT REFERENCES users (user_id), + status varchar(50) CHECK (status IN ('WAITING', 'APPROVED', 'REJECTED', 'CANCELED')) +); + + + + +CREATE TABLE IF NOT EXISTS comments ( + comment_id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL UNIQUE, + text VARCHAR(512) NOT NULL, + item_id BIGINT REFERENCES items (item_id), + author_id BIGINT REFERENCES users (user_id), + created TIMESTAMP WITHOUT TIME ZONE CHECK NOT NULL +); diff --git a/src/test/java/ru/practicum/shareit/ShareItTests.java b/src/test/java/ru/practicum/shareit/ShareItTests.java index 4d79052f0..77f8aa7fc 100644 --- a/src/test/java/ru/practicum/shareit/ShareItTests.java +++ b/src/test/java/ru/practicum/shareit/ShareItTests.java @@ -2,8 +2,10 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; @SpringBootTest +@ContextConfiguration class ShareItTests { @Test