This commit is contained in:
indx0
2025-11-21 21:05:27 +03:00
parent be8818b71f
commit a612c92833
14 changed files with 187 additions and 22 deletions

View File

@@ -1,12 +1,19 @@
package com.example.nto; package com.example.nto;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * FINISHED_TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
*/ */
@SpringBootApplication
public class App { public class App {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(App.class, args);
} }
} }

View File

@@ -1,10 +1,51 @@
package com.example.nto.controller; package com.example.nto.controller;
import com.example.nto.dto.EmployeeDTO;
import com.example.nto.entity.Employee;
import com.example.nto.exception.CodeNotFoundException;
import com.example.nto.repository.EmployeeRepository;
import com.example.nto.service.EmployeeService;
import com.example.nto.util.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
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: ДОРАБОТАТЬ в рамках задания * TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
*/ */
@RestController()
@RequestMapping("/api")
public class EmployeeController { public class EmployeeController {
@Autowired
EmployeeService employeeService;
@GetMapping("/{code}/auth")
public ResponseEntity<Void> auth(@PathVariable String code) {
boolean codeExists = employeeService.codeExists(code);
if(codeExists) {
return ResponseEntity.ok().build();
}
else {
throw new CodeNotFoundException("Code Does Not Exist");
}
}
@GetMapping("/{code}/info")
public ResponseEntity<EmployeeDTO> info(@PathVariable String code) {
boolean codeExists = employeeService.codeExists(code);
if(codeExists) {
return ResponseEntity.ok(employeeService.getInfo(code));
}
else {
throw new CodeNotFoundException("Code Does Not Exist");
}
}
} }

View File

@@ -0,0 +1,17 @@
package com.example.nto.dto;
import com.example.nto.entity.Booking;
import com.example.nto.entity.Place;
import lombok.Data;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
@Data
public class EmployeeDTO {
private String name;
private String photoUrl;
private Map<LocalDate, Place> booking;
}

View File

@@ -1,18 +1,13 @@
package com.example.nto.entity; package com.example.nto.entity;
import jakarta.persistence.FetchType; import jakarta.persistence.*;
import jakarta.persistence.JoinColumn; import lombok.*;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate; import java.time.LocalDate;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * FINISHED_TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
@@ -21,15 +16,22 @@ import java.time.LocalDate;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Entity
@ToString(exclude = {"employee", "place"})
public class Booking { public class Booking {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id; private long id;
@Column(name = "date", nullable = false)
private LocalDate date; private LocalDate date;
@ManyToOne(targetEntity = Place.class, fetch = FetchType.LAZY) @ManyToOne(targetEntity = Place.class, fetch = FetchType.LAZY)
@JoinColumn(name = "place_id") @JoinColumn(name = "place_id", nullable = false)
private Place place; private Place place;
@ManyToOne(targetEntity = Employee.class, fetch = FetchType.LAZY)
@JoinColumn(name = "employee_id", nullable = false)
private Employee employee; private Employee employee;
} }

View File

@@ -10,7 +10,7 @@ import java.util.List;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * FINISHED_TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
@@ -19,16 +19,22 @@ import java.util.List;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Entity
public class Employee { public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id; private long id;
@Column(name = "name", nullable = false)
private String name; private String name;
@Column(name = "code", nullable = false, unique = true)
private String code; private String code;
@Column(name = "photo_url")
private String photoUrl; private String photoUrl;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Booking> bookingList; private List<Booking> booking;
} }

View File

@@ -1,8 +1,6 @@
package com.example.nto.entity; package com.example.nto.entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.*;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@@ -10,7 +8,7 @@ import lombok.NoArgsConstructor;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * FINISHED_TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
@@ -19,11 +17,13 @@ import lombok.NoArgsConstructor;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Entity
public class Place { public class Place {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private long id; private long id;
@Column(name = "place_name", nullable = false, unique = true)
private String place; private String place;
} }

View File

