package com.example.nto.controller; 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 employeeOpt = employeeService.findByCode(code); if (employeeOpt.isEmpty()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } Employee employee = employeeOpt.get(); Map bookings = bookingService.getBookingsByEmployee(employee); Map 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> available = bookingService.getAvailablePlaces(); Map> 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 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 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 } }