Skip to content

Commit edd47ee

Browse files
committed
code update: update fastapi
1 parent b37d849 commit edd47ee

9 files changed

Lines changed: 293 additions & 17 deletions

File tree

app/api/v1/address.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# app/api/v1/address.py
21
from fastapi import APIRouter, Depends, HTTPException, Request
32
from sqlalchemy.orm import Session
43

@@ -9,7 +8,7 @@
98
from app.schemas.base import Failed, Successfully
109
from app.services.address import AddressService
1110

12-
router = APIRouter(prefix="/addresses", tags=["addresses"])
11+
router = APIRouter(prefix="/addresses", tags=["Addresses"])
1312

1413

1514
def get_current_user(request: Request) -> User:

app/api/v1/auth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from app.schemas.base import Successfully
1313
from app.services.auth import AuthService
1414

15-
router = APIRouter(prefix="/auth", tags=["auth"])
15+
router = APIRouter(prefix="/auth", tags=["Auth"])
1616

1717

1818
def get_auth_service(db: Session = Depends(get_db)) -> AuthService:

app/api/v1/cart.py

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
from typing import List
2+
3+
from fastapi import APIRouter, Depends, HTTPException, Request
4+
from sqlalchemy.orm import Session
5+
6+
from app.core.db.connect import get_db
7+
from app.models.cart import Cart, CartLine
8+
from app.models.user import User, UserRole
9+
from app.schemas.base import Failed, Successfully
10+
from app.services.cart import (
11+
CartCreate,
12+
CartLineCreate,
13+
CartLineService,
14+
CartLineUpdate,
15+
CartService,
16+
CartUpdate,
17+
)
18+
19+
router = APIRouter(prefix="/carts", tags=["Cart"])
20+
21+
22+
def get_current_user(request: Request) -> User:
23+
"""Dependency to get the current user from request.state."""
24+
user = request.state.user
25+
if not user:
26+
raise HTTPException(status_code=401, detail="Authentication required")
27+
return user
28+
29+
30+
def get_admin_user(current_user: User = Depends(get_current_user)) -> User:
31+
"""Dependency to ensure the user is an admin."""
32+
if current_user.role != UserRole.ADMIN: # type: ignore[comparison-overlap]
33+
raise HTTPException(status_code=403, detail="Admin access required")
34+
return current_user
35+
36+
37+
@router.get("/carts/{cart_id}", response_model=Successfully[Cart])
38+
def get_cart(cart_id: int, db: Session = Depends(get_db)):
39+
service = CartService(db)
40+
cart = service.get(cart_id)
41+
if not cart:
42+
return Failed(msg="Cart not found", code=404)
43+
return Successfully(data=cart, msg="Cart retrieved successfully", code=200)
44+
45+
46+
@router.get("/carts/", response_model=Successfully[List[Cart]])
47+
def get_carts(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
48+
service = CartService(db)
49+
list_cart = service.get_multi(skip, limit)
50+
return Successfully(data=list_cart, msg="Carts retrieved successfully", code=200)
51+
52+
53+
@router.post("/carts/", response_model=Successfully[Cart])
54+
def create_cart(cart: CartCreate, db: Session = Depends(get_db)):
55+
service = CartService(db)
56+
obj = service.create(cart)
57+
return Successfully(data=obj, msg="Cart created successfully", code=201)
58+
59+
60+
@router.put("/carts/{cart_id}", response_model=Successfully[Cart])
61+
def update_cart(cart_id: int, cart: CartUpdate, db: Session = Depends(get_db)):
62+
service = CartService(db)
63+
db_cart = service.get(cart_id)
64+
if not db_cart:
65+
return Failed(msg="Cart not found", code=404)
66+
obj = service.update(db_cart, cart)
67+
return Successfully(data=obj, msg="Cart updated successfully", code=200)
68+
69+
70+
@router.delete("/carts/{cart_id}", response_model=Successfully[Cart])
71+
def delete_cart(cart_id: int, db: Session = Depends(get_db)):
72+
service = CartService(db)
73+
cart = service.remove(cart_id)
74+
if not cart:
75+
return Failed(msg="Cart not found", code=404)
76+
return Successfully(data=cart, msg="Cart deleted successfully", code=200)
77+
78+
79+
@router.get("/carts/{cart_id}/total/")
80+
def get_cart_total(cart_id: int, tax_rate: float = 0.07, db: Session = Depends(get_db)):
81+
service = CartService(db)
82+
total = service.calculate_total(cart_id, tax_rate)
83+
json = {"cart_id": cart_id, "total_amount": total}
84+
return Successfully(data=json, msg="Cart total retrieved successfully", code=200)
85+
86+
87+
@router.post("/carts/{cart_id}/apply-discount/")
88+
def apply_cart_discount(
89+
cart_id: int, discount_rate: float, db: Session = Depends(get_db)
90+
):
91+
service = CartService(db)
92+
total_discount = service.apply_discount(cart_id, discount_rate)
93+
json = {"cart_id": cart_id, "total_discount": total_discount}
94+
return Successfully(data=json, msg="Cart discount applied successfully", code=200)
95+
96+
97+
# 4. CartLine Endpoints
98+
@router.get("/cart-lines/{cart_line_id}", response_model=Successfully[CartLine])
99+
def get_cart_line(cart_line_id: int, db: Session = Depends(get_db)):
100+
service = CartLineService(db)
101+
cart_line = service.get(cart_line_id)
102+
if not cart_line:
103+
return Failed(msg="CartLine not found", code=404)
104+
return Successfully(data=cart_line, msg="CartLine retrieved successfully", code=200)
105+
106+
107+
@router.get("/cart-lines/", response_model=Successfully[List[CartLine]])
108+
def get_cart_lines(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
109+
service = CartLineService(db)
110+
obj = service.get_multi(skip, limit)
111+
return Successfully(data=obj, msg="CartLines retrieved successfully", code=200)
112+
113+
114+
@router.post("/cart-lines/", response_model=Successfully[CartLine])
115+
def create_cart_line(cart_line: CartLineCreate, db: Session = Depends(get_db)):
116+
service = CartLineService(db)
117+
obj = service.create(cart_line)
118+
return Successfully(data=obj, msg="CartLine created successfully", code=201)
119+
120+
121+
@router.put("/cart-lines/{cart_line_id}", response_model=Successfully[CartLine])
122+
def update_cart_line(
123+
cart_line_id: int, cart_line: CartLineUpdate, db: Session = Depends(get_db)
124+
):
125+
service = CartLineService(db)
126+
db_cart_line = service.get(cart_line_id)
127+
if not db_cart_line:
128+
return Failed(msg="CartLine not found", code=404)
129+
obj = service.update(db_cart_line, cart_line)
130+
return Successfully(data=obj, msg="CartLine updated successfully", code=200)
131+
132+
133+
@router.delete("/cart-lines/{cart_line_id}", response_model=Successfully[CartLine])
134+
def delete_cart_line(cart_line_id: int, db: Session = Depends(get_db)):
135+
service = CartLineService(db)
136+
cart_line = service.remove(cart_line_id)
137+
if not cart_line:
138+
return Failed(msg="CartLine not found", code=404)
139+
return Successfully(data=cart_line, msg="CartLine deleted successfully", code=200)
140+
141+
142+
@router.post("/cart-lines/{cart_line_id}/apply-discount/")
143+
def apply_cart_line_discount(
144+
cart_line_id: int, discount_rate: float, db: Session = Depends(get_db)
145+
):
146+
service = CartLineService(db)
147+
discount = service.apply_discount(cart_line_id, discount_rate)
148+
json = {"cart_line_id": cart_line_id, "discount": discount}
149+
return Successfully(
150+
data=json, msg="CartLine discount applied successfully", code=200
151+
)
152+
153+
154+
@router.get("/cart-lines/{cart_line_id}/tax/")
155+
def get_cart_line_tax(
156+
cart_line_id: int, tax_rate: float = 0.07, db: Session = Depends(get_db)
157+
):
158+
service = CartLineService(db)
159+
tax = service.calculate_tax(cart_line_id, tax_rate)
160+
json = {"cart_line_id": cart_line_id, "tax": tax}
161+
return Successfully(data=json, msg="CartLine tax calculated successfully", code=200)

app/api/v1/catalogue.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from typing import List
2+
3+
from fastapi import APIRouter, Depends
4+
from sqlalchemy.orm import Session
5+
6+
from app.core.db.connect import get_db
7+
from app.models.catalogue import Catalogue
8+
from app.schemas.base import Failed, Successfully
9+
from app.schemas.catalogue import CatalogueCreate, CatalogueUpdate
10+
from app.services.catalogue import CatalogueService
11+
12+
router = APIRouter(prefix="/catalogues", tags=["Catalogue"])
13+
14+
15+
@router.get("/catalogues/{catalogue_id}", response_model=Successfully[Catalogue])
16+
def get_catalogue(catalogue_id: int, db: Session = Depends(get_db)):
17+
service = CatalogueService(db)
18+
catalogue = service.get(catalogue_id)
19+
if not catalogue:
20+
return Failed(code=404, msg="Catalogue not found")
21+
return Successfully(
22+
data=catalogue, msg="Catalogue retrieved successfully", code=200
23+
)
24+
25+
26+
@router.get("/catalogues/", response_model=Successfully[List[Catalogue]])
27+
def get_catalogues(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
28+
service = CatalogueService(db)
29+
obj = service.get_multi(skip, limit)
30+
return Successfully(data=obj, msg="Catalogues retrieved successfully", code=200)
31+
32+
33+
@router.post("/catalogues/", response_model=Successfully[Catalogue])
34+
def create_catalogue(catalogue: CatalogueCreate, db: Session = Depends(get_db)):
35+
service = CatalogueService(db)
36+
obj = service.create(catalogue)
37+
return Successfully(data=obj, msg="Catalogue created successfully", code=201)
38+
39+
40+
@router.put("/catalogues/{catalogue_id}", response_model=Successfully[Catalogue])
41+
def update_catalogue(
42+
catalogue_id: int, catalogue: CatalogueUpdate, db: Session = Depends(get_db)
43+
):
44+
service = CatalogueService(db)
45+
db_catalogue = service.get(catalogue_id)
46+
if not db_catalogue:
47+
return Failed(code=404, msg="Catalogue not found")
48+
obj = service.update(db_catalogue, catalogue)
49+
return Successfully(data=obj, msg="Catalogue updated successfully", code=200)
50+
51+
52+
@router.delete("/catalogues/{catalogue_id}", response_model=Successfully[Catalogue])
53+
def delete_catalogue(catalogue_id: int, db: Session = Depends(get_db)):
54+
service = CatalogueService(db)
55+
catalogue = service.remove(catalogue_id)
56+
if not catalogue:
57+
return Failed(code=404, msg="Catalogue not found")
58+
return Successfully(data=catalogue, msg="Catalogue deleted successfully", code=200)

app/api/v1/checkout.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from typing import List
2+
3+
from fastapi import APIRouter, Depends
4+
from sqlalchemy.orm import Session
5+
6+
from app.core.db.connect import get_db
7+
from app.models.checkout import Checkout
8+
from app.schemas.checkout import CheckoutCreate, CheckoutUpdate
9+
from app.services.checkout import CheckoutService
10+
from app.schemas.base import Failed, Successfully
11+
12+
router = APIRouter(prefix="/checkouts", tags=["Checkout"])
13+
14+
15+
@router.get("/checkouts/{checkout_id}", response_model=Successfully[Checkout])
16+
def get_checkout(checkout_id: int, db: Session = Depends(get_db)):
17+
service = CheckoutService(db)
18+
checkout = service.get(checkout_id)
19+
if not checkout:
20+
return Failed(code=404, msg="Checkout not found")
21+
return Successfully(
22+
status="success", code=200, msg="Checkout retrieved", data=checkout
23+
)
24+
25+
26+
@router.get("/checkouts/", response_model=Successfully[List[Checkout]])
27+
def get_checkouts(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
28+
service = CheckoutService(db)
29+
obj = service.get_multi(skip, limit)
30+
return Successfully(data=obj, msg="Checkouts retrieved successfully", code=200)
31+
32+
33+
@router.post("/checkouts/", response_model=Successfully[Checkout])
34+
def create_checkout(checkout: CheckoutCreate, db: Session = Depends(get_db)):
35+
service = CheckoutService(db)
36+
obj = service.create(checkout)
37+
return Successfully(data=obj, msg="Checkout created successfully", code=201)
38+
39+
40+
@router.put("/checkouts/{checkout_id}", response_model=Successfully[Checkout])
41+
def update_checkout(
42+
checkout_id: int, checkout: CheckoutUpdate, db: Session = Depends(get_db)
43+
):
44+
service = CheckoutService(db)
45+
db_checkout = service.get(checkout_id)
46+
if not db_checkout:
47+
return Failed(code=404, msg="Checkout not found")
48+
obj = service.update(db_checkout, checkout)
49+
return Successfully(data=obj, msg="Checkout updated successfully", code=200)
50+
51+
52+
@router.delete("/checkouts/{checkout_id}", response_model=Successfully[Checkout])
53+
def delete_checkout(checkout_id: int, db: Session = Depends(get_db)):
54+
service = CheckoutService(db)
55+
checkout = service.remove(checkout_id)
56+
if not checkout:
57+
return Failed(code=404, msg="Checkout not found")
58+
return Successfully(data=checkout, msg="Checkout deleted successfully", code=200)

app/api/v1/users.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from app.schemas.user import UserResponse, UserUpdate
88
from app.services.user import UserService
99

10-
router = APIRouter(prefix="/users", tags=["users"])
10+
router = APIRouter(prefix="/users", tags=["Users"])
1111

1212

1313
def get_current_user(request: Request) -> User:

app/core/security.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
1-
from fastapi import Depends
2-
from fastapi.security import OAuth2PasswordBearer
31
from passlib.context import CryptContext
42

5-
from .auth_handler import decode_jwt
63

74
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
8-
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="v1/auth/login")
95

106

117
def get_password_hash(password: str) -> str:
128
return pwd_context.hash(password)
13-
14-
15-
async def get_current_user(token: str = Depends(oauth2_scheme)):
16-
payload = decode_jwt(token)
17-
return payload.get("id")

app/main.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import logging
22

33
from fastapi import FastAPI
4-
4+
from fastapi.security import OAuth2AuthorizationCodeBearer
5+
from app.api.v1.address import router as address_router
56
from app.api.v1.auth import router as auth_router
7+
from app.api.v1.cart import router as cart_router
68
from app.api.v1.users import router as users_router
7-
from app.api.v1.address import router as address_router
9+
from app.api.v1.catalogue import router as catalogue_router
10+
from app.api.v1.checkout import router as checkout_router
811
from app.core.config import (
912
configure_app,
1013
configure_exception_handlers,
@@ -13,6 +16,10 @@
1316
from app.core.db.connect import Base, get_engine
1417

1518
logger = logging.getLogger(__name__)
19+
oauth2_scheme = OAuth2AuthorizationCodeBearer(
20+
authorizationUrl="/v1/auth/login", # URL สำหรับการขอ token (ในที่นี้เป็น placeholder)
21+
tokenUrl="/v1/auth/login", # URL สำหรับการขอ token (ในที่นี้เป็น placeholder)
22+
)
1623

1724

1825
def create_app(db_engine=None) -> FastAPI:
@@ -38,7 +45,10 @@ async def shutdown_event():
3845
configure_exception_handlers(app)
3946
app.include_router(auth_router, prefix="/v1")
4047
app.include_router(users_router, prefix="/v1")
41-
app.include_router(address_router, prefix="/v1") # Add this line
48+
app.include_router(address_router, prefix="/v1")
49+
app.include_router(cart_router, prefix="/v1")
50+
app.include_router(catalogue_router, prefix="/v1")
51+
app.include_router(checkout_router, prefix="/v1")
4252

4353
@app.get("/")
4454
def read_root():

app/models/user.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ class User(BaseModel):
3131

3232
last_login = Column(DateTime(timezone=True), nullable=True)
3333

34-
addresses = relationship("Address", back_populates="user")
3534

3635
# # ความสัมพันธ์กับตารางอื่น
3736
# orders = relationship("Order", back_populates="user") # ความสัมพันธ์กับคำสั่งซื้อ

0 commit comments

Comments
 (0)