Skip to content

Commit

Permalink
Merge pull request #109 from kucc/exp
Browse files Browse the repository at this point in the history
Exp: Merge exp to main
  • Loading branch information
smreosms13 authored Nov 30, 2024
2 parents 40c3f8e + 49c96d1 commit 059b4d2
Show file tree
Hide file tree
Showing 32 changed files with 928 additions and 299 deletions.
4 changes: 2 additions & 2 deletions src/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ def get_current_active_user(user: User = Depends(get_current_user)):
return user


def get_current_admin(user: User = Depends(get_current_active_user)):
def get_current_admin(user: User = Depends(get_current_user)):
"""
get_current_admin 사용법 예시
def example(current_user: User = Depends(get_current_admin)):
return {"message": "Welcome Admin!"}
"""
if not user.admin or not user.admin[0].admin_status or user.admin[0].is_deleted:
if not user.admin or not user.admin[-1].admin_status or user.admin[-1].is_deleted:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="The user doesn't have enough privileges"
Expand Down
18 changes: 0 additions & 18 deletions src/domain/enums/admin_status.py

This file was deleted.

78 changes: 78 additions & 0 deletions src/domain/enums/status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from enum import Enum


class ExtendEnum(Enum):
@classmethod
def is_valid_enum_value(cls, status) -> bool:
return status in cls._value2member_map_

def __call__(self):
return self.value

def __repr__(self):
return f"<{self.__class__.__name__}.{self.name}({self.value})>"

class AdminStatus(ExtendEnum):
'''
# 사용 예시
# print(AdminStatus.ACTIVE) # 현재 활성화된 관리자입니다.
# print(AdminStatus.ACTIVE()) # True
# print(AdminStatus.INACTIVE()) # False
'''
ACTIVE = True
INACTIVE = False

def __str__(self):
desc = "활성화된" if self.value else "비활성화된"
return f"현재 {desc} 관리자입니다."


class BookStatus(ExtendEnum):
AVAILABLE = True
INAVILABLE = False

def __str__(self):
desc = "이용 가능" if self.value else "이용 불가능한"
return f"현재 {desc} 한 도서입니다."

class BookRequestStatus(ExtendEnum):
'''
# 사용 예시
# print(BookRequestStatus.WAITING) # 해당 도서 구매 요청은 대기 중입니다.
# print(BookRequestStatus.WAITING()) # 0
# print(BookRequestStatus.WAITING.__repr__()) # <BookRequestStatus.WAITING(0)>
# print(BookRequestStatus.is_valid_enum_value(3)) # True
'''
WAITING = 0
PURCHASED = 1
CANCELED = 2
REJECTED = 3

def __str__(self):
status_descriptions = {
0: "해당 도서 구매 요청은 대기 중입니다.",
1: "해당 도서 구매 요청은 구매 완료되었습니다.",
2: "해당 도서 구매 요청은 신청자 취소되었습니다.",
3: "해당 도서 구매 요청은 관리자 반려되었습니다."
}
return status_descriptions.get(self.value, "잘못된 도서 구매 요청 상태입니다.")


class ReturnStatus(ExtendEnum):
RETURNED = True
NOT_RETURNED = False

def __str__(self):
desc = "반납 완료된" if self.value else "대출 중인"
return f"현재 {desc} 도서입니다."


class ExtendStatus(ExtendEnum):
EXTENDED = True
NOT_EXTENDED = False

def __str__(self):
desc = "연장된" if self.value else "연장되지 않은"
return f"대출이 {desc} 상태입니다."


11 changes: 10 additions & 1 deletion src/domain/schemas/bookrequest_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ class DomainResBookRequest(BaseModel):
publication_year: int = Field(title="publication_year", description="출판년도", example=2022, gt=0)
request_link: str = Field(title="request_link", description="요청 링크", example="https://example.com/request")
reason: str = Field(title="reason", description="이유", example="Need for study")
processing_status: int = Field(0, title="processing_status", description="처리 상태", example=0, ge=0, le=3)
processing_status: int = Field(0, title="processing_status", description="처리 상태", example=0)
request_date: date = Field(title="request_date", description="요청 일자", example=date.today())
reject_reason: str | None = Field(None, title="reject_reason", description="거절 사유", example="Not available")

class DomainResAdminGetBookRequest(BaseModel):
data: list[DomainResBookRequest]
total: int = Field(0, title="total", description="총 도서 구매 요청", example=0, ge=0)

