diff --git a/src/main/java/com/example/nto/App.java b/src/main/java/com/example/nto/App.java index e453f89..d4add94 100644 --- a/src/main/java/com/example/nto/App.java +++ b/src/main/java/com/example/nto/App.java @@ -1,12 +1,11 @@ package com.example.nto; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication public class App { public static void main(String[] args) { + SpringApplication.run(App.class, args); } } diff --git a/src/main/java/com/example/nto/controller/EmployeeController.java b/src/main/java/com/example/nto/controller/EmployeeController.java index 47658f9..fb14c65 100644 --- a/src/main/java/com/example/nto/controller/EmployeeController.java +++ b/src/main/java/com/example/nto/controller/EmployeeController.java @@ -1,10 +1,70 @@ package com.example.nto.controller; +import com.example.nto.dto.BookingInfoRequestDto; +import com.example.nto.dto.EmployeeDto; +import com.example.nto.dto.converter.BookingInfoRequestDtoConverter; +import com.example.nto.dto.converter.EmployeeDtoConverter; +import com.example.nto.entity.*; +import com.example.nto.service.EmployeeService; +import jakarta.validation.Valid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ +@RestController public class EmployeeController { + @Autowired + private EmployeeService employeeService; + + @GetMapping("api/{code}/auth") + @ResponseStatus(HttpStatus.OK) + public ResponseEntity CheckAutorization(@PathVariable String code) { + if (employeeService.CheckAuthorization(code)) + return new ResponseEntity<>("данный код существует - можно пользоваться приложением", HttpStatus.OK); + else + return new ResponseEntity<>("кода не существует", HttpStatus.UNAUTHORIZED); + } + + @GetMapping("/api/{code}/info") + @ResponseStatus(HttpStatus.OK) + public ResponseEntity FindEmployee(@PathVariable String code) { + EmployeeInfo employee = employeeService.GetEmployee(code); + //EmployeeDtoConverter.ToDto(employee) + if (employee != null) + return new ResponseEntity<>(employee, HttpStatus.OK); + else + return new ResponseEntity<>("кода не существует", HttpStatus.UNAUTHORIZED); + } + + @GetMapping("/api/{code}/allbookings") + @ResponseStatus(HttpStatus.OK) + public Map GetAllBookings(@PathVariable String code) { + return employeeService.GetAllBookings(code); + } + + @GetMapping("/api/{code}/booking") + @ResponseStatus(HttpStatus.OK) + public ResponseEntity GetFreeBookings(@PathVariable String code) { + Map> freeBookings = employeeService.GetFreeBookings(code); + if (freeBookings != null) + return new ResponseEntity<>(freeBookings, HttpStatus.OK); + else + return new ResponseEntity<>("кода не существует", HttpStatus.UNAUTHORIZED); + } + + @PostMapping("/api/{code}/book") + public ResponseEntity SetNewBooking(@PathVariable String code, + @RequestBody BookingInfoRequestDto bookingInfo) { + return employeeService.SetNewBooking(code, BookingInfoRequestDtoConverter.ToEntity(bookingInfo)); + } } diff --git a/src/main/java/com/example/nto/dto/BookingInfoRequestDto.java b/src/main/java/com/example/nto/dto/BookingInfoRequestDto.java new file mode 100644 index 0000000..bb4a6ce --- /dev/null +++ b/src/main/java/com/example/nto/dto/BookingInfoRequestDto.java @@ -0,0 +1,21 @@ +package com.example.nto.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class BookingInfoRequestDto { + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate date; + + private long placeID; +} diff --git a/src/main/java/com/example/nto/dto/EmployeeDto.java b/src/main/java/com/example/nto/dto/EmployeeDto.java new file mode 100644 index 0000000..ce47bdf --- /dev/null +++ b/src/main/java/com/example/nto/dto/EmployeeDto.java @@ -0,0 +1,17 @@ +package com.example.nto.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Set; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class EmployeeDto { + private String name; + private String photoUrl; +} diff --git a/src/main/java/com/example/nto/dto/converter/BookingInfoRequestDtoConverter.java b/src/main/java/com/example/nto/dto/converter/BookingInfoRequestDtoConverter.java new file mode 100644 index 0000000..80387dc --- /dev/null +++ b/src/main/java/com/example/nto/dto/converter/BookingInfoRequestDtoConverter.java @@ -0,0 +1,22 @@ +package com.example.nto.dto.converter; + +import com.example.nto.dto.BookingInfoRequestDto; +import com.example.nto.entity.BookingInfo; +import lombok.experimental.UtilityClass; + +@UtilityClass +public class BookingInfoRequestDtoConverter { + public BookingInfo ToEntity(BookingInfoRequestDto dto) { + return BookingInfo.builder() + .date(dto.getDate()) + .placeId(dto.getPlaceID()) + .build(); + } + + public BookingInfoRequestDto ToDto(BookingInfo entity) { + return BookingInfoRequestDto.builder() + .date(entity.getDate()) + .placeID(entity.getPlaceId()) + .build(); + } +} diff --git a/src/main/java/com/example/nto/dto/converter/EmployeeDtoConverter.java b/src/main/java/com/example/nto/dto/converter/EmployeeDtoConverter.java new file mode 100644 index 0000000..fdea39e --- /dev/null +++ b/src/main/java/com/example/nto/dto/converter/EmployeeDtoConverter.java @@ -0,0 +1,19 @@ +package com.example.nto.dto.converter; + +import com.example.nto.dto.EmployeeDto; +import com.example.nto.entity.Employee; +import lombok.experimental.UtilityClass; + +import java.util.stream.Collectors; + +@UtilityClass +public class EmployeeDtoConverter { + + public EmployeeDto ToDto(Employee entity) { + return EmployeeDto.builder() + .name(entity.getName()) + .photoUrl(entity.getPhotoUrl()) + //.booking(entity.getBooking().stream().map(DateBookingsDtoConverter::ToDto).collect(Collectors.toSet())) + .build(); + } +} diff --git a/src/main/java/com/example/nto/entity/Booking.java b/src/main/java/com/example/nto/entity/Booking.java index 21c1981..1524f15 100644 --- a/src/main/java/com/example/nto/entity/Booking.java +++ b/src/main/java/com/example/nto/entity/Booking.java @@ -1,12 +1,8 @@ package com.example.nto.entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import lombok.*; import java.time.LocalDate; @@ -21,15 +17,24 @@ import java.time.LocalDate; @Builder @NoArgsConstructor @AllArgsConstructor +@Entity +@Table(name = "booking") +@EqualsAndHashCode(exclude = {"employee", "place"}) public class Booking { - + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; + @Column(name = "date") private LocalDate date; @ManyToOne(targetEntity = Place.class, fetch = FetchType.LAZY) @JoinColumn(name = "place_id") + @JsonIgnore private Place place; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "employee_id", nullable = false) + @JsonIgnore private Employee employee; } diff --git a/src/main/java/com/example/nto/entity/BookingInfo.java b/src/main/java/com/example/nto/entity/BookingInfo.java new file mode 100644 index 0000000..59fd1c4 --- /dev/null +++ b/src/main/java/com/example/nto/entity/BookingInfo.java @@ -0,0 +1,19 @@ +package com.example.nto.entity; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class BookingInfo { + @JsonFormat(pattern = "yyyy-MM-dd") + public LocalDate date; + public long placeId; +} diff --git a/src/main/java/com/example/nto/entity/Employee.java b/src/main/java/com/example/nto/entity/Employee.java index a52102b..72d49d6 100644 --- a/src/main/java/com/example/nto/entity/Employee.java +++ b/src/main/java/com/example/nto/entity/Employee.java @@ -1,12 +1,16 @@ package com.example.nto.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** @@ -19,16 +23,23 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor +@Entity +@Table(name = "employee") public class Employee { - + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; + @Column(name = "name") private String name; + @Column(name = "code") private String code; + @Column(name = "photo_url") private String photoUrl; @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private List bookingList; + @JsonIgnore + private List bookingList = new ArrayList<>();; } diff --git a/src/main/java/com/example/nto/entity/EmployeeInfo.java b/src/main/java/com/example/nto/entity/EmployeeInfo.java new file mode 100644 index 0000000..f53a878 --- /dev/null +++ b/src/main/java/com/example/nto/entity/EmployeeInfo.java @@ -0,0 +1,19 @@ +package com.example.nto.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class EmployeeInfo { + public String name; + public String photoUrl; + public Map booking = new HashMap<>(); +} diff --git a/src/main/java/com/example/nto/entity/Place.java b/src/main/java/com/example/nto/entity/Place.java index 00c253b..6ab9c70 100644 --- a/src/main/java/com/example/nto/entity/Place.java +++ b/src/main/java/com/example/nto/entity/Place.java @@ -1,12 +1,7 @@ package com.example.nto.entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import jakarta.persistence.*; +import lombok.*; /** @@ -19,11 +14,13 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor +@Entity +@Table(name = "place") public class Place { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; + @Column(name = "place_name") private String place; } diff --git a/src/main/java/com/example/nto/exceptions/NoSuchEmployeeException.java b/src/main/java/com/example/nto/exceptions/NoSuchEmployeeException.java new file mode 100644 index 0000000..c6dcc10 --- /dev/null +++ b/src/main/java/com/example/nto/exceptions/NoSuchEmployeeException.java @@ -0,0 +1,7 @@ +package com.example.nto.exceptions; + +public class NoSuchEmployeeException extends RuntimeException{ + public NoSuchEmployeeException(String message) { + super(message); + } +} diff --git a/src/main/java/com/example/nto/repository/BookingRepository.java b/src/main/java/com/example/nto/repository/BookingRepository.java index 303bb54..0eb71da 100644 --- a/src/main/java/com/example/nto/repository/BookingRepository.java +++ b/src/main/java/com/example/nto/repository/BookingRepository.java @@ -1,10 +1,16 @@ package com.example.nto.repository; +import com.example.nto.entity.Booking; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.time.LocalDate; +import java.util.Optional; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ -public interface BookingRepository { +public interface BookingRepository extends JpaRepository { } diff --git a/src/main/java/com/example/nto/repository/EmployeeRepository.java b/src/main/java/com/example/nto/repository/EmployeeRepository.java index 210d29c..ad05255 100644 --- a/src/main/java/com/example/nto/repository/EmployeeRepository.java +++ b/src/main/java/com/example/nto/repository/EmployeeRepository.java @@ -1,10 +1,17 @@ package com.example.nto.repository; +import com.example.nto.entity.Employee; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ -public interface EmployeeRepository { + +public interface EmployeeRepository extends JpaRepository { + Optional findByCode(String code); } diff --git a/src/main/java/com/example/nto/repository/PlaceRepository.java b/src/main/java/com/example/nto/repository/PlaceRepository.java index d3bea1d..aff1a7c 100644 --- a/src/main/java/com/example/nto/repository/PlaceRepository.java +++ b/src/main/java/com/example/nto/repository/PlaceRepository.java @@ -1,10 +1,13 @@ package com.example.nto.repository; +import com.example.nto.entity.Place; +import org.springframework.data.jpa.repository.JpaRepository; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ -public interface PlaceRepository { +public interface PlaceRepository extends JpaRepository { } diff --git a/src/main/java/com/example/nto/service/EmployeeService.java b/src/main/java/com/example/nto/service/EmployeeService.java index cccd209..f76335c 100644 --- a/src/main/java/com/example/nto/service/EmployeeService.java +++ b/src/main/java/com/example/nto/service/EmployeeService.java @@ -1,10 +1,23 @@ package com.example.nto.service; +import com.example.nto.dto.EmployeeDto; +import com.example.nto.entity.*; +import org.springframework.http.ResponseEntity; + +import java.util.List; +import java.util.Map; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ + public interface EmployeeService { + boolean CheckAuthorization(String code); + EmployeeInfo GetEmployee(String code); + Map GetAllBookings(String code); + Map> GetFreeBookings(String code); + ResponseEntity SetNewBooking(String code, BookingInfo booking); } diff --git a/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java b/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java index f8125e5..7dd7638 100644 --- a/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java +++ b/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java @@ -1,6 +1,17 @@ package com.example.nto.service.impl; +import com.example.nto.entity.*; +import com.example.nto.repository.BookingRepository; +import com.example.nto.repository.EmployeeRepository; +import com.example.nto.repository.PlaceRepository; import com.example.nto.service.EmployeeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.util.*; /** * TODO: ДОРАБОТАТЬ в рамках задания @@ -8,5 +19,102 @@ import com.example.nto.service.EmployeeService; * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ + +@Service public class EmployeeServiceImpl implements EmployeeService { -} + private final EmployeeRepository employeeRepository; + private final BookingRepository bookingRepository; + private final PlaceRepository placeRepository; + + @Autowired + public EmployeeServiceImpl(EmployeeRepository employeeRepositoryToCath, PlaceRepository placeRepositoryToCatch, BookingRepository bookingRepositoryToCatch) { + employeeRepository = employeeRepositoryToCath; + placeRepository = placeRepositoryToCatch; + bookingRepository = bookingRepositoryToCatch; + } + + @Override + public boolean CheckAuthorization(String code) { + List allEmployees = employeeRepository.findAll(); + for (int i = 0; i < allEmployees.size(); i++) { + if (allEmployees.get(i).getCode().equals(code)) + return true; + } + return false; + } + + @Override + public EmployeeInfo GetEmployee(String code) { + List allEmployees = employeeRepository.findAll(); + for (int i = 0; i < allEmployees.size(); i++) { + if (allEmployees.get(i).getCode().equals(code)) { + Employee selectedEmployee = allEmployees.get(i); + Map bookings = GetAllBookings(code); + return new EmployeeInfo(selectedEmployee.getName(), selectedEmployee.getPhotoUrl(), bookings); + } + } + return null; + } + + @Override + public Map GetAllBookings(String code) { + List allBookings = bookingRepository.findAll(); + Map formatedBookings = new HashMap<>(); + for (int i = 0; i < allBookings.size(); i++) { + if (allBookings.get(i).getEmployee().getCode().equals(code)) { + Place bookedPlace = allBookings.get(i).getPlace(); + formatedBookings.put(allBookings.get(i).getDate().toString(), new Place(bookedPlace.getId(), bookedPlace.getPlace())); + } + } + return formatedBookings; + } + + @Override + public Map> GetFreeBookings(String code) { + if (!CheckAuthorization(code)) + return null; + + Map> freeBookings = new HashMap<>(); + List allPlaces = placeRepository.findAll(); + List allBookings = bookingRepository.findAll(); + LocalDate today = LocalDate.now(); + for (int i = 0; i < 4; i++) { + LocalDate currentDate = today.plusDays(i); + List currentDateFreePlaces = new ArrayList<>(); + boolean[] placeBooked = new boolean[allPlaces.size()]; + for (int j = 0; j < allBookings.size(); j++) { + if (allBookings.get(j).getDate().toString().equals(currentDate.toString())) + placeBooked[Math.toIntExact(allBookings.get(j).getPlace().getId() - 1)] = true; + } + for (int j = 0; j < allPlaces.size(); j++) { + if (!placeBooked[j]) { + currentDateFreePlaces.add(new Place(allPlaces.get(j).getId(), allPlaces.get(j).getPlace())); + } + } + freeBookings.put(currentDate.toString(), currentDateFreePlaces); + } + return freeBookings; + } + + @Override + public ResponseEntity SetNewBooking(String code, BookingInfo bookingInfo) { + if (!CheckAuthorization(code)) + return new ResponseEntity<>("кода не существует", HttpStatus.UNAUTHORIZED); + + Map> freePlacesMap = GetFreeBookings(code); + if (!freePlacesMap.containsKey(bookingInfo.date.toString())) + return new ResponseEntity<>("что-то пошло не так", HttpStatus.BAD_REQUEST); + List freePlaces = freePlacesMap.get(bookingInfo.date.toString()); + for (int i = 0; i < freePlaces.size(); i++) { + if (freePlaces.get(i).getId() == bookingInfo.placeId) { + bookingRepository.save(Booking.builder() + .date(bookingInfo.date) + .place(freePlaces.get(i)) + .employee(employeeRepository.findByCode(code).get()) + .build()); + return new ResponseEntity<>("бронирование успешно создано", HttpStatus.CREATED); + } + } + return new ResponseEntity<>("уже забронировано", HttpStatus.CONFLICT); + } +} \ No newline at end of file