|
|
|
@ -1,12 +1,13 @@ |
|
|
|
/* © SRSoftware 2025 */ |
|
|
|
/* © SRSoftware 2025 */ |
|
|
|
package de.srsoftware.umbrella.core.model; |
|
|
|
package de.srsoftware.umbrella.core.model; |
|
|
|
|
|
|
|
|
|
|
|
import static de.srsoftware.tools.Optionals.getPath; |
|
|
|
|
|
|
|
import static de.srsoftware.tools.Optionals.nullIfEmpty; |
|
|
|
import static de.srsoftware.tools.Optionals.nullIfEmpty; |
|
|
|
import static de.srsoftware.umbrella.core.Constants.*; |
|
|
|
import static de.srsoftware.umbrella.core.Constants.*; |
|
|
|
|
|
|
|
import static de.srsoftware.umbrella.core.Util.LOG; |
|
|
|
import static de.srsoftware.umbrella.core.Util.markdown; |
|
|
|
import static de.srsoftware.umbrella.core.Util.markdown; |
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidFieldException; |
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidFieldException; |
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException; |
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException; |
|
|
|
|
|
|
|
import static java.lang.System.Logger.Level.WARNING; |
|
|
|
|
|
|
|
|
|
|
|
import de.srsoftware.tools.Mappable; |
|
|
|
import de.srsoftware.tools.Mappable; |
|
|
|
import org.json.JSONObject; |
|
|
|
import org.json.JSONObject; |
|
|
|
@ -14,10 +15,74 @@ import org.json.JSONObject; |
|
|
|
import java.sql.ResultSet; |
|
|
|
import java.sql.ResultSet; |
|
|
|
import java.sql.SQLException; |
|
|
|
import java.sql.SQLException; |
|
|
|
import java.time.LocalDate; |
|
|
|
import java.time.LocalDate; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.*; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
public class Task implements Mappable { |
|
|
|
|
|
|
|
public static final System.Logger LOG = System.getLogger(Task.class.getSimpleName()); |
|
|
|
|
|
|
|
private final long id, projectId; |
|
|
|
|
|
|
|
private final Long parentTaskId; |
|
|
|
|
|
|
|
private String name; |
|
|
|
|
|
|
|
private String description; |
|
|
|
|
|
|
|
private Status status; |
|
|
|
|
|
|
|
private final Double estimatedTime; |
|
|
|
|
|
|
|
private final LocalDate start, dueDate; |
|
|
|
|
|
|
|
private boolean showClosed; |
|
|
|
|
|
|
|
private final boolean noIndex; |
|
|
|
|
|
|
|
private final Map<Long, Member> members; |
|
|
|
|
|
|
|
private final Set<String> dirtyFields = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Task (long id, long projectId, Long parentTaskId, String name, String description, Status status, Double estimatedTime, LocalDate start, LocalDate dueDate, boolean showClosed, boolean noIndex, Map<Long,Member> members){ |
|
|
|
|
|
|
|
this.id = id; |
|
|
|
|
|
|
|
this.projectId = projectId; |
|
|
|
|
|
|
|
this.parentTaskId = parentTaskId; |
|
|
|
|
|
|
|
this.name = name; |
|
|
|
|
|
|
|
this.description = description; |
|
|
|
|
|
|
|
this.status = status; |
|
|
|
|
|
|
|
this.estimatedTime = estimatedTime; |
|
|
|
|
|
|
|
this.start = start; |
|
|
|
|
|
|
|
this.dueDate = dueDate; |
|
|
|
|
|
|
|
this.showClosed = showClosed; |
|
|
|
|
|
|
|
this.noIndex = noIndex; |
|
|
|
|
|
|
|
this.members = members; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void clean() { |
|
|
|
|
|
|
|
dirtyFields.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String description(){ |
|
|
|
|
|
|
|
return description; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public LocalDate dueDate(){ |
|
|
|
|
|
|
|
return dueDate; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Double estimatedTime(){ |
|
|
|
|
|
|
|
return estimatedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public long id(){ |
|
|
|
|
|
|
|
return id; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean isDirty() { |
|
|
|
|
|
|
|
return !dirtyFields.isEmpty(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Map<Long,Member> members(){ |
|
|
|
|
|
|
|
return members; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String name(){ |
|
|
|
|
|
|
|
return name; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean noIndex(){ |
|
|
|
|
|
|
|
return noIndex; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public record Task(long id, long projectId, Long parentTaskId, String name, String description, Status status, Double estimatedTime, LocalDate start, LocalDate dueDate, boolean showClosed, boolean noIndex, Map<Long,Member> members) implements Mappable { |
|
|
|
|
|
|
|
public static Task of(ResultSet rs) throws SQLException { |
|
|
|
public static Task of(ResultSet rs) throws SQLException { |
|
|
|
var estTime = rs.getDouble(EST_TIME); |
|
|
|
var estTime = rs.getDouble(EST_TIME); |
|
|
|
var parentTaskId = rs.getLong(PARENT_TASK_ID); |
|
|
|
var parentTaskId = rs.getLong(PARENT_TASK_ID); |
|
|
|
@ -69,6 +134,43 @@ public record Task(long id, long projectId, Long parentTaskId, String name, Stri |
|
|
|
return new Task(0,prjId.longValue(),parentTaskId,name,description,status,estimatedTime,startDate,dueDate,showClosed,noIndex,new HashMap<>()); |
|
|
|
return new Task(0,prjId.longValue(),parentTaskId,name,description,status,estimatedTime,startDate,dueDate,showClosed,noIndex,new HashMap<>()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Task patch(JSONObject json) { |
|
|
|
|
|
|
|
for (var key : json.keySet()){ |
|
|
|
|
|
|
|
switch (key){ |
|
|
|
|
|
|
|
case DESCRIPTION: description = json.getString(key); break; |
|
|
|
|
|
|
|
case NAME: name = json.getString(key); break; |
|
|
|
|
|
|
|
case SHOW_CLOSED: showClosed = json.getBoolean(SHOW_CLOSED); break; |
|
|
|
|
|
|
|
case STATUS: status = json.get(key) instanceof Number number ? Status.of(number.intValue()) : Status.valueOf(json.getString(key)); break; |
|
|
|
|
|
|
|
default: { |
|
|
|
|
|
|
|
key = null; |
|
|
|
|
|
|
|
LOG.log(WARNING,"Tried to patch field ''{0}'' of task, which is not implemented!"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (key != null) dirtyFields.add(key); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return this; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Long parentTaskId(){ |
|
|
|
|
|
|
|
return parentTaskId; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public long projectId(){ |
|
|
|
|
|
|
|
return projectId; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean showClosed(){ |
|
|
|
|
|
|
|
return showClosed; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public LocalDate start(){ |
|
|
|
|
|
|
|
return start; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Status status(){ |
|
|
|
|
|
|
|
return status; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Map<String, Object> toMap() { |
|
|
|
public Map<String, Object> toMap() { |
|
|
|
var map = new HashMap<String,Object>(); |
|
|
|
var map = new HashMap<String,Object>(); |
|
|
|
@ -95,4 +197,5 @@ public record Task(long id, long projectId, Long parentTaskId, String name, Stri |
|
|
|
public boolean hasMember(UmbrellaUser user) { |
|
|
|
public boolean hasMember(UmbrellaUser user) { |
|
|
|
return members.containsKey(user.id()); |
|
|
|
return members.containsKey(user.id()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|