diff --git a/pom.xml b/pom.xml
index 95e4f3f..fe7daef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,17 @@
spring-boot-starter-data-jpa
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.modelmapper
+ modelmapper
+ 3.0.0
+
+
org.springframework.boot
diff --git a/src/main/java/com/libraryman_api/book/Book.java b/src/main/java/com/libraryman_api/book/Book.java
index b4d3f8e..63ca3e9 100644
--- a/src/main/java/com/libraryman_api/book/Book.java
+++ b/src/main/java/com/libraryman_api/book/Book.java
@@ -1,9 +1,17 @@
package com.libraryman_api.book;
import jakarta.persistence.*;
+import lombok.*;
+
@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+@Setter
+@Builder
+@ToString
public class Book {
@Id
@@ -33,91 +41,5 @@ public class Book {
@Column(name = "copies_available", nullable = false)
private int copiesAvailable;
- public Book() {
- }
-
- public Book(String title, String author, String isbn, String publisher, int publishedYear, String genre, int copiesAvailable) {
- this.title = title;
- this.author = author;
- this.isbn = isbn;
- this.publisher = publisher;
- this.publishedYear = publishedYear;
- this.genre = genre;
- this.copiesAvailable = copiesAvailable;
- }
-
- public int getBookId() {
- return bookId;
- }
-
- public String getTitle() {
- return title;
- }
-
- public String getAuthor() {
- return author;
- }
-
- public String getIsbn() {
- return isbn;
- }
-
- public String getPublisher() {
- return publisher;
- }
-
- public int getPublishedYear() {
- return publishedYear;
- }
-
- public String getGenre() {
- return genre;
- }
-
- public int getCopiesAvailable() {
- return copiesAvailable;
- }
-
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public void setAuthor(String author) {
- this.author = author;
- }
-
- public void setIsbn(String isbn) {
- this.isbn = isbn;
- }
-
- public void setPublisher(String publisher) {
- this.publisher = publisher;
- }
-
- public void setPublishedYear(int publishedYear) {
- this.publishedYear = publishedYear;
- }
-
- public void setGenre(String genre) {
- this.genre = genre;
- }
-
- public void setCopiesAvailable(int copiesAvailable) {
- this.copiesAvailable = copiesAvailable;
- }
- @Override
- public String toString() {
- return "Books{" +
- "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/book/BookController.java b/src/main/java/com/libraryman_api/book/BookController.java
index 778f7c4..b658cd4 100644
--- a/src/main/java/com/libraryman_api/book/BookController.java
+++ b/src/main/java/com/libraryman_api/book/BookController.java
@@ -23,10 +23,11 @@ public class BookController {
/**
* Retrieves a list of all books in the library.
*
- * @return a list of {@link Book} objects representing all the books in the library.
+ * @return a list of {@link BookDto} objects representing all the books in the library.
*/
@GetMapping
- public List getAllBooks() {
+ public List getAllBooks() {
+
return bookService.getAllBooks();
}
@@ -34,11 +35,11 @@ public List getAllBooks() {
* Retrieves a book by its ID.
*
* @param id the ID of the book to retrieve.
- * @return a {@link ResponseEntity} containing the {@link Book} object, if found.
+ * @return a {@link ResponseEntity} containing the {@link BookDto} object, if found.
* @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"));
@@ -47,24 +48,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/BookDto.java b/src/main/java/com/libraryman_api/book/BookDto.java
new file mode 100644
index 0000000..5211e0e
--- /dev/null
+++ b/src/main/java/com/libraryman_api/book/BookDto.java
@@ -0,0 +1,34 @@
+package com.libraryman_api.book;
+
+import jakarta.persistence.Column;
+import lombok.*;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+@Builder
+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;
+
+
+
+}
diff --git a/src/main/java/com/libraryman_api/book/BookService.java b/src/main/java/com/libraryman_api/book/BookService.java
index 652f01a..a880fc3 100644
--- a/src/main/java/com/libraryman_api/book/BookService.java
+++ b/src/main/java/com/libraryman_api/book/BookService.java
@@ -1,6 +1,8 @@
package com.libraryman_api.book;
import com.libraryman_api.exception.ResourceNotFoundException;
+import org.modelmapper.ModelMapper;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -25,6 +27,8 @@
public class BookService {
private final BookRepository bookRepository;
+ @Autowired
+ private ModelMapper mapper;
/**
* Constructs a new {@code BookService} with the specified {@code BookRepository}.
@@ -32,6 +36,7 @@ public class BookService {
* @param bookRepository the repository to be used by this service to interact with the database
*/
public BookService(BookRepository bookRepository) {
+
this.bookRepository = bookRepository;
}
@@ -40,8 +45,9 @@ public BookService(BookRepository bookRepository) {
*
* @return a list of all books
*/
- public List getAllBooks() {
- return bookRepository.findAll();
+ public List getAllBooks() {
+ List allBooks = bookRepository.findAll();
+ return allBooks.stream().map(this::EntityToDto).toList();
}
/**
@@ -50,39 +56,44 @@ public List getAllBooks() {
* @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 getBook = bookRepository.findById(bookId);
+ return getBook.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);
}
/**
@@ -97,4 +108,13 @@ public void deleteBook(int bookId) {
bookRepository.delete(book);
}
+
+
+ public BookDto EntityToDto(Book book){
+ return mapper.map(book,BookDto.class);
+ }
+ public Book DtoToEntity(BookDto bookDto){
+ return mapper.map(bookDto,Book.class);
+ }
+
}
diff --git a/src/main/java/com/libraryman_api/borrowing/BorrowingController.java b/src/main/java/com/libraryman_api/borrowing/BorrowingController.java
index e76ae53..bd3f5a7 100644
--- a/src/main/java/com/libraryman_api/borrowing/BorrowingController.java
+++ b/src/main/java/com/libraryman_api/borrowing/BorrowingController.java
@@ -31,19 +31,20 @@ public BorrowingController(BorrowingService borrowingService) {
* @return a list of {@link Borrowings} objects representing all borrowings.
*/
@GetMapping
- public List getAllBorrowings() {
+ public List getAllBorrowings() {
+
return borrowingService.getAllBorrowings();
}
/**
* Records a new book borrowing.
*
- * @param borrowing the {@link Borrowings} object containing borrowing details.
+ * @param borrowingDto 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 borrowingDto) {
+ return borrowingService.borrowBook(borrowingDto);
}
/**
@@ -52,8 +53,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);
}
/**
@@ -75,7 +76,7 @@ public String payFine(@PathVariable int id) {
* @return a list of {@link Borrowings} objects representing the member's borrowings.
*/
@GetMapping("member/{memberId}")
- public List getAllBorrowingsOfAMember(@PathVariable int memberId) {
+ public List getAllBorrowingsOfAMember(@PathVariable int memberId) {
return borrowingService.getAllBorrowingsOfMember(memberId);
}
@@ -87,7 +88,7 @@ public List 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 668d0cc..c65fe14 100644
--- a/src/main/java/com/libraryman_api/borrowing/BorrowingService.java
+++ b/src/main/java/com/libraryman_api/borrowing/BorrowingService.java
@@ -1,11 +1,17 @@
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;
import com.libraryman_api.exception.ResourceNotFoundException;
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.modelmapper.ModelMapper;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
@@ -39,20 +45,24 @@ public class BorrowingService {
private final FineRepository fineRepository;
private final NotificationService notificationService;
private final BookService bookService;
+ private final MemberService memberService;
+ @Autowired
+ private ModelMapper mapper;
/**
* Constructs a new {@code BorrowingService} with the specified repositories and services.
*
* @param borrowingRepository the repository for managing borrowing records
- * @param fineRepository the repository for managing fine records
+ * @param fineRepository the repository for managing fine records
* @param notificationService the service for sending notifications
- * @param bookService the service for managing book records
+ * @param bookService the service for managing book records
*/
- public BorrowingService(BorrowingRepository borrowingRepository, FineRepository fineRepository, NotificationService notificationService, BookService bookService) {
+ public BorrowingService(BorrowingRepository borrowingRepository, FineRepository fineRepository, NotificationService notificationService, BookService bookService, MemberService memberService) {
this.borrowingRepository = borrowingRepository;
this.fineRepository = fineRepository;
this.notificationService = notificationService;
this.bookService = bookService;
+ this.memberService = memberService;
}
/**
@@ -60,8 +70,10 @@ public BorrowingService(BorrowingRepository borrowingRepository, FineRepository
*
* @return a list of all borrowings
*/
- public List getAllBorrowings() {
- return borrowingRepository.findAll();
+ public List getAllBorrowings() {
+
+ List borrowings = borrowingRepository.findAll();
+ return borrowings.stream().map(borrowing -> mapper.map(borrowing, BorrowingsDto.class)).toList();
}
/**
@@ -70,8 +82,9 @@ public List getAllBorrowings() {
* @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 borrowingOptional = borrowingRepository.findById(borrowingId);
+ return borrowingOptional.map(borrowing -> mapper.map(borrowing, BorrowingsDto.class));
}
/**
@@ -82,35 +95,68 @@ public Optional getBorrowingById(int borrowingId) {
* or roll back in case of any errors. It updates the book's availability, sets the
* borrowing and due dates, and sends notifications related to the borrowing.
*
- * @param borrowing the borrowing details provided by the user
+ * @param borrowingDto the borrowing details provided by the user
* @return the saved borrowing record
* @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());
+ public synchronized BorrowingsDto borrowBook(BorrowingsDto borrowingDto) {
+ // Retrieve the book by its ID from the borrowingDto
+ Optional bookDtoOptional = bookService.getBookById(borrowingDto.getBook().getBookId());
- if (book.isPresent()) {
- Book bookEntity = book.get();
+ if (bookDtoOptional.isPresent()) {
+ BookDto bookDto = bookDtoOptional.get(); // Fetch the BookDto
+
+ Optional membersDtoOptional = memberService.getMemberById(borrowingDto.getMember().getMemberId());
+ if (membersDtoOptional.isPresent()) {
+ MembersDto membersDto = membersDtoOptional.get();
+
+ // Check if copies are available
+ if (bookDto.getCopiesAvailable() > 0) {
+ // Update the book copies
+ updateBookCopies(borrowingDto.getBook().getBookId(), "REMOVE", 1);
+
+ // Set borrow date and due date in borrowingDto
+ borrowingDto.setBorrowDate(new Date());
+ borrowingDto.setDueDate(calculateDueDate());
+
+ // Directly create Borrowings and populate its fields
+ Borrowings borrowing = new Borrowings();
+ borrowing.setBook(mapper.map(bookDto, Book.class));// Map BookDto to Book entity
+ Members members = mapper.map(membersDto, Members.class);
+ borrowing.setMember(members); // Map MembersDto to Members entity
+ borrowing.setBorrowDate(borrowingDto.getBorrowDate());
+ borrowing.setDueDate(borrowingDto.getDueDate());
+ borrowing.setReturnDate(null); // Set return date if applicable
- if (bookEntity.getCopiesAvailable() > 0) {
- updateBookCopies(borrowing.getBook().getBookId(), "REMOVE", 1);
- borrowing.setBorrowDate(new Date());
- borrowing.setDueDate(calculateDueDate());
+ // Save the borrowing record
+ Borrowings savedBorrowing = borrowingRepository.save(borrowing);
- Borrowings savedBorrowing = borrowingRepository.save(borrowing);
+ // Log saved borrowing for debugging
+ System.out.println("Saved Borrowing: " + savedBorrowing);
- notificationService.borrowBookNotification(savedBorrowing); // Null Book problem
- notificationService.reminderNotification(savedBorrowing); // send this notification two days before the due date // Null Book problem
- return savedBorrowing;
+ // Send notifications
+ notificationService.borrowBookNotification(savedBorrowing);
+ notificationService.reminderNotification(savedBorrowing);
+
+ // Map and return the saved borrowing as BorrowingsDto
+ BorrowingsDto resultDto = mapper.map(savedBorrowing, BorrowingsDto.class);
+ System.out.println("Mapped BorrowingsDto: " + resultDto); // Debugging log
+ return resultDto;
+ } else {
+ throw new ResourceNotFoundException("Not enough copies available");
+ }
} else {
- throw new ResourceNotFoundException("Not enough copies available");
+ throw new ResourceNotFoundException("Member not found");
}
- } else {
+ }
+ else {
throw new ResourceNotFoundException("Book not found");
}
}
+
/**
* Manages the return process for a borrowed book.
*
@@ -122,8 +168,8 @@ 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 borrowing = getBorrowingById(borrowingId)
.orElseThrow(() -> new ResourceNotFoundException("Borrowing not found"));
if (borrowing.getReturnDate() != null) {
@@ -131,8 +177,9 @@ public synchronized void returnBook(int borrowingId) {
}
if (borrowing.getDueDate().before(new Date())) {
if (borrowing.getFine() == null) {
- borrowing.setFine(imposeFine(borrowing));
- borrowingRepository.save(borrowing);
+ Borrowings borrowings = mapper.map(borrowing, Borrowings.class);
+ borrowing.setFine(imposeFine(borrowings));
+ borrowingRepository.save(borrowings);
notificationService.fineImposedNotification(borrowing);
throw new ResourceNotFoundException("Due date passed. Fine imposed, pay fine first to return the book");
} else if (!borrowing.getFine().isPaid()) {
@@ -143,8 +190,10 @@ public synchronized void returnBook(int borrowingId) {
borrowing.setReturnDate(new Date());
updateBookCopies(borrowing.getBook().getBookId(), "ADD", 1);
- notificationService.bookReturnedNotification(borrowing);
- borrowingRepository.save(borrowing);
+ Borrowings borrowings = mapper.map(borrowing, Borrowings.class);
+ notificationService.bookReturnedNotification(borrowings);
+ Borrowings returnedBookRecord = borrowingRepository.save(borrowings);
+ return mapper.map(returnedBookRecord,BorrowingsDto.class);
}
/**
@@ -170,15 +219,16 @@ 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);
+ Borrowings borrowings = mapper.map(borrowingsDto, Borrowings.class);
+ notificationService.finePaidNotification(borrowings);
fineRepository.save(fine); // Save the updated fine
- borrowingRepository.save(borrowing); // Save borrowing with updated fine
+ borrowingRepository.save(borrowings); // Save borrowing with updated fine
} else {
throw new ResourceNotFoundException("No outstanding fine found or fine already paid");
}
@@ -198,10 +248,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 book = bookService.getBookById(bookId);
if (book.isPresent()) {
- Book bookEntity = book.get();
+ BookDto bookEntity = book.get();
if (operation.equals("ADD")) {
bookEntity.setCopiesAvailable(bookEntity.getCopiesAvailable() + numberOfCopies);
} else if (operation.equals("REMOVE")) {
@@ -252,7 +302,8 @@ private BigDecimal calculateFineAmount(Borrowings borrowing) {
* @return a list of borrowings associated with the specified member
* @throws ResourceNotFoundException if the member has not borrowed any books
*/
- public List getAllBorrowingsOfMember(int memberId) {
- return borrowingRepository.findByMember_memberId(memberId).orElseThrow(() -> new ResourceNotFoundException("Member didn't borrow any book"));
+ public List getAllBorrowingsOfMember(int memberId) {
+ List borrowingsList = borrowingRepository.findByMember_memberId(memberId).orElseThrow(() -> new ResourceNotFoundException("Member didn't borrow any book"));
+ return borrowingsList.stream().map(borrowings -> mapper.map(borrowings,BorrowingsDto.class)).toList();
}
}
diff --git a/src/main/java/com/libraryman_api/borrowing/Borrowings.java b/src/main/java/com/libraryman_api/borrowing/Borrowings.java
index c562e40..db9fd9c 100644
--- a/src/main/java/com/libraryman_api/borrowing/Borrowings.java
+++ b/src/main/java/com/libraryman_api/borrowing/Borrowings.java
@@ -4,10 +4,17 @@
import com.libraryman_api.fine.Fines;
import com.libraryman_api.member.Members;
import jakarta.persistence.*;
+import lombok.*;
import java.util.Date;
@Entity
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
public class Borrowings {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
@@ -30,7 +37,7 @@ public class Borrowings {
@JoinColumn(name = "member_id", nullable = false)
private Members member;
- @Column(name = "borrow_date",nullable = false)
+ @Column(name = "borrow_date", nullable = false)
private Date borrowDate;
@Column(name = "due_date", nullable = false)
@@ -40,66 +47,4 @@ public class Borrowings {
private Date returnDate;
- public Borrowings() {
- }
-
- public Borrowings(Book book, Members member, Date borrowDate, Date dueDate, Date returnDate) {
- this.book = book;
- this.member = member;
- this.borrowDate = borrowDate;
- this.dueDate = dueDate;
- this.returnDate = returnDate;
- }
-
- public Fines getFine() {
- return fine;
- }
-
- public void setFine(Fines fine) {
- this.fine = fine;
- }
-
- public int getBorrowingId() {
- return borrowingId;
- }
-
- public Book getBook() {
- return book;
- }
-
- public void setBook(Book book) {
- this.book = book;
- }
-
- public Members getMember() {
- return member;
- }
-
- public void setMember(Members 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;
- }
}
\ No newline at end of file
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..90a8a82
--- /dev/null
+++ b/src/main/java/com/libraryman_api/borrowing/BorrowingsDto.java
@@ -0,0 +1,34 @@
+package com.libraryman_api.borrowing;
+
+
+import com.libraryman_api.book.BookDto;
+import com.libraryman_api.fine.Fines;
+import com.libraryman_api.member.MembersDto;
+import lombok.*;
+import java.util.Date;
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@ToString
+
+public class BorrowingsDto {
+
+
+ private int borrowingId;
+
+ private BookDto book;
+
+ private Fines fine;
+
+ private MembersDto member;
+
+ private Date borrowDate;
+
+ private Date dueDate;
+
+ private Date returnDate;
+
+
+}
diff --git a/src/main/java/com/libraryman_api/email/EmailService.java b/src/main/java/com/libraryman_api/email/EmailService.java
index 288723f..5bd0d8e 100644
--- a/src/main/java/com/libraryman_api/email/EmailService.java
+++ b/src/main/java/com/libraryman_api/email/EmailService.java
@@ -8,6 +8,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
diff --git a/src/main/java/com/libraryman_api/fine/Fines.java b/src/main/java/com/libraryman_api/fine/Fines.java
index 48e06c2..7cbfbf3 100644
--- a/src/main/java/com/libraryman_api/fine/Fines.java
+++ b/src/main/java/com/libraryman_api/fine/Fines.java
@@ -1,10 +1,16 @@
package com.libraryman_api.fine;
import jakarta.persistence.*;
+import lombok.*;
import java.math.BigDecimal;
@Entity
+@Getter
+@Setter
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
public class Fines {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
@@ -26,33 +32,4 @@ public class Fines {
@Column(nullable = false)
private boolean paid = false;
- public Fines() {
- }
-
-
- public Fines( BigDecimal amount, boolean paid) {
-
- this.amount = amount;
- this.paid = paid;
- }
-
- public BigDecimal getAmount() {
- return amount;
- }
-
- public void setAmount(BigDecimal amount) {
- this.amount = amount;
- }
-
- public boolean isPaid() {
- return paid;
- }
-
- public void setPaid(boolean paid) {
- this.paid = paid;
- }
-
- public int getFineId() {
- return fineId;
- }
}
diff --git a/src/main/java/com/libraryman_api/member/MemberController.java b/src/main/java/com/libraryman_api/member/MemberController.java
index 246589c..bed41ee 100644
--- a/src/main/java/com/libraryman_api/member/MemberController.java
+++ b/src/main/java/com/libraryman_api/member/MemberController.java
@@ -31,7 +31,7 @@ public MemberController(MemberService memberService) {
* @return a list of {@link Members} representing all members in the library
*/
@GetMapping
- public List getAllMembers() {
+ public List getAllMembers() {
return memberService.getAllMembers();
}
@@ -43,7 +43,7 @@ public List getAllMembers() {
* @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"));
@@ -52,12 +52,13 @@ public ResponseEntity getMemberById(@PathVariable int id) {
/**
* Adds a new library member.
*
- * @param member the {@link Members} object representing the new member
+ * @param memberDto 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 memberDto) {
+
+ return memberService.addMember(memberDto);
}
/**
@@ -65,12 +66,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 memberDtoDetails 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 memberDtoDetails) {
+ return memberService.updateMember(id, memberDtoDetails);
}
/**
diff --git a/src/main/java/com/libraryman_api/member/MemberService.java b/src/main/java/com/libraryman_api/member/MemberService.java
index b73e384..1185bcd 100644
--- a/src/main/java/com/libraryman_api/member/MemberService.java
+++ b/src/main/java/com/libraryman_api/member/MemberService.java
@@ -2,6 +2,9 @@
import com.libraryman_api.exception.ResourceNotFoundException;
import com.libraryman_api.notification.NotificationService;
+import org.modelmapper.ModelMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.Banner;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@@ -26,6 +29,8 @@ public class MemberService {
private final MemberRepository memberRepository;
private final NotificationService notificationService;
+ @Autowired
+ private ModelMapper mapper;
/**
* Constructs a new {@code MemberService} with the specified repositories and services.
@@ -43,8 +48,10 @@ public MemberService(MemberRepository memberRepository, NotificationService noti
*
* @return a list of all members
*/
- public List getAllMembers() {
- return memberRepository.findAll();
+ public List getAllMembers() {
+
+ List membersList = memberRepository.findAll();
+ return membersList.stream().map(members -> mapper.map(members,MembersDto.class)).toList();
}
/**
@@ -53,8 +60,10 @@ public List getAllMembers() {
* @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 member = memberRepository.findById(memberId);
+ return member.map(member1 -> mapper.map(member1,MembersDto.class));
}
/**
@@ -63,14 +72,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 memberDto the member details to be added
* @return the saved member record
*/
- public Members addMember(Members member) {
+ public MembersDto addMember(MembersDto memberDto) {
+ Members member = mapper.map(memberDto, Members.class);
Members currentMember = memberRepository.save(member);
notificationService.accountCreatedNotification(currentMember);
+ return mapper.map(currentMember, MembersDto.class);
- return currentMember;
}
/**
@@ -81,21 +91,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 memberDtoDetails 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 memberDtoDetails) {
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 = memberRepository.save(member);
- notificationService.accountDetailsUpdateNotification(member);
- return member;
+ member.setName(memberDtoDetails.getName());
+ member.setEmail(memberDtoDetails.getEmail());
+ member.setPassword(memberDtoDetails.getPassword());
+ member.setRole(memberDtoDetails.getRole());
+ member.setMembershipDate(memberDtoDetails.getMembershipDate());
+ Members updateMember = memberRepository.save(member);
+ notificationService.accountDetailsUpdateNotification(updateMember);
+ return mapper.map(updateMember,MembersDto.class);
}
/**
diff --git a/src/main/java/com/libraryman_api/member/Members.java b/src/main/java/com/libraryman_api/member/Members.java
index f11b805..1bbfa78 100644
--- a/src/main/java/com/libraryman_api/member/Members.java
+++ b/src/main/java/com/libraryman_api/member/Members.java
@@ -1,11 +1,17 @@
package com.libraryman_api.member;
import jakarta.persistence.*;
+import lombok.*;
import java.util.Date;
@Entity
+@Getter
+@Setter
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
public class Members {
@Id
@@ -34,59 +40,4 @@ public class Members {
private Date membershipDate;
-
- public Members() {
- }
-
- public Members(String name, String email, String password, Role role, Date membershipDate) {
- this.name = name;
- this.email = email;
- this.password = password;
- this.role = role;
- this.membershipDate = membershipDate;
- }
-
- public int getMemberId() {
- return 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;
- }
}
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..4a4c748
--- /dev/null
+++ b/src/main/java/com/libraryman_api/member/MembersDto.java
@@ -0,0 +1,29 @@
+package com.libraryman_api.member;
+
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.util.Date;
+@Getter
+@Setter
+@Builder
+@ToString
+@AllArgsConstructor
+@NoArgsConstructor
+public class MembersDto {
+
+ private int memberId;
+
+ private String name;
+
+ private String email;
+
+ private String password;
+
+ private Role role;
+
+ private Date membershipDate;
+
+
+
+}
diff --git a/src/main/java/com/libraryman_api/notification/NotificationService.java b/src/main/java/com/libraryman_api/notification/NotificationService.java
index 1d37dde..51f1e3e 100644
--- a/src/main/java/com/libraryman_api/notification/NotificationService.java
+++ b/src/main/java/com/libraryman_api/notification/NotificationService.java
@@ -1,10 +1,13 @@
package com.libraryman_api.notification;
import com.libraryman_api.borrowing.Borrowings;
+import com.libraryman_api.borrowing.BorrowingsDto;
import com.libraryman_api.email.EmailSender;
import com.libraryman_api.exception.ResourceNotFoundException;
import com.libraryman_api.member.MemberRepository;
import com.libraryman_api.member.Members;
+import org.modelmapper.ModelMapper;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
@@ -25,6 +28,8 @@ public class NotificationService {
private final EmailSender emailSender;
private final NotificationRepository notificationRepository;
private final MemberRepository memberRepository;
+ @Autowired
+ private ModelMapper mapper;
/**
* Constructs a new {@code NotificationService} with the specified {@link EmailSender},
@@ -137,17 +142,17 @@ public void finePaidNotification(Borrowings borrowing) {
/**
* Sends a notification to a member when a fine is imposed for the late return of a borrowed book.
*
- * @param borrowing the borrowing instance containing information about the overdue book and the fine imposed.
+ * @param borrowingsDto the borrowing instance containing information about the overdue book and the fine imposed.
*/
- public void fineImposedNotification(Borrowings borrowing) {
+ public void fineImposedNotification(BorrowingsDto borrowingsDto) {
Notifications notification = new Notifications();
- notification.setMember(borrowing.getMember());
+ notification.setMember(mapper.map(borrowingsDto.getMember(),Members.class));
notification.setMessage("We hope you enjoyed reading '" +
- borrowing.getBook().getTitle() +
+ borrowingsDto.getBook().getTitle() +
"'. Unfortunately, our records show that the book was returned after the due date of " +
- LocalDateTime.ofInstant(borrowing.getDueDate().toInstant(), ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("dd MMMM yyyy HH:mm")) +
+ LocalDateTime.ofInstant(borrowingsDto.getDueDate().toInstant(), ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("dd MMMM yyyy HH:mm")) +
". As a result, a fine of ₹10 per day has been imposed for the late return.
The total fine amount for this overdue return is ₹" +
- borrowing.getFine().getAmount() +
+ borrowingsDto.getFine().getAmount() +
".
If you have any questions or would like to discuss this matter further, please don't hesitate to contact us.
Thank you for your understanding and for being a valued member of our library.");
notification.setNotificationType(NotificationType.FINE);
notification.setSentDate(new Timestamp(System.currentTimeMillis()));
diff --git a/src/main/java/com/libraryman_api/notification/Notifications.java b/src/main/java/com/libraryman_api/notification/Notifications.java
index 3ef9cb6..66e6603 100644
--- a/src/main/java/com/libraryman_api/notification/Notifications.java
+++ b/src/main/java/com/libraryman_api/notification/Notifications.java
@@ -2,9 +2,17 @@
import com.libraryman_api.member.Members;
import jakarta.persistence.*;
+import lombok.*;
+
import java.sql.Timestamp;
@Entity
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@ToString
public class Notifications {
@Id
@@ -32,58 +40,4 @@ public class Notifications {
- public Notifications() {
- }
-
- public Notifications(Members member, String message, NotificationType notificationType, Timestamp sentDate, NotificationStatus notificationStatus) {
- this.member = member;
- this.message = message;
- this.notificationType = notificationType;
- this.sentDate = sentDate;
- this.notificationStatus = notificationStatus;
- }
-
- public int getNotificationId() {
- return notificationId;
- }
-
- public Members getMember() {
- return member;
- }
-
- public void setMember(Members member) {
- this.member = member;
- }
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
- public NotificationType getNotificationType() {
- return notificationType;
- }
-
- public void setNotificationType(NotificationType notificationType) {
- this.notificationType = notificationType;
- }
-
- public Timestamp getSentDate() {
- return sentDate;
- }
-
- public void setSentDate(Timestamp sentDate) {
- this.sentDate = sentDate;
- }
-
- public NotificationStatus getNotificationStatus() {
- return notificationStatus;
- }
-
- public void setNotificationStatus(NotificationStatus notificationStatus) {
- this.notificationStatus = notificationStatus;
- }
}
diff --git a/src/main/java/com/libraryman_api/projectConfig/ProjectConfiguration.java b/src/main/java/com/libraryman_api/projectConfig/ProjectConfiguration.java
new file mode 100644
index 0000000..7b7db47
--- /dev/null
+++ b/src/main/java/com/libraryman_api/projectConfig/ProjectConfiguration.java
@@ -0,0 +1,13 @@
+package com.libraryman_api.projectConfig;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ProjectConfiguration {
+ @Bean
+ public ModelMapper mapper(){
+ return new ModelMapper();
+ }
+}
diff --git a/src/main/resources/application-development.properties b/src/main/resources/application-development.properties
index c3cf3e5..462665c 100644
--- a/src/main/resources/application-development.properties
+++ b/src/main/resources/application-development.properties
@@ -4,42 +4,45 @@
## Make this file as it was earlier before commiting code
# Change this connection string to this format: jdbc:mysql://{ip_address}:{port}/{database_name}
-spring.datasource.url=jdbc:mysql://localhost:3306/Add_Your_Database_Name
+spring.datasource.url=jdbc:mysql://localhost:3306/DATABASE NAME
## Add your Database Username and Password
-spring.datasource.username=Add_Your_UserName
-spring.datasource.password=Add_Your_Password
+spring.datasource.username=ADD_YOUR_USERNAME
+spring.datasource.password=ADD_YOUR_PASSWORD
# Hibernate Dialect for MySQL 8
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
# Prevent early database interaction
-spring.jpa.properties.hibernate.boot.allow_jdbc_metadata_access=false
+#spring.jpa.properties.hibernate.boot.allow_jdbc_metadata_access=false
spring.jpa.hibernate.ddl-auto=update
-spring.sql.init.mode=never
+spring.jpa.show-sql=true
+#spring.sql.init.mode=never
# Format SQL
-spring.jpa.properties.hibernate.format_sql=true
+#spring.jpa.properties.hibernate.format_sql=true
# Error Handling
-server.error.include-binding-errors=always
-server.error.include-message=always
-server.error.include-stacktrace=never
-server.error.include-exception=true
+#server.error.include-binding-errors=always
+#server.error.include-message=always
+#server.error.include-stacktrace=never
+#server.error.include-exception=true
# Logging for Spring Security
-logging.level.org.springframework.security=TRACE
-
+#logging.level.org.springframework.security=TRACE
# --- Mail Service Setup ---
# I use docker mail service https://hub.docker.com/r/maildev/maildev
# Or Web based Mail service https://mailtrap.io/
-spring.mail.host=Add_Your_Mail_Service_Host
-spring.mail.port=Add_Your_Mail_Service_Port
-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.host=Add_Your_Mail_Service_Host
+#spring.mail.port=Add_Your_Mail_Service_Port
+#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
+
+
+
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index eeefb5c..0530635 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,2 +1,3 @@
spring.application.name=libraryman-api
-spring.profiles.active=${ENV:dev}
\ No newline at end of file
+#spring.profiles.active=${ENV:dev}
+spring.profiles.active=development
\ No newline at end of file