diff --git a/src/main/java/de/assecutor/votianlt/model/User.java b/src/main/java/de/assecutor/votianlt/model/User.java index 2978a1b..363da6d 100644 --- a/src/main/java/de/assecutor/votianlt/model/User.java +++ b/src/main/java/de/assecutor/votianlt/model/User.java @@ -6,7 +6,6 @@ import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.index.Indexed; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Set; @@ -18,28 +17,29 @@ public class User { private ObjectId id; private int usrId; - private int hqId; - private short type; private String title; - private String name; - private String firstname; - private LocalDate birthdate; + private String name; // Nachname + private String firstname; // Vorname + + // Firmen-/Adressdaten + private String company; // Firma + private String street; // Straße + private String houseNumber; // Hausnr + private String addressAddition; // Adresszusatz (optional) + private String zip; // Postleitzahl + private String city; // Stadt @Indexed(unique = true) private String email; - private String invitationEmail; private String phone; private String phone2; private String fax; private String password; private byte isActivated; - private String activationCode; private byte isEmailConfirmed; - private byte isPasswordLost; private String passwordCode; private LocalDateTime passwordTimestamp; - private LocalDateTime activationDate; private LocalDateTime createdAt; private LocalDateTime updatedAt; private Set roles; diff --git a/src/main/java/de/assecutor/votianlt/pages/service/AddJobService.java b/src/main/java/de/assecutor/votianlt/pages/service/AddJobService.java index 31bc9f9..0337114 100644 --- a/src/main/java/de/assecutor/votianlt/pages/service/AddJobService.java +++ b/src/main/java/de/assecutor/votianlt/pages/service/AddJobService.java @@ -40,7 +40,7 @@ public class AddJobService { job.setCreatedAt(now); job.setUpdatedAt(now); job.setStatus(JobStatus.CREATED); - job.setCreatedBy(securityService.getCurrentUsername()); + job.setCreatedBy(securityService.getCurrentUserId().toHexString()); // Auftragsnummer generieren, falls nicht vorhanden if (job.getJobNumber() == null || job.getJobNumber().isEmpty()) { diff --git a/src/main/java/de/assecutor/votianlt/pages/view/RegisterView.java b/src/main/java/de/assecutor/votianlt/pages/view/RegisterView.java index 09fca81..0fa753d 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/RegisterView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/RegisterView.java @@ -7,6 +7,8 @@ import com.vaadin.flow.component.html.H2; import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.component.orderedlayout.FlexComponent; import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.formlayout.FormLayout; import com.vaadin.flow.component.textfield.PasswordField; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.router.PageTitle; @@ -31,6 +33,17 @@ public class RegisterView extends VerticalLayout { private TextField emailField; private PasswordField passwordField; private PasswordField confirmPasswordField; + + // Zusätzliche Pflichtfelder aus EditProfileView + private TextField firstNameField; + private TextField lastNameField; + private TextField phoneField; + private TextField companyField; + private TextField streetField; + private TextField houseNumberField; + private TextField zipField; + private TextField cityField; + private TextField codeField; private Button submitButton; private Button verifyButton; @@ -58,7 +71,7 @@ public class RegisterView extends VerticalLayout { private VerticalLayout createFormContainer() { VerticalLayout container = new VerticalLayout(); - container.setWidth("400px"); + container.setWidth("980px"); container.setPadding(true); container.setSpacing(true); container.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH); @@ -98,6 +111,32 @@ public class RegisterView extends VerticalLayout { confirmPasswordField.setRequired(true); confirmPasswordField.setPlaceholder("Passwort wiederholen"); + // Pflichtfelder aus EditProfileView + firstNameField = new TextField("Vorname"); + firstNameField.setWidthFull(); + firstNameField.setRequired(true); + lastNameField = new TextField("Nachname"); + lastNameField.setWidthFull(); + lastNameField.setRequired(true); + phoneField = new TextField("Telefonnummer"); + phoneField.setWidthFull(); + phoneField.setRequired(true); + companyField = new TextField("Firma"); + companyField.setWidthFull(); + companyField.setRequired(true); + streetField = new TextField("Straße"); + streetField.setWidthFull(); + streetField.setRequired(true); + houseNumberField = new TextField("Hausnr"); + houseNumberField.setWidthFull(); + houseNumberField.setRequired(true); + zipField = new TextField("Postleitzahl"); + zipField.setWidthFull(); + zipField.setRequired(true); + cityField = new TextField("Stadt"); + cityField.setWidthFull(); + cityField.setRequired(true); + codeField = new TextField("Bestätigungscode (6 Ziffern)"); codeField.setWidthFull(); codeField.setMaxLength(6); @@ -132,8 +171,43 @@ public class RegisterView extends VerticalLayout { backButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); backButton.setWidthFull(); - container.add(title, subtitle, emailField, passwordField, confirmPasswordField, - submitButton, codeField, verifyButton, resendButton, backButton); + // Zweispaltiges Formular + FormLayout form = new FormLayout(); + form.setWidthFull(); + form.setResponsiveSteps( + new FormLayout.ResponsiveStep("0", 2) + ); + + // Erste Reihe: Zugangsdaten + form.add(emailField, passwordField, confirmPasswordField); + form.setColspan(emailField, 2); + + // Personen-/Firmendaten + form.add(firstNameField, lastNameField); + form.add(phoneField, companyField); + form.add(streetField, houseNumberField); + form.add(zipField, cityField); + + // Code und Verifikations-Buttons (ausgeblendet bis Versand) + form.add(codeField); + form.setColspan(codeField, 2); + + // Button-Zeile: Verifizieren/Resenden nebeneinander + HorizontalLayout verifyRow = new HorizontalLayout(verifyButton, resendButton); + verifyRow.setWidthFull(); + verifyRow.setSpacing(true); + verifyRow.setAlignItems(FlexComponent.Alignment.STRETCH); + verifyRow.setFlexGrow(1, verifyButton, resendButton); + form.add(verifyRow); + form.setColspan(verifyRow, 2); + + // Haupt-Submit-Button und Zurück-Link über volle Breite + form.add(submitButton); + form.setColspan(submitButton, 2); + form.add(backButton); + form.setColspan(backButton, 2); + + container.add(title, subtitle, form); return container; } @@ -173,6 +247,56 @@ public class RegisterView extends VerticalLayout { return; } + // Weitere Pflichtfelder prüfen (aus Edit-Profile) + var firstName = firstNameField.getValue() != null ? firstNameField.getValue().trim() : ""; + if (firstName.isEmpty()) { + Notification.show("Bitte geben Sie Ihren Vornamen ein.", 3000, Notification.Position.MIDDLE); + firstNameField.focus(); + return; + } + var lastName = lastNameField.getValue() != null ? lastNameField.getValue().trim() : ""; + if (lastName.isEmpty()) { + Notification.show("Bitte geben Sie Ihren Nachnamen ein.", 3000, Notification.Position.MIDDLE); + lastNameField.focus(); + return; + } + var phone = phoneField.getValue() != null ? phoneField.getValue().trim() : ""; + if (phone.isEmpty()) { + Notification.show("Bitte geben Sie Ihre Telefonnummer ein.", 3000, Notification.Position.MIDDLE); + phoneField.focus(); + return; + } + var company = companyField.getValue() != null ? companyField.getValue().trim() : ""; + if (company.isEmpty()) { + Notification.show("Bitte geben Sie den Firmennamen ein.", 3000, Notification.Position.MIDDLE); + companyField.focus(); + return; + } + var street = streetField.getValue() != null ? streetField.getValue().trim() : ""; + if (street.isEmpty()) { + Notification.show("Bitte geben Sie die Straße ein.", 3000, Notification.Position.MIDDLE); + streetField.focus(); + return; + } + var houseNo = houseNumberField.getValue() != null ? houseNumberField.getValue().trim() : ""; + if (houseNo.isEmpty()) { + Notification.show("Bitte geben Sie die Hausnummer ein.", 3000, Notification.Position.MIDDLE); + houseNumberField.focus(); + return; + } + var zip = zipField.getValue() != null ? zipField.getValue().trim() : ""; + if (zip.isEmpty()) { + Notification.show("Bitte geben Sie die Postleitzahl ein.", 3000, Notification.Position.MIDDLE); + zipField.focus(); + return; + } + var city = cityField.getValue() != null ? cityField.getValue().trim() : ""; + if (city.isEmpty()) { + Notification.show("Bitte geben Sie die Stadt ein.", 3000, Notification.Position.MIDDLE); + cityField.focus(); + return; + } + // Alles ok: Code erzeugen und senden sendVerificationCode(email); } @@ -205,6 +329,17 @@ public class RegisterView extends VerticalLayout { emailField.setReadOnly(true); passwordField.setReadOnly(true); confirmPasswordField.setReadOnly(true); + + // Zusätzliche Felder sperren + firstNameField.setReadOnly(true); + lastNameField.setReadOnly(true); + phoneField.setReadOnly(true); + companyField.setReadOnly(true); + streetField.setReadOnly(true); + houseNumberField.setReadOnly(true); + zipField.setReadOnly(true); + cityField.setReadOnly(true); + submitButton.setEnabled(false); Notification.show("Ein Bestätigungscode wurde an " + email + " gesendet.", 4000, Notification.Position.MIDDLE); @@ -236,8 +371,24 @@ public class RegisterView extends VerticalLayout { // Code korrekt -> Benutzer erstellen var email = emailField.getValue().trim(); var password = passwordField.getValue(); + var firstName = firstNameField.getValue() != null ? firstNameField.getValue().trim() : ""; + var lastName = lastNameField.getValue() != null ? lastNameField.getValue().trim() : ""; + var phone = phoneField.getValue() != null ? phoneField.getValue().trim() : ""; try { - userService.createUser(email, password, "Benutzer", "Name"); + var user = userService.createUser(email, password, firstName, lastName); + // Persistiere zusätzliche Profil-/Adressdaten + if (!phone.isBlank()) user.setPhone(phone); + var company = companyField.getValue() != null ? companyField.getValue().trim() : null; + var street = streetField.getValue() != null ? streetField.getValue().trim() : null; + var houseNo = houseNumberField.getValue() != null ? houseNumberField.getValue().trim() : null; + var zip = zipField.getValue() != null ? zipField.getValue().trim() : null; + var city = cityField.getValue() != null ? cityField.getValue().trim() : null; + user.setCompany(company); + user.setStreet(street); + user.setHouseNumber(houseNo); + user.setZip(zip); + user.setCity(city); + userService.save(user); VaadinSession.getCurrent().setAttribute("flashMessage", "Registrierung erfolgreich. Bitte melden Sie sich an."); getUI().ifPresent(ui -> ui.navigate("login")); } catch (RuntimeException e) { diff --git a/src/main/java/de/assecutor/votianlt/pages/view/ShowCustomersView.java b/src/main/java/de/assecutor/votianlt/pages/view/ShowCustomersView.java index b9ebfdd..a283b15 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/ShowCustomersView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/ShowCustomersView.java @@ -11,6 +11,7 @@ import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import de.assecutor.votianlt.model.Customer; import de.assecutor.votianlt.pages.service.CustomerService; +import de.assecutor.votianlt.security.SecurityService; import jakarta.annotation.security.RolesAllowed; import org.springframework.beans.factory.annotation.Autowired; @@ -20,11 +21,13 @@ import org.springframework.beans.factory.annotation.Autowired; public class ShowCustomersView extends VerticalLayout { private final CustomerService customerService; + private final SecurityService securityService; private final Grid grid = new Grid<>(Customer.class, false); @Autowired - public ShowCustomersView(CustomerService customerService) { + public ShowCustomersView(CustomerService customerService, SecurityService securityService) { this.customerService = customerService; + this.securityService = securityService; setSizeFull(); setPadding(true); setSpacing(true); @@ -86,6 +89,10 @@ public class ShowCustomersView extends VerticalLayout { private void loadData() { var customers = customerService.findAll(); - grid.setItems(customers); + var currentUserId = securityService.getCurrentUserId(); + var ownCustomers = customers.stream() + .filter(c -> c.getCreatedBy() != null && c.getCreatedBy().equals(currentUserId)) + .toList(); + grid.setItems(ownCustomers); } } diff --git a/src/main/java/de/assecutor/votianlt/pages/view/ShowJobsView.java b/src/main/java/de/assecutor/votianlt/pages/view/ShowJobsView.java index d8fdb59..b6d79d9 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/ShowJobsView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/ShowJobsView.java @@ -13,6 +13,7 @@ import com.vaadin.flow.router.Route; 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 jakarta.annotation.security.RolesAllowed; import org.springframework.beans.factory.annotation.Autowired; @@ -24,11 +25,13 @@ public class ShowJobsView extends VerticalLayout { private final DatePicker startDate = new DatePicker("Startdatum"); private final DatePicker endDate = new DatePicker("Enddatum"); private final JobRepository jobRepository; + private final SecurityService securityService; private final Grid grid = new Grid<>(Job.class, false); @Autowired - public ShowJobsView(JobRepository jobRepository) { + public ShowJobsView(JobRepository jobRepository, SecurityService securityService) { this.jobRepository = jobRepository; + this.securityService = securityService; setSizeFull(); setPadding(true); setSpacing(true); @@ -88,16 +91,20 @@ public class ShowJobsView extends VerticalLayout { java.time.LocalDateTime startDt = start != null ? start.atStartOfDay() : java.time.LocalDate.now().minusDays(30).atStartOfDay(); java.time.LocalDateTime endDt = end != null ? end.atTime(23,59,59) : java.time.LocalDate.now().atTime(23,59,59); - // Hole Aufträge im Zeitraum und filtere auf offene Status + // Aktuellen Benutzer (ObjectId Hex) ermitteln + String currentUserIdHex = securityService.getCurrentUserId().toHexString(); + + // Hole Aufträge im Zeitraum, filtere auf offenen Status und auf den angemeldeten Benutzer var inRange = jobRepository.findByCreatedAtBetween(startDt, endDt); - var open = inRange.stream() + var openAndOwn = inRange.stream() .filter(j -> j.getStatus() == JobStatus.CREATED || j.getStatus() == JobStatus.IN_PROGRESS || j.getStatus() == JobStatus.PICKUP_SCHEDULED || j.getStatus() == JobStatus.PICKED_UP || j.getStatus() == JobStatus.IN_TRANSIT) + .filter(j -> j.getCreatedBy() != null && j.getCreatedBy().equals(currentUserIdHex)) .toList(); - grid.setItems(open); + grid.setItems(openAndOwn); } private void exportToCsv() {