Erweiterungen

This commit is contained in:
2026-02-17 16:01:50 +01:00
parent b114c115d7
commit 6181f53854

View File

@@ -125,6 +125,11 @@ public class AddJobView extends Main {
private Span vatTotalLabel;
private Span grossTotalLabel;
// Route distance display
private VerticalLayout routeInfoBox;
private Span routeDistanceLabel;
private Span routeDurationLabel;
// Date picker fields for appointments
private DatePicker pickupDate;
private DatePicker deliveryDate;
@@ -603,6 +608,49 @@ public class AddJobView extends Main {
content.setWidthFull();
content.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
// Route Info Box (ganz oben)
routeInfoBox = new VerticalLayout();
routeInfoBox.setPadding(true);
routeInfoBox.setSpacing(true);
routeInfoBox.getStyle().set("border", "1px solid var(--lumo-primary-color-50pct)");
routeInfoBox.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
routeInfoBox.getStyle().set("background-color", "var(--lumo-primary-color-10pct)");
routeInfoBox.setWidthFull();
routeInfoBox.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
routeInfoBox.setVisible(false); // Initial versteckt
H3 routeTitle = new H3("Streckeninformation");
routeTitle.getStyle().set("margin", "0");
routeTitle.getStyle().set("color", "var(--lumo-primary-text-color)");
HorizontalLayout routeRow = new HorizontalLayout();
routeRow.setWidthFull();
routeRow.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
routeRow.setAlignItems(FlexComponent.Alignment.CENTER);
Span distanceLabel = new Span("Entfernung:");
routeDistanceLabel = new Span("-");
routeDistanceLabel.getStyle().set("font-weight", "bold");
routeDistanceLabel.getStyle().set("font-size", "var(--lumo-font-size-l)");
routeDistanceLabel.getStyle().set("color", "var(--lumo-primary-text-color)");
routeRow.add(distanceLabel, routeDistanceLabel);
HorizontalLayout durationRow = new HorizontalLayout();
durationRow.setWidthFull();
durationRow.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
durationRow.setAlignItems(FlexComponent.Alignment.CENTER);
Span durationLabel = new Span("Fahrtzeit:");
routeDurationLabel = new Span("-");
routeDurationLabel.getStyle().set("font-weight", "bold");
routeDurationLabel.getStyle().set("color", "var(--lumo-secondary-text-color)");
durationRow.add(durationLabel, routeDurationLabel);
routeInfoBox.add(routeTitle, routeRow, durationRow);
content.add(routeInfoBox);
// Title
H3 servicesTitle = new H3("Leistungen");
servicesTitle.getStyle().set("margin", "0");
@@ -2739,7 +2787,8 @@ public class AddJobView extends Main {
}
/**
* Zeigt den Adressvalidierungsdialog an.
* Zeigt den Adressvalidierungsdialog an. Die Prüfung erfolgt im Hintergrund und
* der Dialog wird aktualisiert, sobald die Ergebnisse vorliegen.
*/
private void showAddressValidationDialog(com.vaadin.flow.component.tabs.Tab targetTab) {
final Dialog dialog = new Dialog();
@@ -2753,13 +2802,19 @@ public class AddJobView extends Main {
content.setPadding(true);
content.setSpacing(true);
// Status-Labels für die Validierung
final Span pickupStatusLabel = new Span("Abholadresse wird überprüft...");
final Span deliveryStatusLabel = new Span("Lieferadresse wird überprüft...");
// Initiale Meldung mit Progress
final Span loadingMessage = new Span("Adressen werden bei Google Maps überprüft...");
loadingMessage.getStyle().set("font-style", "italic");
loadingMessage.getStyle().set("color", "var(--lumo-secondary-text-color)");
content.add(pickupStatusLabel, deliveryStatusLabel);
// Progress-Indikator
final com.vaadin.flow.component.progressbar.ProgressBar progressBar = new com.vaadin.flow.component.progressbar.ProgressBar();
progressBar.setIndeterminate(true);
progressBar.setWidthFull();
// Layout für die Ergebnisanzeige
content.add(loadingMessage, progressBar);
// Layout für die Ergebnisanzeige (initial versteckt)
final VerticalLayout resultLayout = new VerticalLayout();
resultLayout.setVisible(false);
resultLayout.setPadding(false);
@@ -2804,64 +2859,79 @@ public class AddJobView extends Main {
dialog.add(content);
dialog.open();
// Asynchrone Validierung durchführen
// Adressdaten speichern für die Validierung
final String pickupStreetValue = getValueOrEmpty(pickupStreet);
final String pickupHouseNumberValue = getValueOrEmpty(pickupHouseNumber);
final String pickupZipValue = getValueOrEmpty(pickupZip);
final String pickupCityValue = getValueOrEmpty(pickupCity);
final boolean pickupChanged = hasPickupAddressChanged();
final String deliveryStreetValue = getValueOrEmpty(deliveryStreet);
final String deliveryHouseNumberValue = getValueOrEmpty(deliveryHouseNumber);
final String deliveryZipValue = getValueOrEmpty(deliveryZip);
final String deliveryCityValue = getValueOrEmpty(deliveryCity);
final boolean deliveryChanged = hasDeliveryAddressChanged();
// Asynchrone Validierung im Hintergrund durchführen
getUI().ifPresent(ui -> {
// UI-Zugriff für Validierung
ui.access(() -> {
// CompletableFuture für Hintergrund-Verarbeitung
java.util.concurrent.CompletableFuture.runAsync(() -> {
// Abholadresse validieren
final AddressValidationResult[] pickupResultHolder = new AddressValidationResult[1];
if (hasPickupAddressChanged()) {
pickupResultHolder[0] = addressValidationService.validateAddress("pickup",
getValueOrEmpty(pickupStreet), getValueOrEmpty(pickupHouseNumber),
getValueOrEmpty(pickupZip), getValueOrEmpty(pickupCity));
addressValidationResults.put("pickup", pickupResultHolder[0]);
if (pickupChanged) {
pickupResultHolder[0] = addressValidationService.validateAddress("pickup", pickupStreetValue,
pickupHouseNumberValue, pickupZipValue, pickupCityValue);
}
// Lieferadresse validieren
final AddressValidationResult[] deliveryResultHolder = new AddressValidationResult[1];
if (hasDeliveryAddressChanged()) {
deliveryResultHolder[0] = addressValidationService.validateAddress("delivery",
getValueOrEmpty(deliveryStreet), getValueOrEmpty(deliveryHouseNumber),
getValueOrEmpty(deliveryZip), getValueOrEmpty(deliveryCity));
addressValidationResults.put("delivery", deliveryResultHolder[0]);
if (deliveryChanged) {
deliveryResultHolder[0] = addressValidationService.validateAddress("delivery", deliveryStreetValue,
deliveryHouseNumberValue, deliveryZipValue, deliveryCityValue);
}
// Route berechnen, wenn beide Adressen gültig sind
final RouteCalculationResult[] routeResultHolder = new RouteCalculationResult[1];
AddressValidationResult pickup = pickupResultHolder[0];
AddressValidationResult delivery = deliveryResultHolder[0];
if ((pickup != null && pickup.isValid()) && (delivery != null && delivery.isValid())) {
routeResultHolder[0] = addressValidationService.calculateRoute(pickup, delivery);
routeCalculationResult = routeResultHolder[0];
} else if (pickup == null) {
// Bereits validierte Abholadresse verwenden
AddressValidationResult existingPickup = addressValidationResults.get("pickup");
if (existingPickup != null && existingPickup.isValid() && delivery != null && delivery.isValid()) {
routeResultHolder[0] = addressValidationService.calculateRoute(existingPickup, delivery);
routeCalculationResult = routeResultHolder[0];
// UI aktualisieren mit den Ergebnissen
ui.access(() -> {
// Ergebnisse speichern
if (pickupResultHolder[0] != null) {
addressValidationResults.put("pickup", pickupResultHolder[0]);
}
} else if (delivery == null) {
// Bereits validierte Lieferadresse verwenden
AddressValidationResult existingDelivery = addressValidationResults.get("delivery");
if (existingDelivery != null && existingDelivery.isValid() && pickup != null && pickup.isValid()) {
routeResultHolder[0] = addressValidationService.calculateRoute(pickup, existingDelivery);
routeCalculationResult = routeResultHolder[0];
if (deliveryResultHolder[0] != null) {
addressValidationResults.put("delivery", deliveryResultHolder[0]);
}
}
// UI aktualisieren
updateValidationDialogUI(pickup, delivery, pickupStatusLabel, deliveryStatusLabel, pickupResultLabel,
deliveryResultLabel, routeResultLabel, resultLayout, buttonLayout, continueButton, targetTab);
// Ergebnisse ermitteln
AddressValidationResult pickupResult = pickupResultHolder[0] != null ? pickupResultHolder[0]
: addressValidationResults.get("pickup");
AddressValidationResult deliveryResult = deliveryResultHolder[0] != null ? deliveryResultHolder[0]
: addressValidationResults.get("delivery");
// Lade-Anzeige ausblenden
loadingMessage.setVisible(false);
progressBar.setVisible(false);
// Prüfen ob beide Adressen gültig sind
boolean bothValid = (pickupResult != null && pickupResult.isValid())
&& (deliveryResult != null && deliveryResult.isValid());
// Route berechnen wenn beide gültig
if (bothValid) {
routeCalculationResult = addressValidationService.calculateRoute(pickupResult, deliveryResult);
}
// Ergebnisse anzeigen
updateValidationDialogResults(pickupResult, deliveryResult, pickupResultLabel, deliveryResultLabel,
routeResultLabel, resultLayout, buttonLayout, continueButton, targetTab);
});
});
});
}
/**
* Aktualisiert die UI des Validierungsdialogs mit den Ergebnissen.
* Aktualisiert die Ergebnisanzeige im Validierungsdialog.
*/
private void updateValidationDialogUI(AddressValidationResult pickupResult, AddressValidationResult deliveryResult,
Span pickupStatusLabel, Span deliveryStatusLabel, Span pickupResultLabel, Span deliveryResultLabel,
private void updateValidationDialogResults(AddressValidationResult pickupResult,
AddressValidationResult deliveryResult, Span pickupResultLabel, Span deliveryResultLabel,
Span routeResultLabel, VerticalLayout resultLayout, HorizontalLayout buttonLayout, Button continueButton,
com.vaadin.flow.component.tabs.Tab targetTab) {
@@ -2898,23 +2968,6 @@ public class AddJobView extends Main {
deliveryResultLabel.setVisible(false);
}
// Prüfen, ob beide Adressen insgesamt gültig sind (auch aus vorherigen
// Validierungen)
AddressValidationResult existingPickup = addressValidationResults.get("pickup");
AddressValidationResult existingDelivery = addressValidationResults.get("delivery");
if (pickupResult != null && !pickupResult.isValid()) {
bothAddressesValid = false;
} else if (pickupResult == null && (existingPickup == null || !existingPickup.isValid())) {
bothAddressesValid = false;
}
if (deliveryResult != null && !deliveryResult.isValid()) {
bothAddressesValid = false;
} else if (deliveryResult == null && (existingDelivery == null || !existingDelivery.isValid())) {
bothAddressesValid = false;
}
// Route anzeigen, wenn beide Adressen gültig sind
if (bothAddressesValid && routeCalculationResult != null && routeCalculationResult.isValid()) {
routeResultLabel.setText("🚛 Route: " + String.format("%.1f km", routeCalculationResult.getDistanceKm())
@@ -2925,14 +2978,11 @@ public class AddJobView extends Main {
routeResultLabel.setVisible(false);
}
// Status-Labels ausblenden, Ergebnisse anzeigen
pickupStatusLabel.setVisible(false);
deliveryStatusLabel.setVisible(false);
// Ergebnisse anzeigen
resultLayout.setVisible(true);
// Farbliche Markierung der Adressfelder
updateAddressFieldStyles(pickupResult != null ? pickupResult : existingPickup,
deliveryResult != null ? deliveryResult : existingDelivery);
updateAddressFieldStyles(pickupResult, deliveryResult);
// Buttons anzeigen
buttonLayout.setVisible(true);
@@ -2943,6 +2993,26 @@ public class AddJobView extends Main {
} else {
continueButton.setText("Trotzdem wechseln");
}
// Route-Info im Preis-Tab aktualisieren
updateRouteInfoBox();
}
/**
* Aktualisiert die Route-Info-Box im Preis-Tab mit den aktuellen Routendaten.
*/
private void updateRouteInfoBox() {
if (routeInfoBox == null || routeCalculationResult == null) {
return;
}
if (routeCalculationResult.isValid()) {
routeDistanceLabel.setText(String.format("%.1f km", routeCalculationResult.getDistanceKm()));
routeDurationLabel.setText(routeCalculationResult.getFormattedDurationLong());
routeInfoBox.setVisible(true);
} else {
routeInfoBox.setVisible(false);
}
}
/**