[ 작업한 내용 ]
< 도서 대출 내역에서 분실처리 기능 추가 >
1. messages.properties
- 도서 분실 관련 메시지 정의.
success.loan.lost=도서가 분실 처리되었습니다.
error.loan.already_losted=해당 대출은 이미 분실처리되었습니다.
error.book.already_losted=해당 도서는 이미 분실처리되었습니다.
error.loan.status.invalid.for.lost=대출 중 또는 연체 중 상태에서만 분실 처리가 가능합니다.
2. LoanSuccessCode
- 도서 분실 처리 성공 코드 정의.
LOAN_MARKED_LOST_SUCCESS(HttpStatus.OK, "LOAN_203", "success.loan.lost");
3. LoanErrorCode
- 도서 분실 처리 에러 코드 정의.
LOAN_ALREADY_LOSTED(HttpStatus.BAD_REQUEST, "LOAN_410", "error.loan.already_loasted");
LOAN_INVALID_STATUS_FOR_LOST(HttpStatus.BAD_REQUEST, "LOAN_411", "error.loan.status.invalid.for.lost");
4. BookErrorCode
- 도서 분실 처리 에러 코드 정의.
BOOK_ALREADY_LOSTED(HttpStatus.BAD_REQUEST, "BOOK_013", "error.book.already_losted");
5. Loan 엔티티 수정
- 도서 대출 내역에서 분실 날짜 기록을 위해 lostDate 추가
- DB loan 테이블에도 lost_date 컬럼 추가
6. Book 엔티티 수정
- 도서의 분실된 날짜를 기록하기 위해 losted_at 추가
- DB book 테이블에도 losted_at 컬럼 추가
7. AdminLoanLostResDTO
- 도서 분실 처리 응답 DTO
- id, loanStatus, lostDate, bookId, bookTitle, bookStatus, lostedAt, userId, username 필드
- Loan 엔티티를 파라미터로 받는 AdminLoanLostResDTO 생성자 함수 정의.
8. AdminLoanController
- PATCH /api/v1/admin/loans/{loanId}/lost 로 요청.
- PathVariable형태로 loanId를 파라미터로 받는다.
- Service 계층으로 loanId를 전달해 도서 분실 처리를 하고 처리 결과를 AdminLoanLostResDTO 형태로 저장한다.
- 클라이언트 측으로 응답할 때에는 성공 메시지와 AdminLoanLostResDTO 객체를 ApiResponse.success()로 감싸 반환한다.
@PatchMapping("/{loanId}/lost")
public ResponseEntity<?> loanLostBook(@PathVariable("loanId") Long loanId) {
// 서비스로직
AdminLoanLostResDTO responseDTO = adminLoanService.loanLostBook(loanId);
// 성공메시지
String message = messageProvider.getMessage(LoanSuccessCode.LOAN_RETURNED_SUCCESS.getMessage());
// 응답
return ResponseEntity
.status(LoanSuccessCode.LOAN_MARKED_LOST_SUCCESS.getHttpStatus())
.body(ApiResponse.success(
LoanSuccessCode.LOAN_MARKED_LOST_SUCCESS,
message,
responseDTO));
}
9. AdminLoanService
- Controller로 전달받은 loanId로 loanRepository.findById() 메서드를 호출하여 해당 도서 대출 내역을 조회하여 Loan 엔티티를 정의한다.
- Loan 엔티티에 정의한 book 필드는 Book 필드와 연관관계이기 때문에 loan.getBook().getId() 데이터를 가져와 bookRepository.fidnById() 메서드를 호출하여 해당 도서의 정보를 가져와 Book 엔티티로 정의한다.
- Loan의 상태가 LOST인지 상태 여부 체크를 한다.
- 도서 대출 내역의 상태를 LOST(분실)로 변경하기 위해서는 Loan의 상태가 LOANED(대출중) 또는 OVERDUE(연체됨) 상태만 가능하다.
- Book의 상태가 Lost인지 상태 여부 체크를 한다.
- 모든 조건에 부합하면 도서 대출 내역의 상태와 도서의 상태를 분실로 변경하고 각 분실날짜를 현재로 업데이트 해준다.
- Controller로 반환시 Loan 데이터를 기반으로 AdminLoanLostResDTO 객체를 만들어 반환한다.
@Transactional
public AdminLoanLostResDTO loanLostBook(Long loanId) {
// loanId 조회 + 예외 처리
Loan loan = loanRepository.findById(loanId)
.orElseThrow(() -> new BaseException(LoanErrorCode.LOAN_NOT_FOUND));
// bookId 조회 + 예외 처리
Book book = bookRepository.findById(loan.getBook().getId())
.orElseThrow(() -> new BaseException(BookErrorCode.BOOK_NOT_FOUND));
// Loan 엔티티 LOST 상태 여부 체크 + 예외 처리
if (loan.getStatus() == LoanStatus.LOST) {
throw new BaseException(LoanErrorCode.LOAN_ALREADY_LOSTED);
}
// Loan 상태가 LOANED, OVERDUE만 LOST 처리 가능
LoanStatus current = loan.getStatus();
if (current != LoanStatus.LOANED && current != LoanStatus.OVERDUE) {
throw new BaseException(LoanErrorCode.LOAN_INVALID_STATUS_FOR_LOST);
}
// Book 엔티티 상태 체크 후 분실 처리
if (book.getStatus() == BookStatus.LOST) {
throw new BaseException(BookErrorCode.BOOK_ALREADY_LOSTED);
}
// 도서 대출 내역과 도서 상태 분실 처리
loan.setStatus(LoanStatus.LOST);
loan.setLostDate(LocalDateTime.now());
book.setStatus(BookStatus.LOST);
book.setLostedAt(LocalDateTime.now());
// 응답
return new AdminLoanLostResDTO(loan);
}
< 그외 작업 >
1. RequestParam 형태로 요청시 파라미터와 맵핑이 안되는 문제 해결.
- @RequestParam("id") Long id 이렇게 명시를 해주는 것으로 전체다 변경.
2. .findAll() 메서드 제거.
- Repository는 Jpa Repository를 상속받기 때문에 특별한 이유가 있는 것이 아니라면 findAll() 메서드를 정의할 필요가 없다고 판단되어 작성된 findAll() 메서드 삭제함.
< 도서 대출 내역에서 분실 처리 실패의 경우 >
< 도서 대출 내역에서 분실 처리 성공 >
'개발 기록 > 도서관 관리 시스템' 카테고리의 다른 글
[Library Management System] 25.09.17 (48일) (0) | 2025.09.17 |
---|---|
[Library Management System] 25.09.16 (47일) (0) | 2025.09.16 |
[Library Management System] 25.09.11 (44일) (0) | 2025.09.11 |
[Library Management System] 25.09.10 (43일) (0) | 2025.09.10 |
[Library Management System] 25.09.09 (42일) (0) | 2025.09.10 |