diff --git a/pom.xml b/pom.xml index d9decdd..6abd81e 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,10 @@ spring-boot-starter-security + org.springframework.boot + spring-boot-starter-oauth2-resource-server + + org.springframework.boot spring-boot-starter-oauth2-client diff --git a/src/main/java/de/zendric/app/xpensely_server/controller/ExpenseListController.java b/src/main/java/de/zendric/app/xpensely_server/controller/ExpenseListController.java index 1fc6a4e..705b306 100644 --- a/src/main/java/de/zendric/app/xpensely_server/controller/ExpenseListController.java +++ b/src/main/java/de/zendric/app/xpensely_server/controller/ExpenseListController.java @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -19,6 +20,7 @@ import org.springframework.web.bind.annotation.RestController; import de.zendric.app.xpensely_server.model.AppUser; import de.zendric.app.xpensely_server.model.Expense; +import de.zendric.app.xpensely_server.model.ExpenseChangeRequest; import de.zendric.app.xpensely_server.model.ExpenseInput; import de.zendric.app.xpensely_server.model.ExpenseList; import de.zendric.app.xpensely_server.model.InviteRequest; @@ -142,6 +144,26 @@ class ExpenseListController { } } + @PutMapping("/{id}/update") + public ResponseEntity updateExpenseInList( + @PathVariable("id") Long expenseListId, + @RequestBody ExpenseChangeRequest expenseChangeRequest) { + try { + AppUser expenseOwner = userService.getUserByName(expenseChangeRequest.getOwnerName()); + Optional expenseList = expenseListService.findById(expenseListId); + if (expenseList.isPresent()) { + Expense expense = expenseChangeRequest.convertToExpense(expenseOwner.getId(), expenseList.get()); + + Expense addedExpense = expenseListService.updateExpense(expenseListId, expense); + return new ResponseEntity<>(addedExpense, HttpStatus.CREATED); + } + return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); + + } catch (Exception e) { + return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); + } + } + @DeleteMapping("/{id}/delete") public ResponseEntity deleteExpenseFromList( @PathVariable("id") Long expenseListId, diff --git a/src/main/java/de/zendric/app/xpensely_server/model/Expense.java b/src/main/java/de/zendric/app/xpensely_server/model/Expense.java index 828eaae..ab7bab7 100644 --- a/src/main/java/de/zendric/app/xpensely_server/model/Expense.java +++ b/src/main/java/de/zendric/app/xpensely_server/model/Expense.java @@ -32,7 +32,8 @@ public class Expense { private AppUser owner; private Double amount; - private Double deviation; + private Double personalUseAmount; + private Double otherPersonAmount; private LocalDate date; diff --git a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseChangeRequest.java b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseChangeRequest.java new file mode 100644 index 0000000..c028b00 --- /dev/null +++ b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseChangeRequest.java @@ -0,0 +1,39 @@ +package de.zendric.app.xpensely_server.model; + +import java.time.LocalDate; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ExpenseChangeRequest { + + private Long id; + private String title; + private String ownerName; + private Double amount; + private Double personalUseAmount; + private Double otherPersonAmount; + private LocalDate date; + + public Expense convertToExpense(Long userId, ExpenseList expenseList) { + AppUser appUser = new AppUser(); + appUser.setId(userId); + appUser.setUsername(ownerName); + + Expense expense = new Expense(); + expense.setAmount(amount); + expense.setDate(date); + expense.setPersonalUseAmount(personalUseAmount); + expense.setOtherPersonAmount(otherPersonAmount); + expense.setExpenseList(expenseList); + expense.setId(id); + expense.setOwner(appUser); + expense.setTitle(title); + + return expense; + } +} \ No newline at end of file diff --git a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseInput.java b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseInput.java index 5d8418f..a36c7cf 100644 --- a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseInput.java +++ b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseInput.java @@ -25,7 +25,8 @@ public class ExpenseInput { private String owner; private Double amount; - private Double deviation; + private Double personalUseAmount; + private Double otherPersonAmount; private LocalDate date; @@ -39,7 +40,7 @@ public class ExpenseInput { Expense expense = new Expense(); expense.setAmount(amount); expense.setDate(date); - expense.setDeviation(deviation); + expense.setPersonalUseAmount(personalUseAmount); expense.setExpenseList(expenseList); expense.setId(id); expense.setOwner(appUser); diff --git a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseList.java b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseList.java index 56e2aee..a31f9de 100644 --- a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseList.java +++ b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseList.java @@ -42,6 +42,7 @@ public class ExpenseList { @OneToMany(mappedBy = "expenseList", cascade = CascadeType.ALL, orphanRemoval = true) @JsonManagedReference + @jakarta.persistence.OrderBy("date ASC, id ASC") private List expenses; public void addExpense(Expense expense) { diff --git a/src/main/java/de/zendric/app/xpensely_server/repo/ExpenseRepository.java b/src/main/java/de/zendric/app/xpensely_server/repo/ExpenseRepository.java index c79b08b..fe7a610 100644 --- a/src/main/java/de/zendric/app/xpensely_server/repo/ExpenseRepository.java +++ b/src/main/java/de/zendric/app/xpensely_server/repo/ExpenseRepository.java @@ -1,5 +1,7 @@ package de.zendric.app.xpensely_server.repo; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -7,4 +9,5 @@ import de.zendric.app.xpensely_server.model.Expense; @Repository public interface ExpenseRepository extends JpaRepository { + List findAllByOrderByDateAsc(); } diff --git a/src/main/java/de/zendric/app/xpensely_server/security/SecurityConfig.java b/src/main/java/de/zendric/app/xpensely_server/security/SecurityConfig.java index 1d7caae..72d7e71 100644 --- a/src/main/java/de/zendric/app/xpensely_server/security/SecurityConfig.java +++ b/src/main/java/de/zendric/app/xpensely_server/security/SecurityConfig.java @@ -10,10 +10,27 @@ import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { + // @Bean + // public SecurityFilterChain securityFilterChain(HttpSecurity http) throws + // Exception { + // http.authorizeHttpRequests(auth -> auth + // .anyRequest().permitAll()).csrf().disable(); + // ; + + // return http.build(); + // } + @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http.authorizeHttpRequests(auth -> auth - .anyRequest().authenticated()).oauth2Login(Customizer.withDefaults()); + http + .authorizeHttpRequests(auth -> auth + .anyRequest().authenticated() // Require authentication for all requests + ) + .oauth2ResourceServer(oauth2 -> oauth2 + .jwt(Customizer.withDefaults()) // Enable JWT validation + ) + .oauth2Login(Customizer.withDefaults()) // Optional if you want OAuth2 login + .csrf().disable(); // Disable CSRF for simplicity in APIs (consider enabling it for forms) return http.build(); } diff --git a/src/main/java/de/zendric/app/xpensely_server/services/ExpenseListService.java b/src/main/java/de/zendric/app/xpensely_server/services/ExpenseListService.java index c37733f..445ab1f 100644 --- a/src/main/java/de/zendric/app/xpensely_server/services/ExpenseListService.java +++ b/src/main/java/de/zendric/app/xpensely_server/services/ExpenseListService.java @@ -160,4 +160,25 @@ public class ExpenseListService { public ExpenseList findByInviteCode(String inviteCode) { return repository.findByInviteCode(inviteCode); } + + public Expense updateExpense(Long expenseListId, Expense updatedExpense) { + ExpenseList expenseList = repository.findById(expenseListId) + .orElseThrow(() -> new IllegalArgumentException("ExpenseList not found")); + + if (!expenseList.getExpenses().stream() + .anyMatch(expense -> expense.getId().equals(updatedExpense.getId()))) { + throw new IllegalArgumentException("Expense does not belong to the specified ExpenseList"); + } + + Expense existingExpense = expenseRepository.findById(updatedExpense.getId()) + .orElseThrow(() -> new IllegalArgumentException("Expense not found")); + existingExpense.setTitle(updatedExpense.getTitle()); + existingExpense.setAmount(updatedExpense.getAmount()); + existingExpense.setPersonalUseAmount(updatedExpense.getPersonalUseAmount()); + existingExpense.setOtherPersonAmount(updatedExpense.getOtherPersonAmount()); + existingExpense.setDate(updatedExpense.getDate()); + existingExpense.setOwner(updatedExpense.getOwner()); + + return expenseRepository.save(existingExpense); + } } \ No newline at end of file