class DomainReqAdminPutBookRequest(BaseModel):
request_id: int = Field(title="book_request_id", description="도서 구매 요청 정보 id", example=1, gt=0)
processing_status: int = Field(0, title="processing_status", description="처리 상태", example=0)
reject_reason: str | None = Field(None, title="reject_reason", description="거절 사유", example="Not available")
36 changes: 2 additions & 34 deletions src/domain/schemas/loan_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,7 @@
from pydantic import BaseModel, Field


class Loan(BaseModel):
id: int = Field(title="loan_id", description="대출 정보 id", example=1, gt=0)
book_id: int = Field(title="book_id", description="대출한 책 ID", example=1, gt=0)
user_id: int = Field(title="user_id", description="대출한 사용자 ID", example=1, gt=0)
created_at: datetime = Field(title="create_at", description="생성일시", example=datetime.now())
updated_at: datetime = Field(title="update_at", description="수정일시", example=datetime.now())
loan_date: date = Field(title="loan_date", description="대출 날짜", example=datetime.today().date())
due_date: date = Field(title="due_date", description="반납 기한", example=(datetime.today() + timedelta(days=14)).date())
extend_status: bool = Field(title="extend_status", description="연장 상태", example=True)
overdue_days: int = Field(title="overdue_days", description="연체 일자", example=1)
return_status: bool = Field(title="return_status", description="반납 상태", example=False)
return_date: date | None = Field(title="return_date", description="반납 날짜", example=None)


class DomainResGetLoanItem(BaseModel):
class DomainResGetLoan(BaseModel):
loan_id: int = Field(title="loan_id", description="대출 정보 id", example=1, gt=0)
book_id: int = Field(title="book_id", description="대출한 책 ID", example=1, gt=0)
user_id: int = Field(title="user_id", description="대출한 사용자 ID", example=1, gt=0)
Expand Down Expand Up @@ -56,25 +42,7 @@ class DomainReqPostLoan(BaseModel):
book_id: int = Field(title="book_id", description="대출한 책 ID", example=1, gt=0)


class LoanCreate(BaseModel):
user_id: int = Field(title="user_id", description="대출한 사용자 ID", example=1, gt=0)
book_id: int = Field(title="book_id", description="대출한 책 ID", example=1, gt=0)
created_at: datetime = Field(title="create_at", description="생성일시", example=datetime.now())
updated_at: datetime = Field(title="update_at", description="수정일시", example=datetime.now())


class DomainResGetLoan(BaseModel):
loan_id: int = Field(title="loan_id", description="대출 정보 id", example=1, gt=0)
book_id: int = Field(title="book_id", description="대출한 책 ID", example=1, gt=0)
user_id: int = Field(title="user_id", description="대출한 사용자 ID", example=1, gt=0)
loan_date: date = Field(title="loan_date", description="대출 날짜", example=datetime.today().date())
due_date: date = Field(title="due_date", description="반납 기한", example=(datetime.today() + timedelta(days=14)).date())
extend_status: bool = Field(title="extend_status", description="연장 상태", example=True)
overdue_days: int = Field(title="overdue_days", description="연체 일자", example=1)
return_status: bool = Field(title="return_status", description="반납 상태", example=False)
return_date: date | None = Field(title="return_date", description="반납 날짜", example=None)

class DomainAdminGetLoanItem(BaseModel):
class DomainAdminGetLoan(BaseModel):
loan_id: int = Field(title="loan_id", description="대출 id", example=1, gt=0)
book_id: int = Field(title="book_id", description="대출한 책 ID", example=1, gt=0)
user_id: int = Field(title="user_id", description="대출한 사용자 ID", example=1, gt=0)
Expand Down
22 changes: 21 additions & 1 deletion src/domain/schemas/user_schemas.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import date, datetime

from pydantic import BaseModel, Field

Expand Down Expand Up @@ -38,3 +38,23 @@ class DomainAdminGetUserItem(BaseModel):
is_active: bool = Field(title="is_active", description="활동 상태")
created_at: datetime = Field(title="create_at", description="생성일시")
updated_at: datetime = Field(title="update_at", description="수정일시")

