From d5564b63eb9319d0865abeb79d6170099cf865df Mon Sep 17 00:00:00 2001 From: gordei Date: Sat, 29 Nov 2025 15:31:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20Ba?= =?UTF-8?q?ckend=20=D0=BD=D1=82=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/nto/App.java | 11 +- .../nto/controller/BookingController.java | 135 +++++++++++++++++- .../nto/controller/EmployeeController.java | 29 +++- .../java/com/example/nto/entity/Booking.java | 48 ++++--- .../java/com/example/nto/entity/Employee.java | 47 +++--- .../java/com/example/nto/entity/Place.java | 55 ++++--- .../nto/repository/BookingRepository.java | 20 ++- .../nto/repository/EmployeeRepository.java | 13 +- .../nto/repository/PlaceRepository.java | 11 +- .../example/nto/service/BookingService.java | 18 ++- .../example/nto/service/EmployeeService.java | 10 +- .../com/example/nto/service/PlaceService.java | 10 ++ .../nto/service/impl/BookingServiceImpl.java | 46 +++++- .../nto/service/impl/EmployeeServiceImpl.java | 22 ++- .../nto/service/impl/PlaceServiceImpl.java | 29 ++++ 15 files changed, 385 insertions(+), 119 deletions(-) create mode 100644 src/main/java/com/example/nto/service/PlaceService.java create mode 100644 src/main/java/com/example/nto/service/impl/PlaceServiceImpl.java 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/BookingController.java b/src/main/java/com/example/nto/controller/BookingController.java index 9885f84..579606f 100644 --- a/src/main/java/com/example/nto/controller/BookingController.java +++ b/src/main/java/com/example/nto/controller/BookingController.java @@ -1,10 +1,133 @@ package com.example.nto.controller; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ +import com.example.nto.entity.Booking; +import com.example.nto.entity.Employee; +import com.example.nto.entity.Place; +import com.example.nto.service.BookingService; +import com.example.nto.service.EmployeeService; +import com.example.nto.service.PlaceService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.util.*; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/api/{code}") public class BookingController { + + private final EmployeeService employeeService; + private final BookingService bookingService; + private final PlaceService placeService; + + public BookingController(EmployeeService employeeService, BookingService bookingService, PlaceService placeService) { + this.employeeService = employeeService; + this.bookingService = bookingService; + this.placeService = placeService; + } + + @GetMapping("/auth") + public ResponseEntity auth(@PathVariable String code) { + Optional employeeOpt = employeeService.findByCode(code); + if (employeeOpt.isPresent()) { + return ResponseEntity.ok().build(); + } else { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } + + + + + @GetMapping("/info") + public ResponseEntity> info(@PathVariable String code) { + Optional employeeOpt = employeeService.findByCode(code); + if (employeeOpt.isEmpty()) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + + Employee employee = employeeOpt.get(); + + Map response = new HashMap<>(); + response.put("name", employee.getName()); + response.put("photoUrl", employee.getPhotoUrl()); + + Map>> bookingsMap = new HashMap<>(); + List bookingList = bookingService.getBookingsByEmployee(employee); + + for (Booking b : bookingList) { + String dateKey = b.getDate().toString(); + Map bookingData = new HashMap<>(); + bookingData.put("id", b.getId()); + bookingData.put("place", b.getPlace().getPlace()); + + bookingsMap.computeIfAbsent(dateKey, k -> new ArrayList<>()).add(bookingData); + } + + response.put("booking", bookingsMap); + + return ResponseEntity.ok(response); + } + + @GetMapping("/booking") + public ResponseEntity>>> availableBooking(@PathVariable String code) { + Optional employeeOpt = employeeService.findByCode(code); + if (employeeOpt.isEmpty()) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + + Map>> result = new LinkedHashMap<>(); + LocalDate today = LocalDate.now(); + List allPlaces = placeService.getAllPlaces(); + + for (int i = 0; i < 4; i++) { + LocalDate date = today.plusDays(i); + List bookings = bookingService.getBookingsByDate(date); + + Set bookedPlaceIds = bookings.stream() + .map(b -> b.getPlace().getId()) + .collect(Collectors.toSet()); + + List> available = allPlaces.stream() + .filter(p -> !bookedPlaceIds.contains(p.getId())) + .map(p -> { + Map m = new HashMap<>(); + m.put("id", p.getId()); + m.put("place", p.getPlace()); + return m; + }) + .collect(Collectors.toList()); + + result.put(date.toString(), available); + } + + return ResponseEntity.ok(result); + } + + + @PostMapping("/book") + public ResponseEntity book(@PathVariable String code, @RequestBody Map body) { + Optional employeeOpt = employeeService.findByCode(code); + if (employeeOpt.isEmpty()) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + Employee employee = employeeOpt.get(); + + try { + String dateStr = body.get("date"); + String placeIdStr = body.get("placeID"); + if (dateStr == null || placeIdStr == null) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); + } + + LocalDate date = LocalDate.parse(dateStr); + Long placeId = Long.parseLong(placeIdStr); + Place place = placeService.getPlaceById(placeId); + + if (bookingService.getBookingByDateAndPlace(date, place).isPresent()) { + return ResponseEntity.status(HttpStatus.CONFLICT).build(); + } + + bookingService.createBooking(employee, place, date); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); + } + } } diff --git a/src/main/java/com/example/nto/controller/EmployeeController.java b/src/main/java/com/example/nto/controller/EmployeeController.java index 47658f9..4763ec3 100644 --- a/src/main/java/com/example/nto/controller/EmployeeController.java +++ b/src/main/java/com/example/nto/controller/EmployeeController.java @@ -1,10 +1,27 @@ package com.example.nto.controller; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ +import com.example.nto.entity.Employee; +import com.example.nto.service.EmployeeService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; + +@RestController +@RequestMapping("/api/employee") public class EmployeeController { + + private final EmployeeService employeeService; + + public EmployeeController(EmployeeService employeeService) { + this.employeeService = employeeService; + } + + @GetMapping("/{code}") + public ResponseEntity getEmployeeByCode(@PathVariable String code) { + Optional employeeOpt = employeeService.findByCode(code); + return employeeOpt.map(ResponseEntity::ok) + .orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND).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..28f33f3 100644 --- a/src/main/java/com/example/nto/entity/Booking.java +++ b/src/main/java/com/example/nto/entity/Booking.java @@ -1,35 +1,43 @@ 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 jakarta.persistence.*; import java.time.LocalDate; - -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor +@Entity +@Table(name = "booking") public class Booking { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private LocalDate date; - @ManyToOne(targetEntity = Place.class, fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "place_id") private Place place; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "employee_id") private Employee employee; + + public Booking() {} + + public Booking(Employee employee, Place place, LocalDate date) { + this.employee = employee; + this.place = place; + this.date = date; + } + + public long getId() { return id; } + public void setId(long id) { this.id = id; } + + public LocalDate getDate() { return date; } + public void setDate(LocalDate date) { this.date = date; } + + public Place getPlace() { return place; } + public void setPlace(Place place) { this.place = place; } + + public Employee getEmployee() { return employee; } + public void setEmployee(Employee employee) { this.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..4f1034f 100644 --- a/src/main/java/com/example/nto/entity/Employee.java +++ b/src/main/java/com/example/nto/entity/Employee.java @@ -1,34 +1,47 @@ package com.example.nto.entity; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - +import java.util.ArrayList; import java.util.List; - -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor +@Entity +@Table(name = "employee") public class Employee { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private String name; + @Column(unique = true) private String code; private String photoUrl; @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private List bookingList; + private List bookingList = new ArrayList<>(); + + public Employee() {} + + public Employee(String name, String code, String photoUrl) { + this.name = name; + this.code = code; + this.photoUrl = photoUrl; + } + + public long getId() { return id; } + public void setId(long id) { this.id = id; } + + public String getName() { return name; } + public void setName(String name) { this.name = name; } + + public String getCode() { return code; } + public void setCode(String code) { this.code = code; } + + public String getPhotoUrl() { return photoUrl; } + public void setPhotoUrl(String photoUrl) { this.photoUrl = photoUrl; } + + public List getBookingList() { return bookingList; } + public void setBookingList(List bookingList) { this.bookingList = bookingList; } } diff --git a/src/main/java/com/example/nto/entity/Place.java b/src/main/java/com/example/nto/entity/Place.java index 00c253b..d88b10b 100644 --- a/src/main/java/com/example/nto/entity/Place.java +++ b/src/main/java/com/example/nto/entity/Place.java @@ -1,29 +1,46 @@ 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.*; - -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor +@Entity +@Table(name = "place") public class Place { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private long id; + private Long id; + @Column(name = "place_name", nullable = false, unique = true) private String place; + + public Place() { + } + + public Place(String place) { + this.place = place; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getPlace() { + return place; + } + + public void setPlace(String place) { + this.place = place; + } + + @Override + public String toString() { + return "Place{" + + "id=" + id + + ", place='" + place + '\'' + + '}'; + } } diff --git a/src/main/java/com/example/nto/repository/BookingRepository.java b/src/main/java/com/example/nto/repository/BookingRepository.java index 303bb54..54291a7 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; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ -public interface BookingRepository { +import com.example.nto.entity.Booking; +import com.example.nto.entity.Employee; +import com.example.nto.entity.Place; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +public interface BookingRepository extends JpaRepository { + List findByEmployee(Employee employee); + List findByDate(LocalDate date); + Optional findByDateAndPlace(LocalDate date, Place place); } diff --git a/src/main/java/com/example/nto/repository/EmployeeRepository.java b/src/main/java/com/example/nto/repository/EmployeeRepository.java index 210d29c..1a4f77a 100644 --- a/src/main/java/com/example/nto/repository/EmployeeRepository.java +++ b/src/main/java/com/example/nto/repository/EmployeeRepository.java @@ -1,10 +1,9 @@ package com.example.nto.repository; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ -public interface EmployeeRepository { +import com.example.nto.entity.Employee; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + +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..e7b84c9 100644 --- a/src/main/java/com/example/nto/repository/PlaceRepository.java +++ b/src/main/java/com/example/nto/repository/PlaceRepository.java @@ -1,10 +1,7 @@ package com.example.nto.repository; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ -public interface PlaceRepository { +import com.example.nto.entity.Place; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PlaceRepository extends JpaRepository { } diff --git a/src/main/java/com/example/nto/service/BookingService.java b/src/main/java/com/example/nto/service/BookingService.java index 31ec148..51f5f60 100644 --- a/src/main/java/com/example/nto/service/BookingService.java +++ b/src/main/java/com/example/nto/service/BookingService.java @@ -1,10 +1,16 @@ package com.example.nto.service; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ +import com.example.nto.entity.Booking; +import com.example.nto.entity.Employee; +import com.example.nto.entity.Place; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + public interface BookingService { + List getBookingsByEmployee(Employee employee); + List getBookingsByDate(LocalDate date); + Optional getBookingByDateAndPlace(LocalDate date, Place place); + Booking createBooking(Employee employee, Place place, LocalDate date); } diff --git a/src/main/java/com/example/nto/service/EmployeeService.java b/src/main/java/com/example/nto/service/EmployeeService.java index cccd209..a300e34 100644 --- a/src/main/java/com/example/nto/service/EmployeeService.java +++ b/src/main/java/com/example/nto/service/EmployeeService.java @@ -1,10 +1,8 @@ package com.example.nto.service; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ +import com.example.nto.entity.Employee; +import java.util.Optional; + public interface EmployeeService { + Optional findByCode(String code); } diff --git a/src/main/java/com/example/nto/service/PlaceService.java b/src/main/java/com/example/nto/service/PlaceService.java new file mode 100644 index 0000000..37e28ac --- /dev/null +++ b/src/main/java/com/example/nto/service/PlaceService.java @@ -0,0 +1,10 @@ +package com.example.nto.service; + +import com.example.nto.entity.Place; + +import java.util.List; + +public interface PlaceService { + List getAllPlaces(); + Place getPlaceById(Long id); +} diff --git a/src/main/java/com/example/nto/service/impl/BookingServiceImpl.java b/src/main/java/com/example/nto/service/impl/BookingServiceImpl.java index d24b244..51b0d19 100644 --- a/src/main/java/com/example/nto/service/impl/BookingServiceImpl.java +++ b/src/main/java/com/example/nto/service/impl/BookingServiceImpl.java @@ -1,12 +1,46 @@ 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.repository.BookingRepository; import com.example.nto.service.BookingService; +import org.springframework.stereotype.Service; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +@Service public class BookingServiceImpl implements BookingService { + + private final BookingRepository bookingRepository; + + public BookingServiceImpl(BookingRepository bookingRepository) { + this.bookingRepository = bookingRepository; + } + + @Override + public List getBookingsByEmployee(Employee employee) { + return bookingRepository.findByEmployee(employee); + } + + @Override + public List getBookingsByDate(LocalDate date) { + return bookingRepository.findByDate(date); + } + + @Override + public Optional getBookingByDateAndPlace(LocalDate date, Place place) { + return bookingRepository.findByDateAndPlace(date, place); + } + + @Override + public Booking createBooking(Employee employee, Place place, LocalDate date) { + Booking booking = new Booking(); + booking.setEmployee(employee); + booking.setPlace(place); + booking.setDate(date); + return bookingRepository.save(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..6939037 100644 --- a/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java +++ b/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java @@ -1,12 +1,22 @@ package com.example.nto.service.impl; +import com.example.nto.entity.Employee; +import com.example.nto.repository.EmployeeRepository; import com.example.nto.service.EmployeeService; +import org.springframework.stereotype.Service; +import java.util.Optional; -/** - * TODO: ДОРАБОТАТЬ в рамках задания - * ================================= - * МОЖНО: Добавлять методы, аннотации, зависимости - * НЕЛЬЗЯ: Изменять название класса и пакета - */ +@Service public class EmployeeServiceImpl implements EmployeeService { + + private final EmployeeRepository employeeRepository; + + public EmployeeServiceImpl(EmployeeRepository employeeRepository) { + this.employeeRepository = employeeRepository; + } + + @Override + public Optional findByCode(String code) { + return employeeRepository.findByCode(code); + } } diff --git a/src/main/java/com/example/nto/service/impl/PlaceServiceImpl.java b/src/main/java/com/example/nto/service/impl/PlaceServiceImpl.java new file mode 100644 index 0000000..3ab1cb1 --- /dev/null +++ b/src/main/java/com/example/nto/service/impl/PlaceServiceImpl.java @@ -0,0 +1,29 @@ +package com.example.nto.service.impl; + +import com.example.nto.entity.Place; +import com.example.nto.repository.PlaceRepository; +import com.example.nto.service.PlaceService; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class PlaceServiceImpl implements PlaceService { + + private final PlaceRepository placeRepository; + + public PlaceServiceImpl(PlaceRepository placeRepository) { + this.placeRepository = placeRepository; + } + + @Override + public List getAllPlaces() { + return placeRepository.findAll(); + } + + @Override + public Place getPlaceById(Long id) { + return placeRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Place not found")); + } +}