From a07a758454d4a47be7adff3b30fd5c6847034878 Mon Sep 17 00:00:00 2001 From: Ajay Negi <97536703+ajaynegi45@users.noreply.github.com> Date: Sat, 5 Oct 2024 19:06:00 +0530 Subject: [PATCH 1/7] Update README.md From 69895066588211bda2b668612e88cd96223f00ac Mon Sep 17 00:00:00 2001 From: Ajay Negi <97536703+ajaynegi45@users.noreply.github.com> Date: Sat, 5 Oct 2024 19:07:09 +0530 Subject: [PATCH 2/7] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 7c399b6..0b96a84 100644 --- a/README.md +++ b/README.md @@ -62,10 +62,8 @@ If you have any questions or would like to connect, please don't hesitate to rea

## Contributors + - - - ### Stargazers From e6ec2bc9de3eb3b5a4091234ec241d90ef6c5475 Mon Sep 17 00:00:00 2001 From: Anish Date: Sun, 6 Oct 2024 23:36:58 +0530 Subject: [PATCH 3/7] added dto class --- .../java/com/libraryman_api/book/BookDto.java | 112 +++++++++++++++++ .../borrowing/BorrowingsDto.java | 113 ++++++++++++++++++ .../com/libraryman_api/member/MembersDto.java | 93 ++++++++++++++ 3 files changed, 318 insertions(+) create mode 100644 src/main/java/com/libraryman_api/book/BookDto.java create mode 100644 src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java create mode 100644 src/main/java/com/libraryman_api/member/MembersDto.java diff --git a/src/main/java/com/libraryman_api/book/BookDto.java b/src/main/java/com/libraryman_api/book/BookDto.java new file mode 100644 index 0000000..b6a5d0e --- /dev/null +++ b/src/main/java/com/libraryman_api/book/BookDto.java @@ -0,0 +1,112 @@ +package com.libraryman_api.book; + +public class BookDto { + + + private int bookId; + private String title; + + private String author; + + private String isbn; + + private String publisher; + + + private int publishedYear; + private String genre; + + private int copiesAvailable; + + public BookDto(int bookId, String title, String author, String isbn, String publisher, int publishedYear, String genre, int copiesAvailable) { + this.bookId = bookId; + this.title = title; + this.author = author; + this.isbn = isbn; + this.publisher = publisher; + this.publishedYear = publishedYear; + this.genre = genre; + this.copiesAvailable = copiesAvailable; + } + + public BookDto() { + } + + public int getBookId() { + return bookId; + } + + public void setBookId(int bookId) { + this.bookId = bookId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public String getPublisher() { + return publisher; + } + + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + public int getPublishedYear() { + return publishedYear; + } + + public void setPublishedYear(int publishedYear) { + this.publishedYear = publishedYear; + } + + public String getGenre() { + return genre; + } + + public void setGenre(String genre) { + this.genre = genre; + } + + public int getCopiesAvailable() { + return copiesAvailable; + } + + public void setCopiesAvailable(int copiesAvailable) { + this.copiesAvailable = copiesAvailable; + } + + @Override + public String toString() { + return "BookDto{" + + "bookId=" + bookId + + ", title='" + title + '\'' + + ", author='" + author + '\'' + + ", isbn='" + isbn + '\'' + + ", publisher='" + publisher + '\'' + + ", publishedYear=" + publishedYear + + ", genre='" + genre + '\'' + + ", copiesAvailable=" + copiesAvailable + + '}'; + } +} diff --git a/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java b/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java new file mode 100644 index 0000000..9ed52ac --- /dev/null +++ b/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java @@ -0,0 +1,113 @@ +package com.libraryman_api.borrowing; + +import com.libraryman_api.book.Book; +import com.libraryman_api.book.BookDto; +import com.libraryman_api.fine.Fines; +import com.libraryman_api.member.Members; +import com.libraryman_api.member.MembersDto; + +import java.util.Date; + +public class BorrowingsDto { + + private int borrowingId; + + + private BookDto book; + + + private Fines fine; + + + private MembersDto member; + + private Date borrowDate; + + + private Date dueDate; + + + private Date returnDate; + + public BorrowingsDto(int borrowingId, BookDto book, Fines fine, MembersDto member, Date borrowDate, Date dueDate, Date returnDate) { + this.borrowingId = borrowingId; + this.book = book; + this.fine = fine; + this.member = member; + this.borrowDate = borrowDate; + this.dueDate = dueDate; + this.returnDate = returnDate; + } + + public BorrowingsDto() { + } + + public int getBorrowingId() { + return borrowingId; + } + + public void setBorrowingId(int borrowingId) { + this.borrowingId = borrowingId; + } + + public BookDto getBook() { + return book; + } + + public void setBook(BookDto book) { + this.book = book; + } + + public Fines getFine() { + return fine; + } + + public void setFine(Fines fine) { + this.fine = fine; + } + + public MembersDto getMember() { + return member; + } + + public void setMember(MembersDto member) { + this.member = member; + } + + public Date getBorrowDate() { + return borrowDate; + } + + public void setBorrowDate(Date borrowDate) { + this.borrowDate = borrowDate; + } + + public Date getDueDate() { + return dueDate; + } + + public void setDueDate(Date dueDate) { + this.dueDate = dueDate; + } + + public Date getReturnDate() { + return returnDate; + } + + public void setReturnDate(Date returnDate) { + this.returnDate = returnDate; + } + + @Override + public String toString() { + return "BorrowingsDto{" + + "borrowingId=" + borrowingId + + ", book=" + book + + ", fine=" + fine + + ", member=" + member + + ", borrowDate=" + borrowDate + + ", dueDate=" + dueDate + + ", returnDate=" + returnDate + + '}'; + } +} diff --git a/src/main/java/com/libraryman_api/member/MembersDto.java b/src/main/java/com/libraryman_api/member/MembersDto.java new file mode 100644 index 0000000..d4f67fe --- /dev/null +++ b/src/main/java/com/libraryman_api/member/MembersDto.java @@ -0,0 +1,93 @@ +package com.libraryman_api.member; + +import java.util.Date; + +public class MembersDto { + + + private int memberId; + + private String name; + + private String email; + + private String password; + + + private Role role; + + + private Date membershipDate; + + public MembersDto(int memberId, String name, String email, String password, Role role, Date membershipDate) { + this.memberId = memberId; + this.name = name; + this.email = email; + this.password = password; + this.role = role; + this.membershipDate = membershipDate; + } + + public MembersDto() { + } + + public int getMemberId() { + return memberId; + } + + public void setMemberId(int memberId) { + this.memberId = memberId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public Date getMembershipDate() { + return membershipDate; + } + + public void setMembershipDate(Date membershipDate) { + this.membershipDate = membershipDate; + } + + @Override + public String toString() { + return "MembersDto{" + + "memberId=" + memberId + + ", name='" + name + '\'' + + ", email='" + email + '\'' + + ", password='" + password + '\'' + + ", role=" + role + + ", membershipDate=" + membershipDate + + '}'; + } +} From 3eafa4b3c6cca955d9c6a8456349ec4da7d01f83 Mon Sep 17 00:00:00 2001 From: Anish Date: Sun, 6 Oct 2024 23:57:50 +0530 Subject: [PATCH 4/7] Enhancement: Use DTOs for entity exposure in controller layer --- .../java/com/libraryman_api/book/Book.java | 1 + .../libraryman_api/book/BookController.java | 18 +-- .../com/libraryman_api/book/BookService.java | 65 ++++++++--- .../borrowing/BorrowingController.java | 16 +-- .../borrowing/BorrowingService.java | 105 +++++++++++------- .../libraryman_api/borrowing/Borrowings.java | 2 + .../borrowing/BorrowingsDto.java | 2 - .../member/MemberController.java | 16 +-- .../libraryman_api/member/MemberService.java | 58 +++++++--- .../com/libraryman_api/member/Members.java | 2 + .../application-development.properties | 6 +- src/main/resources/application.properties | 2 +- 12 files changed, 194 insertions(+), 99 deletions(-) diff --git a/src/main/java/com/libraryman_api/book/Book.java b/src/main/java/com/libraryman_api/book/Book.java index b4d3f8e..d3cdb31 100644 --- a/src/main/java/com/libraryman_api/book/Book.java +++ b/src/main/java/com/libraryman_api/book/Book.java @@ -78,6 +78,7 @@ public int getCopiesAvailable() { return copiesAvailable; } + public void setBookId(int bookId) {this.bookId = bookId;} public void setTitle(String title) { this.title = title; diff --git a/src/main/java/com/libraryman_api/book/BookController.java b/src/main/java/com/libraryman_api/book/BookController.java index fbacbec..4401e67 100644 --- a/src/main/java/com/libraryman_api/book/BookController.java +++ b/src/main/java/com/libraryman_api/book/BookController.java @@ -29,11 +29,11 @@ public class BookController { * @param pageable contains pagination information (page number, size, and sorting). * @param sortBy (optional) the field by which to sort the results. * @param sortDir (optional) the direction of sorting (asc or desc). Defaults to ascending. - * @return a {@link Page} of {@link Book} objects representing the books in the library. + * @return a {@link Page} of {@link BookDto} objects representing the books in the library. * The results are sorted by title by default and limited to 5 books per page. */ @GetMapping - public Page getAllBooks(@PageableDefault(page=0, size=5, sort="title") Pageable pageable, + public Page getAllBooks(@PageableDefault(page=0, size=5, sort="title") Pageable pageable, @RequestParam(required = false) String sortBy, @RequestParam(required = false) String sortDir) { @@ -58,7 +58,7 @@ public Page getAllBooks(@PageableDefault(page=0, size=5, sort="title") Pag * @throws ResourceNotFoundException if the book with the specified ID is not found. */ @GetMapping("/{id}") - public ResponseEntity getBookById(@PathVariable int id) { + public ResponseEntity getBookById(@PathVariable int id) { return bookService.getBookById(id) .map(ResponseEntity::ok) .orElseThrow(() -> new ResourceNotFoundException("Book not found")); @@ -67,24 +67,24 @@ public ResponseEntity getBookById(@PathVariable int id) { /** * Adds a new book to the library. * - * @param book the {@link Book} object representing the new book to add. + * @param bookDto the {@link Book} object representing the new book to add. * @return the added {@link Book} object. */ @PostMapping - public Book addBook(@RequestBody Book book) { - return bookService.addBook(book); + public BookDto addBook(@RequestBody BookDto bookDto) { + return bookService.addBook(bookDto); } /** * Updates an existing book in the library. * * @param id the ID of the book to update. - * @param bookDetails the {@link Book} object containing the updated book details. + * @param bookDtoDetails the {@link Book} object containing the updated book details. * @return the updated {@link Book} object. */ @PutMapping("/{id}") - public Book updateBook(@PathVariable int id, @RequestBody Book bookDetails) { - return bookService.updateBook(id, bookDetails); + public BookDto updateBook(@PathVariable int id, @RequestBody BookDto bookDtoDetails) { + return bookService.updateBook(id, bookDtoDetails); } /** diff --git a/src/main/java/com/libraryman_api/book/BookService.java b/src/main/java/com/libraryman_api/book/BookService.java index 32fac54..1c63cef 100644 --- a/src/main/java/com/libraryman_api/book/BookService.java +++ b/src/main/java/com/libraryman_api/book/BookService.java @@ -46,9 +46,10 @@ public BookService(BookRepository bookRepository) { * @return a {@link Page} of {@link Book} representing all books * @throws InvalidSortFieldException if an invalid sortBy field is specified */ - public Page getAllBooks(Pageable pageable) { + public Page getAllBooks(Pageable pageable) { try { - return bookRepository.findAll(pageable); + Page pagedBooks = bookRepository.findAll(pageable); + return pagedBooks.map(this::EntityToDto); } catch (PropertyReferenceException ex) { throw new InvalidSortFieldException("The specified 'sortBy' value is invalid."); } @@ -60,39 +61,44 @@ public Page getAllBooks(Pageable pageable) { * @param bookId the ID of the book to retrieve * @return an {@code Optional} containing the found book, or {@code Optional.empty()} if no book was found */ - public Optional getBookById(int bookId) { - return bookRepository.findById(bookId); + public Optional getBookById(int bookId) { + + Optional bookById = bookRepository.findById(bookId); + return bookById.map(this::EntityToDto); } /** * Adds a new book to the database. * - * @param book the book to be added + * @param bookDto the book to be added * @return the saved book */ - public Book addBook(Book book) { - return bookRepository.save(book); + public BookDto addBook(BookDto bookDto) { + Book book = DtoToEntity(bookDto); + Book savedBook = bookRepository.save(book); + return EntityToDto(savedBook); } /** * Updates an existing book with the given details. * * @param bookId the ID of the book to update - * @param bookDetails the new details for the book + * @param bookDtoDetails the new details for the book * @return the updated book * @throws ResourceNotFoundException if the book with the specified ID is not found */ - public Book updateBook(int bookId, Book bookDetails) { + public BookDto updateBook(int bookId, BookDto bookDtoDetails) { Book book = bookRepository.findById(bookId) .orElseThrow(() -> new ResourceNotFoundException("Book not found")); - book.setTitle(bookDetails.getTitle()); - book.setAuthor(bookDetails.getAuthor()); - book.setIsbn(bookDetails.getIsbn()); - book.setPublisher(bookDetails.getPublisher()); - book.setPublishedYear(bookDetails.getPublishedYear()); - book.setGenre(bookDetails.getGenre()); - book.setCopiesAvailable(bookDetails.getCopiesAvailable()); - return bookRepository.save(book); + book.setTitle(bookDtoDetails.getTitle()); + book.setAuthor(bookDtoDetails.getAuthor()); + book.setIsbn(bookDtoDetails.getIsbn()); + book.setPublisher(bookDtoDetails.getPublisher()); + book.setPublishedYear(bookDtoDetails.getPublishedYear()); + book.setGenre(bookDtoDetails.getGenre()); + book.setCopiesAvailable(bookDtoDetails.getCopiesAvailable()); + Book updatedBook = bookRepository.save(book); + return EntityToDto(updatedBook); } /** @@ -107,4 +113,29 @@ public void deleteBook(int bookId) { bookRepository.delete(book); } + public BookDto EntityToDto(Book book){ + BookDto bookDto= new BookDto(); + bookDto.setBookId(book.getBookId()); + bookDto.setPublisher(book.getPublisher()); + bookDto.setPublishedYear(book.getPublishedYear()); + bookDto.setTitle(book.getTitle()); + bookDto.setAuthor(book.getAuthor()); + bookDto.setGenre(book.getGenre()); + bookDto.setIsbn(book.getIsbn()); + bookDto.setCopiesAvailable(book.getCopiesAvailable()); + return bookDto; + } + + public Book DtoToEntity(BookDto bookDto){ + Book book= new Book(); + book.setBookId(bookDto.getBookId()); + book.setAuthor(bookDto.getAuthor()); + book.setGenre(bookDto.getGenre()); + book.setPublisher(bookDto.getPublisher()); + book.setPublishedYear(bookDto.getPublishedYear()); + book.setTitle(bookDto.getTitle()); + book.setCopiesAvailable(bookDto.getCopiesAvailable()); + book.setIsbn(bookDto.getIsbn()); + return book; + } } diff --git a/src/main/java/com/libraryman_api/borrowing/BorrowingController.java b/src/main/java/com/libraryman_api/borrowing/BorrowingController.java index 1dddc89..0a6dc65 100644 --- a/src/main/java/com/libraryman_api/borrowing/BorrowingController.java +++ b/src/main/java/com/libraryman_api/borrowing/BorrowingController.java @@ -39,7 +39,7 @@ public BorrowingController(BorrowingService borrowingService) { * The results are sorted by borrow date by default and limited to 5 members per page. */ @GetMapping - public Page getAllBorrowings(@PageableDefault(page=0, size=5, sort="borrowDate") Pageable pageable, + public Page getAllBorrowings(@PageableDefault(page=0, size=5, sort="borrowDate") Pageable pageable, @RequestParam(required = false) String sortBy, @RequestParam(required = false) String sortDir) { @@ -60,12 +60,12 @@ public Page getAllBorrowings(@PageableDefault(page=0, size=5, sort=" /** * Records a new book borrowing. * - * @param borrowing the {@link Borrowings} object containing borrowing details. + * @param borrowingsDto the {@link Borrowings} object containing borrowing details. * @return the saved {@link Borrowings} object representing the borrowing record. */ @PostMapping - public Borrowings borrowBook(@RequestBody Borrowings borrowing) { - return borrowingService.borrowBook(borrowing); + public BorrowingsDto borrowBook(@RequestBody BorrowingsDto borrowingsDto) { + return borrowingService.borrowBook(borrowingsDto); } /** @@ -74,8 +74,8 @@ public Borrowings borrowBook(@RequestBody Borrowings borrowing) { * @param id the ID of the borrowing record to update. */ @PutMapping("/{id}/return") - public void returnBook(@PathVariable int id) { - borrowingService.returnBook(id); + public BorrowingsDto returnBook(@PathVariable int id) { + return borrowingService.returnBook(id); } /** @@ -101,7 +101,7 @@ public String payFine(@PathVariable int id) { * The results are sorted by borrow date by default and limited to 5 members per page. */ @GetMapping("member/{memberId}") - public Page getAllBorrowingsOfAMember(@PathVariable int memberId, + public Page getAllBorrowingsOfAMember(@PathVariable int memberId, @PageableDefault(page=0, size=5, sort="borrowDate") Pageable pageable, @RequestParam(required = false) String sortBy, @RequestParam(required = false) String sortDir) { @@ -128,7 +128,7 @@ public Page getAllBorrowingsOfAMember(@PathVariable int memberId, * @throws ResourceNotFoundException if the borrowing record with the specified ID is not found. */ @GetMapping("{borrowingId}") - public Borrowings getBorrowingById(@PathVariable int borrowingId) { + public BorrowingsDto getBorrowingById(@PathVariable int borrowingId) { return borrowingService.getBorrowingById(borrowingId) .orElseThrow(() -> new ResourceNotFoundException("Borrowing not found")); } diff --git a/src/main/java/com/libraryman_api/borrowing/BorrowingService.java b/src/main/java/com/libraryman_api/borrowing/BorrowingService.java index 3a7d785..ac9c22f 100644 --- a/src/main/java/com/libraryman_api/borrowing/BorrowingService.java +++ b/src/main/java/com/libraryman_api/borrowing/BorrowingService.java @@ -1,5 +1,6 @@ package com.libraryman_api.borrowing; +import com.libraryman_api.book.BookDto; import com.libraryman_api.book.BookService; import com.libraryman_api.book.Book; import com.libraryman_api.fine.Fines; @@ -8,6 +9,7 @@ import com.libraryman_api.fine.FineRepository; import com.libraryman_api.member.MemberService; import com.libraryman_api.member.Members; +import com.libraryman_api.member.MembersDto; import com.libraryman_api.notification.NotificationService; import org.springframework.data.domain.Page; @@ -70,9 +72,10 @@ public BorrowingService(BorrowingRepository borrowingRepository, FineRepository * @return a {@link Page} of {@link Borrowings} representing all borrowings * @throws InvalidSortFieldException if an invalid sortBy field is specified */ - public Page getAllBorrowings(Pageable pageable) { + public Page getAllBorrowings(Pageable pageable) { try { - return borrowingRepository.findAll(pageable); + Page pagedBorrowings = borrowingRepository.findAll(pageable); + return pagedBorrowings.map(this::EntityToDto); } catch (PropertyReferenceException ex) { throw new InvalidSortFieldException("The specified 'sortBy' value is invalid."); } @@ -84,8 +87,9 @@ public Page getAllBorrowings(Pageable pageable) { * @param borrowingId the ID of the borrowing to retrieve * @return an {@code Optional} containing the found borrowing, or {@code Optional.empty()} if no borrowing was found */ - public Optional getBorrowingById(int borrowingId) { - return borrowingRepository.findById(borrowingId); + public Optional getBorrowingById(int borrowingId) { + Optional borrowingsById = borrowingRepository.findById(borrowingId); + return borrowingsById.map(this::EntityToDto); } /** @@ -101,30 +105,30 @@ public Optional getBorrowingById(int borrowingId) { * @throws ResourceNotFoundException if the book is not found or if there are not enough copies available */ @Transactional - public synchronized Borrowings borrowBook(Borrowings borrowing) { - Optional book = bookService.getBookById(borrowing.getBook().getBookId()); - Optional member = memberService.getMemberById(borrowing.getMember().getMemberId()); - if (book.isPresent() && member.isPresent()) { - Book bookEntity = book.get(); - Members memberEntity = member.get(); + public synchronized BorrowingsDto borrowBook(BorrowingsDto borrowing) { + Optional bookDto = bookService.getBookById(borrowing.getBook().getBookId()); + Optional member = memberService.getMemberById(borrowing.getMember().getMemberId()); + if (bookDto.isPresent() && member.isPresent()) { + Book bookEntity = bookService.DtoToEntity(bookDto.get()); + Members memberEntity = memberService.DtoEntity(member.get()); if (bookEntity.getCopiesAvailable() > 0) { updateBookCopies(borrowing.getBook().getBookId(), "REMOVE", 1); borrowing.setBorrowDate(new Date()); - borrowing.setBook(bookEntity); - borrowing.setMember(memberEntity); + borrowing.setBook(bookService.EntityToDto(bookEntity)); + borrowing.setMember(memberService.EntityToDto(memberEntity)); borrowing.setDueDate(calculateDueDate()); - Borrowings savedBorrowing = borrowingRepository.save(borrowing); + Borrowings savedBorrowing = borrowingRepository.save(DtoToEntity(borrowing)); notificationService.borrowBookNotification(savedBorrowing); // Null Book problem notificationService.reminderNotification(savedBorrowing); // send this notification two days before the due date // Null Book problem - return savedBorrowing; + return EntityToDto(savedBorrowing); } else { throw new ResourceNotFoundException("Not enough copies available"); } } else { - if (book.isEmpty()) { + if (bookDto.isEmpty()) { throw new ResourceNotFoundException("Book not found"); } throw new ResourceNotFoundException("Member not found"); @@ -142,29 +146,30 @@ public synchronized Borrowings borrowBook(Borrowings borrowing) { * @param borrowingId the ID of the borrowing record * @throws ResourceNotFoundException if the borrowing record is not found, if the book has already been returned, or if there are outstanding fines */ - public synchronized void returnBook(int borrowingId) { - Borrowings borrowing = getBorrowingById(borrowingId) + public synchronized BorrowingsDto returnBook(int borrowingId) { + BorrowingsDto borrowingsDto = getBorrowingById(borrowingId) .orElseThrow(() -> new ResourceNotFoundException("Borrowing not found")); - if (borrowing.getReturnDate() != null) { + if (borrowingsDto.getReturnDate() != null) { throw new ResourceNotFoundException("Book has already been returned"); } - if (borrowing.getDueDate().before(new Date())) { - if (borrowing.getFine() == null) { - borrowing.setFine(imposeFine(borrowing)); - borrowingRepository.save(borrowing); - notificationService.fineImposedNotification(borrowing); + if (borrowingsDto.getDueDate().before(new Date())) { + if (borrowingsDto.getFine() == null) { + borrowingsDto.setFine(imposeFine(DtoToEntity(borrowingsDto))); + borrowingRepository.save(DtoToEntity(borrowingsDto)); + notificationService.fineImposedNotification(DtoToEntity(borrowingsDto)); throw new ResourceNotFoundException("Due date passed. Fine imposed, pay fine first to return the book"); - } else if (!borrowing.getFine().isPaid()) { - notificationService.fineImposedNotification(borrowing); + } else if (!borrowingsDto.getFine().isPaid()) { + notificationService.fineImposedNotification(DtoToEntity(borrowingsDto)); throw new ResourceNotFoundException("Outstanding fine, please pay before returning the book"); } } - borrowing.setReturnDate(new Date()); - updateBookCopies(borrowing.getBook().getBookId(), "ADD", 1); - notificationService.bookReturnedNotification(borrowing); - borrowingRepository.save(borrowing); + borrowingsDto.setReturnDate(new Date()); + updateBookCopies(borrowingsDto.getBook().getBookId(), "ADD", 1); + notificationService.bookReturnedNotification(DtoToEntity(borrowingsDto)); + borrowingRepository.save(DtoToEntity(borrowingsDto)); + return borrowingsDto; } /** @@ -190,15 +195,15 @@ private Fines imposeFine(Borrowings borrowing) { * @throws ResourceNotFoundException if the borrowing record is not found or if there is no outstanding fine */ public String payFine(int borrowingId) { - Borrowings borrowing = getBorrowingById(borrowingId) + BorrowingsDto borrowingsDto = getBorrowingById(borrowingId) .orElseThrow(() -> new ResourceNotFoundException("Borrowing not found")); - Fines fine = borrowing.getFine(); + Fines fine = borrowingsDto.getFine(); if (fine != null && !fine.isPaid()) { fine.setPaid(true); - notificationService.finePaidNotification(borrowing); + notificationService.finePaidNotification(DtoToEntity(borrowingsDto)); fineRepository.save(fine); // Save the updated fine - borrowingRepository.save(borrowing); // Save borrowing with updated fine + borrowingRepository.save(DtoToEntity(borrowingsDto)); // Save borrowing with updated fine } else { throw new ResourceNotFoundException("No outstanding fine found or fine already paid"); } @@ -218,10 +223,10 @@ public String payFine(int borrowingId) { * @throws ResourceNotFoundException if the book is not found or if there are not enough copies to remove */ public void updateBookCopies(int bookId, String operation, int numberOfCopies) { - Optional book = bookService.getBookById(bookId); + Optional bookDto = bookService.getBookById(bookId); - if (book.isPresent()) { - Book bookEntity = book.get(); + if (bookDto.isPresent()) { + Book bookEntity = bookService.DtoToEntity(bookDto.get()); if (operation.equals("ADD")) { bookEntity.setCopiesAvailable(bookEntity.getCopiesAvailable() + numberOfCopies); } else if (operation.equals("REMOVE")) { @@ -274,16 +279,40 @@ private BigDecimal calculateFineAmount(Borrowings borrowing) { * @throws InvalidSortFieldException if an invalid sortBy field is specified * @return a {@link Page} of {@link Borrowings} representing all borrowing associated with a specific member */ - public Page getAllBorrowingsOfMember(int memberId, Pageable pageable) { + public Page getAllBorrowingsOfMember(int memberId, Pageable pageable) { try { Page borrowings = borrowingRepository.findByMember_memberId(memberId, pageable); if (borrowings.isEmpty()) { throw new ResourceNotFoundException("Member didn't borrow any book"); } - return borrowings; + return borrowings.map(this::EntityToDto); } catch (PropertyReferenceException ex) { throw new InvalidSortFieldException("The specified 'sortBy' value is invalid."); } } + + public Borrowings DtoToEntity(BorrowingsDto borrowingsDto){ + Borrowings borrowings = new Borrowings(); + borrowings.setBorrowDate(borrowingsDto.getBorrowDate()); + borrowings.setMember(memberService.DtoEntity(borrowingsDto.getMember())); + borrowings.setFine(borrowingsDto.getFine()); + borrowings.setReturnDate(borrowingsDto.getReturnDate()); + borrowings.setDueDate(borrowingsDto.getDueDate()); + borrowings.setBook(bookService.DtoToEntity(borrowingsDto.getBook())); + borrowings.setBorrowingId(borrowingsDto.getBorrowingId()); + return borrowings; + } + + public BorrowingsDto EntityToDto(Borrowings borrowings){ + BorrowingsDto borrowingsDto = new BorrowingsDto(); + borrowingsDto.setBorrowingId(borrowings.getBorrowingId()); + borrowingsDto.setFine(borrowings.getFine()); + borrowingsDto.setBorrowDate(borrowings.getBorrowDate()); + borrowingsDto.setReturnDate(borrowings.getReturnDate()); + borrowingsDto.setDueDate(borrowings.getDueDate()); + borrowingsDto.setMember(memberService.EntityToDto(borrowings.getMember())); + borrowingsDto.setBook(bookService.EntityToDto(borrowings.getBook())); + return borrowingsDto; + } } diff --git a/src/main/java/com/libraryman_api/borrowing/Borrowings.java b/src/main/java/com/libraryman_api/borrowing/Borrowings.java index c562e40..547f1ac 100644 --- a/src/main/java/com/libraryman_api/borrowing/Borrowings.java +++ b/src/main/java/com/libraryman_api/borrowing/Borrowings.java @@ -75,6 +75,8 @@ public Members getMember() { return member; } + public void setBorrowingId(int borrowingId) {this.borrowingId = borrowingId;} + public void setMember(Members member) { this.member = member; } diff --git a/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java b/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java index 9ed52ac..28b36b3 100644 --- a/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java +++ b/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java @@ -1,9 +1,7 @@ package com.libraryman_api.borrowing; -import com.libraryman_api.book.Book; import com.libraryman_api.book.BookDto; import com.libraryman_api.fine.Fines; -import com.libraryman_api.member.Members; import com.libraryman_api.member.MembersDto; import java.util.Date; diff --git a/src/main/java/com/libraryman_api/member/MemberController.java b/src/main/java/com/libraryman_api/member/MemberController.java index f6d016f..da67d9e 100644 --- a/src/main/java/com/libraryman_api/member/MemberController.java +++ b/src/main/java/com/libraryman_api/member/MemberController.java @@ -39,7 +39,7 @@ public MemberController(MemberService memberService) { * The results are sorted by name by default and limited to 5 members per page. */ @GetMapping - public Page getAllMembers(@PageableDefault(page=0, size=5, sort="name") Pageable pageable, + public Page getAllMembers(@PageableDefault(page=0, size=5, sort="name") Pageable pageable, @RequestParam(required = false) String sortBy, @RequestParam(required = false) String sortDir) { @@ -65,7 +65,7 @@ public Page getAllMembers(@PageableDefault(page=0, size=5, sort="name") * @return a {@link ResponseEntity} containing the found {@link Members} object */ @GetMapping("/{id}") - public ResponseEntity getMemberById(@PathVariable int id) { + public ResponseEntity getMemberById(@PathVariable int id) { return memberService.getMemberById(id) .map(ResponseEntity::ok) .orElseThrow(() -> new ResourceNotFoundException("Member not found")); @@ -74,12 +74,12 @@ public ResponseEntity getMemberById(@PathVariable int id) { /** * Adds a new library member. * - * @param member the {@link Members} object representing the new member + * @param membersDto the {@link Members} object representing the new member * @return the added {@link Members} object */ @PostMapping - public Members addMember(@RequestBody Members member) { - return memberService.addMember(member); + public MembersDto addMember(@RequestBody MembersDto membersDto) { + return memberService.addMember(membersDto); } /** @@ -87,12 +87,12 @@ public Members addMember(@RequestBody Members member) { * If the member is not found, a {@link ResourceNotFoundException} is thrown. * * @param id the ID of the member to update - * @param memberDetails the {@link Members} object containing the updated details + * @param membersDtoDetails the {@link Members} object containing the updated details * @return the updated {@link Members} object */ @PutMapping("/{id}") - public Members updateMember(@PathVariable int id, @RequestBody Members memberDetails) { - return memberService.updateMember(id, memberDetails); + public MembersDto updateMember(@PathVariable int id, @RequestBody MembersDto membersDtoDetails) { + return memberService.updateMember(id, membersDtoDetails); } /** diff --git a/src/main/java/com/libraryman_api/member/MemberService.java b/src/main/java/com/libraryman_api/member/MemberService.java index e5c4d2a..62c7cc4 100644 --- a/src/main/java/com/libraryman_api/member/MemberService.java +++ b/src/main/java/com/libraryman_api/member/MemberService.java @@ -11,6 +11,8 @@ import com.libraryman_api.exception.ResourceNotFoundException; import com.libraryman_api.notification.NotificationService; +import javax.xml.stream.events.DTD; + /** * Service class responsible for managing member-related operations in the LibraryMan system. * @@ -50,9 +52,10 @@ public MemberService(MemberRepository memberRepository, NotificationService noti * @return a {@link Page} of {@link Members} representing all members * @throws InvalidSortFieldException if an invalid sortBy field is specified */ - public Page getAllMembers(Pageable pageable) { + public Page getAllMembers(Pageable pageable) { try { - return memberRepository.findAll(pageable); + Page pagedMembers = memberRepository.findAll(pageable); + return pagedMembers.map(this::EntityToDto); } catch (PropertyReferenceException ex) { throw new InvalidSortFieldException("The specified 'sortBy' value is invalid."); } @@ -64,8 +67,10 @@ public Page getAllMembers(Pageable pageable) { * @param memberId the ID of the member to retrieve * @return an {@code Optional} containing the found member, or {@code Optional.empty()} if no member was found */ - public Optional getMemberById(int memberId) { - return memberRepository.findById(memberId); + public Optional getMemberById(int memberId) { + + Optional memberById = memberRepository.findById(memberId); + return memberById.map(this::EntityToDto); } /** @@ -74,14 +79,15 @@ public Optional getMemberById(int memberId) { *

