From 60fce4cd3d206edf9bca13e2b434af793193d16f Mon Sep 17 00:00:00 2001
From: Denis Oleynik <oleynik.denis.2009@gmail.com>
Date: Tue, 18 Feb 2025 18:54:02 +0300
Subject: [PATCH] Files from NTO-2 stage (Olympath command)

---
 pom.xml                                       |   2 +
 src/main/java/com/example/nto/App.java        |   2 +
 .../nto/controller/EmployeeController.java    | 153 ++++++++++++++++++
 .../java/com/example/nto/entity/Code.java     |  16 +-
 .../java/com/example/nto/entity/CodeBody.java |  13 ++
 .../java/com/example/nto/entity/Employee.java |  23 ++-
 .../com/example/nto/entity/ResponseData.java  |  14 ++
 .../nto/repository/EmployeeRepository.java    |   5 +
 .../example/nto/service/EmployeeService.java  |  15 ++
 .../nto/service/impl/EmployeeServiceImpl.java |  44 ++++-
 10 files changed, 278 insertions(+), 9 deletions(-)
 create mode 100644 src/main/java/com/example/nto/entity/CodeBody.java
 create mode 100644 src/main/java/com/example/nto/entity/ResponseData.java

diff --git a/pom.xml b/pom.xml
index 88282ee..04a45b9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,8 @@
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
+            <version>1.18.30</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
diff --git a/src/main/java/com/example/nto/App.java b/src/main/java/com/example/nto/App.java
index d771a13..d4add94 100644
--- a/src/main/java/com/example/nto/App.java
+++ b/src/main/java/com/example/nto/App.java
@@ -1,9 +1,11 @@
 package com.example.nto;
 
+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 fcb92ec..dd23971 100644
--- a/src/main/java/com/example/nto/controller/EmployeeController.java
+++ b/src/main/java/com/example/nto/controller/EmployeeController.java
@@ -1,4 +1,157 @@
 package com.example.nto.controller;
 
