implemented adding required tasks to task

This commit is contained in:
2025-09-06 00:38:58 +02:00
parent 91f536a658
commit cce488f615
16 changed files with 190 additions and 53 deletions

View File

@@ -4,11 +4,10 @@ package de.srsoftware.umbrella.task;
public class Constants {
private Constants(){}
public static final String CONFIG_DATABASE = "umbrella.modules.task.database";
public static final String CHILDREN = "children";
public static final String ESTIMATED_TIMES = "estimated_times";
public static final String IDS = "ids";
public static final String REQUIRED_TASK_ID = "required_task_id";
public static final String TABLE_TASK_DEPENDENCIES = "task_dependencies";
public static final String TABLE_TASKS = "tasks";

View File

@@ -166,14 +166,7 @@ CREATE TABLE IF NOT EXISTS {0} (
}
}
private void init(){
var version = createTables();
LOG.log(INFO,"Updated task db to version {0}",version);
}
public HashMap<Long, Task> listTasks(Collection<Long> projectIds) throws UmbrellaException {
public Map<Long, Task> listTasks(Collection<Long> projectIds) throws UmbrellaException {
try {
var tasks = new HashMap<Long,Task>();
var rs = select(ALL).from(TABLE_TASKS).where(PROJECT_ID, in(projectIds.toArray())).exec(db);
@@ -182,13 +175,13 @@ CREATE TABLE IF NOT EXISTS {0} (
tasks.put(task.id(),task);
}
rs.close();
return tasks;
return loadDependencies(tasks);
} catch (SQLException e) {
throw new UmbrellaException("Failed to load tasks for project ids");
throw databaseException("Failed to load tasks for project ids");
}
}
public HashMap<Long, Task> listRootTasks(Long projectId, UmbrellaUser user, boolean showClosed) {
public Map<Long, Task> listRootTasks(Long projectId, UmbrellaUser user, boolean showClosed) {
try {
var tasks = new HashMap<Long,Task>();
var query = select(ALL).from(TABLE_TASKS).leftJoin(ID,TABLE_TASKS_USERS,TASK_ID)
@@ -202,14 +195,14 @@ CREATE TABLE IF NOT EXISTS {0} (
tasks.put(task.id(),task);
}
rs.close();
return tasks;
return loadDependencies(tasks);
} catch (SQLException e){
LOG.log(WARNING,"Failed to load tasks for project (pid: {0}, user_id: {1}",projectId,user.id(),e);
throw new UmbrellaException("Failed to load tasks for project id");
throw databaseException("Failed to load tasks for project id");
}
}
public HashMap<Long, Task> listChildrenOf(Long parentTaskId, UmbrellaUser user, boolean showClosed) {
public Map<Long, Task> listChildrenOf(Long parentTaskId, UmbrellaUser user, boolean showClosed) {
try {
var tasks = new HashMap<Long,Task>();
var query = select(ALL).from(TABLE_TASKS).leftJoin(ID,TABLE_TASKS_USERS,TASK_ID)
@@ -222,15 +215,15 @@ CREATE TABLE IF NOT EXISTS {0} (
tasks.put(task.id(),task);
}
rs.close();
return tasks;
return loadDependencies(tasks);
} catch (SQLException e){
LOG.log(WARNING,"Failed to load child tasks (parentTaskId: {0}, user_id: {1}",parentTaskId,user.id(),e);
throw new UmbrellaException("Failed to load tasks for project id");
throw databaseException("Failed to load tasks for project id");
}
}
@Override
public HashMap<Long, Task> listProjectTasks(Long projectId, Long parentTaskId, boolean noIndex) throws UmbrellaException {
public Map<Long, Task> listProjectTasks(Long projectId, Long parentTaskId, boolean noIndex) throws UmbrellaException {
try {
var query = select(ALL).from(TABLE_TASKS).where(PROJECT_ID,equal(projectId));
if (parentTaskId != 0) query.where(PARENT_TASK_ID,equal(parentTaskId));
@@ -242,9 +235,9 @@ CREATE TABLE IF NOT EXISTS {0} (
tasks.put(task.id(),task);
}
rs.close();
return tasks;
return loadDependencies(tasks);
} catch (SQLException e){
throw new UmbrellaException("Failed to load tasks for project {0}",projectId);
throw databaseException("Failed to load tasks for project {0}",projectId);
}
}
@@ -265,18 +258,43 @@ CREATE TABLE IF NOT EXISTS {0} (
@Override
public Task load(long taskId) throws UmbrellaException {
var map = load(List.of(taskId));
var task = map.get(taskId);
if (task == null) throw UmbrellaException.notFound("No task found for id {0}",taskId);
return task;
}
@Override
public Map<Long, Task> load(Collection<Long> taskIds) throws UmbrellaException {
try {
var rs = select(ALL).from(TABLE_TASKS).where(ID, equal(taskId)).exec(db);
Task result = null;
if (rs.next()) result = Task.of(rs);
var rs = select(ALL).from(TABLE_TASKS).where(ID, in(taskIds.toArray())).exec(db);
var map = new HashMap<Long, Task>();
while (rs.next()) {
var task = Task.of(rs);
map.put(task.id(),task);
}
rs.close();
if (result == null) throw UmbrellaException.notFound("No task found for id {0}",taskId);
return result;
return loadDependencies(map);
} catch (SQLException e) {
throw new UmbrellaException("Failed to load task from database");
}
}
private Map<Long, Task> loadDependencies(Map<Long, Task> tasks) {
try {
var rs = select(ALL).from(TABLE_TASK_DEPENDENCIES).where(TASK_ID,in(tasks.keySet().toArray())).exec(db);
while (rs.next()){
var taskId = rs.getLong(TASK_ID);
var requiredTaskId = rs.getLong(REQUIRED_TASK_ID);
tasks.get(taskId).requiredTasksIds().add(requiredTaskId);
}
rs.close();
return tasks;
} catch (SQLException e) {
throw databaseException("Failed to load task dependencies");
}
}
@Override
public Task save(Task task) {
try {
@@ -297,6 +315,12 @@ CREATE TABLE IF NOT EXISTS {0} (
query.execute(db).close();
task.clean(MEMBERS);
}
if (task.isDirty(REQUIRED_TASKS_IDS)) {
var query = replaceInto(TABLE_TASK_DEPENDENCIES,TASK_ID,REQUIRED_TASK_ID);
for (var reqId : task.requiredTasksIds()) query.values(task.id(),reqId);
query.execute(db).close();
task.clean(REQUIRED_TASKS_IDS);
}
if (task.isDirty()) {
update(TABLE_TASKS).set(PROJECT_ID,PARENT_TASK_ID,NAME,DESCRIPTION,STATUS,EST_TIME,START_DATE,DUE_DATE,SHOW_CLOSED,NO_INDEX)
.where(ID,equal(task.id())).prepare(db)

View File

@@ -7,7 +7,6 @@ import de.srsoftware.umbrella.core.model.Permission;
import de.srsoftware.umbrella.core.model.Task;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -15,16 +14,17 @@ public interface TaskDb {
void delete(Task task) throws UmbrellaException;
void dropMember(long projectId, long userId);
HashMap<Long, Task> find(long userId, List<String> keys, boolean fulltext);
Map<Long, Task> find(long userId, List<String> keys, boolean fulltext);
Map<Long, Permission> getMembers(Task task);
HashMap<Long, Task> listChildrenOf(Long parentTaskId, UmbrellaUser user, boolean showClosed);
HashMap<Long, Task> listProjectTasks(Long projectId, Long parentTaskId, boolean noIndex) throws UmbrellaException;
HashMap<Long, Task> listRootTasks(Long projectId, UmbrellaUser user, boolean showClosed);
HashMap<Long, Task> listTasks(Collection<Long> projectIds) throws UmbrellaException;
Map<Long, Task> listChildrenOf(Long parentTaskId, UmbrellaUser user, boolean showClosed);
Map<Long, Task> listProjectTasks(Long projectId, Long parentTaskId, boolean noIndex) throws UmbrellaException;
Map<Long, Task> listRootTasks(Long projectId, UmbrellaUser user, boolean showClosed);
Map<Long, Task> listTasks(Collection<Long> projectIds) throws UmbrellaException;
List<Task> listUserTasks(long userId, Long limit, long offset, boolean showClosed);
Task load(long taskId) throws UmbrellaException;
Map<Long, Task> load(Collection<Long> taskIds) throws UmbrellaException;
Task save(Task task);

View File

@@ -206,13 +206,13 @@ public class TaskModule extends BaseHandler implements TaskService {
}
@Override
public HashMap<Long, Task> listCompanyTasks(long companyId) throws UmbrellaException {
public Map<Long, Task> listCompanyTasks(long companyId) throws UmbrellaException {
var projectList = projectService().listCompanyProjects(companyId,false);
return taskDb.listTasks(projectList.keySet());
}
@Override
public HashMap<Long, Task> listProjectTasks(long projectId) throws UmbrellaException {
public Map<Long, Task> listProjectTasks(long projectId) throws UmbrellaException {
return taskDb.listTasks(List.of(projectId));
}
@@ -226,13 +226,8 @@ public class TaskModule extends BaseHandler implements TaskService {
}
@Override
public HashMap<Long, Task> load(Collection<Long> taskIds) {
try {
var map = taskIds.stream().map(this::loadTaskOrNull).filter(Objects::nonNull).collect(Collectors.toMap(Task::id, t -> t));
return new HashMap<>(map);
} catch (Exception e){
throw new UmbrellaException(e.getMessage());
}
public Map<Long, Task> load(Collection<Long> taskIds) {
return taskDb.load(taskIds);
}
@Override
@@ -359,9 +354,11 @@ public class TaskModule extends BaseHandler implements TaskService {
private boolean postSearch(UmbrellaUser user, HttpExchange ex) throws IOException {
var json = json(ex);
if (!(json.has(KEY) && json.get(KEY) instanceof String key)) throw missingFieldException(KEY);
var projectId = json.has(PROJECT_ID) && json.get(PROJECT_ID) instanceof Number pid ? pid.longValue() : null;
var keys = Arrays.asList(key.split(" "));
var fulltext = json.has(FULLTEXT) && json.get(FULLTEXT) instanceof Boolean val && val;
var tasks = taskDb.find(user.id(),keys,fulltext);
if (projectId != null) tasks = tasks.values().stream().filter(task -> task.projectId() == projectId).collect(Collectors.toMap(Task::id, t -> t));
return sendContent(ex,mapValues(tasks));
}
@@ -379,6 +376,8 @@ public class TaskModule extends BaseHandler implements TaskService {
return sendContent(ex,mapValues(projectTasks));
}
if (isSet(parentTaskId)) return sendContent(ex,mapValues(taskDb.listChildrenOf(parentTaskId,user,showClosed)));
var taskIds = json.has(IDS) && json.get(IDS) instanceof JSONArray ids ? ids.toList().stream().map(Object::toString).map(Long::parseLong).toList() : null;
if (isSet(taskIds)) return sendContent(ex,mapValues(taskDb.load(taskIds)));
return sendEmptyResponse(HTTP_NOT_IMPLEMENTED,ex);
}
}