Skip to content

Commit

Permalink
refactor: resolve merge conflicts and update application files
Browse files Browse the repository at this point in the history
  • Loading branch information
Guhapriya01 committed Oct 14, 2024
2 parents dbde4e5 + 186da19 commit 12bae50
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 39 deletions.
41 changes: 25 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@

LibraryMan is a user-friendly software solution for schools, companies, and libraries to efficiently manage book collections, track borrowing, and monitor due dates. It streamlines operations, reduces errors, and enhances the lending experience, making it easy to maintain a well-organized library.

Checkout [Frontend](https://github.com/ajaynegi45/LibraryMan) Repository
#### Checkout [Frontend](https://github.com/ajaynegi45/LibraryMan) Repository

<br>

## Project Structure 📂
## Project Structure 📂
Checkout [Project Structure](https://github.com/ajaynegi45/LibraryMan-API/tree/main/project-structure) Diagram

<br>

## API Endpoints 🔗

#### Learn More
Expand All @@ -19,8 +15,6 @@ Want to know more about our API endpoints? Check out our [API Documentation](htt
#### Test Endpoints
Ready to try out our API endpoints? Use [Postman Documentation](https://documenter.getpostman.com/view/28691426/2sAXjJ6D7L) to test and explore our APIs.

<br>

## How to Run the Project 💨

1. Ensure you have Java and MySQL installed on your system.
Expand All @@ -29,19 +23,13 @@ Ready to try out our API endpoints? Use [Postman Documentation](https://document
4. Set up the MySQL database and update the database configurations in the `application-development.properties` file.
5. Build and run the project using the IDE or by running `mvn spring-boot:run` command from the project root directory.

<br>

## ‼️ Important Note ‼️

- You need to set up the database and make sure the application properties are correctly configured to run the project successfully.

<br>

## Upcoming Update
Adding more features, error handling, authentication, and security measures.

<br>

## Contributing 🤗

Feel free to explore and use these project. If you encounter any issues or have suggestions for improvements, please feel free to contribute or reach out for assistance.
Expand All @@ -52,8 +40,6 @@ See [`contributing.md`](https://github.com/ajaynegi45/Library-API/blob/main/Cont

Please adhere to this project's [`code_of_conduct.md`](https://github.com/ajaynegi45/Library-API/blob/main/code_of_conduct.md).

<br>

## Contact Information 📧

If you have any questions or would like to connect, please don't hesitate to reach out. I'd be more than happy to chat and learn from your experiences too.
Expand All @@ -64,6 +50,29 @@ If you have any questions or would like to connect, please don't hesitate to rea
## Contributors
<img src="https://contrib.rocks/image?repo=ajaynegi45/LibraryMan-API" />

---

<table>
<thead align="center">
<tr border: 2px;>
<td><b>🌟 Stars</b></td>
<td><b>🍴 Forks</b></td>
<td><b>🐛 Issues</b></td>
<td><b>🔔 Open PRs</b></td>
<td><b>🔕 Close PRs</b></td>
</tr>
</thead>
<tbody>
<tr>
<td><img alt="Stars" src="https://img.shields.io/github/stars/ajaynegi45/LibraryMan-API?style=flat&logo=github"/></td>
<td><img alt="Forks" src="https://img.shields.io/github/forks/ajaynegi45/LibraryMan-API?style=flat&logo=github"/></td>
<td><img alt="Issues" src="https://img.shields.io/github/issues/ajaynegi45/LibraryMan-API?style=flat&logo=github"/></td>
<td><img alt="Open Pull Requests" src="https://img.shields.io/github/issues-pr/ajaynegi45/LibraryMan-API?style=flat&logo=github"/></td>
<td><img alt="Close Pull Requests" src="https://img.shields.io/github/issues-pr-closed/ajaynegi45/LibraryMan-API?style=flat&color=green&logo=github"/></td>
</tr>
</tbody>
</table>


### Stargazers

Expand Down
2 changes: 1 addition & 1 deletion api-docs/borrowings-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ The Borrowings API provides a set of endpoints to manage the borrowing and retur

### 3. **Pay Fine**

**Endpoint:** `/borrowings/{id}/pay-fine`
**Endpoint:** `/borrowings/{id}/pay`
**Method:** `PUT`
**Description:** Pays the fine associated with a borrowing.

Expand Down
14 changes: 9 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,36 +35,36 @@
</properties>
<dependencies>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
Expand All @@ -84,7 +84,6 @@
<scope>test</scope>
</dependency>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
Expand All @@ -94,17 +93,22 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>

</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/com/libraryman_api/book/BookService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.util.Optional;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mapping.PropertyReferenceException;
Expand Down Expand Up @@ -46,6 +49,8 @@ public BookService(BookRepository bookRepository) {
* @return a {@link Page} of {@link Book} representing all books
* @throws InvalidSortFieldException if an invalid sortBy field is specified
*/

@Cacheable(value = "books")
public Page<BookDto> getAllBooks(Pageable pageable) {
try {
Page<Book> pagedBooks = bookRepository.findAll(pageable);
Expand All @@ -61,6 +66,8 @@ public Page<BookDto> 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
*/

@Cacheable(value = "books", key ="#bookId")
public Optional<BookDto> getBookById(int bookId) {

Optional<Book> bookById = bookRepository.findById(bookId);
Expand All @@ -73,6 +80,8 @@ public Optional<BookDto> getBookById(int bookId) {
* @param bookDto the book to be added
* @return the saved book
*/

@CacheEvict(value = "books", allEntries = true)
public BookDto addBook(BookDto bookDto) {
Book book = DtoToEntity(bookDto);
Book savedBook = bookRepository.save(book);
Expand All @@ -87,6 +96,11 @@ public BookDto addBook(BookDto bookDto) {
* @return the updated book
* @throws ResourceNotFoundException if the book with the specified ID is not found
*/

@Caching(evict = {
@CacheEvict(value = "books", key = "#bookId"), // Evict the specific book cache
@CacheEvict(value = "books", allEntries = true) // Evict the list cache
})
public BookDto updateBook(int bookId, BookDto bookDtoDetails) {
Book book = bookRepository.findById(bookId)
.orElseThrow(() -> new ResourceNotFoundException("Book not found"));
Expand All @@ -107,6 +121,11 @@ public BookDto updateBook(int bookId, BookDto bookDtoDetails) {
* @param bookId the ID of the book to delete
* @throws ResourceNotFoundException if the book with the specified ID is not found
*/

@Caching(evict = {
@CacheEvict(value = "books", key = "#bookId"), // Evict the specific book cache
@CacheEvict(value = "books", allEntries = true) // Evict the list cache
})
public void deleteBook(int bookId) {
Book book = bookRepository.findById(bookId)
.orElseThrow(() -> new ResourceNotFoundException("Book not found"));
Expand Down
24 changes: 15 additions & 9 deletions src/main/java/com/libraryman_api/borrowing/BorrowingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ public Optional<BorrowingsDto> getBorrowingById(int borrowingId) {
@Transactional
public synchronized BorrowingsDto borrowBook(BorrowingsDto borrowing) {
Optional<BookDto> bookDto = bookService.getBookById(borrowing.getBook().getBookId());
Optional<MembersDto> member = memberService.getMemberById(borrowing.getMember().getMemberId());
if (bookDto.isPresent() && member.isPresent()) {
Optional<MembersDto> memberDto = memberService.getMemberById(borrowing.getMember().getMemberId());
if (bookDto.isPresent() && memberDto.isPresent()) {
Book bookEntity = bookService.DtoToEntity(bookDto.get());
Members memberEntity = memberService.DtoEntity(member.get());
Members memberEntity = memberService.DtoEntity(memberDto.get());

if (bookEntity.getCopiesAvailable() > 0) {
updateBookCopies(borrowing.getBook().getBookId(), "REMOVE", 1);
updateBookCopies(bookDto, "REMOVE", 1);
borrowing.setBorrowDate(new Date());
borrowing.setBook(bookService.EntityToDto(bookEntity));
borrowing.setMember(memberService.EntityToDto(memberEntity));
Expand Down Expand Up @@ -149,7 +149,10 @@ public synchronized BorrowingsDto borrowBook(BorrowingsDto borrowing) {
public synchronized BorrowingsDto returnBook(int borrowingId) {
BorrowingsDto borrowingsDto = getBorrowingById(borrowingId)
.orElseThrow(() -> new ResourceNotFoundException("Borrowing not found"));

Optional<MembersDto> memberDto = memberService.getMemberById(borrowingsDto.getMember().getMemberId());
if(!memberDto.isPresent()){
throw new ResourceNotFoundException("Member not found");
}
if (borrowingsDto.getReturnDate() != null) {
throw new ResourceNotFoundException("Book has already been returned");
}
Expand All @@ -166,7 +169,8 @@ public synchronized BorrowingsDto returnBook(int borrowingId) {
}

borrowingsDto.setReturnDate(new Date());
updateBookCopies(borrowingsDto.getBook().getBookId(), "ADD", 1);
Optional<BookDto> bookDto = bookService.getBookById(borrowingsDto.getBook().getBookId());
updateBookCopies(bookDto, "ADD", 1);
notificationService.bookReturnedNotification(DtoToEntity(borrowingsDto));
borrowingRepository.save(DtoToEntity(borrowingsDto));
return borrowingsDto;
Expand Down Expand Up @@ -197,6 +201,10 @@ private Fines imposeFine(Borrowings borrowing) {
public String payFine(int borrowingId) {
BorrowingsDto borrowingsDto = getBorrowingById(borrowingId)
.orElseThrow(() -> new ResourceNotFoundException("Borrowing not found"));
Optional<MembersDto> memberDto = memberService.getMemberById(borrowingsDto.getMember().getMemberId());
if(!memberDto.isPresent()){
throw new ResourceNotFoundException("Member not found");
}
Fines fine = borrowingsDto.getFine();

if (fine != null && !fine.isPaid()) {
Expand All @@ -222,9 +230,7 @@ public String payFine(int borrowingId) {
* @param numberOfCopies the number of copies to add or remove
* @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<BookDto> bookDto = bookService.getBookById(bookId);

public void updateBookCopies(Optional<BookDto> bookDto, String operation, int numberOfCopies) {
if (bookDto.isPresent()) {
Book bookEntity = bookService.DtoToEntity(bookDto.get());
if (operation.equals("ADD")) {
Expand Down
14 changes: 12 additions & 2 deletions src/main/java/com/libraryman_api/member/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.Optional;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mapping.PropertyReferenceException;
Expand Down Expand Up @@ -67,6 +69,8 @@ public Page<MembersDto> 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
*/

@Cacheable(value = "members", key = "#memberId")
public Optional<MembersDto> getMemberById(int memberId) {

Optional<Members> memberById = memberRepository.findById(memberId);
Expand All @@ -85,7 +89,8 @@ public Optional<MembersDto> getMemberById(int memberId) {
public MembersDto addMember(MembersDto membersDto) {
Members member = DtoEntity(membersDto);
Members currentMember = memberRepository.save(member);
notificationService.accountCreatedNotification(currentMember);
if(currentMember!=null)
notificationService.accountCreatedNotification(currentMember);

return EntityToDto(currentMember);
}
Expand All @@ -102,6 +107,8 @@ public MembersDto addMember(MembersDto membersDto) {
* @return the updated member record
* @throws ResourceNotFoundException if the member is not found
*/

@CacheEvict(value = "members", key = "#memberId")
public MembersDto updateMember(int memberId, MembersDto membersDtoDetails) {
Members member = memberRepository.findById(memberId)
.orElseThrow(() -> new ResourceNotFoundException("Member not found"));
Expand All @@ -111,7 +118,8 @@ public MembersDto updateMember(int memberId, MembersDto membersDtoDetails) {
member.setRole(membersDtoDetails.getRole());
member.setMembershipDate(membersDtoDetails.getMembershipDate());
member = memberRepository.save(member);
notificationService.accountDetailsUpdateNotification(member);
if(member!=null)
notificationService.accountDetailsUpdateNotification(member);
return EntityToDto(member);
}

Expand All @@ -125,6 +133,8 @@ public MembersDto updateMember(int memberId, MembersDto membersDtoDetails) {
* @param memberId the ID of the member to delete
* @throws ResourceNotFoundException if the member is not found
*/

@CacheEvict(value = "members", key = "#memberId")
public void deleteMember(int memberId) {
Members member = memberRepository.findById(memberId)
.orElseThrow(() -> new ResourceNotFoundException("Member not found"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
Expand All @@ -29,6 +32,7 @@ public class NotificationService {
private final EmailSender emailSender;
private final NotificationRepository notificationRepository;
private final MemberRepository memberRepository;
private static final Logger LOGGER = LoggerFactory.getLogger(NotificationService.class);

/**
* Constructs a new {@code NotificationService} with the specified {@link EmailSender},
Expand Down Expand Up @@ -201,14 +205,11 @@ public void bookReturnedNotification(Borrowings borrowing) {
* @param notification the notification instance containing information about the notification.
*/
private void sendNotification(Notifications notification) {
Members member = memberRepository.findByMemberId(notification.getMember().getMemberId())
.orElseThrow(() -> new ResourceNotFoundException("Member not found"));

emailSender.send(
member.getEmail(),
notification.getMember().getEmail(),
buildEmail(
subject(notification.getNotificationType()),
member.getName(),
notification.getMember().getName(),
notification.getMessage()
),
subject(notification.getNotificationType()),
Expand All @@ -234,7 +235,13 @@ public void sendDueDateReminders(){

// Send reminders for each borrowing
for (Borrowings borrowing : borrowingsDueSoon) {
reminderNotification(borrowing);
try {
Optional<Members> member = memberRepository.findByMemberId(borrowing.getMember().getMemberId());
if(member.isPresent())
reminderNotification(borrowing);
} catch (ResourceNotFoundException e) {
LOGGER.error("Member not found for memberId: " + borrowing.getMember().getMemberId(), e);
}
}
}

Expand Down

0 comments on commit 12bae50

Please sign in to comment.