Skip to content

Commit

Permalink
midified: package hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
siuyunyip committed Nov 7, 2023
1 parent ac179c6 commit a805eaa
Show file tree
Hide file tree
Showing 21 changed files with 188 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.codemagician.onlinelibrary.enums;
package com.codemagician.onlinelibrary.common.enums;

/**
* @author Siuyun Yip
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.codemagician.onlinelibrary.enums;
package com.codemagician.onlinelibrary.common.enums;

/**
* @author Siuyun Yip
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.codemagician.onlinelibrary.exception;
package com.codemagician.onlinelibrary.common.exception;

import com.codemagician.onlinelibrary.enums.MsgEnum;
import com.codemagician.onlinelibrary.common.enums.MsgEnum;

/**
* @author Siuyun Yip
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.codemagician.onlinelibrary.exception;
package com.codemagician.onlinelibrary.common.exception;

import com.codemagician.onlinelibrary.enums.MsgEnum;
import com.codemagician.onlinelibrary.common.enums.MsgEnum;

/**
* @author Siuyun Yip
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.codemagician.onlinelibrary.exception;
package com.codemagician.onlinelibrary.common.exception;

import com.codemagician.onlinelibrary.enums.MsgEnum;
import com.codemagician.onlinelibrary.common.enums.MsgEnum;

/**
* @author Siuyun Yip
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.codemagician.onlinelibrary.handler;
package com.codemagician.onlinelibrary.common.exception.handler;

import com.codemagician.onlinelibrary.enums.MsgEnum;
import com.codemagician.onlinelibrary.exception.BusinessException;
import com.codemagician.onlinelibrary.exception.NotFoundException;
import com.codemagician.onlinelibrary.common.exception.BusinessException;
import com.codemagician.onlinelibrary.common.exception.NotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.codemagician.onlinelibrary.domain.req.LoginReq;
import com.codemagician.onlinelibrary.domain.req.SignupReq;
import com.codemagician.onlinelibrary.domain.rsp.JwtRsp;
import com.codemagician.onlinelibrary.enums.MsgEnum;
import com.codemagician.onlinelibrary.common.enums.MsgEnum;
import com.codemagician.onlinelibrary.service.UserService;
import com.codemagician.onlinelibrary.util.ResponseWrapper;
import jakarta.validation.Valid;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.codemagician.onlinelibrary.controller;

import com.codemagician.onlinelibrary.enums.MsgEnum;
import com.codemagician.onlinelibrary.domain.rsp.CurrentLoansRsp;
import com.codemagician.onlinelibrary.common.enums.MsgEnum;
import com.codemagician.onlinelibrary.security.jwt.JwtUtils;
import com.codemagician.onlinelibrary.service.BookService;
import com.codemagician.onlinelibrary.domain.vo.BookVO;
Expand Down Expand Up @@ -107,6 +108,7 @@ public ResponseEntity checkoutBook(@RequestParam Long bookId) {
return ResponseWrapper.build(MsgEnum.SUCCESS.getMsg(), HttpStatus.OK, book);
}


/**
* check the checkout state of the book
* /api/books/secure/ischeckout/byuser/?bookId=?
Expand All @@ -123,6 +125,33 @@ public ResponseEntity validateCheckout(@RequestParam Long bookId) {
return ResponseWrapper.build(MsgEnum.SUCCESS.getMsg(), HttpStatus.OK, isCheckout);
}

@GetMapping("/secure/currentloans")
@PreAuthorize("hasRole('USER')")
public ResponseEntity currentLoans() {
Long userId = jwtUtils.getUserIdFromContext();
List<CurrentLoansRsp> currentLoansRspList = bookService.currentLoans(userId);
return ResponseWrapper.build(MsgEnum.SUCCESS.getMsg(), HttpStatus.OK, currentLoansRspList);
}

@PutMapping("/secure/return")
@PreAuthorize("hasRole('USER')")
public ResponseEntity returnBook(@RequestParam Long bookId) {
Long userId = jwtUtils.getUserIdFromContext();
bookService.returnBook(bookId, userId);

return ResponseWrapper.success();
}

@PutMapping("/secure/renew/loan")
@PreAuthorize("hasRole('USER')")
public ResponseEntity renewLoan(@RequestParam Long bookId) {
Long userId = jwtUtils.getUserIdFromContext();
bookService.renewLoan(bookId, userId);

return ResponseWrapper.success();
}


/**
* get the number of loans of book for the user
* /api/books/secure/loans/count
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.codemagician.onlinelibrary.domain.req.LeaveReviewReq;
import com.codemagician.onlinelibrary.domain.rsp.ReviewWithUserInfoRsp;
import com.codemagician.onlinelibrary.enums.MsgEnum;
import com.codemagician.onlinelibrary.common.enums.MsgEnum;
import com.codemagician.onlinelibrary.security.jwt.JwtUtils;
import com.codemagician.onlinelibrary.service.ReviewService;
import com.codemagician.onlinelibrary.util.ResponseWrapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.codemagician.onlinelibrary.controller;

import com.codemagician.onlinelibrary.domain.vo.UserVO;
import com.codemagician.onlinelibrary.enums.MsgEnum;
import com.codemagician.onlinelibrary.common.enums.MsgEnum;
import com.codemagician.onlinelibrary.security.jwt.JwtUtils;
import com.codemagician.onlinelibrary.service.UserService;
import com.codemagician.onlinelibrary.util.ResponseWrapper;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.codemagician.onlinelibrary.domain.entity.CheckoutDO;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

/**
* @author Siuyun Yip
* @version 1.0
Expand All @@ -14,4 +16,6 @@ public interface CheckoutRepository extends JpaRepository<CheckoutDO, Long> {
Boolean existsByUserIdAndBookId(Long userId, Long bookId);

Integer countByUserId(Long userId);

List<CheckoutDO> findByUserId(Long userId);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.codemagician.onlinelibrary.dao.repo;

import com.codemagician.onlinelibrary.domain.entity.RoleDO;
import com.codemagician.onlinelibrary.enums.RoleEnum;
import com.codemagician.onlinelibrary.common.enums.RoleEnum;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.codemagician.onlinelibrary.domain.entity;

import com.codemagician.onlinelibrary.enums.RoleEnum;
import com.codemagician.onlinelibrary.common.enums.RoleEnum;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.codemagician.onlinelibrary.security.jwt;

import com.codemagician.onlinelibrary.exception.AccessException;
import com.codemagician.onlinelibrary.common.exception.AccessException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
* @author Siuyun Yip
* @version 1.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.codemagician.onlinelibrary.security.jwt;

import com.codemagician.onlinelibrary.exception.AccessException;
import com.codemagician.onlinelibrary.common.exception.AccessException;
import com.codemagician.onlinelibrary.security.services.UserDetailsServiceImpl;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.codemagician.onlinelibrary.domain.entity.UserDO;
import com.codemagician.onlinelibrary.dao.repo.UserRepository;
import com.codemagician.onlinelibrary.exception.AccessException;
import com.codemagician.onlinelibrary.common.exception.AccessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.codemagician.onlinelibrary.service;

import com.codemagician.onlinelibrary.domain.rsp.CurrentLoansRsp;
import com.codemagician.onlinelibrary.domain.vo.BookVO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand Down Expand Up @@ -58,6 +59,30 @@ public interface BookService {
*/
Boolean isCheckout(Long userId, Long bookId);

