Erweiterungen
This commit is contained in:
@@ -2,41 +2,113 @@ package de.assecutor.votianlt.model;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Field;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@Document(collection = "jobs")
|
||||||
public class Job {
|
public class Job {
|
||||||
|
@Id
|
||||||
private ObjectId id;
|
private ObjectId id;
|
||||||
|
|
||||||
|
// Metadaten
|
||||||
|
@Field("job_number")
|
||||||
|
private String jobNumber; // Eindeutige Auftragsnummer
|
||||||
|
|
||||||
|
@Field("status")
|
||||||
|
private JobStatus status = JobStatus.CREATED; // Status des Auftrags
|
||||||
|
|
||||||
|
@Field("created_at")
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@Field("updated_at")
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
@Field("created_by")
|
||||||
|
private String createdBy; // Benutzer, der den Auftrag erstellt hat
|
||||||
|
|
||||||
|
@Field("is_draft")
|
||||||
|
private boolean isDraft = false; // Kennzeichnet Entwürfe
|
||||||
|
|
||||||
// Auftraggeber/Rechnungsempfänger
|
// Auftraggeber/Rechnungsempfänger
|
||||||
|
@Field("customer_selection")
|
||||||
private String customerSelection; // Kunde01 | KOTVor K01Nach
|
private String customerSelection; // Kunde01 | KOTVor K01Nach
|
||||||
|
|
||||||
// Abholadresse
|
// Abholadresse
|
||||||
|
@Field("pickup_company")
|
||||||
private String pickupCompany;
|
private String pickupCompany;
|
||||||
|
|
||||||
|
@Field("pickup_salutation")
|
||||||
private String pickupSalutation;
|
private String pickupSalutation;
|
||||||
|
|
||||||
|
@Field("pickup_first_name")
|
||||||
private String pickupFirstName;
|
private String pickupFirstName;
|
||||||
|
|
||||||
|
@Field("pickup_last_name")
|
||||||
private String pickupLastName;
|
private String pickupLastName;
|
||||||
|
|
||||||
|
@Field("pickup_phone")
|
||||||
private String pickupPhone;
|
private String pickupPhone;
|
||||||
|
|
||||||
|
@Field("pickup_street")
|
||||||
private String pickupStreet;
|
private String pickupStreet;
|
||||||
|
|
||||||
|
@Field("pickup_house_number")
|
||||||
private String pickupHouseNumber;
|
private String pickupHouseNumber;
|
||||||
|
|
||||||
|
@Field("pickup_address_addition")
|
||||||
private String pickupAddressAddition;
|
private String pickupAddressAddition;
|
||||||
|
|
||||||
|
@Field("pickup_zip")
|
||||||
private String pickupZip;
|
private String pickupZip;
|
||||||
|
|
||||||
|
@Field("pickup_city")
|
||||||
private String pickupCity;
|
private String pickupCity;
|
||||||
|
|
||||||
|
@Field("save_pickup_address")
|
||||||
private boolean savePickupAddress;
|
private boolean savePickupAddress;
|
||||||
|
|
||||||
// Lieferadresse
|
// Lieferadresse
|
||||||
|
@Field("delivery_company")
|
||||||
private String deliveryCompany;
|
private String deliveryCompany;
|
||||||
|
|
||||||
|
@Field("delivery_salutation")
|
||||||
private String deliverySalutation;
|
private String deliverySalutation;
|
||||||
|
|
||||||
|
@Field("delivery_first_name")
|
||||||
private String deliveryFirstName;
|
private String deliveryFirstName;
|
||||||
|
|
||||||
|
@Field("delivery_last_name")
|
||||||
private String deliveryLastName;
|
private String deliveryLastName;
|
||||||
|
|
||||||
|
@Field("delivery_phone")
|
||||||
private String deliveryPhone;
|
private String deliveryPhone;
|
||||||
|
|
||||||
|
@Field("delivery_street")
|
||||||
private String deliveryStreet;
|
private String deliveryStreet;
|
||||||
|
|
||||||
|
@Field("delivery_house_number")
|
||||||
private String deliveryHouseNumber;
|
private String deliveryHouseNumber;
|
||||||
|
|
||||||
|
@Field("delivery_address_addition")
|
||||||
private String deliveryAddressAddition;
|
private String deliveryAddressAddition;
|
||||||
|
|
||||||
|
@Field("delivery_zip")
|
||||||
private String deliveryZip;
|
private String deliveryZip;
|
||||||
|
|
||||||
|
@Field("delivery_city")
|
||||||
private String deliveryCity;
|
private String deliveryCity;
|
||||||
|
|
||||||
|
@Field("save_delivery_address")
|
||||||
private boolean saveDeliveryAddress;
|
private boolean saveDeliveryAddress;
|
||||||
|
|
||||||
// Digitale Abwicklung per App
|
// Digitale Abwicklung per App
|
||||||
|
@Field("digital_processing")
|
||||||
private boolean digitalProcessing;
|
private boolean digitalProcessing;
|
||||||
|
|
||||||
|
@Field("app_user")
|
||||||
private String appUser;
|
private String appUser;
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/main/java/de/assecutor/votianlt/model/JobStatus.java
Normal file
30
src/main/java/de/assecutor/votianlt/model/JobStatus.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package de.assecutor.votianlt.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status-Enum für Aufträge
|
||||||
|
*/
|
||||||
|
public enum JobStatus {
|
||||||
|
CREATED("Erstellt"),
|
||||||
|
IN_PROGRESS("In Bearbeitung"),
|
||||||
|
PICKUP_SCHEDULED("Abholung geplant"),
|
||||||
|
PICKED_UP("Abgeholt"),
|
||||||
|
IN_TRANSIT("Unterwegs"),
|
||||||
|
DELIVERED("Zugestellt"),
|
||||||
|
COMPLETED("Abgeschlossen"),
|
||||||
|
CANCELLED("Storniert");
|
||||||
|
|
||||||
|
private final String displayName;
|
||||||
|
|
||||||
|
JobStatus(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,245 @@
|
|||||||
package de.assecutor.votianlt.pages.add_job.service;
|
package de.assecutor.votianlt.pages.add_job.service;
|
||||||
|
|
||||||
import de.assecutor.votianlt.model.Job;
|
import de.assecutor.votianlt.model.Job;
|
||||||
|
import de.assecutor.votianlt.model.JobStatus;
|
||||||
|
import de.assecutor.votianlt.repository.JobRepository;
|
||||||
|
import de.assecutor.votianlt.security.SecurityService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class AddJobService {
|
public class AddJobService {
|
||||||
|
|
||||||
public void addJob(Job job) {
|
private final JobRepository jobRepository;
|
||||||
// TODO: Implement job persistence logic
|
private final SecurityService securityService;
|
||||||
System.out.println("Job would be saved: " + job.toString());
|
|
||||||
|
/**
|
||||||
|
* Speichert einen neuen Auftrag in der MongoDB
|
||||||
|
*/
|
||||||
|
public Job addJob(Job job) {
|
||||||
|
try {
|
||||||
|
// Metadaten setzen
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
job.setCreatedAt(now);
|
||||||
|
job.setUpdatedAt(now);
|
||||||
|
job.setStatus(JobStatus.CREATED);
|
||||||
|
job.setCreatedBy(securityService.getCurrentUsername());
|
||||||
|
|
||||||
|
// Auftragsnummer generieren, falls nicht vorhanden
|
||||||
|
if (job.getJobNumber() == null || job.getJobNumber().isEmpty()) {
|
||||||
|
job.setJobNumber(generateJobNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auftrag speichern
|
||||||
|
Job savedJob = jobRepository.save(job);
|
||||||
|
log.info("Auftrag erfolgreich gespeichert: {}", savedJob.getJobNumber());
|
||||||
|
|
||||||
|
return savedJob;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Fehler beim Speichern des Auftrags: {}", e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Auftrag konnte nicht gespeichert werden: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiert einen bestehenden Auftrag
|
||||||
|
*/
|
||||||
|
public Job updateJob(Job job) {
|
||||||
|
try {
|
||||||
|
job.setUpdatedAt(LocalDateTime.now());
|
||||||
|
Job updatedJob = jobRepository.save(job);
|
||||||
|
log.info("Auftrag erfolgreich aktualisiert: {}", updatedJob.getJobNumber());
|
||||||
|
return updatedJob;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Fehler beim Aktualisieren des Auftrags: {}", e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Auftrag konnte nicht aktualisiert werden: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet einen Auftrag anhand der ID
|
||||||
|
*/
|
||||||
|
public Optional<Job> findById(String id) {
|
||||||
|
try {
|
||||||
|
return jobRepository.findById(new org.bson.types.ObjectId(id));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Fehler beim Suchen des Auftrags mit ID {}: {}", id, e.getMessage());
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet einen Auftrag anhand der Auftragsnummer
|
||||||
|
*/
|
||||||
|
public Optional<Job> findByJobNumber(String jobNumber) {
|
||||||
|
return jobRepository.findByJobNumber(jobNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Aufträge eines Benutzers
|
||||||
|
*/
|
||||||
|
public List<Job> findJobsByUser(String username) {
|
||||||
|
return jobRepository.findByCreatedBy(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Aufträge mit einem bestimmten Status
|
||||||
|
*/
|
||||||
|
public List<Job> findJobsByStatus(JobStatus status) {
|
||||||
|
return jobRepository.findByStatus(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht einen Auftrag
|
||||||
|
*/
|
||||||
|
public void deleteJob(String id) {
|
||||||
|
try {
|
||||||
|
jobRepository.deleteById(new org.bson.types.ObjectId(id));
|
||||||
|
log.info("Auftrag mit ID {} erfolgreich gelöscht", id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Fehler beim Löschen des Auftrags mit ID {}: {}", id, e.getMessage());
|
||||||
|
throw new RuntimeException("Auftrag konnte nicht gelöscht werden: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generiert eine eindeutige Auftragsnummer
|
||||||
|
*/
|
||||||
|
private String generateJobNumber() {
|
||||||
|
String prefix = "JOB";
|
||||||
|
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||||
|
|
||||||
|
// Zähle Aufträge des aktuellen Tages
|
||||||
|
String todayPrefix = prefix + timestamp;
|
||||||
|
long todayCount = jobRepository.findAll().stream()
|
||||||
|
.filter(job -> job.getJobNumber() != null && job.getJobNumber().startsWith(todayPrefix))
|
||||||
|
.count();
|
||||||
|
|
||||||
|
// Generiere neue Nummer
|
||||||
|
String jobNumber;
|
||||||
|
do {
|
||||||
|
todayCount++;
|
||||||
|
jobNumber = String.format("%s%s%03d", prefix, timestamp, todayCount);
|
||||||
|
} while (jobRepository.existsByJobNumber(jobNumber));
|
||||||
|
|
||||||
|
return jobNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zählt alle Aufträge
|
||||||
|
*/
|
||||||
|
public long countAllJobs() {
|
||||||
|
return jobRepository.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zählt Aufträge nach Status
|
||||||
|
*/
|
||||||
|
public long countJobsByStatus(JobStatus status) {
|
||||||
|
return jobRepository.countByStatus(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Speichert einen Auftrag als Entwurf (für automatisches Speichern)
|
||||||
|
*/
|
||||||
|
public Job saveDraft(Job job) {
|
||||||
|
try {
|
||||||
|
// Prüfen ob bereits ein Entwurf für diesen Benutzer existiert
|
||||||
|
String currentUser = securityService.getCurrentUsername();
|
||||||
|
List<Job> existingDrafts = jobRepository.findByCreatedByAndIsDraftTrue(currentUser);
|
||||||
|
|
||||||
|
Job draftJob;
|
||||||
|
if (!existingDrafts.isEmpty()) {
|
||||||
|
// Bestehenden Entwurf aktualisieren
|
||||||
|
draftJob = existingDrafts.get(0);
|
||||||
|
updateJobFromForm(draftJob, job);
|
||||||
|
draftJob.setUpdatedAt(LocalDateTime.now());
|
||||||
|
} else {
|
||||||
|
// Neuen Entwurf erstellen
|
||||||
|
draftJob = job;
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
draftJob.setCreatedAt(now);
|
||||||
|
draftJob.setUpdatedAt(now);
|
||||||
|
draftJob.setStatus(JobStatus.CREATED);
|
||||||
|
draftJob.setCreatedBy(currentUser);
|
||||||
|
draftJob.setDraft(true);
|
||||||
|
|
||||||
|
// Spezielle Entwurfs-Auftragsnummer
|
||||||
|
draftJob.setJobNumber("DRAFT_" + currentUser.replace("@", "_") + "_" +
|
||||||
|
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")));
|
||||||
|
}
|
||||||
|
|
||||||
|
Job savedDraft = jobRepository.save(draftJob);
|
||||||
|
log.info("Entwurf automatisch gespeichert für Benutzer: {}", currentUser);
|
||||||
|
|
||||||
|
return savedDraft;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Fehler beim Speichern des Entwurfs: {}", e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Entwurf konnte nicht gespeichert werden: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiert einen bestehenden Job mit neuen Formulardaten
|
||||||
|
*/
|
||||||
|
private void updateJobFromForm(Job existingJob, Job formJob) {
|
||||||
|
existingJob.setCustomerSelection(formJob.getCustomerSelection());
|
||||||
|
|
||||||
|
// Pickup address
|
||||||
|
existingJob.setPickupCompany(formJob.getPickupCompany());
|
||||||
|
existingJob.setPickupSalutation(formJob.getPickupSalutation());
|
||||||
|
existingJob.setPickupFirstName(formJob.getPickupFirstName());
|
||||||
|
existingJob.setPickupLastName(formJob.getPickupLastName());
|
||||||
|
existingJob.setPickupPhone(formJob.getPickupPhone());
|
||||||
|
existingJob.setPickupStreet(formJob.getPickupStreet());
|
||||||
|
existingJob.setPickupHouseNumber(formJob.getPickupHouseNumber());
|
||||||
|
existingJob.setPickupAddressAddition(formJob.getPickupAddressAddition());
|
||||||
|
existingJob.setPickupZip(formJob.getPickupZip());
|
||||||
|
existingJob.setPickupCity(formJob.getPickupCity());
|
||||||
|
existingJob.setSavePickupAddress(formJob.isSavePickupAddress());
|
||||||
|
|
||||||
|
// Delivery address
|
||||||
|
existingJob.setDeliveryCompany(formJob.getDeliveryCompany());
|
||||||
|
existingJob.setDeliverySalutation(formJob.getDeliverySalutation());
|
||||||
|
existingJob.setDeliveryFirstName(formJob.getDeliveryFirstName());
|
||||||
|
existingJob.setDeliveryLastName(formJob.getDeliveryLastName());
|
||||||
|
existingJob.setDeliveryPhone(formJob.getDeliveryPhone());
|
||||||
|
existingJob.setDeliveryStreet(formJob.getDeliveryStreet());
|
||||||
|
existingJob.setDeliveryHouseNumber(formJob.getDeliveryHouseNumber());
|
||||||
|
existingJob.setDeliveryAddressAddition(formJob.getDeliveryAddressAddition());
|
||||||
|
existingJob.setDeliveryZip(formJob.getDeliveryZip());
|
||||||
|
existingJob.setDeliveryCity(formJob.getDeliveryCity());
|
||||||
|
existingJob.setSaveDeliveryAddress(formJob.isSaveDeliveryAddress());
|
||||||
|
|
||||||
|
// Digital processing
|
||||||
|
existingJob.setDigitalProcessing(formJob.isDigitalProcessing());
|
||||||
|
existingJob.setAppUser(formJob.getAppUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet den aktuellen Entwurf eines Benutzers
|
||||||
|
*/
|
||||||
|
public Optional<Job> findCurrentDraft(String username) {
|
||||||
|
List<Job> drafts = jobRepository.findByCreatedByAndIsDraftTrue(username);
|
||||||
|
return drafts.isEmpty() ? Optional.empty() : Optional.of(drafts.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht alle Entwürfe eines Benutzers
|
||||||
|
*/
|
||||||
|
public void deleteUserDrafts(String username) {
|
||||||
|
List<Job> drafts = jobRepository.findByCreatedByAndIsDraftTrue(username);
|
||||||
|
jobRepository.deleteAll(drafts);
|
||||||
|
log.info("Entwürfe für Benutzer {} gelöscht", username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,20 @@ import com.vaadin.flow.component.button.Button;
|
|||||||
import com.vaadin.flow.component.button.ButtonVariant;
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
import com.vaadin.flow.component.checkbox.Checkbox;
|
import com.vaadin.flow.component.checkbox.Checkbox;
|
||||||
import com.vaadin.flow.component.combobox.ComboBox;
|
import com.vaadin.flow.component.combobox.ComboBox;
|
||||||
|
|
||||||
import com.vaadin.flow.component.html.Div;
|
import com.vaadin.flow.component.html.Div;
|
||||||
import com.vaadin.flow.component.html.H3;
|
import com.vaadin.flow.component.html.H3;
|
||||||
import com.vaadin.flow.component.html.Main;
|
import com.vaadin.flow.component.html.Main;
|
||||||
import com.vaadin.flow.component.html.Span;
|
import com.vaadin.flow.component.html.Span;
|
||||||
import com.vaadin.flow.component.icon.Icon;
|
import com.vaadin.flow.component.icon.Icon;
|
||||||
import com.vaadin.flow.component.icon.VaadinIcon;
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
|
import com.vaadin.flow.component.notification.Notification;
|
||||||
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
||||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
import com.vaadin.flow.component.textfield.TextField;
|
import com.vaadin.flow.component.textfield.TextField;
|
||||||
|
import com.vaadin.flow.component.ClientCallable;
|
||||||
|
import com.vaadin.flow.component.UI;
|
||||||
import com.vaadin.flow.data.binder.Binder;
|
import com.vaadin.flow.data.binder.Binder;
|
||||||
import com.vaadin.flow.data.binder.ValidationException;
|
import com.vaadin.flow.data.binder.ValidationException;
|
||||||
import com.vaadin.flow.router.Menu;
|
import com.vaadin.flow.router.Menu;
|
||||||
@@ -25,11 +29,14 @@ import de.assecutor.votianlt.pages.add_job.service.AddJobService;
|
|||||||
import de.assecutor.votianlt.pages.base.ui.component.ViewToolbar;
|
import de.assecutor.votianlt.pages.base.ui.component.ViewToolbar;
|
||||||
|
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Route(value = "add_job", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
|
@Route(value = "add_job", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
|
||||||
@PageTitle("Neuen Auftrag anlegen")
|
@PageTitle("Neuen Auftrag anlegen")
|
||||||
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neuen Auftrag anlegen")
|
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neuen Auftrag anlegen")
|
||||||
@RolesAllowed("USER")
|
@RolesAllowed("USER")
|
||||||
|
@Slf4j
|
||||||
public class AddJobView extends Main {
|
public class AddJobView extends Main {
|
||||||
|
|
||||||
private final AddJobService addJobService;
|
private final AddJobService addJobService;
|
||||||
@@ -76,83 +83,94 @@ public class AddJobView extends Main {
|
|||||||
|
|
||||||
private final Binder<Job> binder = new Binder<>(Job.class);
|
private final Binder<Job> binder = new Binder<>(Job.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public AddJobView(AddJobService addJobService) {
|
public AddJobView(AddJobService addJobService) {
|
||||||
this.addJobService = addJobService;
|
this.addJobService = addJobService;
|
||||||
initializeComponents();
|
initializeComponents();
|
||||||
setupLayout();
|
setupLayout();
|
||||||
setupValidation();
|
setupValidation();
|
||||||
|
loadDraftIfExists();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeComponents() {
|
private void initializeComponents() {
|
||||||
// Customer selection
|
// Customer selection
|
||||||
customerSelection = new ComboBox<>("Auftraggeber/Rechnungsempfänger");
|
customerSelection = new ComboBox<>("Auftraggeber/Rechnungsempfänger");
|
||||||
customerSelection.setItems("Kunde01 | KOTVor K01Nach");
|
customerSelection.setItems("Kunde01 | KOTVor K01Nach");
|
||||||
customerSelection.setValue("Kunde01 | KOTVor K01Nach");
|
customerSelection.setPlaceholder("Wählen Sie einen Auftraggeber aus...");
|
||||||
customerSelection.setWidthFull();
|
customerSelection.setWidthFull();
|
||||||
|
|
||||||
preloadAddressButton = new Button("Vorbelegte Adressfelder leeren");
|
preloadAddressButton = new Button("Vorbelegte Adressfelder leeren");
|
||||||
preloadAddressButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
preloadAddressButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
preloadAddressButton.setIcon(new Icon(VaadinIcon.QUESTION_CIRCLE));
|
preloadAddressButton.addClickListener(event -> clearAllFields());
|
||||||
|
|
||||||
// Required fields notice
|
|
||||||
requiredFieldsNotice = new Span("Die mit (*) gekennzeichneten Felder sind Pflichtfelder.");
|
|
||||||
requiredFieldsNotice.getStyle().set("color", "red");
|
|
||||||
requiredFieldsNotice.getStyle().set("font-size", "14px");
|
|
||||||
|
|
||||||
// Pickup address
|
// Pickup address
|
||||||
pickupCompany = new TextField("Firma");
|
pickupCompany = new TextField("Firma");
|
||||||
pickupCompany.setValue("Kunde01");
|
pickupCompany.setPlaceholder("z.B. IKEA, McDonald's, DHL...");
|
||||||
|
addGooglePlacesAutocomplete(pickupCompany, 0); // Stage 0 für Pickup
|
||||||
pickupSalutation = new ComboBox<>("Anrede");
|
pickupSalutation = new ComboBox<>("Anrede");
|
||||||
pickupSalutation.setItems("Herr", "Frau", "Divers");
|
pickupSalutation.setItems("Herr", "Frau", "Divers");
|
||||||
pickupFirstName = new TextField("Vorname*");
|
pickupSalutation.setPlaceholder("Anrede wählen...");
|
||||||
pickupFirstName.setValue("K01Vor");
|
pickupFirstName = new TextField("Vorname");
|
||||||
|
pickupFirstName.setPlaceholder("Max");
|
||||||
pickupFirstName.setRequiredIndicatorVisible(true);
|
pickupFirstName.setRequiredIndicatorVisible(true);
|
||||||
pickupLastName = new TextField("Nachname*");
|
pickupLastName = new TextField("Nachname");
|
||||||
pickupLastName.setValue("K01Nach");
|
pickupLastName.setPlaceholder("Mustermann");
|
||||||
pickupLastName.setRequiredIndicatorVisible(true);
|
pickupLastName.setRequiredIndicatorVisible(true);
|
||||||
pickupPhone = new TextField("Telefonnummer");
|
pickupPhone = new TextField("Telefonnummer");
|
||||||
pickupPhone.setValue("01");
|
pickupPhone.setPlaceholder("+49 123 456789");
|
||||||
pickupStreet = new TextField("Straße*");
|
pickupStreet = new TextField("Straße");
|
||||||
pickupStreet.setValue("Ottensener Str.");
|
pickupStreet.setPlaceholder("Musterstraße");
|
||||||
pickupStreet.setRequiredIndicatorVisible(true);
|
pickupStreet.setRequiredIndicatorVisible(true);
|
||||||
pickupHouseNumber = new TextField("Hausnr*");
|
pickupHouseNumber = new TextField("Hausnummer");
|
||||||
pickupHouseNumber.setValue("8");
|
pickupHouseNumber.setPlaceholder("123");
|
||||||
pickupHouseNumber.setRequiredIndicatorVisible(true);
|
pickupHouseNumber.setRequiredIndicatorVisible(true);
|
||||||
pickupAddressAddition = new TextField("Adresszusatz");
|
pickupAddressAddition = new TextField("Adresszusatz");
|
||||||
pickupZip = new TextField("Postleitzahl*");
|
pickupAddressAddition.setPlaceholder("2. OG, Hinterhaus...");
|
||||||
pickupZip.setValue("22525");
|
pickupZip = new TextField("Postleitzahl");
|
||||||
|
pickupZip.setPlaceholder("12345");
|
||||||
pickupZip.setRequiredIndicatorVisible(true);
|
pickupZip.setRequiredIndicatorVisible(true);
|
||||||
pickupCity = new TextField("Ort*");
|
pickupCity = new TextField("Ort");
|
||||||
pickupCity.setValue("Hamburg");
|
pickupCity.setPlaceholder("Hamburg");
|
||||||
pickupCity.setRequiredIndicatorVisible(true);
|
pickupCity.setRequiredIndicatorVisible(true);
|
||||||
savePickupAddress = new Checkbox("Die Adresse für zukünftige Aufträge speichern.");
|
savePickupAddress = new Checkbox("Die Adresse für zukünftige Aufträge speichern.");
|
||||||
|
|
||||||
// Delivery address
|
// Delivery address
|
||||||
deliveryCompany = new TextField("Firma");
|
deliveryCompany = new TextField("Firma");
|
||||||
|
deliveryCompany.setPlaceholder("z.B. EDEKA, Bauhaus, Amazon...");
|
||||||
|
addGooglePlacesAutocomplete(deliveryCompany, 1); // Stage 1 für Delivery
|
||||||
deliverySalutation = new ComboBox<>("Anrede");
|
deliverySalutation = new ComboBox<>("Anrede");
|
||||||
deliverySalutation.setItems("Herr", "Frau", "Divers");
|
deliverySalutation.setItems("Herr", "Frau", "Divers");
|
||||||
deliveryFirstName = new TextField("Vorname*");
|
deliverySalutation.setPlaceholder("Anrede wählen...");
|
||||||
|
deliveryFirstName = new TextField("Vorname");
|
||||||
|
deliveryFirstName.setPlaceholder("Anna");
|
||||||
deliveryFirstName.setRequiredIndicatorVisible(true);
|
deliveryFirstName.setRequiredIndicatorVisible(true);
|
||||||
deliveryLastName = new TextField("Nachname*");
|
deliveryLastName = new TextField("Nachname");
|
||||||
|
deliveryLastName.setPlaceholder("Beispiel");
|
||||||
deliveryLastName.setRequiredIndicatorVisible(true);
|
deliveryLastName.setRequiredIndicatorVisible(true);
|
||||||
deliveryPhone = new TextField("Telefonnummer");
|
deliveryPhone = new TextField("Telefonnummer");
|
||||||
deliveryStreet = new TextField("Straße*");
|
deliveryPhone.setPlaceholder("+49 987 654321");
|
||||||
|
deliveryStreet = new TextField("Straße");
|
||||||
|
deliveryStreet.setPlaceholder("Beispielweg");
|
||||||
deliveryStreet.setRequiredIndicatorVisible(true);
|
deliveryStreet.setRequiredIndicatorVisible(true);
|
||||||
deliveryHouseNumber = new TextField("Hausnr*");
|
deliveryHouseNumber = new TextField("Hausnr");
|
||||||
|
deliveryHouseNumber.setPlaceholder("456");
|
||||||
deliveryHouseNumber.setRequiredIndicatorVisible(true);
|
deliveryHouseNumber.setRequiredIndicatorVisible(true);
|
||||||
deliveryAddressAddition = new TextField("Adresszusatz");
|
deliveryAddressAddition = new TextField("Adresszusatz");
|
||||||
deliveryZip = new TextField("Postleitzahl*");
|
deliveryAddressAddition.setPlaceholder("Erdgeschoss, links...");
|
||||||
|
deliveryZip = new TextField("Postleitzahl");
|
||||||
|
deliveryZip.setPlaceholder("54321");
|
||||||
deliveryZip.setRequiredIndicatorVisible(true);
|
deliveryZip.setRequiredIndicatorVisible(true);
|
||||||
deliveryCity = new TextField("Ort*");
|
deliveryCity = new TextField("Ort");
|
||||||
|
deliveryCity.setPlaceholder("Berlin");
|
||||||
deliveryCity.setRequiredIndicatorVisible(true);
|
deliveryCity.setRequiredIndicatorVisible(true);
|
||||||
saveDeliveryAddress = new Checkbox("Die Adresse für zukünftige Aufträge speichern.");
|
saveDeliveryAddress = new Checkbox("Die Adresse für zukünftige Aufträge speichern.");
|
||||||
saveDeliveryAddress.setValue(true);
|
|
||||||
|
|
||||||
// Digital processing
|
// Digital processing
|
||||||
digitalProcessing = new Checkbox("Digitale Abwicklung per App");
|
digitalProcessing = new Checkbox("Digitale Abwicklung per App");
|
||||||
digitalProcessing.setValue(true);
|
|
||||||
appUser = new ComboBox<>("App-Nutzer");
|
appUser = new ComboBox<>("App-Nutzer");
|
||||||
appUser.setItems("App-Nutzer");
|
appUser.setItems("App-Nutzer");
|
||||||
|
appUser.setPlaceholder("App-Nutzer auswählen...");
|
||||||
|
|
||||||
// Submit button
|
// Submit button
|
||||||
submitButton = new Button("Auftrag anlegen", event -> submit());
|
submitButton = new Button("Auftrag anlegen", event -> submit());
|
||||||
@@ -176,7 +194,6 @@ public class AddJobView extends Main {
|
|||||||
preloadAddressButton.setWidth("30%");
|
preloadAddressButton.setWidth("30%");
|
||||||
|
|
||||||
add(customerLayout);
|
add(customerLayout);
|
||||||
add(requiredFieldsNotice);
|
|
||||||
|
|
||||||
// Main content layout with two equal columns (50% each)
|
// Main content layout with two equal columns (50% each)
|
||||||
HorizontalLayout mainLayout = new HorizontalLayout();
|
HorizontalLayout mainLayout = new HorizontalLayout();
|
||||||
@@ -185,24 +202,14 @@ public class AddJobView extends Main {
|
|||||||
mainLayout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.START);
|
mainLayout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.START);
|
||||||
|
|
||||||
// Left column (50%) - Pickup address section
|
// Left column (50%) - Pickup address section
|
||||||
VerticalLayout leftColumn = createPickupSection();
|
VerticalLayout pickupSection = createPickupSection();
|
||||||
leftColumn.setWidth("50%");
|
pickupSection.setWidth("50%");
|
||||||
|
|
||||||
// Right column (50%) - Delivery address section
|
// Right column (50%) - Delivery address section
|
||||||
VerticalLayout rightColumn = createDeliverySection();
|
VerticalLayout deliverySection = createDeliverySection();
|
||||||
rightColumn.setWidth("50%");
|
deliverySection.setWidth("50%");
|
||||||
|
|
||||||
// Add copy button to the right column at the top
|
mainLayout.add(pickupSection, deliverySection);
|
||||||
Button copyButton = new Button("Abholadresse kopieren");
|
|
||||||
copyButton.setIcon(new Icon(VaadinIcon.ARROW_RIGHT));
|
|
||||||
copyButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
|
|
||||||
copyButton.addClickListener(e -> copyPickupToDelivery());
|
|
||||||
copyButton.getStyle().set("margin-bottom", "var(--lumo-space-m)");
|
|
||||||
|
|
||||||
// Insert copy button at the beginning of right column
|
|
||||||
rightColumn.addComponentAsFirst(copyButton);
|
|
||||||
|
|
||||||
mainLayout.add(leftColumn, rightColumn);
|
|
||||||
|
|
||||||
add(mainLayout);
|
add(mainLayout);
|
||||||
|
|
||||||
@@ -222,17 +229,35 @@ public class AddJobView extends Main {
|
|||||||
private VerticalLayout createPickupSection() {
|
private VerticalLayout createPickupSection() {
|
||||||
VerticalLayout section = new VerticalLayout();
|
VerticalLayout section = new VerticalLayout();
|
||||||
section.setSpacing(true);
|
section.setSpacing(true);
|
||||||
section.setPadding(false);
|
section.setPadding(true);
|
||||||
|
section.setWidthFull();
|
||||||
|
|
||||||
|
// Hellgrauer Rahmen hinzufügen
|
||||||
|
section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
|
||||||
|
section.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
|
||||||
|
section.getStyle().set("background-color", "var(--lumo-base-color)");
|
||||||
|
|
||||||
H3 title = new H3("Abholadresse");
|
H3 title = new H3("Abholadresse");
|
||||||
title.getStyle().set("margin", "0");
|
title.getStyle().set("margin", "0");
|
||||||
title.getStyle().set("display", "flex");
|
|
||||||
title.getStyle().set("align-items", "center");
|
|
||||||
Icon helpIcon = new Icon(VaadinIcon.QUESTION_CIRCLE);
|
|
||||||
helpIcon.getStyle().set("margin-left", "8px");
|
|
||||||
title.add(helpIcon);
|
|
||||||
|
|
||||||
section.add(title);
|
|
||||||
|
|
||||||
|
HorizontalLayout titleLayout = new HorizontalLayout();
|
||||||
|
titleLayout.setWidthFull();
|
||||||
|
titleLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
|
||||||
|
titleLayout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||||
|
titleLayout.add(title);
|
||||||
|
|
||||||
|
// Alle einzelnen Controls auf volle Breite setzen
|
||||||
|
pickupCompany.setWidthFull();
|
||||||
|
pickupSalutation.setWidthFull();
|
||||||
|
pickupFirstName.setWidthFull();
|
||||||
|
pickupLastName.setWidthFull();
|
||||||
|
pickupPhone.setWidthFull();
|
||||||
|
pickupAddressAddition.setWidthFull();
|
||||||
|
savePickupAddress.setWidthFull();
|
||||||
|
|
||||||
|
section.add(titleLayout);
|
||||||
section.add(pickupCompany);
|
section.add(pickupCompany);
|
||||||
section.add(pickupSalutation);
|
section.add(pickupSalutation);
|
||||||
section.add(pickupFirstName);
|
section.add(pickupFirstName);
|
||||||
@@ -241,6 +266,7 @@ public class AddJobView extends Main {
|
|||||||
|
|
||||||
HorizontalLayout streetLayout = new HorizontalLayout();
|
HorizontalLayout streetLayout = new HorizontalLayout();
|
||||||
streetLayout.setWidthFull();
|
streetLayout.setWidthFull();
|
||||||
|
streetLayout.setSpacing(true);
|
||||||
streetLayout.add(pickupStreet, pickupHouseNumber);
|
streetLayout.add(pickupStreet, pickupHouseNumber);
|
||||||
pickupStreet.setWidth("70%");
|
pickupStreet.setWidth("70%");
|
||||||
pickupHouseNumber.setWidth("30%");
|
pickupHouseNumber.setWidth("30%");
|
||||||
@@ -250,6 +276,7 @@ public class AddJobView extends Main {
|
|||||||
|
|
||||||
HorizontalLayout zipCityLayout = new HorizontalLayout();
|
HorizontalLayout zipCityLayout = new HorizontalLayout();
|
||||||
zipCityLayout.setWidthFull();
|
zipCityLayout.setWidthFull();
|
||||||
|
zipCityLayout.setSpacing(true);
|
||||||
zipCityLayout.add(pickupZip, pickupCity);
|
zipCityLayout.add(pickupZip, pickupCity);
|
||||||
pickupZip.setWidth("30%");
|
pickupZip.setWidth("30%");
|
||||||
pickupCity.setWidth("70%");
|
pickupCity.setWidth("70%");
|
||||||
@@ -263,12 +290,35 @@ public class AddJobView extends Main {
|
|||||||
private VerticalLayout createDeliverySection() {
|
private VerticalLayout createDeliverySection() {
|
||||||
VerticalLayout section = new VerticalLayout();
|
VerticalLayout section = new VerticalLayout();
|
||||||
section.setSpacing(true);
|
section.setSpacing(true);
|
||||||
section.setPadding(false);
|
section.setPadding(true);
|
||||||
|
section.setWidthFull();
|
||||||
|
|
||||||
|
// Hellgrauer Rahmen hinzufügen
|
||||||
|
section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
|
||||||
|
section.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
|
||||||
|
section.getStyle().set("background-color", "var(--lumo-base-color)");
|
||||||
|
|
||||||
H3 title = new H3("Lieferadresse");
|
H3 title = new H3("Lieferadresse");
|
||||||
title.getStyle().set("margin", "0");
|
title.getStyle().set("margin", "0");
|
||||||
|
|
||||||
section.add(title);
|
|
||||||
|
|
||||||
|
HorizontalLayout titleLayout = new HorizontalLayout();
|
||||||
|
titleLayout.setWidthFull();
|
||||||
|
titleLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
|
||||||
|
titleLayout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||||
|
titleLayout.add(title);
|
||||||
|
|
||||||
|
// Alle einzelnen Controls auf volle Breite setzen
|
||||||
|
deliveryCompany.setWidthFull();
|
||||||
|
deliverySalutation.setWidthFull();
|
||||||
|
deliveryFirstName.setWidthFull();
|
||||||
|
deliveryLastName.setWidthFull();
|
||||||
|
deliveryPhone.setWidthFull();
|
||||||
|
deliveryAddressAddition.setWidthFull();
|
||||||
|
saveDeliveryAddress.setWidthFull();
|
||||||
|
|
||||||
|
section.add(titleLayout);
|
||||||
section.add(deliveryCompany);
|
section.add(deliveryCompany);
|
||||||
section.add(deliverySalutation);
|
section.add(deliverySalutation);
|
||||||
section.add(deliveryFirstName);
|
section.add(deliveryFirstName);
|
||||||
@@ -277,6 +327,7 @@ public class AddJobView extends Main {
|
|||||||
|
|
||||||
HorizontalLayout streetLayout = new HorizontalLayout();
|
HorizontalLayout streetLayout = new HorizontalLayout();
|
||||||
streetLayout.setWidthFull();
|
streetLayout.setWidthFull();
|
||||||
|
streetLayout.setSpacing(true);
|
||||||
streetLayout.add(deliveryStreet, deliveryHouseNumber);
|
streetLayout.add(deliveryStreet, deliveryHouseNumber);
|
||||||
deliveryStreet.setWidth("70%");
|
deliveryStreet.setWidth("70%");
|
||||||
deliveryHouseNumber.setWidth("30%");
|
deliveryHouseNumber.setWidth("30%");
|
||||||
@@ -286,6 +337,7 @@ public class AddJobView extends Main {
|
|||||||
|
|
||||||
HorizontalLayout zipCityLayout = new HorizontalLayout();
|
HorizontalLayout zipCityLayout = new HorizontalLayout();
|
||||||
zipCityLayout.setWidthFull();
|
zipCityLayout.setWidthFull();
|
||||||
|
zipCityLayout.setSpacing(true);
|
||||||
zipCityLayout.add(deliveryZip, deliveryCity);
|
zipCityLayout.add(deliveryZip, deliveryCity);
|
||||||
deliveryZip.setWidth("30%");
|
deliveryZip.setWidth("30%");
|
||||||
deliveryCity.setWidth("70%");
|
deliveryCity.setWidth("70%");
|
||||||
@@ -296,6 +348,10 @@ public class AddJobView extends Main {
|
|||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void copyPickupToDelivery() {
|
private void copyPickupToDelivery() {
|
||||||
deliveryCompany.setValue(pickupCompany.getValue());
|
deliveryCompany.setValue(pickupCompany.getValue());
|
||||||
deliverySalutation.setValue(pickupSalutation.getValue());
|
deliverySalutation.setValue(pickupSalutation.getValue());
|
||||||
@@ -347,7 +403,367 @@ public class AddJobView extends Main {
|
|||||||
job.setAppUser(appUser.getValue());
|
job.setAppUser(appUser.getValue());
|
||||||
job.setCustomerSelection(customerSelection.getValue());
|
job.setCustomerSelection(customerSelection.getValue());
|
||||||
|
|
||||||
addJobService.addJob(job);
|
try {
|
||||||
System.out.println("Job created successfully");
|
Job savedJob = addJobService.addJob(job);
|
||||||
|
|
||||||
|
// Erfolgsmeldung anzeigen
|
||||||
|
Notification successNotification = Notification.show(
|
||||||
|
"Auftrag erfolgreich erstellt! Auftragsnummer: " + savedJob.getJobNumber());
|
||||||
|
successNotification.setDuration(5000);
|
||||||
|
|
||||||
|
// Formular zurücksetzen
|
||||||
|
clearForm();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Fehlermeldung anzeigen
|
||||||
|
Notification errorNotification = Notification.show(
|
||||||
|
"Fehler beim Erstellen des Auftrags: " + e.getMessage());
|
||||||
|
errorNotification.setDuration(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setzt alle Formularfelder zurück
|
||||||
|
*/
|
||||||
|
private void clearForm() {
|
||||||
|
// Customer selection
|
||||||
|
customerSelection.clear();
|
||||||
|
|
||||||
|
// Pickup address
|
||||||
|
pickupCompany.clear();
|
||||||
|
pickupSalutation.clear();
|
||||||
|
pickupFirstName.clear();
|
||||||
|
pickupLastName.clear();
|
||||||
|
pickupPhone.clear();
|
||||||
|
pickupStreet.clear();
|
||||||
|
pickupHouseNumber.clear();
|
||||||
|
pickupAddressAddition.clear();
|
||||||
|
pickupZip.clear();
|
||||||
|
pickupCity.clear();
|
||||||
|
savePickupAddress.setValue(false);
|
||||||
|
|
||||||
|
// Delivery address
|
||||||
|
deliveryCompany.clear();
|
||||||
|
deliverySalutation.clear();
|
||||||
|
deliveryFirstName.clear();
|
||||||
|
deliveryLastName.clear();
|
||||||
|
deliveryPhone.clear();
|
||||||
|
deliveryStreet.clear();
|
||||||
|
deliveryHouseNumber.clear();
|
||||||
|
deliveryAddressAddition.clear();
|
||||||
|
deliveryZip.clear();
|
||||||
|
deliveryCity.clear();
|
||||||
|
saveDeliveryAddress.setValue(false);
|
||||||
|
|
||||||
|
// Digital processing
|
||||||
|
digitalProcessing.setValue(false);
|
||||||
|
appUser.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistiert die aktuellen Formulardaten als Entwurf
|
||||||
|
*/
|
||||||
|
private void persistCurrentData() {
|
||||||
|
// Prüfen ob mindestens ein Feld ausgefüllt ist
|
||||||
|
if (isFormEmpty()) {
|
||||||
|
return; // Keine Daten zum Speichern
|
||||||
|
}
|
||||||
|
|
||||||
|
Job job = new Job();
|
||||||
|
|
||||||
|
// Alle aktuellen Werte aus dem Formular lesen
|
||||||
|
job.setCustomerSelection(customerSelection.getValue());
|
||||||
|
|
||||||
|
// Pickup address
|
||||||
|
job.setPickupCompany(pickupCompany.getValue());
|
||||||
|
job.setPickupSalutation(pickupSalutation.getValue());
|
||||||
|
job.setPickupFirstName(pickupFirstName.getValue());
|
||||||
|
job.setPickupLastName(pickupLastName.getValue());
|
||||||
|
job.setPickupPhone(pickupPhone.getValue());
|
||||||
|
job.setPickupStreet(pickupStreet.getValue());
|
||||||
|
job.setPickupHouseNumber(pickupHouseNumber.getValue());
|
||||||
|
job.setPickupAddressAddition(pickupAddressAddition.getValue());
|
||||||
|
job.setPickupZip(pickupZip.getValue());
|
||||||
|
job.setPickupCity(pickupCity.getValue());
|
||||||
|
job.setSavePickupAddress(savePickupAddress.getValue());
|
||||||
|
|
||||||
|
// Delivery address
|
||||||
|
job.setDeliveryCompany(deliveryCompany.getValue());
|
||||||
|
job.setDeliverySalutation(deliverySalutation.getValue());
|
||||||
|
job.setDeliveryFirstName(deliveryFirstName.getValue());
|
||||||
|
job.setDeliveryLastName(deliveryLastName.getValue());
|
||||||
|
job.setDeliveryPhone(deliveryPhone.getValue());
|
||||||
|
job.setDeliveryStreet(deliveryStreet.getValue());
|
||||||
|
job.setDeliveryHouseNumber(deliveryHouseNumber.getValue());
|
||||||
|
job.setDeliveryAddressAddition(deliveryAddressAddition.getValue());
|
||||||
|
job.setDeliveryZip(deliveryZip.getValue());
|
||||||
|
job.setDeliveryCity(deliveryCity.getValue());
|
||||||
|
job.setSaveDeliveryAddress(saveDeliveryAddress.getValue());
|
||||||
|
|
||||||
|
// Digital processing
|
||||||
|
job.setDigitalProcessing(digitalProcessing.getValue());
|
||||||
|
job.setAppUser(appUser.getValue());
|
||||||
|
|
||||||
|
// Als Entwurf speichern
|
||||||
|
addJobService.saveDraft(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft ob das Formular komplett leer ist
|
||||||
|
*/
|
||||||
|
private boolean isFormEmpty() {
|
||||||
|
return (customerSelection.getValue() == null || customerSelection.getValue().trim().isEmpty()) &&
|
||||||
|
(pickupCompany.getValue() == null || pickupCompany.getValue().trim().isEmpty()) &&
|
||||||
|
(pickupFirstName.getValue() == null || pickupFirstName.getValue().trim().isEmpty()) &&
|
||||||
|
(pickupLastName.getValue() == null || pickupLastName.getValue().trim().isEmpty()) &&
|
||||||
|
(pickupStreet.getValue() == null || pickupStreet.getValue().trim().isEmpty()) &&
|
||||||
|
(pickupCity.getValue() == null || pickupCity.getValue().trim().isEmpty()) &&
|
||||||
|
(deliveryCompany.getValue() == null || deliveryCompany.getValue().trim().isEmpty()) &&
|
||||||
|
(deliveryFirstName.getValue() == null || deliveryFirstName.getValue().trim().isEmpty()) &&
|
||||||
|
(deliveryLastName.getValue() == null || deliveryLastName.getValue().trim().isEmpty()) &&
|
||||||
|
(deliveryStreet.getValue() == null || deliveryStreet.getValue().trim().isEmpty()) &&
|
||||||
|
(deliveryCity.getValue() == null || deliveryCity.getValue().trim().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lädt einen bestehenden Entwurf, falls vorhanden
|
||||||
|
*/
|
||||||
|
private void loadDraftIfExists() {
|
||||||
|
try {
|
||||||
|
String currentUser = getCurrentUsername();
|
||||||
|
if (currentUser != null) {
|
||||||
|
Optional<Job> draftOpt = addJobService.findCurrentDraft(currentUser);
|
||||||
|
if (draftOpt.isPresent()) {
|
||||||
|
Job draft = draftOpt.get();
|
||||||
|
loadJobIntoForm(draft);
|
||||||
|
|
||||||
|
// Benutzer informieren
|
||||||
|
Notification notification = Notification.show(
|
||||||
|
"Entwurf wiederhergestellt. Sie können Ihre Arbeit fortsetzen.");
|
||||||
|
notification.setDuration(4000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Fehler beim Laden des Entwurfs sollten nicht die Anwendung blockieren
|
||||||
|
System.err.println("Fehler beim Laden des Entwurfs: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lädt Job-Daten in das Formular
|
||||||
|
*/
|
||||||
|
private void loadJobIntoForm(Job job) {
|
||||||
|
if (job.getCustomerSelection() != null) {
|
||||||
|
customerSelection.setValue(job.getCustomerSelection());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pickup address
|
||||||
|
if (job.getPickupCompany() != null) pickupCompany.setValue(job.getPickupCompany());
|
||||||
|
if (job.getPickupSalutation() != null) pickupSalutation.setValue(job.getPickupSalutation());
|
||||||
|
if (job.getPickupFirstName() != null) pickupFirstName.setValue(job.getPickupFirstName());
|
||||||
|
if (job.getPickupLastName() != null) pickupLastName.setValue(job.getPickupLastName());
|
||||||
|
if (job.getPickupPhone() != null) pickupPhone.setValue(job.getPickupPhone());
|
||||||
|
if (job.getPickupStreet() != null) pickupStreet.setValue(job.getPickupStreet());
|
||||||
|
if (job.getPickupHouseNumber() != null) pickupHouseNumber.setValue(job.getPickupHouseNumber());
|
||||||
|
if (job.getPickupAddressAddition() != null) pickupAddressAddition.setValue(job.getPickupAddressAddition());
|
||||||
|
if (job.getPickupZip() != null) pickupZip.setValue(job.getPickupZip());
|
||||||
|
if (job.getPickupCity() != null) pickupCity.setValue(job.getPickupCity());
|
||||||
|
savePickupAddress.setValue(job.isSavePickupAddress());
|
||||||
|
|
||||||
|
// Delivery address
|
||||||
|
if (job.getDeliveryCompany() != null) deliveryCompany.setValue(job.getDeliveryCompany());
|
||||||
|
if (job.getDeliverySalutation() != null) deliverySalutation.setValue(job.getDeliverySalutation());
|
||||||
|
if (job.getDeliveryFirstName() != null) deliveryFirstName.setValue(job.getDeliveryFirstName());
|
||||||
|
if (job.getDeliveryLastName() != null) deliveryLastName.setValue(job.getDeliveryLastName());
|
||||||
|
if (job.getDeliveryPhone() != null) deliveryPhone.setValue(job.getDeliveryPhone());
|
||||||
|
if (job.getDeliveryStreet() != null) deliveryStreet.setValue(job.getDeliveryStreet());
|
||||||
|
if (job.getDeliveryHouseNumber() != null) deliveryHouseNumber.setValue(job.getDeliveryHouseNumber());
|
||||||
|
if (job.getDeliveryAddressAddition() != null) deliveryAddressAddition.setValue(job.getDeliveryAddressAddition());
|
||||||
|
if (job.getDeliveryZip() != null) deliveryZip.setValue(job.getDeliveryZip());
|
||||||
|
if (job.getDeliveryCity() != null) deliveryCity.setValue(job.getDeliveryCity());
|
||||||
|
saveDeliveryAddress.setValue(job.isSaveDeliveryAddress());
|
||||||
|
|
||||||
|
// Digital processing
|
||||||
|
digitalProcessing.setValue(job.isDigitalProcessing());
|
||||||
|
if (job.getAppUser() != null) appUser.setValue(job.getAppUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hilfsmethode zum Abrufen des aktuellen Benutzernamens
|
||||||
|
*/
|
||||||
|
private String getCurrentUsername() {
|
||||||
|
try {
|
||||||
|
// Hier würden Sie normalerweise den SecurityService verwenden
|
||||||
|
// Für diese Demo nehmen wir einen festen Wert
|
||||||
|
return "test@votianlt.de"; // TODO: SecurityService integrieren
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leert alle Felder im Formular
|
||||||
|
*/
|
||||||
|
private void clearAllFields() {
|
||||||
|
// Customer selection
|
||||||
|
customerSelection.clear();
|
||||||
|
|
||||||
|
// Pickup address
|
||||||
|
pickupCompany.clear();
|
||||||
|
pickupSalutation.clear();
|
||||||
|
pickupFirstName.clear();
|
||||||
|
pickupLastName.clear();
|
||||||
|
pickupPhone.clear();
|
||||||
|
pickupStreet.clear();
|
||||||
|
pickupHouseNumber.clear();
|
||||||
|
pickupAddressAddition.clear();
|
||||||
|
pickupZip.clear();
|
||||||
|
pickupCity.clear();
|
||||||
|
savePickupAddress.setValue(false);
|
||||||
|
|
||||||
|
// Delivery address
|
||||||
|
deliveryCompany.clear();
|
||||||
|
deliverySalutation.clear();
|
||||||
|
deliveryFirstName.clear();
|
||||||
|
deliveryLastName.clear();
|
||||||
|
deliveryPhone.clear();
|
||||||
|
deliveryStreet.clear();
|
||||||
|
deliveryHouseNumber.clear();
|
||||||
|
deliveryAddressAddition.clear();
|
||||||
|
deliveryZip.clear();
|
||||||
|
deliveryCity.clear();
|
||||||
|
saveDeliveryAddress.setValue(false);
|
||||||
|
|
||||||
|
// Digital processing
|
||||||
|
digitalProcessing.setValue(false);
|
||||||
|
appUser.clear();
|
||||||
|
|
||||||
|
// Benutzer-Feedback
|
||||||
|
Notification.show("Alle Felder wurden geleert", 2000, Notification.Position.BOTTOM_CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fügt Google Places Autocomplete zu einem TextField hinzu
|
||||||
|
*/
|
||||||
|
private void addGooglePlacesAutocomplete(TextField textField, int stageIndex) {
|
||||||
|
// Initialisierung als Runnable kapseln
|
||||||
|
Runnable initAutocomplete = () -> {
|
||||||
|
// Google Places API Script laden (falls noch nicht geladen)
|
||||||
|
UI.getCurrent().getPage().addJavaScript("https://maps.googleapis.com/maps/api/js?key=AIzaSyDnbitL06iLp3elmj-WtPudCykX9xvXcVE&libraries=places");
|
||||||
|
|
||||||
|
// JavaScript für Google Places Autocomplete - nutzt direkt das Input-Element
|
||||||
|
String script = """
|
||||||
|
setTimeout(function() {
|
||||||
|
var host = $0; // Vaadin TextField element
|
||||||
|
var input = host && host.inputElement ? host.inputElement : (host && host.shadowRoot ? host.shadowRoot.querySelector('input') : null);
|
||||||
|
if (input && window.google && window.google.maps && window.google.maps.places) {
|
||||||
|
var autocomplete = new google.maps.places.Autocomplete(input, {
|
||||||
|
types: ['establishment'],
|
||||||
|
componentRestrictions: {country: 'de'}
|
||||||
|
});
|
||||||
|
|
||||||
|
autocomplete.addListener('place_changed', function() {
|
||||||
|
var place = autocomplete.getPlace();
|
||||||
|
if (place && place.address_components) {
|
||||||
|
var streetNumber = '';
|
||||||
|
var route = '';
|
||||||
|
var locality = '';
|
||||||
|
var postalCode = '';
|
||||||
|
var country = '';
|
||||||
|
var companyName = place.name || '';
|
||||||
|
|
||||||
|
for (var i = 0; i < place.address_components.length; i++) {
|
||||||
|
var component = place.address_components[i];
|
||||||
|
var types = component.types || [];
|
||||||
|
|
||||||
|
if (types.indexOf('street_number') !== -1) {
|
||||||
|
streetNumber = component.long_name;
|
||||||
|
} else if (types.indexOf('route') !== -1) {
|
||||||
|
route = component.long_name;
|
||||||
|
} else if (types.indexOf('locality') !== -1) {
|
||||||
|
locality = component.long_name;
|
||||||
|
} else if (types.indexOf('postal_code') !== -1) {
|
||||||
|
postalCode = component.long_name;
|
||||||
|
} else if (types.indexOf('country') !== -1) {
|
||||||
|
country = component.long_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setze den Firmennamen in das Feld (sichtbar und Vaadin-Wert)
|
||||||
|
input.value = companyName || '';
|
||||||
|
host.value = companyName || '';
|
||||||
|
|
||||||
|
// Sende Daten an Server mit Stage-Index
|
||||||
|
$1.$server.handleGooglePlaceSelected(%d, companyName, route, streetNumber, postalCode, locality, country);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
setTimeout(arguments.callee, 500);
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
""".formatted(stageIndex);
|
||||||
|
|
||||||
|
// executeJs mit Referenzen: $0 => input element (shadowRoot), $1 => Server (this)
|
||||||
|
textField.getElement().executeJs(script, textField.getElement(), getElement());
|
||||||
|
|
||||||
|
log.debug("Google Places Autocomplete initialisiert (Stage {})", stageIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wenn UI bereits existiert, direkt initialisieren; sonst beim Attach initialisieren
|
||||||
|
textField.getUI().ifPresentOrElse(
|
||||||
|
ui -> ui.access((com.vaadin.flow.server.Command) initAutocomplete::run),
|
||||||
|
() -> textField.addAttachListener(event -> event.getUI().access((com.vaadin.flow.server.Command) initAutocomplete::run))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler für Google Places Auswahl - wird vom JavaScript aufgerufen
|
||||||
|
*/
|
||||||
|
@ClientCallable
|
||||||
|
public void handleGooglePlaceSelected(int stageIndex, String companyName, String route, String streetNumber, String postalCode, String locality, String country) {
|
||||||
|
log.debug("Google Place ausgewählt - Stage: {}, Company: {}, Route: {}, StreetNumber: {}, PostalCode: {}, Locality: {}, Country: {}",
|
||||||
|
stageIndex, companyName, route, streetNumber, postalCode, locality, country);
|
||||||
|
|
||||||
|
if (stageIndex == 0) {
|
||||||
|
// Pickup address
|
||||||
|
// Firmenname wird bereits durch das TextField selbst gesetzt
|
||||||
|
if (route != null && !route.isEmpty()) {
|
||||||
|
pickupStreet.setValue(route);
|
||||||
|
}
|
||||||
|
if (streetNumber != null && !streetNumber.isEmpty()) {
|
||||||
|
pickupHouseNumber.setValue(streetNumber);
|
||||||
|
}
|
||||||
|
if (postalCode != null && !postalCode.isEmpty()) {
|
||||||
|
pickupZip.setValue(postalCode);
|
||||||
|
}
|
||||||
|
if (locality != null && !locality.isEmpty()) {
|
||||||
|
pickupCity.setValue(locality);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notification für Benutzer
|
||||||
|
Notification.show("Abholadresse automatisch ausgefüllt: " + (companyName != null ? companyName : ""),
|
||||||
|
3000, Notification.Position.BOTTOM_CENTER);
|
||||||
|
|
||||||
|
} else if (stageIndex == 1) {
|
||||||
|
// Delivery address
|
||||||
|
// Firmenname wird bereits durch das TextField selbst gesetzt
|
||||||
|
if (route != null && !route.isEmpty()) {
|
||||||
|
deliveryStreet.setValue(route);
|
||||||
|
}
|
||||||
|
if (streetNumber != null && !streetNumber.isEmpty()) {
|
||||||
|
deliveryHouseNumber.setValue(streetNumber);
|
||||||
|
}
|
||||||
|
if (postalCode != null && !postalCode.isEmpty()) {
|
||||||
|
deliveryZip.setValue(postalCode);
|
||||||
|
}
|
||||||
|
if (locality != null && !locality.isEmpty()) {
|
||||||
|
deliveryCity.setValue(locality);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notification für Benutzer
|
||||||
|
Notification.show("Lieferadresse automatisch ausgefüllt: " + (companyName != null ? companyName : ""),
|
||||||
|
3000, Notification.Position.BOTTOM_CENTER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package de.assecutor.votianlt.repository;
|
||||||
|
|
||||||
|
import de.assecutor.votianlt.model.Job;
|
||||||
|
import de.assecutor.votianlt.model.JobStatus;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||||
|
import org.springframework.data.mongodb.repository.Query;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface JobRepository extends MongoRepository<Job, ObjectId> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet einen Auftrag anhand der Auftragsnummer
|
||||||
|
*/
|
||||||
|
Optional<Job> findByJobNumber(String jobNumber);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Aufträge eines bestimmten Status
|
||||||
|
*/
|
||||||
|
List<Job> findByStatus(JobStatus status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Aufträge, die von einem bestimmten Benutzer erstellt wurden
|
||||||
|
*/
|
||||||
|
List<Job> findByCreatedBy(String createdBy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Aufträge in einem bestimmten Zeitraum
|
||||||
|
*/
|
||||||
|
List<Job> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Aufträge mit einer bestimmten Abholstadt
|
||||||
|
*/
|
||||||
|
List<Job> findByPickupCity(String pickupCity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Aufträge mit einer bestimmten Lieferstadt
|
||||||
|
*/
|
||||||
|
List<Job> findByDeliveryCity(String deliveryCity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Aufträge mit digitaler Abwicklung
|
||||||
|
*/
|
||||||
|
List<Job> findByDigitalProcessingTrue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zählt Aufträge nach Status
|
||||||
|
*/
|
||||||
|
long countByStatus(JobStatus status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet die neuesten Aufträge (sortiert nach Erstellungsdatum)
|
||||||
|
*/
|
||||||
|
@Query(value = "{}", sort = "{ 'created_at' : -1 }")
|
||||||
|
List<Job> findLatestJobs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet Aufträge anhand einer Kundenauswahl
|
||||||
|
*/
|
||||||
|
List<Job> findByCustomerSelection(String customerSelection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft, ob eine Auftragsnummer bereits existiert
|
||||||
|
*/
|
||||||
|
boolean existsByJobNumber(String jobNumber);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle Entwürfe eines Benutzers
|
||||||
|
*/
|
||||||
|
List<Job> findByCreatedByAndIsDraftTrue(String createdBy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Findet alle finalen Aufträge (keine Entwürfe)
|
||||||
|
*/
|
||||||
|
List<Job> findByIsDraftFalse();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zählt alle Entwürfe
|
||||||
|
*/
|
||||||
|
long countByIsDraftTrue();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user