diff --git a/src/main/java/com/libraryman_api/book/BookController.java b/src/main/java/com/libraryman_api/book/BookController.java index 778f7c4..a07d262 100644 --- a/src/main/java/com/libraryman_api/book/BookController.java +++ b/src/main/java/com/libraryman_api/book/BookController.java @@ -9,21 +9,42 @@ /** * REST controller for managing books in the LibraryMan application. - * This controller provides endpoints for performing CRUD operations on books, - * including retrieving all books, getting a book by its ID, adding a new book, - * updating an existing book, and deleting a book. + * + *

This controller provides a set of endpoints for performing CRUD operations + * on books. The operations include retrieving a list of all books, fetching + * a book by its ID, adding a new book, updating an existing book, and deleting + * a book.

+ * + *

All endpoints are accessible under the base URL path /api/books.

+ * + *

Note: The {@link ResourceNotFoundException} is thrown when an invalid book ID is + * provided for retrieval, update, or deletion.

+ * + *

Usage examples for each endpoint can be found in the API documentation.

*/ @RestController @RequestMapping("/api/books") public class BookController { + private final BookService bookService; + + /** + * Constructs a new {@code BookController} with the specified {@code BookService}. + * + * @param bookService the service used to manage book operations + */ @Autowired - private BookService bookService; + public BookController(BookService bookService) { + this.bookService = bookService; + } /** * Retrieves a list of all books in the library. * - * @return a list of {@link Book} objects representing all the books in the library. + *

This endpoint handles GET requests to /api/books and + * returns a list of all books currently available in the library.

+ * + * @return a list of {@link Book} objects representing all books in the library */ @GetMapping public List getAllBooks() { @@ -31,24 +52,30 @@ public List getAllBooks() { } /** - * Retrieves a book by its ID. + * Retrieves a specific book by its ID. + * + *

This endpoint handles GET requests to /api/books/{id} + * and returns the details of the book with the specified ID.

* - * @param id the ID of the book to retrieve. - * @return a {@link ResponseEntity} containing the {@link Book} object, if found. - * @throws ResourceNotFoundException if the book with the specified ID is not found. + * @param id the ID of the book to retrieve + * @return a {@link ResponseEntity} containing the {@link Book} object if found + * @throws ResourceNotFoundException if the book with the specified ID is not found */ @GetMapping("/{id}") public ResponseEntity getBookById(@PathVariable int id) { return bookService.getBookById(id) .map(ResponseEntity::ok) - .orElseThrow(() -> new ResourceNotFoundException("Book not found")); + .orElseThrow(() -> new ResourceNotFoundException("Book with ID " + id + " not found")); } /** * Adds a new book to the library. * - * @param book the {@link Book} object representing the new book to add. - * @return the added {@link Book} object. + *

This endpoint handles POST requests to /api/books + * to add a new book to the library.

+ * + * @param book the {@link Book} object representing the new book to add + * @return the added {@link Book} object */ @PostMapping public Book addBook(@RequestBody Book book) { @@ -58,9 +85,13 @@ public Book addBook(@RequestBody Book book) { /** * 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. - * @return the updated {@link Book} object. + *

This endpoint handles PUT requests to /api/books/{id} + * to update the details of an existing book in the library.

+ * + * @param id the ID of the book to update + * @param bookDetails the updated {@link Book} details + * @return the updated {@link Book} object + * @throws ResourceNotFoundException if the book with the specified ID is not found */ @PutMapping("/{id}") public Book updateBook(@PathVariable int id, @RequestBody Book bookDetails) { @@ -70,7 +101,11 @@ public Book updateBook(@PathVariable int id, @RequestBody Book bookDetails) { /** * Deletes a book from the library by its ID. * - * @param id the ID of the book to delete. + *

This endpoint handles DELETE requests to /api/books/{id} + * to remove a book from the library.

+ * + * @param id the ID of the book to delete + * @throws ResourceNotFoundException if the book with the specified ID is not found */ @DeleteMapping("/{id}") public void deleteBook(@PathVariable int id) { diff --git a/src/main/java/com/libraryman_api/book/BookService.java b/src/main/java/com/libraryman_api/book/BookService.java index 652f01a..c2e5ff5 100644 --- a/src/main/java/com/libraryman_api/book/BookService.java +++ b/src/main/java/com/libraryman_api/book/BookService.java @@ -7,19 +7,21 @@ import java.util.Optional; /** - * Service class for managing books in the LibraryMan system. + * Service class responsible for managing book-related operations in the LibraryMan system. * - *

This service provides methods to perform CRUD operations on books, including - * retrieving all books, retrieving a book by its ID, adding a new book, updating - * an existing book, and deleting a book by its ID.

+ *

This service handles various CRUD operations, such as retrieving all books, fetching + * a book by its ID, adding a new book, updating book details, and deleting a book from the system.

* - *

Each method in this service interacts with the {@link BookRepository} to - * perform database operations.

- * - *

In the case of an invalid book ID being provided, the service throws a + *

All interactions with the database are facilitated via the {@link BookRepository}. + * If a book with a given ID is not found, the service throws a * {@link ResourceNotFoundException}.

- * - * @author Ajay Negi + * + *

Usage examples and further documentation on the book management process + * can be found in the associated API documentation.

+ * + * @see BookRepository + * @see ResourceNotFoundException + * @author */ @Service public class BookService { @@ -27,54 +29,70 @@ public class BookService { private final BookRepository bookRepository; /** - * Constructs a new {@code BookService} with the specified {@code BookRepository}. + * Constructs a new {@code BookService} instance, injecting the required + * {@link BookRepository} to facilitate database operations. * - * @param bookRepository the repository to be used by this service to interact with the database + * @param bookRepository the repository used to access and modify book data in the database */ public BookService(BookRepository bookRepository) { this.bookRepository = bookRepository; } /** - * Retrieves all books from the database. + * Retrieves all books stored in the library. + * + *

This method interacts with the database to fetch a complete list of + * all {@link Book} entities available in the library's collection.

* - * @return a list of all books + * @return a {@link List} of all books in the system */ public List getAllBooks() { return bookRepository.findAll(); } /** - * Retrieves a book by its ID. + * Fetches a specific book by its ID. * - * @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 + *

If the book with the specified ID exists, it is returned as an + * {@link Optional}. If the book is not found, {@code Optional.empty()} is returned.

+ * + * @param bookId the unique identifier of the book to be retrieved + * @return an {@link Optional} containing the book if found, or {@code Optional.empty()} if not */ public Optional getBookById(int bookId) { return bookRepository.findById(bookId); } /** - * Adds a new book to the database. + * Adds a new book to the library. + * + *

This method saves the provided {@link Book} entity to the database. + * The book entity must contain the necessary details such as title, author, + * and publication details.

* - * @param book the book to be added - * @return the saved book + * @param book the {@link Book} object to be added to the library + * @return the saved {@link Book} entity with any auto-generated fields populated (e.g., ID) */ public Book addBook(Book book) { return bookRepository.save(book); } /** - * Updates an existing book with the given details. + * Updates an existing book's details. * - * @param bookId the ID of the book to update - * @param bookDetails the new details for the book - * @return the updated book - * @throws ResourceNotFoundException if the book with the specified ID is not found + *

When called, this method updates the properties of an existing book + * using the new data passed in {@code bookDetails}. If the book with the + * specified ID does not exist, a {@link ResourceNotFoundException} is thrown.

+ * + * @param bookId the unique identifier of the book to update + * @param bookDetails the new details to be applied to the book + * @return the updated {@link Book} object after saving the changes + * @throws ResourceNotFoundException if the book with the specified ID does not exist */ public Book updateBook(int bookId, Book bookDetails) { Book book = bookRepository.findById(bookId) - .orElseThrow(() -> new ResourceNotFoundException("Book not found")); + .orElseThrow(() -> new ResourceNotFoundException("Book with ID " + bookId + " not found")); + book.setTitle(bookDetails.getTitle()); book.setAuthor(bookDetails.getAuthor()); book.setIsbn(bookDetails.getIsbn()); @@ -82,19 +100,22 @@ public Book updateBook(int bookId, Book bookDetails) { book.setPublishedYear(bookDetails.getPublishedYear()); book.setGenre(bookDetails.getGenre()); book.setCopiesAvailable(bookDetails.getCopiesAvailable()); + return bookRepository.save(book); } /** - * Deletes a book by its ID. + * Deletes a book from the library by its ID. * - * @param bookId the ID of the book to delete + *

If the book with the specified ID exists, it is removed from the system. + * If not, a {@link ResourceNotFoundException} is thrown.

+ * + * @param bookId the unique identifier of the book to delete * @throws ResourceNotFoundException if the book with the specified ID is not found */ public void deleteBook(int bookId) { Book book = bookRepository.findById(bookId) - .orElseThrow(() -> new ResourceNotFoundException("Book not found")); + .orElseThrow(() -> new ResourceNotFoundException("Book with ID " + bookId + " not found")); bookRepository.delete(book); } - } diff --git a/src/main/java/com/libraryman_api/email/EmailSender.java b/src/main/java/com/libraryman_api/email/EmailSender.java index d4bd9e7..98c95f5 100644 --- a/src/main/java/com/libraryman_api/email/EmailSender.java +++ b/src/main/java/com/libraryman_api/email/EmailSender.java @@ -3,20 +3,41 @@ import com.libraryman_api.notification.Notifications; /** - * Interface representing an email sending service for the Library Management System. - * Classes implementing this interface are responsible for sending emails - * and updating the status of notifications in the system. + * Interface representing an email sending service for the LibraryMan system. + * + *

This interface defines the contract for sending emails asynchronously to recipients. + * Implementing classes are responsible for constructing and sending the email, as well as + * updating the status of notifications (represented by {@link Notifications}) within the system.

+ * + *

The email sending process involves constructing an email with a subject, body, and recipient + * details, and ensuring that the notification entity is updated based on whether the email + * was successfully sent or encountered an error.

+ * + *

Classes implementing this interface typically use a mailing service such as + * {@link org.springframework.mail.javamail.JavaMailSender} to perform the actual email delivery.

+ * + * @see Notifications */ public interface EmailSender { /** - * Sends an email to the specified recipient with the given body, subject, and notification details. - * + * Sends an email asynchronously to the specified recipient with the provided content and subject. + * + *

This method is responsible for constructing the email message, sending it to the recipient, + * and updating the corresponding notification status within the system based on the outcome. + * The email body can be in HTML or plain text format, and the associated {@link Notifications} entity + * tracks the status of the email (e.g., SENT or FAILED).

+ * + *

In case of errors during the sending process, the implementation of this method should handle + * the exceptions and log any failures accordingly. The notification status should be updated to reflect + * the success or failure of the email operation.

+ * * @param to the email address of the recipient - * @param body the body of the email, typically in HTML or plain text format - * @param subject the subject of the email - * @param notification the notification entity associated with the email being sent, - * used to track the status of the notification + * @param body the content of the email, either in HTML or plain text format + * @param subject the subject line of the email + * @param notification the notification entity representing the email notification in the system, + * used to track the status (SENT or FAILED) of the email being sent + * @throws IllegalStateException if there is an issue sending the email */ void send(String to, String body, String subject, Notifications notification); } diff --git a/src/main/java/com/libraryman_api/email/EmailService.java b/src/main/java/com/libraryman_api/email/EmailService.java index 288723f..0b972d5 100644 --- a/src/main/java/com/libraryman_api/email/EmailService.java +++ b/src/main/java/com/libraryman_api/email/EmailService.java @@ -14,25 +14,36 @@ import org.springframework.stereotype.Service; /** - * Service class for sending emails asynchronously. - * This class handles the construction and sending of MIME email messages. + * Service class responsible for sending emails asynchronously in the LibraryMan system. + * + *

This service manages the creation and sending of MIME email messages, as well as updating the + * status of notifications within the system. It ensures that emails are sent in the background + * using asynchronous execution, allowing the main thread to remain responsive.

+ * + *

In the case of a failed email sending operation, the service logs the error, updates + * the notification status to {@link NotificationStatus#FAILED}, and throws an {@link IllegalStateException}.

+ * + * @see NotificationRepository + * @see JavaMailSender + * @see Notifications + * @see NotificationStatus */ @Service public class EmailService implements EmailSender { private final NotificationRepository notificationRepository; private final JavaMailSender mailSender; - private static final Logger LOGGER = LoggerFactory.getLogger(EmailService.class); @Value("${spring.mail.properties.domain_name}") private String domainName; /** - * Constructs a new {@code EmailService} with the specified {@link NotificationRepository} and {@link JavaMailSender}. + * Constructs a new {@code EmailService} instance, injecting the necessary dependencies + * for sending emails and managing notification entities. * - * @param notificationRepository the repository for managing notification entities - * @param mailSender the mail sender for sending email messages + * @param notificationRepository the repository for storing and managing email notifications + * @param mailSender the {@link JavaMailSender} used for sending emails */ public EmailService(NotificationRepository notificationRepository, JavaMailSender mailSender) { this.notificationRepository = notificationRepository; @@ -40,37 +51,47 @@ public EmailService(NotificationRepository notificationRepository, JavaMailSende } /** - * Sends an email asynchronously to the specified recipient. - * If the email is successfully sent, the notification status is updated to SENT. - * If the email fails to send, the notification status is updated to FAILED and an exception is thrown. + * Sends an email asynchronously to a specified recipient. + * + *

This method creates a MIME message and sends it to the recipient using + * the configured {@link JavaMailSender}. If the email is successfully sent, the + * notification's status is updated to {@link NotificationStatus#SENT}. In case of a failure, + * the status is updated to {@link NotificationStatus#FAILED} and an error is logged.

+ * + *

This method runs asynchronously, meaning the main application flow is not blocked + * while the email is being processed and sent.

* * @param to the recipient's email address - * @param email the content of the email to send - * @param subject the subject of the email - * @param notification the {@link Notifications} object representing the email notification + * @param email the body of the email to be sent (HTML content supported) + * @param subject the subject line of the email + * @param notification the {@link Notifications} object representing the email notification in the system + * @throws IllegalStateException if the email fails to send due to a {@link MessagingException} */ @Override @Async public void send(String to, String email, String subject, Notifications notification) { try { + // Construct the email message MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, "utf-8"); - helper.setText(email, true); - helper.setTo(to); - helper.setSubject(subject); - helper.setFrom(domainName); + helper.setText(email, true); // Set email body (HTML enabled) + helper.setTo(to); // Set recipient email + helper.setSubject(subject); // Set subject + helper.setFrom(domainName); // Set sender's email (from domain) + + // Send the email mailSender.send(mimeMessage); // Update notification status to SENT notification.setNotificationStatus(NotificationStatus.SENT); notificationRepository.save(notification); } catch (MessagingException e) { - LOGGER.error("Failed to send email", e); - - // Update notification status to FAILED + // Log the failure and update notification status to FAILED + LOGGER.error("Failed to send email to {}", to, e); notification.setNotificationStatus(NotificationStatus.FAILED); notificationRepository.save(notification); + // Throw an exception to signal the failure throw new IllegalStateException("Failed to send email", e); } } diff --git a/src/main/java/com/libraryman_api/exception/ErrorDetails.java b/src/main/java/com/libraryman_api/exception/ErrorDetails.java index 29e6112..f635495 100644 --- a/src/main/java/com/libraryman_api/exception/ErrorDetails.java +++ b/src/main/java/com/libraryman_api/exception/ErrorDetails.java @@ -3,58 +3,60 @@ import java.util.Date; /** - * The compiler automatically generates the following members: + * A record representing error details for exceptions in the LibraryMan system. + * + *

The {@code ErrorDetails} record captures essential information about errors + * that occur within the application, such as the time the error occurred, a message + * describing the error, and any additional details that may be helpful for debugging.

+ * + *

The compiler automatically generates several members for this record, including:

*
    *
  • A private final field for each component of the record.
  • *
  • A public constructor with parameters for each component.
  • - *
  • Public getter methods for each component (the method name is the same as the component name).
  • - *
  • A toString() method that includes the names and values of the components.
  • - *
  • An equals() method that checks for equality based on the components.
  • - *
  • A hashCode() method that calculates a hash code based on the components.
  • + *
  • Public getter methods for each component, with names corresponding to the component names.
  • + *
  • A {@code toString()} method that includes the names and values of the components.
  • + *
  • An {@code equals()} method that checks for equality based on the components.
  • + *
  • A {@code hashCode()} method that calculates a hash code based on the components.
  • *
* - * For the ErrorDetails record, the compiler will automatically generate the following members: - *

- * Private final fields: - *

    - *
  • private final Date timestamp;
  • - *
  • private final String message;
  • - *
  • private final String details;
  • - *
- *

- *

- * Public constructor: - *

public ErrorDetails(Date timestamp, String message, String details) { ... }
- *

- *

- * Public getter methods: - *

    - *
  • public Date timestamp() { return timestamp; }
  • - *
  • public String message() { return message; }
  • - *
  • public String details() { return details; }
  • - *
- *

- *

- * toString() method: - *

public String toString() { return "ErrorDetails[timestamp=" + timestamp + ", message=" + message + ", details=" + details + "]"; }
- *

- *

- * equals() method: - *

@Override
- *     public boolean equals(Object obj) {
- *         if (this == obj) return true;
- *         if (obj == null || getClass() != obj.getClass()) return false;
- *         ErrorDetails other = (ErrorDetails) obj;
- *         return timestamp.equals(other.timestamp) && message.equals(other.message) && details.equals(other.details);
- *     }
- *

- *

- * hashCode() method: - *

@Override
- *     public int hashCode() {
- *         return java.util.Objects.hash(timestamp, message, details);
- *     }
- *

+ *

Record Components:

+ *

The following private final fields are automatically generated:

+ *
    + *
  • private final Date timestamp; - The date and time when the error occurred.
  • + *
  • private final String message; - A brief message describing the error.
  • + *
  • private final String details; - Additional details about the error that may be useful for troubleshooting.
  • + *
+ * + *

Public Methods:

+ *

The following public methods are automatically generated for the record:

+ *
    + *
  • public Date timestamp() { return timestamp; } - Returns the timestamp of the error.
  • + *
  • public String message() { return message; } - Returns the error message.
  • + *
  • public String details() { return details; } - Returns any additional error details.
  • + *
+ * + *

Automatically Generated Methods:

+ *

The following methods are also generated:

+ *
    + *
  • toString() method: + *
    public String toString() { return "ErrorDetails[timestamp=" + timestamp + ", message=" + message + ", details=" + details + "]"; }
    + *
  • + *
  • equals() method: + *
    @Override
    + *         public boolean equals(Object obj) {
    + *             if (this == obj) return true;
    + *             if (obj == null || getClass() != obj.getClass()) return false;
    + *             ErrorDetails other = (ErrorDetails) obj;
    + *             return timestamp.equals(other.timestamp) && message.equals(other.message) && details.equals(other.details);
    + *         }
    + *
  • + *
  • hashCode() method: + *
    @Override
    + *         public int hashCode() {
    + *             return java.util.Objects.hash(timestamp, message, details);
    + *         }
    + *
  • + *
*/ public record ErrorDetails(Date timestamp, String message, String details) { -} \ No newline at end of file +} diff --git a/src/main/java/com/libraryman_api/exception/GlobalExceptionHandler.java b/src/main/java/com/libraryman_api/exception/GlobalExceptionHandler.java index 26704ef..542410f 100644 --- a/src/main/java/com/libraryman_api/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/libraryman_api/exception/GlobalExceptionHandler.java @@ -10,25 +10,37 @@ /** * Global exception handler for the LibraryMan API. - * This class provides centralized exception handling across all controllers in the application. - * It handles specific exceptions and returns appropriate HTTP responses. + * + *

This class provides centralized exception handling for all controllers in the application. + * It intercepts specific exceptions thrown during the execution of the application and returns + * appropriate HTTP responses to the client.

+ * + *

The primary purpose of this class is to ensure that the API responds with meaningful error + * messages when exceptions occur, thereby improving the client experience.

*/ @ControllerAdvice public class GlobalExceptionHandler { /** * Handles {@link ResourceNotFoundException} exceptions. - * This method is triggered when a {@code ResourceNotFoundException} is thrown in the application. - * It constructs an {@link ErrorDetails} object containing the exception details and returns - * a {@link ResponseEntity} with an HTTP status of {@code 404 Not Found}. + * + *

This method is triggered when a {@code ResourceNotFoundException} is thrown in the application. + * It constructs an {@link ErrorDetails} object containing the details of the exception and returns + * a {@link ResponseEntity} with an HTTP status of {@code 404 Not Found}.

* - * @param ex the exception that was thrown. - * @param request the current web request in which the exception was thrown. + *

By handling this exception globally, the API ensures that all requests resulting in + * a resource not being found will return a consistent and informative response.

+ * + * @param ex the {@code ResourceNotFoundException} that was thrown. + * @param request the current web request during which the exception occurred. * @return a {@link ResponseEntity} containing the {@link ErrorDetails} and an HTTP status of {@code 404 Not Found}. */ @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) { + // Create an ErrorDetails object to hold error information ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false)); + + // Return a response entity with the error details and HTTP status return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND); } } diff --git a/src/main/java/com/libraryman_api/exception/ResourceNotFoundException.java b/src/main/java/com/libraryman_api/exception/ResourceNotFoundException.java index 56a5840..da97374 100644 --- a/src/main/java/com/libraryman_api/exception/ResourceNotFoundException.java +++ b/src/main/java/com/libraryman_api/exception/ResourceNotFoundException.java @@ -5,27 +5,30 @@ /** * Custom exception class to handle scenarios where a requested resource * is not found in the Library Management System. - * This exception is thrown when an operation fails to locate a resource such as - * a book, member, or borrowing record. + * + *

This exception is thrown when an operation fails to locate a resource such as + * a book, member, or borrowing record.

+ * + *

By using this exception, the application can provide meaningful feedback to clients + * when they attempt to access a resource that does not exist.

*/ public class ResourceNotFoundException extends RuntimeException { /** * The {@code serialVersionUID} is a unique identifier for each version of a serializable class. * It is used during the deserialization process to verify that the sender and receiver of a - * serialized object have loaded classes for that object that are compatible with each other. + * serialized object have loaded classes that are compatible with each other. * - * The {@code serialVersionUID} field is important for ensuring that a serialized class - * (especially when transmitted over a network or saved to disk) can be successfully deserialized, - * even if the class definition changes in later versions. If the {@code serialVersionUID} does not - * match during deserialization, an {@code InvalidClassException} is thrown. + *

Including this field is important for ensuring that a serialized class can be successfully + * deserialized, even if the class definition changes in later versions. If the {@code serialVersionUID} + * does not match during deserialization, an {@code InvalidClassException} is thrown.

* - * This field is optional, but it is good practice to explicitly declare it to prevent - * automatic generation, which could lead to compatibility issues when the class structure changes. + *

This field is optional, but it is good practice to explicitly declare it to prevent + * automatic generation, which could lead to compatibility issues when the class structure changes.

* - * The {@code @Serial} annotation is used here to indicate that this field is related to - * serialization. This annotation is available starting from Java 14 and helps improve clarity - * regarding the purpose of this field. + *

The {@code @Serial} annotation indicates that this field is related to serialization. This + * annotation is available starting from Java 14 and helps improve clarity regarding the purpose + * of this field.

*/ @Serial private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/libraryman_api/fine/Fines.java b/src/main/java/com/libraryman_api/fine/Fines.java index 48e06c2..b52cd33 100644 --- a/src/main/java/com/libraryman_api/fine/Fines.java +++ b/src/main/java/com/libraryman_api/fine/Fines.java @@ -4,54 +4,98 @@ import java.math.BigDecimal; +/** + * Represents a fine in the Library Management System. + * + *

This entity is responsible for storing information about fines incurred by library members, + * including the amount of the fine and whether it has been paid.

+ */ @Entity public class Fines { + + /** + * Unique identifier for the fine. + *

This field is automatically generated using a sequence generator.

+ */ @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE, - generator = "fine_id_generator") - @SequenceGenerator(name = "fine_id_generator", - sequenceName = "fine_id_sequence", - allocationSize = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "fine_id_generator") + @SequenceGenerator(name = "fine_id_generator", sequenceName = "fine_id_sequence", allocationSize = 1) @Column(name = "fine_id") private int fineId; -/** - * precision = 10 means the total number of digits (including decimal places) is 10. - * scale = 2 means the number of decimal places is 2. - * @Column(nullable = false, precision = 10, scale = 2) - * */ - @Column(nullable = false, scale = 2) + /** + * The amount of the fine. + *

This field has a precision of 10, allowing for a total of 10 digits, + * with 2 decimal places. It cannot be null.

+ */ + @Column(nullable = false, precision = 10, scale = 2) private BigDecimal amount; + /** + * Indicates whether the fine has been paid. + *

This field is set to false by default, indicating that the fine is unpaid when created.

+ */ @Column(nullable = false) private boolean paid = false; + /** + * Default constructor for the Fines entity. + */ public Fines() { } - - public Fines( BigDecimal amount, boolean paid) { - + /** + * Constructs a new Fines object with the specified amount and payment status. + * + * @param amount the amount of the fine + * @param paid indicates whether the fine has been paid + */ + public Fines(BigDecimal amount, boolean paid) { this.amount = amount; this.paid = paid; } + /** + * Gets the amount of the fine. + * + * @return the amount of the fine + */ public BigDecimal getAmount() { return amount; } + /** + * Sets the amount of the fine. + * + * @param amount the amount to set + */ public void setAmount(BigDecimal amount) { this.amount = amount; } + /** + * Checks if the fine has been paid. + * + * @return true if the fine has been paid, false otherwise + */ public boolean isPaid() { return paid; } + /** + * Sets the payment status of the fine. + * + * @param paid indicates whether the fine has been paid + */ public void setPaid(boolean paid) { this.paid = paid; } + /** + * Gets the unique identifier of the fine. + * + * @return the fine ID + */ 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..26ed546 100644 --- a/src/main/java/com/libraryman_api/member/MemberController.java +++ b/src/main/java/com/libraryman_api/member/MemberController.java @@ -7,8 +7,13 @@ import java.util.List; /** - * REST controller for managing library members. - * This controller provides endpoints for performing CRUD operations on members. + * REST controller for handling CRUD operations related to library members. + * + *

This controller provides API endpoints for retrieving, creating, updating, + * and deleting library members. It interacts with {@link MemberService} to + * manage these operations and uses standard HTTP responses for success or error scenarios.

+ * + * @see MemberService */ @RestController @RequestMapping("/api/members") @@ -19,16 +24,18 @@ public class MemberController { /** * Constructs a new {@code MemberController} with the specified {@link MemberService}. * - * @param memberService the service to handle member-related operations + * @param memberService the service responsible for managing member-related operations */ public MemberController(MemberService memberService) { this.memberService = memberService; } /** - * Retrieves a list of all library members. + * Retrieves a list of all members in the library system. * - * @return a list of {@link Members} representing all members in the library + *

This method handles HTTP GET requests and returns a list of all members.

+ * + * @return a list of {@link Members} representing all members in the system */ @GetMapping public List getAllMembers() { @@ -36,11 +43,14 @@ public List getAllMembers() { } /** - * Retrieves a library member by their ID. - * If the member is not found, a {@link ResourceNotFoundException} is thrown. + * Retrieves a member by their ID. + * + *

This method handles HTTP GET requests with a member ID as a path variable. + * If the member is not found, a {@link ResourceNotFoundException} is thrown.

* * @param id the ID of the member to retrieve - * @return a {@link ResponseEntity} containing the found {@link Members} object + * @return a {@link ResponseEntity} containing the member data if found + * @throws ResourceNotFoundException if the member with the given ID does not exist */ @GetMapping("/{id}") public ResponseEntity getMemberById(@PathVariable int id) { @@ -50,10 +60,12 @@ public ResponseEntity getMemberById(@PathVariable int id) { } /** - * Adds a new library member. + * Adds a new member to the library system. + * + *

This method handles HTTP POST requests to create a new member record.

* * @param member the {@link Members} object representing the new member - * @return the added {@link Members} object + * @return the newly added {@link Members} object */ @PostMapping public Members addMember(@RequestBody Members member) { @@ -61,12 +73,15 @@ public Members addMember(@RequestBody Members member) { } /** - * Updates an existing library member. - * If the member is not found, a {@link ResourceNotFoundException} is thrown. + * Updates the details of an existing member. + * + *

This method handles HTTP PUT requests to update a member's details. + * 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 * @return the updated {@link Members} object + * @throws ResourceNotFoundException if the member with the given ID does not exist */ @PutMapping("/{id}") public Members updateMember(@PathVariable int id, @RequestBody Members memberDetails) { @@ -74,10 +89,13 @@ public Members updateMember(@PathVariable int id, @RequestBody Members memberDet } /** - * Deletes a library member by their ID. - * If the member is not found, a {@link ResourceNotFoundException} is thrown. + * Deletes a member by their ID. + * + *

This method handles HTTP DELETE requests to remove a member from the system. + * If the member is not found, a {@link ResourceNotFoundException} is thrown.

* * @param id the ID of the member to delete + * @throws ResourceNotFoundException if the member with the given ID does not exist */ @DeleteMapping("/{id}") public void deleteMember(@PathVariable int id) { diff --git a/src/main/java/com/libraryman_api/member/MemberService.java b/src/main/java/com/libraryman_api/member/MemberService.java index b73e384..7d64fc6 100644 --- a/src/main/java/com/libraryman_api/member/MemberService.java +++ b/src/main/java/com/libraryman_api/member/MemberService.java @@ -7,19 +7,20 @@ import java.util.Optional; /** - * Service class responsible for managing member-related operations in the LibraryMan system. + * Service class responsible for handling operations related to library members, + * including retrieving, adding, updating, and deleting member records. * - *

This service provides methods for retrieving, adding, updating, and deleting member records. - * It integrates with the {@link NotificationService} to send notifications related to member - * activities such as account creation, updates, and deletions.

+ *

Integrates with {@link NotificationService} to manage notifications for + * various member-related actions such as account creation, updates, and deletions.

* - *

Each method interacts with the {@link MemberRepository} to perform database operations, ensuring - * proper transactional behavior and consistency.

+ *

Uses {@link MemberRepository} for database interactions. In cases where a + * member is not found, a {@link ResourceNotFoundException} is thrown.

* - *

In cases where a member record is not found, the service throws a - * {@link ResourceNotFoundException} to indicate the error.

+ *

This service ensures consistency and proper transaction management + * while interacting with the database.

* - * @author Ajay Negi + * @see MemberRepository + * @see NotificationService */ @Service public class MemberService { @@ -28,10 +29,10 @@ public class MemberService { private final NotificationService notificationService; /** - * Constructs a new {@code MemberService} with the specified repositories and services. + * Constructs a {@code MemberService} with the necessary dependencies. * - * @param memberRepository the repository for managing member records - * @param notificationService the service for sending notifications related to member activities + * @param memberRepository the repository used for managing member records + * @param notificationService the service used for sending notifications related to member activities */ public MemberService(MemberRepository memberRepository, NotificationService notificationService) { this.memberRepository = memberRepository; @@ -39,50 +40,43 @@ public MemberService(MemberRepository memberRepository, NotificationService noti } /** - * Retrieves all members from the database. + * Retrieves all members from the system. * - * @return a list of all members + * @return a list of all members present in the library database */ public List getAllMembers() { return memberRepository.findAll(); } /** - * Retrieves a member record by its ID. + * Retrieves a member by their ID. * * @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 + * @return an {@code Optional} containing the member if found, otherwise {@code Optional.empty()} */ public Optional getMemberById(int memberId) { return memberRepository.findById(memberId); } /** - * Adds a new member to the library system. + * Adds a new member to the system and sends an account creation notification. * - *

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 - * @return the saved member record + * @param member the new member to add to the system + * @return the saved member entity */ public Members addMember(Members member) { Members currentMember = memberRepository.save(member); notificationService.accountCreatedNotification(currentMember); - return currentMember; } /** - * Updates an existing member's details. - * - *

This method updates the member's details in the database. It throws a - * {@link ResourceNotFoundException} if the member is not found. After updating, - * a notification about the account details update is sent.

+ * Updates an existing member's details. Throws a {@link ResourceNotFoundException} if the member + * is not found. After updating, an account details update notification is sent. * * @param memberId the ID of the member to update * @param memberDetails the updated member details - * @return the updated member record + * @return the updated member entity * @throws ResourceNotFoundException if the member is not found */ public Members updateMember(int memberId, Members memberDetails) { @@ -99,11 +93,8 @@ public Members updateMember(int memberId, Members memberDetails) { } /** - * Deletes a member from the library system. - * - *

This method deletes the member record from the database after ensuring that - * the member has no outstanding fines or borrowed books. Before deletion, it - * sends a notification about the account deletion.

+ * Deletes a member from the system after ensuring no outstanding fines or borrowed books exist. + * Sends an account deletion notification before deletion. * * @param memberId the ID of the member to delete * @throws ResourceNotFoundException if the member is not found @@ -113,7 +104,6 @@ public void deleteMember(int memberId) { .orElseThrow(() -> new ResourceNotFoundException("Member not found")); // TODO: Implement logic to check if the member has any outstanding fines or borrowed books. - // If there are no pending obligations, delete all related notifications, borrowings, and fines. notificationService.accountDeletionNotification(member); memberRepository.delete(member);