#79 adding task planer generation
This commit is contained in:
parent
7ce8b20841
commit
65dea9bce2
49
src/main/java/ru/ulstu/students/model/Scheduler.java
Normal file
49
src/main/java/ru/ulstu/students/model/Scheduler.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package ru.ulstu.students.model;
|
||||||
|
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import ru.ulstu.core.model.BaseEntity;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.OneToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "scheduler")
|
||||||
|
public class Scheduler extends BaseEntity {
|
||||||
|
|
||||||
|
@OneToOne(optional = false)
|
||||||
|
@JoinColumn(name = "task_id")
|
||||||
|
private Task task;
|
||||||
|
|
||||||
|
@Temporal(value = TemporalType.TIMESTAMP)
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
public Scheduler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scheduler(Task task, Date date) {
|
||||||
|
this.task = task;
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task getTask() {
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTask(Task task) {
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(Date date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package ru.ulstu.students.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import ru.ulstu.students.model.Scheduler;
|
||||||
|
|
||||||
|
public interface SchedulerRepository extends JpaRepository<Scheduler, Integer> {
|
||||||
|
|
||||||
|
}
|
@ -20,4 +20,6 @@ public interface TaskRepository extends JpaRepository<Task, Integer> {
|
|||||||
"(YEAR FROM t.createDate) = :year)")
|
"(YEAR FROM t.createDate) = :year)")
|
||||||
List<Task> findToGenerate(@Param("day") Integer day, @Param("month") Integer month, @Param("year") Integer year);
|
List<Task> findToGenerate(@Param("day") Integer day, @Param("month") Integer month, @Param("year") Integer year);
|
||||||
|
|
||||||
|
@Query("SELECT t FROM Task t WHERE(:tag IS NULL OR :tag MEMBER OF t.tags) ORDER BY create_date DESC")
|
||||||
|
List<Task> findByTag(@Param("tag") Tag tag);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
package ru.ulstu.students.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import ru.ulstu.students.model.Scheduler;
|
||||||
|
import ru.ulstu.students.model.Task;
|
||||||
|
import ru.ulstu.students.repository.SchedulerRepository;
|
||||||
|
import ru.ulstu.tags.model.Tag;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SchedulerService {
|
||||||
|
|
||||||
|
private final TaskService taskService;
|
||||||
|
private final SchedulerRepository schedulerRepository;
|
||||||
|
|
||||||
|
public SchedulerService(TaskService taskService, SchedulerRepository schedulerRepository) {
|
||||||
|
this.taskService = taskService;
|
||||||
|
this.schedulerRepository = schedulerRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save(Tag tag) {
|
||||||
|
List<Task> taskList = taskService.findTasksByTag(tag);
|
||||||
|
create(taskList.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
private Scheduler create(Task task) {
|
||||||
|
Scheduler scheduler = new Scheduler(task, task.getDeadlines().get(task.getDeadlines().size() - 1).getDate());
|
||||||
|
return schedulerRepository.save(scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
private void delete(Integer schedulerId) {
|
||||||
|
if (schedulerRepository.exists(schedulerId)) {
|
||||||
|
schedulerRepository.delete(schedulerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkPlanToday() {
|
||||||
|
List<Scheduler> schedulerList = schedulerRepository.findAll();
|
||||||
|
if (!schedulerList.isEmpty()) {
|
||||||
|
doTodayPlanIfNeed(schedulerList);
|
||||||
|
schedulerList = schedulerRepository.findAll();
|
||||||
|
}
|
||||||
|
checkNewPlan(schedulerList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNewPlan(List<Scheduler> schedulerList) {
|
||||||
|
Set<Tag> tags = taskService.checkRepeatingTags();
|
||||||
|
Tag newTag = null;
|
||||||
|
if (!schedulerList.isEmpty()) {
|
||||||
|
newTag = checkNewTag(tags, schedulerList);
|
||||||
|
} else {
|
||||||
|
if (!tags.isEmpty()) {
|
||||||
|
newTag = tags.iterator().next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newTag != null) {
|
||||||
|
save(newTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Tag checkNewTag(Set<Tag> tags, List<Scheduler> schedulerList) {
|
||||||
|
Set<Tag> newTags = tags
|
||||||
|
.stream()
|
||||||
|
.filter(tag -> schedulerList
|
||||||
|
.stream()
|
||||||
|
.anyMatch(scheduler ->
|
||||||
|
!scheduler.getTask().getTags().contains(tag)))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
if (!newTags.isEmpty()) {
|
||||||
|
return newTags.iterator().next();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTodayPlanIfNeed(List<Scheduler> schedulerList) {
|
||||||
|
List<Scheduler> plan = schedulerList
|
||||||
|
.stream()
|
||||||
|
.filter(scheduler -> scheduler.getDate().before(new Date()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
doToday(plan);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doToday(List<Scheduler> plan) {
|
||||||
|
plan.forEach(scheduler -> {
|
||||||
|
taskService.createPeriodTask(scheduler);
|
||||||
|
delete(scheduler.getId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -10,16 +10,25 @@ public class TaskGenerationService {
|
|||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(TaskGenerationService.class);
|
private final Logger log = LoggerFactory.getLogger(TaskGenerationService.class);
|
||||||
private final TaskService taskService;
|
private final TaskService taskService;
|
||||||
|
private final SchedulerService schedulerService;
|
||||||
|
|
||||||
public TaskGenerationService(TaskService taskService) {
|
public TaskGenerationService(TaskService taskService, SchedulerService schedulerService) {
|
||||||
|
|
||||||
this.taskService = taskService;
|
this.taskService = taskService;
|
||||||
|
this.schedulerService = schedulerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Scheduled(cron = "0 * * ? * *", zone = "Europe/Samara")
|
||||||
|
// public void generateYearTasks() {
|
||||||
|
// log.debug("TaskService.generateYearTasks started");
|
||||||
|
// taskService.generateYearTasks();
|
||||||
|
// log.debug("TaskService.generateYearTasks finished");
|
||||||
|
// }
|
||||||
|
|
||||||
@Scheduled(cron = "0 * * ? * *", zone = "Europe/Samara")
|
@Scheduled(cron = "0 * * ? * *", zone = "Europe/Samara")
|
||||||
public void generateYearTasks() {
|
public void checkPlanToday() {
|
||||||
log.debug("TaskService.generateYearTasks started");
|
log.debug("SchedulerService.checkPlanToday started");
|
||||||
taskService.generateYearTasks();
|
schedulerService.checkPlanToday();
|
||||||
log.debug("TaskService.generateYearTasks finished");
|
log.debug("SchedulerService.checkPlanToday finished");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,10 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import ru.ulstu.core.util.DateUtils;
|
||||||
import ru.ulstu.deadline.model.Deadline;
|
import ru.ulstu.deadline.model.Deadline;
|
||||||
import ru.ulstu.deadline.service.DeadlineService;
|
import ru.ulstu.deadline.service.DeadlineService;
|
||||||
|
import ru.ulstu.students.model.Scheduler;
|
||||||
import ru.ulstu.students.model.Task;
|
import ru.ulstu.students.model.Task;
|
||||||
import ru.ulstu.students.model.TaskDto;
|
import ru.ulstu.students.model.TaskDto;
|
||||||
import ru.ulstu.students.model.TaskFilterDto;
|
import ru.ulstu.students.model.TaskFilterDto;
|
||||||
@ -18,6 +20,10 @@ import java.util.Arrays;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||||
@ -108,14 +114,46 @@ public class TaskService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task copyYearTask(Task task) {
|
public void copyMainPart(Task newTask, Task task) {
|
||||||
|
|
||||||
Task newTask = new Task();
|
|
||||||
newTask.setTitle(task.getTitle());
|
newTask.setTitle(task.getTitle());
|
||||||
newTask.setTags(tagService.saveOrCreate(task.getTags()));
|
newTask.setTags(tagService.saveOrCreate(task.getTags()));
|
||||||
newTask.setCreateDate(new Date());
|
newTask.setCreateDate(new Date());
|
||||||
newTask.setStatus(Task.TaskStatus.LOADED_FROM_KIAS);
|
newTask.setStatus(Task.TaskStatus.LOADED_FROM_KIAS);
|
||||||
newTask.setDeadlines(task.getDeadlines()
|
}
|
||||||
|
|
||||||
|
public Task copyTaskWithNewDates(Task task) {
|
||||||
|
Task newTask = new Task();
|
||||||
|
copyMainPart(newTask, task);
|
||||||
|
Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"));
|
||||||
|
cal1.setTime(newTask.getCreateDate());
|
||||||
|
Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"));
|
||||||
|
cal2.setTime(task.getCreateDate());
|
||||||
|
Integer interval = cal1.get(Calendar.DAY_OF_YEAR) - cal2.get(Calendar.DAY_OF_YEAR);
|
||||||
|
newTask.setDeadlines(newDatesDeadlines(task.getDeadlines(), interval));
|
||||||
|
return newTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Deadline> newDatesDeadlines(List<Deadline> deadlines, Integer interval) {
|
||||||
|
return deadlines
|
||||||
|
.stream()
|
||||||
|
.map(deadline -> {
|
||||||
|
Deadline newDeadline = new Deadline();
|
||||||
|
Date newDate = DateUtils.addDays(deadline.getDate(), interval);
|
||||||
|
newDeadline.setDescription(deadline.getDescription());
|
||||||
|
newDeadline.setDate(newDate);
|
||||||
|
return deadlineService.create(newDeadline);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task copyTaskWithNewYear(Task task) {
|
||||||
|
Task newTask = new Task();
|
||||||
|
copyMainPart(newTask, task);
|
||||||
|
newTask.setDeadlines(newYearDeadlines(task.getDeadlines()));
|
||||||
|
return newTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Deadline> newYearDeadlines(List<Deadline> deadlines) {
|
||||||
|
return deadlines
|
||||||
.stream()
|
.stream()
|
||||||
.map(deadline -> {
|
.map(deadline -> {
|
||||||
Deadline newDeadline = new Deadline();
|
Deadline newDeadline = new Deadline();
|
||||||
@ -125,22 +163,40 @@ public class TaskService {
|
|||||||
newDeadline.setDescription(deadline.getDescription());
|
newDeadline.setDescription(deadline.getDescription());
|
||||||
newDeadline.setDate(cal.getTime());
|
newDeadline.setDate(cal.getTime());
|
||||||
return deadlineService.create(newDeadline);
|
return deadlineService.create(newDeadline);
|
||||||
}).collect(Collectors.toList()));
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
return newTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void generateYearTasks() {
|
public void generateYearTasks() {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.setTime(new Date());
|
cal.setTime(new Date());
|
||||||
List<Task> tasks = taskRepository.findToGenerate(cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.YEAR) - 1);
|
List<Task> tasks = taskRepository.findToGenerate(cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.YEAR) - 1);
|
||||||
tasks.forEach(task -> {
|
tasks.forEach(task -> {
|
||||||
Task newTask = copyYearTask(task);
|
Task newTask = copyTaskWithNewYear(task);
|
||||||
taskRepository.save(newTask);
|
taskRepository.save(newTask);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Set<Tag> checkRepeatingTags() {
|
||||||
|
Map<Tag, Long> tagsCount = new TreeMap<>();
|
||||||
|
List<Tag> tags = tagService.getTags();
|
||||||
|
List<Task> tasks = taskRepository.findAll();
|
||||||
|
tags.forEach(tag ->
|
||||||
|
tagsCount.put(tag, tasks
|
||||||
|
.stream()
|
||||||
|
.filter(task -> task.getTags().contains(tag))
|
||||||
|
.count()));
|
||||||
|
|
||||||
|
return tagsCount
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter(tagLongEntry -> tagLongEntry.getValue() >= 2)
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
|
||||||
|
.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
public List<Task.TaskStatus> getTaskStatuses() {
|
public List<Task.TaskStatus> getTaskStatuses() {
|
||||||
return Arrays.asList(Task.TaskStatus.values());
|
return Arrays.asList(Task.TaskStatus.values());
|
||||||
}
|
}
|
||||||
@ -149,4 +205,13 @@ public class TaskService {
|
|||||||
return tagService.getTags();
|
return tagService.getTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Task> findTasksByTag(Tag tag) {
|
||||||
|
return taskRepository.findByTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void createPeriodTask(Scheduler scheduler) {
|
||||||
|
Task newTask = copyTaskWithNewDates(scheduler.getTask());
|
||||||
|
taskRepository.save(newTask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import javax.persistence.Column;
|
|||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "tag")
|
@Table(name = "tag")
|
||||||
@ -41,4 +42,17 @@ public class Tag extends BaseEntity {
|
|||||||
public void setTagName(String tagName) {
|
public void setTagName(String tagName) {
|
||||||
this.tagName = tagName;
|
this.tagName = tagName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Tag tag = (Tag) o;
|
||||||
|
return tagName.equals(tag.tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), tagName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
24
src/main/resources/db/changelog-20190505_000000-schema.xml
Normal file
24
src/main/resources/db/changelog-20190505_000000-schema.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||||
|
<changeSet author="nastya" id="20190505_000000-1">
|
||||||
|
<createTable tableName="scheduler">
|
||||||
|
<column name="id" type="integer">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="task_id" type="integer">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="date" type="timestamp">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="version" type="integer"/>
|
||||||
|
</createTable>
|
||||||
|
<addPrimaryKey columnNames="id" constraintName="pk_scheduler" tableName="scheduler"/>
|
||||||
|
<addForeignKeyConstraint baseTableName="scheduler" baseColumnNames="task_id"
|
||||||
|
constraintName="fk_scheduler_task_id" referencedTableName="task"
|
||||||
|
referencedColumnNames="id"/>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
@ -34,4 +34,5 @@
|
|||||||
<include file="db/changelog-20190421_000000-schema.xml"/>
|
<include file="db/changelog-20190421_000000-schema.xml"/>
|
||||||
<include file="db/changelog-20190422_000000-schema.xml"/>
|
<include file="db/changelog-20190422_000000-schema.xml"/>
|
||||||
<include file="db/changelog-20190424_000000-schema.xml"/>
|
<include file="db/changelog-20190424_000000-schema.xml"/>
|
||||||
|
<include file="db/changelog-20190505_000000-schema.xml"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
@ -21,7 +21,7 @@ $(document).ready(function () {
|
|||||||
$("#input-tag").keyup(function (event) {
|
$("#input-tag").keyup(function (event) {
|
||||||
if(event.keyCode == 13 || event.keyCode == 188) {
|
if(event.keyCode == 13 || event.keyCode == 188) {
|
||||||
var tagNumber = $("#tags .tag").length;
|
var tagNumber = $("#tags .tag").length;
|
||||||
if(length != 0) {
|
if(tagNumber > 0) {
|
||||||
tagNumber = $("#tags .tag").last()
|
tagNumber = $("#tags .tag").last()
|
||||||
.children('input')
|
.children('input')
|
||||||
.attr("name")
|
.attr("name")
|
||||||
|
Loading…
Reference in New Issue
Block a user