fix: major changes

This commit is contained in:
filippo-ferrari 2024-09-08 16:10:50 +02:00
parent 6475f83dd8
commit 50a0325341
7 changed files with 224 additions and 136 deletions

View file

@ -13,7 +13,7 @@ import java.time.LocalDateTime;
@Getter @Getter
@Setter @Setter
@Table(name = "expenses") @Table(name = "expenses")
public class Expense extends AbstractEntity { public class Expense {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@ -46,11 +46,11 @@ public class Expense extends AbstractEntity {
@ManyToOne @ManyToOne
@JoinColumn(name = "CreditorId") @JoinColumn(name = "CreditorId")
private Person creditor; private Person payer;
@ManyToOne @ManyToOne
@JoinColumn(name = "DebtorId") @JoinColumn(name = "DebtorId")
private Person debtor; private Person beneficiary;
@ManyToOne @ManyToOne
@JoinColumn(name = "EventId") @JoinColumn(name = "EventId")

View file

@ -40,11 +40,12 @@ public class Person extends AbstractEntity {
@Column(name = "credit") @Column(name = "credit")
private BigDecimal credit; private BigDecimal credit;
@OneToMany(mappedBy = "creditor") // Updated to match the new field names in Expense
private Set<Expense> creditExpenses; @OneToMany(mappedBy = "payer")
private Set<Expense> expensesAsPayer;
@OneToMany(mappedBy = "debtor") @OneToMany(mappedBy = "beneficiary")
private Set<Expense> debtExpenses; private Set<Expense> expensesAsBeneficiary;
@ManyToMany(mappedBy = "participants") @ManyToMany(mappedBy = "participants")
private Set<Event> events; private Set<Event> events;

View file

@ -14,24 +14,24 @@ import java.util.Set;
public interface ExpenseRepository extends JpaRepository<Expense, Long>, JpaSpecificationExecutor<Expense> { public interface ExpenseRepository extends JpaRepository<Expense, Long>, JpaSpecificationExecutor<Expense> {
// Find expenses where the creditor is a specific person // Find expenses where the creditor is a specific person
@Query("SELECT e FROM Expense e WHERE e.creditor.id = :personId") @Query("SELECT e FROM Expense e WHERE e.payer.id = :personId")
Set<Expense> findCreditorsExpensesByPersonId(@Param("personId") Long personId); Set<Expense> findExpensesByPayer(@Param("personId") Long personId);
// Find expenses where the debtor is a specific person // Find expenses where the debtor is a specific person
@Query("SELECT e FROM Expense e WHERE e.debtor.id = :personId") @Query("SELECT e FROM Expense e WHERE e.beneficiary.id = :personId")
Set<Expense> findDebtorsExpensesByPersonId(@Param("personId") Long personId); Set<Expense> findExpensesByBeneficiary(@Param("personId") Long personId);
// Find all expenses for a given year // Find all expenses for a given year
@Query("SELECT e FROM Expense e WHERE YEAR(e.date) = :year") @Query("SELECT e FROM Expense e WHERE YEAR(e.date) = :year")
List<Expense> findAllByYear(@Param("year") int year); List<Expense> findAllByYear(@Param("year") int year);
// Find unpaid expenses where the creditor is a specific person // Find unpaid expenses where the creditor is a specific person
@Query("SELECT e FROM Expense e WHERE e.creditor.id = :personId AND e.isPaid = false") @Query("SELECT e FROM Expense e WHERE e.payer.id = :personId AND e.isPaid = false")
Set<Expense> findUnpaidCreditorsExpensesByPersonId(@Param("personId") Long personId); Set<Expense> findUnpaidExpensesByPayer(@Param("personId") Long personId);
// Find unpaid expenses where the debtor is a specific person // Find unpaid expenses where the debtor is a specific person
@Query("SELECT e FROM Expense e WHERE e.debtor.id = :personId AND e.isPaid = false") @Query("SELECT e FROM Expense e WHERE e.beneficiary.id = :personId AND e.isPaid = false")
Set<Expense> findUnpaidDebtorsExpensesByPersonId(@Param("personId") Long personId); Set<Expense> findUnapidExpensesByBeneficiary(@Param("personId") Long personId);
// Find expenses for a given year and filter by expense type and paid status // Find expenses for a given year and filter by expense type and paid status
@Query("SELECT e FROM Expense e WHERE YEAR(e.date) = :year AND NOT (e.expenseType = :expenseType AND e.isPaid = true)") @Query("SELECT e FROM Expense e WHERE YEAR(e.date) = :year AND NOT (e.expenseType = :expenseType AND e.isPaid = true)")

View file

@ -26,99 +26,102 @@ public class ExpenseService {
this.expenseRepository = expenseRepository; this.expenseRepository = expenseRepository;
} }
/**
* Retrieves an expense by its ID.
* @param id the ID of the expense
* @return an Optional containing the expense if found, otherwise empty
*/
public Optional<Expense> get(Long id) { public Optional<Expense> get(Long id) {
return expenseRepository.findById(id); return expenseRepository.findById(id);
} }
/** /**
* finds all expenses tagged as debit given a user * Finds all expenses where the specified person is the beneficiary.
* @param person the user of the expenses * @param person the user of the expenses
* @return the collections of expenses found * @return the collection of expenses found
*/ */
public Collection<Expense> findDebtByUser(final Person person) { public Collection<Expense> findExpensesWhereBeneficiary(final Person person) {
return expenseRepository.findDebtorsExpensesByPersonId(person.getId()); return expenseRepository.findExpensesByBeneficiary(person.getId());
} }
/** /**
* finds all expenses tagged as credit given a user * Finds all expenses where the specified person is the payer.
* @param person the user of the expenses * @param person the user of the expenses
* @return the collections of expenses found * @return the collection of expenses found
*/ */
public Collection<Expense> findCreditByUser(final Person person) { public Collection<Expense> findExpensesWherePayer(final Person person) {
return expenseRepository.findCreditorsExpensesByPersonId(person.getId()); return expenseRepository.findExpensesByPayer(person.getId());
} }
/** /**
* finds all expenses tagged as debit and unpaid given a user * Finds all expenses where the specified person is the beneficiary and the expense is unpaid.
* @param person the user of the expenses * @param person the user of the expenses
* @return the collections of expenses found * @return the collection of unpaid expenses found
*/ */
public Collection<Expense> findUnpaidDebtByUser(final Person person) { public Collection<Expense> findUnpaidExpensesWhereBeneficiary(final Person person) {
return expenseRepository.findUnpaidDebtorsExpensesByPersonId(person.getId()); return expenseRepository.findUnapidExpensesByBeneficiary(person.getId());
} }
/** /**
* finds all expenses tagged as credit and unpaid given a user * Finds all expenses where the specified person is the payer and the expense is unpaid.
* @param person the user of the expenses * @param person the user of the expenses
* @return the collections of expenses found * @return the collection of unpaid expenses found
*/ */
public Collection<Expense> findUnpaidCreditByUser(final Person person) { public Collection<Expense> findUnpaidExpensesWherePayer(final Person person) {
return expenseRepository.findUnpaidCreditorsExpensesByPersonId(person.getId()); return expenseRepository.findUnpaidExpensesByPayer(person.getId());
} }
/** /**
* finds all expenses related to a user * Finds all expenses related to a user, both where the user is a payer and a beneficiary.
* @param person the user of the expenses * @param person the user of the expenses
* @return the collections of expenses found * @return the list of expenses found
*/ */
public List<Expense> findExpenseByUser(final Person person) { public List<Expense> findExpensesByUser(final Person person) {
final var credits = this.findCreditByUser(person); // Retrieve expenses where the person is the payer
final var debits = this.findDebtByUser(person); final var payerExpenses = this.findExpensesWherePayer(person);
return Stream.concat(credits.stream(), debits.stream()).toList(); // Retrieve expenses where the person is the beneficiary
final var beneficiaryExpenses = this.findExpensesWhereBeneficiary(person);
// Combine both sets of expenses into a single list without duplicates
return Stream.concat(payerExpenses.stream(), beneficiaryExpenses.stream())
.distinct()
.toList();
} }
public List<Expense> findAll() {return expenseRepository.findAll();}
/** /**
* updates an expense * Retrieves all expenses.
* @param entity the expense to update * @return the list of all expenses
*/ */
public void update(Expense entity) { public List<Expense> findAll() {
if (Boolean.TRUE.equals(entity.getIsPaid())) entity.setPaymentDate(LocalDateTime.now()); return expenseRepository.findAll();
this.setExpenseType(entity);
expenseRepository.save(entity);
} }
/** /**
* deletes an expense given the ID * Finds all expenses for a given year.
* @param id the id of the expense to delete * @param year the year for which to find expenses
* @return the list of expenses found
*/ */
public void delete(Long id) { public List<Expense> findAllByYear(final int year) {
expenseRepository.deleteById(id);
}
public Page<Expense> list(Pageable pageable) {
return expenseRepository.findAll(pageable);
}
public Page<Expense> list(Pageable pageable, Specification<Expense> filter) {
return expenseRepository.findAll(filter, pageable);
}
public int count() {
return (int) expenseRepository.count();
}
public List<Expense> findAllByYear(final int year ) {
return this.expenseRepository.findAllByYear(year); return this.expenseRepository.findAllByYear(year);
} }
/**
* Fetches all expenses ordered by date in descending order.
* @return the list of expenses found
*/
public List<Expense> findAllOrderByDateDescending() {
return this.expenseRepository.findAllByOrderByDateDesc();
}
/**
* Finds expenses by year excluding those marked as credit and paid.
* @param year the year for which to find expenses
* @return the list of expenses found
*/
public List<Expense> findExpensesByYearExcludingCreditPaid(int year) { public List<Expense> findExpensesByYearExcludingCreditPaid(int year) {
return expenseRepository.findByYearAndFilterCreditPaid(year, ExpenseType.CREDIT); return expenseRepository.findByYearAndFilterCreditPaid(year, ExpenseType.CREDIT);
} }
/** /**
* checks if an expense has been paid * Checks if an expense has been paid.
* @param expense the expense to check * @param expense the expense to check
* @return true if the expense has been paid, false otherwise * @return true if the expense has been paid, false otherwise
*/ */
@ -127,35 +130,76 @@ public class ExpenseService {
} }
/** /**
* fetches all expenses ordered by date descending * Updates an existing expense.
* @return the list of expenses found * @param entity the expense to update
*/ */
public List<Expense> findAllOrderByDateDescending() { public void update(Expense entity) {
return this.expenseRepository.findAllByOrderByDateDesc(); if (Boolean.TRUE.equals(entity.getIsPaid())) {
entity.setPaymentDate(LocalDateTime.now());
}
this.setExpenseType(entity);
expenseRepository.save(entity);
} }
/** /**
* sets the Expense type depending on the presence or absence of creditors and debtors * Deletes an expense given its ID.
* this is used to filter expenses with a creditor that are paid, since they are not part of * @param id the ID of the expense to delete
* the actual money the user has spent, it's just a load technically */
public void delete(Long id) {
expenseRepository.deleteById(id);
}
/**
* Lists expenses in a paginated format.
* @param pageable the pagination information
* @return a page of expenses
*/
public Page<Expense> list(Pageable pageable) {
return expenseRepository.findAll(pageable);
}
/**
* Lists expenses in a paginated format with filtering options.
* @param pageable the pagination information
* @param filter the filter specification
* @return a page of expenses matching the filter
*/
public Page<Expense> list(Pageable pageable, Specification<Expense> filter) {
return expenseRepository.findAll(filter, pageable);
}
/**
* Counts the total number of expenses.
* @return the count of expenses
*/
public int count() {
return (int) expenseRepository.count();
}
// ================================
// Private methods
// ================================
/**
* Sets the expense type depending on the presence or absence of a payer and beneficiary.
* This is used to filter expenses where the payer has been reimbursed.
* @param expense the expense to set the type of * @param expense the expense to set the type of
*/ */
private void setExpenseType(final @Nonnull Expense expense) { private void setExpenseType(final @Nonnull Expense expense) {
// Check if the creditor is present // Check if the payer is present
if (Objects.nonNull(expense.getCreditor())) { if (Objects.nonNull(expense.getPayer())) {
// If creditor is present, set type to CREDIT // If payer is present, set type to CREDIT
expense.setExpenseType(ExpenseType.CREDIT); expense.setExpenseType(ExpenseType.CREDIT);
} }
// Check if the debtor is present and no creditor // Check if the beneficiary is present and no payer
else if (Objects.nonNull(expense.getDebtor())) { else if (Objects.nonNull(expense.getBeneficiary())) {
// If debtor is present and no creditor, set type to DEBIT // If beneficiary is present and no payer, set type to DEBIT
expense.setExpenseType(ExpenseType.DEBIT); expense.setExpenseType(ExpenseType.DEBIT);
} }
// If neither creditor nor debtor is present // If neither payer nor beneficiary is present
else { else {
// If neither creditor nor debtor is present, set type to NONE // Set type to NONE
expense.setExpenseType(ExpenseType.NONE); expense.setExpenseType(ExpenseType.NONE);
} }
} }
} }

View file

@ -9,7 +9,7 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Collection; import java.util.List;
import java.util.Optional; import java.util.Optional;
@Service @Service
@ -23,60 +23,108 @@ public class PersonService {
this.expenseService = expenseService; this.expenseService = expenseService;
} }
/**
* Finds a person by ID.
* @param id the ID of the person
* @return an optional containing the person if found, otherwise empty
*/
public Optional<Person> get(Long id) { public Optional<Person> get(Long id) {
return personRepository.findById(id); return personRepository.findById(id);
} }
public Collection<Person> findAll() { /**
* Finds all persons.
* @return a collection of all persons
*/
public List<Person> findAll() {
return this.personRepository.findAll(); return this.personRepository.findAll();
} }
public void update(Person person) { /**
this.personRepository.save(person); * Lists all persons with pagination.
} * @param pageable the pagination information
* @return a page of persons
public void delete(Long id) { */
this.personRepository.deleteById(id); public Page<Person> list(Pageable pageable) {
}
public Page<Person> list(Pageable pageable){
return personRepository.findAll(pageable); return personRepository.findAll(pageable);
} }
/**
* Lists all persons with pagination and filtering.
* @param pageable the pagination information
* @param filter the specification filter
* @return a page of persons matching the filter
*/
public Page<Person> list(Pageable pageable, Specification<Person> filter) { public Page<Person> list(Pageable pageable, Specification<Person> filter) {
return this.personRepository.findAll(filter, pageable); return this.personRepository.findAll(filter, pageable);
} }
/**
* Counts the total number of persons.
* @return the total count of persons
*/
public int count() { public int count() {
return (int) this.personRepository.count(); return (int) this.personRepository.count();
} }
/** /**
* calculates the debt a certain person has * Updates a person in the repository.
* @param person the person of which you want to know the debt * @param person the person to update
* @return the debt that a certain person has
*/ */
public BigDecimal calculateDebt(final Person person){ public void update(Person person) {
return this.expenseService.findDebtByUser(person).stream().map(Expense::getCost).reduce(BigDecimal.ZERO, BigDecimal::add); this.personRepository.save(person);
} }
/** /**
* calculates the credit a certain person has * Deletes a person by ID.
* @param person the person of which you want to know the credit * @param id the ID of the person to delete
* @return the credit that a certain person has */
public void delete(Long id) {
this.personRepository.deleteById(id);
}
/**
* Calculates the total debt of a person.
* @param person the person whose debt is to be calculated
* @return the total debt amount
*/
public BigDecimal calculateDebt(final Person person) {
return this.expenseService.findExpensesWherePayer(person).stream()
.filter(expense -> !expense.getBeneficiary().equals(person) && Boolean.FALSE.equals(expense.getIsPaid()))
.map(Expense::getCost)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* Calculates the total credit of a person.
* @param person the person whose credit is to be calculated
* @return the total credit amount
*/ */
public BigDecimal calculateCredit(final Person person) { public BigDecimal calculateCredit(final Person person) {
return this.expenseService.findCreditByUser(person).stream().map(Expense::getCost).reduce(BigDecimal.ZERO, BigDecimal::add); return this.expenseService.findExpensesWhereBeneficiary(person).stream()
.filter(expense -> !expense.getPayer().equals(person) && Boolean.FALSE.equals(expense.getIsPaid()))
.map(Expense::getCost)
.reduce(BigDecimal.ZERO, BigDecimal::add);
} }
/** /**
* calculates the balance of a person using the money owed or paid off to that person * Calculates the net balance of a person.
* @param person the person of which you want to know the balance * The net balance is the difference between the total amount the person is owed
* @return the amount of money owed or paid off to a certain person * (expenses where they are the payer) and the total amount the person owes
* (expenses where they are the beneficiary).
*
* A positive net balance means the person is owed money.
* A negative net balance means the person owes money.
*
* @param person the person whose net balance is to be calculated
* @return the net balance amount
*/ */
public BigDecimal calculateNetBalance(final Person person) { public BigDecimal calculateNetBalance(final Person person) {
final var credit = this.expenseService.findUnpaidCreditByUser(person).stream().map(Expense::getCost).reduce(BigDecimal.ZERO, BigDecimal::add); // Calculate total debt (what others owe to the person)
final var debit = this.expenseService.findUnpaidDebtByUser(person).stream().map(Expense::getCost).reduce(BigDecimal.ZERO, BigDecimal::add); final BigDecimal debt = this.calculateDebt(person);
return credit.subtract(debit); // Calculate total credit (what the person owes to others)
final BigDecimal credit = this.calculateCredit(person);
// Net balance calculation: debt (owed to the person) - credit (person owes)
return debt.subtract(credit);
} }
} }