+import com.example.nto.entity.Code;
+import com.example.nto.entity.CodeBody;
+import com.example.nto.entity.Employee;
+import com.example.nto.entity.ResponseData;
+import com.example.nto.service.EmployeeService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Repository;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.time.LocalDateTime;
+import java.util.Optional;
+
+@RestController
 public class EmployeeController {
+    @Autowired
+    private EmployeeService employeeService;
+
+    private ResponseEntity<ResponseData> NotFound() {
+        return new ResponseEntity<>(new ResponseData(HttpStatus.UNAUTHORIZED.value(), "Login not found or invalid"), HttpStatus.UNAUTHORIZED);
+    }
+
+    private ResponseEntity<ResponseData> BadRequest() {
+        return new ResponseEntity<>(new ResponseData(HttpStatus.BAD_REQUEST.value(), "Something went wrong"), HttpStatus.BAD_REQUEST);
+    }
+
+    private ResponseEntity<ResponseData> Ok(String message) {
+        return new ResponseEntity<>(new ResponseData(HttpStatus.OK.value(), message), HttpStatus.OK);
+    }
+
+
+    @Operation(summary = "Auth employee with login")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200",
+                    description = "Auth employee with login success",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = ResponseData.class))}),
+            @ApiResponse(responseCode = "401",
+                    description = "Login not found or invalid",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = ResponseData.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Something went wrong",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = ResponseData.class))})
+    })
+    @GetMapping("/api/{login}/auth")
+    public ResponseEntity<?> auth(@PathVariable("login") String login) {
+        try {
+            if (login == null || login.isEmpty() || !employeeService.existsByLogin(login)) {
+                return NotFound();
+            }
+
+            return Ok("Auth success");
+        } catch (Exception e) {
+            System.out.println("Exception: " + e.getMessage());
+            return BadRequest();
+        }
+    }
+
+
+    @Operation(summary = "Get employee info with login")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200",
+                    description = "OK",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = Employee.class))}),
+            @ApiResponse(responseCode = "401",
+                    description = "Login not found or invalid",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = ResponseData.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Something went wrong",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = ResponseData.class))})
+    })
+    @GetMapping("/api/{login}/info")
+    public ResponseEntity<?> info(@PathVariable("login") String login) {
+        try {
+            if (login == null || login.isEmpty() || login.isBlank() || !employeeService.existsByLogin(login)) {
+                return NotFound();
+            }
+
+            Optional<Employee> employee = employeeService.findByLogin(login);
+            if (employee.isEmpty()) {
+                return NotFound();
+            }
+
+            return new ResponseEntity<>(employee.get(), HttpStatus.OK);
+        } catch (Exception e) {
+            System.out.println("Exception: " + e.getMessage());
+            return BadRequest();
+        }
+    }
+
+    @Operation(summary = "Open door with code")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200",
+                    description = "Door opened success",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = ResponseData.class))}),
+            @ApiResponse(responseCode = "401",
+                    description = "Login not found or invalid",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = ResponseData.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Something went wrong",
+                    content = {@Content(mediaType = "application/json",
+                            schema = @Schema(implementation = ResponseData.class))})
+    })
+    @PatchMapping("/api/{login}/open")
+    public ResponseEntity<?> open(@PathVariable("login") String login, @Valid @RequestBody CodeBody body) {
+        try {
+            if (login == null || login.isEmpty() || login.isBlank() || !employeeService.existsByLogin(login)) {
+                return NotFound();
+            }
+
+            Optional<Employee> employee = employeeService.findByLogin(login);
+            if (employee.isEmpty()) {
+                return NotFound();
+            }
+            Optional<Code> code = employeeService.findCodeById(employee.get().getId());
+            if (code.isEmpty()) {
+                return BadRequest();
+            }
+
+            long dbValue = 0;
+            try {
+                dbValue = code.get().getValue();
+            } catch (Exception e) {
+                employeeService.setCodeEmployee(employee.get().getId(), body.getValue());
+
+                employeeService.setLastVisitEmployee(employee.get().getId(), LocalDateTime.now());
+                return Ok("Door opened success");
+            }
+
+            if (dbValue != body.getValue()) {
+                return BadRequest();
+            }
+
+            employeeService.setLastVisitEmployee(employee.get().getId(), LocalDateTime.now());
+            return Ok("Door opened success");
+        } catch (Exception e) {
+            System.out.println("Exception: " + e.getMessage());
+            return BadRequest();
+        }
+    }
 }
diff --git a/src/main/java/com/example/nto/entity/Code.java b/src/main/java/com/example/nto/entity/Code.java
index e1009f5..fd26269 100644
--- a/src/main/java/com/example/nto/entity/Code.java
+++ b/src/main/java/com/example/nto/entity/Code.java
@@ -1,15 +1,23 @@
 package com.example.nto.entity;
 
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.*;
 
+import javax.persistence.*;
+
+@Entity
+@Table(name = "code")
+@Getter
+@Setter
 @Data
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class Code {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id", unique = true, nullable = false)
     private long id;
+
+    @Column(name = "value", nullable = false)
     private long value;
 }
diff --git a/src/main/java/com/example/nto/entity/CodeBody.java b/src/main/java/com/example/nto/entity/CodeBody.java
new file mode 100644
index 0000000..85a892e
--- /dev/null
+++ b/src/main/java/com/example/nto/entity/CodeBody.java
@@ -0,0 +1,13 @@
+package com.example.nto.entity;
+
+import lombok.*;
+
+@Getter
+@Setter
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CodeBody {
+    private long value;
+}
diff --git a/src/main/java/com/example/nto/entity/Employee.java b/src/main/java/com/example/nto/entity/Employee.java
index aa57aa4..8114ed4 100644
--- a/src/main/java/com/example/nto/entity/Employee.java
+++ b/src/main/java/com/example/nto/entity/Employee.java
@@ -1,21 +1,36 @@
 package com.example.nto.entity;
 
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.*;
 
+import javax.persistence.*;
 import java.time.LocalDateTime;
 
