diff --git a/pom.xml b/pom.xml index 4a4217c..5a0cfdd 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,10 @@ org.springframework.boot spring-boot-starter-security + + org.springframework.boot + spring-boot-starter-oauth2-client + org.projectlombok diff --git a/src/main/java/com/faf223/expensetrackerfaf/config/SecurityConfiguration.java b/src/main/java/com/faf223/expensetrackerfaf/config/SecurityConfiguration.java index 430f3ff..7343ab9 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/config/SecurityConfiguration.java +++ b/src/main/java/com/faf223/expensetrackerfaf/config/SecurityConfiguration.java @@ -1,13 +1,25 @@ package com.faf223.expensetrackerfaf.config; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; +import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; +import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -23,7 +35,7 @@ public class SecurityConfiguration { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http - .csrf(csrf -> csrf.disable()) + .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(auth -> auth .requestMatchers("/api/v1/auth/**").permitAll() .anyRequest().authenticated() @@ -31,7 +43,7 @@ public class SecurityConfiguration { .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authenticationProvider(authenticationProvider) .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); // will be executed before UsernamePasswordAuthenticationFilter - return http.build(); } + } diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java index e7f000f..532d01c 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java @@ -4,10 +4,18 @@ import com.faf223.expensetrackerfaf.dto.ExpenseCreationDTO; import com.faf223.expensetrackerfaf.dto.ExpenseDTO; import com.faf223.expensetrackerfaf.dto.mappers.ExpenseMapper; import com.faf223.expensetrackerfaf.model.Expense; +import com.faf223.expensetrackerfaf.model.ExpenseCategory; +import com.faf223.expensetrackerfaf.model.User; +import com.faf223.expensetrackerfaf.service.ExpenseCategoryService; import com.faf223.expensetrackerfaf.service.ExpenseService; +import com.faf223.expensetrackerfaf.service.UserService; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; @@ -20,12 +28,14 @@ import java.util.stream.Collectors; public class ExpenseController { private final ExpenseService expenseService; + private final UserService userService; private final ExpenseMapper expenseMapper; + private final ExpenseCategoryService expenseCategoryService; @GetMapping() @PreAuthorize("hasRole('ADMIN')") public ResponseEntity> getAllExpenses() { - List expenses = expenseService.getExpenses().stream().map(expenseMapper::toDto).collect(Collectors.toList()); + List expenses = expenseService.getTransactions().stream().map(expenseMapper::toDto).collect(Collectors.toList()); if (!expenses.isEmpty()) return ResponseEntity.ok(expenses); else return ResponseEntity.notFound().build(); } @@ -34,31 +44,58 @@ public class ExpenseController { public ResponseEntity createNewExpense(@RequestBody ExpenseCreationDTO expenseDTO, BindingResult bindingResult) { Expense expense = expenseMapper.toExpense(expenseDTO); - if (!bindingResult.hasErrors()) { - expenseService.createOrUpdateExpense(expense); - return ResponseEntity.ok(expenseMapper.toDto(expense)); - } else { - return ResponseEntity.notFound().build(); + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { + + String email = userDetails.getUsername(); + User user = userService.getUserByEmail(email); + expense.setUser(user); + + expenseService.createOrUpdate(expense); + ExpenseDTO createdExpenseDTO = expenseMapper.toDto(expense); + return ResponseEntity.status(HttpStatus.CREATED).body(createdExpenseDTO); } + + return ResponseEntity.notFound().build(); } + // TODO: has to be checked on auto extracting Uuid @PatchMapping() public ResponseEntity updateExpense(@RequestBody ExpenseCreationDTO expenseDTO, BindingResult bindingResult) { Expense expense = expenseMapper.toExpense(expenseDTO); if (!bindingResult.hasErrors()) { - expenseService.createOrUpdateExpense(expense); + expenseService.createOrUpdate(expense); return ResponseEntity.ok(expenseMapper.toDto(expense)); } else { return ResponseEntity.notFound().build(); } } - @GetMapping("/{userUuid}") - public ResponseEntity> getExpensesByUser(@PathVariable String userUuid) { - List expenses = expenseService.getExpensesByUserId(userUuid).stream().map(expenseMapper::toDto).collect(Collectors.toList()); - if (!expenses.isEmpty()) return ResponseEntity.ok(expenses); + @GetMapping("/personal-expenses") + public ResponseEntity> getExpensesByUser() { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { + + String email = userDetails.getUsername(); + List expenses = expenseService.getTransactionsByEmail(email).stream().map(expenseMapper::toDto).collect(Collectors.toList()); + + if (!expenses.isEmpty()) { + return ResponseEntity.ok(expenses); + } + } + + return ResponseEntity.notFound().build(); + } + + @GetMapping("/categories") + public ResponseEntity> getAllCategories() { + List categories = expenseCategoryService.getAllCategories(); + if (!categories.isEmpty()) return ResponseEntity.ok(categories); else return ResponseEntity.notFound().build(); } -} - +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java index eb42b55..aecab85 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java @@ -4,29 +4,38 @@ import com.faf223.expensetrackerfaf.dto.IncomeCreationDTO; import com.faf223.expensetrackerfaf.dto.IncomeDTO; import com.faf223.expensetrackerfaf.dto.mappers.IncomeMapper; import com.faf223.expensetrackerfaf.model.Income; +import com.faf223.expensetrackerfaf.model.IncomeCategory; +import com.faf223.expensetrackerfaf.model.User; +import com.faf223.expensetrackerfaf.service.IncomeCategoryService; import com.faf223.expensetrackerfaf.service.IncomeService; +import com.faf223.expensetrackerfaf.service.UserService; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.stream.Collectors; -@CrossOrigin @RestController @RequestMapping("/incomes") @RequiredArgsConstructor public class IncomeController { private final IncomeService incomeService; + private final UserService userService; private final IncomeMapper incomeMapper; + private final IncomeCategoryService incomeCategoryService; @GetMapping() @PreAuthorize("hasRole('ADMIN')") public ResponseEntity> getAllIncomes() { - List incomes = incomeService.getIncomes().stream().map(incomeMapper::toDto).collect(Collectors.toList()); + List incomes = incomeService.getTransactions().stream().map(incomeMapper::toDto).collect(Collectors.toList()); if (!incomes.isEmpty()) return ResponseEntity.ok(incomes); else return ResponseEntity.notFound().build(); } @@ -35,12 +44,21 @@ public class IncomeController { public ResponseEntity createNewIncome(@RequestBody IncomeCreationDTO incomeDTO, BindingResult bindingResult) { Income income = incomeMapper.toIncome(incomeDTO); - if (!bindingResult.hasErrors()) { - incomeService.createOrUpdateIncome(income); - return ResponseEntity.ok(incomeMapper.toDto(income)); - } else { - return ResponseEntity.notFound().build(); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { + + String email = userDetails.getUsername(); + User user = userService.getUserByEmail(email); + income.setUser(user); + + System.out.println(income); + incomeService.createOrUpdate(income); + IncomeDTO createdIncomeDTO = incomeMapper.toDto(income); + return ResponseEntity.status(HttpStatus.CREATED).body(createdIncomeDTO); } + + return ResponseEntity.notFound().build(); } @PatchMapping() @@ -48,19 +66,35 @@ public class IncomeController { BindingResult bindingResult) { Income income = incomeMapper.toIncome(incomeDTO); if (!bindingResult.hasErrors()) { - incomeService.createOrUpdateIncome(income); + incomeService.createOrUpdate(income); return ResponseEntity.ok(incomeMapper.toDto(income)); } else { return ResponseEntity.notFound().build(); } } - @CrossOrigin - @GetMapping("/{userUuid}") - public ResponseEntity> getIncomesByUser(@PathVariable String userUuid) { - List incomes = incomeService.getIncomesByUserId(userUuid).stream().map(incomeMapper::toDto).collect(Collectors.toList()); - if (!incomes.isEmpty()) return ResponseEntity.ok(incomes); + @GetMapping("/personal-incomes") + public ResponseEntity> getIncomesByUser() { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { + + String email = userDetails.getUsername(); + List incomes = incomeService.getTransactionsByEmail(email).stream().map(incomeMapper::toDto).collect(Collectors.toList()); + + if (!incomes.isEmpty()) { + return ResponseEntity.ok(incomes); + } + } + + return ResponseEntity.notFound().build(); + } + + @GetMapping("/categories") + public ResponseEntity> getAllCategories() { + List categories = incomeCategoryService.getAllCategories(); + if (!categories.isEmpty()) return ResponseEntity.ok(categories); else return ResponseEntity.notFound().build(); } -} - +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/dto/ExpenseCreationDTO.java b/src/main/java/com/faf223/expensetrackerfaf/dto/ExpenseCreationDTO.java index eb3eea5..5434b68 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/dto/ExpenseCreationDTO.java +++ b/src/main/java/com/faf223/expensetrackerfaf/dto/ExpenseCreationDTO.java @@ -11,9 +11,6 @@ import java.time.LocalDate; @Data @AllArgsConstructor public class ExpenseCreationDTO { - private long expenseId; - private User user; - private ExpenseCategory expenseCategory; - private LocalDate date; + private int expenseCategory; private BigDecimal amount; -} +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/dto/ExpenseDTO.java b/src/main/java/com/faf223/expensetrackerfaf/dto/ExpenseDTO.java index b18643a..e956e14 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/dto/ExpenseDTO.java +++ b/src/main/java/com/faf223/expensetrackerfaf/dto/ExpenseDTO.java @@ -1,6 +1,7 @@ package com.faf223.expensetrackerfaf.dto; import com.faf223.expensetrackerfaf.model.ExpenseCategory; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Data; @@ -9,10 +10,11 @@ import java.time.LocalDate; @Data @AllArgsConstructor +@JsonIgnoreProperties({"expenseCategory"}) public class ExpenseDTO { private long expenseId; private UserDTO userDTO; private ExpenseCategory expenseCategory; private LocalDate date; private BigDecimal amount; -} +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/dto/IncomeCreationDTO.java b/src/main/java/com/faf223/expensetrackerfaf/dto/IncomeCreationDTO.java index 2671bb1..620071e 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/dto/IncomeCreationDTO.java +++ b/src/main/java/com/faf223/expensetrackerfaf/dto/IncomeCreationDTO.java @@ -11,9 +11,6 @@ import java.time.LocalDate; @Data @AllArgsConstructor public class IncomeCreationDTO { - private long incomeId; - private User user; - private IncomeCategory category; - private LocalDate date; + private int incomeCategory; private BigDecimal amount; -} +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/dto/IncomeDTO.java b/src/main/java/com/faf223/expensetrackerfaf/dto/IncomeDTO.java index 3ee4998..b494bfb 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/dto/IncomeDTO.java +++ b/src/main/java/com/faf223/expensetrackerfaf/dto/IncomeDTO.java @@ -1,6 +1,7 @@ package com.faf223.expensetrackerfaf.dto; import com.faf223.expensetrackerfaf.model.IncomeCategory; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Data; @@ -9,10 +10,11 @@ import java.time.LocalDate; @Data @AllArgsConstructor +@JsonIgnoreProperties({"incomeCategory"}) public class IncomeDTO { private long incomeId; private UserDTO userDTO; - private IncomeCategory category; + private IncomeCategory incomeCategory; private LocalDate date; private BigDecimal amount; -} +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/ExpenseMapper.java b/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/ExpenseMapper.java index 74eeff7..9bc257f 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/ExpenseMapper.java +++ b/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/ExpenseMapper.java @@ -3,32 +3,35 @@ package com.faf223.expensetrackerfaf.dto.mappers; import com.faf223.expensetrackerfaf.dto.ExpenseCreationDTO; import com.faf223.expensetrackerfaf.dto.ExpenseDTO; import com.faf223.expensetrackerfaf.model.Expense; +import com.faf223.expensetrackerfaf.service.ExpenseCategoryService; import com.faf223.expensetrackerfaf.service.ExpenseService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.time.LocalDate; + @Component public class ExpenseMapper { private final ExpenseService expenseService; + private final ExpenseCategoryService expenseCategoryService; private final UserMapper userMapper; @Autowired - public ExpenseMapper(ExpenseService expenseService, UserMapper userMapper) { + public ExpenseMapper(ExpenseService expenseService, ExpenseCategoryService expenseCategoryService, UserMapper userMapper) { this.expenseService = expenseService; + this.expenseCategoryService = expenseCategoryService; this.userMapper = userMapper; } public ExpenseDTO toDto(Expense expense) { - return new ExpenseDTO(expense.getExpenseId(), userMapper.toDto(expense.getUser()), + return new ExpenseDTO(expense.getId(), userMapper.toDto(expense.getUser()), expense.getCategory(), expense.getDate(), expense.getAmount()); } public Expense toExpense(ExpenseCreationDTO expenseDTO) { - Expense expense = expenseService.getExpenseById(expenseDTO.getExpenseId()); - if(expense == null) return new Expense(expenseDTO.getExpenseId(), expenseDTO.getUser(), - expenseDTO.getExpenseCategory(), expenseDTO.getDate(), expenseDTO.getAmount()); - return expense; + + return new Expense(expenseCategoryService.getCategoryById(expenseDTO.getExpenseCategory()), LocalDate.now(), expenseDTO.getAmount()); } -} +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/IncomeMapper.java b/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/IncomeMapper.java index 32ca33e..a59a2dd 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/IncomeMapper.java +++ b/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/IncomeMapper.java @@ -4,32 +4,34 @@ import com.faf223.expensetrackerfaf.dto.IncomeCreationDTO; import com.faf223.expensetrackerfaf.dto.IncomeDTO; import com.faf223.expensetrackerfaf.model.Expense; import com.faf223.expensetrackerfaf.model.Income; +import com.faf223.expensetrackerfaf.service.IncomeCategoryService; import com.faf223.expensetrackerfaf.service.IncomeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.time.LocalDate; + @Component public class IncomeMapper { private final IncomeService incomeService; + private final IncomeCategoryService incomeCategoryService; private final UserMapper userMapper; @Autowired - public IncomeMapper(IncomeService incomeService, UserMapper userMapper) { + public IncomeMapper(IncomeService incomeService, IncomeCategoryService incomeCategoryService, UserMapper userMapper) { this.incomeService = incomeService; + this.incomeCategoryService = incomeCategoryService; this.userMapper = userMapper; } public IncomeDTO toDto(Income income) { - return new IncomeDTO(income.getIncomeId(), userMapper.toDto(income.getUser()), + return new IncomeDTO(income.getId(), userMapper.toDto(income.getUser()), income.getCategory(), income.getDate(), income.getAmount()); } public Income toIncome(IncomeCreationDTO incomeDTO) { - Income income = incomeService.getIncomeById(incomeDTO.getIncomeId()); - if(income == null) return new Income(incomeDTO.getIncomeId(), incomeDTO.getUser(), - incomeDTO.getCategory(), incomeDTO.getDate(), incomeDTO.getAmount()); - return income; + return new Income(incomeCategoryService.getCategoryById(incomeDTO.getIncomeCategory()), LocalDate.now(), incomeDTO.getAmount()); } -} +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/Credential.java b/src/main/java/com/faf223/expensetrackerfaf/model/Credential.java index f993e9f..ae93f5f 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/model/Credential.java +++ b/src/main/java/com/faf223/expensetrackerfaf/model/Credential.java @@ -1,35 +1,35 @@ - package com.faf223.expensetrackerfaf.model; +package com.faf223.expensetrackerfaf.model; - import jakarta.persistence.*; - import lombok.AllArgsConstructor; - import lombok.Data; - import lombok.NoArgsConstructor; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; - @Data - @Entity(name = "credentials") - @NoArgsConstructor - @AllArgsConstructor - public class Credential { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long credentialId; +@Data +@Entity(name = "credentials") +@NoArgsConstructor +@AllArgsConstructor +public class Credential { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long credentialId; - @ManyToOne - @JoinColumn(name = "user_uuid") - private User user; + @ManyToOne + @JoinColumn(name = "user_uuid") + private User user; - private String email; - private String password; + private String email; + private String password; - @Enumerated(EnumType.STRING) - private Role role; + @Enumerated(EnumType.STRING) + private Role role; - public Credential(User user, String email, String password) { - this.user = user; - this.email = email; - this.password = password; + public Credential(User user, String email, String password) { + this.user = user; + this.email = email; + this.password = password; - this.role = Role.ROLE_USER; - } + this.role = Role.ROLE_USER; } +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/Expense.java b/src/main/java/com/faf223/expensetrackerfaf/model/Expense.java index 6bdccb1..322bb52 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/model/Expense.java +++ b/src/main/java/com/faf223/expensetrackerfaf/model/Expense.java @@ -1,10 +1,7 @@ package com.faf223.expensetrackerfaf.model; import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.ToString; -import lombok.NoArgsConstructor; +import lombok.*; import java.math.BigDecimal; import java.time.LocalDate; @@ -13,10 +10,11 @@ import java.time.LocalDate; @AllArgsConstructor @NoArgsConstructor @Entity(name = "expenses") -public class Expense { +public class Expense implements IMoneyTransaction { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long expenseId; + @Column(name = "expense_id") + private Long id; @ManyToOne() @JoinColumn(name = "user_uuid") @@ -30,5 +28,13 @@ public class Expense { private LocalDate date; private BigDecimal amount; -} + public Expense(LocalDate date, BigDecimal amount) { + } + + public Expense(ExpenseCategory expenseCategory, LocalDate date, BigDecimal amount) { + this.category = expenseCategory; + this.date = date; + this.amount = amount; + } +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/ExpenseCategory.java b/src/main/java/com/faf223/expensetrackerfaf/model/ExpenseCategory.java index 7662ce6..c5989ea 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/model/ExpenseCategory.java +++ b/src/main/java/com/faf223/expensetrackerfaf/model/ExpenseCategory.java @@ -1,17 +1,16 @@ package com.faf223.expensetrackerfaf.model; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.Data; @Data @Entity(name = "expense_categories") -public class ExpenseCategory { +public class ExpenseCategory implements IMoneyTransactionCategory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long categoryId; + @Column(name = "category_id") + private Long id; - private String categoryName; + @Column(name = "category_name") + private String name; } diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/IMoneyTransaction.java b/src/main/java/com/faf223/expensetrackerfaf/model/IMoneyTransaction.java new file mode 100644 index 0000000..f565db3 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/model/IMoneyTransaction.java @@ -0,0 +1,14 @@ +package com.faf223.expensetrackerfaf.model; + +import java.math.BigDecimal; +import java.time.LocalDate; + +public interface IMoneyTransaction { + + Long getId(); + LocalDate getDate(); + User getUser(); + BigDecimal getAmount(); + IMoneyTransactionCategory getCategory(); + +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/IMoneyTransactionCategory.java b/src/main/java/com/faf223/expensetrackerfaf/model/IMoneyTransactionCategory.java new file mode 100644 index 0000000..f326a9b --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/model/IMoneyTransactionCategory.java @@ -0,0 +1,6 @@ +package com.faf223.expensetrackerfaf.model; + +public interface IMoneyTransactionCategory { + Long getId(); + String getName(); +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/Income.java b/src/main/java/com/faf223/expensetrackerfaf/model/Income.java index a4c88f1..cba3dac 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/model/Income.java +++ b/src/main/java/com/faf223/expensetrackerfaf/model/Income.java @@ -2,10 +2,8 @@ package com.faf223.expensetrackerfaf.model; import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.ToString; -import lombok.NoArgsConstructor; +import lombok.*; + import java.math.BigDecimal; import java.time.LocalDate; @@ -13,10 +11,11 @@ import java.time.LocalDate; @AllArgsConstructor @NoArgsConstructor @Entity(name = "incomes") -public class Income { +public class Income implements IMoneyTransaction { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long incomeId; + @Column(name = "income_id") + private Long id; @ManyToOne @JoinColumn(name = "user_uuid") @@ -30,4 +29,10 @@ public class Income { private LocalDate date; private BigDecimal amount; + + public Income(IncomeCategory incomeCategory, LocalDate date, BigDecimal amount) { + this.category = incomeCategory; + this.date = date; + this.amount = amount; + } } diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/IncomeCategory.java b/src/main/java/com/faf223/expensetrackerfaf/model/IncomeCategory.java index 8bb54f0..237c41f 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/model/IncomeCategory.java +++ b/src/main/java/com/faf223/expensetrackerfaf/model/IncomeCategory.java @@ -1,18 +1,17 @@ package com.faf223.expensetrackerfaf.model; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.Data; @Data @Entity(name = "income_categories") -public class IncomeCategory { +public class IncomeCategory implements IMoneyTransactionCategory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long categoryId; + @Column(name = "category_id") + private Long id; - private String categoryName; + @Column(name = "category_name") + private String name; } diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/Role.java b/src/main/java/com/faf223/expensetrackerfaf/model/Role.java index ea04328..6169bd2 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/model/Role.java +++ b/src/main/java/com/faf223/expensetrackerfaf/model/Role.java @@ -1,4 +1,3 @@ - package com.faf223.expensetrackerfaf.model; public enum Role { diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/User.java b/src/main/java/com/faf223/expensetrackerfaf/model/User.java index 339416f..9588570 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/model/User.java +++ b/src/main/java/com/faf223/expensetrackerfaf/model/User.java @@ -1,4 +1,3 @@ - package com.faf223.expensetrackerfaf.model; import jakarta.persistence.*; diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseCategoryService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseCategoryService.java new file mode 100644 index 0000000..2d90b6a --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseCategoryService.java @@ -0,0 +1,26 @@ +package com.faf223.expensetrackerfaf.service; + +import com.faf223.expensetrackerfaf.model.ExpenseCategory; +import com.faf223.expensetrackerfaf.repository.ExpenseCategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class ExpenseCategoryService implements ICategoryService { + + private final ExpenseCategoryRepository expenseCategoryRepository; + + @Override + public List getAllCategories() { + return expenseCategoryRepository.findAll(); + } + + @Override + public ExpenseCategory getCategoryById(long id) { + return expenseCategoryRepository.getReferenceById(id); + } + +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java index 0683998..4209fd6 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java @@ -1,11 +1,11 @@ package com.faf223.expensetrackerfaf.service; +import com.faf223.expensetrackerfaf.model.Credential; import com.faf223.expensetrackerfaf.model.Expense; -import com.faf223.expensetrackerfaf.model.User; +import com.faf223.expensetrackerfaf.model.IMoneyTransaction; +import com.faf223.expensetrackerfaf.repository.CredentialRepository; import com.faf223.expensetrackerfaf.repository.ExpenseRepository; -import com.faf223.expensetrackerfaf.repository.UserRepository; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -14,30 +14,30 @@ import java.util.Optional; @Service @RequiredArgsConstructor -public class ExpenseService { +public class ExpenseService implements ITransactionService { private final ExpenseRepository expenseRepository; - private final UserRepository userRepository; + private final CredentialRepository credentialRepository; - public void createOrUpdateExpense(Expense expense) { - expenseRepository.save(expense); + public void createOrUpdate(IMoneyTransaction expense) { + expenseRepository.save((Expense) expense); } - public List getExpensesByUserId(String userUuid) { + public List getTransactionsByEmail(String email) { - Optional user = userRepository.getUserByUserUuid(userUuid); - if (user.isPresent()) { - return expenseRepository.findByUser(user.get()); + Optional credential = credentialRepository.findByEmail(email); + if (credential.isPresent()) { + return expenseRepository.findByUser(credential.get().getUser()); } return new ArrayList<>(); } - public List getExpenses() { + public List getTransactions() { return expenseRepository.findAll(); } - public Expense getExpenseById(long id) { + public Expense getTransactionById(long id) { return expenseRepository.findById(id).orElse(null); } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ICategoryService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ICategoryService.java new file mode 100644 index 0000000..d48d8f7 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ICategoryService.java @@ -0,0 +1,12 @@ +package com.faf223.expensetrackerfaf.service; + +import com.faf223.expensetrackerfaf.model.IMoneyTransactionCategory; + +import java.util.List; + +public interface ICategoryService { + + List getAllCategories(); + IMoneyTransactionCategory getCategoryById(long id); + +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java new file mode 100644 index 0000000..6219bef --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java @@ -0,0 +1,14 @@ +package com.faf223.expensetrackerfaf.service; + +import com.faf223.expensetrackerfaf.model.IMoneyTransaction; + +import java.util.List; + +public interface ITransactionService { + + void createOrUpdate(IMoneyTransaction transaction); + List getTransactions(); + List getTransactionsByEmail(String email); + IMoneyTransaction getTransactionById(long id); + +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeCategoryService.java b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeCategoryService.java new file mode 100644 index 0000000..b7ce745 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeCategoryService.java @@ -0,0 +1,25 @@ +package com.faf223.expensetrackerfaf.service; + +import com.faf223.expensetrackerfaf.model.IncomeCategory; +import com.faf223.expensetrackerfaf.repository.IncomeCategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class IncomeCategoryService implements ICategoryService { + + private final IncomeCategoryRepository incomeCategoryRepository; + + @Override + public List getAllCategories() { + return incomeCategoryRepository.findAll(); + } + + @Override + public IncomeCategory getCategoryById(long id) { + return incomeCategoryRepository.getReferenceById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java index 63e1bab..8287d01 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java @@ -1,11 +1,11 @@ package com.faf223.expensetrackerfaf.service; +import com.faf223.expensetrackerfaf.model.Credential; +import com.faf223.expensetrackerfaf.model.IMoneyTransaction; import com.faf223.expensetrackerfaf.model.Income; -import com.faf223.expensetrackerfaf.model.User; +import com.faf223.expensetrackerfaf.repository.CredentialRepository; import com.faf223.expensetrackerfaf.repository.IncomeRepository; -import com.faf223.expensetrackerfaf.repository.UserRepository; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -14,30 +14,30 @@ import java.util.Optional; @Service @RequiredArgsConstructor -public class IncomeService { +public class IncomeService implements ITransactionService { private final IncomeRepository incomeRepository; - private final UserRepository userRepository; + private final CredentialRepository credentialRepository; - public void createOrUpdateIncome(Income income) { - incomeRepository.save(income); + public void createOrUpdate(IMoneyTransaction income) { + incomeRepository.save((Income) income); } - public List getIncomes() { + public List getTransactions() { return incomeRepository.findAll(); } - public List getIncomesByUserId(String userUuid) { + public List getTransactionsByEmail(String email) { - Optional user = userRepository.getUserByUserUuid(userUuid); - if (user.isPresent()) { - return incomeRepository.findByUser(user.get()); + Optional credential = credentialRepository.findByEmail(email); + if (credential.isPresent()) { + return incomeRepository.findByUser(credential.get().getUser()); } return new ArrayList<>(); } - public Income getIncomeById(long id) { + public Income getTransactionById(long id) { return incomeRepository.findById(id).orElse(null); } } diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/UserService.java b/src/main/java/com/faf223/expensetrackerfaf/service/UserService.java index 75d3243..20dbc96 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/UserService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/UserService.java @@ -1,17 +1,21 @@ package com.faf223.expensetrackerfaf.service; +import com.faf223.expensetrackerfaf.model.Credential; import com.faf223.expensetrackerfaf.model.User; +import com.faf223.expensetrackerfaf.repository.CredentialRepository; import com.faf223.expensetrackerfaf.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; @Service @RequiredArgsConstructor public class UserService { private final UserRepository userRepository; + private final CredentialRepository credentialRepository; public void updateUser(User user) { userRepository.save(user); @@ -24,4 +28,12 @@ public class UserService { public User getUserById(String userUuid) { return userRepository.findById(userUuid).orElse(null); } + public User getUserByEmail(String email) { + Optional credential = credentialRepository.findByEmail(email); + if (credential.isPresent()) { + Optional user = userRepository.findById(credential.get().getUser().getUserUuid()); + return user.orElse(null); + } + return null; + } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/util/IMoneyTransaction.java b/src/main/java/com/faf223/expensetrackerfaf/util/IMoneyTransaction.java deleted file mode 100644 index 8817420..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/util/IMoneyTransaction.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.faf223.expensetrackerfaf.util; - -import com.faf223.expensetrackerfaf.model.User; - -public interface IMoneyTransaction { - - User getUser(); - int getAmount(); - String getCategory(); - -}