student-30864-patch-1 #11

Closed
student-30864 wants to merge 19 commits from student-30864/NTO-2025-Backend-TeamTask-1:student-30864-patch-1 into main
Showing only changes of commit d6553f2888 - Show all commits

View File

@@ -1,10 +1,170 @@
package com.example.nto.controller;
/**
* TODO: ДОРАБОТАТЬ в рамках задания
* =================================
* МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета
*/
import com.example.nto.dto.BookingRequestDto;
import com.example.nto.dto.BookingShortDto;
import com.example.nto.dto.EmployeeInfoResponseDto;
import com.example.nto.entity.Booking;
import com.example.nto.entity.Employee;
import com.example.nto.entity.Place;
import com.example.nto.repository.PlaceRepository;
import com.example.nto.service.BookingService;
import com.example.nto.service.EmployeeService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class BookingController {
private final EmployeeService employeeService;
private final BookingService bookingService;
private final PlaceRepository placeRepository;
/**
* GET api/{code}/info
*
* Ответ (пример из README):
* {
* "name": "Иванов Петр Федорович",
* "photoUrl": "https://...",
* "booking": {
* "2025-01-05": {"id":1,"place":"102"},
* "2025-01-09": {"id":3,"place":"Зона 51. 50"}
* }
* }
*
* 400 что-то пошло не так
* 401 кода не существует
* 200 ОК
*/
@GetMapping("/{code}/info")
public ResponseEntity<?> getInfo(@PathVariable("code") String code) {
if (code == null || code.isBlank()) {
return ResponseEntity.badRequest().build();
}
Optional<Employee> employeeOpt = employeeService.findByCode(code);
if (employeeOpt.isEmpty()) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
Employee employee = employeeOpt.get();
Map<LocalDate, Booking> bookings = bookingService.getBookingsByEmployee(employee);
Map<String, BookingShortDto> bookingMap = new LinkedHashMap<>();
bookings.forEach((date, booking) -> bookingMap.put(
date.toString(),
new BookingShortDto(
booking.getPlace().getId(),
booking.getPlace().getPlace()
)
));
EmployeeInfoResponseDto response = new EmployeeInfoResponseDto(
employee.getName(),
employee.getPhotoUrl(),
bookingMap
);
return ResponseEntity.ok(response);
}
/**
* GET api/{code}/booking
*
* Ответ (пример из README):
* {
* "2025-01-05": [{"id":1,"place":"102"}, {"id":2,"place":"209.13"}],
* "2025-01-06": [{"id":3,"place":"Зона 51. 50"}],
* ...
* }
*
* 400 что-то пошло не так
* 401 кода не существует
* 200 ОК
*/
@GetMapping("/{code}/booking")
public ResponseEntity<?> getAvailable(@PathVariable("code") String code) {
if (code == null || code.isBlank()) {
return ResponseEntity.badRequest().build();
}
if (!employeeService.existsByCode(code)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
Map<LocalDate, List<Place>> available = bookingService.getAvailablePlaces();
Map<String, List<BookingShortDto>> body = new LinkedHashMap<>();
available.forEach((date, places) -> body.put(
date.toString(),
places.stream()
.map(place -> new BookingShortDto(place.getId(), place.getPlace()))
.collect(Collectors.toList())
));
return ResponseEntity.ok(body);
}
/**
* POST api/{code}/book
*
* Тело:
* {
* "date": "2025-01-05",
* "placeId": 1
* }
*
* 400 что-то пошло не так (неправильный формат даты, нет placeId и т.п.)
* 401 кода не существует
* 409 место уже занято или у сотрудника уже есть бронь на эту дату
* 201 бронирование успешно создано
*/
@PostMapping("/{code}/book")
public ResponseEntity<?> createBooking(@PathVariable("code") String code,
@RequestBody BookingRequestDto request) {
if (code == null || code.isBlank()) {
return ResponseEntity.badRequest().build();
}
Optional<Employee> employeeOpt = employeeService.findByCode(code);
if (employeeOpt.isEmpty()) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
if (request == null || request.date() == null || request.placeId() == null) {
return ResponseEntity.badRequest().build();
}
LocalDate date;
try {
date = LocalDate.parse(request.date());
} catch (DateTimeParseException ex) {
return ResponseEntity.badRequest().build();
}
Optional<Place> placeOpt = placeRepository.findById(request.placeId());
if (placeOpt.isEmpty()) {
return ResponseEntity.badRequest().build();
}
Employee employee = employeeOpt.get();
Place place = placeOpt.get();
if (bookingService.existsBookingForEmployeeOnDate(employee, date)
|| bookingService.isPlaceBookedOnDate(place, date)) {
return ResponseEntity.status(HttpStatus.CONFLICT).build(); // 409
}
bookingService.createBooking(employee, date, place);
return ResponseEntity.status(HttpStatus.CREATED).build(); // 201
}
}