#79 adding task planer generation

This commit is contained in:
ASH 2019-05-06 22:39:08 +04:00
parent 7ce8b20841
commit 65dea9bce2
10 changed files with 285 additions and 14 deletions

View 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;
}
}

View File

@ -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> {
}

View File

@ -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);
} }

View File

@ -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());
});
}
}

View File

@ -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");
} }
} }

View File

@ -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);
}
} }

View File

@ -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);
}
} }

View 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>

View File

@ -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>

View File

@ -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")