View file

@ -66,8 +66,8 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
private ComboBox<PeriodUnit> periodUnit; private ComboBox<PeriodUnit> periodUnit;
private TextField periodInterval; private TextField periodInterval;
private DatePicker date; private DatePicker date;
private ComboBox<Person> creditor; private ComboBox<Person> payer;
private ComboBox<Person> debtor; private ComboBox<Person> beneficiary;
private ComboBox<Event> event; private ComboBox<Event> event;
public ExpensesView(ExpenseService expenseService, CategoryService categoryService, PersonService personService, EventService eventService, ViewService viewService) { public ExpensesView(ExpenseService expenseService, CategoryService categoryService, PersonService personService, EventService eventService, ViewService viewService) {
@ -94,7 +94,6 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
grid.addColumn(Expense::getPeriodUnit).setHeader("Period Unit").setSortable(true); grid.addColumn(Expense::getPeriodUnit).setHeader("Period Unit").setSortable(true);
grid.addColumn(Expense::getDate).setHeader("Date").setSortable(true).setSortProperty("date"); grid.addColumn(Expense::getDate).setHeader("Date").setSortable(true).setSortProperty("date");
// grid.addColumn(expenseEvent -> expenseEvent.getEvent().getName()).setHeader("Event").setSortable(true); // grid.addColumn(expenseEvent -> expenseEvent.getEvent().getName()).setHeader("Event").setSortable(true);
grid.addColumn(new ComponentRenderer<>(this.viewService::createExpenseBadge)).setHeader("Status").setSortable(true); grid.addColumn(new ComponentRenderer<>(this.viewService::createExpenseBadge)).setHeader("Status").setSortable(true);
grid.getColumns().forEach(col -> col.setAutoWidth(true)); grid.getColumns().forEach(col -> col.setAutoWidth(true));
@ -156,11 +155,11 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
//TODO: THIS NEEDS TO BE IMPLEMENTED BUT FOR THE SINGLE PERSON NOW, STILL NEEDED //TODO: THIS NEEDS TO BE IMPLEMENTED BUT FOR THE SINGLE PERSON NOW, STILL NEEDED
// // Event listeners that will remove the selected creditors from the debtors list and vice versa // // Event listeners that will remove the selected creditors from the debtors list and vice versa
// // Done so that the user cant create an expense with the same person as creditor and debtor // // Done so that the user cant create an expense with the same person as creditor and debtor
// debtors.addValueChangeListener(event -> { // payer.addValueChangeListener(event -> {
// Set<Person> selectedDebtors = event.getValue(); // Person selectedDebtors = event.getValue();
// final var creditorsSet = new HashSet<>(personService.findAll()); // final var creditorsSet = new HashSet<>(personService.findAll());
// creditorsSet.removeIf(selectedDebtors::contains); // creditorsSet.removeIf(creditorsSet.contains(selectedDebtors));
// creditors.setItems(creditorsSet); // payer.setItems(creditorsSet);
// }); // });
// //
// creditors.addValueChangeListener(event -> { // creditors.addValueChangeListener(event -> {
@ -232,10 +231,10 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
private void createEditorLayout(SplitLayout splitLayout) { private void createEditorLayout(SplitLayout splitLayout) {
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();
FormLayout formLayout = new FormLayout(); FormLayout formLayout = new FormLayout();
name = new TextField("Name"); name = new TextField("Name");
@ -247,15 +246,15 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
periodUnit = new ComboBox<>("Period Unit"); periodUnit = new ComboBox<>("Period Unit");
periodUnit.setItems(PeriodUnit.values()); periodUnit.setItems(PeriodUnit.values());
periodInterval = new TextField("Period Interval"); periodInterval = new TextField("Period Interval");
creditor = new ComboBox<>("Creditor"); payer = new ComboBox<>("Payer");
creditor.setItems(personService.findAll()); payer.setItems(people);
creditor.setItemLabelGenerator(Person::getFirstName); payer.setItemLabelGenerator(Person::getFirstName);
event = new ComboBox<>("Event"); event = new ComboBox<>("Event");
event.setItems(eventService.findAll()); event.setItems(eventService.findAll());
event.setItemLabelGenerator(Event::getName); event.setItemLabelGenerator(Event::getName);
debtor = new ComboBox<>("Debtor"); beneficiary = new ComboBox<>("Beneficiary");
debtor.setItems(personService.findAll()); beneficiary.setItems(people);
debtor.setItemLabelGenerator(Person::getFirstName); beneficiary.setItemLabelGenerator(Person::getFirstName);
date = new DatePicker("Date"); date = new DatePicker("Date");
// Horizontal layout for checkboxes // Horizontal layout for checkboxes
@ -264,7 +263,7 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
isPaid = new Checkbox("Paid"); isPaid = new Checkbox("Paid");
checkboxLayout.add(isPeriodic, isPaid); checkboxLayout.add(isPeriodic, isPaid);
formLayout.add(name, cost, category, description, checkboxLayout, periodUnit, periodInterval, date, creditor, debtor, event); formLayout.add(name, cost, category, description, checkboxLayout, periodUnit, periodInterval, date, payer, beneficiary, event);
editorDiv.add(formLayout); editorDiv.add(formLayout);
createButtonLayout(editorLayoutDiv); createButtonLayout(editorLayoutDiv);
@ -304,9 +303,5 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
boolean isPeriodicChecked = (value != null) && value.getIsPeriodic(); boolean isPeriodicChecked = (value != null) && value.getIsPeriodic();
periodUnit.setVisible(isPeriodicChecked); periodUnit.setVisible(isPeriodicChecked);
periodInterval.setVisible(isPeriodicChecked); periodInterval.setVisible(isPeriodicChecked);
// Set selected items for creditor and debtor
creditor.setValue(value != null ? value.getCreditor() : null);
debtor.setValue(value != null ? value.getDebtor() : null);
} }
} }

