diff --git a/src/main/java/com/example/caselabproject/CaseLabProjectApplication.java b/src/main/java/com/example/caselabproject/CaseLabProjectApplication.java index 99d11523..7edc2119 100644 --- a/src/main/java/com/example/caselabproject/CaseLabProjectApplication.java +++ b/src/main/java/com/example/caselabproject/CaseLabProjectApplication.java @@ -2,8 +2,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication +@EnableScheduling public class CaseLabProjectApplication { public static void main(String[] args) { diff --git a/src/main/java/com/example/caselabproject/repositories/ApplicationRepository.java b/src/main/java/com/example/caselabproject/repositories/ApplicationRepository.java index 18346e03..102ae092 100644 --- a/src/main/java/com/example/caselabproject/repositories/ApplicationRepository.java +++ b/src/main/java/com/example/caselabproject/repositories/ApplicationRepository.java @@ -1,7 +1,17 @@ package com.example.caselabproject.repositories; import com.example.caselabproject.models.entities.Application; +import com.example.caselabproject.models.enums.ApplicationStatus; +import com.example.caselabproject.models.enums.RecordState; import org.springframework.data.jpa.repository.JpaRepository; +import java.time.LocalDateTime; + +import java.util.List; + public interface ApplicationRepository extends JpaRepository { + + List findAllByRecordStateAndApplicationStatusAndDeadlineDateBefore( + RecordState recordState, ApplicationStatus applicationStatus, LocalDateTime now + ); } diff --git a/src/main/java/com/example/caselabproject/scheduler/ApplicationScheduler.java b/src/main/java/com/example/caselabproject/scheduler/ApplicationScheduler.java new file mode 100644 index 00000000..72bc2d5d --- /dev/null +++ b/src/main/java/com/example/caselabproject/scheduler/ApplicationScheduler.java @@ -0,0 +1,36 @@ +package com.example.caselabproject.scheduler; + +import com.example.caselabproject.models.entities.Application; +import com.example.caselabproject.models.enums.ApplicationStatus; +import com.example.caselabproject.models.enums.RecordState; +import com.example.caselabproject.repositories.ApplicationRepository; +import com.example.caselabproject.services.implementations.ApplicationItemServiceImpl; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class ApplicationScheduler { + private final ApplicationRepository applicationRepository; + private final ApplicationItemServiceImpl applicationItemServiceImpl; + + /** + * + * + * @see Application + */ + @Scheduled(cron = "5 * * * * *") // every 5-th second of each minute + public void setScheduler() { + List applications = applicationRepository + .findAllByRecordStateAndApplicationStatusAndDeadlineDateBefore( + RecordState.ACTIVE, ApplicationStatus.WAITING_FOR_ANSWER, LocalDateTime.now()); + + for (Application application : applications) { + applicationItemServiceImpl.calcApplicationItemsResult(application); + } + } +} diff --git a/src/main/java/com/example/caselabproject/services/implementations/ApplicationItemServiceImpl.java b/src/main/java/com/example/caselabproject/services/implementations/ApplicationItemServiceImpl.java index 7c849575..de174040 100644 --- a/src/main/java/com/example/caselabproject/services/implementations/ApplicationItemServiceImpl.java +++ b/src/main/java/com/example/caselabproject/services/implementations/ApplicationItemServiceImpl.java @@ -173,7 +173,7 @@ public ApplicationItemVoteResponseDto voteApplicationItem(Long applicationId, return ApplicationItemVoteResponseDto.mapFromEntity(applicationItem); } - void calcApplicationItemsResult(Application application) { + public void calcApplicationItemsResult(Application application) { AtomicInteger pending = new AtomicInteger(); AtomicInteger accepted = new AtomicInteger(); AtomicInteger denied = new AtomicInteger(); @@ -188,9 +188,9 @@ void calcApplicationItemsResult(Application application) { } }); if(sum * 0.6 >= accepted.get() + denied.get()){ - application.setApplicationStatus(ApplicationStatus.NOT_ENOUGH_VOTES); + application.setApplicationStatus(ApplicationStatus.DENIED); }else if(accepted.get() == denied.get()){ - application.setApplicationStatus(ApplicationStatus.DRAW); + application.setApplicationStatus(ApplicationStatus.DENIED); } else if (accepted.get() > denied.get()) { application.setApplicationStatus(ApplicationStatus.ACCEPTED); }else if (accepted.get() < denied.get()) { diff --git a/src/main/java/com/example/caselabproject/services/implementations/ApplicationServiceImpl.java b/src/main/java/com/example/caselabproject/services/implementations/ApplicationServiceImpl.java index 97605fe1..66499ef0 100644 --- a/src/main/java/com/example/caselabproject/services/implementations/ApplicationServiceImpl.java +++ b/src/main/java/com/example/caselabproject/services/implementations/ApplicationServiceImpl.java @@ -27,8 +27,11 @@ @Service @RequiredArgsConstructor public class ApplicationServiceImpl implements ApplicationService { + private final ApplicationRepository applicationRepository; + private final UserRepository userRepository; + private final ApplicationItemRepository applicationItemRepository; @@ -59,7 +62,6 @@ public ApplicationUpdateResponseDto updateApplication(Long id, String username, updateApplication.setDeadlineDate(application.getDeadlineDate()); applicationRepository.save(updateApplication); } - return ApplicationUpdateResponseDto.mapFromEntity(application); } diff --git a/src/main/java/com/example/caselabproject/services/implementations/DepartmentServiceImpl.java b/src/main/java/com/example/caselabproject/services/implementations/DepartmentServiceImpl.java index 65b8f321..3b46f416 100644 --- a/src/main/java/com/example/caselabproject/services/implementations/DepartmentServiceImpl.java +++ b/src/main/java/com/example/caselabproject/services/implementations/DepartmentServiceImpl.java @@ -200,8 +200,6 @@ private boolean departmentIsActive(Department department) { */ private Department saveInternal(Department department) { try { - // при использовании просто save(), мы не сможем обработать ограничение - // уникальности, поэтому используем saveAndFlush(). return departmentRepository.save(department); } catch (DataIntegrityViolationException ex) { throw new DepartmentNameExistsException(department.getName()); diff --git a/src/test/java/com/example/caselabproject/repositories/ApplicationRepositoryTest.java b/src/test/java/com/example/caselabproject/repositories/ApplicationRepositoryTest.java new file mode 100644 index 00000000..2e6f48c0 --- /dev/null +++ b/src/test/java/com/example/caselabproject/repositories/ApplicationRepositoryTest.java @@ -0,0 +1,62 @@ +package com.example.caselabproject.repositories; + + +import com.example.caselabproject.models.entities.Application; +import com.example.caselabproject.models.enums.ApplicationStatus; +import com.example.caselabproject.models.enums.RecordState; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +class ApplicationRepositoryTest { + @Autowired + private ApplicationRepository underTest; + + @Test /* Application#findAllByRecordStateAndApplicationStatusAndDeadlineDateBefore */ + void shouldReturnNotEmptyList_whenStateIsActiveAndStatusIsWaiting() { + // given + LocalDateTime now = LocalDateTime.now(); + final Application first = getApplication( + RecordState.ACTIVE, ApplicationStatus.WAITING_FOR_ANSWER, now.minusWeeks(1)); + final Application second = getApplication( + RecordState.ACTIVE, ApplicationStatus.WAITING_FOR_ANSWER, now.minusMinutes(1)); + final Application third = getApplication( + RecordState.DELETED, ApplicationStatus.WAITING_FOR_ANSWER, now.minusWeeks(1)); + final Application fourth = getApplication( + RecordState.DELETED, ApplicationStatus.WAITING_FOR_ANSWER, now.plusHours(4)); + final Application fifth = getApplication( + RecordState.ACTIVE, ApplicationStatus.DENIED, now.minusWeeks(1)); + final Application sixth = getApplication( + RecordState.ACTIVE, ApplicationStatus.WAITING_FOR_ANSWER, now.plusMinutes(1)); + final Application seventh = getApplication( + RecordState.DELETED, ApplicationStatus.WAITING_FOR_ANSWER, now.minusWeeks(1)); + + underTest.saveAll(List.of(first, second, third, fourth, fifth, sixth, seventh)); + + // when + final List actualApplications = underTest + .findAllByRecordStateAndApplicationStatusAndDeadlineDateBefore( + RecordState.ACTIVE, ApplicationStatus.WAITING_FOR_ANSWER, now); + + // then + assertThat(actualApplications) + .hasSize(2) + .contains(first, second); + } + + private Application getApplication( + RecordState state, ApplicationStatus status, LocalDateTime deadline) { + return Application.builder() + .name("something") + .recordState(state) + .applicationStatus(status) + .deadlineDate(deadline) + .build(); + } +}