From 6e625487ec35cd9b25a5b1ffe7abf7bd1180207b Mon Sep 17 00:00:00 2001
From: Petr Rudichev <petrrudichev@gmail.com>
Date: Wed, 19 Feb 2025 15:03:57 +0300
Subject: [PATCH] feat: finish VisitService and VisitServiceImpl

---
 .../example/nto/service/TerminalService.java  |   5 +
 .../com/example/nto/service/VisitService.java |  21 +++
 .../nto/service/impl/TerminalServiceImpl.java |   6 +
 .../nto/service/impl/VisitServiceImpl.java    | 125 ++++++++++++++++++
 4 files changed, 157 insertions(+)
 create mode 100644 src/main/java/com/example/nto/service/TerminalService.java
 create mode 100644 src/main/java/com/example/nto/service/VisitService.java
 create mode 100644 src/main/java/com/example/nto/service/impl/TerminalServiceImpl.java
 create mode 100644 src/main/java/com/example/nto/service/impl/VisitServiceImpl.java

diff --git a/src/main/java/com/example/nto/service/TerminalService.java b/src/main/java/com/example/nto/service/TerminalService.java
new file mode 100644
index 0000000..ad98f62
--- /dev/null
+++ b/src/main/java/com/example/nto/service/TerminalService.java
@@ -0,0 +1,5 @@
+package com.example.nto.service;
+
+public interface TerminalService {
+
+}
diff --git a/src/main/java/com/example/nto/service/VisitService.java b/src/main/java/com/example/nto/service/VisitService.java
new file mode 100644
index 0000000..83180ee
--- /dev/null
+++ b/src/main/java/com/example/nto/service/VisitService.java
@@ -0,0 +1,21 @@
+package com.example.nto.service;
+
+import com.example.nto.dto.entity.VisitDTO;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface VisitService {
+    List<VisitDTO> getAll();
+    List<VisitDTO> getAllVisitByEmployee(long employeeId);
+    List<VisitDTO> getAllVisitByPeriod(LocalDateTime start, LocalDateTime stop);
+    List<VisitDTO> getAllFinished(boolean isFinished);
+
+    VisitDTO getById(long visitId);
+    VisitDTO open(long employeeId, long startTerminalId, String passageName);
+    void exit(long employeeId, long endTerminalId);
+
+    // update не нужен он не будет использоваться :)
+
+    void delete(long visitId);
+}
diff --git a/src/main/java/com/example/nto/service/impl/TerminalServiceImpl.java b/src/main/java/com/example/nto/service/impl/TerminalServiceImpl.java
new file mode 100644
index 0000000..2dd7abd
--- /dev/null
+++ b/src/main/java/com/example/nto/service/impl/TerminalServiceImpl.java
@@ -0,0 +1,6 @@
+package com.example.nto.service.impl;
+
+import com.example.nto.service.TerminalService;
+
+public class TerminalServiceImpl implements TerminalService {
+}
diff --git a/src/main/java/com/example/nto/service/impl/VisitServiceImpl.java b/src/main/java/com/example/nto/service/impl/VisitServiceImpl.java
new file mode 100644
index 0000000..0c462f2
--- /dev/null
+++ b/src/main/java/com/example/nto/service/impl/VisitServiceImpl.java
@@ -0,0 +1,125 @@
+package com.example.nto.service.impl;
+
+import com.example.nto.aspect.annotation.LogExample;
+import com.example.nto.domain.entity.Employee;
+import com.example.nto.domain.entity.Passage;
+import com.example.nto.domain.entity.Terminal;
+import com.example.nto.domain.entity.Visit;
+import com.example.nto.domain.exception.ResourceNotFoundException;
+import com.example.nto.dto.entity.VisitDTO;
+import com.example.nto.dto.mappers.VisitMapper;
+import com.example.nto.repository.EmployeeRepository;
+import com.example.nto.repository.PassageRepository;
+import com.example.nto.repository.TerminalRepository;
+import com.example.nto.repository.VisitRepository;
+import com.example.nto.service.VisitService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+public class VisitServiceImpl implements VisitService {
+    private final EmployeeRepository employeeRepository;
+    private final VisitRepository visitRepository;
+    private final TerminalRepository terminalRepository;
+    private final PassageRepository passageRepository;
+
+    @Override
+    @LogExample
+    public List<VisitDTO> getAll() {
+        return visitRepository.findAll().stream().map(VisitMapper::convertToDTO).collect(Collectors.toList());
+    }
+
+    @Override
+    @LogExample
+    public List<VisitDTO> getAllVisitByEmployee(long employeeId) {
+        return visitRepository.findAll().stream()
+                .filter(visit -> checkEmployeeVisit(visit, employeeId))
+                .map(VisitMapper::convertToDTO).collect(Collectors.toList());
+    }
+
+    @Override
+    @LogExample
+    public List<VisitDTO> getAllVisitByPeriod(LocalDateTime start, LocalDateTime stop) {
+        // todo: Доделать если останется время
+        return List.of();
+    }
+
+    @Override
+    @LogExample
+    public List<VisitDTO> getAllFinished(boolean isFinished) {
+        return visitRepository.findAll().stream()
+                .filter(visit -> checkFinishVisit(visit, isFinished))
+                .map(VisitMapper::convertToDTO).collect(Collectors.toList());
+    }
+
+    @Override
+    @LogExample
+    public VisitDTO getById(long visitId) {
+        return visitRepository.findById(visitId).map(VisitMapper::convertToDTO)
+                .orElseThrow(() -> new ResourceNotFoundException("Посещение с id (" + visitId + ") не найден!"));
+    }
+
+    @Override
+    @LogExample
+    public void delete(long visitId) {
+        visitRepository.findById(visitId).orElseThrow(() -> new ResourceNotFoundException("Посещение с id (" + visitId + ") не найден!"));
+        visitRepository.deleteById(visitId);
+    }
+
+    @Override
+    @LogExample
+    public VisitDTO open(long employeeId, long startTerminalId, String passageName) {
+        Employee employee = employeeRepository.findById(employeeId)
+                .orElseThrow(() -> new ResourceNotFoundException("Работник с id (" + employeeId + ") не найден!"));
+        Terminal terminal = terminalRepository.findById(startTerminalId)
+                .orElseThrow(() -> new ResourceNotFoundException("Терминал с id (" + startTerminalId + ") не найден!"));
+        Passage passage = passageRepository.findByPassageName(passageName)
+                .orElseThrow(() -> new ResourceNotFoundException("Тип входа с названием (" + passageName + ") не найден!"));
+
+        Visit visit = new Visit();
+
+        visit.setEmployee(employee);
+        visit.setStartVisit(LocalDateTime.now());
+        visit.setFinished(false);
+        visit.setStartTerminal(terminal);
+        visit.setPassage(passage);
+
+        return VisitMapper.convertToDTO(visitRepository.save(visit));
+    }
+
+    @Override
+    @LogExample
+    public void exit(long employeeId, long endTerminalId) {
+        Employee employee = employeeRepository.findById(employeeId)
+                .orElseThrow(() -> new ResourceNotFoundException("Работник с id (" + employeeId + ") не найден!"));
+        Terminal terminal = terminalRepository.findById(endTerminalId)
+                .orElseThrow(() -> new ResourceNotFoundException("Терминал с id (" + endTerminalId + ") не найден!"));
+        Visit activeVisit = getActiveVisit(employee);
+
+        activeVisit.setStartVisit(LocalDateTime.now());
+        activeVisit.setFinished(true);
+        activeVisit.setEndTerminal(terminal);
+
+        visitRepository.save(activeVisit);
+    }
+
+    private static boolean checkEmployeeVisit(Visit visit, long employeeId) {
+        return visit.getEmployee().getId() == employeeId;
+    }
+
+    private static boolean checkFinishVisit(Visit visit, boolean isFinished) {
+        return visit.isFinished() == isFinished;
+    }
+
+    private static Visit getActiveVisit(Employee employee) {
+        List<Visit> visits = employee.getVisits().stream().filter(Visit::isFinished).collect(Collectors.toList());
+
+        if (visits.size() == 1) return visits.get(0);
+        else throw new IllegalStateException("Пользователь не может находится в суперпозиции");
+    }
+}