+@Entity
+@Setter
+@Getter
 @Data
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
+@Table(name = "employee")
 public class Employee {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id", unique = true, nullable = false)
     private long id;
+
+    @Column(name = "login", unique = true, nullable = false)
     private String login;
+
+    @Column(name = "name", nullable = false)
     private String name;
+
+    @Column(name = "photo", nullable = false)
     private String photo;
+
+    @Column(name = "position", nullable = false)
     private String position;
+
+    @Column(name = "last_visit", nullable = false)
     private LocalDateTime lastVisit;
 }
diff --git a/src/main/java/com/example/nto/entity/ResponseData.java b/src/main/java/com/example/nto/entity/ResponseData.java
new file mode 100644
index 0000000..f04194e
--- /dev/null
+++ b/src/main/java/com/example/nto/entity/ResponseData.java
@@ -0,0 +1,14 @@
+package com.example.nto.entity;
+
+import lombok.*;
+
+@Setter
+@Getter
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ResponseData {
+    private int status;
+    private String message;
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/nto/repository/EmployeeRepository.java b/src/main/java/com/example/nto/repository/EmployeeRepository.java
index e1265db..42a2a2d 100644
--- a/src/main/java/com/example/nto/repository/EmployeeRepository.java
+++ b/src/main/java/com/example/nto/repository/EmployeeRepository.java
@@ -3,5 +3,10 @@ package com.example.nto.repository;
 import com.example.nto.entity.Employee;
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.Optional;
+
 public interface EmployeeRepository extends JpaRepository<Employee, Long> {
+    Optional<Employee> findByLogin(String login);
+
+    boolean existsByLogin(String login);
 }
diff --git a/src/main/java/com/example/nto/service/EmployeeService.java b/src/main/java/com/example/nto/service/EmployeeService.java
index 7b91091..3c04aee 100644
--- a/src/main/java/com/example/nto/service/EmployeeService.java
+++ b/src/main/java/com/example/nto/service/EmployeeService.java
@@ -1,4 +1,19 @@
 package com.example.nto.service;
 
+import com.example.nto.entity.Code;
+import com.example.nto.entity.Employee;
+
+import java.time.LocalDateTime;
+import java.util.Optional;
+
 public interface EmployeeService {
+    boolean existsByLogin(String login);
+
+    void setLastVisitEmployee(long Id, LocalDateTime lastVisit);
+
+    Code setCodeEmployee(long Id, long code);
+
+    Optional<Employee> findByLogin(String login);
+
+    Optional<Code> findCodeById(Long id);
 }
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 2414533..9bab6c9 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,48 @@
 package com.example.nto.service.impl;
 
+import com.example.nto.entity.Code;
+import com.example.nto.entity.Employee;
+import com.example.nto.repository.CodeRepository;
 import com.example.nto.service.EmployeeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
+import java.time.LocalDateTime;
+import java.util.Optional;
+
+@Service
 public class EmployeeServiceImpl implements EmployeeService {
-}
+    @Autowired
+    private com.example.nto.repository.EmployeeRepository EmployeeRepository;
+    @Autowired
+    private CodeRepository codeRepository;
+
+    @Override
+    public Optional<Employee> findByLogin(String login) {
+        return EmployeeRepository.findByLogin(login);
+    }
+
+    @Override
+    public Optional<Code> findCodeById(Long id) {
+        return Optional.of(codeRepository.getById(id));
+    }
+
+    @Override
+    public void setLastVisitEmployee(long Id, LocalDateTime lastVisit) {
+        Employee employee = EmployeeRepository.getById(Id);
+        employee.setLastVisit(lastVisit);
+        EmployeeRepository.save(employee);
+    }
+
+    @Override
+    public boolean existsByLogin(String login) {
+        return EmployeeRepository.existsByLogin(login);
+    }
+
+    @Override
+    public Code setCodeEmployee(long Id, long code) {
+        Code newCode = new Code(Id, code);
+        codeRepository.save(newCode);
+        return newCode;
+    }
+}
\ No newline at end of file