class DomainReqAdminPutUser(BaseModel):
user_id: int = Field(title="user_id", description="관리자의 회원 ID", gt=0)
user_status: bool | None = Field(None, title="is_active", description="회원 상태(대출 가능 여부)", examples=[True])
admin_status: bool | None = Field(None, title="admin_status", description="관리자 권한 상태")
expiration_date : date | None = Field(None, title="expiration_date", description="관리자 권한 만료일, \
기본적으로 권한 부여일로부터 1년", examples=["2025-07-02"])
class DomainResAdminPutUser(BaseModel):
user_id: int = Field(title="user_id", description="유저 고유 ID", example=1111, gt=0)
auth_id: str = Field(title="auth_id", description="로그인 ID", example="gildong1")
email: str = Field(title="email", description="이메일 주소", example="KUCC@korea.ac.kr")
user_name: str = Field(title="user_name", description="사용자 이름", example="홍길동")
is_active: bool = Field(title="is_active", description="활동 상태", examples=[True])
is_admin: bool = Field(title="is_admin", description="관리자 권환", examples=[False])
expiration_date : date | None = Field(title="expiration_date", description="관리자 권한 만료일, \
기본적으로 권한 부여일로부터 1년", examples=["2025-07-02"])

class DomainReqAdminDelUser(BaseModel):
user_id: int = Field(title="user_id", description="유저 고유 ID", example=1111, gt=0)

7 changes: 0 additions & 7 deletions src/domain/services/admin/book_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,6 @@ async def service_admin_search_books(


async def service_admin_create_book(request: DomainReqAdminPostBook, db: Session):
# check if the book already exists in database
stmt = select(Book).where(Book.book_title == request.book_title)
exist_request = db.execute(stmt).scalar_one_or_none()

if exist_request:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
detail="Already exists")
if request.code[0] not in {category.name for category in BookCategoryStatus}:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid Category")
Expand Down
133 changes: 133 additions & 0 deletions src/domain/services/admin/bookrequest_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@

from datetime import datetime
from math import ceil

from fastapi import HTTPException, status
from sqlalchemy import and_, func, select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session

from domain.enums.status import BookRequestStatus
from domain.schemas.bookrequest_schemas import (
DomainReqAdminPutBookRequest,
DomainResAdminGetBookRequest,
DomainResBookRequest,
)
from repositories.models import RequestedBook


async def service_admin_read_bookrequest(db: Session, page: int, limit: int):
total = db.execute(select(func.count()).select_from(RequestedBook)
.where(RequestedBook.is_deleted==False)).scalar()
if ceil(total/limit) <page:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Page is out of range"
)
offset = (page-1)*limit
stmt = (select(RequestedBook).where(RequestedBook.is_deleted==False).order_by(RequestedBook.updated_at.desc())
.limit(limit).offset(offset))
bookrequest = db.execute(stmt).scalars().all()
if not bookrequest:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Not found"
)
result = [DomainResBookRequest(
user_id=book.user_id,
request_id=book.id,
book_title=book.book_title,
publication_year=book.publication_year,
request_link=book.request_link,
reason=book.reason,
processing_status=book.processing_status,
request_date=book.request_date,
reject_reason=book.reject_reason
) for book in bookrequest]

response = DomainResAdminGetBookRequest(
data=result,
total = total
)
return response


async def service_admin_update_bookrequest(db:Session, request: DomainReqAdminPutBookRequest):
stmt = select(RequestedBook).where(and_(RequestedBook.id==request.request_id, RequestedBook.is_deleted==False))
request_book = db.execute(stmt).scalar_one_or_none()
if not request_book:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="BookRequest Not found"
)

try:
request_book.processing_status = request.processing_status
if request_book.processing_status == BookRequestStatus.REJECTED():
request_book.reject_reason = request.reject_reason
else:
request_book.reject_reason = None
request_book.updated_at = datetime.now()

db.flush()

except IntegrityError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=f"Integrity Error occurred during update the Review item.: {str(e)}",
) from e

except Exception as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Unexpected error occurred during update: {str(e)}",
) from e

else:
db.commit()
db.refresh(request_book)
result = DomainResBookRequest(
user_id=request_book.user_id,
request_id=request_book.id,
book_title=request_book.book_title,
publication_year=request_book.publication_year,
request_link=request_book.request_link,
reason=request_book.reason,
processing_status=request_book.processing_status,
request_date=request_book.request_date,
reject_reason=request_book.reject_reason
)
return result

async def service_admin_delete_bookrequest(request_id: int, db: Session):
stmt = select(RequestedBook).where(RequestedBook.id==request_id, RequestedBook.is_deleted==False)
request_book = db.execute(stmt).scalar_one_or_none()
if not request_book:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="BookRequest Not found"
)
try:
request_book.is_deleted = True
db.flush()

except IntegrityError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=f"Integrity Error occurred during update the Review item.: {str(e)}",
) from e

except Exception as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Unexpected error occurred during update: {str(e)}",
) from e

else:
db.commit()
db.refresh(request_book)
return
Loading

0 comments on commit 059b4d2

Please sign in to comment.