Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5ae79ff
added shoping_cart schemas
AndriiDementiev Feb 1, 2025
b149b43
added crud with db query for shoping_cart routes & validations
AndriiDementiev Feb 1, 2025
6be1f96
added shoping_cart routes
AndriiDementiev Feb 1, 2025
18ac11a
fixed imports with old naming
AndriiDementiev Feb 1, 2025
07041b0
fixed merge conflicts after pull from develop
AndriiDementiev Feb 2, 2025
f10aa32
"fixed old naming"
AndriiDementiev Feb 2, 2025
2148c19
added custome routes
AndriiDementiev Feb 2, 2025
1834e72
"fixed naming conflict"
AndriiDementiev Feb 2, 2025
2d50415
Merge branch 'develop' of https://github.com/Mxbely/FastAPI_Cinema_Pr…
AndriiDementiev Feb 3, 2025
d4d2224
added specific response schema for purchased movies
AndriiDementiev Feb 3, 2025
73c8609
removed auxiliary func from routes to crud & improve some crud foo
AndriiDementiev Feb 3, 2025
ec0aa1f
updated routes to the main project code style & improved them accordi…
AndriiDementiev Feb 3, 2025
e36c12e
added functionality for admin so they can view the contents of users'…
AndriiDementiev Feb 3, 2025
1abc2fd
added route for notifying moderators when attempting to delete a movi…
AndriiDementiev Feb 3, 2025
bdc9109
fixed imoprts with ruff
AndriiDementiev Feb 3, 2025
99d1550
separated db logic from routes into crud
AndriiDementiev Feb 3, 2025
f3a0ec8
resolved conflicts after pulling from dev
AndriiDementiev Feb 3, 2025
aaf688f
fixed code with ruff
AndriiDementiev Feb 3, 2025
b1913ab
fixed some typy annotations
AndriiDementiev Feb 3, 2025
de39381
fixed return type annotation for jwt_manager
AndriiDementiev Feb 3, 2025
af9c679
fixed mypy
AndriiDementiev Feb 3, 2025
6ad9853
fixed mypy
AndriiDementiev Feb 3, 2025
28cc15e
deleted unusable imports
AndriiDementiev Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/database/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
)
from database.models.orders import Order, OrderItem
from database.models.payments import Payment, PaymentItem, PaymentStatusEnum
from database.models.shoping_cart import Cart, CartItem
from database.models.shopping_cart import Cart, CartItem
from database.session_postgresql import get_postgresql_db as get_db
from database.session_postgresql import (
get_postgresql_db_contextmanager as get_db_contextmanager,
Expand Down
162 changes: 162 additions & 0 deletions src/database/crud/shopping_cart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
from typing import List, Optional, cast

from fastapi import HTTPException
from sqlalchemy.orm import Session

from database import (
Cart,
CartItem,
Movie,
Order,
OrderItem,
Payment,
PaymentItem,
PaymentStatusEnum,
User,
)
from schemas.shopping_cart import CartItemDetail


def get_user_cart(user: User, db: Session) -> Cart | None:
return db.query(Cart).filter(Cart.user_id == user.id).first()


def get_movie_by_id(movie_id: int, db: Session) -> Movie | None:
return db.query(Movie).filter(Movie.id == movie_id).first()


def get_cart_item(cart: Cart, movie_id: int, db: Session) -> CartItem | None:
return db.query(CartItem).filter(
CartItem.cart_id == cart.id, CartItem.movie_id == movie_id
).first()


def create_cart(user: User, db: Session) -> Cart:
cart = Cart(user_id=user.id)
db.add(cart)
db.commit()
db.refresh(cart)
return cart


def add_cart_item(cart: Cart, movie: Movie, db: Session) -> CartItem:
existing_item = get_cart_item(cart, movie.id, db)
if existing_item:
raise HTTPException(status_code=400, detail="Movie is already in the cart")

cart_item = CartItem(cart_id=cart.id, movie_id=movie.id)
db.add(cart_item)
db.commit()
db.refresh(cart_item)
return cart_item


def delete_cart_item(cart_item: CartItem, db: Session) -> None:
db.delete(cart_item)
db.commit()


def delete_cart_item_by_cart(db: Session, cart_id: int) -> None:
db.query(CartItem).filter(CartItem.cart_id == cart_id).delete()
db.commit()


def create_order(db: Session, order: Order) -> None:
db.add(order)
db.commit()
db.refresh(order)


def create_order_items(db: Session, order: Order, cart: Cart) -> List[OrderItem]:
order_items: List[OrderItem] = []
for item in cart.items:
order_item = OrderItem(
order_id=order.id,
movie_id=item.movie.id,
price_at_order=item.movie.price
)
db.add(order_item)
order_items.append(order_item)

db.commit()
return order_items


def create_payment(db: Session, user: User, order: Order) -> Payment:
payment = Payment(
user_id=user.id,
order_id=order.id,
status=PaymentStatusEnum.PENDING,
amount=order.total_amount,
external_payment_id=None
)
db.add(payment)
db.commit()
db.refresh(payment)
return payment


def create_payment_items(
db: Session,
payment: Payment,
order_items: List[OrderItem]
) -> None:
for order_item in order_items:
payment_item = PaymentItem(
payment_id=payment.id,
order_item_id=order_item.id,
price_at_payment=order_item.price_at_order
)
db.add(payment_item)

db.commit()


def process_order_payment_and_clear_cart(
db: Session,
user: User,
order: Order,
cart: Cart
) -> Payment:
order_items = create_order_items(db, order, cart)
payment = create_payment(db, user, order)
create_payment_items(db, payment, order_items)

delete_cart_item_by_cart(db, cart.id)

return payment


def is_movie_in_any_cart(db: Session, movie_id: int) -> bool:
return bool(db.query(CartItem).filter(CartItem.movie_id == movie_id).count())


def delete_movie(db: Session, movie: Movie) -> None:
db.delete(movie)
db.commit()


def get_purchased_movies_from_db(user: User, db: Session) -> list[Movie]:
result = (
db.query(Movie)
.join(CartItem)
.join(Cart)
.join(Order, Order.user_id == Cart.user_id)
.filter(Order.user_id == user.id)
.distinct()
.all()
)
return cast(List[Movie], result)


def get_cart_items_details(cart: Optional[Cart]) -> List[CartItemDetail]:
return [
CartItemDetail(
movie_id=item.movie.id,
title=item.movie.name,
price=item.movie.price,
genre=item.movie.genres[0].name if item.movie.genres else "Unknown",
release_year=item.movie.year
)
for item in cart.items
] if cart else []
4 changes: 4 additions & 0 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from fastapi_pagination import add_pagination

from routes import accounts_router, payments_router, profiles_router
from routes.shopping_cart import router as shopping_carts_router

app = FastAPI(
title="Movies Cinema",
Expand All @@ -20,3 +21,6 @@
)

add_pagination(app)
app.include_router(
shopping_carts_router, prefix=f"{api_version_prefix}/carts", tags=["carts"]
)
Loading