diff --git a/src/main/java/com/example/nto/App.java b/src/main/java/com/example/nto/App.java index e453f89..e5435c1 100644 --- a/src/main/java/com/example/nto/App.java +++ b/src/main/java/com/example/nto/App.java @@ -1,12 +1,17 @@ package com.example.nto; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ +@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..5e7f79d 100644 --- a/src/main/java/com/example/nto/controller/EmployeeController.java +++ b/src/main/java/com/example/nto/controller/EmployeeController.java @@ -1,10 +1,33 @@ package com.example.nto.controller; +import com.example.nto.dto.EmployeeInfoWithBookingDto; +import com.example.nto.service.EmployeeService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") public class EmployeeController { + private final EmployeeService employeeService; + + @GetMapping("/{code}/auth") + void auth(@PathVariable("code") String code) { + employeeService.auth(code); + } + + @GetMapping("/{code}/info") + EmployeeInfoWithBookingDto info(@PathVariable("code") String code) { + return employeeService.info(code); + } } diff --git a/src/main/java/com/example/nto/dto/BookingRecordDto.java b/src/main/java/com/example/nto/dto/BookingRecordDto.java new file mode 100644 index 0000000..e0986a3 --- /dev/null +++ b/src/main/java/com/example/nto/dto/BookingRecordDto.java @@ -0,0 +1,14 @@ +package com.example.nto.dto; + +import com.example.nto.entity.Place; +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDate; + +@Data +@Builder +public class BookingRecordDto { + private long id; + private String place; +} diff --git a/src/main/java/com/example/nto/dto/BookingWithDateDto.java b/src/main/java/com/example/nto/dto/BookingWithDateDto.java new file mode 100644 index 0000000..ffd0085 --- /dev/null +++ b/src/main/java/com/example/nto/dto/BookingWithDateDto.java @@ -0,0 +1,18 @@ +package com.example.nto.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class BookingWithDateDto { + private LocalDate date; + private long id; + private String place; +} diff --git a/src/main/java/com/example/nto/dto/EmployeeInfoWithBookingDto.java b/src/main/java/com/example/nto/dto/EmployeeInfoWithBookingDto.java new file mode 100644 index 0000000..a56557e --- /dev/null +++ b/src/main/java/com/example/nto/dto/EmployeeInfoWithBookingDto.java @@ -0,0 +1,15 @@ +package com.example.nto.dto; + +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDate; +import java.util.Map; + +@Data +@Builder +public class EmployeeInfoWithBookingDto { + private String name; + private String photoUrl; + Map booking; +} diff --git a/src/main/java/com/example/nto/dto/EmployeeNameAndPhotoDto.java b/src/main/java/com/example/nto/dto/EmployeeNameAndPhotoDto.java new file mode 100644 index 0000000..17ceb4f --- /dev/null +++ b/src/main/java/com/example/nto/dto/EmployeeNameAndPhotoDto.java @@ -0,0 +1,11 @@ +package com.example.nto.dto; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class EmployeeNameAndPhotoDto { + private String name; + private String photoUrl; +} diff --git a/src/main/java/com/example/nto/dto/mapper/ListBookingWithDateDtoMapper.java b/src/main/java/com/example/nto/dto/mapper/ListBookingWithDateDtoMapper.java new file mode 100644 index 0000000..0b679b1 --- /dev/null +++ b/src/main/java/com/example/nto/dto/mapper/ListBookingWithDateDtoMapper.java @@ -0,0 +1,24 @@ +package com.example.nto.dto.mapper; + +import com.example.nto.dto.BookingRecordDto; +import com.example.nto.dto.BookingWithDateDto; +import lombok.experimental.UtilityClass; + +import java.time.LocalDate; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +@UtilityClass +public class ListBookingWithDateDtoMapper { + public static Map toMapLocalDateBookingRecordDto(List d) { + Map res = new TreeMap<>(); + d.forEach(bookingWithDate -> { + res.put(bookingWithDate.getDate(), BookingRecordDto.builder() + .id(bookingWithDate.getId()) + .place(bookingWithDate.getPlace()) + .build()); + }); + return res; + } +} diff --git a/src/main/java/com/example/nto/entity/Booking.java b/src/main/java/com/example/nto/entity/Booking.java index 21c1981..cf27b9d 100644 --- a/src/main/java/com/example/nto/entity/Booking.java +++ b/src/main/java/com/example/nto/entity/Booking.java @@ -1,8 +1,6 @@ package com.example.nto.entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -21,15 +19,25 @@ import java.time.LocalDate; @Builder @NoArgsConstructor @AllArgsConstructor +@Entity +@Table(name = "booking") public class Booking { - + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private long id; + @Column(name = "date") private LocalDate date; @ManyToOne(targetEntity = Place.class, fetch = FetchType.LAZY) @JoinColumn(name = "place_id") private Place place; + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn( + name = "employee_id", + referencedColumnName = "id" + ) private Employee employee; } diff --git a/src/main/java/com/example/nto/entity/Employee.java b/src/main/java/com/example/nto/entity/Employee.java index a52102b..673c739 100644 --- a/src/main/java/com/example/nto/entity/Employee.java +++ b/src/main/java/com/example/nto/entity/Employee.java @@ -19,14 +19,21 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor +@Entity +@Table(name = "employee") public class Employee { - + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") 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) diff --git a/src/main/java/com/example/nto/entity/Place.java b/src/main/java/com/example/nto/entity/Place.java index 00c253b..f8f7fe7 100644 --- a/src/main/java/com/example/nto/entity/Place.java +++ b/src/main/java/com/example/nto/entity/Place.java @@ -1,8 +1,6 @@ package com.example.nto.entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -19,11 +17,14 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor +@Entity +@Table(name = "place") public class Place { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private long id; + @Column(name = "place_name") private String place; } diff --git a/src/main/java/com/example/nto/exception/EmployeeNotFoundByCodeException.java b/src/main/java/com/example/nto/exception/EmployeeNotFoundByCodeException.java new file mode 100644 index 0000000..1791af1 --- /dev/null +++ b/src/main/java/com/example/nto/exception/EmployeeNotFoundByCodeException.java @@ -0,0 +1,7 @@ +package com.example.nto.exception; + +public class EmployeeNotFoundByCodeException extends RuntimeException { + public EmployeeNotFoundByCodeException(String message) { + super(message); + } +} diff --git a/src/main/java/com/example/nto/exception/GlobalExceptionHandler.java b/src/main/java/com/example/nto/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..ec69958 --- /dev/null +++ b/src/main/java/com/example/nto/exception/GlobalExceptionHandler.java @@ -0,0 +1,38 @@ +package com.example.nto.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler { + @ExceptionHandler(EmployeeNotFoundByCodeException.class) + ResponseEntity codeNotFoundExceptionHandler(EmployeeNotFoundByCodeException e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.UNAUTHORIZED); + } + /*@ExceptionHandler(CodeNotFoundException.class) + ResponseEntity codeNotFoundExceptionHandler(CodeNotFoundException e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(EmployeeNotFoundException.class) + ResponseEntity employeeNotFoundExceptionHandler(EmployeeNotFoundException e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.UNAUTHORIZED); + } + + @ExceptionHandler(EmployeeDataNotFoundException.class) + ResponseEntity employeeDataNotFoundExceptionHandler(EmployeeDataNotFoundException e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + @ExceptionHandler(EmployeeIsBlockedException.class) + ResponseEntity employeeIsBlockedExceptionHandler(EmployeeIsBlockedException e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.LOCKED); + } + + @ExceptionHandler(SelfChangeException.class) + ResponseEntity selfChangeExceptionHandler(SelfChangeException e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_ACCEPTABLE); + }*/ +} diff --git a/src/main/java/com/example/nto/repository/BookingRepository.java b/src/main/java/com/example/nto/repository/BookingRepository.java index 303bb54..04b2382 100644 --- a/src/main/java/com/example/nto/repository/BookingRepository.java +++ b/src/main/java/com/example/nto/repository/BookingRepository.java @@ -1,10 +1,22 @@ package com.example.nto.repository; +import com.example.nto.dto.BookingWithDateDto; +import com.example.nto.entity.Booking; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ -public interface BookingRepository { +@Repository +public interface BookingRepository extends JpaRepository { + @Query("select new com.example.nto.dto.BookingWithDateDto(b.date, b.id, b.place.place) from Booking b where b.employee.code = :code order by b.date") + List getBookingsByCode(@Param("code") String code); } diff --git a/src/main/java/com/example/nto/repository/EmployeeRepository.java b/src/main/java/com/example/nto/repository/EmployeeRepository.java index 210d29c..20370e1 100644 --- a/src/main/java/com/example/nto/repository/EmployeeRepository.java +++ b/src/main/java/com/example/nto/repository/EmployeeRepository.java @@ -1,10 +1,23 @@ package com.example.nto.repository; +import com.example.nto.dto.EmployeeNameAndPhotoDto; +import com.example.nto.entity.Employee; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ -public interface EmployeeRepository { +@Repository +public interface EmployeeRepository extends JpaRepository { + @Query("select count(e) > 0 from Employee e where e.code = :code") + boolean isExist(@Param("code") String code); + + @Query("select e.name, e.photoUrl from Employee e where e.code = :code") + EmployeeNameAndPhotoDto getNameAndPhoto(@Param("code") String code); } diff --git a/src/main/java/com/example/nto/service/EmployeeService.java b/src/main/java/com/example/nto/service/EmployeeService.java index cccd209..1eb38e7 100644 --- a/src/main/java/com/example/nto/service/EmployeeService.java +++ b/src/main/java/com/example/nto/service/EmployeeService.java @@ -1,5 +1,7 @@ package com.example.nto.service; +import com.example.nto.dto.EmployeeInfoWithBookingDto; + /** * TODO: ДОРАБОТАТЬ в рамках задания * ================================= @@ -7,4 +9,6 @@ package com.example.nto.service; * НЕЛЬЗЯ: Изменять название класса и пакета */ public interface EmployeeService { + void auth(String code); + EmployeeInfoWithBookingDto info(String code); } 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..8e91e17 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,15 @@ package com.example.nto.service.impl; +import com.example.nto.dto.EmployeeInfoWithBookingDto; +import com.example.nto.dto.EmployeeNameAndPhotoDto; +import com.example.nto.exception.EmployeeNotFoundByCodeException; +import com.example.nto.repository.BookingRepository; +import com.example.nto.repository.EmployeeRepository; import com.example.nto.service.EmployeeService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import static com.example.nto.dto.mapper.ListBookingWithDateDtoMapper.toMapLocalDateBookingRecordDto; /** * TODO: ДОРАБОТАТЬ в рамках задания @@ -8,5 +17,31 @@ import com.example.nto.service.EmployeeService; * МОЖНО: Добавлять методы, аннотации, зависимости * НЕЛЬЗЯ: Изменять название класса и пакета */ +@Service +@RequiredArgsConstructor public class EmployeeServiceImpl implements EmployeeService { + private final EmployeeRepository employeeRepository; + private final BookingRepository bookingRepository; + + @Override + public void auth(String code) { + if (!employeeRepository.isExist(code)) { + throw new EmployeeNotFoundByCodeException("employee with code " + code + " not found"); + } + } + + @Override + public EmployeeInfoWithBookingDto info(String code) { + if (!employeeRepository.isExist(code)) { + throw new EmployeeNotFoundByCodeException("employee with code " + code + " not found"); + } + + EmployeeNameAndPhotoDto nameAndPhoto = employeeRepository.getNameAndPhoto(code); + + return EmployeeInfoWithBookingDto.builder() + .name(nameAndPhoto.getName()) + .photoUrl(nameAndPhoto.getPhotoUrl()) + .booking(toMapLocalDateBookingRecordDto(bookingRepository.getBookingsByCode(code))) + .build(); + } }