@@ -0,0 +1,7 @@
package com.example.nto.exception;
public class CodeNotFoundException extends RuntimeException {
public CodeNotFoundException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,15 @@
package com.example.nto.exception.handler;
import com.example.nto.exception.CodeNotFoundException;
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(CodeNotFoundException.class)
public ResponseEntity<Void> handleCodeNotFoundException(CodeNotFoundException e) {
return new ResponseEntity<Void>(HttpStatus.UNAUTHORIZED);
}
}

View File

@@ -1,10 +1,13 @@
package com.example.nto.repository; package com.example.nto.repository;
import com.example.nto.entity.Booking;
import org.springframework.data.jpa.repository.JpaRepository;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * FINISHED_TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
*/ */
public interface BookingRepository { public interface BookingRepository extends JpaRepository<Booking, Long> {
} }

View File

@@ -1,10 +1,15 @@
package com.example.nto.repository; package com.example.nto.repository;
import com.example.nto.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * FINISHED_TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
*/ */
public interface EmployeeRepository { public interface EmployeeRepository extends JpaRepository<Employee, Long> {
public boolean existsByCode(String code);
public Employee findByCode(String code);
} }

View File

@@ -1,10 +1,13 @@
package com.example.nto.repository; package com.example.nto.repository;
import com.example.nto.entity.Place;
import org.springframework.data.jpa.repository.JpaRepository;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * FINISHED_TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
*/ */
public interface PlaceRepository { public interface PlaceRepository extends JpaRepository<Place, Long> {
} }

View File

@@ -1,5 +1,7 @@
package com.example.nto.service; package com.example.nto.service;
import com.example.nto.dto.EmployeeDTO;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * TODO: ДОРАБОТАТЬ в рамках задания
* ================================= * =================================
@@ -7,4 +9,6 @@ package com.example.nto.service;
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
*/ */
public interface EmployeeService { public interface EmployeeService {
public boolean codeExists(String code);
public EmployeeDTO getInfo(String code);
} }

View File

@@ -1,6 +1,12 @@
package com.example.nto.service.impl; package com.example.nto.service.impl;
import com.example.nto.dto.EmployeeDTO;
import com.example.nto.entity.Employee;
import com.example.nto.repository.EmployeeRepository;
import com.example.nto.service.EmployeeService; import com.example.nto.service.EmployeeService;
import com.example.nto.util.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/** /**
* TODO: ДОРАБОТАТЬ в рамках задания * TODO: ДОРАБОТАТЬ в рамках задания
@@ -8,5 +14,20 @@ import com.example.nto.service.EmployeeService;
* МОЖНО: Добавлять методы, аннотации, зависимости * МОЖНО: Добавлять методы, аннотации, зависимости
* НЕЛЬЗЯ: Изменять название класса и пакета * НЕЛЬЗЯ: Изменять название класса и пакета
*/ */
@Service
public class EmployeeServiceImpl implements EmployeeService { public class EmployeeServiceImpl implements EmployeeService {
@Autowired
EmployeeRepository employeeRepository;
@Override
public boolean codeExists(String code) {
boolean codeExists = employeeRepository.existsByCode(code);
return codeExists;
}
@Override
public EmployeeDTO getInfo(String code) {
Employee employee = employeeRepository.findByCode(code);
return EmployeeMapper.convertToDTO(employee);
}
} }

View File

@@ -0,0 +1,34 @@
package com.example.nto.util;
import com.example.nto.dto.EmployeeDTO;
import com.example.nto.entity.Booking;
import com.example.nto.entity.Employee;
import com.example.nto.entity.Place;
import lombok.experimental.UtilityClass;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;
@UtilityClass
public class EmployeeMapper {
public static EmployeeDTO convertToDTO(Employee employee) {
EmployeeDTO employeeDto = new EmployeeDTO();
employeeDto.setName(employee.getName());
employeeDto.setPhotoUrl(employee.getPhotoUrl());
Map<LocalDate, Place> bookingMap = employee.getBooking()
.stream()
.collect(Collectors.toMap(
Booking::getDate,
b -> Place.builder()
.id(b.getPlace().getId())
.place(b.getPlace().getPlace())
.build()
));
employeeDto.setBooking(bookingMap);
return employeeDto;
}
}