/**
* get loaned books by userId
*
* @param userId
* @return
*/
List<CurrentLoansRsp> currentLoans(Long userId);

/**
* return book
*
* @param bookId
* @param userId
*/
void returnBook(Long bookId, Long userId);

/**
* renew loan for user
*
* @param bookId
* @param userId
*/
void renewLoan(Long bookId, Long userId);

/**
* get the number of current loans for user
* @param userId
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,46 @@
package com.codemagician.onlinelibrary.service.impl;

import com.codemagician.onlinelibrary.dao.repo.HistoryRepository;
import com.codemagician.onlinelibrary.domain.entity.BookDO;
import com.codemagician.onlinelibrary.domain.entity.CheckoutDO;
import com.codemagician.onlinelibrary.dao.repo.BookRepository;
import com.codemagician.onlinelibrary.dao.repo.CheckoutRepository;
import com.codemagician.onlinelibrary.exception.BusinessException;
import com.codemagician.onlinelibrary.exception.NotFoundException;
import com.codemagician.onlinelibrary.domain.entity.HistoryDO;
import com.codemagician.onlinelibrary.domain.rsp.CurrentLoansRsp;
import com.codemagician.onlinelibrary.common.exception.BusinessException;
import com.codemagician.onlinelibrary.common.exception.NotFoundException;
import com.codemagician.onlinelibrary.service.BookService;
import com.codemagician.onlinelibrary.domain.vo.BookVO;
import com.codemagician.onlinelibrary.util.ObjectMapperUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class BookServiceImpl implements BookService {

private Logger logger = LoggerFactory.getLogger(BookServiceImpl.class);

@Autowired
private BookRepository bookRepository;
@Autowired
private CheckoutRepository checkoutRepository;
@Autowired
private HistoryRepository historyRepository;

@Override
public List<String> getAllCategories() {
Expand Down Expand Up @@ -90,6 +104,88 @@ public Boolean isCheckout(Long userId, Long bookId) {
return checkoutRepository.existsByUserIdAndBookId(userId, bookId);
}

@Override
public List<CurrentLoansRsp> currentLoans(Long userId) {

List<CheckoutDO> checkouts = checkoutRepository.findByUserId(userId);

List<Long> bookIdList = new ArrayList<>();
for (CheckoutDO checkout : checkouts) {
bookIdList.add(checkout.getBookId());
}
List<BookDO> books = bookRepository.findAllById(bookIdList);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

List<CurrentLoansRsp> currentLoansRspList = new ArrayList<>();
for (BookDO book : books) {
Optional<CheckoutDO> checkout = checkouts.stream().filter(c -> c.getBookId() == book.getId()).findFirst();
if (checkout.isPresent()) {
try {
BookVO bookVO = ObjectMapperUtils.map(book, BookVO.class);

Date returnDate = sdf.parse(checkout.get().getReturnDate());
Date currDate = sdf.parse(LocalDate.now().toString());
TimeUnit time = TimeUnit.DAYS;
long diffInTime = time.convert(returnDate.getTime() - currDate.getTime(), TimeUnit.MILLISECONDS);

currentLoansRspList.add(new CurrentLoansRsp(bookVO, (int) diffInTime));
} catch (ParseException e) {
logger.error("date parsed error while getting loans ", e);
throw new RuntimeException(e);
}
}
}

return currentLoansRspList;
}

@Override
public void returnBook(Long bookId, Long userId) {
Optional<BookDO> bookOpt = bookRepository.findById(bookId);
if (!bookOpt.isPresent()) {
throw new NotFoundException("Book doesn't exist");
}
BookDO book = bookOpt.get();

CheckoutDO checkout = checkoutRepository.findByUserIdAndBookId(userId, bookId);
if (null == checkout) {
throw new NotFoundException("Book is not checked out by user");
}

// increment book stock by 1
book.setCopiesAvailable(book.getCopiesAvailable() + 1);
bookRepository.save(book);

// delete checkout record
checkoutRepository.deleteById(checkout.getId());

// add checkout to history
HistoryDO history = new HistoryDO(userId, checkout.getCheckoutDate(), LocalDate.now().toString(), book.getTitle(), book.getAuthor(), book.getDescription(), book.getImg());
historyRepository.save(history);
}

@Override
public void renewLoan(Long bookId, Long userId) {
CheckoutDO checkout = checkoutRepository.findByUserIdAndBookId(userId, bookId);
if (null == checkout) {
throw new NotFoundException("Book is not checked out by user");
}

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date returnDate = sdf.parse(checkout.getReturnDate());
Date now = sdf.parse(LocalDate.now().toString());
if (returnDate.compareTo(now) > 0 || returnDate.compareTo(now) == 0) {
// only renew while eligible
checkout.setReturnDate(LocalDate.now().plusDays(7).toString());
checkoutRepository.save(checkout);
}
} catch (ParseException e) {
logger.error("date parsed error while renewing loans ", e);
throw new RuntimeException(e);
}
}

@Override
public int countCurrentLoans(Long userId) {
return checkoutRepository.countByUserId(userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import com.codemagician.onlinelibrary.domain.req.SignupReq;
import com.codemagician.onlinelibrary.domain.rsp.JwtRsp;
import com.codemagician.onlinelibrary.domain.vo.UserVO;
import com.codemagician.onlinelibrary.enums.RoleEnum;
import com.codemagician.onlinelibrary.exception.BusinessException;
import com.codemagician.onlinelibrary.common.enums.RoleEnum;
import com.codemagician.onlinelibrary.common.exception.BusinessException;
import com.codemagician.onlinelibrary.security.jwt.JwtUtils;
import com.codemagician.onlinelibrary.security.services.UserDetailsImpl;
import com.codemagician.onlinelibrary.service.UserService;
Expand Down
Loading

0 comments on commit a805eaa

Please sign in to comment.