Erweiterungen
This commit is contained in:
@@ -125,6 +125,11 @@ public class AddJobView extends Main {
|
|||||||
private Span vatTotalLabel;
|
private Span vatTotalLabel;
|
||||||
private Span grossTotalLabel;
|
private Span grossTotalLabel;
|
||||||
|
|
||||||
|
// Route distance display
|
||||||
|
private VerticalLayout routeInfoBox;
|
||||||
|
private Span routeDistanceLabel;
|
||||||
|
private Span routeDurationLabel;
|
||||||
|
|
||||||
// Date picker fields for appointments
|
// Date picker fields for appointments
|
||||||
private DatePicker pickupDate;
|
private DatePicker pickupDate;
|
||||||
private DatePicker deliveryDate;
|
private DatePicker deliveryDate;
|
||||||
@@ -603,6 +608,49 @@ public class AddJobView extends Main {
|
|||||||
content.setWidthFull();
|
content.setWidthFull();
|
||||||
content.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
|
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
|
// Title
|
||||||
H3 servicesTitle = new H3("Leistungen");
|
H3 servicesTitle = new H3("Leistungen");
|
||||||
servicesTitle.getStyle().set("margin", "0");
|
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) {
|
private void showAddressValidationDialog(com.vaadin.flow.component.tabs.Tab targetTab) {
|
||||||
final Dialog dialog = new Dialog();
|
final Dialog dialog = new Dialog();
|
||||||
@@ -2753,13 +2802,19 @@ public class AddJobView extends Main {
|
|||||||
content.setPadding(true);
|
content.setPadding(true);
|
||||||
content.setSpacing(true);
|
content.setSpacing(true);
|
||||||
|
|
||||||
// Status-Labels für die Validierung
|
// Initiale Meldung mit Progress
|
||||||
final Span pickupStatusLabel = new Span("Abholadresse wird überprüft...");
|
final Span loadingMessage = new Span("Adressen werden bei Google Maps überprüft...");
|
||||||
final Span deliveryStatusLabel = new Span("Lieferadresse wird ü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();
|
final VerticalLayout resultLayout = new VerticalLayout();
|
||||||
resultLayout.setVisible(false);
|
resultLayout.setVisible(false);
|
||||||
resultLayout.setPadding(false);
|
resultLayout.setPadding(false);
|
||||||
@@ -2804,64 +2859,79 @@ public class AddJobView extends Main {
|
|||||||
dialog.add(content);
|
dialog.add(content);
|
||||||
dialog.open();
|
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 -> {
|
getUI().ifPresent(ui -> {
|
||||||
// UI-Zugriff für Validierung
|
// CompletableFuture für Hintergrund-Verarbeitung
|
||||||
ui.access(() -> {
|
java.util.concurrent.CompletableFuture.runAsync(() -> {
|
||||||
// Abholadresse validieren
|
// Abholadresse validieren
|
||||||
final AddressValidationResult[] pickupResultHolder = new AddressValidationResult[1];
|
final AddressValidationResult[] pickupResultHolder = new AddressValidationResult[1];
|
||||||
if (hasPickupAddressChanged()) {
|
if (pickupChanged) {
|
||||||
pickupResultHolder[0] = addressValidationService.validateAddress("pickup",
|
pickupResultHolder[0] = addressValidationService.validateAddress("pickup", pickupStreetValue,
|
||||||
getValueOrEmpty(pickupStreet), getValueOrEmpty(pickupHouseNumber),
|
pickupHouseNumberValue, pickupZipValue, pickupCityValue);
|
||||||
getValueOrEmpty(pickupZip), getValueOrEmpty(pickupCity));
|
|
||||||
addressValidationResults.put("pickup", pickupResultHolder[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lieferadresse validieren
|
// Lieferadresse validieren
|
||||||
final AddressValidationResult[] deliveryResultHolder = new AddressValidationResult[1];
|
final AddressValidationResult[] deliveryResultHolder = new AddressValidationResult[1];
|
||||||
if (hasDeliveryAddressChanged()) {
|
if (deliveryChanged) {
|
||||||
deliveryResultHolder[0] = addressValidationService.validateAddress("delivery",
|
deliveryResultHolder[0] = addressValidationService.validateAddress("delivery", deliveryStreetValue,
|
||||||
getValueOrEmpty(deliveryStreet), getValueOrEmpty(deliveryHouseNumber),
|
deliveryHouseNumberValue, deliveryZipValue, deliveryCityValue);
|
||||||
getValueOrEmpty(deliveryZip), getValueOrEmpty(deliveryCity));
|
}
|
||||||
|
|
||||||
|
// UI aktualisieren mit den Ergebnissen
|
||||||
|
ui.access(() -> {
|
||||||
|
// Ergebnisse speichern
|
||||||
|
if (pickupResultHolder[0] != null) {
|
||||||
|
addressValidationResults.put("pickup", pickupResultHolder[0]);
|
||||||
|
}
|
||||||
|
if (deliveryResultHolder[0] != null) {
|
||||||
addressValidationResults.put("delivery", deliveryResultHolder[0]);
|
addressValidationResults.put("delivery", deliveryResultHolder[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route berechnen, wenn beide Adressen gültig sind
|
// Ergebnisse ermitteln
|
||||||
final RouteCalculationResult[] routeResultHolder = new RouteCalculationResult[1];
|
AddressValidationResult pickupResult = pickupResultHolder[0] != null ? pickupResultHolder[0]
|
||||||
AddressValidationResult pickup = pickupResultHolder[0];
|
: addressValidationResults.get("pickup");
|
||||||
AddressValidationResult delivery = deliveryResultHolder[0];
|
AddressValidationResult deliveryResult = deliveryResultHolder[0] != null ? deliveryResultHolder[0]
|
||||||
|
: addressValidationResults.get("delivery");
|
||||||
|
|
||||||
if ((pickup != null && pickup.isValid()) && (delivery != null && delivery.isValid())) {
|
// Lade-Anzeige ausblenden
|
||||||
routeResultHolder[0] = addressValidationService.calculateRoute(pickup, delivery);
|
loadingMessage.setVisible(false);
|
||||||
routeCalculationResult = routeResultHolder[0];
|
progressBar.setVisible(false);
|
||||||
} else if (pickup == null) {
|
|
||||||
// Bereits validierte Abholadresse verwenden
|
// Prüfen ob beide Adressen gültig sind
|
||||||
AddressValidationResult existingPickup = addressValidationResults.get("pickup");
|
boolean bothValid = (pickupResult != null && pickupResult.isValid())
|
||||||
if (existingPickup != null && existingPickup.isValid() && delivery != null && delivery.isValid()) {
|
&& (deliveryResult != null && deliveryResult.isValid());
|
||||||
routeResultHolder[0] = addressValidationService.calculateRoute(existingPickup, delivery);
|
|
||||||
routeCalculationResult = routeResultHolder[0];
|
// Route berechnen wenn beide gültig
|
||||||
}
|
if (bothValid) {
|
||||||
} else if (delivery == null) {
|
routeCalculationResult = addressValidationService.calculateRoute(pickupResult, deliveryResult);
|
||||||
// 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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI aktualisieren
|
// Ergebnisse anzeigen
|
||||||
updateValidationDialogUI(pickup, delivery, pickupStatusLabel, deliveryStatusLabel, pickupResultLabel,
|
updateValidationDialogResults(pickupResult, deliveryResult, pickupResultLabel, deliveryResultLabel,
|
||||||
deliveryResultLabel, routeResultLabel, resultLayout, buttonLayout, continueButton, targetTab);
|
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,
|
private void updateValidationDialogResults(AddressValidationResult pickupResult,
|
||||||
Span pickupStatusLabel, Span deliveryStatusLabel, Span pickupResultLabel, Span deliveryResultLabel,
|
AddressValidationResult deliveryResult, Span pickupResultLabel, Span deliveryResultLabel,
|
||||||
Span routeResultLabel, VerticalLayout resultLayout, HorizontalLayout buttonLayout, Button continueButton,
|
Span routeResultLabel, VerticalLayout resultLayout, HorizontalLayout buttonLayout, Button continueButton,
|
||||||
com.vaadin.flow.component.tabs.Tab targetTab) {
|
com.vaadin.flow.component.tabs.Tab targetTab) {
|
||||||
|
|
||||||
@@ -2898,23 +2968,6 @@ public class AddJobView extends Main {
|
|||||||
deliveryResultLabel.setVisible(false);
|
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
|
// Route anzeigen, wenn beide Adressen gültig sind
|
||||||
if (bothAddressesValid && routeCalculationResult != null && routeCalculationResult.isValid()) {
|
if (bothAddressesValid && routeCalculationResult != null && routeCalculationResult.isValid()) {
|
||||||
routeResultLabel.setText("🚛 Route: " + String.format("%.1f km", routeCalculationResult.getDistanceKm())
|
routeResultLabel.setText("🚛 Route: " + String.format("%.1f km", routeCalculationResult.getDistanceKm())
|
||||||
@@ -2925,14 +2978,11 @@ public class AddJobView extends Main {
|
|||||||
routeResultLabel.setVisible(false);
|
routeResultLabel.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status-Labels ausblenden, Ergebnisse anzeigen
|
// Ergebnisse anzeigen
|
||||||
pickupStatusLabel.setVisible(false);
|
|
||||||
deliveryStatusLabel.setVisible(false);
|
|
||||||
resultLayout.setVisible(true);
|
resultLayout.setVisible(true);
|
||||||
|
|
||||||
// Farbliche Markierung der Adressfelder
|
// Farbliche Markierung der Adressfelder
|
||||||
updateAddressFieldStyles(pickupResult != null ? pickupResult : existingPickup,
|
updateAddressFieldStyles(pickupResult, deliveryResult);
|
||||||
deliveryResult != null ? deliveryResult : existingDelivery);
|
|
||||||
|
|
||||||
// Buttons anzeigen
|
// Buttons anzeigen
|
||||||
buttonLayout.setVisible(true);
|
buttonLayout.setVisible(true);
|
||||||
@@ -2943,6 +2993,26 @@ public class AddJobView extends Main {
|
|||||||
} else {
|
} else {
|
||||||
continueButton.setText("Trotzdem wechseln");
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user