diff --git a/src/main/java/ru/practicum/shareit/booking/Booking.java b/src/main/java/ru/practicum/shareit/booking/Booking.java index 2d9c666..d76494a 100644 --- a/src/main/java/ru/practicum/shareit/booking/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/Booking.java @@ -1,7 +1,28 @@ package ru.practicum.shareit.booking; +import lombok.Data; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; + /** * TODO Sprint add-bookings. */ +@Data public class Booking { + private Long id; + private LocalDateTime start; + private LocalDateTime end; + private Item item; + private User booker; + private Status status; + + enum Status { + WAITING, + APPROVED, + REJECTED, + CANCELED + } + } diff --git a/src/main/java/ru/practicum/shareit/exception/AlreadyExistException.java b/src/main/java/ru/practicum/shareit/exception/AlreadyExistException.java new file mode 100644 index 0000000..5378b90 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/AlreadyExistException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.exception; + +public class AlreadyExistException extends RuntimeException { + public AlreadyExistException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java new file mode 100644 index 0000000..000fbff --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java @@ -0,0 +1,41 @@ +package ru.practicum.shareit.exception; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +public class ErrorHandler { + + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleValidationException(MethodArgumentNotValidException e) { + log.debug(e.getBindingResult().getAllErrors().getFirst().getDefaultMessage(), e); + return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getBindingResult().getAllErrors().getFirst().getDefaultMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse handleValidationException(NotFoundException e) { + log.debug(e.getMessage(), e); + return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.CONFLICT) + public ErrorResponse handleValidationException(AlreadyExistException e) { + log.debug(e.getMessage(), e); + return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.FORBIDDEN) + public ErrorResponse handleValidationException(NotAccessException e) { + log.debug(e.getMessage(), e); + return new ErrorResponse(HttpStatus.FORBIDDEN.value(), e.getMessage()); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java b/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java new file mode 100644 index 0000000..d10218a --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java @@ -0,0 +1,11 @@ +package ru.practicum.shareit.exception; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class ErrorResponse { + private Integer statusCode; + private String error; +} diff --git a/src/main/java/ru/practicum/shareit/exception/NotAccessException.java b/src/main/java/ru/practicum/shareit/exception/NotAccessException.java new file mode 100644 index 0000000..0c0873b --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/NotAccessException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.exception; + +public class NotAccessException extends RuntimeException { + public NotAccessException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/NotFoundException.java b/src/main/java/ru/practicum/shareit/exception/NotFoundException.java new file mode 100644 index 0000000..508b545 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.exception; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index bb17668..af398c8 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -1,12 +1,47 @@ package ru.practicum.shareit.item; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.item.dto.ItemDto; +import ru.practicum.shareit.item.service.ItemService; + +import java.util.List; -/** - * TODO Sprint add-controllers. - */ @RestController +@AllArgsConstructor @RequestMapping("/items") public class ItemController { + + private final ItemService itemService; + + @GetMapping + public List getItemsByUserId(@RequestHeader("X-Sharer-User-Id") Long userId) { + return itemService.getItemsByUserId(userId); + } + + @GetMapping("/{itemId}") + public ItemDto getItemById(@PathVariable Long itemId) { + return itemService.getItemById(itemId); + } + + @PostMapping + public ItemDto createItem( + @Valid @RequestBody ItemDto itemDto, + @RequestHeader("X-Sharer-User-Id") Long userId) { + return itemService.createItem(itemDto, userId); + } + + @PatchMapping("/{itemId}") + public ItemDto updateItem( + @RequestBody ItemDto itemDto, + @PathVariable Long itemId, + @RequestHeader("X-Sharer-User-Id") Long userId) { + return itemService.updateItem(itemDto, itemId, userId); + } + + @GetMapping("/search") + public List getItemsSearchByText(@RequestParam String text) { + return itemService.searchItemsByText(text); + } } 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 9319d7d..1b82a99 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java @@ -1,7 +1,19 @@ package ru.practicum.shareit.item.dto; -/** - * TODO Sprint add-controllers. - */ +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor public class ItemDto { + private Long id; + @NotBlank(message = "Название не может быть пустым") + private String name; + @NotBlank(message = "Описание не может быть пустым") + private String description; + @NotNull(message = "Статус о доступности не может быть пустым") + private Boolean available; + private Long requestId; } diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java new file mode 100644 index 0000000..76264bf --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -0,0 +1,30 @@ +package ru.practicum.shareit.item.mapper; + +import ru.practicum.shareit.item.dto.ItemDto; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.user.model.User; + +public class ItemMapper { + + public static ItemDto toItemDto(Item item) { + return new ItemDto( + item.getId(), + item.getName(), + item.getDescription(), + item.getAvailable(), + item.getRequest() != null ? item.getRequest().getId() : null + ); + } + + public static Item toItem(ItemDto itemDto, User owner, ItemRequest request) { + return new Item( + itemDto.getName(), + itemDto.getDescription(), + itemDto.getAvailable(), + owner, + request + ); + } + +} 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 44eb73d..69e581b 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -1,7 +1,26 @@ package ru.practicum.shareit.item.model; -/** - * TODO Sprint add-controllers. - */ + +import lombok.AllArgsConstructor; +import lombok.Data; +import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.user.model.User; + +@Data +@AllArgsConstructor public class Item { + private Long id; + private String name; + private String description; + private Boolean available; + private User owner; + private ItemRequest request; + + public Item(String name, String description, Boolean available, User owner, ItemRequest request) { + this.name = name; + this.description = description; + this.available = available; + this.owner = owner; + this.request = request; + } } 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 0000000..73c780d --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepository.java @@ -0,0 +1,20 @@ +package ru.practicum.shareit.item.repository; + +import ru.practicum.shareit.item.model.Item; + +import java.util.List; +import java.util.Optional; + +public interface ItemRepository { + + List getItemsByUserId(Long userId); + + Item createItem(Item item); + + Item updateItem(Item item); + + Optional getItemById(Long itemId); + + List searchItemsByText(String text); + +} 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 0000000..297c005 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/repository/ItemRepositoryImpl.java @@ -0,0 +1,55 @@ +package ru.practicum.shareit.item.repository; + +import org.springframework.stereotype.Repository; +import ru.practicum.shareit.item.model.Item; + +import java.util.*; + +@Repository +public class ItemRepositoryImpl implements ItemRepository { + + private final Map items = new HashMap<>(); + + @Override + public List getItemsByUserId(Long userId) { + return items.values().stream() + .filter(item -> Objects.equals(item.getOwner().getId(), userId)) + .toList(); + } + + @Override + public Item createItem(Item item) { + item.setId(getNewItemId()); + items.put(item.getId(), item); + return items.get(item.getId()); + } + + @Override + public Item updateItem(Item item) { + items.put(item.getId(), item); + return items.get(item.getId()); + } + + @Override + public Optional getItemById(Long itemId) { + return Optional.ofNullable(items.get(itemId)); + } + + @Override + public List searchItemsByText(String text) { + return items.values().stream() + .filter(item -> (containsIgnoreCase(item.getName(), text) || + containsIgnoreCase(item.getDescription(), text)) && item.getAvailable()) + .toList(); + } + + private Boolean containsIgnoreCase(String text, String containsText) { + return text.toLowerCase().contains(containsText.toLowerCase()); + } + + private Long getNewItemId() { + return items.keySet().stream() + .max(Long::compareTo) + .orElse(0L) + 1; + } +} 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 0000000..f76170f --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.item.service; + +import ru.practicum.shareit.item.dto.ItemDto; + +import java.util.List; + +public interface ItemService { + List getItemsByUserId(Long userId); + + ItemDto createItem(ItemDto itemDto, Long userId); + + ItemDto updateItem(ItemDto itemDto, Long itemId, Long userId); + + ItemDto getItemById(Long itemId); + + List searchItemsByText(String text); +} 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 0000000..95ddca5 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -0,0 +1,93 @@ +package ru.practicum.shareit.item.service; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import ru.practicum.shareit.exception.NotAccessException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.item.dto.ItemDto; +import ru.practicum.shareit.item.mapper.ItemMapper; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.item.repository.ItemRepository; +import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.user.service.UserService; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Slf4j +@Service +@AllArgsConstructor +public class ItemServiceImpl implements ItemService { + + private final ItemRepository itemRepository; + private final UserService userService; + + + @Override + public List getItemsByUserId(Long userId) { + log.info("Поиск вещей пользователя с ID = {}", userId); + userService.getUserWithCheck(userId); + List itemsByUserId = itemRepository.getItemsByUserId(userId); + return itemsByUserId.stream() + .map(ItemMapper::toItemDto) + .toList(); + } + + public Item getItemWithCheck(Long itemId) { + return itemRepository.getItemById(itemId) + .orElseThrow(() -> new NotFoundException("Вещь с ID = " + itemId + " не найдена")); + } + + @Override + public ItemDto createItem(ItemDto itemDto, Long userId) { + log.info("Создание вещи у пользователя с ID = {}", userId); + User user = userService.getUserWithCheck(userId); + return ItemMapper.toItemDto( + itemRepository.createItem( + ItemMapper.toItem(itemDto, user, null))); + } + + @Override + public ItemDto updateItem(ItemDto itemDto, Long itemId, Long userId) { + log.info("Обновление вещи у пользователя с ID = {}", userId); + + Item findItem = getItemWithCheck(itemId); + checkUser(findItem, userId); + userService.getUserWithCheck(userId); + + findItem.setName(itemDto.getName() == null || itemDto.getName().isBlank() ? + findItem.getName() : itemDto.getName()); + findItem.setDescription(itemDto.getDescription() == null || itemDto.getDescription().isBlank() ? + findItem.getDescription() : itemDto.getDescription()); + findItem.setAvailable(itemDto.getAvailable() != null ? itemDto.getAvailable() : findItem.getAvailable()); + + return ItemMapper.toItemDto(itemRepository.updateItem(findItem)); + } + + @Override + public ItemDto getItemById(Long itemId) { + log.info("Запрос вещи с ID = {}", itemId); + Item item = getItemWithCheck(itemId); + return ItemMapper.toItemDto(item); + } + + @Override + public List searchItemsByText(String text) { + log.info("Поиск вещей по тексту \"{}\"", text); + if (text.isBlank()) { + return new ArrayList<>(); + } + return itemRepository.searchItemsByText(text).stream() + .map(ItemMapper::toItemDto) + .toList(); + } + + private void checkUser(Item item, Long userIdFromRequest) { + if (!Objects.equals(item.getOwner().getId(), userIdFromRequest)) { + throw new NotAccessException("Вещь с ID = " + item.getId() + " не принадлежит пользователю с ID = " + userIdFromRequest); + } + } + +} diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/ItemRequest.java index 95d6f23..decd8a3 100644 --- a/src/main/java/ru/practicum/shareit/request/ItemRequest.java +++ b/src/main/java/ru/practicum/shareit/request/ItemRequest.java @@ -1,7 +1,17 @@ package ru.practicum.shareit.request; +import lombok.Data; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; + /** * TODO Sprint add-item-requests. */ +@Data public class ItemRequest { + private Long id; + private String description; + private User requestor; + private LocalDateTime created; } diff --git a/src/main/java/ru/practicum/shareit/user/User.java b/src/main/java/ru/practicum/shareit/user/User.java deleted file mode 100644 index ae6e7f3..0000000 --- a/src/main/java/ru/practicum/shareit/user/User.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.user; - -/** - * TODO Sprint add-controllers. - */ -public class User { -} diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 03039b9..421d352 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -1,12 +1,35 @@ package ru.practicum.shareit.user; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.user.dto.UserDto; +import ru.practicum.shareit.user.service.UserService; -/** - * TODO Sprint add-controllers. - */ @RestController +@AllArgsConstructor @RequestMapping(path = "/users") public class UserController { + + private final UserService userService; + + @GetMapping("/{userId}") + public UserDto getUserById(@PathVariable Long userId) { + return userService.getUserById(userId); + } + + @PostMapping + public UserDto createUser(@Valid @RequestBody UserDto userDto) { + return userService.createUser(userDto); + } + + @PatchMapping("/{userId}") + public UserDto updateUser(@RequestBody UserDto userDto, @PathVariable Long userId) { + return userService.updateUser(userDto, userId); + } + + @DeleteMapping("/{userId}") + public void deleteUser(@PathVariable Long userId) { + userService.deleteUserById(userId); + } } 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 0000000..b94bd2e --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDto.java @@ -0,0 +1,18 @@ +package ru.practicum.shareit.user.dto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class UserDto { + private Long id; + @NotNull(message = "Имя не может быть пустым") + private String name; + @NotBlank(message = "Почта не может быть пустой") + @Email(message = "Некорректный email") + private String email; +} diff --git a/src/main/java/ru/practicum/shareit/user/mapper/UserMapper.java b/src/main/java/ru/practicum/shareit/user/mapper/UserMapper.java new file mode 100644 index 0000000..b1350ed --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/mapper/UserMapper.java @@ -0,0 +1,21 @@ +package ru.practicum.shareit.user.mapper; + +import ru.practicum.shareit.user.dto.UserDto; +import ru.practicum.shareit.user.model.User; + +public class UserMapper { + public static UserDto toUserDto(User user) { + return new UserDto( + user.getId(), + user.getName(), + user.getEmail() + ); + } + + public static User toUser(UserDto user) { + return new User( + user.getName(), + user.getEmail() + ); + } +} 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 0000000..c3779e3 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/model/User.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.user.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class User { + private Long id; + private String name; + private String email; + + public User(String name, String email) { + this.name = name; + this.email = email; + } +} 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 0000000..820e66f --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/repository/UserRepository.java @@ -0,0 +1,21 @@ +package ru.practicum.shareit.user.repository; + +import ru.practicum.shareit.user.model.User; + +import java.util.List; +import java.util.Optional; + +public interface UserRepository { + + List getUsers(); + + Optional getUserById(Long userId); + + User createUser(User user); + + User updateUser(User user); + + void deleteUserById(Long userId); + + void checkEmail(String email); +} 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 0000000..d52efba --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/repository/UserRepositoryImpl.java @@ -0,0 +1,56 @@ +package ru.practicum.shareit.user.repository; + +import org.springframework.stereotype.Repository; +import ru.practicum.shareit.exception.AlreadyExistException; +import ru.practicum.shareit.user.model.User; + +import java.util.*; + +@Repository +public class UserRepositoryImpl implements UserRepository { + + private final Map users = new HashMap<>(); + + @Override + public List getUsers() { + return new ArrayList<>(users.values()); + } + + @Override + public Optional getUserById(Long userId) { + return Optional.ofNullable(users.get(userId)); + } + + @Override + public User createUser(User user) { + user.setId(getNewUserId()); + users.put(user.getId(), user); + return users.get(user.getId()); + } + + @Override + public User updateUser(User user) { + users.put(user.getId(), user); + return users.get(user.getId()); + } + + @Override + public void deleteUserById(Long userId) { + users.remove(userId); + } + + @Override + public void checkEmail(String email) { + if (getUsers().stream() + .map(User::getEmail) + .anyMatch(email::equals)) { + throw new AlreadyExistException("Пользователь с почтой " + email + " уже существует"); + } + } + + private Long getNewUserId() { + return users.keySet().stream() + .max(Long::compareTo) + .orElse(0L) + 1; + } +} 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 0000000..045ba1a --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/service/UserService.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.user.service; + +import ru.practicum.shareit.user.dto.UserDto; +import ru.practicum.shareit.user.model.User; + +public interface UserService { + + UserDto getUserById(Long userId); + + User getUserWithCheck(Long userId); + + UserDto createUser(UserDto user); + + UserDto updateUser(UserDto user, Long userId); + + void deleteUserById(Long userId); +} 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 0000000..8cc1711 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -0,0 +1,61 @@ +package ru.practicum.shareit.user.service; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.user.dto.UserDto; +import ru.practicum.shareit.user.mapper.UserMapper; +import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.user.repository.UserRepository; + +@Slf4j +@Service +@AllArgsConstructor +public class UserServiceImpl implements UserService { + + private final UserRepository userRepository; + + @Override + public UserDto getUserById(Long userId) { + log.info("Запрос пользователя с ID = {}", userId); + User userById = getUserWithCheck(userId); + return UserMapper.toUserDto(userById); + } + + @Override + public User getUserWithCheck(Long userId) { + return userRepository.getUserById(userId) + .orElseThrow(() -> new NotFoundException("Пользователь с ID = " + userId + " не найден")); + } + + @Override + public UserDto createUser(UserDto userDto) { + log.info("Создание пользователя"); + userRepository.checkEmail(userDto.getEmail()); + return UserMapper.toUserDto( + userRepository.createUser( + UserMapper.toUser(userDto))); + } + + @Override + public UserDto updateUser(UserDto userDto, Long userId) { + log.info("Обновление пользователя с ID = {}", userId); + User findUser = getUserWithCheck(userId); + if (userDto.getEmail() != null && !userDto.getEmail().equals(findUser.getEmail())) { + userRepository.checkEmail(userDto.getEmail()); + } + findUser.setEmail(userDto.getEmail() == null || userDto.getEmail().isBlank() ? + findUser.getEmail() : userDto.getEmail()); + findUser.setName(userDto.getName() == null || userDto.getName().isBlank() ? + findUser.getName() : userDto.getName()); + return UserMapper.toUserDto(userRepository.updateUser(findUser)); + } + + @Override + public void deleteUserById(Long userId) { + log.info("Удаление пользователя с ID = {}", userId); + getUserWithCheck(userId); + userRepository.deleteUserById(userId); + } +}