diff --git a/src/main/java/com/SkillsForge/expensetracker/app/filter/TransactionFilter.java b/src/main/java/com/SkillsForge/expensetracker/app/filter/TransactionFilter.java index e9eab30..8d483cd 100644 --- a/src/main/java/com/SkillsForge/expensetracker/app/filter/TransactionFilter.java +++ b/src/main/java/com/SkillsForge/expensetracker/app/filter/TransactionFilter.java @@ -8,6 +8,6 @@ @Getter @Setter public class TransactionFilter { - private TransactionCategory category; - private TransactionType type; + private TransactionCategory category; + private TransactionType type; } diff --git a/src/main/java/com/SkillsForge/expensetracker/controller/TransactionController.java b/src/main/java/com/SkillsForge/expensetracker/controller/TransactionController.java index 2391e98..09358b2 100644 --- a/src/main/java/com/SkillsForge/expensetracker/controller/TransactionController.java +++ b/src/main/java/com/SkillsForge/expensetracker/controller/TransactionController.java @@ -1,17 +1,14 @@ package com.SkillsForge.expensetracker.controller; +import com.SkillsForge.expensetracker.app.filter.TransactionFilter; import com.SkillsForge.expensetracker.dto.CreateTransactionRequest; import com.SkillsForge.expensetracker.dto.TransactionDto; -import com.SkillsForge.expensetracker.app.filter.TransactionFilter; import com.SkillsForge.expensetracker.dto.TransactionUpdateRequest; import com.SkillsForge.expensetracker.service.TransactionService; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.web.bind.annotation.*; -import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -22,31 +19,26 @@ public class TransactionController { private final TransactionService transactionService; @PostMapping - public ResponseEntity createTransaction( + @ResponseStatus(HttpStatus.CREATED) + public TransactionDto createTransaction( @RequestBody @Validated CreateTransactionRequest request) { - TransactionDto response = transactionService.createTransaction(request); - return ResponseEntity.status(HttpStatus.CREATED).body(response); + return transactionService.createTransaction(request); } @GetMapping("/{id}") - public ResponseEntity getTransactionById(@PathVariable Long id) { - TransactionDto response = transactionService.getTransactionById(id); - return ResponseEntity.ok(response); + public TransactionDto getTransactionById(@PathVariable Long id) { + return transactionService.getTransactionById(id); } @PutMapping("/{id}") public TransactionDto updateTransaction( - @PathVariable Long id, - @RequestBody TransactionUpdateRequest request - ) { + @PathVariable Long id, @RequestBody TransactionUpdateRequest request) { return transactionService.updateTransaction(id, request); } @GetMapping public Page getAllTransactions( - @ModelAttribute TransactionFilter filter, - Pageable pageable - ) { + @ModelAttribute TransactionFilter filter, Pageable pageable) { return transactionService.getAllTransactions(filter, pageable); } } diff --git a/src/main/java/com/SkillsForge/expensetracker/dto/TransactionUpdateRequest.java b/src/main/java/com/SkillsForge/expensetracker/dto/TransactionUpdateRequest.java index c7564f0..6f53044 100644 --- a/src/main/java/com/SkillsForge/expensetracker/dto/TransactionUpdateRequest.java +++ b/src/main/java/com/SkillsForge/expensetracker/dto/TransactionUpdateRequest.java @@ -2,18 +2,17 @@ import com.SkillsForge.expensetracker.app.enums.TransactionCategory; import com.SkillsForge.expensetracker.app.enums.TransactionType; +import java.time.LocalDate; import lombok.Getter; import lombok.Setter; -import java.time.LocalDate; - @Getter @Setter public class TransactionUpdateRequest { - private String description; - private TransactionCategory category; - private TransactionType type; - private Long amount; - private LocalDate date; + private String description; + private TransactionCategory category; + private TransactionType type; + private Long amount; + private LocalDate date; } diff --git a/src/main/java/com/SkillsForge/expensetracker/persistence/entity/Transaction.java b/src/main/java/com/SkillsForge/expensetracker/persistence/entity/Transaction.java index d39664f..f11327a 100644 --- a/src/main/java/com/SkillsForge/expensetracker/persistence/entity/Transaction.java +++ b/src/main/java/com/SkillsForge/expensetracker/persistence/entity/Transaction.java @@ -36,8 +36,7 @@ public class Transaction extends BaseEntity { private LocalDate date; // the date the transaction was made @Column(nullable = false) - private Long - amount; // We save amount in kobo value so 1.50 naira will be saved as 150 + private Long amount; // We save amount in kobo value so 1.50 naira will be saved as 150 // constructor to accept dto public Transaction(CreateTransactionRequest request) { diff --git a/src/main/java/com/SkillsForge/expensetracker/persistence/repository/TransactionRepository.java b/src/main/java/com/SkillsForge/expensetracker/persistence/repository/TransactionRepository.java index b97dd32..162c69d 100644 --- a/src/main/java/com/SkillsForge/expensetracker/persistence/repository/TransactionRepository.java +++ b/src/main/java/com/SkillsForge/expensetracker/persistence/repository/TransactionRepository.java @@ -5,6 +5,4 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; public interface TransactionRepository - extends JpaRepository, - JpaSpecificationExecutor { -} + extends JpaRepository, JpaSpecificationExecutor {} diff --git a/src/main/java/com/SkillsForge/expensetracker/service/TransactionService.java b/src/main/java/com/SkillsForge/expensetracker/service/TransactionService.java index 70850cf..94d2d21 100644 --- a/src/main/java/com/SkillsForge/expensetracker/service/TransactionService.java +++ b/src/main/java/com/SkillsForge/expensetracker/service/TransactionService.java @@ -1,13 +1,12 @@ package com.SkillsForge.expensetracker.service; +import com.SkillsForge.expensetracker.app.filter.TransactionFilter; +import com.SkillsForge.expensetracker.dto.CreateTransactionRequest; import com.SkillsForge.expensetracker.dto.TransactionDto; import com.SkillsForge.expensetracker.dto.TransactionUpdateRequest; -import com.SkillsForge.expensetracker.app.filter.TransactionFilter; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import com.SkillsForge.expensetracker.dto.CreateTransactionRequest; - public interface TransactionService { TransactionDto createTransaction(CreateTransactionRequest request); @@ -16,6 +15,4 @@ public interface TransactionService { TransactionDto updateTransaction(Long id, TransactionUpdateRequest request); Page getAllTransactions(TransactionFilter filter, Pageable pageable); - - } diff --git a/src/main/java/com/SkillsForge/expensetracker/service/TransactionServiceImpl.java b/src/main/java/com/SkillsForge/expensetracker/service/TransactionServiceImpl.java index ed23fd7..25cf00e 100644 --- a/src/main/java/com/SkillsForge/expensetracker/service/TransactionServiceImpl.java +++ b/src/main/java/com/SkillsForge/expensetracker/service/TransactionServiceImpl.java @@ -8,6 +8,9 @@ import com.SkillsForge.expensetracker.persistence.entity.Transaction; import com.SkillsForge.expensetracker.persistence.repository.TransactionRepository; import jakarta.persistence.criteria.Predicate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -16,89 +19,88 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - @Service @Slf4j @RequiredArgsConstructor public class TransactionServiceImpl implements TransactionService { - private final TransactionRepository transactionRepository; - - // ================= CREATE ================= - @Override - @Transactional - public TransactionDto createTransaction(CreateTransactionRequest request) { - LocalDateTime now = LocalDateTime.now(); - - Transaction transaction = new Transaction(request); - transaction.setCreatedAt(now); - transaction.setUpdatedAt(now); - - Transaction saved = transactionRepository.save(transaction); - log.info("Transaction created successfully with ID: {}", saved.getId()); - - return TransactionDto.fromEntity(saved); - } - - // ================= GET BY ID ================= - @Override - @Transactional(readOnly = true) - public TransactionDto getTransactionById(Long id) { - log.info("Fetching transaction with ID: {}", id); - - Transaction transaction = transactionRepository.findById(id) - .orElseThrow(() -> - new ResourceNotFoundException("Transaction not found with ID: " + id)); - - return TransactionDto.fromEntity(transaction); - } - - // ================= UPDATE ================= - @Override - @Transactional - public TransactionDto updateTransaction(Long id, TransactionUpdateRequest request) { - - Transaction existing = transactionRepository.findById(id) - .orElseThrow(() -> - new ResourceNotFoundException("Transaction not found with ID: " + id)); - - existing.setDescription(request.getDescription()); - existing.setCategory(request.getCategory()); - existing.setType(request.getType()); - existing.setAmount(request.getAmount()); - existing.setDate(request.getDate()); - existing.setUpdatedAt(LocalDateTime.now()); - - Transaction saved = transactionRepository.save(existing); - log.info("Transaction updated successfully with ID: {}", saved.getId()); - - return TransactionDto.fromEntity(saved); - } - - // ================= GET ALL (FILTERED) ================= - @Override - @Transactional(readOnly = true) - public Page getAllTransactions(TransactionFilter filter, Pageable pageable) { - - Specification spec = (root, query, cb) -> { - List predicates = new ArrayList<>(); - - if (filter.getCategory() != null) { - predicates.add(cb.equal(root.get("category"), filter.getCategory())); - } - - if (filter.getType() != null) { - predicates.add(cb.equal(root.get("type"), filter.getType())); - } - - return cb.and(predicates.toArray(new Predicate[0])); + private final TransactionRepository transactionRepository; + + // ================= CREATE ================= + @Override + @Transactional + public TransactionDto createTransaction(CreateTransactionRequest request) { + LocalDateTime now = LocalDateTime.now(); + + Transaction transaction = new Transaction(request); + transaction.setCreatedAt(now); + transaction.setUpdatedAt(now); + + Transaction saved = transactionRepository.save(transaction); + log.info("Transaction created successfully with ID: {}", saved.getId()); + + return TransactionDto.fromEntity(saved); + } + + // ================= GET BY ID ================= + @Override + @Transactional(readOnly = true) + public TransactionDto getTransactionById(Long id) { + log.info("Fetching transaction with ID: {}", id); + + Transaction transaction = + transactionRepository + .findById(id) + .orElseThrow( + () -> new ResourceNotFoundException("Transaction not found with ID: " + id)); + + return TransactionDto.fromEntity(transaction); + } + + // ================= UPDATE ================= + @Override + @Transactional + public TransactionDto updateTransaction(Long id, TransactionUpdateRequest request) { + + Transaction existing = + transactionRepository + .findById(id) + .orElseThrow( + () -> new ResourceNotFoundException("Transaction not found with ID: " + id)); + + existing.setDescription(request.getDescription()); + existing.setCategory(request.getCategory()); + existing.setType(request.getType()); + existing.setAmount(request.getAmount()); + existing.setDate(request.getDate()); + existing.setUpdatedAt(LocalDateTime.now()); + + Transaction saved = transactionRepository.save(existing); + log.info("Transaction updated successfully with ID: {}", saved.getId()); + + return TransactionDto.fromEntity(saved); + } + + // ================= GET ALL (FILTERED) ================= + @Override + @Transactional(readOnly = true) + public Page getAllTransactions(TransactionFilter filter, Pageable pageable) { + + Specification spec = + (root, query, cb) -> { + List predicates = new ArrayList<>(); + + if (filter.getCategory() != null) { + predicates.add(cb.equal(root.get("category"), filter.getCategory())); + } + + if (filter.getType() != null) { + predicates.add(cb.equal(root.get("type"), filter.getType())); + } + + return cb.and(predicates.toArray(new Predicate[0])); }; - return transactionRepository - .findAll(spec, pageable) - .map(TransactionDto::fromEntity); - } + return transactionRepository.findAll(spec, pageable).map(TransactionDto::fromEntity); + } }