Skip to content

Commit 2e7a1b0

Browse files
committed
fix33
1 parent 7deb096 commit 2e7a1b0

5 files changed

Lines changed: 186 additions & 9 deletions

File tree

ewm-service/src/main/java/ru/practicum/ewm/event/controller/AdminEventController.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package ru.practicum.ewm.event.controller;
22

33
import jakarta.validation.Valid;
4+
import jakarta.validation.constraints.Positive;
5+
import jakarta.validation.constraints.PositiveOrZero;
46
import lombok.RequiredArgsConstructor;
7+
import org.springframework.format.annotation.DateTimeFormat;
58
import org.springframework.validation.annotation.Validated;
69
import org.springframework.web.bind.annotation.*;
710
import ru.practicum.ewm.event.dto.AdminEventSearchParams;
811
import ru.practicum.ewm.event.dto.EventFullDto;
912
import ru.practicum.ewm.event.dto.UpdateEventAdminRequest;
1013
import ru.practicum.ewm.event.service.EventService;
1114

15+
import java.time.LocalDateTime;
1216
import java.util.List;
1317

1418
@RestController
@@ -18,8 +22,27 @@
1822
public class AdminEventController {
1923
private final EventService eventService;
2024

25+
// @GetMapping
26+
// public List<EventFullDto> getEvents(@Valid @ModelAttribute AdminEventSearchParams params) {
27+
// return eventService.getEventsForAdmin(params);
28+
// }
29+
2130
@GetMapping
22-
public List<EventFullDto> getEvents(@Valid @ModelAttribute AdminEventSearchParams params) {
31+
public List<EventFullDto> getEvents(@RequestParam(required = false) List<Long> users,
32+
@RequestParam(required = false) List<String> states,
33+
@RequestParam(required = false) List<Long> categories,
34+
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime rangeStart,
35+
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime rangeEnd,
36+
@RequestParam(defaultValue = "0") @PositiveOrZero int from,
37+
@RequestParam(defaultValue = "10") @Positive int size) {
38+
AdminEventSearchParams params = new AdminEventSearchParams();
39+
params.setUsers(users);
40+
params.setStates(states);
41+
params.setCategories(categories);
42+
params.setRangeStart(rangeStart);
43+
params.setRangeEnd(rangeEnd);
44+
params.setFrom(from);
45+
params.setSize(size);
2346
return eventService.getEventsForAdmin(params);
2447
}
2548

ewm-service/src/main/java/ru/practicum/ewm/event/service/EventServiceImpl.java

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,28 +76,67 @@ public EventFullDto getUserEvent(Long userId, Long eventId) {
7676
return EventMapper.toEventFullDto(event, 0L, 0L);
7777
}
7878

79+
// @Override
80+
// @Transactional
81+
// public EventFullDto updateUserEvent(Long userId, Long eventId, UpdateEventUserRequest request) {
82+
// Event event = eventRepository.findById(eventId)
83+
// .orElseThrow(() -> new NotFoundException("Событие с id=" + eventId + " не найдено"));
84+
// if (!event.getInitiator().getId().equals(userId)) {
85+
// throw new NotFoundException("Событие не принадлежит пользователю");
86+
// }
87+
// if (event.getState() != EventState.PENDING && event.getState() != EventState.CANCELED) {
88+
// throw new ConflictException("Можно изменять только события в статусе PENDING или CANCELED");
89+
// }
90+
// if (request.getEventDate() != null && request.getEventDate().isBefore(LocalDateTime.now().plusHours(2))) {
91+
// throw new ConflictException("Дата события должна быть не ранее чем через 2 часа от текущего момента");
92+
// }
93+
// EventMapper.updateEventFromUserRequest(request, event);
94+
// if (request.getStateAction() != null) {
95+
// if (request.getStateAction().equals("SEND_TO_REVIEW")) {
96+
// event.setState(EventState.PENDING);
97+
// } else if (request.getStateAction().equals("CANCEL_REVIEW")) {
98+
// event.setState(EventState.CANCELED);
99+
// }
100+
// }
101+
// event = eventRepository.save(event);
102+
// return EventMapper.toEventFullDto(event, 0L, 0L);
103+
// }
104+
79105
@Override
80106
@Transactional
81107
public EventFullDto updateUserEvent(Long userId, Long eventId, UpdateEventUserRequest request) {
82108
Event event = eventRepository.findById(eventId)
83109
.orElseThrow(() -> new NotFoundException("Событие с id=" + eventId + " не найдено"));
110+
84111
if (!event.getInitiator().getId().equals(userId)) {
85112
throw new NotFoundException("Событие не принадлежит пользователю");
86113
}
114+
87115
if (event.getState() != EventState.PENDING && event.getState() != EventState.CANCELED) {
88116
throw new ConflictException("Можно изменять только события в статусе PENDING или CANCELED");
89117
}
118+
90119
if (request.getEventDate() != null && request.getEventDate().isBefore(LocalDateTime.now().plusHours(2))) {
91120
throw new ConflictException("Дата события должна быть не ранее чем через 2 часа от текущего момента");
92121
}
122+
93123
EventMapper.updateEventFromUserRequest(request, event);
124+
94125
if (request.getStateAction() != null) {
95-
if (request.getStateAction().equals("SEND_TO_REVIEW")) {
126+
String action = request.getStateAction();
127+
if ("SEND_TO_REVIEW".equals(action)) {
128+
if (event.getState() != EventState.CANCELED) {
129+
throw new ConflictException("Отправить на повторное рассмотрение можно только отменённое событие");
130+
}
96131
event.setState(EventState.PENDING);
97-
} else if (request.getStateAction().equals("CANCEL_REVIEW")) {
132+
} else if ("CANCEL_REVIEW".equals(action)) {
133+
if (event.getState() != EventState.PENDING) {
134+
throw new ConflictException("Отменить можно только событие в статусе PENDING");
135+
}
98136
event.setState(EventState.CANCELED);
99137
}
100138
}
139+
101140
event = eventRepository.save(event);
102141
return EventMapper.toEventFullDto(event, 0L, 0L);
103142
}
@@ -136,19 +175,73 @@ public List<EventFullDto> getEventsForAdmin(AdminEventSearchParams params) {
136175
}
137176

138177

178+
// @Override
179+
// @Transactional
180+
// public EventFullDto updateEventByAdmin(Long eventId, UpdateEventAdminRequest request) {
181+
// Event event = eventRepository.findById(eventId)
182+
// .orElseThrow(() -> new NotFoundException("Событие с id=" + eventId + " не найдено"));
183+
//
184+
// if (request.getStateAction() != null) {
185+
// if (request.getStateAction().equals("PUBLISH_EVENT")) {
186+
// if (event.getState() != EventState.PENDING) {
187+
// throw new ConflictException("Событие можно публиковать только в статусе PENDING");
188+
// }
189+
// if (event.getEventDate().isBefore(LocalDateTime.now().plusHours(1))) {
190+
// throw new ConflictException("Дата начала события должна быть не ранее чем за час от текущего момента");
191+
// }
192+
// event.setState(EventState.PUBLISHED);
193+
// event.setPublishedOn(LocalDateTime.now());
194+
// } else if (request.getStateAction().equals("REJECT_EVENT")) {
195+
// if (event.getState() == EventState.PUBLISHED) {
196+
// throw new ConflictException("Нельзя отклонить уже опубликованное событие");
197+
// }
198+
// event.setState(EventState.CANCELED);
199+
// }
200+
// }
201+
//
202+
// if (request.getAnnotation() != null) event.setAnnotation(request.getAnnotation());
203+
// if (request.getDescription() != null) event.setDescription(request.getDescription());
204+
// if (request.getTitle() != null) event.setTitle(request.getTitle());
205+
// if (request.getParticipantLimit() != null) event.setParticipantLimit(request.getParticipantLimit());
206+
// if (request.getPaid() != null) event.setPaid(request.getPaid());
207+
// if (request.getRequestModeration() != null) event.setRequestModeration(request.getRequestModeration());
208+
//
209+
// if (request.getEventDate() != null) {
210+
// if (request.getEventDate().isBefore(LocalDateTime.now().plusHours(2))) {
211+
// throw new ConflictException("Дата события не может быть раньше чем через 2 часа от текущего момента");
212+
// }
213+
// event.setEventDate(request.getEventDate());
214+
// }
215+
//
216+
// if (request.getCategory() != null) {
217+
// Category newCategory = categoryRepository.findById(request.getCategory())
218+
// .orElseThrow(() -> new NotFoundException("Категория с id=" + request.getCategory() + " не найдена"));
219+
// event.setCategory(newCategory);
220+
// }
221+
//
222+
// if (request.getLocation() != null) event.setLocation(request.getLocation());
223+
//
224+
// event = eventRepository.save(event);
225+
// Long views = 0L;
226+
// Long confirmed = eventRepository.countConfirmedRequests(eventId);
227+
// return EventMapper.toEventFullDto(event, views, confirmed);
228+
// }
229+
139230
@Override
140231
@Transactional
141232
public EventFullDto updateEventByAdmin(Long eventId, UpdateEventAdminRequest request) {
142233
Event event = eventRepository.findById(eventId)
143234
.orElseThrow(() -> new NotFoundException("Событие с id=" + eventId + " не найдено"));
144235

236+
// 1. Обработка изменения статуса (публикация/отклонение)
145237
if (request.getStateAction() != null) {
146238
if (request.getStateAction().equals("PUBLISH_EVENT")) {
147239
if (event.getState() != EventState.PENDING) {
148240
throw new ConflictException("Событие можно публиковать только в статусе PENDING");
149241
}
242+
// Проверка: дата события должна быть не ранее чем за 1 час от текущего момента
150243
if (event.getEventDate().isBefore(LocalDateTime.now().plusHours(1))) {
151-
throw new ConflictException("Дата начала события должна быть не ранее чем за час от текущего момента");
244+
throw new ConflictException("Дата начала события должна быть не ранее чем за час от даты публикации");
152245
}
153246
event.setState(EventState.PUBLISHED);
154247
event.setPublishedOn(LocalDateTime.now());
@@ -160,26 +253,31 @@ public EventFullDto updateEventByAdmin(Long eventId, UpdateEventAdminRequest req
160253
}
161254
}
162255

256+
// 2. Обновление остальных полей (если переданы)
163257
if (request.getAnnotation() != null) event.setAnnotation(request.getAnnotation());
164258
if (request.getDescription() != null) event.setDescription(request.getDescription());
165259
if (request.getTitle() != null) event.setTitle(request.getTitle());
166260
if (request.getParticipantLimit() != null) event.setParticipantLimit(request.getParticipantLimit());
167261
if (request.getPaid() != null) event.setPaid(request.getPaid());
168262
if (request.getRequestModeration() != null) event.setRequestModeration(request.getRequestModeration());
169263

264+
// 3. Обновление даты события (с проверкой, специфичной для администратора)
170265
if (request.getEventDate() != null) {
171-
if (request.getEventDate().isBefore(LocalDateTime.now().plusHours(2))) {
172-
throw new ConflictException("Дата события не может быть раньше чем через 2 часа от текущего момента");
266+
// Для администратора ограничение на изменение даты – не ранее чем за 1 час от текущего момента
267+
if (request.getEventDate().isBefore(LocalDateTime.now().plusHours(1))) {
268+
throw new ConflictException("Дата события не может быть раньше чем за 1 час от текущего момента");
173269
}
174270
event.setEventDate(request.getEventDate());
175271
}
176272

273+
// 4. Обновление категории
177274
if (request.getCategory() != null) {
178275
Category newCategory = categoryRepository.findById(request.getCategory())
179276
.orElseThrow(() -> new NotFoundException("Категория с id=" + request.getCategory() + " не найдена"));
180277
event.setCategory(newCategory);
181278
}
182279

280+
// 5. Обновление локации
183281
if (request.getLocation() != null) event.setLocation(request.getLocation());
184282

185283
event = eventRepository.save(event);

ewm-service/src/main/java/ru/practicum/ewm/request/dto/ParticipationRequestDto.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
@AllArgsConstructor
1414
public class ParticipationRequestDto {
1515
private Long id;
16-
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
16+
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS")
1717
private LocalDateTime created;
1818
private Long event;
1919
private Long requester;

ewm-service/src/main/java/ru/practicum/ewm/request/repository/RequestRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ public interface RequestRepository extends JpaRepository<Request, Long> {
1515
Optional<Request> findByRequesterIdAndEventId(Long userId, Long eventId);
1616

1717
long countByEventIdAndStatus(Long eventId, RequestStatus status);
18+
19+
List<Request> findAllByEventIdAndStatus(Long eventId, RequestStatus status);
1820
}

ewm-service/src/main/java/ru/practicum/ewm/request/service/RequestServiceImpl.java

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,44 @@ public List<ParticipationRequestDto> getEventRequestsByOwner(Long userId, Long e
9595
.collect(Collectors.toList());
9696
}
9797

98+
// @Override
99+
// @Transactional
100+
// public EventRequestStatusUpdateResult updateRequestStatus(Long userId, Long eventId,
101+
// EventRequestStatusUpdateRequest update) {
102+
// Event event = eventRepository.findById(eventId)
103+
// .orElseThrow(() -> new NotFoundException("Событие не найдено"));
104+
// if (!event.getInitiator().getId().equals(userId)) {
105+
// throw new ConflictException("Только владелец может изменять статус заявок");
106+
// }
107+
// if (event.getParticipantLimit() == 0 && !event.getRequestModeration()) {
108+
// throw new ConflictException("Для этого события не требуется подтверждение заявок");
109+
// }
110+
//
111+
// List<Request> requests = requestRepository.findAllById(update.getRequestIds());
112+
// long confirmedNow = requestRepository.countByEventIdAndStatus(eventId, RequestStatus.CONFIRMED);
113+
// int limit = event.getParticipantLimit();
114+
// List<ParticipationRequestDto> confirmed = new ArrayList<>();
115+
// List<ParticipationRequestDto> rejected = new ArrayList<>();
116+
//
117+
// for (Request req : requests) {
118+
// if (req.getStatus() != RequestStatus.PENDING) {
119+
// throw new ConflictException("Статус можно изменить только у заявок в состоянии PENDING");
120+
// }
121+
// if (update.getStatus().equals("CONFIRMED")) {
122+
// if (limit > 0 && confirmedNow >= limit) {
123+
// throw new ConflictException("Достигнут лимит участников");
124+
// }
125+
// req.setStatus(RequestStatus.CONFIRMED);
126+
// confirmed.add(RequestMapper.toDto(req));
127+
// confirmedNow++;
128+
// } else if (update.getStatus().equals("REJECTED")) {
129+
// req.setStatus(RequestStatus.REJECTED);
130+
// rejected.add(RequestMapper.toDto(req));
131+
// } else {
132+
// throw new IllegalArgumentException("Некорректный статус");
133+
// }
134+
// }
135+
98136
@Override
99137
@Transactional
100138
public EventRequestStatusUpdateResult updateRequestStatus(Long userId, Long eventId,
@@ -114,25 +152,41 @@ public EventRequestStatusUpdateResult updateRequestStatus(Long userId, Long even
114152
List<ParticipationRequestDto> confirmed = new ArrayList<>();
115153
List<ParticipationRequestDto> rejected = new ArrayList<>();
116154

155+
// 1. Обрабатываем переданные заявки
117156
for (Request req : requests) {
118157
if (req.getStatus() != RequestStatus.PENDING) {
119158
throw new ConflictException("Статус можно изменить только у заявок в состоянии PENDING");
120159
}
121-
if (update.getStatus().equals("CONFIRMED")) {
160+
if ("CONFIRMED".equals(update.getStatus())) {
122161
if (limit > 0 && confirmedNow >= limit) {
123162
throw new ConflictException("Достигнут лимит участников");
124163
}
125164
req.setStatus(RequestStatus.CONFIRMED);
126165
confirmed.add(RequestMapper.toDto(req));
127166
confirmedNow++;
128-
} else if (update.getStatus().equals("REJECTED")) {
167+
} else if ("REJECTED".equals(update.getStatus())) {
129168
req.setStatus(RequestStatus.REJECTED);
130169
rejected.add(RequestMapper.toDto(req));
131170
} else {
132171
throw new IllegalArgumentException("Некорректный статус");
133172
}
134173
}
135174

175+
// 2. Если после подтверждения лимит исчерпан, автоматически отклоняем все оставшиеся PENDING заявки
176+
if (limit > 0 && confirmedNow >= limit) {
177+
List<Request> pendingRequests = requestRepository.findAllByEventIdAndStatus(eventId, RequestStatus.PENDING);
178+
for (Request pending : pendingRequests) {
179+
// Исключаем те, что уже обработаны в текущем запросе (чтобы не дублировать)
180+
if (!requests.contains(pending)) {
181+
pending.setStatus(RequestStatus.REJECTED);
182+
rejected.add(RequestMapper.toDto(pending));
183+
}
184+
}
185+
// Сохраняем автоматически отклонённые заявки (обработанные уже сохранены в контексте транзакции)
186+
requestRepository.saveAll(pendingRequests);
187+
}
188+
189+
// 3. Сохраняем изменения для переданных заявок (если они не были сохранены ранее — они в managed состоянии, но явно сохраним для надёжности
136190
requestRepository.saveAll(requests);
137191
return new EventRequestStatusUpdateResult(confirmed, rejected);
138192
}

0 commit comments

Comments
 (0)