2019-07-20 14:31:44 +04:00

271 lines
10 KiB
Java

package ru.ulstu.activity.students.service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.activity.common.service.ActivityService;
import ru.ulstu.activity.deadline.model.Deadline;
import ru.ulstu.activity.deadline.service.DeadlineService;
import ru.ulstu.activity.ping.service.PingService;
import ru.ulstu.activity.students.model.Scheduler;
import ru.ulstu.activity.students.model.Task;
import ru.ulstu.activity.students.model.TaskDashboardDto;
import ru.ulstu.activity.students.model.TaskDto;
import ru.ulstu.activity.students.model.TaskFilterDto;
import ru.ulstu.activity.students.model.TaskListDto;
import ru.ulstu.activity.tags.model.Tag;
import ru.ulstu.activity.tags.service.TagService;
import ru.ulstu.activity.timeline.model.Event;
import ru.ulstu.activity.timeline.service.EventService;
import ru.ulstu.core.jpa.OffsetablePageRequest;
import ru.ulstu.core.model.response.PageableItems;
import ru.ulstu.core.util.DateUtils;
import javax.persistence.EntityNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
import static ru.ulstu.activity.students.model.Task.TaskStatus.IN_WORK;
import static ru.ulstu.core.util.StreamApiUtils.convert;
import static ru.ulstu.core.util.StreamApiUtils.convertPageable;
@Service
public class TaskService extends ActivityService<TaskListDto, Task, TaskDto> {
private final TaskRepository taskRepository;
private final TaskNotificationService taskNotificationService;
private final SchedulerRepository schedulerRepository;
private final DeadlineService deadlineService;
private final TagService tagService;
private final EventService eventService;
private final PingService pingService;
public TaskService(TaskRepository taskRepository,
TaskNotificationService taskNotificationService,
DeadlineService deadlineService,
TagService tagService,
SchedulerRepository schedulerRepository,
EventService eventService,
PingService pingService) {
super(taskRepository, taskNotificationService, pingService, eventService);
this.taskRepository = taskRepository;
this.taskNotificationService = taskNotificationService;
this.deadlineService = deadlineService;
this.tagService = tagService;
this.eventService = eventService;
this.schedulerRepository = schedulerRepository;
this.pingService = pingService;
}
public List<Task> findAll() {
return taskRepository.findAll(new Sort(Sort.Direction.DESC, "createDate"));
}
public PageableItems<Task> findAll(int offset, int count) {
final Page<Task> page = taskRepository.findAll(new OffsetablePageRequest(offset, count));
return new PageableItems<>(page.getTotalElements(), page.getContent());
}
@Override
protected TaskListDto getActivityListDto(Task entity) {
return new TaskListDto(entity);
}
@Override
protected Task getNewActivity() {
return new Task();
}
@Override
protected TaskDto getNewActivityDto(Task entity) {
return new TaskDto(entity);
}
public List<TaskDto> filter(TaskFilterDto filterDto) {
if (filterDto.getOrder().compareTo("new") == 0) {
return convert(taskRepository.filterNew(
filterDto.getStatus(),
filterDto.getTag() == null ? null : tagService.findById(filterDto.getTag())), TaskDto::new);
} else {
return convert(taskRepository.filterOld(
filterDto.getStatus(),
filterDto.getTag() == null ? null : tagService.findById(filterDto.getTag())), TaskDto::new);
}
}
protected Task copyFromDto(Task task, TaskDto taskDto) {
task.setTitle(taskDto.getTitle());
task.setDescription(taskDto.getDescription());
task.setStatus(taskDto.getStatus() == null ? IN_WORK : taskDto.getStatus());
task.setDeadlines(deadlineService.saveOrCreate(taskDto.getDeadlines()));
task.setCreateDate(task.getCreateDate() == null ? new Date() : task.getCreateDate());
task.setUpdateDate(new Date());
task.getTags().clear();
//task.setTags(tagService.saveOrCreate(taskDto.getTags()));
return task;
}
@Override
protected List<Event> getEvents(Task entity) {
return eventService.findByTask(entity);
}
private void copyMainPart(Task newTask, Task task) {
newTask.setTitle(task.getTitle());
newTask.setTags(tagService.saveOrCreate(task.getTags()));
newTask.setCreateDate(new Date());
newTask.setStatus(Task.TaskStatus.LOADED_FROM_KIAS);
}
private Task copyTaskWithNewDates(Task task) {
Task newTask = new Task();
copyMainPart(newTask, task);
Calendar cal1 = DateUtils.getCalendar(newTask.getCreateDate());
Calendar cal2 = DateUtils.getCalendar(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());
}
private 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()
.map(deadline -> {
Deadline newDeadline = new Deadline();
newDeadline.setDescription(deadline.getDescription());
newDeadline.setDate(DateUtils.addYears(deadline.getDate(), 1));
return deadlineService.create(newDeadline);
}).collect(Collectors.toList());
}
private boolean equalsDate(Task task) {
Calendar taskDate = DateUtils.getCalendar(task.getCreateDate());
Calendar nowDate = DateUtils.getCalendar(new Date());
return (taskDate.get(Calendar.DAY_OF_MONTH) == nowDate.get(Calendar.DAY_OF_MONTH) &&
taskDate.get(Calendar.MONTH) + 1 == nowDate.get(Calendar.MONTH) + 1 &&
taskDate.get(Calendar.YEAR) + 1 == nowDate.get(Calendar.YEAR));
}
@Transactional
public List<Task> generateYearTasks() {
Set<Tag> tags = checkRepeatingTags(false);
List<Task> tasks = new ArrayList<>();
tags.forEach(tag -> {
Task singleTask = findTasksByTag(tag).get(0);
if (equalsDate(singleTask)) {
if (!tasks.contains(singleTask)) {
tasks.add(singleTask);
}
}
});
if (tasks != null) {
tasks.forEach(task -> {
Task newTask = copyTaskWithNewYear(task);
taskRepository.save(newTask);
});
return tasks;
}
return null;
}
@Transactional
public Set<Tag> checkRepeatingTags(Boolean createPeriodTask) { //param: false = year task; true = period task
Map<Tag, Long> tagsCount = new TreeMap<>();
List<Tag> tags = tagService.getTags();
List<Task> tasks = taskRepository.findAllYear(DateUtils.clearTime(DateUtils.addYears(new Date(), -1)));
tags.forEach(tag ->
tagsCount.put(tag, tasks
.stream()
.filter(task -> task.getTags().contains(tag))
.count()));
if (!createPeriodTask) {
return tagsCount
.entrySet()
.stream()
.filter(tagLongEntry -> tagLongEntry.getValue() == 1)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
.keySet();
} else {
return tagsCount
.entrySet()
.stream()
.filter(tagLongEntry -> tagLongEntry.getValue() >= 2)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
.keySet();
}
}
public List<Task.TaskStatus> getTaskStatuses() {
return Arrays.asList(Task.TaskStatus.values());
}
public List<Tag> getTags() {
return tagService.getTags();
}
public List<Task> findTasksByTag(Tag tag) {
return taskRepository.findByTag(tag);
}
@Transactional
public Task createPeriodTask(Scheduler scheduler) {
Task newTask = copyTaskWithNewDates(scheduler.getTask());
taskRepository.save(newTask);
return newTask;
}
@Override
public PageableItems<TaskDashboardDto> findAllActiveDto(int offset, int count) {
return convertPageable(findAllActive(offset, count), TaskDashboardDto::new);
}
@Override
public PageableItems<Task> findAllActive(int offset, int count) {
return findAll(offset, count);
}
public TaskDto findTaskById(Integer taskId) {
return new TaskDto(findById(taskId));
}
public Task findById(Integer taskId) {
return taskRepository.findById(taskId)
.orElseThrow(() -> new EntityNotFoundException("Paper with id=" + taskId + " not found"));
}
@Transactional
public void ping(int taskId) {
pingService.addPing(findById(taskId));
}
}