View file

@ -83,9 +83,9 @@ public class PeopleView extends Div implements BeforeEnterObserver {
else return this.viewService.createExpenseBadge(((Expense) persona)); else return this.viewService.createExpenseBadge(((Expense) persona));
})).setHeader("Balance Status"); })).setHeader("Balance Status");
grid.addColumn(new ComponentRenderer<>(person -> { grid.addColumn(new ComponentRenderer<>(persona -> {
if (person instanceof Person) { if (persona instanceof Person) {
Button markPaidButton = new Button("Mark All Expenses Paid", event -> markExpensesPaid((Person) person)); Button markPaidButton = new Button("Mark All Expenses Paid", event -> markExpensesPaid((Person) persona));
markPaidButton.addThemeVariants(ButtonVariant.LUMO_SMALL, ButtonVariant.LUMO_PRIMARY); markPaidButton.addThemeVariants(ButtonVariant.LUMO_SMALL, ButtonVariant.LUMO_PRIMARY);
return markPaidButton; return markPaidButton;
} else { } else {
@ -93,7 +93,7 @@ public class PeopleView extends Div implements BeforeEnterObserver {
} }
})).setHeader("Actions"); })).setHeader("Actions");
List<Person> people = (List<Person>) personService.findAll(); List<Person> people = personService.findAll();
this.setGridData(people); this.setGridData(people);
@ -248,7 +248,7 @@ public class PeopleView extends Div implements BeforeEnterObserver {
grid.getTreeData().addItem(null, user); grid.getTreeData().addItem(null, user);
// Fetch expenses for the current person // Fetch expenses for the current person
List<Expense> expenses = expenseService.findExpenseByUser(user); List<Expense> expenses = expenseService.findExpensesByUser(user);
// 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(user, expense);
@ -257,7 +257,7 @@ public class PeopleView extends Div implements BeforeEnterObserver {
private void markExpensesPaid(Person person) { private void markExpensesPaid(Person person) {
try { try {
List<Expense> expenses = expenseService.findCreditByUser(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);