This method saves the new member record in the database and sends a notification * about the account creation.

* - * @param member the member details to be added + * @param membersDto the member details to be added * @return the saved member record */ - public Members addMember(Members member) { + public MembersDto addMember(MembersDto membersDto) { + Members member = DtoEntity(membersDto); Members currentMember = memberRepository.save(member); notificationService.accountCreatedNotification(currentMember); - return currentMember; + return EntityToDto(currentMember); } /** @@ -92,21 +98,21 @@ public Members addMember(Members member) { * a notification about the account details update is sent.

* * @param memberId the ID of the member to update - * @param memberDetails the updated member details + * @param membersDtoDetails the updated member details * @return the updated member record * @throws ResourceNotFoundException if the member is not found */ - public Members updateMember(int memberId, Members memberDetails) { + public MembersDto updateMember(int memberId, MembersDto membersDtoDetails) { Members member = memberRepository.findById(memberId) .orElseThrow(() -> new ResourceNotFoundException("Member not found")); - member.setName(memberDetails.getName()); - member.setEmail(memberDetails.getEmail()); - member.setPassword(memberDetails.getPassword()); - member.setRole(memberDetails.getRole()); - member.setMembershipDate(memberDetails.getMembershipDate()); + member.setName(membersDtoDetails.getName()); + member.setEmail(membersDtoDetails.getEmail()); + member.setPassword(membersDtoDetails.getPassword()); + member.setRole(membersDtoDetails.getRole()); + member.setMembershipDate(membersDtoDetails.getMembershipDate()); member = memberRepository.save(member); notificationService.accountDetailsUpdateNotification(member); - return member; + return EntityToDto(member); } /** @@ -129,4 +135,26 @@ public void deleteMember(int memberId) { notificationService.accountDeletionNotification(member); memberRepository.delete(member); } + + public Members DtoEntity(MembersDto membersDto){ + Members members= new Members(); + members.setMemberId(membersDto.getMemberId()); + members.setRole(membersDto.getRole()); + members.setName(membersDto.getName()); + members.setEmail(membersDto.getEmail()); + members.setPassword(membersDto.getPassword()); + members.setMembershipDate(membersDto.getMembershipDate()); + return members; + } + + public MembersDto EntityToDto(Members members){ + MembersDto membersDto= new MembersDto(); + membersDto.setMemberId(members.getMemberId()); + membersDto.setName(members.getName()); + membersDto.setRole(members.getRole()); + membersDto.setEmail(members.getEmail()); + membersDto.setPassword(members.getPassword()); + membersDto.setMembershipDate(members.getMembershipDate()); + return membersDto; + } } diff --git a/src/main/java/com/libraryman_api/member/Members.java b/src/main/java/com/libraryman_api/member/Members.java index f11b805..352a3c7 100644 --- a/src/main/java/com/libraryman_api/member/Members.java +++ b/src/main/java/com/libraryman_api/member/Members.java @@ -70,6 +70,8 @@ public String getPassword() { return password; } + public void setMemberId(int memberId) {this.memberId = memberId;} + public void setPassword(String password) { this.password = password; } diff --git a/src/main/resources/application-development.properties b/src/main/resources/application-development.properties index c3cf3e5..cd5618e 100644 --- a/src/main/resources/application-development.properties +++ b/src/main/resources/application-development.properties @@ -42,4 +42,8 @@ spring.mail.username=Add_Your_Mail_Service_Username spring.mail.password=Add_Your_Mail_Service_Password spring.mail.properties.mail.smtp.auth=Add_Your_Mail_Service_SMTP spring.mail.properties.mail.starttls.enable=Add_Your_Mail_Service_Start_TLS -spring.mail.properties.domain_name=Add_Your_Mail_Service_Domain_Name \ No newline at end of file +spring.mail.properties.domain_name=Add_Your_Mail_Service_Domain_Name + + + + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 53718a7..eef557c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,2 @@ spring.application.name=libraryman-api -spring.profiles.active=${ENV:development} \ No newline at end of file +spring.profiles.active=${ENV:development} From e14ee36c1a79874c6ee503816f210e8729be8024 Mon Sep 17 00:00:00 2001 From: Anish Date: Sun, 6 Oct 2024 23:59:27 +0530 Subject: [PATCH 5/7] removed unused import statement --- src/main/java/com/libraryman_api/member/MemberService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/libraryman_api/member/MemberService.java b/src/main/java/com/libraryman_api/member/MemberService.java index 62c7cc4..b4ecd2f 100644 --- a/src/main/java/com/libraryman_api/member/MemberService.java +++ b/src/main/java/com/libraryman_api/member/MemberService.java @@ -11,7 +11,7 @@ import com.libraryman_api.exception.ResourceNotFoundException; import com.libraryman_api.notification.NotificationService; -import javax.xml.stream.events.DTD; + /** * Service class responsible for managing member-related operations in the LibraryMan system. From 4b8c601c31edd92c42ff56eb735430316e236e0f Mon Sep 17 00:00:00 2001 From: Anish Date: Mon, 7 Oct 2024 00:40:48 +0530 Subject: [PATCH 6/7] added a method description --- .../com/libraryman_api/book/BookService.java | 23 ++++++++++++++++ .../borrowing/BorrowingService.java | 26 +++++++++++++++++++ .../libraryman_api/member/MemberService.java | 23 ++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/main/java/com/libraryman_api/book/BookService.java b/src/main/java/com/libraryman_api/book/BookService.java index 1c63cef..3cb288b 100644 --- a/src/main/java/com/libraryman_api/book/BookService.java +++ b/src/main/java/com/libraryman_api/book/BookService.java @@ -112,6 +112,17 @@ public void deleteBook(int bookId) { .orElseThrow(() -> new ResourceNotFoundException("Book not found")); bookRepository.delete(book); } + /** + * Converts a Book entity to a BookDto object. + * + *

This method takes a Book entity and transforms it into a BookDto object for + * data transfer between application layers. It maps all relevant book details, + * including book ID, publisher, published year, title, author, genre, ISBN, + * and copies available, from the entity to the DTO.

+ * + * @param book the entity object containing book information + * @return a BookDto object with data populated from the entity + */ public BookDto EntityToDto(Book book){ BookDto bookDto= new BookDto(); @@ -125,6 +136,18 @@ public BookDto EntityToDto(Book book){ bookDto.setCopiesAvailable(book.getCopiesAvailable()); return bookDto; } + /** + * Converts a BookDto object to a Book entity. + * + *

This method takes a BookDto object and converts it into a Book entity for + * use in database operations. It maps all relevant book details, including + * book ID, author, genre, publisher, published year, title, ISBN, and copies + * available, from the DTO to the entity.

+ * + * @param bookDto the DTO object containing book information + * @return a Book entity with data populated from the DTO + */ + public Book DtoToEntity(BookDto bookDto){ Book book= new Book(); diff --git a/src/main/java/com/libraryman_api/borrowing/BorrowingService.java b/src/main/java/com/libraryman_api/borrowing/BorrowingService.java index ac9c22f..c16f5e0 100644 --- a/src/main/java/com/libraryman_api/borrowing/BorrowingService.java +++ b/src/main/java/com/libraryman_api/borrowing/BorrowingService.java @@ -291,6 +291,19 @@ public Page getAllBorrowingsOfMember(int memberId, Pageable pagea throw new InvalidSortFieldException("The specified 'sortBy' value is invalid."); } } + /** + * Converts a BorrowingsDto object to a Borrowings entity. + * + *

This method takes a BorrowingsDto object and transforms it into a Borrowings + * entity for use in database operations. It maps all relevant borrowing details + * from the DTO, including borrow date, member information, fine, return date, + * due date, and book details. It also retrieves and converts related entities + * such as Member and Book using respective service methods.

+ * + * @param borrowingsDto the DTO object containing borrowing information + * @return a Borrowings entity with data populated from the DTO + */ + public Borrowings DtoToEntity(BorrowingsDto borrowingsDto){ Borrowings borrowings = new Borrowings(); @@ -303,6 +316,19 @@ public Borrowings DtoToEntity(BorrowingsDto borrowingsDto){ borrowings.setBorrowingId(borrowingsDto.getBorrowingId()); return borrowings; } + /** + * Converts a Borrowings entity to a BorrowingsDto object. + * + *

This method takes a Borrowings entity and converts it into a BorrowingsDto + * object for data transfer between application layers. It maps all necessary + * borrowing details from the entity, including borrowing ID, fine, borrow date, + * return date, due date, and related Member and Book entities, converting them + * into DTOs using respective service methods.

+ * + * @param borrowings the entity object containing borrowing information + * @return a BorrowingsDto object with data populated from the entity + */ + public BorrowingsDto EntityToDto(Borrowings borrowings){ BorrowingsDto borrowingsDto = new BorrowingsDto(); diff --git a/src/main/java/com/libraryman_api/member/MemberService.java b/src/main/java/com/libraryman_api/member/MemberService.java index b4ecd2f..d45f782 100644 --- a/src/main/java/com/libraryman_api/member/MemberService.java +++ b/src/main/java/com/libraryman_api/member/MemberService.java @@ -135,6 +135,17 @@ public void deleteMember(int memberId) { notificationService.accountDeletionNotification(member); memberRepository.delete(member); } + /** + * Converts a MembersDto object to a Members entity. + * + *

This method takes a MembersDto object and transforms it into a Members entity + * to be used in database operations. It maps all relevant member details from + * the DTO, including member ID, role, name, email, password, and membership date.

+ * + * @param membersDto the DTO object containing member information + * @return a Members entity with data populated from the DTO + */ + public Members DtoEntity(MembersDto membersDto){ Members members= new Members(); @@ -146,6 +157,18 @@ public Members DtoEntity(MembersDto membersDto){ members.setMembershipDate(membersDto.getMembershipDate()); return members; } + /** + * Converts a Members entity to a MembersDto object. + * + *

This method takes a Members entity object and converts it into a MembersDto + * object to be used for data transfer between layers. It maps all necessary + * member details, including member ID, name, role, email, password, and membership + * date, from the entity to the DTO.

+ * + * @param members the entity object containing member information + * @return a MembersDto object with data populated from the entity + */ + public MembersDto EntityToDto(Members members){ MembersDto membersDto= new MembersDto(); From ddc6b0d4a974d5f65fc007da7569c92664728dcb Mon Sep 17 00:00:00 2001 From: Talupula Sahithi Date: Mon, 7 Oct 2024 17:20:23 +0530 Subject: [PATCH 7/7] Resolved merge conflict in application.properties --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index eef557c..53718a7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,2 @@ spring.application.name=libraryman-api -spring.profiles.active=${ENV:development} +spring.profiles.active=${ENV:development} \ No newline at end of file