feat: persist splitMode/splitPercentage and list defaultSplitPercentage
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,8 @@ import java.time.LocalDateTime;
|
|||||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||||
|
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
import jakarta.persistence.GenerationType;
|
import jakarta.persistence.GenerationType;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
@@ -36,6 +38,12 @@ public class Expense {
|
|||||||
private Double personalUseAmount;
|
private Double personalUseAmount;
|
||||||
private Double otherPersonAmount;
|
private Double otherPersonAmount;
|
||||||
private String category;
|
private String category;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private SplitMode splitMode;
|
||||||
|
|
||||||
|
private Integer splitPercentage;
|
||||||
|
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
private LocalDateTime lastModified;
|
private LocalDateTime lastModified;
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ public class ExpenseChangeRequest {
|
|||||||
private Double personalUseAmount;
|
private Double personalUseAmount;
|
||||||
private Double otherPersonAmount;
|
private Double otherPersonAmount;
|
||||||
|
|
||||||
|
private SplitMode splitMode;
|
||||||
|
private Integer splitPercentage;
|
||||||
|
|
||||||
@NotNull(message = "Date is required")
|
@NotNull(message = "Date is required")
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
|
||||||
@@ -55,6 +58,8 @@ public class ExpenseChangeRequest {
|
|||||||
// The edit dialog sends "" for a missing category; store null so the
|
// The edit dialog sends "" for a missing category; store null so the
|
||||||
// stub state stays uniform and history diffs don't report null -> "".
|
// stub state stays uniform and history diffs don't report null -> "".
|
||||||
expense.setCategory(category == null || category.isBlank() ? null : category);
|
expense.setCategory(category == null || category.isBlank() ? null : category);
|
||||||
|
expense.setSplitMode(splitMode == null ? SplitMode.DETAILED : splitMode);
|
||||||
|
expense.setSplitPercentage(splitPercentage);
|
||||||
|
|
||||||
return expense;
|
return expense;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ public class ExpenseInput {
|
|||||||
private Double personalUseAmount;
|
private Double personalUseAmount;
|
||||||
private Double otherPersonAmount;
|
private Double otherPersonAmount;
|
||||||
|
|
||||||
|
private SplitMode splitMode;
|
||||||
|
private Integer splitPercentage;
|
||||||
|
|
||||||
@NotNull(message = "Date is required")
|
@NotNull(message = "Date is required")
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
|
||||||
@@ -56,6 +59,8 @@ public class ExpenseInput {
|
|||||||
expense.setOwner(appUser);
|
expense.setOwner(appUser);
|
||||||
expense.setTitle(title);
|
expense.setTitle(title);
|
||||||
expense.setCategory(category);
|
expense.setCategory(category);
|
||||||
|
expense.setSplitMode(splitMode == null ? SplitMode.DETAILED : splitMode);
|
||||||
|
expense.setSplitPercentage(splitPercentage);
|
||||||
|
|
||||||
return expense;
|
return expense;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ public class ExpenseList {
|
|||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
private Integer defaultSplitPercentage = 50;
|
||||||
|
|
||||||
private String inviteCode;
|
private String inviteCode;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private LocalDateTime inviteCodeExpiration;
|
private LocalDateTime inviteCodeExpiration;
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package de.zendric.app.xpensely_server.model;
|
||||||
|
|
||||||
|
public enum SplitMode {
|
||||||
|
DETAILED,
|
||||||
|
PERCENTAGE
|
||||||
|
}
|
||||||
@@ -137,6 +137,8 @@ public class ExpenseListService {
|
|||||||
existingExpense.setDate(updatedExpense.getDate());
|
existingExpense.setDate(updatedExpense.getDate());
|
||||||
existingExpense.setOwner(updatedExpense.getOwner());
|
existingExpense.setOwner(updatedExpense.getOwner());
|
||||||
existingExpense.setCategory(updatedExpense.getCategory());
|
existingExpense.setCategory(updatedExpense.getCategory());
|
||||||
|
existingExpense.setSplitMode(updatedExpense.getSplitMode());
|
||||||
|
existingExpense.setSplitPercentage(updatedExpense.getSplitPercentage());
|
||||||
existingExpense.setLastModified(LocalDateTime.now());
|
existingExpense.setLastModified(LocalDateTime.now());
|
||||||
|
|
||||||
Expense saved = expenseRepository.save(existingExpense);
|
Expense saved = expenseRepository.save(existingExpense);
|
||||||
@@ -153,6 +155,8 @@ public class ExpenseListService {
|
|||||||
copy.setPersonalUseAmount(e.getPersonalUseAmount());
|
copy.setPersonalUseAmount(e.getPersonalUseAmount());
|
||||||
copy.setOtherPersonAmount(e.getOtherPersonAmount());
|
copy.setOtherPersonAmount(e.getOtherPersonAmount());
|
||||||
copy.setCategory(e.getCategory());
|
copy.setCategory(e.getCategory());
|
||||||
|
copy.setSplitMode(e.getSplitMode());
|
||||||
|
copy.setSplitPercentage(e.getSplitPercentage());
|
||||||
copy.setDate(e.getDate());
|
copy.setDate(e.getDate());
|
||||||
copy.setOwner(e.getOwner());
|
copy.setOwner(e.getOwner());
|
||||||
return copy;
|
return copy;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package de.zendric.app.xpensely_Server.services;
|
|||||||
import de.zendric.app.xpensely_server.model.AppUser;
|
import de.zendric.app.xpensely_server.model.AppUser;
|
||||||
import de.zendric.app.xpensely_server.model.Expense;
|
import de.zendric.app.xpensely_server.model.Expense;
|
||||||
import de.zendric.app.xpensely_server.model.ExpenseList;
|
import de.zendric.app.xpensely_server.model.ExpenseList;
|
||||||
|
import de.zendric.app.xpensely_server.model.SplitMode;
|
||||||
import de.zendric.app.xpensely_server.repo.ExpenseListRepository;
|
import de.zendric.app.xpensely_server.repo.ExpenseListRepository;
|
||||||
import de.zendric.app.xpensely_server.repo.ExpenseRepository;
|
import de.zendric.app.xpensely_server.repo.ExpenseRepository;
|
||||||
import de.zendric.app.xpensely_server.repo.XpenselyCustomCategoryRepository;
|
import de.zendric.app.xpensely_server.repo.XpenselyCustomCategoryRepository;
|
||||||
@@ -109,6 +110,29 @@ class ExpenseListServiceTest {
|
|||||||
assertThat(beforeCaptor.getValue().getAmount()).isEqualTo(12.0);
|
assertThat(beforeCaptor.getValue().getAmount()).isEqualTo(12.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void updateExpense_persistsSplitModeAndPercentage() {
|
||||||
|
AppUser actor = new AppUser(); actor.setId(1L);
|
||||||
|
ExpenseList list = new ExpenseList(); list.setId(10L); list.setOwner(actor);
|
||||||
|
Expense existing = makeExpense(5L, "Groceries", 100.0);
|
||||||
|
list.setExpenses(new ArrayList<>(List.of(existing)));
|
||||||
|
|
||||||
|
Expense incoming = makeExpense(5L, "Groceries", 100.0);
|
||||||
|
incoming.setDate(LocalDate.now());
|
||||||
|
incoming.setOwner(list.getOwner());
|
||||||
|
incoming.setSplitMode(SplitMode.PERCENTAGE);
|
||||||
|
incoming.setSplitPercentage(70);
|
||||||
|
|
||||||
|
when(repository.findById(10L)).thenReturn(Optional.of(list));
|
||||||
|
when(expenseRepository.findById(5L)).thenReturn(Optional.of(existing));
|
||||||
|
when(expenseRepository.save(any(Expense.class))).thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
Expense saved = service.updateExpense(10L, incoming, actor);
|
||||||
|
|
||||||
|
assertThat(saved.getSplitMode()).isEqualTo(SplitMode.PERCENTAGE);
|
||||||
|
assertThat(saved.getSplitPercentage()).isEqualTo(70);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void deleteById_deletesHistoryEntriesBeforeDeletingList() {
|
void deleteById_deletesHistoryEntriesBeforeDeletingList() {
|
||||||
service.deleteById(10L);
|
service.deleteById(10L);
|
||||||
|
|||||||
Reference in New Issue
Block a user