package com.example.nto.service.impl; import com.example.nto.entity.Booking; import com.example.nto.entity.Employee; import com.example.nto.entity.Place; import com.example.nto.excepation.EmployeeNotFoundException; import com.example.nto.repository.BookingRepository; import com.example.nto.repository.EmployeeRepository; import com.example.nto.repository.PlaceRepository; import com.example.nto.service.BookingService; import com.example.nto.service.EmployeeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.util.*; @Service public class BookingServiceImpl implements BookingService { @Autowired private BookingRepository bookingRepository; @Autowired private PlaceRepository placeRepository; @Autowired private EmployeeService employeeService; @Autowired private EmployeeRepository employeeRepository; @Override public Map findAvailableBookings(String employeeCode) { if (employeeCode == null || employeeCode.isEmpty()) { throw new IllegalArgumentException("Employee code cannot be null or empty"); } Employee employee = employeeService.getEmployeeByCode(employeeCode); if (employee == null) { throw new EmployeeNotFoundException("Employee not found with code: " + employeeCode); } LocalDate today = LocalDate.now(); LocalDate endDate = today.plusDays(3); List bookings = bookingRepository.findByDateBetween(today, endDate); List places = placeRepository.findAll(); Map>> result = new LinkedHashMap<>(); for (int i = 0; i <= 3; i++) { LocalDate date = today.plusDays(i); List> freePlaces = new ArrayList<>(); for (Place place : places) { boolean isBooked = bookings.stream() .anyMatch(b -> b.getDate().isEqual(date) && b.getPlace().getId() == place.getId()); if (!isBooked) { Map placeInfo = new LinkedHashMap<>(); placeInfo.put("id", place.getId()); placeInfo.put("place", place.getPlace()); freePlaces.add(placeInfo); } } result.put(date.toString(), freePlaces); } return Collections.unmodifiableMap(result); } public Map createBooking(String code, Long placeId, String date) { if (code == null || code.isBlank()) { throw new IllegalArgumentException("Employee code is empty"); } if (placeId == null || date == null || date.isBlank()) { throw new IllegalArgumentException("Place ID and date must be provided"); } Employee employee = employeeRepository.findByCode(code) .orElseThrow(() -> new EmployeeNotFoundException("Employee not found")); Place place = placeRepository.findById(placeId) .orElseThrow(() -> new IllegalArgumentException("Place not found")); LocalDate bookingDate; try { bookingDate = LocalDate.parse(date); } catch (Exception e) { throw new IllegalArgumentException("Invalid date format. Use yyyy-MM-dd"); } boolean exists = bookingRepository.findByDateBetween(bookingDate, bookingDate) .stream() .anyMatch(b -> b.getPlace().getId() == placeId); if (exists) { throw new IllegalArgumentException("Place already booked for this date"); } Booking booking = new Booking(); booking.setEmployee((Employee) employee); booking.setPlace(place); booking.setDate(bookingDate); bookingRepository.save(booking); Map result = new LinkedHashMap<>(); result.put("id", booking.getId()); result.put("date", booking.getDate()); result.put("placeId", place.getId()); result.put("employeeId", employee.getId()); return result; } }