diff --git a/src/main/bundles/prod.bundle b/src/main/bundles/prod.bundle index 26f8738..4ffda7b 100644 Binary files a/src/main/bundles/prod.bundle and b/src/main/bundles/prod.bundle differ diff --git a/src/main/java/de/assecutor/votianlt/config/MongoConfig.java b/src/main/java/de/assecutor/votianlt/config/MongoConfig.java index 161c377..d301b95 100644 --- a/src/main/java/de/assecutor/votianlt/config/MongoConfig.java +++ b/src/main/java/de/assecutor/votianlt/config/MongoConfig.java @@ -1,6 +1,7 @@ package de.assecutor.votianlt.config; import de.assecutor.votianlt.model.task.*; +import de.assecutor.votianlt.model.task.CommentTask; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; @@ -96,6 +97,17 @@ public class MongoConfig { ((BarcodeTask) task).setMaxBarcodeCount(source.getInteger("max_barcode_count")); } break; + case "de.assecutor.votianlt.model.task.CommentTask": + case "CommentTask": + log.debug("Creating CommentTask"); + task = new CommentTask(); + if (source.containsKey("comment_text")) { + ((CommentTask) task).setCommentText(source.getString("comment_text")); + } + if (source.containsKey("required")) { + ((CommentTask) task).setRequired(source.getBoolean("required", false)); + } + break; default: log.warn("Unknown className '{}', falling back to ConfirmationTask", className); task = new ConfirmationTask(); // fallback @@ -109,9 +121,6 @@ public class MongoConfig { if (source.containsKey("job_id")) { task.setJobId(source.getObjectId("job_id")); } - if (source.containsKey("text")) { - task.setText(source.getString("text")); - } if (source.containsKey("task_order")) { task.setTaskOrder(source.getInteger("task_order", 0)); } @@ -150,6 +159,8 @@ public class MongoConfig { return "de.assecutor.votianlt.model.task.TodoListTask"; case "BARCODE": return "de.assecutor.votianlt.model.task.BarcodeTask"; + case "COMMENT": + return "de.assecutor.votianlt.model.task.CommentTask"; default: return "de.assecutor.votianlt.model.task.ConfirmationTask"; } diff --git a/src/main/java/de/assecutor/votianlt/model/task/BaseTask.java b/src/main/java/de/assecutor/votianlt/model/task/BaseTask.java index 766f2e7..5af066e 100644 --- a/src/main/java/de/assecutor/votianlt/model/task/BaseTask.java +++ b/src/main/java/de/assecutor/votianlt/model/task/BaseTask.java @@ -21,7 +21,8 @@ import java.time.LocalDateTime; @JsonSubTypes.Type(value = SignatureTask.class, name = "SIGNATURE"), @JsonSubTypes.Type(value = TodoListTask.class, name = "TODOLIST"), @JsonSubTypes.Type(value = PhotoTask.class, name = "PHOTO"), - @JsonSubTypes.Type(value = BarcodeTask.class, name = "BARCODE") }) + @JsonSubTypes.Type(value = BarcodeTask.class, name = "BARCODE"), + @JsonSubTypes.Type(value = CommentTask.class, name = "COMMENT") }) public abstract class BaseTask { @Id @JsonIgnore @@ -31,9 +32,6 @@ public abstract class BaseTask { @JsonIgnore private ObjectId jobId; - @Field("text") - private String text; - @Field("task_order") private Integer taskOrder = 0; diff --git a/src/main/java/de/assecutor/votianlt/model/task/CommentTask.java b/src/main/java/de/assecutor/votianlt/model/task/CommentTask.java new file mode 100644 index 0000000..2dbcb76 --- /dev/null +++ b/src/main/java/de/assecutor/votianlt/model/task/CommentTask.java @@ -0,0 +1,44 @@ +package de.assecutor.votianlt.model.task; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.springframework.data.mongodb.core.mapping.Field; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class CommentTask extends BaseTask { + + @Field("comment_text") + private String commentText; + + @Field("required") + private boolean required = false; + + public CommentTask(String commentText, boolean required) { + this.commentText = commentText; + this.required = required; + } + + @Override + public String getTaskType() { + return "COMMENT"; + } + + @Override + public String getDisplayName() { + return "Kommentar"; + } + + @Override + public Object getTaskSpecificData() { + return new TaskSpecificData(); + } + + public class TaskSpecificData { + public String taskType = getTaskType(); + public String commentText = CommentTask.this.commentText; + public boolean required = CommentTask.this.required; + } +} \ No newline at end of file diff --git a/src/main/java/de/assecutor/votianlt/model/task/TaskType.java b/src/main/java/de/assecutor/votianlt/model/task/TaskType.java index 6355c6d..36562bb 100644 --- a/src/main/java/de/assecutor/votianlt/model/task/TaskType.java +++ b/src/main/java/de/assecutor/votianlt/model/task/TaskType.java @@ -1,7 +1,7 @@ package de.assecutor.votianlt.model.task; public enum TaskType { - CONFIRMATION("Bestätigung"), SIGNATURE("Unterschrift"), TODOLIST("To-Do Liste"), PHOTO("Foto"), BARCODE("Barcode"); + CONFIRMATION("Bestätigung"), SIGNATURE("Unterschrift"), TODOLIST("To-Do Liste"), PHOTO("Foto"), BARCODE("Barcode"), COMMENT("Kommentar"); private final String displayName; diff --git a/src/main/java/de/assecutor/votianlt/pages/view/AddJobView.java b/src/main/java/de/assecutor/votianlt/pages/view/AddJobView.java index cbd623f..1a555c2 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/AddJobView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/AddJobView.java @@ -35,6 +35,7 @@ import de.assecutor.votianlt.model.task.SignatureTask; import de.assecutor.votianlt.model.task.TodoListTask; import de.assecutor.votianlt.model.task.PhotoTask; import de.assecutor.votianlt.model.task.BarcodeTask; +import de.assecutor.votianlt.model.task.CommentTask; import de.assecutor.votianlt.pages.service.AddJobService; import de.assecutor.votianlt.pages.service.CustomerService; import de.assecutor.votianlt.pages.base.ui.component.ViewToolbar; @@ -1531,24 +1532,24 @@ public class AddJobView extends Main { BaseTask newTask = createTaskByType(selectedType); BaseTask oldTask = currentTask[0]; - newTask.setText(oldTask.getText()); newTask.setCompleted(oldTask.isCompleted()); newTask.setCompletedAt(oldTask.getCompletedAt()); newTask.setCompletedBy(oldTask.getCompletedBy()); // Preserve task-specific properties - if (oldTask instanceof ConfirmationTask oldConfirmationTask - && newTask instanceof ConfirmationTask newConfirmationTask) { - newConfirmationTask.setButtonText(oldConfirmationTask.getButtonText()); - } else if (oldTask instanceof TodoListTask oldTodoTask && newTask instanceof TodoListTask newTodoTask) { - newTodoTask.setTodoItems(oldTodoTask.getTodoItems()); - } else if (oldTask instanceof PhotoTask oldPhotoTask && newTask instanceof PhotoTask newPhotoTask) { - newPhotoTask.setMinPhotoCount(oldPhotoTask.getMinPhotoCount()); - newPhotoTask.setMaxPhotoCount(oldPhotoTask.getMaxPhotoCount()); - } else if (oldTask instanceof BarcodeTask oldBarcodeTask - && newTask instanceof BarcodeTask newBarcodeTask) { - newBarcodeTask.setMinBarcodeCount(oldBarcodeTask.getMinBarcodeCount()); - newBarcodeTask.setMaxBarcodeCount(oldBarcodeTask.getMaxBarcodeCount()); + switch (oldTask) { + case ConfirmationTask oldConfirmationTask when newTask instanceof ConfirmationTask newConfirmationTask -> newConfirmationTask.setButtonText(oldConfirmationTask.getButtonText()); + case TodoListTask oldTodoTask when newTask instanceof TodoListTask newTodoTask -> newTodoTask.setTodoItems(oldTodoTask.getTodoItems()); + case PhotoTask oldPhotoTask when newTask instanceof PhotoTask newPhotoTask -> { + newPhotoTask.setMinPhotoCount(oldPhotoTask.getMinPhotoCount()); + newPhotoTask.setMaxPhotoCount(oldPhotoTask.getMaxPhotoCount()); + } + case BarcodeTask oldBarcodeTask when newTask instanceof BarcodeTask newBarcodeTask -> { + newBarcodeTask.setMinBarcodeCount(oldBarcodeTask.getMinBarcodeCount()); + newBarcodeTask.setMaxBarcodeCount(oldBarcodeTask.getMaxBarcodeCount()); + } + default -> { + } } // Replace in state and preserve order @@ -1577,6 +1578,7 @@ public class AddJobView extends Main { case TODOLIST -> new TodoListTask(new ArrayList<>()); case PHOTO -> new PhotoTask(1, 10); case BARCODE -> new BarcodeTask(1, 10); + case COMMENT -> new CommentTask("", false); }; } @@ -1594,8 +1596,6 @@ public class AddJobView extends Main { configContainer.removeAll(); TaskType taskType = TaskType.valueOf(task.getTaskType()); - if (taskType == null) - return; switch (taskType) { case CONFIRMATION: @@ -1606,12 +1606,8 @@ public class AddJobView extends Main { buttonTextField.setValue(confirmationTask.getButtonText() != null ? confirmationTask.getButtonText() : ""); buttonTextField.addValueChangeListener(ev -> { // Find the current ConfirmationTask in tasksState and update it - for (int i = 0; i < tasksState.size(); i++) { - BaseTask stateTask = tasksState.get(i); - if (stateTask == task && stateTask instanceof ConfirmationTask) { - ((ConfirmationTask) stateTask).setButtonText(ev.getValue()); - break; - } + for (BaseTask stateTask : tasksState) { + ((ConfirmationTask) stateTask).setButtonText(ev.getValue()); } }); configContainer.add(buttonTextField); @@ -1735,8 +1731,7 @@ public class AddJobView extends Main { private void updateTodoItems(VerticalLayout todoList, BaseTask task) { List todoItems = todoList.getChildren().map(component -> { - if (component instanceof HorizontalLayout) { - HorizontalLayout row = (HorizontalLayout) component; + if (component instanceof HorizontalLayout row) { TextField field = (TextField) row.getChildren().findFirst().orElse(null); return field != null ? field.getValue() : null; } diff --git a/src/main/java/de/assecutor/votianlt/pages/view/JobSummaryView.java b/src/main/java/de/assecutor/votianlt/pages/view/JobSummaryView.java index 0efe95c..7ee1caf 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/JobSummaryView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/JobSummaryView.java @@ -25,6 +25,7 @@ import de.assecutor.votianlt.model.task.PhotoTask; import de.assecutor.votianlt.model.task.SignatureTask; import de.assecutor.votianlt.model.task.ConfirmationTask; import de.assecutor.votianlt.model.task.BarcodeTask; +import de.assecutor.votianlt.model.task.CommentTask; import de.assecutor.votianlt.model.AppUser; import de.assecutor.votianlt.pages.base.ui.component.ViewToolbar; import lombok.extern.slf4j.Slf4j; @@ -579,6 +580,16 @@ public class JobSummaryView extends Main implements HasUrlParameter { log.debug("Failed to load barcodes for task {}: {}", task.getId(), e.getMessage()); } } + } else if (task instanceof CommentTask commentTask) { + content.add(new Span("Kommentar erforderlich")); + + if (commentTask.getCommentText() != null && !commentTask.getCommentText().isBlank()) { + content.add(new Span("Hinweis: " + commentTask.getCommentText())); + } + + if (commentTask.isRequired()) { + content.add(new Span("Pflichtfeld")); + } } } @@ -667,6 +678,8 @@ public class JobSummaryView extends Main implements HasUrlParameter { return new Icon(VaadinIcon.CHECK_CIRCLE); } else if (task instanceof BarcodeTask) { return new Icon(VaadinIcon.BARCODE); + } else if (task instanceof CommentTask) { + return new Icon(VaadinIcon.COMMENT); } else { return new Icon(VaadinIcon.TASKS); } @@ -704,6 +717,12 @@ public class JobSummaryView extends Main implements HasUrlParameter { } } else if (task instanceof BarcodeTask) { return "Barcode-Scan erforderlich"; + } else if (task instanceof CommentTask commentTask) { + if (commentTask.getCommentText() != null && !commentTask.getCommentText().isBlank()) { + return "Kommentar: " + commentTask.getCommentText(); + } else { + return "Kommentar erforderlich"; + } } return "Aufgabe offen"; diff --git a/src/main/java/de/assecutor/votianlt/service/EmailService.java b/src/main/java/de/assecutor/votianlt/service/EmailService.java index debe1a9..173ba94 100644 --- a/src/main/java/de/assecutor/votianlt/service/EmailService.java +++ b/src/main/java/de/assecutor/votianlt/service/EmailService.java @@ -145,6 +145,7 @@ public class EmailService { case "BARCODE" -> "Barcode scannen"; case "CONFIRMATION" -> "Bestätigung"; case "TODO_LIST" -> "Checkliste"; + case "COMMENT" -> "Kommentar"; default -> taskType; }; }