From 1a5cd4a22c7fcb5349f5b2dfeccb0f941797a595 Mon Sep 17 00:00:00 2001 From: Mario Diaz Date: Wed, 31 Jan 2024 12:25:54 +0100 Subject: [PATCH] Adding new features to Loans --- .../config/LoanRequestToLoanConverter.java | 2 - .../operador/controller/LoansController.java | 16 ++++-- .../EntityInvalidOperationException.java | 7 +++ .../bookabook/operador/model/api/LoanDto.java | 7 +-- .../operador/model/api/LoanRequest.java | 5 +- .../operador/model/api/LoanResponse.java | 7 +-- .../bookabook/operador/model/sql/Loan.java | 7 +-- .../repository/LoanJpaRepository.java | 2 + .../operador/repository/LoanRepository.java | 4 +- .../operador/service/ILoanService.java | 3 +- .../operador/service/LoanService.java | 49 +++++++++++++------ 11 files changed, 75 insertions(+), 34 deletions(-) create mode 100644 src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/EntityInvalidOperationException.java diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanRequestToLoanConverter.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanRequestToLoanConverter.java index 3a4a860..8964171 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanRequestToLoanConverter.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanRequestToLoanConverter.java @@ -12,8 +12,6 @@ public Loan convert(LoanRequest source) { return Loan.builder() .bookId(source.getBookId()) .clientId(source.getClientId()) - .loanDate(source.getLoanDate()) - .dueDate(source.getDueDate()) .returnDate(source.getReturnDate()) .isReturned(source.getIsReturned()) .renewalCount(source.getRenewalCount()) diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/controller/LoansController.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/controller/LoansController.java index a596104..8b9b29b 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/controller/LoansController.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/controller/LoansController.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.BadParametersException; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.EntityInvalidOperationException; import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.EntityNotFoundException; import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanRequest; import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanResponse; @@ -14,7 +15,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.time.LocalDate; import java.util.*; +import java.util.logging.Logger; @RestController @RequiredArgsConstructor @@ -30,11 +33,11 @@ public ResponseEntity> getLoans( @Parameter(name="clientId", example = "") @RequestParam(required = false) Long clientId, @Parameter(name="loanDate", example = "") - @RequestParam(required = false)Date loanDate, + @RequestParam(required = false) LocalDate loanDate, @Parameter(name="returnDate", example = "") - @RequestParam(required = false)Date returnDate, + @RequestParam(required = false)LocalDate returnDate, @Parameter(name="dueDate", example = "") - @RequestParam(required = false)Date dueDate, + @RequestParam(required = false)LocalDate dueDate, @Parameter(name="isReturned", example = "") @RequestParam(required = false)Boolean isReturned, @Parameter(name="renewalCount", example = "") @@ -98,10 +101,15 @@ public ResponseEntity addLoan(@RequestBody LoanRequest loanRequest } catch (BadParametersException e) { + Logger.getGlobal().warning("Bad Parameters"); + return ResponseEntity.badRequest().build(); + } + catch(EntityInvalidOperationException e) { return ResponseEntity.badRequest().build(); } catch (Exception e) { + Logger.getGlobal().warning("Error: " + e.getMessage()); return ResponseEntity.internalServerError().build(); } } @@ -147,7 +155,7 @@ public ResponseEntity patchLoan(@RequestBody LoanRequest loanReque } } - @GetMapping("/loans/client/{clientId}") + @GetMapping("/clients/{clientId}/loans") public ResponseEntity> getLoanByClientId(@PathVariable String clientId) { try { diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/EntityInvalidOperationException.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/EntityInvalidOperationException.java new file mode 100644 index 0000000..e36cab1 --- /dev/null +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/EntityInvalidOperationException.java @@ -0,0 +1,7 @@ +package net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions; + +import jakarta.ws.rs.NotAllowedException; + +public class EntityInvalidOperationException extends RuntimeException { + public EntityInvalidOperationException(String errorMessage, Throwable err) { super(errorMessage, err); } +} diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanDto.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanDto.java index 24cf40c..20d9b2c 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanDto.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanDto.java @@ -2,6 +2,7 @@ import lombok.*; +import java.time.LocalDate; import java.util.Date; @Getter @@ -13,9 +14,9 @@ public class LoanDto { private Long bookId; private Long clientId; - private Date loanDate; - private Date returnDate; - private Date dueDate; + private LocalDate loanDate; + private LocalDate returnDate; + private LocalDate dueDate; private Boolean isReturned; private Integer renewalCount; } diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanRequest.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanRequest.java index 3174e37..e583300 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanRequest.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanRequest.java @@ -1,6 +1,7 @@ package net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api; import lombok.*; +import java.time.LocalDate; import java.util.Date; @Getter @@ -12,9 +13,7 @@ public class LoanRequest { private Long bookId; private Long clientId; - private Date loanDate; - private Date returnDate; - private Date dueDate; + private LocalDate returnDate = null; private Boolean isReturned; private Integer renewalCount; } diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanResponse.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanResponse.java index d40fc88..1121931 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanResponse.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/api/LoanResponse.java @@ -2,6 +2,7 @@ import lombok.*; +import java.time.LocalDate; import java.util.Date; @Getter @@ -14,9 +15,9 @@ public class LoanResponse { private Long id; private Long bookId; private Long clientId; - private Date loanDate; - private Date returnDate; - private Date dueDate; + private LocalDate loanDate; + private LocalDate returnDate; + private LocalDate dueDate; private Boolean isReturned; private Integer renewalCount; } diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/sql/Loan.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/sql/Loan.java index 9f15221..9962fbe 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/sql/Loan.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/sql/Loan.java @@ -1,5 +1,6 @@ package net.unir.missi.desarrollowebfullstack.bookabook.operador.model.sql; +import java.time.LocalDate; import java.util.Date; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -32,11 +33,11 @@ public class Loan { @Column(name = "clientId") private Long clientId; @Column(name = "loanDate") - private Date loanDate; + private LocalDate loanDate; @Column(name = "returnDate") - private Date returnDate; + private LocalDate returnDate; @Column(name = "dueDate") - private Date dueDate; + private LocalDate dueDate; @Column(name = "isReturned") private Boolean isReturned; @Column(name = "renewalCount") diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanJpaRepository.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanJpaRepository.java index 646cbab..7feb005 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanJpaRepository.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanJpaRepository.java @@ -10,4 +10,6 @@ @Repository public interface LoanJpaRepository extends JpaRepository, JpaSpecificationExecutor { List findByClientId(Long clientId); + List findByBookIdAndIsReturned(Long bookId, boolean isRturned); + } diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanRepository.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanRepository.java index 24a1fed..4f40afc 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanRepository.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanRepository.java @@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; +import java.time.LocalDate; import java.util.Date; import java.util.List; import java.util.Optional; @@ -26,6 +27,7 @@ public LoanRepository(LoanJpaRepository loanJpaRepository) { public List findAll() { return loanJpaRepository.findAll(); } public Loan findById(Long id) { return loanJpaRepository.findById(id).orElse(null); } public List findByClientId(Long clientId){ return loanJpaRepository.findByClientId(clientId); } + public List findByBookIdAndIsReturned(Long bookId, boolean isRturned){ return loanJpaRepository.findByBookIdAndIsReturned(bookId, isRturned); } public Loan save(Loan loan){ return loanJpaRepository.save(loan); } public Loan delete(Loan loan) { @@ -34,7 +36,7 @@ public Loan delete(Loan loan) return l.get(); } - public List search(Long bookId, Long clientId, Date loanDate, Date returnDate, Date dueDate, Boolean isReturned, Integer renewalCount) { + public List search(Long bookId, Long clientId, LocalDate loanDate, LocalDate returnDate, LocalDate dueDate, Boolean isReturned, Integer renewalCount) { SearchCriteria spec = new SearchCriteria<>(); if(bookId != null) { diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/ILoanService.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/ILoanService.java index 430fb72..93621f7 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/ILoanService.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/ILoanService.java @@ -3,12 +3,13 @@ import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanRequest; import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanResponse; +import java.time.LocalDate; import java.util.Date; import java.util.List; public interface ILoanService { // CRUD - List getAllLoans(Long bookId, Long clientId, Date loanDate, Date returnDate, Date dueDate, Boolean isReturned, Integer renewalCount); + List getAllLoans(Long bookId, Long clientId, LocalDate loanDate, LocalDate returnDate, LocalDate dueDate, Boolean isReturned, Integer renewalCount); LoanResponse createLoan(LoanRequest request); LoanResponse getLoanById(Long id); LoanResponse modifyAllLoanData(LoanRequest loan, Long id); diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/LoanService.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/LoanService.java index 2bf495b..9ac06b2 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/LoanService.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/LoanService.java @@ -7,6 +7,7 @@ import net.unir.missi.desarrollowebfullstack.bookabook.operador.config.LoanRequestToLoanConverter; import net.unir.missi.desarrollowebfullstack.bookabook.operador.config.LoanToLoanResponseConverter; import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.BadParametersException; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.EntityInvalidOperationException; import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.EntityNotFoundException; import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.BookResponse; import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.ClientResponse; @@ -19,6 +20,7 @@ import org.springframework.stereotype.Service; import java.awt.print.Book; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -51,7 +53,7 @@ public class LoanService implements ILoanService { // CRUD @Override - public List getAllLoans(Long bookId, Long clientId, Date loanDate, Date returnDate, Date dueDate, Boolean isReturned, Integer renewalCount) { + public List getAllLoans(Long bookId, Long clientId, LocalDate loanDate, LocalDate returnDate, LocalDate dueDate, Boolean isReturned, Integer renewalCount) { Loan loan = new Loan(null, bookId, clientId, loanDate, returnDate, dueDate, isReturned, renewalCount); List loanList; if (this.isValidSyntaxLoanForNulls(loan)) { @@ -75,25 +77,30 @@ public LoanResponse createLoan(LoanRequest request) { throw new BadParametersException("One or more parameters of the request are wrong", null); } - Logger.getGlobal().warning("hasta aki"); // If loan referencing non-existing books throw 404 if (! isExistingBook(loan.getBookId().toString())) { throw new EntityNotFoundException("Book id " + loan.getBookId() + " does not exist.", null); } - - Logger.getGlobal().warning("hasta aki existe book"); // If loan referencing non-existing clients throw 404 if(! isExistingClient(loan.getClientId().toString())) { throw new EntityNotFoundException("Client id " + loan.getClientId() + " does not exist.", null); } - Logger.getGlobal().warning("hasta aki existe client"); + List foundLoanedBook = loanRepository.findByBookIdAndIsReturned(request.getBookId(), false); + Logger.getGlobal().warning("Book Count: " + foundLoanedBook.stream().count()); + + if((long) foundLoanedBook.size() != 0) { + Logger.getGlobal().warning("Error: Book " + request.getBookId() + " cannot be loaned because it's already loaned to other client"); + throw new EntityInvalidOperationException("Error: Book " + request.getBookId() + " cannot be loaned because it's already loaned to other client", null); + } + + loan.setLoanDate(LocalDate.now()); + loan.setDueDate(loan.getLoanDate().plusDays(7)); // Implicit else: valid loan is saved in the DB Loan createdLoan = loanRepository.save(loan); - Logger.getGlobal().warning("hasta aki ya se ha guardao"); return this.loanToLoanResponseConverter.convert(createdLoan); } @@ -155,13 +162,11 @@ public LoanResponse modifyLoan(LoanRequest loanRequest, Long id) { Loan loan = this.loanRequestToLoanConverter.convert(loanRequest); // If loan has null values or wrong values throw 400 - if ( - ! this.isValidSyntaxLoanForNulls(Objects.requireNonNull(loan)) + if (!this.isValidSyntaxLoanForNulls(Objects.requireNonNull(loan)) || ! this.isValidSyntaxLoanForZeroes(loan)) { throw new BadParametersException("One or more parameters of the request are wrong", null); } - // If loan does not exist throw 404 Loan loanMatched = loanRepository.findById(id); if (loanMatched == null) @@ -181,6 +186,15 @@ public LoanResponse modifyLoan(LoanRequest loanRequest, Long id) { throw new EntityNotFoundException("Client id " + loan.getClientId() + " does not exist.", null); } + if(loan.getIsReturned()) { + loan.setReturnDate(LocalDate.now()); + } + else + { + loan.setDueDate(LocalDate.now().plusDays(7)); + loan.setRenewalCount(loan.getRenewalCount() + 1); + } + // Update values of matched loan with values of received request Loan mergedLoan = this.loanMergerNonEmpty.merge(loanMatched, loan); @@ -222,7 +236,6 @@ public List getLoansByClientId(Long clientId) { private boolean isExistingBook(String id) { try { ResponseEntity book = buscadorClient.getBook(id); - Logger.getGlobal().warning("MyText"); return book != null; } catch(Exception e) { @@ -230,10 +243,20 @@ private boolean isExistingBook(String id) { } } + private BookResponse getBook(String id) { + try { + ResponseEntity book = buscadorClient.getBook(id); + BookResponse response = book.getBody(); + return response; + } + catch(Exception e) { + return null; + } + } + private boolean isExistingClient(String id) { try { ResponseEntity client = buscadorClient.getClient(id); - Logger.getGlobal().warning("MyText"); return client != null; } catch(Exception e) { @@ -245,9 +268,7 @@ private boolean isValidSyntaxLoanForNulls(Loan loan) { return loan.getBookId() != null && loan.getClientId() != null - && loan.getLoanDate() != null - && loan.getReturnDate() != null - && loan.getDueDate() != null + //&& loan.getReturnDate() != null && loan.getIsReturned() != null && loan.getRenewalCount() != null; }