feat: multi-tenancy

This commit is contained in:
effe 2024-09-14 12:35:29 -04:00
parent d3e0490eee
commit b476cb9846
12 changed files with 93 additions and 63 deletions

View file

@ -49,7 +49,7 @@ public class Person {
@Column(name = "Username", unique = true) @Column(name = "Username", unique = true)
private String username; // This field will link to the User entity private String username; // This field will link to the User entity
@Column(name = "UserId", unique = true, nullable = false) @Column(name = "UserId", nullable = false)
private Long userId; // Reference to the User entity private Long userId; // Reference to the User entity
@Override @Override

View file

@ -14,9 +14,9 @@ public class ExpenseFacade {
this.expenseService = expenseService; this.expenseService = expenseService;
} }
public void setExpensePaid(Expense expense, TreeGrid<Object> grid) { public void setExpensePaid(Expense expense, TreeGrid<Object> grid, Long userId) {
expense.setIsPaid(true); expense.setIsPaid(true);
this.expenseService.update(expense); this.expenseService.update(expense, userId);
Notification.show("Expense " + expense.getName() + " set as paid" ); Notification.show("Expense " + expense.getName() + " set as paid" );
grid.select(null); grid.select(null);
grid.getDataProvider().refreshAll(); grid.getDataProvider().refreshAll();

View file

@ -18,12 +18,12 @@ public class PersonFacade {
public PersonFacade(ExpenseService expenseService) { public PersonFacade(ExpenseService expenseService) {
this.expenseService = expenseService; this.expenseService = expenseService;
} }
public void setDebtPaid(Person person, TreeGrid<Object> grid) { public void setDebtPaid(Person person, TreeGrid<Object> grid, Long userId) {
try { try {
List<Expense> expenses = expenseService.findExpensesWherePayer(person).stream().toList(); List<Expense> expenses = expenseService.findExpensesWherePayer(person).stream().toList();
for (Expense expense : expenses) { for (Expense expense : expenses) {
expense.setIsPaid(true); expense.setIsPaid(true);
expenseService.update(expense); expenseService.update(expense, userId);
} }
Notification.show("All expenses marked as paid for " + person.getFirstName() + " " + person.getLastName()); Notification.show("All expenses marked as paid for " + person.getFirstName() + " " + person.getLastName());
grid.select(null); grid.select(null);
@ -35,12 +35,12 @@ public class PersonFacade {
} }
} }
public void setCreditPaid(Person person, TreeGrid<Object> grid) { public void setCreditPaid(Person person, TreeGrid<Object> grid, Long userId) {
try { try {
List<Expense> expenses = expenseService.findExpensesWhereBeneficiary(person).stream().toList(); List<Expense> expenses = expenseService.findExpensesWhereBeneficiary(person).stream().toList();
for (Expense expense : expenses) { for (Expense expense : expenses) {
expense.setIsPaid(true); expense.setIsPaid(true);
expenseService.update(expense); expenseService.update(expense, userId);
} }
Notification.show("All expenses marked as paid for " + person.getFirstName() + " " + person.getLastName()); Notification.show("All expenses marked as paid for " + person.getFirstName() + " " + person.getLastName());
grid.select(null); grid.select(null);

View file

@ -56,5 +56,5 @@ public interface ExpenseRepository extends JpaRepository<Expense, Long>, JpaSpec
boolean existsByIdAndIsPaidTrue(Long id); boolean existsByIdAndIsPaidTrue(Long id);
// Find all expenses ordered by date descending // Find all expenses ordered by date descending
List<Expense> findAllByOrderByDateDesc(); List<Expense> findByUserIdOrderByDateDesc(Long userId);
} }

View file

@ -1,16 +1,30 @@
package com.application.munera.repositories; package com.application.munera.repositories;
import com.application.munera.data.Person; import com.application.munera.data.Person;
import com.application.munera.data.User;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
public interface PersonRepository extends JpaRepository<Person, Long>, JpaSpecificationExecutor<Person> { public interface PersonRepository extends JpaRepository<Person, Long>, JpaSpecificationExecutor<Person> {
Optional<Person> findByUserId(Long userId);
@Query("SELECT p FROM Person p WHERE p.userId IS NULL") Person findByUsername(String username);
List<Person> findAllExcludeUser();
@Query("SELECT p FROM Person p WHERE p.username = :username")
Optional<Person> findOptionalByUsername(@Param("username") String username);
/**
* finds all the people that the logged user has created, minus the person that represents the logged user
* @param userId the logged user id, to get all people connected to id
* @param username the logged username, to filter out
* @return the list people found
*/
@Query("SELECT p FROM Person p WHERE p.userId = :userId AND (p.username IS NULL OR p.username <> :username)")
List<Person> findAllByUserIdExcludingPerson(@Param("userId") Long userId, @Param("username") String username);
List<Person> findByUserId(Long userId);
} }

View file

@ -2,6 +2,8 @@ package com.application.munera.repositories;
import com.application.munera.data.User; import com.application.munera.data.User;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -10,5 +12,5 @@ import java.util.Optional;
@Repository @Repository
public interface UserRepository extends JpaRepository<User, Long> { public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(final @Nonnull String username); @Query("SELECT u FROM User u WHERE u.username = :username")
} Optional<User> findByUsername(@Param("username") String username);}

View file

@ -16,7 +16,6 @@ import org.springframework.stereotype.Service;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Year; import java.time.Year;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -83,11 +82,11 @@ public class ExpenseService {
} }
/** /**
* Finds all expenses related to a user, both where the user is a payer and a beneficiary. * Finds all expenses related to a person, both where the person is a payer and a beneficiary.
* @param person the user of the expenses * @param person the person of the expenses
* @return the list of expenses found * @return the list of expenses found
*/ */
public List<Expense> findExpensesByUser(final Person person) { public List<Expense> findExpensesByPerson(final Person person) {
// Retrieve expenses where the person is the payer // Retrieve expenses where the person is the payer
final var payerExpenses = this.findExpensesWherePayer(person); final var payerExpenses = this.findExpensesWherePayer(person);
// Retrieve expenses where the person is the beneficiary // Retrieve expenses where the person is the beneficiary
@ -118,8 +117,8 @@ public class ExpenseService {
* Fetches all expenses ordered by date in descending order. * Fetches all expenses ordered by date in descending order.
* @return the list of expenses found * @return the list of expenses found
*/ */
public List<Expense> findAllOrderByDateDescending() { public List<Expense> findAllOrderByDateDescending(Long userId) {
return this.expenseRepository.findAllByOrderByDateDesc(); return this.expenseRepository.findByUserIdOrderByDateDesc(userId);
} }
/** /**
@ -144,7 +143,8 @@ public class ExpenseService {
* Updates an existing expense. * Updates an existing expense.
* @param entity the expense to update * @param entity the expense to update
*/ */
public void update(Expense entity) { public void update(Expense entity, Long userId) {
entity.setUserId(userId);
if (Boolean.TRUE.equals(entity.getIsPaid())) entity.setPaymentDate(LocalDate.now()); if (Boolean.TRUE.equals(entity.getIsPaid())) entity.setPaymentDate(LocalDate.now());
else entity.setPaymentDate(null); else entity.setPaymentDate(null);
this.setExpenseType(entity); this.setExpenseType(entity);
@ -223,14 +223,12 @@ public class ExpenseService {
*/ */
private void setExpenseType(final @Nonnull Expense expense) { private void setExpenseType(final @Nonnull Expense expense) {
// Get the currently logged-in user // Get the currently logged-in user
UserDetails userDetails = SecurityUtils.getLoggedInUserDetails(); final var userDetails = SecurityUtils.getLoggedInUserDetails();
if (userDetails == null) { if (userDetails == null) throw new IllegalStateException("No logged-in user found");
throw new IllegalStateException("No logged-in user found");
}
// Fetch the logged-in user // Fetch the logged-in user
final var loggedInUserId = userRepository.findByUsername(userDetails.getUsername()) final var loggedInUser = userRepository.findByUsername(userDetails.getUsername())
.orElseThrow(() -> new UsernameNotFoundException("User not found")).getId(); .orElseThrow(() -> new UsernameNotFoundException("User not found"));
Person loggedInPerson = this.personRepository.findByUserId(loggedInUserId).orElse(null); Person loggedInPerson = this.personRepository.findByUsername(loggedInUser.getUsername());
if (loggedInPerson == null) throw new IllegalStateException("No associated Person entity found for logged-in user"); if (loggedInPerson == null) throw new IllegalStateException("No associated Person entity found for logged-in user");

View file

@ -2,11 +2,11 @@ package com.application.munera.services;
import com.application.munera.data.Expense; import com.application.munera.data.Expense;
import com.application.munera.data.Person; import com.application.munera.data.Person;
import com.application.munera.data.User;
import com.application.munera.repositories.PersonRepository; import com.application.munera.repositories.PersonRepository;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -40,20 +40,22 @@ public class PersonService {
* Finds all persons. * Finds all persons.
* @return a collection of all persons * @return a collection of all persons
*/ */
public List<Person> findAll() { public List<Person> findAllByUserId(Long userId) {
return this.personRepository.findAll(); return this.personRepository.findByUserId(userId);
} }
public Optional<Person> findByUserId(Long id) { public Person findByUsername(String username) {
return this.personRepository.findByUserId(id); return this.personRepository.findByUsername(username);
} }
/** /**
* Finds all people excluding the users'ones. * Finds all people excluding the users'ones.
* @return a collection of all persons * @return a collection of all persons
*/ */
public List<Person> findAllExcludeUsers() { public List<Person> findAllExcludeLoggedUser(User user) {
return this.personRepository.findAllExcludeUser(); final var userId = user.getId();
final var username = user.getUsername();
return this.personRepository.findAllByUserIdExcludingPerson(userId, username);
} }
/** /**
@ -90,14 +92,15 @@ public class PersonService {
*/ */
public Person getLoggedInPerson() { public Person getLoggedInPerson() {
final var user = userService.getLoggedInUser(); final var user = userService.getLoggedInUser();
return Objects.requireNonNull(personRepository.findByUserId(user.getId()).orElse(null)); return Objects.requireNonNull(personRepository.findByUsername(user.getUsername()));
} }
/** /**
* Updates a person in the repository. * Updates a person in the repository.
* @param person the person to update * @param person the person to update
*/ */
public void update(Person person) { public void update(Person person, Long userId) {
person.setUserId(userId);
this.personRepository.save(person); this.personRepository.save(person);
} }

View file

@ -5,7 +5,6 @@ import com.application.munera.data.User;
import com.application.munera.repositories.PersonRepository; import com.application.munera.repositories.PersonRepository;
import com.application.munera.repositories.UserRepository; import com.application.munera.repositories.UserRepository;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@ -59,7 +58,7 @@ public class UserService {
userRepository.save(userToSave); userRepository.save(userToSave);
// Check if the associated person exists for the user // Check if the associated person exists for the user
final var existingPersonOptional = personRepository.findByUserId(userToSave.getId()); final var existingPersonOptional = personRepository.findOptionalByUsername(userToSave.getUsername());
if (existingPersonOptional.isPresent()) { if (existingPersonOptional.isPresent()) {
// If person exists, update the person entity // If person exists, update the person entity
@ -106,7 +105,7 @@ public class UserService {
public void delete(final User user) { public void delete(final User user) {
this.userRepository.delete(user); this.userRepository.delete(user);
final var person = this.personRepository.findByUserId(user.getId()); final var person = this.personRepository.findByUsername(user.getUsername());
person.ifPresent(this.personRepository::delete); this.personRepository.delete(person);
} }
} }

View file

@ -2,8 +2,10 @@ package com.application.munera.views.dashboard;
import com.application.munera.data.Expense; import com.application.munera.data.Expense;
import com.application.munera.data.Person; import com.application.munera.data.Person;
import com.application.munera.data.User;
import com.application.munera.services.ExpenseService; import com.application.munera.services.ExpenseService;
import com.application.munera.services.PersonService; import com.application.munera.services.PersonService;
import com.application.munera.services.UserService;
import com.application.munera.views.MainLayout; import com.application.munera.views.MainLayout;
import com.nimbusds.jose.shaded.gson.Gson; import com.nimbusds.jose.shaded.gson.Gson;
import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.Div;
@ -28,10 +30,14 @@ public class DashboardView extends Div {
private final ExpenseService expenseService; private final ExpenseService expenseService;
private final PersonService personService; private final PersonService personService;
private final UserService userService;
private final User loggedUser;
public DashboardView(final ExpenseService expenseService, final PersonService personService) { public DashboardView(final ExpenseService expenseService, final PersonService personService, UserService userService) {
this.expenseService = expenseService; this.expenseService = expenseService;
this.personService = personService; this.personService = personService;
this.userService = userService;
loggedUser = userService.getLoggedInUser();
addClassName("highcharts-view"); // Optional CSS class for styling addClassName("highcharts-view"); // Optional CSS class for styling
VerticalLayout mainLayout = new VerticalLayout(); VerticalLayout mainLayout = new VerticalLayout();
@ -190,7 +196,7 @@ public class DashboardView extends Div {
} }
private String generateNegativeColumnChartScript() { private String generateNegativeColumnChartScript() {
final var people = personService.findAllExcludeUsers().stream() final var people = personService.findAllExcludeLoggedUser(loggedUser).stream()
.filter(person -> personService.calculateNetBalance(person).compareTo(BigDecimal.ZERO) != 0) .filter(person -> personService.calculateNetBalance(person).compareTo(BigDecimal.ZERO) != 0)
.toList(); .toList();
if (people.isEmpty()) return generatePlaceholderChartScript("bottomLeftChart", "All Payments Settled"); if (people.isEmpty()) return generatePlaceholderChartScript("bottomLeftChart", "All Payments Settled");

View file

@ -56,6 +56,7 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
private final BeanValidationBinder<Expense> binder; private final BeanValidationBinder<Expense> binder;
private Expense expense; private Expense expense;
private Long userId;
private final ExpenseService expenseService; private final ExpenseService expenseService;
private final CategoryService categoryService; private final CategoryService categoryService;
@ -81,6 +82,7 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
this.personService = personService; this.personService = personService;
this.viewsService = viewsService; this.viewsService = viewsService;
this.userService = userService; this.userService = userService;
this.userId = userService.getLoggedInUser().getId();
addClassNames("expenses-view"); addClassNames("expenses-view");
// Create UI // Create UI
@ -101,7 +103,7 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
grid.addColumn(new ComponentRenderer<>(this.viewsService::createExpenseBadge)).setHeader("Status").setSortable(true); grid.addColumn(new ComponentRenderer<>(this.viewsService::createExpenseBadge)).setHeader("Status").setSortable(true);
grid.getColumns().forEach(col -> col.setAutoWidth(true)); grid.getColumns().forEach(col -> col.setAutoWidth(true));
grid.setItems(this.expenseService.findAllOrderByDateDescending()); grid.setItems(this.expenseService.findAllOrderByDateDescending(userId));
grid.setPaginatorSize(5); grid.setPaginatorSize(5);
grid.setPageSize(22); // setting page size grid.setPageSize(22); // setting page size
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER); grid.addThemeVariants(GridVariant.LUMO_NO_BORDER);
@ -180,7 +182,7 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
try { try {
if (this.expense == null) this.expense = new Expense(); if (this.expense == null) this.expense = new Expense();
binder.writeBean(this.expense); binder.writeBean(this.expense);
expenseService.update(this.expense); expenseService.update(this.expense, userId);
clearForm(); clearForm();
refreshGrid(); refreshGrid();
Notification.show("Data updated"); Notification.show("Data updated");
@ -235,13 +237,12 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
} }
private void createEditorLayout(SplitLayout splitLayout) { private void createEditorLayout(SplitLayout splitLayout) {
final var userId = this.userService.getLoggedInUser().getId();
Div editorLayoutDiv = new Div(); Div editorLayoutDiv = new Div();
editorLayoutDiv.setClassName("editor-layout"); editorLayoutDiv.setClassName("editor-layout");
Div editorDiv = new Div(); Div editorDiv = new Div();
editorDiv.setClassName("editor"); editorDiv.setClassName("editor");
editorLayoutDiv.add(editorDiv); editorLayoutDiv.add(editorDiv);
final var people = this.personService.findAll(); final var people = this.personService.findAllByUserId(userId);
FormLayout formLayout = new FormLayout(); FormLayout formLayout = new FormLayout();
name = new TextField("Name"); name = new TextField("Name");
@ -292,7 +293,7 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
} }
private void refreshGrid() { private void refreshGrid() {
grid.setItems(this.expenseService.findAllOrderByDateDescending()); grid.setItems(this.expenseService.findAllOrderByDateDescending(userId));
grid.select(null); grid.select(null);
grid.getDataProvider().refreshAll(); grid.getDataProvider().refreshAll();
} }
@ -309,19 +310,18 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
periodInterval.setVisible(isPeriodicChecked); periodInterval.setVisible(isPeriodicChecked);
} }
//TODO: check and improve this mess pls
private void initializeComboBoxes() { private void initializeComboBoxes() {
// Fetch the logged-in user's Person entity // Fetch the logged-in user's Person entity
UserDetails userDetails = SecurityUtils.getLoggedInUserDetails(); UserDetails userDetails = SecurityUtils.getLoggedInUserDetails();
if (userDetails != null) { if (userDetails != null) {
String username = userDetails.getUsername(); String username = userDetails.getUsername();
final var user = this.userService.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("User not found")); final var user = this.userService.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("User not found"));
Optional<Person> loggedInPerson = personService.findByUserId(user.getId()); final var loggedInPerson = personService.findByUsername(user.getUsername());
if (loggedInPerson.isPresent()) {
Person person = loggedInPerson.get();
// Set default values for payer and beneficiary ComboBoxes // Set default values for payer and beneficiary ComboBoxes
payer.setValue(person); payer.setValue(loggedInPerson);
beneficiary.setValue(person); beneficiary.setValue(loggedInPerson);
}
} }
} }
} }

View file

@ -2,10 +2,12 @@ package com.application.munera.views.people;
import com.application.munera.data.Expense; import com.application.munera.data.Expense;
import com.application.munera.data.Person; import com.application.munera.data.Person;
import com.application.munera.data.User;
import com.application.munera.facades.ExpenseFacade; import com.application.munera.facades.ExpenseFacade;
import com.application.munera.facades.PersonFacade; import com.application.munera.facades.PersonFacade;
import com.application.munera.services.ExpenseService; import com.application.munera.services.ExpenseService;
import com.application.munera.services.PersonService; import com.application.munera.services.PersonService;
import com.application.munera.services.UserService;
import com.application.munera.services.ViewsService; import com.application.munera.services.ViewsService;
import com.application.munera.views.MainLayout; import com.application.munera.views.MainLayout;
import com.vaadin.flow.component.UI; import com.vaadin.flow.component.UI;
@ -56,21 +58,27 @@ public class PeopleView extends Div implements BeforeEnterObserver {
private final BeanValidationBinder<Person> binder; private final BeanValidationBinder<Person> binder;
private Person person; private Person person;
private User loggedUser;
private Long userId;
private final PersonService personService; private final PersonService personService;
private final PersonFacade personFacade; private final PersonFacade personFacade;
private final ExpenseFacade expenseFacade; private final ExpenseFacade expenseFacade;
private final ExpenseService expenseService; private final ExpenseService expenseService;
private final ViewsService viewsService; private final ViewsService viewsService;
private final UserService userService;
private TextField firstName; private TextField firstName;
private TextField lastName; private TextField lastName;
private EmailField email; private EmailField email;
public PeopleView(PersonService personService, ExpenseService expenseService, ViewsService viewsService, PersonFacade personFacade, ExpenseFacade expenseFacade) { public PeopleView(PersonService personService, ExpenseService expenseService, ViewsService viewsService, PersonFacade personFacade, ExpenseFacade expenseFacade, UserService userService) {
this.personService = personService; this.personService = personService;
this.expenseService = expenseService; this.expenseService = expenseService;
this.viewsService = viewsService; this.viewsService = viewsService;
this.personFacade = personFacade; this.personFacade = personFacade;
this.expenseFacade = expenseFacade; this.expenseFacade = expenseFacade;
this.userService = userService;
loggedUser = userService.getLoggedInUser();
userId = loggedUser.getId();
addClassNames("expenses-view"); addClassNames("expenses-view");
// Create UI // Create UI
@ -92,12 +100,12 @@ public class PeopleView extends Div implements BeforeEnterObserver {
grid.addColumn(new ComponentRenderer<>(persona -> { grid.addColumn(new ComponentRenderer<>(persona -> {
switch (persona) { switch (persona) {
case Person person1 -> { case Person person1 -> {
Button setDebtPaidButton = new Button("Set all debt as paid", event -> this.personFacade.setDebtPaid(person1, grid)); Button setDebtPaidButton = new Button("Set all debt as paid", event -> this.personFacade.setDebtPaid(person1, grid, userId));
setDebtPaidButton.addThemeVariants(ButtonVariant.LUMO_SMALL, ButtonVariant.LUMO_PRIMARY); setDebtPaidButton.addThemeVariants(ButtonVariant.LUMO_SMALL, ButtonVariant.LUMO_PRIMARY);
return setDebtPaidButton; return setDebtPaidButton;
} }
case Expense expense -> { case Expense expense -> {
Button setExpensePaidButton = new Button("Set as paid", event -> this.expenseFacade.setExpensePaid(expense, grid)); Button setExpensePaidButton = new Button("Set as paid", event -> this.expenseFacade.setExpensePaid(expense, grid, userId));
setExpensePaidButton.addThemeVariants(ButtonVariant.LUMO_SMALL); setExpensePaidButton.addThemeVariants(ButtonVariant.LUMO_SMALL);
if (Boolean.TRUE.equals((expense).getIsPaid())) setExpensePaidButton.setEnabled(false); if (Boolean.TRUE.equals((expense).getIsPaid())) setExpensePaidButton.setEnabled(false);
return setExpensePaidButton; return setExpensePaidButton;
@ -110,13 +118,13 @@ public class PeopleView extends Div implements BeforeEnterObserver {
grid.addColumn(new ComponentRenderer<>(persona -> { grid.addColumn(new ComponentRenderer<>(persona -> {
if (persona instanceof Person person1) { if (persona instanceof Person person1) {
Button setCreditPaidButton = new Button("Set all credit as paid", event -> this.personFacade.setCreditPaid(person1, grid)); Button setCreditPaidButton = new Button("Set all credit as paid", event -> this.personFacade.setCreditPaid(person1, grid, userId));
setCreditPaidButton.addThemeVariants(ButtonVariant.LUMO_SMALL, ButtonVariant.LUMO_PRIMARY); setCreditPaidButton.addThemeVariants(ButtonVariant.LUMO_SMALL, ButtonVariant.LUMO_PRIMARY);
return setCreditPaidButton; return setCreditPaidButton;
} else return new Span(); } else return new Span();
})); }));
List<Person> people = personService.findAllExcludeUsers(); List<Person> people = personService.findAllExcludeLoggedUser(loggedUser);
this.setGridData(people); this.setGridData(people);
@ -148,7 +156,7 @@ public class PeopleView extends Div implements BeforeEnterObserver {
try { try {
if (this.person == null) this.person = new Person(); if (this.person == null) this.person = new Person();
binder.writeBean(this.person); binder.writeBean(this.person);
personService.update(this.person); personService.update(this.person, userId);
clearForm(); clearForm();
refreshGrid(); refreshGrid();
Notification.show("Data updated"); Notification.show("Data updated");
@ -263,15 +271,15 @@ public class PeopleView extends Div implements BeforeEnterObserver {
} }
public void setGridData(List<Person> people) { public void setGridData(List<Person> people) {
for (Person user : people) { for (Person person : people) {
// Add the person as a root item // Add the person as a root item
grid.getTreeData().addItem(null, user); grid.getTreeData().addItem(null, person);
// Fetch expenses for the current person // Fetch expenses for the current person
List<Expense> expenses = expenseService.findExpensesByUser(user); List<Expense> expenses = expenseService.findExpensesByPerson(person);
// Add each expense as a child item under the person // Add each expense as a child item under the person
for (Expense expense : expenses) grid.getTreeData().addItem(user, expense); for (Expense expense : expenses) grid.getTreeData().addItem(person, expense);
} }
} }
} }