userIds) {
+ log.info("""
+ PLEASE WAITING
+ Система получает пользователей по ID
+ userids: {}""", userIds);
+ return switch (RemoteCallExecutor.execute(() -> userClient.getShortUsersByIds(userIds))) {
+ case RemoteCallResult.Success(var response) -> response;
+ case RemoteCallResult.Failure(var exeption) -> {
+ log.warn("""
+ Бизнес-исключение
+ Не удалось получить краткий список пользователей
+ userIds: {}""", userIds);
+ throw exeption;
+ }
+ case RemoteCallResult.Degraded(var cause) -> {
+ log.warn("""
+ Деградация
+ Не удалось получить краткий список пользователей
+ userIds: {}""", userIds);
+ throw new UserServiceUnavailableException(cause);
+ }
+ };
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public void checkUser(Long userId) {
+ log.info("""
+ PLEASE WAITING
+ Система проверяет наличие пользователя с id={}""", userId);
+ switch (RemoteCallExecutor.executeVoid(() -> userClient.checkUser(userId))) {
+ case RemoteCallResult.Success(var nullable) -> {
+ }
+ case RemoteCallResult.Failure(var exeption) -> {
+ log.warn("""
+ Бизнес-исключение
+ Не удалось проверить наличие пользователя с id={}""", userId);
+ throw exeption;
+ }
+ case RemoteCallResult.Degraded(var cause) -> {
+ log.warn("""
+ Деградация
+ Не удалось проверить наличие пользователя с id={}""", userId);
+ throw new UserServiceUnavailableException(cause);
+ }
+ }
+ }
+
+}
diff --git a/core/main-service/pom.xml b/core/event-service/pom.xml
similarity index 79%
rename from core/main-service/pom.xml
rename to core/event-service/pom.xml
index 2098d21..86abe85 100644
--- a/core/main-service/pom.xml
+++ b/core/event-service/pom.xml
@@ -10,15 +10,9 @@
0.0.1-SNAPSHOT
- main-service
+ event-service
jar
-
- 21
- 21
- UTF-8
-
-
ru.practicum
@@ -27,15 +21,10 @@
ru.practicum
- stat-client
+ aggregation-api
0.0.1-SNAPSHOT
-
- org.projectlombok
- lombok
-
-
-
+
org.springframework.boot
spring-boot-starter-web
@@ -53,11 +42,14 @@
spring-boot-starter-test
test
+
- org.zalando
- logbook-spring-boot-starter
- 4.0.3
+ io.hypersistence
+ hypersistence-utils-hibernate-63
+ 3.15.2
+ compile
+
org.postgresql
postgresql
@@ -68,12 +60,6 @@
h2
runtime
-
- io.hypersistence
- hypersistence-utils-hibernate-63
- 3.15.2
- compile
-
org.springframework.cloud
@@ -110,6 +96,18 @@
io.micrometer
micrometer-registry-prometheus
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-circuitbreaker-resilience4j
+
@@ -118,13 +116,6 @@
org.springframework.boot
spring-boot-maven-plugin
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
- -Duser.language=ru -Duser.country=RU
-
-
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/EventServiceApp.java b/core/event-service/src/main/java/ru/practicum/ewm/events/EventServiceApp.java
new file mode 100644
index 0000000..d7cdb4d
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/EventServiceApp.java
@@ -0,0 +1,33 @@
+package ru.practicum.ewm.events;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+import ru.practicum.aggregation.client.event.EventClient;
+import ru.practicum.aggregation.client.request.RequestClient;
+import ru.practicum.aggregation.client.stats.StatsClient;
+import ru.practicum.aggregation.client.user.UserClient;
+import ru.practicum.aggregation.config.JacksonConfiguration;
+
+@SpringBootApplication
+@EnableFeignClients(clients = {
+ UserClient.class,
+ EventClient.class,
+ RequestClient.class,
+ StatsClient.class
+})
+@ComponentScan(value = {
+ "ru.practicum.ewm.events",
+ "ru.practicum.aggregation.config",
+ "ru.practicum.aggregation.client",
+ "ru.practicum.aggregation.error",
+ "ru.practicum.aggregation.repository"
+})
+@ConfigurationPropertiesScan(basePackageClasses = JacksonConfiguration.class)
+public class EventServiceApp {
+ public static void main(String[] args) {
+ SpringApplication.run(EventServiceApp.class, args);
+ }
+}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminCategoryController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminCategoryController.java
similarity index 50%
rename from core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminCategoryController.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminCategoryController.java
index 341ae49..f7504db 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminCategoryController.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminCategoryController.java
@@ -1,13 +1,17 @@
-package ru.practicum.ewm.controller.admin;
+package ru.practicum.ewm.events.controller.admin;
+import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
+import lombok.NonNull;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.dto.category.NewCategoryDto;
-import ru.practicum.ewm.service.category.CategoryService;
+import ru.practicum.aggregation.dto.category.output.CategoryDto;
+import ru.practicum.aggregation.dto.category.come.NewCategoryDto;
+import ru.practicum.ewm.events.service.category.CategoryService;
+@Slf4j
@RestController
@RequestMapping(path = "/admin/categories")
@RequiredArgsConstructor
@@ -16,42 +20,48 @@ public class AdminCategoryController {
private final CategoryService categoryService;
/**
- * Добавление новой категории. Обратите внимание: имя категории должно быть уникальным
- *
+ * Обратите внимание: имя категории должно быть уникальным
* @param newCategoryDto данные добавляемой категории
- * @return CategoryDto
*/
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
- public CategoryDto addNewCategory(@RequestBody @Valid NewCategoryDto newCategoryDto) {
+ public CategoryDto addNewCategory(@RequestBody @Valid NewCategoryDto newCategoryDto,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Добавление новой категории
+ {} {}""", request.getMethod(), request.getRequestURI());
+
return categoryService.adminAddNewCategory(newCategoryDto);
}
/**
- * Изменение категории
- *
* Обратите внимание: имя категории должно быть уникальным
- *
- * @param catId id категории
- * @param categoryDto Данные категории для изменения
- * @return CategoryDto
*/
@PatchMapping("/{catId}")
public CategoryDto updateCategory(@PathVariable Long catId,
- @RequestBody @Valid CategoryDto categoryDto) {
+ @RequestBody @Valid CategoryDto categoryDto,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Изменение категории
+ {} {}""", request.getMethod(), request.getRequestURI());
+
return categoryService.updateCategory(catId, categoryDto);
}
/**
- * Удаление категории
- *
* Обратите внимание: с категорией не должно быть связано ни одного события.
- *
- * @param catId id категории
*/
@DeleteMapping("/{catId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
- public void deleteCategory(@PathVariable Long catId) {
+ public void deleteCategory(@PathVariable Long catId,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Удаление категории
+ {} {}""", request.getMethod(), request.getRequestURI());
+
categoryService.deleteCategory(catId);
}
}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminCompilationController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminCompilationController.java
new file mode 100644
index 0000000..f212281
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminCompilationController.java
@@ -0,0 +1,61 @@
+package ru.practicum.ewm.events.controller.admin;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import ru.practicum.aggregation.dto.compilation.output.CompilationDto;
+import ru.practicum.aggregation.dto.compilation.come.update.CompilationUpdateDto;
+import ru.practicum.aggregation.dto.compilation.come.create.NewCompilationDto;
+import ru.practicum.ewm.events.service.compilation.CompilationService;
+
+@Slf4j
+@RestController
+@RequestMapping(path = "/admin/compilations")
+@RequiredArgsConstructor
+public class AdminCompilationController {
+
+ private final CompilationService compilationService;
+
+ /**
+ * подборка может не содержать событий
+ */
+ @PostMapping
+ @ResponseStatus(HttpStatus.CREATED)
+ public CompilationDto createCompilation(@RequestBody @Valid NewCompilationDto newCompilationDto,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Добавление новой подборки
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ return compilationService.addCompilation(newCompilationDto);
+ }
+
+ @PatchMapping("/{compId}")
+ public CompilationDto updateCompilation(@RequestBody @Valid CompilationUpdateDto compilationUpdateDto,
+ @PathVariable Long compId,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Обновление подборки
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ return compilationService.updateCompilation(compId, compilationUpdateDto);
+ }
+
+ @DeleteMapping("/{compId}")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void delById(@PathVariable Long compId,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Удаление подборки
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ compilationService.delById(compId);
+ }
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminEventController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminEventController.java
new file mode 100644
index 0000000..7b57395
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/admin/AdminEventController.java
@@ -0,0 +1,102 @@
+package ru.practicum.ewm.events.controller.admin;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+import ru.practicum.aggregation.model.data.AdminGetData;
+import ru.practicum.aggregation.dto.event.output.EventFullDto;
+import ru.practicum.aggregation.dto.event.come.update.UpdateEventAdminRequest;
+import ru.practicum.aggregation.enums.EventState;
+import ru.practicum.ewm.events.service.event.EventService;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(path = "/admin/events")
+@RequiredArgsConstructor
+public class AdminEventController {
+
+ private final EventService eventService;
+
+ /**
+ * Эндпоинт возвращает полную информацию обо всех событиях подходящих под переданные условия
+ * В случае, если по заданным фильтрам не найдено ни одного события, возвращает пустой список
+ */
+ @GetMapping
+ public List adminGetEvents(
+ @RequestParam(required = false)
+ List users,
+
+ @RequestParam(required = false)
+ List states,
+
+ @RequestParam(required = false)
+ List categories,
+
+ @RequestParam(required = false)
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ LocalDateTime rangeStart,
+
+ @RequestParam(required = false)
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ LocalDateTime rangeEnd,
+
+ @RequestParam(required = false, defaultValue = "0")
+ Integer from,
+
+ @RequestParam(required = false, defaultValue = "10")
+ Integer size,
+
+ @NonNull HttpServletRequest request
+ ) {
+
+ log.info("""
+ ENDPOINT
+ Поиск событий
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ AdminGetData getDto = AdminGetData.builder()
+ .users(users)
+ .states(states)
+ .categories(categories)
+ .rangeStart(rangeStart)
+ .rangeEnd(rangeEnd)
+ .from(from)
+ .size(size)
+ .build();
+
+ return eventService.adminGetEvents(getDto);
+ }
+
+ /**
+ * Редактирование данных любого события администратором.
+ * Валидация данных не требуется.
+ * Обратите внимание:
+ * - дата начала изменяемого события должна быть не ранее чем за час от даты публикации.
+ * (Ожидается код ошибки 409)
+ * - событие можно публиковать, только если оно в состоянии ожидания публикации
+ * (Ожидается код ошибки 409)
+ * - событие можно отклонить, только если оно еще не опубликовано
+ * (Ожидается код ошибки 409)
+ */
+ @PatchMapping("/{eventId}")
+ public EventFullDto adminUpdateEvent(
+ @PathVariable Long eventId,
+ @RequestBody @Valid UpdateEventAdminRequest updateRequest,
+ @NonNull HttpServletRequest request) {
+
+ log.info("""
+ ENDPOINT
+ Редактирование данных события и его статуса (отклонение/публикация)
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ return eventService.adminUpdateEvent(eventId, updateRequest);
+ }
+
+}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeCategoryController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeCategoryController.java
similarity index 62%
rename from core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeCategoryController.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeCategoryController.java
index f3eb20b..a282d43 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeCategoryController.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeCategoryController.java
@@ -1,12 +1,14 @@
-package ru.practicum.ewm.controller.free;
+package ru.practicum.ewm.events.controller.free;
+import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
+import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.service.category.CategoryService;
+import ru.practicum.aggregation.dto.category.output.CategoryDto;
+import ru.practicum.ewm.events.service.category.CategoryService;
import java.util.List;
@@ -19,32 +21,38 @@ public class FreeCategoryController {
private final CategoryService categoryService;
/**
- * Получение категорий.
- *
* В случае, если по заданным фильтрам не найдено ни одной категории, возвращает пустой список
*
* @param from количество категорий, которые нужно пропустить для формирования текущего набора
* Default value : 0
* @param size количество категорий в наборе
* Default value : 10
- * @return List<{@link CategoryDto}>
*/
@GetMapping
public List findAll(@RequestParam(defaultValue = "0") @PositiveOrZero Integer from,
- @RequestParam(defaultValue = "10") @Positive Integer size) {
+ @RequestParam(defaultValue = "10") @Positive Integer size,
+ @NonNull HttpServletRequest request) {
+
+ log.info("""
+ ENDPOINT
+ Получение категорий
+ {} {}""", request.getMethod(), request.getRequestURI());
+
return categoryService.findAll(from, size);
}
/**
- * Получение информации о категории по её идентификатору.
- *
* В случае, если категории с заданным id не найдено, возвращает статус код 404
- *
- * @param catId id категории
- * @return {@link CategoryDto}
*/
@GetMapping("/{catId}")
- public CategoryDto findById(@PathVariable @Positive Long catId) {
+ public CategoryDto findById(@PathVariable @Positive Long catId,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Получение информации о категории по её идентификатору
+ {} {}""", request.getMethod(), request.getRequestURI());
+
return categoryService.findById(catId);
}
+
}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeCompilationController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeCompilationController.java
new file mode 100644
index 0000000..691086e
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeCompilationController.java
@@ -0,0 +1,58 @@
+package ru.practicum.ewm.events.controller.free;
+
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import ru.practicum.aggregation.dto.compilation.output.CompilationDto;
+import ru.practicum.aggregation.dto.compilation.come.get.CompilationSearchFilter;
+import ru.practicum.ewm.events.service.compilation.CompilationService;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(path = "/compilations")
+@RequiredArgsConstructor
+public class FreeCompilationController {
+
+ private final CompilationService compilationService;
+
+ /**
+ * В случае, если по заданным фильтрам не найдено ни одной подборки, возвращает пустой список
+ */
+ @GetMapping
+ public List getCompilations(
+ @RequestParam(required = false) Boolean pinned,
+ @RequestParam(defaultValue = "0") Integer from,
+ @RequestParam(defaultValue = "10") Integer size,
+ @NonNull HttpServletRequest request
+ ) {
+ log.info("""
+ ENDPOINT
+ Получение подборок событий
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ CompilationSearchFilter filter = CompilationSearchFilter.builder()
+ .pinned(pinned)
+ .from(from)
+ .size(size)
+ .build();
+
+ return compilationService.getByFilter(filter, request);
+ }
+
+ @GetMapping("/{compId}")
+ public CompilationDto getCompilationById(@PathVariable Long compId,
+ @NonNull HttpServletRequest request) {
+
+ log.info("""
+ ENDPOINT
+ Получение подборки событий по её id
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ return compilationService.getById(compId, request);
+ }
+
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeEventController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeEventController.java
new file mode 100644
index 0000000..728027a
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/free/FreeEventController.java
@@ -0,0 +1,114 @@
+package ru.practicum.ewm.events.controller.free;
+
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.AccessLevel;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+import ru.practicum.aggregation.dto.event.output.EventFullDto;
+import ru.practicum.aggregation.dto.event.output.EventShortDto;
+import ru.practicum.aggregation.model.data.FreeGetData;
+import ru.practicum.aggregation.repository.StatsFeignRepository;
+import ru.practicum.ewm.events.service.event.EventService;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(path = "/events")
+@RequiredArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+public class FreeEventController {
+
+ EventService eventService;
+ StatsFeignRepository statsFeignRepository;
+
+ /**
+ * Обратите внимание:
+ * - это публичный эндпоинт, соответственно в выдаче должны быть только опубликованные события
+ * - текстовый поиск (по аннотации и подробному описанию) должен быть без учета регистра букв
+ * - если в запросе не указан диапазон дат [rangeStart-rangeEnd], то нужно выгружать события,
+ * которые произойдут позже текущей даты и времени
+ * - информация о каждом событии должна включать в себя количество просмотров и количество
+ * уже одобренных заявок на участие
+ * - информацию о том, что по этому эндпоинту был осуществлен и обработан запрос, нужно
+ * сохранить в сервисе статистики
+ * В случае, если по заданным фильтрам не найдено ни одного события, возвращает пустой список
+ */
+ @GetMapping
+ public List getFreeEvents(
+
+ @RequestParam(required = false)
+ String text,
+
+ @RequestParam(required = false)
+ List categories,
+
+ @RequestParam(required = false)
+ Boolean paid,
+
+ @RequestParam(required = false)
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ LocalDateTime rangeStart,
+
+ @RequestParam(required = false)
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ LocalDateTime rangeEnd,
+
+ @RequestParam(required = false, defaultValue = "false")
+ Boolean onlyAvailable,
+
+ @RequestParam(required = false)
+ FreeGetData.FreeEventSort sort,
+
+ @RequestParam(required = false, defaultValue = "0")
+ Integer from,
+
+ @RequestParam(required = false, defaultValue = "10")
+ Integer size,
+
+ @NonNull HttpServletRequest request
+ ) {
+ FreeGetData freeGetData = FreeGetData.builder()
+ .text(text)
+ .categories(categories)
+ .paid(paid)
+ .rangeStart(rangeStart)
+ .rangeEnd(rangeEnd)
+ .onlyAvailable(onlyAvailable)
+ .sort(sort)
+ .from(from)
+ .size(size)
+ .build();
+
+ log.info("""
+ ENDPOINT
+ Получение событий с возможностью фильтрации
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ var result = eventService.getFreeEvents(freeGetData, request);
+ statsFeignRepository.sendHitRequest(request);
+
+ return result;
+ }
+
+ @GetMapping(value = "/{eventId}")
+ public EventFullDto getFreeEventById(@PathVariable Long eventId,
+ @NonNull HttpServletRequest request) {
+
+ log.info("""
+ ENDPOINT
+ Получение подробной информации об опубликованном событии по его идентификатору.
+ {} {}""", request.getMethod(), request.getRequestURI());
+
+ var result = eventService.getFreeEventById(eventId, request);
+ statsFeignRepository.sendHitRequest(request);
+
+ return result;
+ }
+
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/controller/system/SystemEventController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/system/SystemEventController.java
new file mode 100644
index 0000000..35987b1
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/system/SystemEventController.java
@@ -0,0 +1,32 @@
+package ru.practicum.ewm.events.controller.system;
+
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.PositiveOrZero;
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import ru.practicum.aggregation.dto.event.output.EventFullDto;
+import ru.practicum.ewm.events.service.event.EventService;
+
+@Slf4j
+@RestController
+@RequestMapping("/system/events")
+@RequiredArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+public class SystemEventController {
+
+ EventService eventService;
+
+ @GetMapping("/{eventId}")
+ public EventFullDto systemFindEventById(@PathVariable @Positive Long eventId,
+ @RequestParam @PositiveOrZero Long confirmets) {
+ return eventService.findEventById(eventId, confirmets);
+ }
+
+ @GetMapping("/{eventId}/initiator")
+ public Long systemGetInitiatorIfPublished(@PathVariable @Positive Long eventId) {
+ return eventService.getInitiatorIfPublished(eventId);
+ }
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/controller/system/SystemRatingController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/system/SystemRatingController.java
new file mode 100644
index 0000000..6bd9ceb
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/system/SystemRatingController.java
@@ -0,0 +1,28 @@
+package ru.practicum.ewm.events.controller.system;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import ru.practicum.aggregation.dto.rating.come.update.RatingUpdateRequest;
+import ru.practicum.ewm.events.service.rating.EventRatingService;
+
+@Slf4j
+@RestController
+@RequestMapping(path = "/system/events/ratings")
+@RequiredArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+public class SystemRatingController {
+
+ EventRatingService eventRatingService;
+
+ @PatchMapping
+ public void updateRating(@RequestBody @NotNull RatingUpdateRequest request) {
+ eventRatingService.updateRating(request);
+ }
+}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/user/UserEventController.java b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/user/UserEventController.java
similarity index 52%
rename from core/main-service/src/main/java/ru/practicum/ewm/controller/user/UserEventController.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/controller/user/UserEventController.java
index 005aaad..591c2da 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/user/UserEventController.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/controller/user/UserEventController.java
@@ -1,119 +1,121 @@
-package ru.practicum.ewm.controller.user;
+package ru.practicum.ewm.events.controller.user;
+import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
+import lombok.NonNull;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.event.EventFullDto;
-import ru.practicum.ewm.dto.event.EventShortDto;
-import ru.practicum.ewm.dto.event.NewEventDto;
-import ru.practicum.ewm.dto.event.UpdateEventUserRequest;
-import ru.practicum.ewm.dto.request.EventRequestStatusUpdateRequest;
-import ru.practicum.ewm.dto.request.EventRequestStatusUpdateResult;
-import ru.practicum.ewm.dto.request.ParticipationRequestDto;
-import ru.practicum.ewm.service.event.EventService;
-import ru.practicum.ewm.service.request.RequestService;
+import ru.practicum.aggregation.dto.event.come.create.NewEventDto;
+import ru.practicum.aggregation.dto.event.come.update.UpdateEventUserRequest;
+import ru.practicum.aggregation.dto.event.output.EventFullDto;
+import ru.practicum.aggregation.dto.event.output.EventShortDto;
+import ru.practicum.aggregation.dto.participation.come.EventRequestStatusUpdateRequest;
+import ru.practicum.aggregation.dto.participation.output.EventRequestStatusUpdateResult;
+import ru.practicum.aggregation.dto.participation.output.ParticipationRequestDto;
+import ru.practicum.ewm.events.service.event.EventService;
+import ru.practicum.ewm.events.service.request.EventRequestService;
import java.util.List;
+@Slf4j
@RestController
@RequestMapping(path = "/users/{userId}/events")
@RequiredArgsConstructor
public class UserEventController {
private final EventService eventService;
- private final RequestService requestService;
+ private final EventRequestService eventRequestService;
/**
- * Получение событий, добавленных текущим пользователем
- *
- * @param userId id текущего пользователя
- * @param from количество элементов, которые нужно пропустить для формирования текущего набора
+ * @param from количество элементов, которые нужно пропустить для формирования текущего набора
* Default value : 0
- * @param size количество элементов в наборе
+ * @param size количество элементов в наборе
* Default value : 10
- * @return List<{@link EventShortDto}>
*/
@GetMapping
- public List findEventsByUserId(@PathVariable @Positive Long userId,
- @RequestParam(defaultValue = "0") @PositiveOrZero Integer from,
- @RequestParam(defaultValue = "10") @Positive Integer size) {
+ public List findEventsByUserId(
+ @PathVariable @Positive Long userId,
+ @RequestParam(defaultValue = "0") @PositiveOrZero Integer from,
+ @RequestParam(defaultValue = "10") @Positive Integer size,
+ @NonNull HttpServletRequest request
+ ) {
+ log.info("""
+ ENDPOINT
+ Получение событий, добавленных текущим пользователем
+ {} {}""", request.getMethod(), request.getRequestURI());
+
return eventService.findByUserId(userId, from, size);
}
- /**
- * Получение полной информации о событии добавленном текущим пользователем
- *
- * @param userId id текущего пользователя
- * @param eventId id события
- * @return {@link EventFullDto}
- */
@GetMapping("/{eventId}")
public EventFullDto findEventById(@PathVariable @Positive Long userId,
- @PathVariable @Positive Long eventId) {
- return eventService.findEventById(userId, eventId);
+ @PathVariable @Positive Long eventId,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Получение полной информации о событии добавленном текущим пользователем
+ {} {}""", request.getMethod(), request.getRequestURI());
+ return eventService.findEventByUserIdAndEventId(userId, eventId);
}
/**
- * Добавление нового события
- *
* Обратите внимание: дата и время на которые намечено событие не может быть раньше,
* чем через два часа от текущего момента
- *
- * @param userId id текущего пользователя
- * @param newEventDto данные добавляемого события
- * @return {@link EventFullDto}
*/
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public EventFullDto addEvent(@PathVariable @Positive Long userId,
- @RequestBody @Valid NewEventDto newEventDto) {
-
+ @RequestBody @Valid NewEventDto newEventDto,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Добавление нового события
+ {} {}""", request.getMethod(), request.getRequestURI());
return eventService.userAddNewEvent(userId, newEventDto);
}
/**
- * Изменение события добавленного текущим пользователем
- *
* Обратите внимание:
*
- * - изменить можно только отмененные события или события в состоянии ожидания модерации (Ожидается код ошибки 409)
+ * - изменить можно только отмененные события или события в состоянии ожидания модерации
+ * (Ожидается код ошибки 409)
*
- * - дата и время на которые намечено событие не может быть раньше, чем через два часа от текущего момента
+ * - дата и время на которые намечено событие не может быть раньше,
+ * чем через два часа от текущего момента
* (Ожидается код ошибки 409)
- *
- * @param userId id текущего пользователя
- * @param eventId id редактируемого события
- * @param request Данные HTTP-запроса
- * @return {@link EventFullDto}
*/
@PatchMapping("/{eventId}")
public EventFullDto patchEvent(@PathVariable @Positive Long userId,
@PathVariable @Positive Long eventId,
- @RequestBody @Valid UpdateEventUserRequest request) {
- return eventService.patchEvent(userId, eventId, request);
+ @RequestBody @Valid UpdateEventUserRequest updateRequest,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Изменение события добавленного текущим пользователем
+ {} {}""", request.getMethod(), request.getRequestURI());
+ return eventService.patchEvent(userId, eventId, updateRequest);
}
/**
- * Получение информации о запросах на участие в событии текущего пользователя
- *
* В случае, если по заданным фильтрам не найдено ни одной заявки, возвращает пустой список
- *
- * @param userId id текущего пользователя
- * @param eventId id события
- * @return List<{@link ParticipationRequestDto}>
*/
@GetMapping("/{eventId}/requests")
public List getRequests(@PathVariable @Positive Long userId,
- @PathVariable @Positive Long eventId) {
- return requestService.findByEventId(userId, eventId);
+ @PathVariable @Positive Long eventId,
+ @NonNull HttpServletRequest request) {
+ log.info("""
+ ENDPOINT
+ Получение информации о запросах на участие в событии текущего пользователя
+ {} {}""", request.getMethod(), request.getRequestURI());
+ return eventRequestService.findByEventId(userId, eventId);
}
/**
- * Изменение статуса (подтверждена, отменена) заявок на участие в событии текущего пользователя
- *
* Обратите внимание:
*
* - если для события лимит заявок равен 0 или отключена пре-модерация заявок, то подтверждение заявок не требуется
@@ -124,16 +126,19 @@ public List getRequests(@PathVariable @Positive Long us
*
* - если при подтверждении данной заявки, лимит заявок для события исчерпан, то все неподтверждённые заявки
* необходимо отклонить
- *
- * @param userId id текущего пользователя
- * @param eventId id события текущего пользователя
- * @param status Новый статус для заявок на участие в событии текущего пользователя
- * @return {@link EventRequestStatusUpdateResult}
*/
@PatchMapping("/{eventId}/requests")
- public EventRequestStatusUpdateResult patchRequests(@PathVariable @Positive Long userId,
- @PathVariable @Positive Long eventId,
- @RequestBody @Valid EventRequestStatusUpdateRequest status) {
- return requestService.updateStatusRequest(userId, eventId, status);
+ public EventRequestStatusUpdateResult patchRequests(
+ @PathVariable @Positive Long userId,
+ @PathVariable @Positive Long eventId,
+ @RequestBody @NotNull @Valid EventRequestStatusUpdateRequest updateRequest,
+ @NonNull HttpServletRequest request
+ ) {
+ log.info("""
+ ENDPOINT
+ Изменение статуса (подтверждена, отменена) заявок на участие в событии текущего пользователя
+ {} {}""", request.getMethod(), request.getRequestURI());
+ return eventRequestService.updateStatusRequest(userId, eventId, updateRequest);
}
+
}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/model/Category.java b/core/event-service/src/main/java/ru/practicum/ewm/events/entity/Category.java
similarity index 81%
rename from core/main-service/src/main/java/ru/practicum/ewm/model/Category.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/entity/Category.java
index d21838c..9d849e2 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/model/Category.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/entity/Category.java
@@ -1,4 +1,4 @@
-package ru.practicum.ewm.model;
+package ru.practicum.ewm.events.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@@ -7,7 +7,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
-import ru.practicum.ewm.util.entity.BaseEntity;
+import ru.practicum.aggregation.model.entity.BaseEntity;
@Getter
@Setter
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/model/Compilation.java b/core/event-service/src/main/java/ru/practicum/ewm/events/entity/Compilation.java
similarity index 87%
rename from core/main-service/src/main/java/ru/practicum/ewm/model/Compilation.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/entity/Compilation.java
index 5d02b70..f24e433 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/model/Compilation.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/entity/Compilation.java
@@ -1,10 +1,10 @@
-package ru.practicum.ewm.model;
+package ru.practicum.ewm.events.entity;
import jakarta.persistence.*;
import lombok.*;
import lombok.experimental.FieldDefaults;
import lombok.experimental.SuperBuilder;
-import ru.practicum.ewm.util.entity.BaseEntity;
+import ru.practicum.aggregation.model.entity.BaseEntity;
import java.util.HashSet;
import java.util.Set;
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/model/Event.java b/core/event-service/src/main/java/ru/practicum/ewm/events/entity/Event.java
similarity index 75%
rename from core/main-service/src/main/java/ru/practicum/ewm/model/Event.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/entity/Event.java
index 32f8cf0..4d09417 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/model/Event.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/entity/Event.java
@@ -1,4 +1,4 @@
-package ru.practicum.ewm.model;
+package ru.practicum.ewm.events.entity;
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
import jakarta.persistence.*;
@@ -11,12 +11,31 @@
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.Type;
import org.hibernate.type.SqlTypes;
-import ru.practicum.ewm.model.enums.EventState;
-import ru.practicum.ewm.util.entity.BaseEntity;
+import ru.practicum.aggregation.enums.EventState;
+import ru.practicum.aggregation.model.entity.BaseEntity;
+import ru.practicum.aggregation.model.entity.Location;
import java.time.LocalDateTime;
import java.util.List;
+/**
+ * @apiNote
+ * {@link String} annotation
+ * {@link Category} category
+ * {@link LocalDateTime} createdOn
+ * {@link String} description
+ * {@link LocalDateTime} eventDate
+ * {@link Long} initiatorId
+ * {@link Location} location
+ * boolean paid
+ * int participantLimit
+ * {@link LocalDateTime} publishedOn
+ * boolean requestModeration
+ * {@link EventState} state
+ * {@link String} title
+ * {@link List}<{@link Compilation}> compilations
+ * long rate
+ */
@Getter
@Setter
@Entity
@@ -48,9 +67,8 @@ public class Event extends BaseEntity {
LocalDateTime eventDate;
/// Пользователь инициатор события
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "initiator_id")
- User initiator;
+ @JoinColumn(name = "initiator_id", nullable = false)
+ Long initiatorId;
/// Широта и долгота места проведения события
@Type(JsonBinaryType.class)
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/mapper/CategoryMapper.java b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/CategoryMapper.java
similarity index 58%
rename from core/main-service/src/main/java/ru/practicum/ewm/mapper/CategoryMapper.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/mapper/CategoryMapper.java
index 448c6d4..6a7a38d 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/mapper/CategoryMapper.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/CategoryMapper.java
@@ -1,10 +1,10 @@
-package ru.practicum.ewm.mapper;
+package ru.practicum.ewm.events.mapper;
import lombok.experimental.UtilityClass;
import org.springframework.lang.NonNull;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.dto.category.NewCategoryDto;
-import ru.practicum.ewm.model.Category;
+import ru.practicum.aggregation.dto.category.output.CategoryDto;
+import ru.practicum.aggregation.dto.category.come.NewCategoryDto;
+import ru.practicum.ewm.events.entity.Category;
@UtilityClass
public class CategoryMapper {
@@ -15,12 +15,6 @@ public CategoryDto toDto(@NonNull Category category) {
.build();
}
- public Category toEntity(@NonNull CategoryDto categoryDto) {
- return Category.builder()
- .name(categoryDto.name())
- .build();
- }
-
public Category toEntity(@NonNull NewCategoryDto newCategoryDto) {
return Category.builder()
.name(newCategoryDto.name())
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/mapper/CompilationMapper.java b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/CompilationMapper.java
similarity index 56%
rename from core/main-service/src/main/java/ru/practicum/ewm/mapper/CompilationMapper.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/mapper/CompilationMapper.java
index db94788..3078c24 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/mapper/CompilationMapper.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/CompilationMapper.java
@@ -1,11 +1,13 @@
-package ru.practicum.ewm.mapper;
+package ru.practicum.ewm.events.mapper;
import lombok.experimental.UtilityClass;
import org.springframework.lang.NonNull;
-import ru.practicum.ewm.dto.compilation.CompilationDto;
-import ru.practicum.ewm.dto.compilation.NewCompilationDto;
-import ru.practicum.ewm.model.Compilation;
-import ru.practicum.ewm.model.Event;
+import ru.practicum.aggregation.dto.compilation.output.CompilationDto;
+import ru.practicum.aggregation.dto.compilation.come.create.NewCompilationDto;
+import ru.practicum.aggregation.dto.user.output.UserShortDto;
+import ru.practicum.ewm.events.entity.Compilation;
+import ru.practicum.ewm.events.entity.Event;
+import ru.practicum.ewm.events.model.EventData;
import java.util.HashSet;
import java.util.Map;
@@ -15,6 +17,7 @@
public class CompilationMapper {
public CompilationDto toCompilationDto(@NonNull Compilation compilation,
+ @NonNull Map eventIdToInitiator,
@NonNull Map confirmedRequests,
@NonNull Map views) {
return CompilationDto.builder()
@@ -24,8 +27,12 @@ public CompilationDto toCompilationDto(@NonNull Compilation compilation,
.events(compilation.getEvents().stream()
.map(event -> EventMapper.toEventShortDto(
event,
- confirmedRequests.getOrDefault(event.getId(), 0L),
- views.getOrDefault(event.getId(), 0L)
+ EventData.builder()
+ .initiator(eventIdToInitiator.get(event.getId()))
+ .confirmedRequests(confirmedRequests
+ .getOrDefault(event.getId(), 0L))
+ .views(views.getOrDefault(event.getId(), 0L))
+ .build()
))
.toList())
.build();
@@ -38,4 +45,5 @@ public Compilation toEntity(@NonNull NewCompilationDto dto, Set events) {
.events(events != null ? events : new HashSet<>())
.build();
}
+
}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/mapper/EventMapper.java b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/EventMapper.java
similarity index 72%
rename from core/main-service/src/main/java/ru/practicum/ewm/mapper/EventMapper.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/mapper/EventMapper.java
index de4cbbd..a6d885e 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/mapper/EventMapper.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/EventMapper.java
@@ -1,12 +1,16 @@
-package ru.practicum.ewm.mapper;
+package ru.practicum.ewm.events.mapper;
import lombok.experimental.UtilityClass;
import org.springframework.lang.NonNull;
-import ru.practicum.ewm.dto.event.*;
-import ru.practicum.ewm.model.Category;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.model.enums.EventState;
+import ru.practicum.aggregation.dto.event.come.create.NewEventDto;
+import ru.practicum.aggregation.dto.event.come.update.UpdateEventAdminRequest;
+import ru.practicum.aggregation.dto.event.come.update.UpdateEventUserRequest;
+import ru.practicum.aggregation.dto.event.output.EventFullDto;
+import ru.practicum.aggregation.dto.event.output.EventShortDto;
+import ru.practicum.aggregation.enums.EventState;
+import ru.practicum.ewm.events.entity.Category;
+import ru.practicum.ewm.events.entity.Event;
+import ru.practicum.ewm.events.model.EventData;
import java.time.LocalDateTime;
import java.util.Optional;
@@ -14,31 +18,33 @@
@UtilityClass
public class EventMapper {
- public EventShortDto toEventShortDto(@NonNull Event event, long confirmedRequests, long views) {
+ public EventShortDto toEventShortDto(@NonNull Event event,
+ @NonNull EventData eventData) {
return EventShortDto.builder()
.annotation(event.getAnnotation())
.category(CategoryMapper.toDto(event.getCategory()))
- .confirmedRequests(confirmedRequests)
+ .confirmedRequests(eventData.confirmedRequests())
.eventDate(event.getEventDate())
.id(event.getId())
- .initiator(UserMapper.toUserShortDto(event.getInitiator()))
+ .initiator(eventData.initiator())
.paid(event.isPaid())
.title(event.getTitle())
- .views(views)
+ .views(eventData.views())
.rate(event.getRate())
.build();
}
- public EventFullDto toEventFullDto(@NonNull Event event, long confirmedRequests, long views) {
+ public EventFullDto toEventFullDto(@NonNull Event event,
+ @NonNull EventData eventData) {
return EventFullDto.builder()
.id(event.getId())
.annotation(event.getAnnotation())
.category(CategoryMapper.toDto(event.getCategory()))
- .confirmedRequests(confirmedRequests)
+ .confirmedRequests(eventData.confirmedRequests())
.createdOn(event.getCreatedOn())
.description(event.getDescription())
.eventDate(event.getEventDate())
- .initiator(UserMapper.toUserShortDto(event.getInitiator()))
+ .initiator(eventData.initiator())
.location(event.getLocation())
.paid(event.isPaid())
.participantLimit(event.getParticipantLimit())
@@ -46,7 +52,7 @@ public EventFullDto toEventFullDto(@NonNull Event event, long confirmedRequests,
.requestModeration(event.isRequestModeration())
.state(event.getState())
.title(event.getTitle())
- .views(views)
+ .views(eventData.views())
.rate(event.getRate())
.build();
}
@@ -54,7 +60,7 @@ public EventFullDto toEventFullDto(@NonNull Event event, long confirmedRequests,
public Event toEntity(@NonNull NewEventDto newEventDto,
Category category,
LocalDateTime createdOn,
- User initiator,
+ Long initiatorId,
LocalDateTime publishedOn,
EventState state) {
return Event.builder()
@@ -63,18 +69,21 @@ public Event toEntity(@NonNull NewEventDto newEventDto,
.createdOn(createdOn)
.description(newEventDto.description())
.eventDate(newEventDto.eventDate())
- .initiator(initiator)
+ .initiatorId(initiatorId)
.location(newEventDto.location())
.paid(newEventDto.paid() != null && newEventDto.paid())
- .participantLimit(newEventDto.participantLimit() == null ? 0 : newEventDto.participantLimit())
+ .participantLimit(newEventDto.participantLimit() == null
+ ? 0 : newEventDto.participantLimit())
.publishedOn(publishedOn)
- .requestModeration(newEventDto.requestModeration() == null || newEventDto.requestModeration())
+ .requestModeration(newEventDto.requestModeration() == null
+ || newEventDto.requestModeration())
.state(state)
.title(newEventDto.title())
.rate(0)
.build();
}
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public static Event update(@NonNull Event oldEvent,
@NonNull UpdateEventAdminRequest request,
EventState state,
@@ -143,4 +152,5 @@ public void merge(Event event, UpdateEventUserRequest dto) {
event.setRequestModeration(dto.requestModeration());
}
}
+
}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/mapper/StateMapper.java b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/StateMapper.java
similarity index 72%
rename from core/main-service/src/main/java/ru/practicum/ewm/mapper/StateMapper.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/mapper/StateMapper.java
index 3acbea8..4448b98 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/mapper/StateMapper.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/StateMapper.java
@@ -1,12 +1,14 @@
-package ru.practicum.ewm.mapper;
+package ru.practicum.ewm.events.mapper;
+import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
-import ru.practicum.ewm.model.enums.EventState;
-import ru.practicum.ewm.model.enums.UserStateAction;
+import ru.practicum.aggregation.enums.EventState;
+import ru.practicum.aggregation.enums.UserStateAction;
@Component
public class StateMapper {
+ @Nullable
public static EventState mapUserEventAction(UserStateAction action) {
return switch (action) {
case CANCEL_REVIEW -> EventState.CANCELED;
@@ -15,6 +17,7 @@ public static EventState mapUserEventAction(UserStateAction action) {
};
}
+ @Nullable
public static EventState mapAdminEventAction(UserStateAction action) {
return switch (action) {
case PUBLISH_EVENT -> EventState.PUBLISHED;
@@ -22,4 +25,5 @@ public static EventState mapAdminEventAction(UserStateAction action) {
case null, default -> null;
};
}
+
}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/UserMapper.java b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/UserMapper.java
new file mode 100644
index 0000000..555f175
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/mapper/UserMapper.java
@@ -0,0 +1,18 @@
+package ru.practicum.ewm.events.mapper;
+
+import lombok.experimental.UtilityClass;
+import org.springframework.lang.NonNull;
+import ru.practicum.aggregation.dto.user.output.UserDto;
+import ru.practicum.aggregation.dto.user.output.UserShortDto;
+
+@UtilityClass
+public class UserMapper {
+
+ public UserShortDto toUserShortDto(@NonNull UserDto userDto) {
+ return UserShortDto.builder()
+ .id(userDto.id())
+ .name(userDto.name())
+ .build();
+ }
+
+}
\ No newline at end of file
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/model/EventData.java b/core/event-service/src/main/java/ru/practicum/ewm/events/model/EventData.java
new file mode 100644
index 0000000..49c8111
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/model/EventData.java
@@ -0,0 +1,18 @@
+package ru.practicum.ewm.events.model;
+
+import lombok.Builder;
+import ru.practicum.aggregation.dto.user.output.UserShortDto;
+
+/**
+ * @apiNote
+ * UserShortDto initiator
+ * long confirmedRequests
+ * long views
+ */
+@Builder
+public record EventData(
+ UserShortDto initiator,
+ long confirmedRequests,
+ long views
+) {
+}
\ No newline at end of file
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dao/CategoryRepository.java b/core/event-service/src/main/java/ru/practicum/ewm/events/repository/CategoryRepository.java
similarity index 66%
rename from core/main-service/src/main/java/ru/practicum/ewm/dao/CategoryRepository.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/repository/CategoryRepository.java
index 48dac91..49b7fec 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/dao/CategoryRepository.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/repository/CategoryRepository.java
@@ -1,7 +1,7 @@
-package ru.practicum.ewm.dao;
+package ru.practicum.ewm.events.repository;
import org.springframework.data.jpa.repository.JpaRepository;
-import ru.practicum.ewm.model.Category;
+import ru.practicum.ewm.events.entity.Category;
public interface CategoryRepository extends JpaRepository {
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dao/CompilationRepository.java b/core/event-service/src/main/java/ru/practicum/ewm/events/repository/CompilationRepository.java
similarity index 76%
rename from core/main-service/src/main/java/ru/practicum/ewm/dao/CompilationRepository.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/repository/CompilationRepository.java
index 0bbb5aa..c860baa 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/dao/CompilationRepository.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/repository/CompilationRepository.java
@@ -1,9 +1,9 @@
-package ru.practicum.ewm.dao;
+package ru.practicum.ewm.events.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
-import ru.practicum.ewm.model.Compilation;
+import ru.practicum.ewm.events.entity.Compilation;
public interface CompilationRepository extends JpaRepository {
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/repository/EventRepository.java b/core/event-service/src/main/java/ru/practicum/ewm/events/repository/EventRepository.java
new file mode 100644
index 0000000..f4c4d98
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/repository/EventRepository.java
@@ -0,0 +1,25 @@
+package ru.practicum.ewm.events.repository;
+
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import ru.practicum.aggregation.enums.EventState;
+import ru.practicum.ewm.events.entity.Event;
+
+import java.util.List;
+
+public interface EventRepository extends JpaRepository, JpaSpecificationExecutor {
+
+ List findByInitiatorId(Long userId, PageRequest pageRequest);
+
+ @Query("""
+ select e.initiatorId from Event e
+ where e.id = :eventId
+ """)
+ Long getInitiatorIdByEventId(Long eventId);
+
+ boolean existsByCategoryId(Long categoryId);
+
+ boolean existsByIdAndState(Long eventId, EventState state);
+}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/category/CategoryService.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/category/CategoryService.java
similarity index 59%
rename from core/main-service/src/main/java/ru/practicum/ewm/service/category/CategoryService.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/service/category/CategoryService.java
index c1843cf..714399a 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/category/CategoryService.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/category/CategoryService.java
@@ -1,23 +1,23 @@
-package ru.practicum.ewm.service.category;
+package ru.practicum.ewm.events.service.category;
import org.springframework.transaction.annotation.Transactional;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.dto.category.NewCategoryDto;
+import ru.practicum.aggregation.dto.category.output.CategoryDto;
+import ru.practicum.aggregation.dto.category.come.NewCategoryDto;
import java.util.List;
+@Transactional
public interface CategoryService {
- @Transactional
CategoryDto adminAddNewCategory(NewCategoryDto newCategoryDto);
+ @Transactional(readOnly = true)
List findAll(Integer from, Integer size);
+ @Transactional(readOnly = true)
CategoryDto findById(Long catId);
- @Transactional
CategoryDto updateCategory(Long catId, CategoryDto categoryDto);
- @Transactional
void deleteCategory(Long catId);
}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/category/CategoryServiceImpl.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/category/CategoryServiceImpl.java
similarity index 81%
rename from core/main-service/src/main/java/ru/practicum/ewm/service/category/CategoryServiceImpl.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/service/category/CategoryServiceImpl.java
index 28e435e..b0919b0 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/category/CategoryServiceImpl.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/category/CategoryServiceImpl.java
@@ -1,4 +1,4 @@
-package ru.practicum.ewm.service.category;
+package ru.practicum.ewm.events.service.category;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
@@ -7,14 +7,14 @@
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import ru.practicum.ewm.dao.CategoryRepository;
-import ru.practicum.ewm.dao.EventRepository;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.dto.category.NewCategoryDto;
-import ru.practicum.ewm.mapper.CategoryMapper;
-import ru.practicum.ewm.model.Category;
-import ru.practicum.ewm.util.error.exception.ConflictException;
-import ru.practicum.ewm.util.error.exception.NotFoundException;
+import ru.practicum.aggregation.dto.category.output.CategoryDto;
+import ru.practicum.aggregation.dto.category.come.NewCategoryDto;
+import ru.practicum.aggregation.error.exception.bussines.cause.ConflictException;
+import ru.practicum.aggregation.error.exception.bussines.cause.NotFoundException;
+import ru.practicum.ewm.events.mapper.CategoryMapper;
+import ru.practicum.ewm.events.entity.Category;
+import ru.practicum.ewm.events.repository.CategoryRepository;
+import ru.practicum.ewm.events.repository.EventRepository;
import java.util.List;
import java.util.stream.Collectors;
@@ -84,4 +84,5 @@ private Category getCategoryById(long categoryId) {
() -> new NotFoundException("Категория с id=" + categoryId + " не найдена")
);
}
+
}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/service/compilation/CompilationService.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/compilation/CompilationService.java
new file mode 100644
index 0000000..217f2be
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/compilation/CompilationService.java
@@ -0,0 +1,26 @@
+package ru.practicum.ewm.events.service.compilation;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.transaction.annotation.Transactional;
+import ru.practicum.aggregation.dto.compilation.output.CompilationDto;
+import ru.practicum.aggregation.dto.compilation.come.get.CompilationSearchFilter;
+import ru.practicum.aggregation.dto.compilation.come.update.CompilationUpdateDto;
+import ru.practicum.aggregation.dto.compilation.come.create.NewCompilationDto;
+
+import java.util.List;
+
+@Transactional
+public interface CompilationService {
+
+ @Transactional(readOnly = true)
+ CompilationDto getById(Long compilationId, HttpServletRequest request);
+
+ void delById(Long compilationId);
+
+ CompilationDto addCompilation(NewCompilationDto compilation);
+
+ CompilationDto updateCompilation(Long compilationId, CompilationUpdateDto compilation);
+
+ @Transactional(readOnly = true)
+ List getByFilter(CompilationSearchFilter filter, HttpServletRequest request);
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/service/compilation/CompilationServiceImpl.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/compilation/CompilationServiceImpl.java
new file mode 100644
index 0000000..9ae7429
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/compilation/CompilationServiceImpl.java
@@ -0,0 +1,235 @@
+package ru.practicum.ewm.events.service.compilation;
+
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.lang.NonNull;
+import org.springframework.stereotype.Service;
+import ru.practicum.aggregation.dto.compilation.come.create.NewCompilationDto;
+import ru.practicum.aggregation.dto.compilation.come.get.CompilationSearchFilter;
+import ru.practicum.aggregation.dto.compilation.come.update.CompilationUpdateDto;
+import ru.practicum.aggregation.dto.compilation.output.CompilationDto;
+import ru.practicum.aggregation.dto.user.output.UserShortDto;
+import ru.practicum.aggregation.error.exception.bussines.cause.NotFoundException;
+import ru.practicum.aggregation.model.entity.BaseEntity;
+import ru.practicum.aggregation.model.repository.EventRequestCount;
+import ru.practicum.aggregation.repository.RequestFeignRepository;
+import ru.practicum.aggregation.repository.StatsFeignRepository;
+import ru.practicum.aggregation.repository.UserFeignRepository;
+import ru.practicum.ewm.events.entity.Compilation;
+import ru.practicum.ewm.events.entity.Event;
+import ru.practicum.ewm.events.mapper.CompilationMapper;
+import ru.practicum.ewm.events.repository.CompilationRepository;
+import ru.practicum.ewm.events.repository.EventRepository;
+import ru.practicum.aggregation.model.data.StatsRequestData;
+import ru.practicum.stat.dto.ViewStatsDto;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+public class CompilationServiceImpl implements CompilationService {
+
+ EventRepository eventRepository;
+ CompilationRepository compilationRepository;
+
+ StatsFeignRepository statsFeignRepository;
+
+ UserFeignRepository userFeignRepository;
+ RequestFeignRepository requestFeignRepository;
+
+ @Override
+ public CompilationDto getById(Long compilationId, HttpServletRequest request) {
+ statsFeignRepository.sendHitRequest(request);
+
+ var compilation = getCompilationById(compilationId);
+ var confirmedRequests = getConfirmedRequests(List.of(compilation));
+ var views = getViews(List.of(compilation));
+ var events = compilation.getEvents();
+ var eventIdToInitiator = eventIdToInitiatorMap(events);
+
+ return CompilationMapper.toCompilationDto(compilation, eventIdToInitiator, confirmedRequests, views);
+ }
+
+ @Override
+ public void delById(Long compilationId) {
+ getCompilationById(compilationId);
+ compilationRepository.deleteById(compilationId);
+ }
+
+ @Override
+ public CompilationDto addCompilation(@NonNull NewCompilationDto compilationDto) {
+ Set events = new HashSet<>();
+
+ if (compilationDto.getEvents() != null && !compilationDto.getEvents().isEmpty()) {
+ events = new HashSet<>(eventRepository.findAllById(compilationDto.getEvents()));
+
+ if (events.size() < compilationDto.getEvents().size()) {
+ throw new NotFoundException("Одно или несколько событий не найдены");
+ }
+ }
+
+ var savedCompilation = compilationRepository.save(CompilationMapper.toEntity(compilationDto, events));
+
+ Map confirmedRequests = new HashMap<>();
+ savedCompilation.getEvents().forEach(event -> confirmedRequests.put(event.getId(), 0L));
+
+ Map views = new HashMap<>();
+ savedCompilation.getEvents().forEach(event -> views.put(event.getId(), 0L));
+
+ var eventIdToInitiator = eventIdToInitiatorMap(events);
+
+ return CompilationMapper.toCompilationDto(
+ savedCompilation, eventIdToInitiator, confirmedRequests, views);
+ }
+
+ @Override
+ public CompilationDto updateCompilation(Long compilationId,
+ @NonNull CompilationUpdateDto compilationUpdateDto) {
+ var compilationInDb = getCompilationById(compilationId);
+
+ if (compilationUpdateDto.getEvents() != null) {
+ List eventsUpdate = new ArrayList<>();
+
+ if (!compilationUpdateDto.getEvents().isEmpty()) {
+ eventsUpdate = eventRepository.findAllById(compilationUpdateDto.getEvents());
+ if (eventsUpdate.size() < compilationUpdateDto.getEvents().size()) {
+ throw new NotFoundException("Одно или несколько событий не найдены");
+ }
+ }
+ compilationInDb.setEvents(new HashSet<>(eventsUpdate));
+ }
+
+ if (compilationUpdateDto.getTitle() != null && !compilationUpdateDto.getTitle().isBlank()) {
+ compilationInDb.setTitle(compilationUpdateDto.getTitle());
+ }
+
+ if (compilationUpdateDto.getPinned() != null) {
+ compilationInDb.setPinned(compilationUpdateDto.getPinned());
+ }
+
+ var confirmedRequests = getConfirmedRequests(List.of(compilationInDb));
+ var views = getViews(List.of(compilationInDb));
+ var compilation = getCompilationById(compilationId);
+ var events = compilation.getEvents();
+ var eventIdToInitiator = eventIdToInitiatorMap(events);
+
+ return CompilationMapper.toCompilationDto(
+ compilationInDb, eventIdToInitiator, confirmedRequests, views);
+ }
+
+ @NonNull
+ private Map eventIdToInitiatorMap(@NonNull Set events) {
+ var initiatorIds = events.stream().map(Event::getInitiatorId).toList();
+ var initiatorMap = userFeignRepository.getUsersByIds(initiatorIds)
+ .stream()
+ .collect(Collectors.toMap(UserShortDto::id, Function.identity()));
+
+ return events.stream()
+ .collect(Collectors.toMap(BaseEntity::getId, e ->
+ initiatorMap.get(e.getInitiatorId())
+ )
+ );
+ }
+
+ @Override
+ public List getByFilter(@NonNull CompilationSearchFilter filter,
+ HttpServletRequest request) {
+ var pageable = PageRequest.of(filter.getFrom() / filter.getSize(), filter.getSize());
+ Page compilationsPage;
+
+ if (filter.getPinned() != null) {
+ compilationsPage = compilationRepository.findAllByPinned(filter.getPinned(), pageable);
+ } else {
+ compilationsPage = compilationRepository.findAll(pageable);
+ }
+
+ List compilations = compilationsPage.getContent();
+
+ if (compilations.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ Map allConfirmedRequests = getConfirmedRequests(compilations);
+ Map allViews = getViews(compilations);
+
+ var result = new ArrayList();
+ for (Compilation compilation : compilations) {
+
+ var events = compilation.getEvents();
+ var eventIdToInitiator = eventIdToInitiatorMap(events);
+
+ result.add(CompilationMapper.toCompilationDto(
+ compilation, eventIdToInitiator, allConfirmedRequests, allViews));
+ }
+
+ return result;
+ }
+
+ @NonNull
+ private Compilation getCompilationById(long compilationId) {
+ return compilationRepository.findById(compilationId).orElseThrow(
+ () -> new NotFoundException("Подборка с id=" + compilationId + " не найдена")
+ );
+ }
+
+ /// Map
+ @NonNull
+ private Map getConfirmedRequests(@NonNull Collection compilations) {
+ List events = compilations.stream()
+ .flatMap(c -> c.getEvents().stream())
+ .toList();
+
+ if (events.isEmpty()) return Collections.emptyMap();
+
+ List eventRequestCountList = requestFeignRepository
+ .getConfirmedRequestsCount(events.stream().map(Event::getId).toList());
+
+ return eventRequestCountList.stream()
+ .collect(Collectors.toMap(
+ EventRequestCount::eventId,
+ EventRequestCount::count,
+ (existing, replacement) -> existing
+ )
+ );
+ }
+
+ /// Map
+ @NonNull
+ private Map getViews(@NonNull Collection compilations) {
+
+ // Все уникальные события
+ List allEvents = compilations.stream()
+ .flatMap(c -> c.getEvents().stream())
+ .distinct()
+ .toList();
+
+ if (allEvents.isEmpty()) return Collections.emptyMap();
+
+ // Все URIs
+ List uris = allEvents.stream().map(e -> "/events/" + e.getId()).toList();
+
+ var statsOptional = statsFeignRepository.getStatList(
+ StatsRequestData.builder()
+ .uris(uris)
+ .unique(false)
+ .build()
+ );
+
+ // Map
+ return statsOptional.map(viewStatsDtos -> viewStatsDtos.stream()
+ .collect(Collectors.toMap(statsDto ->
+ Long.parseLong(statsDto.getUri().replace("/events/", "")),
+ ViewStatsDto::getHits,
+ (a, b) -> a
+ ))
+ ).orElse(Collections.emptyMap());
+ }
+
+}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/event/EventService.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/event/EventService.java
similarity index 60%
rename from core/main-service/src/main/java/ru/practicum/ewm/service/event/EventService.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/service/event/EventService.java
index af8549f..eac622a 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/event/EventService.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/event/EventService.java
@@ -1,16 +1,23 @@
-package ru.practicum.ewm.service.event;
+package ru.practicum.ewm.events.service.event;
import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.constraints.Positive;
import org.springframework.transaction.annotation.Transactional;
-import ru.practicum.ewm.dto.event.*;
+import ru.practicum.aggregation.dto.event.come.create.NewEventDto;
+import ru.practicum.aggregation.dto.event.come.update.UpdateEventAdminRequest;
+import ru.practicum.aggregation.dto.event.come.update.UpdateEventUserRequest;
+import ru.practicum.aggregation.dto.event.output.EventFullDto;
+import ru.practicum.aggregation.dto.event.output.EventShortDto;
+import ru.practicum.aggregation.model.data.AdminGetData;
+import ru.practicum.aggregation.model.data.FreeGetData;
import java.util.List;
-@Transactional
+@Transactional(readOnly = true)
public interface EventService {
/// Получение событий незарегистрированным пользователем с возможностью фильтрации
- List getFreeEvents(FreeGetDto freeGetDto, HttpServletRequest request);
+ List getFreeEvents(FreeGetData freeGetData, HttpServletRequest request);
/**
* Получение незарегистрированным пользователем подробной информации об опубликованном событии
@@ -19,21 +26,28 @@ public interface EventService {
EventFullDto getFreeEventById(Long eventId, HttpServletRequest request);
/// Добавление нового события зарегистрированным пользователем
+ @Transactional
EventFullDto userAddNewEvent(Long userId, NewEventDto newEventDto);
/// Поиск событий администратором
- @Transactional(readOnly = true)
- List adminGetEvents(AdminGetDto adminGetDto);
+ List adminGetEvents(AdminGetData adminGetData);
/// Редактирование администратором данных события и его статуса (отклонение/публикация)
+ @Transactional
EventFullDto adminUpdateEvent(Long eventId, UpdateEventAdminRequest request);
/// Получение событий, добавленных текущим пользователем
List findByUserId(Long userId, Integer from, Integer size);
/// Получение полной информации о событии добавленном текущим пользователем
- EventFullDto findEventById(Long userId, Long eventId);
+ EventFullDto findEventByUserIdAndEventId(Long userId, Long eventId);
+
+ /// Получение полной информации о событии по ID
+ EventFullDto findEventById(long eventId, long confirmets);
/// Изменение события добавленного текущим пользователем
+ @Transactional
EventFullDto patchEvent(Long userId, Long eventId, UpdateEventUserRequest request);
+
+ long getInitiatorIfPublished(@Positive Long eventId);
}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/service/event/EventServiceImpl.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/event/EventServiceImpl.java
new file mode 100644
index 0000000..0f1a1e5
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/event/EventServiceImpl.java
@@ -0,0 +1,602 @@
+package ru.practicum.ewm.events.service.event;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.ValidationException;
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.lang.NonNull;
+import org.springframework.stereotype.Service;
+import ru.practicum.aggregation.dto.event.come.create.NewEventDto;
+import ru.practicum.aggregation.dto.event.come.update.UpdateEventAdminRequest;
+import ru.practicum.aggregation.dto.event.come.update.UpdateEventUserRequest;
+import ru.practicum.aggregation.dto.event.output.EventFullDto;
+import ru.practicum.aggregation.dto.event.output.EventShortDto;
+import ru.practicum.aggregation.dto.user.output.UserDto;
+import ru.practicum.aggregation.dto.user.output.UserShortDto;
+import ru.practicum.aggregation.enums.AdminStateAction;
+import ru.practicum.aggregation.enums.EventState;
+import ru.practicum.aggregation.enums.UserStateAction;
+import ru.practicum.aggregation.error.exception.bussines.cause.ConflictException;
+import ru.practicum.aggregation.error.exception.bussines.cause.NotFoundException;
+import ru.practicum.aggregation.model.data.AdminGetData;
+import ru.practicum.aggregation.model.data.FreeGetData;
+import ru.practicum.aggregation.model.data.StatsRequestData;
+import ru.practicum.aggregation.model.repository.EventRequestCount;
+import ru.practicum.aggregation.repository.RequestFeignRepositoryImpl;
+import ru.practicum.aggregation.repository.StatsFeignRepository;
+import ru.practicum.aggregation.repository.UserFeignRepositoryImpl;
+import ru.practicum.ewm.events.entity.Category;
+import ru.practicum.ewm.events.entity.Event;
+import ru.practicum.ewm.events.mapper.EventMapper;
+import ru.practicum.ewm.events.mapper.StateMapper;
+import ru.practicum.ewm.events.mapper.UserMapper;
+import ru.practicum.ewm.events.model.EventData;
+import ru.practicum.ewm.events.repository.CategoryRepository;
+import ru.practicum.ewm.events.repository.EventRepository;
+import ru.practicum.ewm.events.specification.EventSpecifications;
+import ru.practicum.ewm.events.specification.SpecBuilder;
+import ru.practicum.stat.dto.ViewStatsDto;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+public class EventServiceImpl implements EventService {
+
+ StatsFeignRepository statsFeignRepository;
+ EventRepository eventRepository;
+ CategoryRepository categoryRepository;
+
+ UserFeignRepositoryImpl userFeignRepository;
+ RequestFeignRepositoryImpl requestFeignRepository;
+
+ private static final String EVENTS_PATH = "/events/";
+ private static final int HOURS_BEFORE_START = 2;
+
+ @Override
+ public List getFreeEvents(@NonNull FreeGetData dto, HttpServletRequest request) {
+
+ if (dto.rangeStart() != null && dto.rangeEnd() != null) {
+ if (dto.rangeEnd().isBefore(dto.rangeStart())) {
+ throw new ValidationException("Окончание события не может быть раньше начала");
+ }
+ }
+
+ SpecBuilder builder = SpecBuilder.builder()
+ .and(EventSpecifications.isPublished())
+ .andIf(dto.text() != null && !dto.text().isBlank(),
+ () -> EventSpecifications.textContains(dto.text()))
+ .andIf(dto.categories() != null && !dto.categories().isEmpty(),
+ () -> EventSpecifications.hasCategories(dto.categories()))
+ .andIf(dto.paid() != null,
+ () -> EventSpecifications.isPaid(dto.paid()))
+ .andIf(Boolean.TRUE.equals(dto.onlyAvailable()),
+ () -> EventSpecifications.onlyAvailable(true));
+
+ boolean hasStart = dto.rangeStart() != null;
+ boolean hasEnd = dto.rangeEnd() != null;
+
+ if (!hasStart && !hasEnd) {
+ builder.and(EventSpecifications.eventDateAfterNow(LocalDateTime.now()));
+ } else {
+ builder
+ .andIf(hasStart,
+ () -> EventSpecifications.dateAfter(dto.rangeStart()))
+ .andIf(hasEnd,
+ () -> EventSpecifications.dateBefore(dto.rangeEnd()));
+ }
+
+ Specification spec = builder.build();
+
+ Sort sort = Sort.unsorted();
+
+ if (dto.sort() != null) {
+ switch (dto.sort()) {
+ case EVENT_DATE -> sort = Sort.by("eventDate").ascending();
+ case VIEWS -> sort = Sort.by("views").descending();
+ }
+ }
+
+ Pageable pageable = PageRequest.of((dto.from() / dto.size()), dto.size(), sort);
+
+ List events = eventRepository.findAll(spec, pageable).getContent();
+ if (events.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ var confirmedRequestsCounts = fetchConfirmedRequestsCount(
+ events.stream().map(Event::getId).toList());
+
+ Map eventIdToRequestCount = getRequestCountMap(confirmedRequestsCounts);
+
+ var statsData = StatsRequestData.builder()
+ .uris(getUris(events))
+ .start(dto.rangeStart())
+ .end(dto.rangeEnd())
+ .unique(false)
+ .build();
+
+ var statsOptional = statsFeignRepository.getStatList(statsData);
+
+ Map userIdToInitiator = getUserShortDtoMap(events);
+
+ return events.stream()
+ .map(event -> {
+ var userId = event.getInitiatorId();
+ var confirmets = eventIdToRequestCount.getOrDefault(userId, 0L);
+ AtomicLong views = new AtomicLong();
+ statsOptional.ifPresentOrElse(stats ->
+ views.set(getViewsFromStatsList(stats, event.getId())),
+ () -> views.set(1L)
+ );
+ var eventData = EventData.builder()
+ .initiator(userIdToInitiator.get(userId))
+ .confirmedRequests(confirmets)
+ .views(views.get())
+ .build();
+ return EventMapper.toEventShortDto(event, eventData);
+ })
+ .toList();
+ }
+
+ @Override
+ public EventFullDto getFreeEventById(Long eventId, @NonNull HttpServletRequest request) {
+ checkEvent(eventId);
+
+ var event = getEventById(eventId);
+ var initiator = UserMapper.toUserShortDto(getUserById(event.getInitiatorId()));
+ var uris = List.of(request.getRequestURI());
+ var statsOptional = statsFeignRepository.getStatList(
+ StatsRequestData.builder()
+ .uris(uris)
+ .unique(true)
+ .build()
+ );
+
+ long views = statsOptional.map(viewStatsDtos -> viewStatsDtos.stream()
+ .findFirst()
+ .map(ViewStatsDto::getHits)
+ .orElse(0L)
+ )
+ .orElse(1L);
+
+ var confirmedRequestsCount = getConfirmedRequestsCountByEventId(eventId);
+
+ var eventData = EventData.builder()
+ .initiator(initiator)
+ .confirmedRequests(confirmedRequestsCount)
+ .views(views)
+ .build();
+
+ return EventMapper.toEventFullDto(event, eventData);
+ }
+
+ @Override
+ public EventFullDto userAddNewEvent(Long userId, @NonNull NewEventDto newEventDto) {
+ if (newEventDto.participantLimit() != null && newEventDto.participantLimit() < 0) {
+ throw new ValidationException(
+ "Ограничение на количество участников должно быть положительным числом");
+ }
+
+ if (newEventDto.eventDate() != null
+ && newEventDto.eventDate().isBefore(LocalDateTime.now().plusHours(2))) {
+ throw new ValidationException(
+ "Начало события не может быть раньше, чем через два часа от текущего момента");
+ }
+
+ userFeignRepository.checkUser(userId);
+
+ var category = getCategoryById(newEventDto.category());
+ var event = eventRepository.save(
+ EventMapper.toEntity(
+ newEventDto,
+ category,
+ LocalDateTime.now(),
+ userId,
+ null,
+ EventState.PENDING
+ )
+ );
+ var initiator = UserMapper.toUserShortDto(getUserById(event.getInitiatorId()));
+
+ var eventData = EventData.builder()
+ .initiator(initiator)
+ .confirmedRequests(0)
+ .views(0)
+ .build();
+
+ return EventMapper.toEventFullDto(event, eventData);
+ }
+
+ @Override
+ public List adminGetEvents(@NonNull AdminGetData dto) {
+ Specification spec = SpecBuilder.builder()
+ .andIf(dto.users() != null && !dto.users().isEmpty(),
+ () -> EventSpecifications.hasUsers(dto.users()))
+ .andIf(dto.states() != null && !dto.states().isEmpty(),
+ () -> EventSpecifications.hasStates(dto.states()))
+ .andIf(dto.categories() != null && !dto.categories().isEmpty(),
+ () -> EventSpecifications.hasCategories(dto.categories()))
+ .andIf(dto.rangeStart() != null,
+ () -> EventSpecifications.dateAfter(dto.rangeStart()))
+ .andIf(dto.rangeEnd() != null,
+ () -> EventSpecifications.dateBefore(dto.rangeEnd()))
+ .build();
+
+ Pageable pageable = PageRequest.of(
+ dto.from() / dto.size(),
+ dto.size()
+ );
+
+ List events = eventRepository.findAll(spec, pageable).getContent();
+ if (events.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ List confirmedRequestsCounts = fetchConfirmedRequestsCount(
+ events.stream().map(Event::getId).toList());
+
+ Map eventIdToRequestCount = getRequestCountMap(confirmedRequestsCounts);
+
+ var statsData = StatsRequestData.builder()
+ .uris(getUris(events))
+ .start(dto.rangeStart())
+ .end(dto.rangeEnd())
+ .unique(false)
+ .build();
+
+ var statsOptional = statsFeignRepository.getStatList(statsData);
+
+ Map initiators = getUserShortDtoMap(events);
+
+ return events.stream()
+ .map(event -> {
+ var userId = event.getInitiatorId();
+ var count = getConfirmedRequestsCountFromMap(eventIdToRequestCount, event.getId());
+ AtomicLong views = new AtomicLong();
+ statsOptional.ifPresentOrElse(stats ->
+ views.set(getViewsFromStatsList(stats, event.getId())),
+ () -> views.set(1L)
+ );
+ var eventData = EventData.builder()
+ .initiator(initiators.get(userId))
+ .confirmedRequests(count)
+ .views(views.get())
+ .build();
+ return EventMapper.toEventFullDto(event, eventData);
+ })
+ .toList();
+ }
+
+ @Override
+ public EventFullDto adminUpdateEvent(Long eventId, @NonNull UpdateEventAdminRequest request) {
+ Event oldEvent = getEventById(eventId);
+ Event newEvent;
+
+ if (request.eventDate() != null && request.eventDate()
+ .isBefore(LocalDateTime.now().plusHours(HOURS_BEFORE_START))) {
+ throw new ValidationException(
+ "Дата события не может быть раньше, чем через два часа от текущего момента");
+ }
+
+ if (request.stateAction() == null) {
+ newEvent = EventMapper.update(
+ oldEvent,
+ request,
+ oldEvent.getState(),
+ oldEvent.getPublishedOn(),
+ request.category() == null ?
+ Optional.empty() :
+ Optional.of(getCategoryById(request.category()))
+ );
+ } else {
+
+ if (request.stateAction().equals(AdminStateAction.PUBLISH_EVENT) &&
+ oldEvent.getState().equals(EventState.PUBLISHED)) {
+ throw new ConflictException("Событие с id=%s уже опубликовано"
+ .formatted(oldEvent.getId())
+ );
+ }
+
+ if (request.stateAction().equals(AdminStateAction.PUBLISH_EVENT) &&
+ oldEvent.getState().equals(EventState.CANCELED)) {
+ throw new ConflictException("Публикация события с id=%s уже отменена пользователем"
+ .formatted(oldEvent.getId())
+ );
+ }
+
+ if (request.stateAction().equals(AdminStateAction.REJECT_EVENT) &&
+ oldEvent.getState().equals(EventState.PUBLISHED)) {
+ throw new ConflictException("Событие с id=%s уже опубликовано, отмена не возможна"
+ .formatted(oldEvent.getId())
+ );
+ }
+
+ newEvent = EventMapper.update(
+ oldEvent,
+ request,
+ request.stateAction().equals(AdminStateAction.REJECT_EVENT)
+ ? EventState.CANCELED : EventState.PUBLISHED,
+ request.stateAction().equals(AdminStateAction.REJECT_EVENT)
+ ? null : LocalDateTime.now(),
+ request.category() == null
+ ? Optional.empty() : Optional.of(getCategoryById(request.category()))
+ );
+ }
+
+ var event = eventRepository.save(newEvent);
+
+ return EventMapper.toEventFullDto(event, getEventData(eventId, event.getInitiatorId()));
+ }
+
+ @Override
+ public List findByUserId(Long userId, Integer from, Integer size) {
+ userFeignRepository.checkUser(userId);
+
+ PageRequest pageRequest = PageRequest.of(from / size, size);
+ List events = eventRepository.findByInitiatorId(userId, pageRequest);
+ if (events.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ List confirmedRequestsCounts = fetchConfirmedRequestsCount(
+ events.stream().map(Event::getId).toList());
+
+ Map eventIdToRequestCount = getRequestCountMap(confirmedRequestsCounts);
+
+ List uris = getUris(events);
+ var statsOptional = statsFeignRepository.getStatList(
+ StatsRequestData.builder()
+ .uris(uris)
+ .unique(true)
+ .build()
+ );
+
+ Map initiators = getUserShortDtoMap(events);
+
+ return events.stream()
+ .map(event -> {
+ var count = getConfirmedRequestsCountFromMap(eventIdToRequestCount, event.getId());
+ AtomicLong views = new AtomicLong();
+ statsOptional.ifPresentOrElse(stats ->
+ views.set(getViewsFromStatsList(stats, event.getId())),
+ () -> views.set(1L)
+ );
+ var eventData = EventData.builder()
+ .initiator(initiators.get(userId))
+ .confirmedRequests(count)
+ .views(views.get())
+ .build();
+ return EventMapper.toEventShortDto(event, eventData);
+ })
+ .toList();
+ }
+
+ @Override
+ public EventFullDto findEventByUserIdAndEventId(Long userId, Long eventId) {
+ userFeignRepository.checkUser(userId);
+
+ Event event = getEventById(eventId);
+ var initiatorId = event.getInitiatorId();
+
+ if (!initiatorId.equals(userId)) {
+ throw new ConflictException("Пользователь должен быть инициатором");
+ }
+
+ return EventMapper.toEventFullDto(event, getEventData(eventId, initiatorId));
+ }
+
+ @Override
+ public EventFullDto findEventById(long eventId, long confirmets) {
+ Event event = getEventById(eventId);
+ var eventData = EventData.builder()
+ .initiator(UserMapper.toUserShortDto(getUserById(event.getInitiatorId())))
+ .confirmedRequests(confirmets)
+ .views(getViews(event.getId()))
+ .build();
+
+ return EventMapper.toEventFullDto(event, eventData);
+ }
+
+ @Override
+ public EventFullDto patchEvent(Long userId, Long eventId, @NonNull UpdateEventUserRequest request) {
+ if (request.participantLimit() != null && request.participantLimit() < 0) {
+ throw new ValidationException(
+ "Ограничение на количество участников должно быть положительным числом");
+ }
+
+ userFeignRepository.checkUser(userId);
+ return patchEvent(eventId, request, false);
+ }
+
+ @Override
+ public long getInitiatorIfPublished(Long eventId) {
+ checkEvent(eventId);
+ long initiatorId = eventRepository.getInitiatorIdByEventId(eventId);
+ userFeignRepository.checkUser(initiatorId);
+ return initiatorId;
+ }
+
+ private void checkEvent(Long eventId) {
+ if (!eventRepository.existsByIdAndState(eventId, EventState.PUBLISHED)) {
+ throw new NotFoundException(
+ "Событие с id=%s не существует или не опубликовано.".formatted(eventId));
+ }
+ }
+
+ @SuppressWarnings("SameParameterValue")
+ private EventFullDto patchEvent(Long eventId,
+ @NonNull UpdateEventUserRequest request,
+ boolean isAdmin) {
+ try {
+ Event event = getEventById(eventId);
+
+ if (!isAdmin && event.getState() == EventState.PUBLISHED) {
+ throw new ConflictException("Нельзя редактировать опубликованное событие");
+ }
+
+ if (request.eventDate() != null) {
+ LocalDateTime eventDateTime = request.eventDate();
+ LocalDateTime minDateTime = LocalDateTime.now().plusHours(HOURS_BEFORE_START);
+
+ if (!isAdmin && eventDateTime.isBefore(minDateTime)) {
+ throw new ValidationException(
+ String.format(
+ "Дата события должна быть не ранее чем за %d часа(ов) до начала",
+ HOURS_BEFORE_START
+ )
+ );
+ }
+ }
+
+ UserStateAction action = request.stateAction();
+
+ if (action != null) {
+ EventState newState = isAdmin
+ ? StateMapper.mapAdminEventAction(action)
+ : StateMapper.mapUserEventAction(action);
+
+ if (EventState.PUBLISHED.equals(newState)) {
+ event.setPublishedOn(LocalDateTime.from(Instant.now()));
+ }
+ if (newState != null) {
+ event.setState(newState);
+ }
+ }
+
+ if (request.category() != null) {
+ Category category = getCategoryById(request.category());
+ event.setCategory(category);
+ }
+
+ EventMapper.merge(event, request);
+
+ Event patched = eventRepository.save(event);
+
+ log.info("Событие обновлено: {}", patched.getId());
+
+ return EventMapper.toEventFullDto(event, getEventData(eventId, event.getInitiatorId()));
+
+ } catch (DataIntegrityViolationException e) {
+ log.debug("Конфликт во время обновления события {}", request, e);
+ throw new ConflictException("Конфликт с другим событием");
+ }
+ }
+
+ private List fetchConfirmedRequestsCount(List events) {
+ return requestFeignRepository.getConfirmedRequestsCount(events);
+ }
+
+ @NonNull
+ private List getUris(@NonNull List events) {
+ return events.stream().map(event -> EVENTS_PATH + event.getId()).toList();
+ }
+
+ private Map getRequestCountMap(@NonNull List eventRequestCountList) {
+ return eventRequestCountList.stream()
+ .collect(Collectors.toMap(EventRequestCount::eventId, EventRequestCount::count,
+ (a, b) -> a));
+ }
+
+ @NonNull
+ private Map getUserShortDtoMap(@NonNull List events) {
+ List userIds = events.stream().map(Event::getInitiatorId).toList();
+ List users = userFeignRepository.getUsersByIds(userIds);
+ return users.stream()
+ .collect(Collectors.toMap(UserShortDto::id, user -> user));
+ }
+
+ private EventData getEventData(long eventId, long initiatorId) {
+ return EventData.builder()
+ .initiator(UserMapper.toUserShortDto(getUserById(initiatorId)))
+ .confirmedRequests(getConfirmedRequestsCountByEventId(eventId))
+ .views(getViews(eventId))
+ .build();
+ }
+
+ @NonNull
+ private UserDto getUserById(long userId) {
+ return userFeignRepository.getUserDtoById(userId);
+ }
+
+ @NonNull
+ private Event getEventById(long eventId) {
+ return eventRepository.findById(eventId).orElseThrow(
+ () -> new NotFoundException("Событие с id=%s не найдено".formatted(eventId))
+ );
+ }
+
+ @NonNull
+ private Category getCategoryById(long categoryId) {
+ return categoryRepository.findById(categoryId).orElseThrow(
+ () -> new NotFoundException("Категория с id=%s не найдена".formatted(categoryId))
+ );
+ }
+
+ private long getConfirmedRequestsCountByEventId(long eventId) {
+ var counts = fetchConfirmedRequestsCount(List.of(eventId));
+ if (counts.isEmpty()) {
+ return 0;
+ }
+
+ return counts.getFirst().count();
+ }
+
+ private long getViews(long eventId) {
+ var uris = List.of(EVENTS_PATH + eventId);
+ var statsOptional = statsFeignRepository.getStatList(
+ StatsRequestData.builder()
+ .uris(uris)
+ .unique(true)
+ .build()
+ );
+
+ if (statsOptional.isEmpty()) {
+ return 1;
+ }
+
+ List stats = statsOptional.get();
+
+ if (stats.isEmpty()) {
+ return 0;
+ }
+ return stats.getFirst().getHits();
+ }
+
+ private long getConfirmedRequestsCountFromMap(@NonNull
+ Map requestCountMap,
+ long eventId) {
+ if (requestCountMap.isEmpty()) {
+ return 0;
+ }
+ if (requestCountMap.containsKey(eventId)) {
+ return requestCountMap.get(eventId);
+ }
+ return 0;
+ }
+
+ private long getViewsFromStatsList(@NonNull List viewStatsMap, long eventId) {
+ return viewStatsMap.stream()
+ .filter(statsDto -> statsDto.getUri().equals(EVENTS_PATH + eventId))
+ .map(ViewStatsDto::getHits)
+ .findAny()
+ .orElse(0L);
+ }
+
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/service/rating/EventRatingService.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/rating/EventRatingService.java
new file mode 100644
index 0000000..aecad37
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/rating/EventRatingService.java
@@ -0,0 +1,10 @@
+package ru.practicum.ewm.events.service.rating;
+
+import org.springframework.transaction.annotation.Transactional;
+import ru.practicum.aggregation.dto.rating.come.update.RatingUpdateRequest;
+
+@Transactional
+public interface EventRatingService {
+
+ void updateRating(RatingUpdateRequest request);
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/service/rating/EventRatingServiceImpl.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/rating/EventRatingServiceImpl.java
new file mode 100644
index 0000000..a31ca86
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/rating/EventRatingServiceImpl.java
@@ -0,0 +1,27 @@
+package ru.practicum.ewm.events.service.rating;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import org.springframework.lang.NonNull;
+import org.springframework.stereotype.Service;
+import ru.practicum.aggregation.dto.rating.come.update.RatingUpdateRequest;
+import ru.practicum.aggregation.error.exception.bussines.cause.NotFoundException;
+import ru.practicum.ewm.events.entity.Event;
+import ru.practicum.ewm.events.repository.EventRepository;
+
+@Service
+@RequiredArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+public class EventRatingServiceImpl implements EventRatingService {
+
+ EventRepository eventRepository;
+
+ @Override
+ public void updateRating(@NonNull RatingUpdateRequest request) {
+ Event event = eventRepository.findById(request.eventId()).orElseThrow(() ->
+ new NotFoundException("Событие с id=%s не найдено".formatted(request.eventId())));
+ event.setRate(request.rate());
+ eventRepository.save(event);
+ }
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/service/request/EventRequestService.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/request/EventRequestService.java
new file mode 100644
index 0000000..09f9154
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/request/EventRequestService.java
@@ -0,0 +1,19 @@
+package ru.practicum.ewm.events.service.request;
+
+import org.springframework.transaction.annotation.Transactional;
+import ru.practicum.aggregation.dto.participation.come.EventRequestStatusUpdateRequest;
+import ru.practicum.aggregation.dto.participation.output.EventRequestStatusUpdateResult;
+import ru.practicum.aggregation.dto.participation.output.ParticipationRequestDto;
+
+import java.util.List;
+
+@Transactional
+public interface EventRequestService {
+
+ @Transactional(readOnly = true)
+ List findByEventId(long userId, long eventId);
+
+ EventRequestStatusUpdateResult updateStatusRequest(long userId,
+ long eventId,
+ EventRequestStatusUpdateRequest status);
+}
diff --git a/core/event-service/src/main/java/ru/practicum/ewm/events/service/request/EventRequestServiceImpl.java b/core/event-service/src/main/java/ru/practicum/ewm/events/service/request/EventRequestServiceImpl.java
new file mode 100644
index 0000000..c715bf3
--- /dev/null
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/service/request/EventRequestServiceImpl.java
@@ -0,0 +1,62 @@
+package ru.practicum.ewm.events.service.request;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import org.springframework.stereotype.Service;
+import ru.practicum.aggregation.dto.participation.come.EventRequestStatusUpdateRequest;
+import ru.practicum.aggregation.dto.participation.output.EventRequestStatusUpdateResult;
+import ru.practicum.aggregation.dto.participation.output.ParticipationRequestDto;
+import ru.practicum.aggregation.error.exception.bussines.cause.ConflictException;
+import ru.practicum.aggregation.error.exception.bussines.cause.NotFoundException;
+import ru.practicum.aggregation.repository.RequestFeignRepository;
+import ru.practicum.aggregation.repository.UserFeignRepositoryImpl;
+import ru.practicum.ewm.events.repository.EventRepository;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+public class EventRequestServiceImpl implements EventRequestService {
+
+ EventRepository eventRepository;
+
+ RequestFeignRepository requestFeignRepository;
+ UserFeignRepositoryImpl userFeignRepository;
+
+ @Override
+ public List findByEventId(long userId, long eventId) {
+ checkEvent(eventId);
+ userFeignRepository.checkUser(userId);
+
+ return requestFeignRepository.findByUserIdAndEventId(userId, eventId);
+ }
+
+ @Override
+ public EventRequestStatusUpdateResult updateStatusRequest(long userId,
+ long eventId,
+ EventRequestStatusUpdateRequest request
+ ) {
+ userFeignRepository.checkUser(userId);
+ var event = eventRepository.findById(eventId).orElseThrow(
+ () -> new NotFoundException("Событие с id=%s не найдено".formatted(eventId))
+ );
+
+ if (!event.getInitiatorId().equals(userId)) {
+ throw new ConflictException("Пользователь с id=%s не является инициатором события с id=%s"
+ .formatted(eventId, userId)
+ );
+ }
+
+ return requestFeignRepository.updateStatusRequest(
+ eventId, event.getParticipantLimit(), event.isRequestModeration(), request);
+ }
+
+ private void checkEvent(long eventId) {
+ if (!eventRepository.existsById(eventId)) {
+ throw new NotFoundException("Событие с id=%s не найдено".formatted(eventId));
+ }
+ }
+
+}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/util/specification/EventSpecifications.java b/core/event-service/src/main/java/ru/practicum/ewm/events/specification/EventSpecifications.java
similarity index 90%
rename from core/main-service/src/main/java/ru/practicum/ewm/util/specification/EventSpecifications.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/specification/EventSpecifications.java
index fe01617..9687d4b 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/util/specification/EventSpecifications.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/specification/EventSpecifications.java
@@ -1,12 +1,12 @@
-package ru.practicum.ewm.util.specification;
+package ru.practicum.ewm.events.specification;
import jakarta.persistence.criteria.Join;
import lombok.experimental.UtilityClass;
import org.springframework.data.jpa.domain.Specification;
-import ru.practicum.ewm.model.Category;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.model.enums.EventState;
+import org.springframework.lang.NonNull;
+import ru.practicum.aggregation.enums.EventState;
+import ru.practicum.ewm.events.entity.Category;
+import ru.practicum.ewm.events.entity.Event;
import java.time.LocalDateTime;
import java.util.List;
@@ -106,18 +106,19 @@ public Specification eventDateAfterNow(LocalDateTime now) {
}
/// initiator
+ @NonNull
public static Specification hasUsers(List userIds) {
return (root, query, cb) -> {
if (userIds == null || userIds.isEmpty()) {
return null;
}
- Join userJoin = root.join("initiator");
- return userJoin.get("id").in(userIds);
+ return root.get("initiatorId").in(userIds);
};
}
/// По статусам
+ @NonNull
public static Specification hasStates(List states) {
return (root, query, cb) -> {
if (states == null || states.isEmpty()) {
@@ -127,4 +128,5 @@ public static Specification hasStates(List states) {
return root.get("state").in(states);
};
}
+
}
\ No newline at end of file
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/util/specification/SpecBuilder.java b/core/event-service/src/main/java/ru/practicum/ewm/events/specification/SpecBuilder.java
similarity index 93%
rename from core/main-service/src/main/java/ru/practicum/ewm/util/specification/SpecBuilder.java
rename to core/event-service/src/main/java/ru/practicum/ewm/events/specification/SpecBuilder.java
index 1ec02c1..e7d546f 100644
--- a/core/main-service/src/main/java/ru/practicum/ewm/util/specification/SpecBuilder.java
+++ b/core/event-service/src/main/java/ru/practicum/ewm/events/specification/SpecBuilder.java
@@ -1,4 +1,4 @@
-package ru.practicum.ewm.util.specification;
+package ru.practicum.ewm.events.specification;
import org.springframework.data.jpa.domain.Specification;
@@ -33,4 +33,5 @@ public SpecBuilder and(Specification other) {
public Specification build() {
return spec;
}
+
}
diff --git a/core/main-service/src/main/resources/application-test.yaml b/core/event-service/src/main/resources/application-test.yaml.bak
similarity index 100%
rename from core/main-service/src/main/resources/application-test.yaml
rename to core/event-service/src/main/resources/application-test.yaml.bak
diff --git a/core/main-service/src/main/resources/application.yml b/core/event-service/src/main/resources/application.yml
similarity index 97%
rename from core/main-service/src/main/resources/application.yml
rename to core/event-service/src/main/resources/application.yml
index 8c9a66f..18d7df8 100644
--- a/core/main-service/src/main/resources/application.yml
+++ b/core/event-service/src/main/resources/application.yml
@@ -3,7 +3,7 @@ server:
spring:
application:
- name: main-service
+ name: event-service
config:
import: "optional:configserver:"
cloud:
diff --git a/core/main-service/src/main/resources/schema-h2.sql b/core/event-service/src/main/resources/schema-h2.sql.bak
similarity index 100%
rename from core/main-service/src/main/resources/schema-h2.sql
rename to core/event-service/src/main/resources/schema-h2.sql.bak
diff --git a/core/event-service/src/main/resources/schema-postgres.sql b/core/event-service/src/main/resources/schema-postgres.sql
new file mode 100644
index 0000000..1345dd0
--- /dev/null
+++ b/core/event-service/src/main/resources/schema-postgres.sql
@@ -0,0 +1,47 @@
+CREATE TABLE IF NOT EXISTS categories (
+ id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+ name varchar(50) NOT NULL,
+ CONSTRAINT pk_categories PRIMARY KEY (id)
+);
+CREATE UNIQUE INDEX IF NOT EXISTS idx_categories_name ON categories (name);
+
+CREATE TABLE IF NOT EXISTS events (
+ id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+ annotation varchar(2000) NOT NULL,
+ created_on timestamp(3) without time zone NOT NULL,
+ description varchar(7000) NOT NULL,
+ event_date timestamp(3) without time zone NOT NULL,
+ location jsonb,
+ paid boolean NOT NULL,
+ participant_limit integer NOT NULL,
+ published_on timestamp(3) without time zone,
+ request_moderation boolean NOT NULL,
+ state varchar(255) check (state in ('PENDING','PUBLISHED','CANCELED')) NOT NULL,
+ title varchar(120) NOT NULL,
+ category_id bigint,
+ initiator_id bigint,
+ rate bigint NOT NULL DEFAULT 0,
+ CONSTRAINT pk_events PRIMARY KEY (id),
+ CONSTRAINT fk_events_categories FOREIGN KEY (category_id)
+ REFERENCES categories (id) MATCH SIMPLE
+ ON UPDATE NO ACTION
+ ON DELETE NO ACTION
+);
+
+CREATE TABLE IF NOT EXISTS compilations (
+ id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+ pinned boolean NOT NULL,
+ title varchar(50) NOT NULL,
+ CONSTRAINT pk_compilations PRIMARY KEY (id)
+);
+
+CREATE TABLE IF NOT EXISTS compilation_events (
+ compilations_id bigint NOT NULL,
+ events_id bigint NOT NULL,
+ CONSTRAINT fk_events_compilations FOREIGN KEY (compilations_id)
+ REFERENCES compilations (id) MATCH SIMPLE
+ ON DELETE CASCADE,
+ CONSTRAINT fk_compilations_events FOREIGN KEY (events_id)
+ REFERENCES events (id) MATCH SIMPLE
+ ON DELETE CASCADE
+);
\ No newline at end of file
diff --git a/core/main-service/src/main/resources/schema-postgres.sql b/core/event-service/src/main/resources/schema-postgres.sql.bak
similarity index 100%
rename from core/main-service/src/main/resources/schema-postgres.sql
rename to core/event-service/src/main/resources/schema-postgres.sql.bak
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/MainServiceApp.java b/core/main-service/src/main/java/ru/practicum/ewm/MainServiceApp.java
deleted file mode 100644
index eab9033..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/MainServiceApp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package ru.practicum.ewm;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-
-@SpringBootApplication
-@ComponentScan(value = {"ru.practicum.ewm", "ru.practicum.stat.client"})
-public class MainServiceApp {
- public static void main(String[] args) {
- SpringApplication.run(MainServiceApp.class, args);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminCompilationController.java b/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminCompilationController.java
deleted file mode 100644
index a68b957..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminCompilationController.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package ru.practicum.ewm.controller.admin;
-
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.compilation.CompilationDto;
-import ru.practicum.ewm.dto.compilation.CompilationUpdateDto;
-import ru.practicum.ewm.dto.compilation.NewCompilationDto;
-import ru.practicum.ewm.service.compilation.CompilationService;
-
-@RestController
-@RequestMapping(path = "/admin/compilations")
-@RequiredArgsConstructor
-public class AdminCompilationController {
-
- private final CompilationService compilationService;
-
- /**
- * Добавление новой подборки (подборка может не содержать событий)
- *
- * @param newCompilationDto данные новой подборки
- * @return {@link CompilationDto}
- */
- @PostMapping
- @ResponseStatus(HttpStatus.CREATED)
- public CompilationDto createCompilation(@RequestBody @Valid NewCompilationDto newCompilationDto) {
- return compilationService.addCompilation(newCompilationDto);
- }
-
- /**
- *
- * @param compilationUpdateDto данные для обновления подборки
- * @param compId id подборки
- * @return {@link CompilationDto}
- */
- @PatchMapping("/{compId}")
- public CompilationDto updateCompilation(@RequestBody @Valid CompilationUpdateDto compilationUpdateDto,
- @PathVariable Long compId) {
- return compilationService.updateCompilation(compId, compilationUpdateDto);
- }
-
- /**
- * Удаление подборки
- *
- * @param compId id подборки
- */
- @DeleteMapping("/{compId}")
- @ResponseStatus(HttpStatus.NO_CONTENT)
- public void delById(@PathVariable Long compId) {
- compilationService.delById(compId);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminEventController.java b/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminEventController.java
deleted file mode 100644
index 9aafe96..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminEventController.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package ru.practicum.ewm.controller.admin;
-
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
-import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.event.AdminGetDto;
-import ru.practicum.ewm.dto.event.EventFullDto;
-import ru.practicum.ewm.dto.event.UpdateEventAdminRequest;
-import ru.practicum.ewm.model.enums.EventState;
-import ru.practicum.ewm.service.event.EventService;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@RestController
-@RequestMapping(path = "/admin/events")
-@RequiredArgsConstructor
-public class AdminEventController {
-
- private final EventService eventService;
-
- /**
- * Поиск событий
- *
- * Эндпоинт возвращает полную информацию обо всех событиях подходящих под переданные условия
- * В случае, если по заданным фильтрам не найдено ни одного события, возвращает пустой список
- *
- * @param users список id пользователей, чьи события нужно найти
- * @param states список состояний в которых находятся искомые события
- * @param categories список id категорий в которых будет вестись поиск
- * @param rangeStart дата и время не раньше которых должно произойти событие
- * @param rangeEnd дата и время не позже которых должно произойти событие
- * @param from количество событий, которые нужно пропустить для формирования текущего набора
- * Default value : 0
- * @param size количество событий в наборе
- * Default value : 10
- * @return List<{@link EventFullDto}>
- */
- @GetMapping
- public List adminGetEvents(
- @RequestParam(required = false) List users,
- @RequestParam(required = false) List states,
- @RequestParam(required = false) List categories,
- @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime rangeStart,
- @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime rangeEnd,
- @RequestParam(required = false, defaultValue = "0") Integer from,
- @RequestParam(required = false, defaultValue = "10") Integer size) {
-
- AdminGetDto getDto = AdminGetDto.builder()
- .users(users)
- .states(states)
- .categories(categories)
- .rangeStart(rangeStart)
- .rangeEnd(rangeEnd)
- .from(from)
- .size(size)
- .build();
-
- return eventService.adminGetEvents(getDto);
- }
-
- /**
- * Редактирование данных события и его статуса (отклонение/публикация)
- *
- * Редактирование данных любого события администратором. Валидация данных не требуется. Обратите внимание:
- * - дата начала изменяемого события должна быть не ранее чем за час от даты публикации. (Ожидается код ошибки 409)
- * - событие можно публиковать, только если оно в состоянии ожидания публикации (Ожидается код ошибки 409)
- * - событие можно отклонить, только если оно еще не опубликовано (Ожидается код ошибки 409)
- *
- * @param eventId id события
- * @param request Данные HTTP-запроса
- * @return {@link EventFullDto}
- */
- @PatchMapping("/{eventId}")
- public EventFullDto adminUpdateEvent(
- @PathVariable Long eventId,
- @RequestBody @Valid UpdateEventAdminRequest request) {
-
- return eventService.adminUpdateEvent(eventId, request);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminUserController.java b/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminUserController.java
deleted file mode 100644
index cc5a305..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/admin/AdminUserController.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package ru.practicum.ewm.controller.admin;
-
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.user.NewUserRequest;
-import ru.practicum.ewm.dto.user.UserDto;
-import ru.practicum.ewm.service.user.UserService;
-
-import java.util.List;
-
-@RestController
-@RequestMapping(path = "/admin/users")
-@RequiredArgsConstructor
-public class AdminUserController {
-
- private final UserService userService;
-
- /**
- * Добавление нового пользователя
- *
- * @param newUserRequest Данные добавляемого пользователя
- * @return {@link UserDto}
- */
- @PostMapping
- @ResponseStatus(HttpStatus.CREATED)
- public UserDto addNewUser(@RequestBody @Valid NewUserRequest newUserRequest) {
- return userService.adminAddNewUser(newUserRequest);
- }
-
- /**
- * Получение информации о пользователях
- *
- * Возвращает информацию обо всех пользователях (учитываются параметры ограничения выборки),
- * либо о конкретных (учитываются указанные идентификаторы)
- * В случае, если по заданным фильтрам не найдено ни одного пользователя, возвращает пустой список
- *
- * @param ids id пользователей
- * @param from количество элементов, которые нужно пропустить для формирования текущего набора
- * Default value : 0
- * @param size количество элементов в наборе
- * Default value : 10
- * @return List<{@link UserDto}>
- */
- @GetMapping
- public List getUsers(
- @RequestParam(required = false) List ids,
- @RequestParam(defaultValue = "0") int from,
- @RequestParam(defaultValue = "10") int size
- ) {
- return userService.getUsers(ids, from, size);
- }
-
- /**
- * Удаление пользователя
- *
- * @param userId id пользователя
- */
- @DeleteMapping("/{userId}")
- @ResponseStatus(HttpStatus.NO_CONTENT)
- public void deleteUser(@PathVariable Long userId) {
- userService.deleteUser(userId);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeCompilationController.java b/core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeCompilationController.java
deleted file mode 100644
index 40450ac..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeCompilationController.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package ru.practicum.ewm.controller.free;
-
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.compilation.CompilationDto;
-import ru.practicum.ewm.dto.compilation.CompilationSearchFilter;
-import ru.practicum.ewm.service.compilation.CompilationService;
-
-import java.util.List;
-
-@RestController
-@RequestMapping(path = "/compilations")
-@RequiredArgsConstructor
-public class FreeCompilationController {
-
- private final CompilationService compilationService;
-
- /**
- * Получение подборок событий
- *
- * В случае, если по заданным фильтрам не найдено ни одной подборки, возвращает пустой список
- *
- * @param pinned искать только закрепленные/не закрепленные подборки
- * @param from количество элементов, которые нужно пропустить для формирования текущего набора
- * Default value : 0
- * @param size количество элементов в наборе
- * Default value : 10
- * @param request Данные HTTP-запроса
- * @return List<{@link CompilationDto}>
- */
- @GetMapping
- public List getCompilations(
- @RequestParam(required = false) Boolean pinned,
- @RequestParam(defaultValue = "0") Integer from,
- @RequestParam(defaultValue = "10") Integer size,
- HttpServletRequest request) {
-
- CompilationSearchFilter filter = CompilationSearchFilter.builder()
- .pinned(pinned)
- .from(from)
- .size(size)
- .build();
-
- return compilationService.getByFilter(filter, request);
- }
-
- /**
- * Получение подборки событий по его id
- *
- * @param compId id подборки
- * @param request Данные HTTP-запроса
- * @return {@link CompilationDto}
- */
- @GetMapping("/{compId}")
- public CompilationDto getCompilationById(@PathVariable Long compId,
- HttpServletRequest request) {
- return compilationService.getById(compId, request);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeEventController.java b/core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeEventController.java
deleted file mode 100644
index 996383e..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/free/FreeEventController.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package ru.practicum.ewm.controller.free;
-
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.RequiredArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
-import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.event.EventFullDto;
-import ru.practicum.ewm.dto.event.EventShortDto;
-import ru.practicum.ewm.dto.event.FreeGetDto;
-import ru.practicum.ewm.service.event.EventService;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@RestController
-@RequestMapping(path = "/events")
-@RequiredArgsConstructor
-public class FreeEventController {
-
- private final EventService eventService;
-
- /**
- * Получение событий с возможностью фильтрации
- *
- * Обратите внимание:
- * - это публичный эндпоинт, соответственно в выдаче должны быть только опубликованные события
- * - текстовый поиск (по аннотации и подробному описанию) должен быть без учета регистра букв
- * - если в запросе не указан диапазон дат [rangeStart-rangeEnd], то нужно выгружать события,
- * которые произойдут позже текущей даты и времени
- * - информация о каждом событии должна включать в себя количество просмотров и количество
- * уже одобренных заявок на участие
- * - информацию о том, что по этому эндпоинту был осуществлен и обработан запрос, нужно
- * сохранить в сервисе статистики
- * В случае, если по заданным фильтрам не найдено ни одного события, возвращает пустой список
- *
- * @param text текст для поиска в содержимом аннотации и подробном описании события
- * @param categories список идентификаторов категорий в которых будет вестись поиск
- * @param paid поиск только платных/бесплатных событий
- * @param rangeStart дата и время не раньше которых должно произойти событие
- * @param rangeEnd дата и время не позже которых должно произойти событие
- * @param onlyAvailable только события у которых не исчерпан лимит запросов на участие Default value : false
- * @param sort Вариант сортировки: по дате события или по количеству просмотров Available values : EVENT_DATE, VIEWS
- * @param from количество событий, которые нужно пропустить для формирования текущего набора Default value : 0
- * @param size количество событий в наборе Default value : 10
- * @param request Данные HTTP-запроса
- * @return List<{@link EventShortDto}>
- */
- @GetMapping
- public List getFreeEvents(
- @RequestParam(required = false) String text,
- @RequestParam(required = false) List categories,
- @RequestParam(required = false) Boolean paid,
- @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime rangeStart,
- @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime rangeEnd,
- @RequestParam(required = false, defaultValue = "false") Boolean onlyAvailable,
- @RequestParam(required = false) FreeGetDto.FreeEventSort sort,
- @RequestParam(required = false, defaultValue = "0") Integer from,
- @RequestParam(required = false, defaultValue = "10") Integer size,
- HttpServletRequest request
- ) {
-
- FreeGetDto freeGetDto = FreeGetDto.builder()
- .text(text)
- .categories(categories)
- .paid(paid)
- .rangeStart(rangeStart)
- .rangeEnd(rangeEnd)
- .onlyAvailable(onlyAvailable)
- .sort(sort)
- .from(from)
- .size(size)
- .build();
-
- return eventService.getFreeEvents(freeGetDto, request);
- }
-
- /**
- * Получение подробной информации об опубликованном событии по его идентификатору.
- *
- * @param eventId id события
- * @param request Данные HTTP-запроса
- * @return {@link EventFullDto}
- */
- @GetMapping(value = "/{eventId}")
- public EventFullDto getFreeEventById(@PathVariable Long eventId,
- HttpServletRequest request) {
- return eventService.getFreeEventById(eventId, request);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/controller/rating/RatingController.java b/core/main-service/src/main/java/ru/practicum/ewm/controller/rating/RatingController.java
deleted file mode 100644
index 0940438..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/controller/rating/RatingController.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package ru.practicum.ewm.controller.rating;
-
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-import ru.practicum.ewm.dto.rating.RatingRequest;
-import ru.practicum.ewm.dto.rating.RatingResponse;
-import ru.practicum.ewm.service.rating.RatingService;
-
-@RestController
-@RequestMapping("/users/{userId}/events/{eventId}/likes")
-@RequiredArgsConstructor
-public class RatingController {
-
- private final RatingService ratingService;
-
- @PostMapping
- @ResponseStatus(HttpStatus.CREATED)
- public RatingResponse addReaction(@PathVariable Long userId,
- @PathVariable Long eventId,
- @Valid @RequestBody RatingRequest request) {
- return ratingService.addOrUpdateReaction(userId, eventId, request);
- }
-
- @DeleteMapping
- @ResponseStatus(HttpStatus.NO_CONTENT)
- public void removeReaction(@PathVariable Long userId,
- @PathVariable Long eventId) {
- ratingService.removeReaction(userId, eventId);
- }
-}
\ No newline at end of file
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dao/EventRepository.java b/core/main-service/src/main/java/ru/practicum/ewm/dao/EventRepository.java
deleted file mode 100644
index 452a0bc..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dao/EventRepository.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package ru.practicum.ewm.dao;
-
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.enums.EventState;
-
-import java.util.Collection;
-import java.util.Optional;
-
-public interface EventRepository extends JpaRepository,
- JpaSpecificationExecutor {
-
- Collection findByInitiatorId(Long userId, PageRequest pageRequest);
-
- Optional findByIdAndState(Long eventId, EventState state);
-
- boolean existsByCategoryId(Long categoryId);
-
- boolean existsByIdAndState(Long eventId, EventState state);
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/compilation/CompilationDto.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/compilation/CompilationDto.java
deleted file mode 100644
index 127b712..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/compilation/CompilationDto.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package ru.practicum.ewm.dto.compilation;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import ru.practicum.ewm.dto.event.EventShortDto;
-
-import java.util.List;
-
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class CompilationDto {
- private Long id;
- private boolean pinned;
- private String title;
- private List events;
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/compilation/CompilationSearchFilter.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/compilation/CompilationSearchFilter.java
deleted file mode 100644
index 68cf761..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/compilation/CompilationSearchFilter.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package ru.practicum.ewm.dto.compilation;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Data
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class CompilationSearchFilter {
-
- Boolean pinned;
-
- @Builder.Default
- Integer from = 0;
-
- @Builder.Default
- Integer size = 10;
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/AdminGetDto.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/event/AdminGetDto.java
deleted file mode 100644
index c165994..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/AdminGetDto.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package ru.practicum.ewm.dto.event;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.Builder;
-import ru.practicum.ewm.model.enums.EventState;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@NotNull
-@Builder
-public record AdminGetDto(
- List users,
- List states,
- List categories,
- LocalDateTime rangeStart,
- LocalDateTime rangeEnd,
- Integer from,
- Integer size
-) {
-}
\ No newline at end of file
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/EventFullDto.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/event/EventFullDto.java
deleted file mode 100644
index 7fc1da1..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/EventFullDto.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package ru.practicum.ewm.dto.event;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Builder;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.dto.user.UserShortDto;
-import ru.practicum.ewm.model.Location;
-import ru.practicum.ewm.model.enums.EventState;
-
-import java.time.LocalDateTime;
-
-@Builder
-public record EventFullDto(
-
- Long id,
-
- @NotBlank
- String annotation,
-
- @NotNull
- CategoryDto category,
-
- Long confirmedRequests,
-
- LocalDateTime createdOn,
-
- String description,
-
- @NotNull
- LocalDateTime eventDate,
-
- @NotNull
- UserShortDto initiator,
-
- @NotNull
- Location location,
-
- boolean paid,
-
- Integer participantLimit,
-
- LocalDateTime publishedOn,
-
- boolean requestModeration,
-
- EventState state,
-
- @NotBlank
- String title,
-
- Long views,
-
- long rate
-) {
-}
\ No newline at end of file
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/EventShortDto.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/event/EventShortDto.java
deleted file mode 100644
index 6f2be95..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/EventShortDto.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package ru.practicum.ewm.dto.event;
-
-import lombok.Builder;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.dto.user.UserShortDto;
-
-import java.time.LocalDateTime;
-
-@Builder
-public record EventShortDto(
- long id,
- String annotation,
- CategoryDto category,
- long confirmedRequests,
- LocalDateTime eventDate,
- UserShortDto initiator,
- boolean paid,
- String title,
- long views,
- long rate
-) {
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/FreeGetDto.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/event/FreeGetDto.java
deleted file mode 100644
index 0343925..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/FreeGetDto.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package ru.practicum.ewm.dto.event;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.Builder;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@NotNull
-@Builder
-public record FreeGetDto(
- String text,
- List categories,
- Boolean paid,
- LocalDateTime rangeStart,
- LocalDateTime rangeEnd,
- Boolean onlyAvailable,
- FreeEventSort sort,
- Integer from,
- Integer size
-) {
-
- public enum FreeEventSort {
- EVENT_DATE, VIEWS
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/UpdateEventUserRequest.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/event/UpdateEventUserRequest.java
deleted file mode 100644
index 45aa833..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/event/UpdateEventUserRequest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package ru.practicum.ewm.dto.event;
-
-import jakarta.validation.constraints.Size;
-import ru.practicum.ewm.model.Location;
-import ru.practicum.ewm.model.enums.UserStateAction;
-
-import java.time.LocalDateTime;
-
-public record UpdateEventUserRequest(
-
- @Size(min = 20, max = 2000)
- String annotation,
-
- Long category,
-
- @Size(min = 20, max = 7000)
- String description,
-
- LocalDateTime eventDate,
-
- Location location,
-
- Boolean paid,
-
- Integer participantLimit,
-
- Boolean requestModeration,
-
- @Size(min = 3, max = 120)
- String title,
-
- UserStateAction stateAction
-) {
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/rating/RatingRequest.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/rating/RatingRequest.java
deleted file mode 100644
index 1a46e1a..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/rating/RatingRequest.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.practicum.ewm.dto.rating;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import ru.practicum.ewm.model.enums.Reaction;
-
-@Data
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class RatingRequest {
-
- @NotNull
- private Reaction reaction;
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/rating/RatingResponse.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/rating/RatingResponse.java
deleted file mode 100644
index 3118cfd..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/rating/RatingResponse.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.practicum.ewm.dto.rating;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import ru.practicum.ewm.model.enums.Reaction;
-
-@Data
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class RatingResponse {
- private Long id;
- private Long userId;
- private Long eventId;
- private Reaction reaction;
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/request/EventRequestStatusUpdateRequest.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/request/EventRequestStatusUpdateRequest.java
deleted file mode 100644
index f2809f8..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/request/EventRequestStatusUpdateRequest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package ru.practicum.ewm.dto.request;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.Builder;
-import ru.practicum.ewm.model.enums.RequestUpdateStatus;
-
-import java.util.List;
-
-@Builder
-public record EventRequestStatusUpdateRequest(
-
- List requestIds,
-
- @NotNull
- RequestUpdateStatus status
-) {
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/request/EventRequestStatusUpdateResult.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/request/EventRequestStatusUpdateResult.java
deleted file mode 100644
index 42af240..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/request/EventRequestStatusUpdateResult.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package ru.practicum.ewm.dto.request;
-
-import lombok.Builder;
-
-import java.util.List;
-
-@Builder
-public record EventRequestStatusUpdateResult(
- List confirmedRequests,
- List rejectedRequests
-) {
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/request/ParticipationRequestDto.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/request/ParticipationRequestDto.java
deleted file mode 100644
index 336e79d..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/request/ParticipationRequestDto.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package ru.practicum.ewm.dto.request;
-
-import lombok.Builder;
-import ru.practicum.ewm.model.enums.ParticipationStatus;
-
-@Builder
-public record ParticipationRequestDto(
- Long id,
- String created,
- Long event,
- Long requester,
- ParticipationStatus status
-) {
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/user/UserDto.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/user/UserDto.java
deleted file mode 100644
index 80725ca..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/user/UserDto.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package ru.practicum.ewm.dto.user;
-
-import lombok.Builder;
-
-@Builder
-public record UserDto(
- Long id,
- String name,
- String email
-) {
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/dto/user/UserShortDto.java b/core/main-service/src/main/java/ru/practicum/ewm/dto/user/UserShortDto.java
deleted file mode 100644
index 7c8dc62..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/dto/user/UserShortDto.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package ru.practicum.ewm.dto.user;
-
-import jakarta.validation.constraints.Email;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Builder;
-
-@NotNull
-@Builder
-public record UserShortDto(
-
- Long id,
-
- @NotBlank
- String name,
-
- @Email
- @Size(min = 6, max = 255)
- @NotBlank
- String email
-) {
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/mapper/RequestMapper.java b/core/main-service/src/main/java/ru/practicum/ewm/mapper/RequestMapper.java
deleted file mode 100644
index dc76c23..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/mapper/RequestMapper.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package ru.practicum.ewm.mapper;
-
-import org.springframework.stereotype.Component;
-import ru.practicum.ewm.dto.request.ParticipationRequestDto;
-import ru.practicum.ewm.model.ParticipationRequest;
-
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-
-
-@Component
-public class RequestMapper {
-
- public static ParticipationRequestDto toParticipationRequestDto(ParticipationRequest participationRequest) {
- if (participationRequest == null) return null;
- return ParticipationRequestDto.builder()
- .event(participationRequest.getEvent().getId())
- .requester(participationRequest.getRequester().getId())
- .status(participationRequest.getStatus())
- .created(formatDateTime(participationRequest.getCreated()))
- .id(participationRequest.getId())
- .build();
- }
-
- private static String formatDateTime(LocalDateTime dateTime) {
- if (dateTime == null) return null;
-
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
- return dateTime.format(formatter);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/AdminStateAction.java b/core/main-service/src/main/java/ru/practicum/ewm/model/enums/AdminStateAction.java
deleted file mode 100644
index 88f2fa6..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/AdminStateAction.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package ru.practicum.ewm.model.enums;
-
-public enum AdminStateAction {
- PUBLISH_EVENT, REJECT_EVENT
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/ParticipationStatus.java b/core/main-service/src/main/java/ru/practicum/ewm/model/enums/ParticipationStatus.java
deleted file mode 100644
index b16afe2..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/ParticipationStatus.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package ru.practicum.ewm.model.enums;
-
-public enum ParticipationStatus {
- PENDING, CONFIRMED, REJECTED, CANCELED
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/Reaction.java b/core/main-service/src/main/java/ru/practicum/ewm/model/enums/Reaction.java
deleted file mode 100644
index d379a2c..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/Reaction.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package ru.practicum.ewm.model.enums;
-
-public enum Reaction {
- LIKE, DISLIKE
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/RequestUpdateStatus.java b/core/main-service/src/main/java/ru/practicum/ewm/model/enums/RequestUpdateStatus.java
deleted file mode 100644
index 37d71e0..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/RequestUpdateStatus.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package ru.practicum.ewm.model.enums;
-
-public enum RequestUpdateStatus {
- CONFIRMED, REJECTED
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/UserStateAction.java b/core/main-service/src/main/java/ru/practicum/ewm/model/enums/UserStateAction.java
deleted file mode 100644
index ce9624b..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/model/enums/UserStateAction.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package ru.practicum.ewm.model.enums;
-
-public enum UserStateAction {
- SEND_TO_REVIEW, CANCEL_REVIEW, PUBLISH_EVENT, REJECT_EVENT
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/compilation/CompilationService.java b/core/main-service/src/main/java/ru/practicum/ewm/service/compilation/CompilationService.java
deleted file mode 100644
index 8af94ca..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/compilation/CompilationService.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package ru.practicum.ewm.service.compilation;
-
-import jakarta.servlet.http.HttpServletRequest;
-import ru.practicum.ewm.dto.compilation.CompilationDto;
-import ru.practicum.ewm.dto.compilation.CompilationSearchFilter;
-import ru.practicum.ewm.dto.compilation.CompilationUpdateDto;
-import ru.practicum.ewm.dto.compilation.NewCompilationDto;
-
-import java.util.List;
-
-public interface CompilationService {
-
- CompilationDto getById(Long compilationId, HttpServletRequest request);
-
- void delById(Long compilationId);
-
- CompilationDto addCompilation(NewCompilationDto compilation);
-
- CompilationDto updateCompilation(Long compilationId, CompilationUpdateDto compilation);
-
- List getByFilter(CompilationSearchFilter filter, HttpServletRequest request);
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/compilation/CompilationServiceImpl.java b/core/main-service/src/main/java/ru/practicum/ewm/service/compilation/CompilationServiceImpl.java
deleted file mode 100644
index 90f4cff..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/compilation/CompilationServiceImpl.java
+++ /dev/null
@@ -1,206 +0,0 @@
-package ru.practicum.ewm.service.compilation;
-
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.AccessLevel;
-import lombok.RequiredArgsConstructor;
-import lombok.experimental.FieldDefaults;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import ru.practicum.ewm.dao.CompilationRepository;
-import ru.practicum.ewm.dao.EventRepository;
-import ru.practicum.ewm.dao.RequestRepository;
-import ru.practicum.ewm.dto.compilation.CompilationDto;
-import ru.practicum.ewm.dto.compilation.CompilationSearchFilter;
-import ru.practicum.ewm.dto.compilation.CompilationUpdateDto;
-import ru.practicum.ewm.dto.compilation.NewCompilationDto;
-import ru.practicum.ewm.mapper.CompilationMapper;
-import ru.practicum.ewm.model.Compilation;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.enums.ParticipationStatus;
-import ru.practicum.ewm.service.request.EventRequestCount;
-import ru.practicum.ewm.util.error.exception.NotFoundException;
-import ru.practicum.ewm.util.statistic.StatRepository;
-import ru.practicum.stat.dto.ViewStatsDto;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-@Service
-@RequiredArgsConstructor
-@Transactional(readOnly = true)
-@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
-public class CompilationServiceImpl implements CompilationService {
-
- CompilationRepository compilationRepository;
- EventRepository eventRepository;
- StatRepository statRepository;
- RequestRepository requestRepository;
-
- @Override
- public CompilationDto getById(Long compilationId, HttpServletRequest request) {
- statRepository.sendHitRequest(request);
-
- Compilation compilation = getCompilationById(compilationId);
-
- return CompilationMapper.toCompilationDto(
- compilation,
- getConfirmedRequests(List.of(compilation)),
- getViews(List.of(compilation))
- );
- }
-
- @Override
- @Transactional
- public void delById(Long compilationId) {
- getCompilationById(compilationId);
- compilationRepository.deleteById(compilationId);
- }
-
- @Override
- @Transactional
- public CompilationDto addCompilation(@NonNull NewCompilationDto compilationDto) {
- Set events = new HashSet<>();
-
- if (compilationDto.getEvents() != null && !compilationDto.getEvents().isEmpty()) {
- events = new HashSet<>(eventRepository.findAllById(compilationDto.getEvents()));
-
- if (events.size() < compilationDto.getEvents().size()) {
- throw new NotFoundException("Одно или несколько событий не найдены");
- }
- }
-
- Compilation compilation = CompilationMapper.toEntity(compilationDto, events);
- Compilation savedCompilation = compilationRepository.save(compilation);
-
- Map confirmedRequests = new HashMap<>();
- savedCompilation.getEvents().forEach(event -> confirmedRequests.put(event.getId(), 0L));
-
- Map views = new HashMap<>();
- savedCompilation.getEvents().forEach(event -> views.put(event.getId(), 0L));
-
- return CompilationMapper.toCompilationDto(
- savedCompilation,
- confirmedRequests,
- views
- );
- }
-
- @Override
- @Transactional
- public CompilationDto updateCompilation(Long compilationId, @NonNull CompilationUpdateDto compilationUpdateDto) {
- Compilation compilationInDb = getCompilationById(compilationId);
-
- if (compilationUpdateDto.getEvents() != null) {
- List eventsUpdate = new ArrayList<>();
-
- if (!compilationUpdateDto.getEvents().isEmpty()) {
- eventsUpdate = eventRepository.findAllById(compilationUpdateDto.getEvents());
- if (eventsUpdate.size() < compilationUpdateDto.getEvents().size()) {
- throw new NotFoundException("Одно или несколько событий не найдены");
- }
- }
- compilationInDb.setEvents(new HashSet<>(eventsUpdate));
-
- }
-
- if (compilationUpdateDto.getTitle() != null && !compilationUpdateDto.getTitle().isBlank()) {
- compilationInDb.setTitle(compilationUpdateDto.getTitle());
- }
-
- if (compilationUpdateDto.getPinned() != null) {
- compilationInDb.setPinned(compilationUpdateDto.getPinned());
- }
-
- return CompilationMapper.toCompilationDto(
- compilationInDb, getConfirmedRequests(List.of(compilationInDb)), getViews(List.of(compilationInDb)));
- }
-
- @Override
- public List getByFilter(@NonNull CompilationSearchFilter filter, HttpServletRequest request) {
- Pageable pageable = PageRequest.of(filter.getFrom() / filter.getSize(), filter.getSize());
- Page compilationsPage;
-
- if (filter.getPinned() != null) {
- compilationsPage = compilationRepository.findAllByPinned(filter.getPinned(), pageable);
- } else {
- compilationsPage = compilationRepository.findAll(pageable);
- }
-
- List compilations = compilationsPage.getContent();
-
- if (compilations.isEmpty()) {
- return Collections.emptyList();
- }
-
- Map allConfirmedRequests = getConfirmedRequests(compilations);
- Map allViews = getViews(compilations);
-
- // Теперь маппим, просто подставляя готовые Map
- return compilations.stream()
- .map(compilation -> CompilationMapper.toCompilationDto(
- compilation,
- allConfirmedRequests,
- allViews
- ))
- .toList();
- }
-
- @NonNull
- private Compilation getCompilationById(long compilationId) {
- return compilationRepository.findById(compilationId).orElseThrow(
- () -> new NotFoundException("Подборка с id=" + compilationId + " не найдена")
- );
- }
-
- /// Map
- @NonNull
- private Map getConfirmedRequests(Collection compilations) {
- List events = compilations.stream()
- .flatMap(c -> c.getEvents().stream())
- .toList();
-
- if (events.isEmpty()) return Collections.emptyMap();
-
- List eventRequestCountList = requestRepository.countConfirmedRequestsByEventIds(
- events.stream().map(Event::getId).toList(),
- ParticipationStatus.CONFIRMED);
-
- return eventRequestCountList.stream()
- .collect(Collectors.toMap(
- EventRequestCount::getEventId,
- EventRequestCount::getCount,
- (existing, replacement) -> existing
- ));
- }
-
- /// Map
- @NonNull
- private Map getViews(Collection compilations) {
- // Все уникальные события
- List allEvents = compilations.stream()
- .flatMap(c -> c.getEvents().stream())
- .distinct()
- .toList();
-
- if (allEvents.isEmpty()) return Collections.emptyMap();
-
- // Все URIs
- List uris = allEvents.stream()
- .map(e -> "/events/" + e.getId())
- .toList();
-
- List stats = statRepository.getStat(uris, false);
-
- // Map
- return stats.stream()
- .collect(Collectors.toMap(
- s -> Long.parseLong(s.getUri().replace("/events/", "")),
- ViewStatsDto::getHits,
- (a, b) -> a
- ));
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/event/EventServiceImpl.java b/core/main-service/src/main/java/ru/practicum/ewm/service/event/EventServiceImpl.java
deleted file mode 100644
index 038df7a..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/event/EventServiceImpl.java
+++ /dev/null
@@ -1,465 +0,0 @@
-package ru.practicum.ewm.service.event;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.validation.ValidationException;
-import lombok.AccessLevel;
-import lombok.RequiredArgsConstructor;
-import lombok.experimental.FieldDefaults;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.dao.DataIntegrityViolationException;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Service;
-import ru.practicum.ewm.dao.CategoryRepository;
-import ru.practicum.ewm.dao.EventRepository;
-import ru.practicum.ewm.dao.RequestRepository;
-import ru.practicum.ewm.dao.UserRepository;
-import ru.practicum.ewm.dto.event.*;
-import ru.practicum.ewm.mapper.EventMapper;
-import ru.practicum.ewm.mapper.StateMapper;
-import ru.practicum.ewm.model.Category;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.model.enums.AdminStateAction;
-import ru.practicum.ewm.model.enums.EventState;
-import ru.practicum.ewm.model.enums.ParticipationStatus;
-import ru.practicum.ewm.model.enums.UserStateAction;
-import ru.practicum.ewm.service.request.EventRequestCount;
-import ru.practicum.ewm.util.error.exception.ConflictException;
-import ru.practicum.ewm.util.error.exception.NotFoundException;
-import ru.practicum.ewm.util.specification.EventSpecifications;
-import ru.practicum.ewm.util.specification.SpecBuilder;
-import ru.practicum.ewm.util.statistic.StatRepository;
-import ru.practicum.stat.dto.ViewStatsDto;
-
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.util.*;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
-public class EventServiceImpl implements EventService {
-
- StatRepository statRepository;
- EventRepository eventRepository;
- UserRepository userRepository;
- CategoryRepository categoryRepository;
- RequestRepository requestRepository;
-
- @Override
- public List getFreeEvents(@NonNull FreeGetDto dto, HttpServletRequest request) {
-
- if (dto.rangeStart() != null && dto.rangeEnd() != null) {
- if (dto.rangeEnd().isBefore(dto.rangeStart())) {
- throw new ValidationException("Окончание события не может быть раньше начала");
- }
- }
-
- statRepository.sendHitRequest(request);
-
- SpecBuilder builder = SpecBuilder.builder()
- .and(EventSpecifications.isPublished())
- .andIf(dto.text() != null && !dto.text().isBlank(),
- () -> EventSpecifications.textContains(dto.text()))
- .andIf(dto.categories() != null && !dto.categories().isEmpty(),
- () -> EventSpecifications.hasCategories(dto.categories()))
- .andIf(dto.paid() != null,
- () -> EventSpecifications.isPaid(dto.paid()))
- .andIf(Boolean.TRUE.equals(dto.onlyAvailable()),
- () -> EventSpecifications.onlyAvailable(true));
-
- boolean hasStart = dto.rangeStart() != null;
- boolean hasEnd = dto.rangeEnd() != null;
-
- if (!hasStart && !hasEnd) {
- builder.and(EventSpecifications.eventDateAfterNow(LocalDateTime.now()));
- } else {
- builder
- .andIf(hasStart,
- () -> EventSpecifications.dateAfter(dto.rangeStart()))
- .andIf(hasEnd,
- () -> EventSpecifications.dateBefore(dto.rangeEnd()));
- }
-
- Specification spec = builder.build();
-
- Sort sort = Sort.unsorted();
-
- if (dto.sort() != null) {
- switch (dto.sort()) {
- case EVENT_DATE -> sort = Sort.by("eventDate").ascending();
- case VIEWS -> sort = Sort.by("views").descending();
- }
- }
-
- Pageable pageable = PageRequest.of(
- dto.from() / dto.size(),
- dto.size(),
- sort
- );
-
- List events = eventRepository.findAll(spec, pageable).getContent();
- if (events.isEmpty()) {
- return Collections.emptyList();
- }
-
- List eventRequestCountList = requestRepository.countConfirmedRequestsByEventIds(
- events.stream().map(Event::getId).toList(), ParticipationStatus.CONFIRMED);
-
- Map requestCountMap = new HashMap<>();
- if (!eventRequestCountList.isEmpty()) {
- eventRequestCountList.forEach(eventRequestCount -> {
- requestCountMap.put(eventRequestCount.getEventId(), eventRequestCount.getCount());
- });
- }
-
- List uris = events.stream().map(event -> "/events/" + event.getId()).toList();
- List stats = statRepository.getStat(
- uris,
- dto.rangeStart(),
- dto.rangeEnd(),
- false);
-
- return events.stream()
- .map(event -> EventMapper.toEventShortDto(
- event,
- requestCountMap.get(event.getId()) == null ? 0L : requestCountMap.get(event.getId()),
- stats.size()
- )
- ).toList();
- }
-
- @Override
- public EventFullDto getFreeEventById(Long eventId, HttpServletRequest request) {
- if (!eventRepository.existsByIdAndState(eventId, EventState.PUBLISHED)) {
- throw new NotFoundException("Событие с id=" + eventId + " не существует или не опубликовано.");
- }
- statRepository.sendHitRequest(request);
- Event event = getEventById(eventId);
-
- long views = statRepository.getStat(List.of(request.getRequestURI()), true).getFirst().getHits();
-
- long confirmedRequests = getConfirmedRequests(eventId);
-
- return EventMapper.toEventFullDto(event, confirmedRequests, views);
- }
-
- @Override
- public EventFullDto userAddNewEvent(Long userId, @NonNull NewEventDto newEventDto) {
- if (newEventDto.participantLimit() != null && newEventDto.participantLimit() < 0) {
- throw new ValidationException("Ограничение на количество участников должно быть положительным числом");
- }
-
- if (newEventDto.eventDate() != null && newEventDto.eventDate().isBefore(LocalDateTime.now().plusHours(2))) {
- throw new ValidationException("Начало события не может быть раньше, " +
- "чем через два часа от текущего момента");
- }
-
- User initiator = getUserById(userId);
- Category category = getCategoryById(newEventDto.category());
-
- Event event = EventMapper.toEntity(
- newEventDto,
- category,
- LocalDateTime.now(),
- initiator,
- null,
- EventState.PENDING
- );
-
- return EventMapper.toEventFullDto(eventRepository.save(event), 0L, 0L);
- }
-
- @Override
- public List adminGetEvents(@NonNull AdminGetDto dto) {
- Specification spec = SpecBuilder.builder()
- .andIf(dto.users() != null && !dto.users().isEmpty(),
- () -> EventSpecifications.hasUsers(dto.users()))
- .andIf(dto.states() != null && !dto.states().isEmpty(),
- () -> EventSpecifications.hasStates(dto.states()))
- .andIf(dto.categories() != null && !dto.categories().isEmpty(),
- () -> EventSpecifications.hasCategories(dto.categories()))
- .andIf(dto.rangeStart() != null,
- () -> EventSpecifications.dateAfter(dto.rangeStart()))
- .andIf(dto.rangeEnd() != null,
- () -> EventSpecifications.dateBefore(dto.rangeEnd()))
- .build();
-
- Pageable pageable = PageRequest.of(
- dto.from() / dto.size(),
- dto.size()
- );
-
- List events = eventRepository.findAll(spec, pageable).getContent();
- if (events.isEmpty()) {
- return Collections.emptyList();
- }
-
- List eventRequestCountList = requestRepository.countConfirmedRequestsByEventIds(
- events.stream().map(Event::getId).toList(), ParticipationStatus.CONFIRMED);
-
- Map requestCountMap = new HashMap<>();
- if (!eventRequestCountList.isEmpty()) {
- eventRequestCountList.forEach(eventRequestCount ->
- requestCountMap.put(eventRequestCount.getEventId(), eventRequestCount.getCount())
- );
- }
-
- List uris = events.stream().map(event -> "/events/" + event.getId()).toList();
- List stats = statRepository.getStat(
- uris,
- dto.rangeStart(),
- dto.rangeEnd(),
- false);
-
- return events.stream()
- .map(event -> EventMapper.toEventFullDto(
- event,
- getConfirmedRequests(requestCountMap, event.getId()),
- getHits(stats, event.getId())
- )
- ).toList();
- }
-
- @Override
- public EventFullDto adminUpdateEvent(Long eventId, @NonNull UpdateEventAdminRequest request) {
- Event oldEvent = getEventById(eventId);
- Event newEvent;
-
- if (request.eventDate() != null && request.eventDate().isBefore(LocalDateTime.now().plusHours(2))) {
- throw new ValidationException("Дата события должна быть не может быть раньше, " +
- "чем через два часа от текущего момента");
- }
-
- if (request.stateAction() == null) {
- newEvent = EventMapper.update(
- oldEvent,
- request,
- oldEvent.getState(),
- oldEvent.getPublishedOn(),
- request.category() == null ?
- Optional.empty() :
- Optional.of(getCategoryById(request.category()))
- );
- } else {
-
- if (request.stateAction().equals(AdminStateAction.PUBLISH_EVENT) &&
- oldEvent.getState().equals(EventState.PUBLISHED)) {
- throw new ConflictException("Событие с id=" + oldEvent.getId() + " уже опубликовано");
- }
-
- if (request.stateAction().equals(AdminStateAction.PUBLISH_EVENT) &&
- oldEvent.getState().equals(EventState.CANCELED)) {
- throw new ConflictException("Публикация события с id=" + oldEvent.getId() +
- " уже отменена пользователем");
- }
-
- if (request.stateAction().equals(AdminStateAction.REJECT_EVENT) &&
- oldEvent.getState().equals(EventState.PUBLISHED)) {
- throw new ConflictException("Событие с id=" + oldEvent.getId() +
- " уже опубликовано, отмена не возможна");
- }
-
- newEvent = EventMapper.update(
- oldEvent,
- request,
- request.stateAction().equals(AdminStateAction.REJECT_EVENT) ?
- EventState.CANCELED : EventState.PUBLISHED,
- request.stateAction().equals(AdminStateAction.REJECT_EVENT) ?
- null : LocalDateTime.now(),
- request.category() == null ?
- Optional.empty() :
- Optional.of(getCategoryById(request.category()))
- );
- }
-
- return EventMapper.toEventFullDto(
- eventRepository.save(newEvent),
- getConfirmedRequests(oldEvent.getId()),
- getHits(oldEvent.getId())
- );
- }
-
- @Override
- public List findByUserId(Long userId, Integer from, Integer size) {
- checkUser(userId);
-
- PageRequest pageRequest = PageRequest.of(from / size, size);
- Collection events = eventRepository.findByInitiatorId(userId, pageRequest);
- if (events.isEmpty()) {
- return Collections.emptyList();
- }
-
- List eventRequestCountList = requestRepository.countConfirmedRequestsByEventIds(
- events.stream().map(Event::getId).toList(), ParticipationStatus.CONFIRMED);
-
- Map requestCountMap = new HashMap<>();
- if (!eventRequestCountList.isEmpty()) {
- eventRequestCountList.forEach(eventRequestCount ->
- requestCountMap.put(eventRequestCount.getEventId(), eventRequestCount.getCount())
- );
- }
-
- List uris = events.stream().map(event -> "/events/" + event.getId()).toList();
- List stats = statRepository.getStat(uris, true);
-
- return events.stream()
- .map(event -> EventMapper.toEventShortDto(
- event,
- getConfirmedRequests(requestCountMap, event.getId()),
- getHits(stats, event.getId())
- )
- ).toList();
- }
-
- @Override
- public EventFullDto findEventById(Long userId, Long eventId) {
- checkUser(userId);
-
- Event event = getEventById(eventId);
-
- if (!event.getInitiator().getId().equals(userId)) {
- throw new ConflictException("Пользователь должен быть инициатором");
- }
-
- return EventMapper.toEventFullDto(
- event,
- getConfirmedRequests(event.getId()),
- getHits(event.getId())
- );
- }
-
- @Override
- public EventFullDto patchEvent(Long userId, Long eventId, @NonNull UpdateEventUserRequest request) {
- if (request.participantLimit() != null && request.participantLimit() < 0) {
- throw new ValidationException("Ограничение на количество участников должно быть положительным числом");
- }
-
- checkUser(userId);
- return patchEvent(eventId, request, 2, false);
- }
-
- private EventFullDto patchEvent(Long eventId, @NonNull UpdateEventUserRequest request, long hoursBeforeStart,
- boolean isAdmin) {
- try {
- Event event = getEventById(eventId);
-
- if (!isAdmin && event.getState() == EventState.PUBLISHED) {
- throw new ConflictException("Нельзя редактировать опубликованное событие");
- }
-
- if (request.eventDate() != null) {
- LocalDateTime eventDateTime = request.eventDate();
- LocalDateTime minDateTime = LocalDateTime.now().plusHours(hoursBeforeStart);
-
- if (!isAdmin && eventDateTime.isBefore(minDateTime)) {
- throw new ValidationException(
- String.format("Дата события должна быть не ранее чем за %d часа(ов) до начала",
- hoursBeforeStart)
- );
- }
- }
-
- UserStateAction action = request.stateAction();
-
- if (action != null) {
- EventState newState = isAdmin
- ? StateMapper.mapAdminEventAction(action)
- : StateMapper.mapUserEventAction(action);
-
- if (EventState.PUBLISHED.equals(newState)) {
- event.setPublishedOn(LocalDateTime.from(Instant.now()));
- }
- if (newState != null) {
- event.setState(newState);
- }
- }
-
- if (request.category() != null) {
- Category category = getCategoryById(request.category());
- event.setCategory(category);
- }
-
- EventMapper.merge(event, request);
-
- Event patched = eventRepository.save(event);
-
- log.info("Ивент обновлен: {}", patched.getId());
-
- return EventMapper.toEventFullDto(
- event,
- getConfirmedRequests(event.getId()),
- getHits(event.getId())
- );
-
- } catch (DataIntegrityViolationException e) {
- log.debug("Конфликт вовремя обновления ивента {}", request, e);
- throw new ConflictException("Конфликт с другим ивентом");
- }
- }
-
- private void checkUser(Long userId) {
- if (!userRepository.existsById(userId)) {
- throw new NotFoundException("Пользователь с id=" + userId + " не найден");
- }
- }
-
- @NonNull
- private User getUserById(long userId) {
- return userRepository.findById(userId)
- .orElseThrow(() -> new NotFoundException("Пользователь с id=" + userId + " не найден"));
- }
-
- @NonNull
- private Event getEventById(long eventId) {
- return eventRepository.findById(eventId).orElseThrow(
- () -> new NotFoundException("Событие с id=" + eventId + " не найдено")
- );
- }
-
- @NonNull
- private Category getCategoryById(long categoryId) {
- return categoryRepository.findById(categoryId).orElseThrow(
- () -> new NotFoundException("Категория с id=" + categoryId + " не найдена")
- );
- }
-
- private long getConfirmedRequests(Long eventId) {
- return requestRepository.countByEventIdAndStatus(eventId, ParticipationStatus.CONFIRMED);
- }
-
- private long getHits(long eventId) {
- List stats = statRepository.getStat(List.of("/events/" + eventId), true);
- if (stats.isEmpty()) {
- return 0;
- }
- return stats.getFirst().getHits();
- }
-
- private long getHits(@NonNull List stats, long eventId) {
- if (stats.isEmpty()) {
- return 0;
- }
- for (ViewStatsDto stat : stats) {
- if (stat.getUri().equals("/events/" + eventId)) {
- return stat.getHits();
- }
- }
- return 0;
- }
-
- private long getConfirmedRequests(@NonNull Map requestCountMap, long eventId) {
- if (requestCountMap.isEmpty()) {
- return 0;
- }
- if (requestCountMap.containsKey(eventId)) {
- return requestCountMap.get(eventId);
- }
- return 0;
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/rating/RatingService.java b/core/main-service/src/main/java/ru/practicum/ewm/service/rating/RatingService.java
deleted file mode 100644
index 27f61d9..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/rating/RatingService.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package ru.practicum.ewm.service.rating;
-
-import ru.practicum.ewm.dto.rating.RatingRequest;
-import ru.practicum.ewm.dto.rating.RatingResponse;
-
-public interface RatingService {
-
- RatingResponse addOrUpdateReaction(Long userId, Long eventId, RatingRequest request);
-
- void removeReaction(Long userId, Long eventId);
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/rating/RatingServiceImpl.java b/core/main-service/src/main/java/ru/practicum/ewm/service/rating/RatingServiceImpl.java
deleted file mode 100644
index df506dc..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/rating/RatingServiceImpl.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package ru.practicum.ewm.service.rating;
-
-import jakarta.validation.ValidationException;
-import lombok.RequiredArgsConstructor;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import ru.practicum.ewm.dao.EventRepository;
-import ru.practicum.ewm.dao.RatingRepository;
-import ru.practicum.ewm.dao.UserRepository;
-import ru.practicum.ewm.dto.rating.RatingRequest;
-import ru.practicum.ewm.dto.rating.RatingResponse;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.Rating;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.model.enums.EventState;
-import ru.practicum.ewm.model.enums.Reaction;
-import ru.practicum.ewm.util.error.exception.ConflictException;
-import ru.practicum.ewm.util.error.exception.NotFoundException;
-
-import java.util.Objects;
-
-@Service
-@RequiredArgsConstructor
-@Transactional
-public class RatingServiceImpl implements RatingService {
-
- private final RatingRepository ratingRepository;
- private final UserRepository userRepository;
- private final EventRepository eventRepository;
-
- @Override
- public RatingResponse addOrUpdateReaction(Long userId, Long eventId, RatingRequest request) {
- User user = userRepository.findById(userId)
- .orElseThrow(() -> new NotFoundException("Пользователь с id=" + userId + " не найден"));
- Event event = eventRepository.findByIdAndState(eventId, EventState.PUBLISHED)
- .orElseThrow(() ->
- new NotFoundException("Событие с id=" + eventId + " не существует или не опубликовано.")
- );
- User initiator = event.getInitiator();
- if (Objects.equals(user.getId(), initiator.getId())) {
- throw new ValidationException("Нельзя ставить реакции своим событиям");
- }
-
- Rating rating = ratingRepository.findByUserIdAndEventId(userId, eventId).orElse(null);
-
- if (rating != null) {
- if (rating.getReaction() == request.getReaction()) {
- ratingRepository.delete(rating);
- updateEventRate(event);
- throw new ConflictException("Reaction removed");
- } else {
- rating.setReaction(request.getReaction());
- ratingRepository.save(rating);
- updateEventRate(event);
- return mapToResponse(rating);
- }
- } else {
- rating = Rating.builder()
- .user(user)
- .event(event)
- .reaction(request.getReaction())
- .build();
- ratingRepository.save(rating);
- updateEventRate(event);
- return mapToResponse(rating);
- }
- }
-
- @Override
- public void removeReaction(Long userId, Long eventId) {
- Rating rating = ratingRepository.findByUserIdAndEventId(userId, eventId)
- .orElseThrow(() -> new NotFoundException("Реакция не найдена"));
- ratingRepository.delete(rating);
- Event event = rating.getEvent();
- updateEventRate(event);
- }
-
- private void updateEventRate(@NonNull Event event) {
- long likes = ratingRepository.countByEventIdAndReaction(event.getId(), Reaction.LIKE);
- long dislikes = ratingRepository.countByEventIdAndReaction(event.getId(), Reaction.DISLIKE);
- event.setRate(likes - dislikes);
- eventRepository.save(event);
- }
-
- private RatingResponse mapToResponse(@NonNull Rating rating) {
- return RatingResponse.builder()
- .id(rating.getId())
- .userId(rating.getUser().getId())
- .eventId(rating.getEvent().getId())
- .reaction(rating.getReaction())
- .build();
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/request/EventRequestCount.java b/core/main-service/src/main/java/ru/practicum/ewm/service/request/EventRequestCount.java
deleted file mode 100644
index a7d0684..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/request/EventRequestCount.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package ru.practicum.ewm.service.request;
-
-
-public interface EventRequestCount {
-
- Long getEventId();
-
- Long getCount();
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/request/RequestService.java b/core/main-service/src/main/java/ru/practicum/ewm/service/request/RequestService.java
deleted file mode 100644
index 50cff58..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/request/RequestService.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package ru.practicum.ewm.service.request;
-
-import org.springframework.transaction.annotation.Transactional;
-import ru.practicum.ewm.dto.request.EventRequestStatusUpdateRequest;
-import ru.practicum.ewm.dto.request.EventRequestStatusUpdateResult;
-import ru.practicum.ewm.dto.request.ParticipationRequestDto;
-
-import java.util.List;
-
-@Transactional
-public interface RequestService {
-
- List findByEventId(Long userId, Long eventId);
-
- EventRequestStatusUpdateResult updateStatusRequest(Long userId, Long eventId,
- EventRequestStatusUpdateRequest request);
-
- List findByRequesterId(Long userId);
-
- ParticipationRequestDto addParticipationRequest(Long userId, Long eventId);
-
- ParticipationRequestDto cancelParticipationRequest(Long userId, Long requestId);
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/request/RequestServiceImpl.java b/core/main-service/src/main/java/ru/practicum/ewm/service/request/RequestServiceImpl.java
deleted file mode 100644
index bed101c..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/request/RequestServiceImpl.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package ru.practicum.ewm.service.request;
-
-import lombok.AccessLevel;
-import lombok.RequiredArgsConstructor;
-import lombok.experimental.FieldDefaults;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import ru.practicum.ewm.dao.EventRepository;
-import ru.practicum.ewm.dao.RequestRepository;
-import ru.practicum.ewm.dao.UserRepository;
-import ru.practicum.ewm.dto.request.EventRequestStatusUpdateRequest;
-import ru.practicum.ewm.dto.request.EventRequestStatusUpdateResult;
-import ru.practicum.ewm.dto.request.ParticipationRequestDto;
-import ru.practicum.ewm.mapper.RequestMapper;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.ParticipationRequest;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.model.enums.EventState;
-import ru.practicum.ewm.model.enums.ParticipationStatus;
-import ru.practicum.ewm.util.error.exception.ConflictException;
-import ru.practicum.ewm.util.error.exception.NotFoundException;
-
-import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
-public class RequestServiceImpl implements RequestService {
-
- RequestRepository requestRepository;
- UserRepository userRepository;
- EventRepository eventRepository;
-
- public List findByEventId(Long userId, Long eventId) {
- Event event = getEventById(eventId);
- if (!event.getInitiator().getId().equals(userId)) {
- throw new NotFoundException("Событие не найдено");
- }
-
- return requestRepository.findByEventId(eventId)
- .stream()
- .map(RequestMapper::toParticipationRequestDto)
- .toList();
- }
-
- public EventRequestStatusUpdateResult updateStatusRequest(Long userId, Long eventId,
- EventRequestStatusUpdateRequest request) {
- Event event = getEventById(eventId);
- if (!event.getInitiator().getId().equals(userId)) {
- throw new NotFoundException("Событие не найдено");
- }
-
- int limit = event.getParticipantLimit();
- List confirmedRequests = new ArrayList<>();
- List rejectedRequests = new ArrayList<>();
-
- boolean isModerationOff = !event.isRequestModeration() || limit == 0;
- boolean idsEmpty = request.requestIds() == null || request.requestIds().isEmpty();
-
- if (isModerationOff || idsEmpty) {
- return EventRequestStatusUpdateResult.builder()
- .confirmedRequests(Collections.emptyList())
- .rejectedRequests(Collections.emptyList())
- .build();
- }
-
- int countConfirmed = requestRepository.countByEventIdAndStatus(eventId, ParticipationStatus.CONFIRMED);
- List requests = requestRepository.findAllByIdIn(request.requestIds());
-
- if (request.status().name().equals(ParticipationStatus.CONFIRMED.name()) && countConfirmed >= limit) {
- throw new ConflictException("Достигнут лимит подтвержденных заявок");
- }
-
- for (ParticipationRequest pr : requests) {
- if (!pr.getStatus().equals(ParticipationStatus.PENDING)) {
- throw new ConflictException("Статус можно изменить только у заявок в состоянии рассмотрения");
- }
-
- if (request.status().name().equals(ParticipationStatus.CONFIRMED.name()) && countConfirmed < limit) {
- pr.setStatus(ParticipationStatus.CONFIRMED);
- countConfirmed++;
- confirmedRequests.add(RequestMapper.toParticipationRequestDto(pr));
- } else {
- pr.setStatus(ParticipationStatus.REJECTED);
- rejectedRequests.add(RequestMapper.toParticipationRequestDto(pr));
- }
- }
-
- requestRepository.saveAll(requests);
-
- // если в процессе лимит превышен - отклоняем все оставшиеся заявки
- if (request.status().name().equals(ParticipationStatus.CONFIRMED.name()) && countConfirmed >= limit) {
- if (requestRepository.rejectPendingRequests(eventId, ParticipationStatus.PENDING) < 0) {
- throw new RuntimeException("Не удалось отклонить заявку");
- }
- }
-
- return EventRequestStatusUpdateResult.builder()
- .confirmedRequests(confirmedRequests)
- .rejectedRequests(rejectedRequests)
- .build();
- }
-
- public List findByRequesterId(Long userId) {
- return requestRepository.findByRequesterId(userId)
- .stream()
- .map(RequestMapper::toParticipationRequestDto)
- .toList();
- }
-
- @Transactional
- public ParticipationRequestDto addParticipationRequest(Long userId, Long eventId) {
- User requester = getUserById(userId);
- Event event = getEventById(eventId);
-
- if (!EventState.PUBLISHED.equals(event.getState())) {
- throw new ConflictException("Нельзя участвовать в неопубликованном событии");
- }
-
- if (requestRepository.existsByRequesterIdAndEventId(userId, eventId)) {
- throw new ConflictException("Запрос уже существует");
- }
-
- if (event.getInitiator().getId().equals(userId)) {
- throw new ConflictException("Инициатор события не может добавить запрос на участие в своём событии");
- }
-
- int limit = event.getParticipantLimit();
- if (limit != 0) {
- long confirmedCount = requestRepository.countByEventIdAndStatus(eventId, ParticipationStatus.CONFIRMED);
-
- if (event.isRequestModeration()) {
- long pendingCount = requestRepository.countByEventIdAndStatus(eventId, ParticipationStatus.PENDING);
- if (confirmedCount + pendingCount >= limit) {
- throw new ConflictException("Достигнут лимит запросов на участие");
- }
- } else {
- if (confirmedCount >= limit) {
- throw new ConflictException("Достигнут лимит запросов на участие");
- }
- }
- }
-
- ParticipationStatus status;
-
- if (!event.isRequestModeration() || limit == 0) {
- status = ParticipationStatus.CONFIRMED;
- } else {
- status = ParticipationStatus.PENDING;
- }
-
- ParticipationRequest request = ParticipationRequest.builder()
- .requester(requester)
- .event(event)
- .status(status)
- .created(LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS))
- .build();
-
- return RequestMapper.toParticipationRequestDto(requestRepository.save(request));
- }
-
- public ParticipationRequestDto cancelParticipationRequest(Long userId, Long requestId) {
- ParticipationRequest request = getRequestById(requestId);
-
- if (!request.getRequester().getId().equals(userId)) {
- throw new ConflictException("Нельзя отменить чужую заявку");
- }
- request.setStatus(ParticipationStatus.CANCELED);
- return RequestMapper.toParticipationRequestDto(requestRepository.save(request));
- }
-
- @NonNull
- private User getUserById(long userId) {
- return userRepository.findById(userId)
- .orElseThrow(() -> new NotFoundException("Пользователь с id=" + userId + " не найден"));
- }
-
- @NonNull
- private Event getEventById(long eventId) {
- return eventRepository.findById(eventId).orElseThrow(
- () -> new NotFoundException("Событие с id=" + eventId + " не найдено")
- );
- }
-
- @NonNull
- private ParticipationRequest getRequestById(Long requestId) {
- return requestRepository.findById(requestId).orElseThrow(
- () -> new NotFoundException("Заявка с id=" + requestId + " не найдена")
- );
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/user/UserService.java b/core/main-service/src/main/java/ru/practicum/ewm/service/user/UserService.java
deleted file mode 100644
index d10ee41..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/user/UserService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ru.practicum.ewm.service.user;
-
-import jakarta.transaction.Transactional;
-import ru.practicum.ewm.dto.user.NewUserRequest;
-import ru.practicum.ewm.dto.user.UserDto;
-
-import java.util.List;
-
-public interface UserService {
-
- @Transactional
- UserDto adminAddNewUser(NewUserRequest newUserRequest);
-
- List getUsers(List ids, int from, int size);
-
- @Transactional
- void deleteUser(Long userId);
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/service/user/UserServiceImpl.java b/core/main-service/src/main/java/ru/practicum/ewm/service/user/UserServiceImpl.java
deleted file mode 100644
index 31cd7cd..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/service/user/UserServiceImpl.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package ru.practicum.ewm.service.user;
-
-import lombok.RequiredArgsConstructor;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import ru.practicum.ewm.dao.UserRepository;
-import ru.practicum.ewm.dto.user.NewUserRequest;
-import ru.practicum.ewm.dto.user.UserDto;
-import ru.practicum.ewm.mapper.UserMapper;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.util.error.exception.ConflictException;
-import ru.practicum.ewm.util.error.exception.NotFoundException;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Service
-@RequiredArgsConstructor
-public class UserServiceImpl implements UserService {
-
- private final UserRepository userRepository;
-
- @Override
- public UserDto adminAddNewUser(@NonNull NewUserRequest newUserRequest) {
- if (userRepository.existsByEmail(newUserRequest.email())) {
- throw new ConflictException("Пользователь с такой почтой " + newUserRequest.email() + " уже существует");
- }
- User user = UserMapper.toEntity(newUserRequest);
- return UserMapper.toUserDto(userRepository.save(user));
- }
-
- @Override
- public List getUsers(List ids, int from, int size) {
- PageRequest page = PageRequest.of(from / size, size);
- List users;
- if (ids == null || ids.isEmpty()) {
- users = userRepository.findAll(page).getContent();
- } else {
- users = userRepository.findAllByIdIn(ids, page);
- }
- return users.stream()
- .map(UserMapper::toUserDto)
- .collect(Collectors.toList());
- }
-
- @Override
- @Transactional
- public void deleteUser(Long userId) {
- checkUser(userId);
- userRepository.deleteById(userId);
- }
-
- private void checkUser(Long userId) {
- if (!userRepository.existsById(userId)) {
- throw new NotFoundException("Пользователь с id=" + userId + " не найден");
- }
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/ConflictException.java b/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/ConflictException.java
deleted file mode 100644
index 8848991..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/ConflictException.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package ru.practicum.ewm.util.error.exception;
-
-public class ConflictException extends RuntimeException {
-
- public ConflictException(String message) {
- super(message);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/NotFoundException.java b/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/NotFoundException.java
deleted file mode 100644
index a9d3922..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/NotFoundException.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package ru.practicum.ewm.util.error.exception;
-
-public class NotFoundException extends RuntimeException {
-
- public NotFoundException(String message) {
- super(message);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/StatResponseException.java b/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/StatResponseException.java
deleted file mode 100644
index f2b13cb..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/util/error/exception/StatResponseException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package ru.practicum.ewm.util.error.exception;
-
-public class StatResponseException extends RuntimeException {
-
- private static final String MESSAGE = "Не удалось получить статистику";
-
- public StatResponseException(Exception ex) {
- super(MESSAGE, ex);
- }
-
- public StatResponseException() {
- super(MESSAGE);
- }
-}
diff --git a/core/main-service/src/main/java/ru/practicum/ewm/util/statistic/StatRepository.java b/core/main-service/src/main/java/ru/practicum/ewm/util/statistic/StatRepository.java
deleted file mode 100644
index 0f9d137..0000000
--- a/core/main-service/src/main/java/ru/practicum/ewm/util/statistic/StatRepository.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package ru.practicum.ewm.util.statistic;
-
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import ru.practicum.ewm.util.error.exception.HitRequestException;
-import ru.practicum.ewm.util.error.exception.StatResponseException;
-import ru.practicum.stat.client.StatClient;
-import ru.practicum.stat.dto.EndpointHitDto;
-import ru.practicum.stat.dto.StatsRequest;
-import ru.practicum.stat.dto.ViewStatsDto;
-
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.temporal.ChronoUnit;
-import java.util.List;
-
-@Component
-@RequiredArgsConstructor
-public class StatRepository {
-
- private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
- private final LocalDateTime startUnixEpoch = LocalDateTime.parse("1970-01-01T00:00:00");
-
- @Value("${spring.application.name}")
- private String appName;
-
- private final StatClient statClient;
-
- public void sendHitRequest(HttpServletRequest request) {
- try {
- statClient.hit(EndpointHitDto.builder()
- .ip(request.getRemoteAddr())
- .uri(request.getRequestURI())
- .app(appName)
- .timestamp(LocalDateTime.now())
- .build()
- );
- } catch (Exception ex) {
- throw new HitRequestException(ex);
- }
- }
-
- public List getStat(List statUris,
- LocalDateTime rangeStart,
- LocalDateTime rangeEnd,
- boolean uniqe) {
- if (statUris == null || statUris.isEmpty()) {
- throw new StatResponseException();
- }
-
- if (rangeStart == null) {
- rangeStart = startUnixEpoch;
- }
-
- if (rangeEnd == null) {
- rangeEnd = LocalDateTime.now();
- }
-
- StatsRequest request = StatsRequest.builder()
- .uris(statUris)
- .start(rangeStart.truncatedTo(ChronoUnit.MILLIS).format(formatter))
- .end(rangeEnd.truncatedTo(ChronoUnit.MILLIS).format(formatter))
- .unique(uniqe)
- .build();
-
- List stats;
- try {
- stats = statClient.getStat(request);
- } catch (Exception ex) {
- throw new StatResponseException(ex);
- }
-
- if (stats == null) {
- throw new StatResponseException();
- }
-
- return stats;
- }
-
- public List getStat(List statUris, boolean uniqe) {
- return getStat(statUris, null, null, uniqe);
- }
-}
diff --git a/core/main-service/src/test/java/ru/practicum/ewm/TestUtils.java b/core/main-service/src/test/java/ru/practicum/ewm/TestUtils.java
deleted file mode 100644
index 80e8ba9..0000000
--- a/core/main-service/src/test/java/ru/practicum/ewm/TestUtils.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package ru.practicum.ewm;
-
-import org.springframework.boot.test.context.TestComponent;
-import ru.practicum.ewm.model.Category;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.Location;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.model.enums.EventState;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-
-@SuppressWarnings("unused")
-@TestComponent
-public class TestUtils {
-
- public final LocalDateTime pastDate = LocalDateTime.parse("2023-01-01T00:00:01");
- public final LocalDateTime futureDate = LocalDateTime.parse("2028-01-01T00:00:01");
-
- private final Random random = new Random();
-
- public String generateRandomText(int length, String addAfterStr, Character... addSynbols) {
- java.util.List symbols = new ArrayList<>(List.of(
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
- 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z'
- ));
- symbols.addAll(Arrays.asList(addSynbols));
- StringBuilder sb = new StringBuilder(length);
-
- for (int i = 0; i < length; i++) {
- int index = random.nextInt(symbols.size());
- sb.append(symbols.get(index));
- }
-
- return sb.append(addAfterStr).toString();
- }
-
- public Location generateLocation() {
- return Location.builder()
- .lat(random.nextFloat())
- .lon(random.nextFloat())
- .build();
- }
-
- public User generateUser() {
- return User.builder()
- .name(generateRandomText(15, "", ' '))
- .email(generateRandomText(15, "@mail.ru"))
- .build();
- }
-
- public Category generateCategory() {
- return Category.builder()
- .name(generateRandomText(10, ""))
- .build();
- }
-
- public Event generateEvent(User initiator,
- Category category,
- LocalDateTime eventDate,
- EventState eventState) {
- return Event.builder()
- .annotation(generateRandomText(100, "", ' '))
- .category(category)
- .createdOn(eventDate.minusDays(1))
- .description(generateRandomText(200, "", ' '))
- .eventDate(eventDate)
- .initiator(initiator)
- .location(generateLocation())
- .paid(random.nextBoolean())
- .participantLimit(random.nextInt(100))
- .publishedOn(eventDate.plusHours(3))
- .requestModeration(random.nextBoolean())
- .state(eventState)
- .title(generateRandomText(15, "", ' '))
- .rate(0)
- .build();
- }
-
- public Event generateEvent(LocalDateTime eventDate, EventState eventState) {
- return generateEvent(generateUser(), generateCategory(), eventDate, eventState);
- }
-
- public Event generateEvent(EventState eventState) {
- return generateEvent(pastDate, eventState);
- }
-
- public Event generateEvent() {
- return generateEvent(pastDate, EventState.PUBLISHED);
- }
-
- public Event getNewCopyOfEvent(Event event) {
- return event.toBuilder().id(null).build();
- }
-
- public Event getNewCopyOfEvent(Event event, EventState eventState) {
- return event.toBuilder().id(null).state(eventState).build();
- }
-}
\ No newline at end of file
diff --git a/core/main-service/src/test/java/ru/practicum/ewm/controller/admin/AdminCategoryControllerTest.java b/core/main-service/src/test/java/ru/practicum/ewm/controller/admin/AdminCategoryControllerTest.java
deleted file mode 100644
index 58fb804..0000000
--- a/core/main-service/src/test/java/ru/practicum/ewm/controller/admin/AdminCategoryControllerTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package ru.practicum.ewm.controller.admin;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.dto.category.NewCategoryDto;
-import ru.practicum.ewm.service.category.CategoryService;
-
-import static org.mockito.Mockito.*;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
-
-@ExtendWith(MockitoExtension.class)
-class AdminCategoryControllerTest {
-
- @Mock
- private CategoryService categoryService;
-
- @InjectMocks
- private AdminCategoryController controller;
-
- private MockMvc mockMvc;
-
- private final ObjectMapper objectMapper = new ObjectMapper();
-
- @BeforeEach
- void setUp() {
- mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
- }
-
- @Test
- void createCategory_blankName_shouldReturn400() throws Exception {
- NewCategoryDto newCat = new NewCategoryDto("");
-
- mockMvc.perform(post("/admin/categories")
- .contentType(MediaType.APPLICATION_JSON)
- .content(objectMapper.writeValueAsString(newCat)))
- .andExpect(status().isBadRequest());
- }
-
- @Test
- void updateCategory_validData_shouldReturn200() throws Exception {
- CategoryDto update = CategoryDto.builder().id(1L).name("Выставки").build();
- CategoryDto updated = CategoryDto.builder().id(1L).name("Выставки").build();
- when(categoryService.updateCategory(1L, update)).thenReturn(updated);
-
- mockMvc.perform(patch("/admin/categories/1")
- .contentType(MediaType.APPLICATION_JSON)
- .content(objectMapper.writeValueAsString(update)))
- .andExpect(status().isOk())
- .andExpect(jsonPath("$.name").value("Выставки"));
- }
-
- @Test
- void deleteCategory_existing_shouldReturn204() throws Exception {
- mockMvc.perform(delete("/admin/categories/1"))
- .andExpect(status().isNoContent());
- }
-}
\ No newline at end of file
diff --git a/core/main-service/src/test/java/ru/practicum/ewm/controller/admin/AdminUserControllerTest.java b/core/main-service/src/test/java/ru/practicum/ewm/controller/admin/AdminUserControllerTest.java
deleted file mode 100644
index 65dc166..0000000
--- a/core/main-service/src/test/java/ru/practicum/ewm/controller/admin/AdminUserControllerTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package ru.practicum.ewm.controller.admin;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import ru.practicum.ewm.dto.user.NewUserRequest;
-import ru.practicum.ewm.dto.user.UserDto;
-import ru.practicum.ewm.service.user.UserService;
-
-import java.util.List;
-
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
-
-@ExtendWith(MockitoExtension.class)
-class AdminUserControllerTest {
-
- @Mock
- private UserService userService;
-
- @InjectMocks
- private AdminUserController controller;
-
- private MockMvc mockMvc;
-
- private final ObjectMapper objectMapper = new ObjectMapper();
-
- @BeforeEach
- void setUp() {
- mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
- }
-
- @Test
- void createUser_validRequest_shouldReturn201() throws Exception {
- NewUserRequest request = new NewUserRequest("Test User", "user@example.com");
- UserDto userDto = new UserDto(1L, "Test User", "user@example.com");
- when(userService.adminAddNewUser(any(NewUserRequest.class))).thenReturn(userDto);
-
- mockMvc.perform(post("/admin/users")
- .contentType(MediaType.APPLICATION_JSON)
- .content(objectMapper.writeValueAsString(request)))
- .andExpect(status().isCreated())
- .andExpect(jsonPath("$.id").value(1L))
- .andExpect(jsonPath("$.name").value("Test User"))
- .andExpect(jsonPath("$.email").value("user@example.com"));
- }
-
- @Test
- void createUser_blankName_shouldReturn400() throws Exception {
- NewUserRequest request = new NewUserRequest("", "user@example.com");
-
- mockMvc.perform(post("/admin/users")
- .contentType(MediaType.APPLICATION_JSON)
- .content(objectMapper.writeValueAsString(request)))
- .andExpect(status().isBadRequest());
- }
-
- @Test
- void getUsers_shouldReturnList() throws Exception {
- UserDto user = new UserDto(1L, "Test User", "user@example.com");
- when(userService.getUsers(any(), anyInt(), anyInt())).thenReturn(List.of(user));
-
- mockMvc.perform(get("/admin/users")
- .param("from", "0")
- .param("size", "10"))
- .andExpect(status().isOk())
- .andExpect(jsonPath("$[0].id").value(1L))
- .andExpect(jsonPath("$[0].name").value("Test User"));
- }
-
- @Test
- void deleteUser_existingUser_shouldReturn204() throws Exception {
- mockMvc.perform(delete("/admin/users/1"))
- .andExpect(status().isNoContent());
- }
-}
\ No newline at end of file
diff --git a/core/main-service/src/test/java/ru/practicum/ewm/dto/NewEventDtoTest.java b/core/main-service/src/test/java/ru/practicum/ewm/dto/NewEventDtoTest.java
deleted file mode 100644
index bec8633..0000000
--- a/core/main-service/src/test/java/ru/practicum/ewm/dto/NewEventDtoTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-package ru.practicum.ewm.dto;
-
-import jakarta.validation.ConstraintViolation;
-import jakarta.validation.Validation;
-import jakarta.validation.Validator;
-import jakarta.validation.ValidatorFactory;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import ru.practicum.ewm.dto.event.NewEventDto;
-import ru.practicum.ewm.model.Location;
-
-import java.time.LocalDateTime;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-/// generated by Alisa
-class NewEventDtoTest {
-
- private Validator validator;
-
- private final String validAnnotation = "Valid annotation text with more than 20 characters";
- private final String validDescription = "Valid description with more than 20 characters and less than 7000 chars";
-
- @BeforeEach
- void setUp() {
- try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
- validator = factory.getValidator();
- }
- }
-
- @Test
- void whenValidDto_thenNoViolations() {
- NewEventDto dto = NewEventDto.builder()
- .annotation(validAnnotation)
- .category(1L)
- .description(validDescription)
- .eventDate(LocalDateTime.now().plusDays(1))
- .location(Location.builder()
- .lat(55.7558F)
- .lon(37.6173F)
- .build())
- .paid(true)
- .participantLimit(100)
- .requestModeration(true)
- .title("Valid title")
- .build();
-
- var violations = validator.validate(dto);
-
- assertEquals(0, violations.size());
- }
-
- @Test
- void whenAnnotationTooShort_thenViolation() {
- NewEventDto dto = NewEventDto.builder()
- .annotation("short")
- .category(1L)
- .description(validDescription)
- .eventDate(LocalDateTime.now().plusDays(1))
- .location(Location.builder()
- .lat(55.7558F)
- .lon(37.6173F)
- .build())
- .paid(true)
- .participantLimit(100)
- .requestModeration(true)
- .title("Valid title")
- .build();
-
- var violations = validator.validate(dto);
-
- assertEquals(1, violations.size());
- ConstraintViolation violation = violations.iterator().next();
- assertEquals("annotation", violation.getPropertyPath().toString());
- assertEquals("размер должен находиться в диапазоне от 20 до 2000", violation.getMessage());
- }
-
- @Test
- void whenCategoryIsNull_thenViolation() {
- NewEventDto dto = NewEventDto.builder()
- .annotation(validAnnotation)
- .category(null)
- .description(validDescription)
- .eventDate(LocalDateTime.now().plusDays(1))
- .location(Location.builder()
- .lat(55.7558F)
- .lon(37.6173F)
- .build())
- .paid(true)
- .participantLimit(100)
- .requestModeration(true)
- .title("Valid title")
- .build();
-
- var violations = validator.validate(dto);
-
- assertEquals(1, violations.size());
- ConstraintViolation violation = violations.iterator().next();
- assertEquals("category", violation.getPropertyPath().toString());
- assertEquals("не должно равняться null", violation.getMessage());
- }
-
- @Test
- void whenDescriptionTooLong_thenViolation() {
- String longDescription = "A".repeat(7001);
- NewEventDto dto = NewEventDto.builder()
- .annotation(validAnnotation)
- .category(1L)
- .description(longDescription)
- .eventDate(LocalDateTime.now().plusDays(1))
- .location(Location.builder()
- .lat(55.7558F)
- .lon(37.6173F)
- .build())
- .paid(true)
- .participantLimit(100)
- .requestModeration(true)
- .title("Valid title")
- .build();
-
- var violations = validator.validate(dto);
-
- assertEquals(1, violations.size());
- ConstraintViolation violation = violations.iterator().next();
- assertEquals("description", violation.getPropertyPath().toString());
- assertEquals("размер должен находиться в диапазоне от 20 до 7000", violation.getMessage());
- }
-
- @Test
- void whenEventDateIsNull_thenViolation() {
- NewEventDto dto = NewEventDto.builder()
- .annotation(validAnnotation)
- .category(1L)
- .description(validDescription)
- .eventDate(null)
- .location(Location.builder()
- .lat(55.7558F)
- .lon(37.6173F)
- .build())
- .paid(true)
- .participantLimit(100)
- .requestModeration(true)
- .title("Valid title")
- .build();
-
- var violations = validator.validate(dto);
-
- assertEquals(1, violations.size());
- ConstraintViolation violation = violations.iterator().next();
- assertEquals("eventDate", violation.getPropertyPath().toString());
- assertEquals("не должно равняться null", violation.getMessage());
- }
-
- @Test
- void whenLocationIsNull_thenViolation() {
- NewEventDto dto = NewEventDto.builder()
- .annotation(validAnnotation)
- .category(1L)
- .description(validDescription)
- .eventDate(LocalDateTime.now().plusDays(1))
- .location(null)
- .paid(true)
- .participantLimit(100)
- .requestModeration(true)
- .title("Valid title")
- .build();
-
- var violations = validator.validate(dto);
-
- assertEquals(1, violations.size());
- ConstraintViolation violation = violations.iterator().next();
- assertEquals("location", violation.getPropertyPath().toString());
- assertEquals("не должно равняться null", violation.getMessage());
- }
-
- @Test
- void whenTitleTooShort_thenViolation() {
- NewEventDto dto = NewEventDto.builder()
- .annotation(validAnnotation)
- .category(1L)
- .description(validDescription)
- .eventDate(LocalDateTime.now().plusDays(1))
- .location(Location.builder()
- .lat(55.7558F)
- .lon(37.6173F)
- .build())
- .paid(true)
- .participantLimit(100)
- .requestModeration(true)
- .title("ab")
- .build();
-
- var violations = validator.validate(dto);
-
- assertEquals(1, violations.size());
- ConstraintViolation violation = violations.iterator().next();
- assertEquals("title", violation.getPropertyPath().toString());
- assertEquals("размер должен находиться в диапазоне от 3 до 120", violation.getMessage());
- }
-}
diff --git a/core/main-service/src/test/java/ru/practicum/ewm/service/AdminCategoryServiceTest.java b/core/main-service/src/test/java/ru/practicum/ewm/service/AdminCategoryServiceTest.java
deleted file mode 100644
index 3da291e..0000000
--- a/core/main-service/src/test/java/ru/practicum/ewm/service/AdminCategoryServiceTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package ru.practicum.ewm.service;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import ru.practicum.ewm.dao.CategoryRepository;
-import ru.practicum.ewm.dao.EventRepository;
-import ru.practicum.ewm.dto.category.CategoryDto;
-import ru.practicum.ewm.dto.category.NewCategoryDto;
-import ru.practicum.ewm.model.Category;
-import ru.practicum.ewm.service.category.CategoryServiceImpl;
-import ru.practicum.ewm.util.error.exception.ConflictException;
-import ru.practicum.ewm.util.error.exception.NotFoundException;
-
-import java.util.Optional;
-
-import static org.assertj.core.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
-
-@ExtendWith(MockitoExtension.class)
-class AdminCategoryServiceTest {
-
- @Mock
- private CategoryRepository categoryRepository;
- @Mock
- private EventRepository eventRepository;
-
- @InjectMocks
- private CategoryServiceImpl categoryService;
-
- private Category category;
- private NewCategoryDto newCategoryDto;
- private CategoryDto updateDto;
-
- @BeforeEach
- void setUp() {
- category = Category.builder()
- .id(1L)
- .name("Концерты")
- .build();
- newCategoryDto = new NewCategoryDto("Концерты");
- updateDto = CategoryDto.builder()
- .id(1L)
- .name("Выставки")
- .build();
- }
-
- @Test
- void createCategory_success() {
- when(categoryRepository.existsByName("Концерты")).thenReturn(false);
- when(categoryRepository.save(any(Category.class))).thenReturn(category);
-
- CategoryDto result = categoryService.adminAddNewCategory(newCategoryDto);
-
- assertThat(result.id()).isEqualTo(1L);
- assertThat(result.name()).isEqualTo("Концерты");
- }
-
- @Test
- void createCategory_duplicateName_shouldThrowConflict() {
- when(categoryRepository.existsByName("Концерты")).thenReturn(true);
-
- assertThatThrownBy(() -> categoryService.adminAddNewCategory(newCategoryDto))
- .isInstanceOf(ConflictException.class)
- .hasMessageContaining("уже существует");
- }
-
- @Test
- void updateCategory_success() {
- when(categoryRepository.findById(1L)).thenReturn(Optional.of(category));
- when(categoryRepository.existsByName("Выставки")).thenReturn(false);
- when(categoryRepository.save(any(Category.class))).thenReturn(category);
-
- CategoryDto result = categoryService.updateCategory(1L, updateDto);
-
- assertThat(result.name()).isEqualTo("Выставки");
- verify(categoryRepository).save(category);
- }
-
- @Test
- void updateCategory_notFound_shouldThrowNotFound() {
- when(categoryRepository.findById(999L)).thenReturn(Optional.empty());
-
- assertThatThrownBy(() -> categoryService.updateCategory(999L, updateDto))
- .isInstanceOf(NotFoundException.class);
- }
-
- @Test
- void deleteCategory_noEvents_success() {
- when(categoryRepository.findById(1L)).thenReturn(Optional.of(category));
- when(eventRepository.existsByCategoryId(1L)).thenReturn(false);
-
- categoryService.deleteCategory(1L);
-
- verify(categoryRepository).delete(category);
- }
-
- @Test
- void deleteCategory_withEvents_shouldThrowConflict() {
- when(categoryRepository.findById(1L)).thenReturn(Optional.of(category));
- when(eventRepository.existsByCategoryId(1L)).thenReturn(true);
-
- assertThatThrownBy(() -> categoryService.deleteCategory(1L))
- .isInstanceOf(ConflictException.class)
- .hasMessageContaining("The category is not empty");
- verify(categoryRepository, never()).delete(any());
- }
-}
\ No newline at end of file
diff --git a/core/main-service/src/test/java/ru/practicum/ewm/service/AdminUserServiceTest.java b/core/main-service/src/test/java/ru/practicum/ewm/service/AdminUserServiceTest.java
deleted file mode 100644
index ec176d8..0000000
--- a/core/main-service/src/test/java/ru/practicum/ewm/service/AdminUserServiceTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package ru.practicum.ewm.service;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.data.domain.PageRequest;
-import ru.practicum.ewm.dao.UserRepository;
-import ru.practicum.ewm.dto.user.NewUserRequest;
-import ru.practicum.ewm.dto.user.UserDto;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.service.user.UserServiceImpl;
-import ru.practicum.ewm.util.error.exception.NotFoundException;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
-import static org.mockito.Mockito.eq;
-
-@ExtendWith(MockitoExtension.class)
-class AdminUserServiceTest {
-
- @Mock
- private UserRepository userRepository;
-
- @InjectMocks
- private UserServiceImpl userService;
-
- private User user;
- private NewUserRequest newUserRequest;
-
- @BeforeEach
- void setUp() {
- user = User.builder()
- .id(1L)
- .name("Test User")
- .email("user@example.com")
- .build();
- newUserRequest = NewUserRequest.builder()
- .name("Test User")
- .email("user@example.com")
- .build();
- }
-
- @Test
- void createUser_shouldReturnUserDto() {
- when(userRepository.save(any(User.class))).thenReturn(user);
-
- UserDto result = userService.adminAddNewUser(newUserRequest);
-
- assertThat(result.id()).isEqualTo(1L);
- assertThat(result.name()).isEqualTo("Test User");
- assertThat(result.email()).isEqualTo("user@example.com");
- verify(userRepository).save(any(User.class));
- }
-
- @Test
- void getUsers_withoutIds_shouldReturnAll() {
- when(userRepository.findAll(any(PageRequest.class)))
- .thenReturn(org.springframework.data.domain.Page.empty());
-
- List result = userService.getUsers(null, 0, 10);
-
- assertThat(result).isEmpty();
- verify(userRepository).findAll(any(PageRequest.class));
- }
-
- @Test
- void getUsers_withIds_shouldFilterByIds() {
- when(userRepository.findAllByIdIn(eq(List.of(1L)), any(PageRequest.class)))
- .thenReturn(List.of(user));
-
- List result = userService.getUsers(List.of(1L), 0, 10);
-
- assertThat(result).hasSize(1);
- assertThat(result.getFirst().id()).isEqualTo(1L);
- }
-
- @Test
- void deleteUser_existingUser_shouldSucceed() {
- when(userRepository.existsById(1L)).thenReturn(true);
- doNothing().when(userRepository).deleteById(1L);
-
- assertThatCode(() -> userService.deleteUser(1L)).doesNotThrowAnyException();
- verify(userRepository).deleteById(1L);
- }
-
- @Test
- void deleteUser_notFound_shouldThrowNotFoundException() {
- when(userRepository.existsById(999L)).thenReturn(false);
-
- assertThatThrownBy(() -> userService.deleteUser(999L))
- .isInstanceOf(NotFoundException.class)
- .hasMessageContaining("Пользователь с id=999 не найден");
- verify(userRepository, never()).deleteById(any());
- }
-}
\ No newline at end of file
diff --git a/core/main-service/src/test/java/ru/practicum/ewm/service/EventServiceImplTest.java b/core/main-service/src/test/java/ru/practicum/ewm/service/EventServiceImplTest.java
deleted file mode 100644
index 9c97663..0000000
--- a/core/main-service/src/test/java/ru/practicum/ewm/service/EventServiceImplTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package ru.practicum.ewm.service;
-
-import jakarta.servlet.http.HttpServletRequest;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.domain.Specification;
-import ru.practicum.ewm.dao.EventRepository;
-import ru.practicum.ewm.dao.RequestRepository;
-import ru.practicum.ewm.dto.event.EventFullDto;
-import ru.practicum.ewm.dto.event.EventShortDto;
-import ru.practicum.ewm.dto.event.FreeGetDto;
-import ru.practicum.ewm.mapper.EventMapper;
-import ru.practicum.ewm.model.Category;
-import ru.practicum.ewm.model.Event;
-import ru.practicum.ewm.model.Location;
-import ru.practicum.ewm.model.User;
-import ru.practicum.ewm.model.enums.EventState;
-import ru.practicum.ewm.model.enums.ParticipationStatus;
-import ru.practicum.ewm.service.event.EventServiceImpl;
-import ru.practicum.ewm.util.statistic.StatRepository;
-import ru.practicum.stat.dto.ViewStatsDto;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Optional;
-
-import static org.hamcrest.MatcherAssert.*;
-import static org.hamcrest.Matchers.*;
-import static org.hamcrest.Matchers.contains;
-import static org.mockito.Mockito.*;
-
-@ExtendWith(MockitoExtension.class)
-class EventServiceImplTest {
-
- @Mock
- StatRepository statRepository;
-
- @Mock
- EventRepository eventRepository;
-
- @Mock
- RequestRepository requestRepository;
-
- @Mock
- HttpServletRequest httpServletRequest;
-
- @InjectMocks
- EventServiceImpl eventService;
-
- private static Event event;
-
- @BeforeAll
- static void setup() {
- event = Event.builder()
- .id(1L)
- .annotation("annotation".repeat(10))
- .category(Category.builder().id(1L).name("category").build())
- .createdOn(LocalDateTime.parse("2026-11-10T19:00:00"))
- .description("description".repeat(10))
- .eventDate(LocalDateTime.parse("2027-01-01T00:00:01"))
- .initiator(User.builder().id(1L).name("User").email("user@email.ry").build())
- .location(Location.builder().lat(25.55F).lon(35.77F).build())
- .paid(true)
- .participantLimit(30)
- .publishedOn(LocalDateTime.parse("2026-12-10T21:00:00"))
- .requestModeration(true)
- .state(EventState.PUBLISHED)
- .title("title")
- .rate(0)
- .build();
- }
-
- @Nested
- @DisplayName("Получение списка публичных событий")
- class GetFreeEvents {
-
- @Test
- void basicFlow() {
- // region setup
- FreeGetDto getDto = FreeGetDto.builder()
- .text("0")
- .categories(List.of(0))
- .paid(true)
- .onlyAvailable(true)
- .rangeStart(LocalDateTime.parse("2026-12-31T23:59:00"))
- .rangeEnd(LocalDateTime.parse("2027-01-01T02:00:00"))
- .sort(FreeGetDto.FreeEventSort.EVENT_DATE)
- .from(0)
- .size(1)
- .build();
-
- Page page = new PageImpl<>(List.of(event));
- // endregion setup
-
- doNothing().when(statRepository).sendHitRequest(httpServletRequest);
- when(eventRepository.findAll(
- ArgumentMatchers.