Version 0.9.14: E-Mail-Feld in Stationsdialogen und Kundenvalidierung
- E-Mail-Feld in Abhol- und Zustellstationsdialogen hinzugefügt - E-Mail-Pflichtfeld bei "Adresse speichern" mit Validierung - Kundenvalidierung im Backend (E-Mail Pflicht und Formatprüfung) - "Adresse speichern" wird bei Auswahl existierender Kunden deaktiviert - Verbessertes Kunden-Matching über alle Felder inkl. E-Mail - Übersetzung "Template" → "Vorlage" in messages_de.properties
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>0.9.13</revision>
|
<revision>0.9.14</revision>
|
||||||
<java.version>21</java.version>
|
<java.version>21</java.version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
private String firstName;
|
private String firstName;
|
||||||
private String lastName;
|
private String lastName;
|
||||||
private String phone;
|
private String phone;
|
||||||
|
private String mail;
|
||||||
private String street;
|
private String street;
|
||||||
private String houseNumber;
|
private String houseNumber;
|
||||||
private String addressAddition;
|
private String addressAddition;
|
||||||
@@ -112,6 +113,14 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
this.phone = phone;
|
this.phone = phone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMail() {
|
||||||
|
return mail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMail(String mail) {
|
||||||
|
this.mail = mail;
|
||||||
|
}
|
||||||
|
|
||||||
public String getStreet() {
|
public String getStreet() {
|
||||||
return street;
|
return street;
|
||||||
}
|
}
|
||||||
@@ -185,6 +194,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
private final TextField firstName;
|
private final TextField firstName;
|
||||||
private final TextField lastName;
|
private final TextField lastName;
|
||||||
private final TextField phone;
|
private final TextField phone;
|
||||||
|
private final TextField mail;
|
||||||
private final TextField street;
|
private final TextField street;
|
||||||
private final TextField houseNumber;
|
private final TextField houseNumber;
|
||||||
private final TextField addressAddition;
|
private final TextField addressAddition;
|
||||||
@@ -258,6 +268,12 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
phone.setWidthFull();
|
phone.setWidthFull();
|
||||||
formLayout.add(phone);
|
formLayout.add(phone);
|
||||||
|
|
||||||
|
// E-Mail
|
||||||
|
mail = new TextField(translationHelper.getTranslation("customers.column.email"));
|
||||||
|
mail.setPlaceholder(translationHelper.getTranslation("customers.column.email"));
|
||||||
|
mail.setWidthFull();
|
||||||
|
formLayout.add(mail);
|
||||||
|
|
||||||
// Street + house number
|
// Street + house number
|
||||||
street = new TextField(translationHelper.getTranslation("profile.street"));
|
street = new TextField(translationHelper.getTranslation("profile.street"));
|
||||||
street.setPlaceholder(translationHelper.getTranslation("profile.street"));
|
street.setPlaceholder(translationHelper.getTranslation("profile.street"));
|
||||||
@@ -307,12 +323,41 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
|
|
||||||
// Clear error styling on value change for required fields and update tab
|
// Clear error styling on value change for required fields and update tab
|
||||||
// indicators
|
// indicators
|
||||||
firstName.addValueChangeListener(ev -> validateRequiredFields());
|
firstName.addValueChangeListener(ev -> {
|
||||||
lastName.addValueChangeListener(ev -> validateRequiredFields());
|
validateRequiredFields();
|
||||||
street.addValueChangeListener(ev -> validateRequiredFields());
|
updateSaveAddressState();
|
||||||
houseNumber.addValueChangeListener(ev -> validateRequiredFields());
|
});
|
||||||
zip.addValueChangeListener(ev -> validateRequiredFields());
|
lastName.addValueChangeListener(ev -> {
|
||||||
city.addValueChangeListener(ev -> validateRequiredFields());
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
street.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
houseNumber.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
zip.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
city.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
salutation.addValueChangeListener(ev -> updateSaveAddressState());
|
||||||
|
phone.addValueChangeListener(ev -> updateSaveAddressState());
|
||||||
|
addressAddition.addValueChangeListener(ev -> updateSaveAddressState());
|
||||||
|
mail.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
saveAddress.addValueChangeListener(ev -> {
|
||||||
|
updateMailRequirement();
|
||||||
|
validateRequiredFields();
|
||||||
|
});
|
||||||
|
|
||||||
// TabSheet with address and tasks tabs
|
// TabSheet with address and tasks tabs
|
||||||
TabSheet tabSheet = new TabSheet();
|
TabSheet tabSheet = new TabSheet();
|
||||||
@@ -453,6 +498,10 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
lastName.setValue(data.getLastName());
|
lastName.setValue(data.getLastName());
|
||||||
if (data.getPhone() != null)
|
if (data.getPhone() != null)
|
||||||
phone.setValue(data.getPhone());
|
phone.setValue(data.getPhone());
|
||||||
|
if (data.getMail() != null)
|
||||||
|
mail.setValue(data.getMail());
|
||||||
|
else
|
||||||
|
mail.clear();
|
||||||
if (data.getStreet() != null)
|
if (data.getStreet() != null)
|
||||||
street.setValue(data.getStreet());
|
street.setValue(data.getStreet());
|
||||||
if (data.getHouseNumber() != null)
|
if (data.getHouseNumber() != null)
|
||||||
@@ -464,7 +513,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
if (data.getCity() != null)
|
if (data.getCity() != null)
|
||||||
city.setValue(data.getCity());
|
city.setValue(data.getCity());
|
||||||
saveAddress.setValue(customerSelectedFromOptions ? false : data.isSaveAddress());
|
saveAddress.setValue(customerSelectedFromOptions ? false : data.isSaveAddress());
|
||||||
updateSaveAddressState(customerSelectedFromOptions);
|
updateSaveAddressState();
|
||||||
|
|
||||||
// Load tasks into dialog state
|
// Load tasks into dialog state
|
||||||
if (data.getTasks() != null && !data.getTasks().isEmpty()) {
|
if (data.getTasks() != null && !data.getTasks().isEmpty()) {
|
||||||
@@ -482,6 +531,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeliveryData collectData() {
|
private DeliveryData collectData() {
|
||||||
@@ -491,6 +541,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
data.setFirstName(firstName.getValue());
|
data.setFirstName(firstName.getValue());
|
||||||
data.setLastName(lastName.getValue());
|
data.setLastName(lastName.getValue());
|
||||||
data.setPhone(phone.getValue());
|
data.setPhone(phone.getValue());
|
||||||
|
data.setMail(mail.getValue());
|
||||||
data.setStreet(street.getValue());
|
data.setStreet(street.getValue());
|
||||||
data.setHouseNumber(houseNumber.getValue());
|
data.setHouseNumber(houseNumber.getValue());
|
||||||
data.setAddressAddition(addressAddition.getValue());
|
data.setAddressAddition(addressAddition.getValue());
|
||||||
@@ -510,6 +561,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
addressValid &= validateTextField(houseNumber);
|
addressValid &= validateTextField(houseNumber);
|
||||||
addressValid &= validateTextField(zip);
|
addressValid &= validateTextField(zip);
|
||||||
addressValid &= validateTextField(city);
|
addressValid &= validateTextField(city);
|
||||||
|
addressValid &= validateMailField();
|
||||||
addressTabError.setVisible(!addressValid);
|
addressTabError.setVisible(!addressValid);
|
||||||
|
|
||||||
// Tasks tab validation
|
// Tasks tab validation
|
||||||
@@ -545,6 +597,17 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
return !empty;
|
return !empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean validateMailField() {
|
||||||
|
String value = mail.getValue();
|
||||||
|
String normalizedValue = value == null ? "" : value.trim();
|
||||||
|
boolean empty = normalizedValue.isEmpty();
|
||||||
|
boolean required = Boolean.TRUE.equals(saveAddress.getValue());
|
||||||
|
boolean invalid = !empty && !normalizedValue.contains("@");
|
||||||
|
boolean hasError = invalid || (required && empty);
|
||||||
|
applyErrorStyling(mail, hasError);
|
||||||
|
return !hasError;
|
||||||
|
}
|
||||||
|
|
||||||
private void applyErrorStyling(com.vaadin.flow.component.Component field, boolean error) {
|
private void applyErrorStyling(com.vaadin.flow.component.Component field, boolean error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
field.getElement().getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)");
|
field.getElement().getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)");
|
||||||
@@ -584,8 +647,8 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
|
|
||||||
companyField.addValueChangeListener(event -> {
|
companyField.addValueChangeListener(event -> {
|
||||||
Customer customer = companyAddressOptions.get(event.getValue());
|
Customer customer = companyAddressOptions.get(event.getValue());
|
||||||
updateSaveAddressState(customer != null);
|
|
||||||
if (customer == null) {
|
if (customer == null) {
|
||||||
|
updateSaveAddressState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,6 +663,8 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
lastName.setValue(customer.getLastName());
|
lastName.setValue(customer.getLastName());
|
||||||
if (customer.getTelephone() != null)
|
if (customer.getTelephone() != null)
|
||||||
phone.setValue(customer.getTelephone());
|
phone.setValue(customer.getTelephone());
|
||||||
|
if (customer.getMail() != null)
|
||||||
|
mail.setValue(customer.getMail());
|
||||||
if (customer.getStreet() != null)
|
if (customer.getStreet() != null)
|
||||||
street.setValue(customer.getStreet());
|
street.setValue(customer.getStreet());
|
||||||
if (customer.getHouseNumber() != null)
|
if (customer.getHouseNumber() != null)
|
||||||
@@ -610,22 +675,32 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
zip.setValue(customer.getZip());
|
zip.setValue(customer.getZip());
|
||||||
if (customer.getCity() != null)
|
if (customer.getCity() != null)
|
||||||
city.setValue(customer.getCity());
|
city.setValue(customer.getCity());
|
||||||
|
updateSaveAddressState();
|
||||||
});
|
});
|
||||||
|
|
||||||
companyField.addCustomValueSetListener(event -> {
|
companyField.addCustomValueSetListener(event -> {
|
||||||
companyField.setValue(event.getDetail());
|
companyField.setValue(event.getDetail());
|
||||||
updateSaveAddressState(false);
|
updateSaveAddressState();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSaveAddressState(boolean customerSelectedFromOptions) {
|
private void updateSaveAddressState() {
|
||||||
|
Customer selectedCustomer = companyAddressOptions.get(company.getValue());
|
||||||
|
boolean customerSelectedFromOptions = selectedCustomer != null && matchesCurrentCustomer(selectedCustomer);
|
||||||
|
|
||||||
if (customerSelectedFromOptions) {
|
if (customerSelectedFromOptions) {
|
||||||
saveAddress.setValue(false);
|
saveAddress.setValue(false);
|
||||||
saveAddress.setEnabled(false);
|
saveAddress.setEnabled(false);
|
||||||
|
updateMailRequirement();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveAddress.setEnabled(true);
|
saveAddress.setEnabled(true);
|
||||||
|
updateMailRequirement();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMailRequirement() {
|
||||||
|
mail.setRequiredIndicatorVisible(Boolean.TRUE.equals(saveAddress.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildCompanyAddressLabel(Customer customer) {
|
private String buildCompanyAddressLabel(Customer customer) {
|
||||||
@@ -687,12 +762,32 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
|
|
||||||
private boolean matchesCustomer(Customer customer, DeliveryData data) {
|
private boolean matchesCustomer(Customer customer, DeliveryData data) {
|
||||||
return equalsNormalized(customer.getCompanyName(), data.getCompany())
|
return equalsNormalized(customer.getCompanyName(), data.getCompany())
|
||||||
|
&& equalsNormalized(customer.getTitle(), data.getSalutation())
|
||||||
|
&& equalsNormalized(customer.getFirstname(), data.getFirstName())
|
||||||
|
&& equalsNormalized(customer.getLastName(), data.getLastName())
|
||||||
|
&& equalsNormalized(customer.getTelephone(), data.getPhone())
|
||||||
|
&& equalsNormalized(customer.getMail(), data.getMail())
|
||||||
&& equalsNormalized(customer.getStreet(), data.getStreet())
|
&& equalsNormalized(customer.getStreet(), data.getStreet())
|
||||||
|
&& equalsNormalized(customer.getAddressAddition(), data.getAddressAddition())
|
||||||
&& equalsNormalized(customer.getHouseNumber(), data.getHouseNumber())
|
&& equalsNormalized(customer.getHouseNumber(), data.getHouseNumber())
|
||||||
&& equalsNormalized(customer.getZip(), data.getZip())
|
&& equalsNormalized(customer.getZip(), data.getZip())
|
||||||
&& equalsNormalized(customer.getCity(), data.getCity());
|
&& equalsNormalized(customer.getCity(), data.getCity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean matchesCurrentCustomer(Customer customer) {
|
||||||
|
return equalsNormalized(customer.getCompanyName(), resolveCompanyValue(company.getValue()))
|
||||||
|
&& equalsNormalized(customer.getTitle(), salutation.getValue())
|
||||||
|
&& equalsNormalized(customer.getFirstname(), firstName.getValue())
|
||||||
|
&& equalsNormalized(customer.getLastName(), lastName.getValue())
|
||||||
|
&& equalsNormalized(customer.getTelephone(), phone.getValue())
|
||||||
|
&& equalsNormalized(customer.getMail(), mail.getValue())
|
||||||
|
&& equalsNormalized(customer.getStreet(), street.getValue())
|
||||||
|
&& equalsNormalized(customer.getAddressAddition(), addressAddition.getValue())
|
||||||
|
&& equalsNormalized(customer.getHouseNumber(), houseNumber.getValue())
|
||||||
|
&& equalsNormalized(customer.getZip(), zip.getValue())
|
||||||
|
&& equalsNormalized(customer.getCity(), city.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean equalsNormalized(String left, String right) {
|
private boolean equalsNormalized(String left, String right) {
|
||||||
String normalizedLeft = left != null ? left.trim() : "";
|
String normalizedLeft = left != null ? left.trim() : "";
|
||||||
String normalizedRight = right != null ? right.trim() : "";
|
String normalizedRight = right != null ? right.trim() : "";
|
||||||
@@ -756,8 +851,9 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
tasksList.setPadding(false);
|
tasksList.setPadding(false);
|
||||||
tasksList.setSpacing(true);
|
tasksList.setSpacing(true);
|
||||||
|
|
||||||
// Add 1 example row
|
// Add 1 example row, then append a signature task once on initial setup
|
||||||
createTaskRow();
|
createTaskRow();
|
||||||
|
ensureTrailingSignatureTask();
|
||||||
|
|
||||||
Button addTaskBtn = new Button(translationHelper.getTranslation("addjob.tasks.add"), new Icon(VaadinIcon.PLUS));
|
Button addTaskBtn = new Button(translationHelper.getTranslation("addjob.tasks.add"), new Icon(VaadinIcon.PLUS));
|
||||||
addTaskBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
addTaskBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
@@ -791,14 +887,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
Button deleteXButton = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
|
Button deleteXButton = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
|
||||||
deleteXButton.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
|
deleteXButton.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
|
||||||
deleteXButton.addClassName("dialog-floating-delete");
|
deleteXButton.addClassName("dialog-floating-delete");
|
||||||
deleteXButton.addClickListener(e -> {
|
deleteXButton.addClickListener(e -> removeTaskRow(taskContainer));
|
||||||
int idx = tasksList.getChildren().toList().indexOf(taskContainer);
|
|
||||||
if (idx >= 0 && idx < tasksState.size()) {
|
|
||||||
tasksState.remove(idx);
|
|
||||||
reorderTasksAfterDeletion();
|
|
||||||
}
|
|
||||||
tasksList.remove(taskContainer);
|
|
||||||
});
|
|
||||||
|
|
||||||
taskContainer.add(taskTypeCombo, configContainer);
|
taskContainer.add(taskTypeCombo, configContainer);
|
||||||
taskContainer.add(deleteXButton);
|
taskContainer.add(deleteXButton);
|
||||||
@@ -810,6 +899,9 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
|
|
||||||
final BaseTask[] currentTask = { task };
|
final BaseTask[] currentTask = { task };
|
||||||
|
|
||||||
|
taskTypeCombo.setValue(TaskType.CONFIRMATION);
|
||||||
|
updateTaskConfiguration(configContainer, currentTask[0]);
|
||||||
|
|
||||||
taskTypeCombo.addValueChangeListener(ev -> {
|
taskTypeCombo.addValueChangeListener(ev -> {
|
||||||
TaskType selectedType = ev.getValue();
|
TaskType selectedType = ev.getValue();
|
||||||
if (selectedType != null) {
|
if (selectedType != null) {
|
||||||
@@ -856,11 +948,8 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set initial configuration
|
|
||||||
taskTypeCombo.setValue(TaskType.CONFIRMATION);
|
|
||||||
updateTaskConfiguration(configContainer, currentTask[0]);
|
|
||||||
|
|
||||||
tasksList.add(taskContainer);
|
tasksList.add(taskContainer);
|
||||||
|
updateTaskDeleteAvailability();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTaskRowFromTask(BaseTask task) {
|
private void createTaskRowFromTask(BaseTask task) {
|
||||||
@@ -882,14 +971,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
Button deleteXButton = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
|
Button deleteXButton = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
|
||||||
deleteXButton.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
|
deleteXButton.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
|
||||||
deleteXButton.addClassName("dialog-floating-delete");
|
deleteXButton.addClassName("dialog-floating-delete");
|
||||||
deleteXButton.addClickListener(e -> {
|
deleteXButton.addClickListener(e -> removeTaskRow(taskContainer));
|
||||||
int idx = tasksList.getChildren().toList().indexOf(taskContainer);
|
|
||||||
if (idx >= 0 && idx < tasksState.size()) {
|
|
||||||
tasksState.remove(idx);
|
|
||||||
reorderTasksAfterDeletion();
|
|
||||||
}
|
|
||||||
tasksList.remove(taskContainer);
|
|
||||||
});
|
|
||||||
|
|
||||||
taskContainer.add(taskTypeCombo, configContainer);
|
taskContainer.add(taskTypeCombo, configContainer);
|
||||||
taskContainer.add(deleteXButton);
|
taskContainer.add(deleteXButton);
|
||||||
@@ -951,6 +1033,7 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
updateTaskConfiguration(configContainer, task);
|
updateTaskConfiguration(configContainer, task);
|
||||||
|
|
||||||
tasksList.add(taskContainer);
|
tasksList.add(taskContainer);
|
||||||
|
updateTaskDeleteAvailability();
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaseTask createTaskByType(TaskType taskType) {
|
private BaseTask createTaskByType(TaskType taskType) {
|
||||||
@@ -973,6 +1056,56 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeTaskRow(VerticalLayout taskContainer) {
|
||||||
|
if (tasksList == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<com.vaadin.flow.component.Component> taskRows = tasksList.getChildren().toList();
|
||||||
|
int idx = taskRows.indexOf(taskContainer);
|
||||||
|
if (idx < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < tasksState.size()) {
|
||||||
|
tasksState.remove(idx);
|
||||||
|
}
|
||||||
|
tasksList.remove(taskContainer);
|
||||||
|
reorderTasksAfterDeletion();
|
||||||
|
updateTaskDeleteAvailability();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureTrailingSignatureTask() {
|
||||||
|
BaseTask lastTask = tasksState.isEmpty() ? null : tasksState.get(tasksState.size() - 1);
|
||||||
|
if (lastTask instanceof SignatureTask) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignatureTask signatureTask = new SignatureTask();
|
||||||
|
signatureTask.setTaskOrder(tasksState.size());
|
||||||
|
tasksState.add(signatureTask);
|
||||||
|
if (tasksList != null) {
|
||||||
|
createTaskRowFromTask(signatureTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTaskDeleteAvailability() {
|
||||||
|
if (tasksList == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean deletable = tasksList.getChildren().count() > 1;
|
||||||
|
tasksList.getChildren()
|
||||||
|
.filter(VerticalLayout.class::isInstance)
|
||||||
|
.map(VerticalLayout.class::cast)
|
||||||
|
.forEach(taskContainer -> taskContainer.getChildren()
|
||||||
|
.filter(Button.class::isInstance)
|
||||||
|
.map(Button.class::cast)
|
||||||
|
.filter(button -> button.getClassNames().contains("dialog-floating-delete"))
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(button -> button.setEnabled(deletable)));
|
||||||
|
}
|
||||||
|
|
||||||
private void updateTaskConfiguration(VerticalLayout configContainer, BaseTask task) {
|
private void updateTaskConfiguration(VerticalLayout configContainer, BaseTask task) {
|
||||||
configContainer.removeAll();
|
configContainer.removeAll();
|
||||||
|
|
||||||
@@ -1315,16 +1448,22 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadTasksFromTemplate(TaskTemplate template, ComboBox<TaskTemplate> templateComboBox) {
|
private void loadTasksFromTemplate(TaskTemplate template, ComboBox<TaskTemplate> templateComboBox) {
|
||||||
ConfirmDialog confirmDialog = new ConfirmDialog();
|
Dialog confirmDialog = DialogStylingHelper
|
||||||
confirmDialog.setHeader(translationHelper.getTranslation("addjob.tasks.template.load.title"));
|
.createStyledDialog(translationHelper.getTranslation("addjob.tasks.template.load.title"), "560px");
|
||||||
confirmDialog.setText(
|
confirmDialog.setCloseOnOutsideClick(false);
|
||||||
translationHelper.getTranslation("addjob.tasks.template.load.text", template.getTemplateName()));
|
confirmDialog.addDialogCloseActionListener(e -> templateComboBox.clear());
|
||||||
confirmDialog.setCancelable(true);
|
|
||||||
confirmDialog.setCancelText(translationHelper.getTranslation("button.cancel"));
|
|
||||||
confirmDialog.setConfirmText(translationHelper.getTranslation("addjob.tasks.template.load.confirm"));
|
|
||||||
confirmDialog.setConfirmButtonTheme("primary");
|
|
||||||
|
|
||||||
confirmDialog.addConfirmListener(e -> {
|
VerticalLayout dialogContent = DialogStylingHelper.createContentLayout("420px");
|
||||||
|
dialogContent.add(new Span(
|
||||||
|
translationHelper.getTranslation("addjob.tasks.template.load.text", template.getTemplateName())));
|
||||||
|
|
||||||
|
Button cancelButton = new Button(translationHelper.getTranslation("button.cancel"), e -> {
|
||||||
|
templateComboBox.clear();
|
||||||
|
confirmDialog.close();
|
||||||
|
});
|
||||||
|
cancelButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
|
||||||
|
|
||||||
|
Button confirmButton = new Button(translationHelper.getTranslation("addjob.tasks.template.load.confirm"), e -> {
|
||||||
tasksState.clear();
|
tasksState.clear();
|
||||||
tasksList.removeAll();
|
tasksList.removeAll();
|
||||||
|
|
||||||
@@ -1338,16 +1477,19 @@ public class DeliveryStationDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensureTrailingSignatureTask();
|
||||||
templateComboBox.clear();
|
templateComboBox.clear();
|
||||||
validateRequiredFields();
|
validateRequiredFields();
|
||||||
|
|
||||||
Notification.show(
|
Notification.show(
|
||||||
translationHelper.getTranslation("addjob.tasks.template.loaded", template.getTemplateName()), 3000,
|
translationHelper.getTranslation("addjob.tasks.template.loaded", template.getTemplateName()), 3000,
|
||||||
Notification.Position.BOTTOM_END);
|
Notification.Position.BOTTOM_END);
|
||||||
|
confirmDialog.close();
|
||||||
});
|
});
|
||||||
|
confirmButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
|
|
||||||
confirmDialog.addCancelListener(e -> templateComboBox.clear());
|
confirmDialog.add(DialogStylingHelper.wrapContent(dialogContent));
|
||||||
|
confirmDialog.getFooter().add(cancelButton, confirmButton);
|
||||||
confirmDialog.open();
|
confirmDialog.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public class PickupStationDialog extends Dialog {
|
|||||||
private String firstName;
|
private String firstName;
|
||||||
private String lastName;
|
private String lastName;
|
||||||
private String phone;
|
private String phone;
|
||||||
|
private String mail;
|
||||||
private String street;
|
private String street;
|
||||||
private String houseNumber;
|
private String houseNumber;
|
||||||
private String addressAddition;
|
private String addressAddition;
|
||||||
@@ -125,6 +126,14 @@ public class PickupStationDialog extends Dialog {
|
|||||||
this.phone = phone;
|
this.phone = phone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMail() {
|
||||||
|
return mail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMail(String mail) {
|
||||||
|
this.mail = mail;
|
||||||
|
}
|
||||||
|
|
||||||
public String getStreet() {
|
public String getStreet() {
|
||||||
return street;
|
return street;
|
||||||
}
|
}
|
||||||
@@ -231,6 +240,7 @@ public class PickupStationDialog extends Dialog {
|
|||||||
private final TextField firstName;
|
private final TextField firstName;
|
||||||
private final TextField lastName;
|
private final TextField lastName;
|
||||||
private final TextField phone;
|
private final TextField phone;
|
||||||
|
private final TextField mail;
|
||||||
private final TextField street;
|
private final TextField street;
|
||||||
private final TextField houseNumber;
|
private final TextField houseNumber;
|
||||||
private final TextField addressAddition;
|
private final TextField addressAddition;
|
||||||
@@ -239,6 +249,8 @@ public class PickupStationDialog extends Dialog {
|
|||||||
private final Checkbox saveAddress;
|
private final Checkbox saveAddress;
|
||||||
|
|
||||||
private final ComboBox<String> customerComboBox;
|
private final ComboBox<String> customerComboBox;
|
||||||
|
private final Map<String, Customer> customerLabelMap = new LinkedHashMap<>();
|
||||||
|
private final Map<String, Customer> companyCustomerMap = new LinkedHashMap<>();
|
||||||
private DatePicker appointmentDatePicker;
|
private DatePicker appointmentDatePicker;
|
||||||
private TimePicker appointmentTimePicker;
|
private TimePicker appointmentTimePicker;
|
||||||
private Checkbox digitalProcessingCheckbox;
|
private Checkbox digitalProcessingCheckbox;
|
||||||
@@ -278,7 +290,7 @@ public class PickupStationDialog extends Dialog {
|
|||||||
customerComboBox.setRequiredIndicatorVisible(true);
|
customerComboBox.setRequiredIndicatorVisible(true);
|
||||||
customerComboBox.setWidthFull();
|
customerComboBox.setWidthFull();
|
||||||
|
|
||||||
Map<String, Customer> customerLabelMap = new LinkedHashMap<>();
|
customerLabelMap.clear();
|
||||||
for (Customer c : customers) {
|
for (Customer c : customers) {
|
||||||
String label = (c.getCompanyName() != null && !c.getCompanyName().isBlank())
|
String label = (c.getCompanyName() != null && !c.getCompanyName().isBlank())
|
||||||
? c.getCompanyName() + " | "
|
? c.getCompanyName() + " | "
|
||||||
@@ -330,6 +342,11 @@ public class PickupStationDialog extends Dialog {
|
|||||||
phone.setPlaceholder(translationHelper.getTranslation("profile.phone"));
|
phone.setPlaceholder(translationHelper.getTranslation("profile.phone"));
|
||||||
phone.setWidthFull();
|
phone.setWidthFull();
|
||||||
|
|
||||||
|
// E-Mail
|
||||||
|
mail = new TextField(translationHelper.getTranslation("customers.column.email"));
|
||||||
|
mail.setPlaceholder(translationHelper.getTranslation("customers.column.email"));
|
||||||
|
mail.setWidthFull();
|
||||||
|
|
||||||
// Street + house number
|
// Street + house number
|
||||||
street = new TextField(translationHelper.getTranslation("profile.street"));
|
street = new TextField(translationHelper.getTranslation("profile.street"));
|
||||||
street.setPlaceholder(translationHelper.getTranslation("profile.street"));
|
street.setPlaceholder(translationHelper.getTranslation("profile.street"));
|
||||||
@@ -375,22 +392,54 @@ public class PickupStationDialog extends Dialog {
|
|||||||
|
|
||||||
// Clear error styling on value change for required fields and update tab
|
// Clear error styling on value change for required fields and update tab
|
||||||
// indicators
|
// indicators
|
||||||
firstName.addValueChangeListener(ev -> validateRequiredFields());
|
firstName.addValueChangeListener(ev -> {
|
||||||
lastName.addValueChangeListener(ev -> validateRequiredFields());
|
validateRequiredFields();
|
||||||
street.addValueChangeListener(ev -> validateRequiredFields());
|
updateSaveAddressState();
|
||||||
houseNumber.addValueChangeListener(ev -> validateRequiredFields());
|
});
|
||||||
zip.addValueChangeListener(ev -> validateRequiredFields());
|
lastName.addValueChangeListener(ev -> {
|
||||||
city.addValueChangeListener(ev -> validateRequiredFields());
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
street.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
houseNumber.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
zip.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
city.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
salutation.addValueChangeListener(ev -> updateSaveAddressState());
|
||||||
|
phone.addValueChangeListener(ev -> updateSaveAddressState());
|
||||||
|
addressAddition.addValueChangeListener(ev -> updateSaveAddressState());
|
||||||
|
mail.addValueChangeListener(ev -> {
|
||||||
|
validateRequiredFields();
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
saveAddress.addValueChangeListener(ev -> {
|
||||||
|
updateMailRequirement();
|
||||||
|
validateRequiredFields();
|
||||||
|
});
|
||||||
|
|
||||||
// Customer selection fills address fields
|
// Customer selection fills address fields
|
||||||
customerComboBox.addValueChangeListener(ev -> {
|
customerComboBox.addValueChangeListener(ev -> {
|
||||||
String selected = ev.getValue();
|
String selected = ev.getValue();
|
||||||
if (selected == null)
|
if (selected == null) {
|
||||||
|
updateSaveAddressState();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
Customer c = customerLabelMap.get(selected);
|
Customer c = customerLabelMap.get(selected);
|
||||||
if (c == null)
|
if (c == null) {
|
||||||
|
updateSaveAddressState();
|
||||||
return;
|
return;
|
||||||
saveAddress.setValue(false);
|
}
|
||||||
if (c.getCompanyName() != null)
|
if (c.getCompanyName() != null)
|
||||||
company.setValue(c.getCompanyName());
|
company.setValue(c.getCompanyName());
|
||||||
else
|
else
|
||||||
@@ -412,6 +461,10 @@ public class PickupStationDialog extends Dialog {
|
|||||||
phone.setValue(c.getTelephone());
|
phone.setValue(c.getTelephone());
|
||||||
else
|
else
|
||||||
phone.clear();
|
phone.clear();
|
||||||
|
if (c.getMail() != null)
|
||||||
|
mail.setValue(c.getMail());
|
||||||
|
else
|
||||||
|
mail.clear();
|
||||||
if (c.getStreet() != null)
|
if (c.getStreet() != null)
|
||||||
street.setValue(c.getStreet());
|
street.setValue(c.getStreet());
|
||||||
else
|
else
|
||||||
@@ -432,10 +485,12 @@ public class PickupStationDialog extends Dialog {
|
|||||||
city.setValue(c.getCity());
|
city.setValue(c.getCity());
|
||||||
else
|
else
|
||||||
city.clear();
|
city.clear();
|
||||||
|
|
||||||
|
updateSaveAddressState();
|
||||||
});
|
});
|
||||||
|
|
||||||
formLayout.add(customerComboBox, company, salutation, firstName, lastName, phone, streetLayout, addressAddition,
|
formLayout.add(customerComboBox, company, salutation, firstName, lastName, phone, mail, streetLayout,
|
||||||
zipCityLayout, saveAddress);
|
addressAddition, zipCityLayout, saveAddress);
|
||||||
|
|
||||||
// TabSheet with address, appointments, and cargo tabs
|
// TabSheet with address, appointments, and cargo tabs
|
||||||
TabSheet tabSheet = new TabSheet();
|
TabSheet tabSheet = new TabSheet();
|
||||||
@@ -564,6 +619,11 @@ public class PickupStationDialog extends Dialog {
|
|||||||
public void setData(PickupData data) {
|
public void setData(PickupData data) {
|
||||||
if (data == null)
|
if (data == null)
|
||||||
return;
|
return;
|
||||||
|
if (data.getCustomerSelection() != null) {
|
||||||
|
customerComboBox.setValue(data.getCustomerSelection());
|
||||||
|
} else {
|
||||||
|
customerComboBox.clear();
|
||||||
|
}
|
||||||
if (data.getCompany() != null)
|
if (data.getCompany() != null)
|
||||||
company.setValue(data.getCompany());
|
company.setValue(data.getCompany());
|
||||||
if (data.getSalutation() != null)
|
if (data.getSalutation() != null)
|
||||||
@@ -574,6 +634,10 @@ public class PickupStationDialog extends Dialog {
|
|||||||
lastName.setValue(data.getLastName());
|
lastName.setValue(data.getLastName());
|
||||||
if (data.getPhone() != null)
|
if (data.getPhone() != null)
|
||||||
phone.setValue(data.getPhone());
|
phone.setValue(data.getPhone());
|
||||||
|
if (data.getMail() != null)
|
||||||
|
mail.setValue(data.getMail());
|
||||||
|
else
|
||||||
|
mail.clear();
|
||||||
if (data.getStreet() != null)
|
if (data.getStreet() != null)
|
||||||
street.setValue(data.getStreet());
|
street.setValue(data.getStreet());
|
||||||
if (data.getHouseNumber() != null)
|
if (data.getHouseNumber() != null)
|
||||||
@@ -584,11 +648,6 @@ public class PickupStationDialog extends Dialog {
|
|||||||
zip.setValue(data.getZip());
|
zip.setValue(data.getZip());
|
||||||
if (data.getCity() != null)
|
if (data.getCity() != null)
|
||||||
city.setValue(data.getCity());
|
city.setValue(data.getCity());
|
||||||
saveAddress.setValue(data.isSaveAddress());
|
|
||||||
|
|
||||||
if (data.getCustomerSelection() != null) {
|
|
||||||
customerComboBox.setValue(data.getCustomerSelection());
|
|
||||||
}
|
|
||||||
if (data.getAppointmentDate() != null && appointmentDatePicker != null) {
|
if (data.getAppointmentDate() != null && appointmentDatePicker != null) {
|
||||||
appointmentDatePicker.setValue(data.getAppointmentDate());
|
appointmentDatePicker.setValue(data.getAppointmentDate());
|
||||||
}
|
}
|
||||||
@@ -608,6 +667,9 @@ public class PickupStationDialog extends Dialog {
|
|||||||
addCargoRowWithData(item);
|
addCargoRowWithData(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveAddress.setValue(data.isSaveAddress());
|
||||||
|
updateSaveAddressState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PickupData collectData() {
|
private PickupData collectData() {
|
||||||
@@ -617,6 +679,7 @@ public class PickupStationDialog extends Dialog {
|
|||||||
data.setFirstName(firstName.getValue());
|
data.setFirstName(firstName.getValue());
|
||||||
data.setLastName(lastName.getValue());
|
data.setLastName(lastName.getValue());
|
||||||
data.setPhone(phone.getValue());
|
data.setPhone(phone.getValue());
|
||||||
|
data.setMail(mail.getValue());
|
||||||
data.setStreet(street.getValue());
|
data.setStreet(street.getValue());
|
||||||
data.setHouseNumber(houseNumber.getValue());
|
data.setHouseNumber(houseNumber.getValue());
|
||||||
data.setAddressAddition(addressAddition.getValue());
|
data.setAddressAddition(addressAddition.getValue());
|
||||||
@@ -649,6 +712,7 @@ public class PickupStationDialog extends Dialog {
|
|||||||
addressValid &= validateTextField(houseNumber);
|
addressValid &= validateTextField(houseNumber);
|
||||||
addressValid &= validateTextField(zip);
|
addressValid &= validateTextField(zip);
|
||||||
addressValid &= validateTextField(city);
|
addressValid &= validateTextField(city);
|
||||||
|
addressValid &= validateMailField();
|
||||||
if (addressTabError != null) {
|
if (addressTabError != null) {
|
||||||
addressTabError.setVisible(!addressValid);
|
addressTabError.setVisible(!addressValid);
|
||||||
}
|
}
|
||||||
@@ -685,6 +749,17 @@ public class PickupStationDialog extends Dialog {
|
|||||||
return !empty;
|
return !empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean validateMailField() {
|
||||||
|
String value = mail.getValue();
|
||||||
|
String normalizedValue = value == null ? "" : value.trim();
|
||||||
|
boolean empty = normalizedValue.isEmpty();
|
||||||
|
boolean required = Boolean.TRUE.equals(saveAddress.getValue());
|
||||||
|
boolean invalid = !empty && !normalizedValue.contains("@");
|
||||||
|
boolean hasError = invalid || (required && empty);
|
||||||
|
applyErrorStyling(mail, hasError);
|
||||||
|
return !hasError;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean validateCargoItems() {
|
private boolean validateCargoItems() {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
if (cargoList == null)
|
if (cargoList == null)
|
||||||
@@ -737,16 +812,25 @@ public class PickupStationDialog extends Dialog {
|
|||||||
List<String> companyNames = customers.stream().map(Customer::getCompanyName)
|
List<String> companyNames = customers.stream().map(Customer::getCompanyName)
|
||||||
.filter(name -> name != null && !name.trim().isEmpty()).distinct().sorted().toList();
|
.filter(name -> name != null && !name.trim().isEmpty()).distinct().sorted().toList();
|
||||||
|
|
||||||
|
companyCustomerMap.clear();
|
||||||
|
for (Customer customer : customers) {
|
||||||
|
String companyName = normalizeValue(customer.getCompanyName());
|
||||||
|
if (companyName.isEmpty() || companyCustomerMap.containsKey(companyName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
companyCustomerMap.put(companyName, customer);
|
||||||
|
}
|
||||||
companyField.setItems(companyNames);
|
companyField.setItems(companyNames);
|
||||||
|
|
||||||
companyField.addValueChangeListener(event -> {
|
companyField.addValueChangeListener(event -> {
|
||||||
String selectedCompany = event.getValue();
|
String selectedCompany = event.getValue();
|
||||||
if (selectedCompany == null || selectedCompany.trim().isEmpty()) {
|
if (selectedCompany == null || selectedCompany.trim().isEmpty()) {
|
||||||
|
updateSaveAddressState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Customer> matchingCustomer = customers.stream()
|
Optional<Customer> matchingCustomer = customers.stream()
|
||||||
.filter(c -> selectedCompany.equals(c.getCompanyName())).findFirst();
|
.filter(c -> sameValue(selectedCompany, c.getCompanyName())).findFirst();
|
||||||
|
|
||||||
if (matchingCustomer.isPresent()) {
|
if (matchingCustomer.isPresent()) {
|
||||||
Customer customer = matchingCustomer.get();
|
Customer customer = matchingCustomer.get();
|
||||||
@@ -761,6 +845,8 @@ public class PickupStationDialog extends Dialog {
|
|||||||
lastName.setValue(customer.getLastName());
|
lastName.setValue(customer.getLastName());
|
||||||
if (customer.getTelephone() != null)
|
if (customer.getTelephone() != null)
|
||||||
phone.setValue(customer.getTelephone());
|
phone.setValue(customer.getTelephone());
|
||||||
|
if (customer.getMail() != null)
|
||||||
|
mail.setValue(customer.getMail());
|
||||||
if (customer.getStreet() != null)
|
if (customer.getStreet() != null)
|
||||||
street.setValue(customer.getStreet());
|
street.setValue(customer.getStreet());
|
||||||
if (customer.getHouseNumber() != null)
|
if (customer.getHouseNumber() != null)
|
||||||
@@ -772,9 +858,57 @@ public class PickupStationDialog extends Dialog {
|
|||||||
if (customer.getCity() != null)
|
if (customer.getCity() != null)
|
||||||
city.setValue(customer.getCity());
|
city.setValue(customer.getCity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateSaveAddressState();
|
||||||
});
|
});
|
||||||
|
|
||||||
companyField.addCustomValueSetListener(event -> companyField.setValue(event.getDetail()));
|
companyField.addCustomValueSetListener(event -> {
|
||||||
|
companyField.setValue(event.getDetail());
|
||||||
|
updateSaveAddressState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSaveAddressState() {
|
||||||
|
Customer selectedCustomer = customerLabelMap.get(customerComboBox.getValue());
|
||||||
|
Customer selectedCompanyCustomer = companyCustomerMap.get(normalizeValue(company.getValue()));
|
||||||
|
boolean existingCustomerSelected = selectedCustomer != null && matchesCustomer(selectedCustomer);
|
||||||
|
boolean existingCompanySelected = selectedCompanyCustomer != null && matchesCustomer(selectedCompanyCustomer);
|
||||||
|
|
||||||
|
if (existingCustomerSelected || existingCompanySelected) {
|
||||||
|
saveAddress.setValue(false);
|
||||||
|
saveAddress.setEnabled(false);
|
||||||
|
updateMailRequirement();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveAddress.setEnabled(true);
|
||||||
|
updateMailRequirement();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMailRequirement() {
|
||||||
|
mail.setRequiredIndicatorVisible(Boolean.TRUE.equals(saveAddress.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesCustomer(Customer customer) {
|
||||||
|
return sameValue(company.getValue(), customer.getCompanyName())
|
||||||
|
&& sameValue(salutation.getValue(), customer.getTitle())
|
||||||
|
&& sameValue(firstName.getValue(), customer.getFirstname())
|
||||||
|
&& sameValue(lastName.getValue(), customer.getLastName())
|
||||||
|
&& sameValue(phone.getValue(), customer.getTelephone())
|
||||||
|
&& sameValue(mail.getValue(), customer.getMail())
|
||||||
|
&& sameValue(street.getValue(), customer.getStreet())
|
||||||
|
&& sameValue(houseNumber.getValue(), customer.getHouseNumber())
|
||||||
|
&& sameValue(addressAddition.getValue(), customer.getAddressAddition())
|
||||||
|
&& sameValue(zip.getValue(), customer.getZip())
|
||||||
|
&& sameValue(city.getValue(), customer.getCity());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean sameValue(String left, String right) {
|
||||||
|
return normalizeValue(left).equals(normalizeValue(right));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String normalizeValue(String value) {
|
||||||
|
return value == null ? "" : value.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ public class AddCustomerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addCustomer(Customer customer) {
|
public void addCustomer(Customer customer) {
|
||||||
|
validateCustomer(customer);
|
||||||
|
|
||||||
// Setze den aktuellen Benutzer als Ersteller - jetzt direkt aus der Session
|
// Setze den aktuellen Benutzer als Ersteller - jetzt direkt aus der Session
|
||||||
de.assecutor.votianlt.model.User currentUser = securityService.getCurrentDatabaseUser();
|
de.assecutor.votianlt.model.User currentUser = securityService.getCurrentDatabaseUser();
|
||||||
customer.setCreatedBy(currentUser.getId());
|
customer.setCreatedBy(currentUser.getId());
|
||||||
@@ -26,4 +28,20 @@ public class AddCustomerService {
|
|||||||
|
|
||||||
addCustomerRepository.save(customer);
|
addCustomerRepository.save(customer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateCustomer(Customer customer) {
|
||||||
|
if (customer == null) {
|
||||||
|
throw new IllegalArgumentException("Kunde darf nicht leer sein");
|
||||||
|
}
|
||||||
|
|
||||||
|
String mail = customer.getMail() != null ? customer.getMail().trim() : "";
|
||||||
|
if (mail.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("E-Mail-Adresse ist ein Pflichtfeld");
|
||||||
|
}
|
||||||
|
if (!mail.contains("@")) {
|
||||||
|
throw new IllegalArgumentException("Bitte geben Sie eine gültige E-Mail-Adresse ein");
|
||||||
|
}
|
||||||
|
|
||||||
|
customer.setMail(mail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
private TextField pickupFirstName;
|
private TextField pickupFirstName;
|
||||||
private TextField pickupLastName;
|
private TextField pickupLastName;
|
||||||
private TextField pickupPhone;
|
private TextField pickupPhone;
|
||||||
|
private String pickupMail;
|
||||||
private TextField pickupStreet;
|
private TextField pickupStreet;
|
||||||
private TextField pickupHouseNumber;
|
private TextField pickupHouseNumber;
|
||||||
private TextField pickupAddressAddition;
|
private TextField pickupAddressAddition;
|
||||||
@@ -143,6 +144,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
private final List<StationTile> deliveryStationTilesList = new ArrayList<>();
|
private final List<StationTile> deliveryStationTilesList = new ArrayList<>();
|
||||||
private final List<DeliveryStation> deliveryStationsState = new ArrayList<>();
|
private final List<DeliveryStation> deliveryStationsState = new ArrayList<>();
|
||||||
private final List<Boolean> deliveryStationsSaveAddress = new ArrayList<>();
|
private final List<Boolean> deliveryStationsSaveAddress = new ArrayList<>();
|
||||||
|
private final List<String> deliveryStationsMailState = new ArrayList<>();
|
||||||
private final List<Div> deliveryStationSlotList = new ArrayList<>();
|
private final List<Div> deliveryStationSlotList = new ArrayList<>();
|
||||||
private final List<Span> deliveryStationDistanceChips = new ArrayList<>();
|
private final List<Span> deliveryStationDistanceChips = new ArrayList<>();
|
||||||
private Div stationsGridContainer;
|
private Div stationsGridContainer;
|
||||||
@@ -720,6 +722,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
// Add empty state for this station
|
// Add empty state for this station
|
||||||
deliveryStationsState.add(new DeliveryStation());
|
deliveryStationsState.add(new DeliveryStation());
|
||||||
deliveryStationsSaveAddress.add(true);
|
deliveryStationsSaveAddress.add(true);
|
||||||
|
deliveryStationsMailState.add(null);
|
||||||
deliveryStationsValidatedByGoogle.add(false);
|
deliveryStationsValidatedByGoogle.add(false);
|
||||||
|
|
||||||
int stationIndex = deliveryStationTilesList.size();
|
int stationIndex = deliveryStationTilesList.size();
|
||||||
@@ -766,6 +769,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
deliveryStationTilesList.remove(removeIdx);
|
deliveryStationTilesList.remove(removeIdx);
|
||||||
deliveryStationsState.remove(removeIdx);
|
deliveryStationsState.remove(removeIdx);
|
||||||
deliveryStationsSaveAddress.remove(removeIdx);
|
deliveryStationsSaveAddress.remove(removeIdx);
|
||||||
|
deliveryStationsMailState.remove(removeIdx);
|
||||||
deliveryStationsValidatedByGoogle.remove(removeIdx);
|
deliveryStationsValidatedByGoogle.remove(removeIdx);
|
||||||
deliveryStationTasksState.remove(removeIdx);
|
deliveryStationTasksState.remove(removeIdx);
|
||||||
Div removedSlot = deliveryStationSlotList.remove(removeIdx);
|
Div removedSlot = deliveryStationSlotList.remove(removeIdx);
|
||||||
@@ -854,6 +858,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
pickupFirstName.setValue(data.getFirstName() != null ? data.getFirstName() : "");
|
pickupFirstName.setValue(data.getFirstName() != null ? data.getFirstName() : "");
|
||||||
pickupLastName.setValue(data.getLastName() != null ? data.getLastName() : "");
|
pickupLastName.setValue(data.getLastName() != null ? data.getLastName() : "");
|
||||||
pickupPhone.setValue(data.getPhone() != null ? data.getPhone() : "");
|
pickupPhone.setValue(data.getPhone() != null ? data.getPhone() : "");
|
||||||
|
pickupMail = trimToNull(data.getMail());
|
||||||
pickupStreet.setValue(data.getStreet() != null ? data.getStreet() : "");
|
pickupStreet.setValue(data.getStreet() != null ? data.getStreet() : "");
|
||||||
pickupHouseNumber.setValue(data.getHouseNumber() != null ? data.getHouseNumber() : "");
|
pickupHouseNumber.setValue(data.getHouseNumber() != null ? data.getHouseNumber() : "");
|
||||||
pickupAddressAddition.setValue(data.getAddressAddition() != null ? data.getAddressAddition() : "");
|
pickupAddressAddition.setValue(data.getAddressAddition() != null ? data.getAddressAddition() : "");
|
||||||
@@ -899,6 +904,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
currentData.setFirstName(pickupFirstName.getValue());
|
currentData.setFirstName(pickupFirstName.getValue());
|
||||||
currentData.setLastName(pickupLastName.getValue());
|
currentData.setLastName(pickupLastName.getValue());
|
||||||
currentData.setPhone(pickupPhone.getValue());
|
currentData.setPhone(pickupPhone.getValue());
|
||||||
|
currentData.setMail(pickupMail);
|
||||||
currentData.setStreet(pickupStreet.getValue());
|
currentData.setStreet(pickupStreet.getValue());
|
||||||
currentData.setHouseNumber(pickupHouseNumber.getValue());
|
currentData.setHouseNumber(pickupHouseNumber.getValue());
|
||||||
currentData.setAddressAddition(pickupAddressAddition.getValue());
|
currentData.setAddressAddition(pickupAddressAddition.getValue());
|
||||||
@@ -1129,6 +1135,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
station.setCity(data.getCity());
|
station.setCity(data.getCity());
|
||||||
station.setTasks(data.getTasks() != null ? new ArrayList<>(data.getTasks()) : new ArrayList<>());
|
station.setTasks(data.getTasks() != null ? new ArrayList<>(data.getTasks()) : new ArrayList<>());
|
||||||
deliveryStationsSaveAddress.set(idx, data.isSaveAddress());
|
deliveryStationsSaveAddress.set(idx, data.isSaveAddress());
|
||||||
|
deliveryStationsMailState.set(idx, trimToNull(data.getMail()));
|
||||||
|
|
||||||
// Store tasks for this delivery station
|
// Store tasks for this delivery station
|
||||||
deliveryStationTasksState.put(idx, data.getTasks() != null ? data.getTasks() : new ArrayList<>());
|
deliveryStationTasksState.put(idx, data.getTasks() != null ? data.getTasks() : new ArrayList<>());
|
||||||
@@ -1166,6 +1173,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
currentData.setFirstName(station.getFirstName());
|
currentData.setFirstName(station.getFirstName());
|
||||||
currentData.setLastName(station.getLastName());
|
currentData.setLastName(station.getLastName());
|
||||||
currentData.setPhone(station.getPhone());
|
currentData.setPhone(station.getPhone());
|
||||||
|
currentData.setMail(actualIndex < deliveryStationsMailState.size() ? deliveryStationsMailState.get(actualIndex) : null);
|
||||||
currentData.setStreet(station.getStreet());
|
currentData.setStreet(station.getStreet());
|
||||||
currentData.setHouseNumber(station.getHouseNumber());
|
currentData.setHouseNumber(station.getHouseNumber());
|
||||||
currentData.setAddressAddition(station.getAddressAddition());
|
currentData.setAddressAddition(station.getAddressAddition());
|
||||||
@@ -1417,6 +1425,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
pickupLastName.setValue(customer.getLastName());
|
pickupLastName.setValue(customer.getLastName());
|
||||||
if (customer.getTelephone() != null)
|
if (customer.getTelephone() != null)
|
||||||
pickupPhone.setValue(customer.getTelephone());
|
pickupPhone.setValue(customer.getTelephone());
|
||||||
|
pickupMail = trimToNull(customer.getMail());
|
||||||
if (customer.getStreet() != null)
|
if (customer.getStreet() != null)
|
||||||
pickupStreet.setValue(customer.getStreet());
|
pickupStreet.setValue(customer.getStreet());
|
||||||
if (customer.getHouseNumber() != null)
|
if (customer.getHouseNumber() != null)
|
||||||
@@ -1443,6 +1452,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
|
|
||||||
// Reactivate save checkbox for custom values
|
// Reactivate save checkbox for custom values
|
||||||
savePickupAddress.setValue(true);
|
savePickupAddress.setValue(true);
|
||||||
|
pickupMail = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1813,6 +1823,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
pickupCustomer.setFirstname(pickupFirstName.getValue());
|
pickupCustomer.setFirstname(pickupFirstName.getValue());
|
||||||
pickupCustomer.setLastName(pickupLastName.getValue());
|
pickupCustomer.setLastName(pickupLastName.getValue());
|
||||||
pickupCustomer.setTelephone(pickupPhone.getValue());
|
pickupCustomer.setTelephone(pickupPhone.getValue());
|
||||||
|
pickupCustomer.setMail(pickupMail);
|
||||||
pickupCustomer.setStreet(pickupStreet.getValue());
|
pickupCustomer.setStreet(pickupStreet.getValue());
|
||||||
pickupCustomer.setHouseNumber(pickupHouseNumber.getValue());
|
pickupCustomer.setHouseNumber(pickupHouseNumber.getValue());
|
||||||
pickupCustomer.setAddressAddition(pickupAddressAddition.getValue());
|
pickupCustomer.setAddressAddition(pickupAddressAddition.getValue());
|
||||||
@@ -1830,6 +1841,7 @@ public class AddJobView extends Main implements HasDynamicTitle {
|
|||||||
deliveryCustomer.setFirstname(ds.getFirstName());
|
deliveryCustomer.setFirstname(ds.getFirstName());
|
||||||
deliveryCustomer.setLastName(ds.getLastName());
|
deliveryCustomer.setLastName(ds.getLastName());
|
||||||
deliveryCustomer.setTelephone(ds.getPhone());
|
deliveryCustomer.setTelephone(ds.getPhone());
|
||||||
|
deliveryCustomer.setMail(i < deliveryStationsMailState.size() ? deliveryStationsMailState.get(i) : null);
|
||||||
deliveryCustomer.setStreet(ds.getStreet());
|
deliveryCustomer.setStreet(ds.getStreet());
|
||||||
deliveryCustomer.setHouseNumber(ds.getHouseNumber());
|
deliveryCustomer.setHouseNumber(ds.getHouseNumber());
|
||||||
deliveryCustomer.setAddressAddition(ds.getAddressAddition());
|
deliveryCustomer.setAddressAddition(ds.getAddressAddition());
|
||||||
|
|||||||
@@ -478,22 +478,22 @@ addjob.cargo.gridcart=Gitterwagen
|
|||||||
addjob.cargo.parcel=Paket
|
addjob.cargo.parcel=Paket
|
||||||
addjob.cargo.add=Fracht hinzufügen
|
addjob.cargo.add=Fracht hinzufügen
|
||||||
addjob.tasks.title=Aufgaben
|
addjob.tasks.title=Aufgaben
|
||||||
addjob.tasks.template.placeholder=Template auswählen
|
addjob.tasks.template.placeholder=Vorlage auswählen
|
||||||
addjob.tasks.template.save.tooltip=Als Template speichern
|
addjob.tasks.template.save.tooltip=Als Vorlage speichern
|
||||||
addjob.tasks.template.save.title=Template speichern
|
addjob.tasks.template.save.title=Vorlage speichern
|
||||||
addjob.tasks.template.name=Template-Name
|
addjob.tasks.template.name=Vorlagen-Name
|
||||||
addjob.tasks.template.name.placeholder=Name eingeben
|
addjob.tasks.template.name.placeholder=Name eingeben
|
||||||
addjob.tasks.template.name.required=Name ist erforderlich
|
addjob.tasks.template.name.required=Name ist erforderlich
|
||||||
addjob.tasks.template.saved=Template "{0}" gespeichert
|
addjob.tasks.template.saved=Vorlage "{0}" gespeichert
|
||||||
addjob.tasks.template.save.error=Fehler beim Speichern: {0}
|
addjob.tasks.template.save.error=Fehler beim Speichern: {0}
|
||||||
addjob.tasks.template.dialog.error=Fehler beim Öffnen des Dialogs: {0}
|
addjob.tasks.template.dialog.error=Fehler beim Öffnen des Dialogs: {0}
|
||||||
addjob.tasks.template.no.tasks=Keine Aufgaben zum Speichern
|
addjob.tasks.template.no.tasks=Keine Aufgaben zum Speichern
|
||||||
addjob.tasks.template.load.title=Template laden
|
addjob.tasks.template.load.title=Vorlage laden
|
||||||
addjob.tasks.template.load.text=Möchten Sie das Template "{0}" laden? Diese Aktion ersetzt alle aktuellen Aufgaben.
|
addjob.tasks.template.load.text=Möchten Sie die Vorlage "{0}" laden? Diese Aktion ersetzt alle aktuellen Aufgaben.
|
||||||
addjob.tasks.template.load.confirm=Laden
|
addjob.tasks.template.load.confirm=Laden
|
||||||
addjob.tasks.template.loaded=Template "{0}" geladen
|
addjob.tasks.template.loaded=Vorlage "{0}" geladen
|
||||||
addjob.tasks.template.load.error=Fehler beim Laden: {0}
|
addjob.tasks.template.load.error=Fehler beim Laden: {0}
|
||||||
addjob.tasks.template.load.templates.error=Fehler beim Laden der Templates: {0}
|
addjob.tasks.template.load.templates.error=Fehler beim Laden der Vorlagen: {0}
|
||||||
addjob.tasks.add=Aufgabe hinzufügen
|
addjob.tasks.add=Aufgabe hinzufügen
|
||||||
addjob.tasks.tasktype=Aufgabentyp
|
addjob.tasks.tasktype=Aufgabentyp
|
||||||
addjob.tasks.tasktype.placeholder=Typ wählen
|
addjob.tasks.tasktype.placeholder=Typ wählen
|
||||||
|
|||||||
Reference in New Issue
Block a user