diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 36aa6e03..9b7230cb 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -23,6 +23,7 @@ dependencies{ implementation(project(":markdown")) implementation(project(":messages")) implementation(project(":notes")) + implementation(project(":poll")) implementation(project(":project")) implementation(project(":stock")) implementation(project(":tags")) diff --git a/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java b/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java index aa47ccf1..42e76b2a 100644 --- a/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java +++ b/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java @@ -23,6 +23,7 @@ import de.srsoftware.umbrella.markdown.MarkdownApi; import de.srsoftware.umbrella.message.MessageSystem; import de.srsoftware.umbrella.messagebus.MessageApi; import de.srsoftware.umbrella.notes.NoteModule; +import de.srsoftware.umbrella.poll.PollModule; import de.srsoftware.umbrella.project.ProjectModule; import de.srsoftware.umbrella.stock.StockModule; import de.srsoftware.umbrella.tags.TagModule; @@ -81,6 +82,7 @@ public class Application { new MarkdownApi().bindPath("/api/markdown").on(server); new NoteModule(config).bindPath("/api/notes").on(server); new StockModule(config).bindPath("/api/stock").on(server); + new PollModule(config).bindPath("/api/poll").on(server); new ProjectModule(config).bindPath("/api/project").on(server); new ProjectLegacy(config).bindPath("/legacy/project").on(server); new TaskModule(config).bindPath("/api/task").on(server); diff --git a/core/src/main/java/de/srsoftware/umbrella/core/ModuleRegistry.java b/core/src/main/java/de/srsoftware/umbrella/core/ModuleRegistry.java index ea02c2c0..dff11922 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/ModuleRegistry.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/ModuleRegistry.java @@ -12,6 +12,7 @@ public class ModuleRegistry { private FileService fileService; private MarkdownService markdownService; private NoteService noteService; + private PollService pollService; private PostBox postBox; private ProjectService projectService; private StockService stockService; @@ -33,9 +34,10 @@ public class ModuleRegistry { case ContactService cs: singleton.contactService = cs; break; case DocumentService ds: singleton.documentService = ds; break; case FileService fs: singleton.fileService = fs; break; - case StockService is: singleton.stockService = is; break; + case StockService is: singleton.stockService = is; break; case MarkdownService ms: singleton.markdownService = ms; break; case NoteService ns: singleton.noteService = ns; break; + case PollService ps: singleton.pollService = ps; break; case PostBox pb: singleton.postBox = pb; break; case ProjectService ps: singleton.projectService = ps; break; case TagService ts: singleton.tagService = ts; break; @@ -81,6 +83,10 @@ public class ModuleRegistry { return singleton.noteService; } + public static PollService pollService() { + return singleton.pollService; + } + public static PostBox postBox() { return singleton.postBox; } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/PollService.java b/core/src/main/java/de/srsoftware/umbrella/core/api/PollService.java new file mode 100644 index 00000000..c559ce2e --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/PollService.java @@ -0,0 +1,5 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.core.api; + +public interface PollService { +} diff --git a/core/src/main/java/de/srsoftware/umbrella/core/constants/Field.java b/core/src/main/java/de/srsoftware/umbrella/core/constants/Field.java index 8ec434c6..7a6ae833 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/constants/Field.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/constants/Field.java @@ -51,10 +51,12 @@ public class Field { public static final String DUE_DATE = "due_date"; public static final String DURATION = "duration"; + public static final String EDITOR = "editor"; public static final String EMAIL = "email"; public static final String END_TIME = "end_time"; public static final String ENTITY_ID = "entity_id"; public static final String EST_TIME = "est_time"; + public static final String EVALUATION = "evaluation"; public static final String EXPECTED = "expected"; public static final String EXPIRATION = "expiration"; @@ -102,7 +104,9 @@ public class Field { public static final String OBJECT = "object"; public static final String OFFSET = "offset"; + public static final String OPTIONS = "options"; public static final String OPTIONAL = "optional"; + public static final String OPTION_ID = "option_id"; public static final String OWNER = "owner"; public static final String OWNER_NUMBER = "owner_number"; @@ -113,11 +117,13 @@ public class Field { public static final String PATH = "path"; public static final String PERMISSION = "permission"; public static final String PHONE = "phone"; + public static final String POLL_ID = "poll_id"; public static final String POS = "pos"; public static final String POSITIONS = "positions"; public static final String PRICE = "single_price"; public static final String PRICE_FORMAT = "price_format"; public static final String PRIORITY = "priority"; + public static final String PRIVATE = "private"; public static final String PROJECT = "project"; public static final String PROJECT_ID = "project_id"; public static final String PROPERTIES = "properties"; @@ -127,9 +133,11 @@ public class Field { public static final String RENDERED = "rendered"; public static final String REQUIRED_TASKS_IDS = "required_tasks_ids"; + public static final String SELECTION = "selection"; public static final String SENDER = "sender"; public static final String SENDER_USER_ID = "sender_user_id"; public static final String SETTINGS = "settings"; + public static final String SHARES = "shares"; public static final String SHOW_CLOSED = "show_closed"; public static final String SILENT = "silent"; public static final String SOURCE = "source"; @@ -178,4 +186,6 @@ public class Field { public static final String VERSION = "version"; public static final String VERSIONS = "versions"; + public static final String WEIGHT = "weight"; + public static final String WEIGHTS = "weights"; } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/constants/Path.java b/core/src/main/java/de/srsoftware/umbrella/core/constants/Path.java index 853be141..5a0f7bb6 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/constants/Path.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/constants/Path.java @@ -13,6 +13,8 @@ public class Path { public static final String COMPANY = "company"; public static final String CONNECTED = "connected"; + public static final String EVALUATE = "evaluate"; + public static final String ITEM = "item"; public static final String JSON = "json"; @@ -27,16 +29,20 @@ public class Path { public static final String MENU = "menu"; - public static final String PAGE = "page"; - public static final String PASSWORD = "password"; - public static final String PROJECT = "project"; - public static final String PROPERTIES = "properties"; + public static final String OPTION = "option"; + + public static final String PAGE = "page"; + public static final String PASSWORD = "password"; + public static final String PERMISSIONS = "permissions"; + public static final String PROJECT = "project"; + public static final String PROPERTIES = "properties"; public static final String PROPERTY = "property"; public static final String READ = "read"; public static final String REDIRECT = "redirect"; public static final String SEARCH = "search"; + public static final String SELECT = "select"; public static final String SETTINGS = "settings"; public static final String STATES = "states"; public static final String STARTED = "started"; @@ -49,4 +55,5 @@ public class Path { public static final String USER = "user"; public static final String USES = "uses"; + public static final String WEIGHT = "weight"; } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/constants/Text.java b/core/src/main/java/de/srsoftware/umbrella/core/constants/Text.java index 562c3e46..41aab871 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/constants/Text.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/constants/Text.java @@ -24,6 +24,7 @@ public class Text { public static final String DOCUMENT_WITH_ID = "document ({id})"; public static final String EMAILS_FOR_RECEIVER = "emails for {email}"; + public static final String EVALUATION = "evaluation"; public static final String FILES = "files"; @@ -39,12 +40,18 @@ public class Text { public static final String MESSAGE = "message"; public static final String MESSAGES = "messages"; - public static final String NOTE = "note"; - public static final String NOTES = "notes"; - public static final String NOTE_WITH_ID = "note ({id})"; - public static final String NUMBER = "number"; + public static final String NOT_ALLOWED_TO_EDIT = "You are not allowed to edit {object}!"; + public static final String NOT_ALLOWED_TO_EVALUATE = "You are not allowed to evaluate this {object}!"; + public static final String NOTE = "note"; + public static final String NOTES = "notes"; + public static final String NOTE_WITH_ID = "note ({id})"; + public static final String NUMBER = "number"; + public static final Object OPTION = "option" + ; public static final String PATH = "path"; + public static final String PERMISSION = "permission"; + public static final String POLL = "poll"; public static final String POLLS = "polls"; public static final String PROJECTS = "projects"; public static final String PROJECT_WITH_ID = "project ({id})"; @@ -54,6 +61,7 @@ public class Text { public static final String RECEIVER = "receiver"; public static final String RECEIVERS = "receivers"; + public static final String SELECTIONS = "selections"; public static final String SENDER = "sender"; public static final String SERVICE_WITH_ID = "service ({id})"; public static final String SESSION = "session"; @@ -72,12 +80,14 @@ public class Text { public static final String UNIT = "unit"; public static final String USER_WITH_ID = "user ({id})"; + public static final String WEIGHT = "weight"; public static final String WIKI = "wiki"; public static final String WIKI_PAGE = "wiki page"; public static final String WIKI_PAGES = "wiki pages"; - public static final String UNIT_PRICE = "unit price"; - public static final String USER = "user"; - public static final String USERS = "users"; + public static final String UNIT_PRICE = "unit price"; + public static final String UNKNOWN_FIELD = "unknown field: {id}"; + public static final String USER = "user"; + public static final String USERS = "users"; } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Permission.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Permission.java index 5f0bd945..aa047de6 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Permission.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Permission.java @@ -31,7 +31,7 @@ public enum Permission implements Mappable { for (var p : Permission.values()){ if (p.code == code) return p; } - throw new InvalidParameterException(format("{0} is not a valid permission code")); + throw new InvalidParameterException(format("{0} is not a valid permission code",code)); } @Override diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Poll.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Poll.java new file mode 100644 index 00000000..6dbc6e64 --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Poll.java @@ -0,0 +1,248 @@ +package de.srsoftware.umbrella.core.model; + +import de.srsoftware.tools.Mappable; +import de.srsoftware.umbrella.core.ModuleRegistry; +import de.srsoftware.umbrella.core.Util; +import de.srsoftware.umbrella.core.api.Owner; +import de.srsoftware.umbrella.core.constants.Field; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + +import static de.srsoftware.umbrella.core.constants.Field.*; +import static java.text.MessageFormat.format; + +public class Poll implements Mappable { + public static class Option implements Mappable{ + + private int id; + + Integer status; + private String description; + private String name; + private final Set dirtyFields = new HashSet<>(); + public Option(int id, String name, String description, Integer status) { + this.id = id; + this.name = name; + this.description = description; + this.status = status; + } + public String description(){ + return description; + } + + public Option description(String newVal){ + description = newVal; + dirtyFields.add(DESCRIPTION); + return this; + } + + public int id(){ + return id; + } + + public Option id(Integer newVal){ + this.id = newVal; + dirtyFields.add(ID); + return this; + } + + public boolean isDirty(){ + return !dirtyFields.isEmpty(); + } + + public boolean isNew(){ + return dirtyFields.contains(ID); + } + + public String name(){ + return name; + } + + public Option name(String newVal){ + name = newVal; + dirtyFields.add(NAME); + return this; + } + + public static Option of(ResultSet rs) throws SQLException { + var id = rs.getInt(ID); + var name = rs.getString(NAME); + var description = rs.getString(DESCRIPTION); + var status = rs.getInt(STATUS); + + return new Option(id,name,description,status); + } + + public Integer status(){ + return status; + } + + public Option status(int newValue){ + this.status = newValue; + dirtyFields.add(STATUS); + return this; + } + + @Override + public Map toMap() { + return Map.of( + ID,id, + NAME,name, + DESCRIPTION, Map.of( + SOURCE,description, + RENDERED,Util.markdown(description) + ), + STATUS,status + ); + } + + @Override + public String toString() { + return format("Option \"{0}\"",name); + } + + + } + public static class Evaluation { + // Map