Skip to content

Commit

Permalink
refactor: refactor queries for oders
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatasoli committed Oct 19, 2024
1 parent 8b08623 commit 11c696d
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 56 deletions.
2 changes: 2 additions & 0 deletions app/entities/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from decimal import Decimal
from pydantic import BaseModel, ConfigDict, SecretStr

from app.entities.payment import PaymentInDB
from app.entities.product import ProductInDB
from app.entities.user import UserInDB

Expand Down Expand Up @@ -46,6 +47,7 @@ class OrderInDB(BaseModel):
freight: str | None
coupon_id: int | None
items: list[OrderItemInDB] | None
payment: PaymentInDB | None = None
model_config = ConfigDict(from_attributes=True)


Expand Down
4 changes: 2 additions & 2 deletions app/entities/payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ class PaymentInDB(BaseModel):
authorization: str | None
payment_method: str | None
payment_gateway: str | None
amount_with_fee: int | None
freight_amount: int | None
amount_with_fee: Decimal | None
freight_amount: Decimal | None
model_config = ConfigDict(from_attributes=True)


Expand Down
14 changes: 14 additions & 0 deletions app/entities/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ class UserAddress(BaseModel):
zip_code: str


class UserAddressInDB(BaseModel):
user_id: int | None
street: str
street_number: str
address_complement: str
neighborhood: str
city: str
state: str
country: str
zipcode: str
model_config = ConfigDict(from_attributes=True)


class UserDBGet(BaseModel):
user_id: int
name: str
Expand Down Expand Up @@ -105,6 +118,7 @@ class UserSchema(BaseModel):
email: str | None = None
full_name: str | None = None
disabled: bool | None = None
addresses: list[UserAddressInDB] | None = None
model_config = ConfigDict(from_attributes=True)


Expand Down
85 changes: 53 additions & 32 deletions app/infra/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,39 @@ class CouponsDB(Base):
)


class PaymentDB(Base):
__tablename__ = 'payment'

payment_id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey('user.user_id'))
user: Mapped['UserDB'] = relationship(
foreign_keys=[user_id],
backref='payment',
cascade='all,delete',
uselist=False,
)
order_id: Mapped[int] = mapped_column(ForeignKey('order.order_id'))
amount: Mapped[Decimal]
amount_with_fee: Mapped[Decimal] = mapped_column(server_default='0')
token: Mapped[str]
gateway_payment_id: Mapped[int] = mapped_column(BIGINT, server_default='0')
status: Mapped[str]
authorization: Mapped[str]
payment_method: Mapped[str]
payment_gateway: Mapped[str]
installments: Mapped[int]
processed: Mapped[bool] = mapped_column(default=False)
processed_at: Mapped[datetime | None]
freight_amount: Mapped[Decimal] = mapped_column(server_default='0')

order: Mapped['OrderDB'] = relationship(
'OrderDB',
back_populates='payment',
foreign_keys=[order_id], # Verifique se essa linha está correta
uselist=False,
)


class OrderDB(Base):
__tablename__ = 'order'

Expand Down Expand Up @@ -178,6 +211,13 @@ class OrderDB(Base):
cascade='all,delete',
foreign_keys='OrderItemsDB.order_id',
lazy='joined',
overlaps="order_items",
)
payment: Mapped['PaymentDB'] = relationship(
'PaymentDB',
foreign_keys=[PaymentDB.order_id],
back_populates="order",
uselist=False,
)


Expand All @@ -192,6 +232,7 @@ class OrderItemsDB(Base):
cascade='all,delete',
foreign_keys=[order_id],
lazy='joined',
overlaps="orders, items",
)
product_id: Mapped[int] = mapped_column(ForeignKey('product.product_id'))
product = relationship(
Expand Down Expand Up @@ -268,38 +309,6 @@ class CustomerDB(Base):
created_at: Mapped[datetime] = mapped_column(default=func.now())


class PaymentDB(Base):
__tablename__ = 'payment'

payment_id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey('user.user_id'))
user: Mapped['UserDB'] = relationship(
foreign_keys=[user_id],
backref='payment',
cascade='all,delete',
uselist=False,
)
order_id: Mapped[int] = mapped_column(ForeignKey('order.order_id'))
order: Mapped['OrderDB'] = relationship(
foreign_keys=[order_id],
backref='payment',
cascade='all,delete',
uselist=False,
)
amount: Mapped[Decimal]
amount_with_fee: Mapped[Decimal] = mapped_column(server_default='0')
token: Mapped[str]
gateway_payment_id: Mapped[int] = mapped_column(BIGINT, server_default='0')
status: Mapped[str]
authorization: Mapped[str]
payment_method: Mapped[str]
payment_gateway: Mapped[str]
installments: Mapped[int]
processed: Mapped[bool] = mapped_column(default=False)
processed_at: Mapped[datetime | None]
freight_amount: Mapped[Decimal] = mapped_column(server_default='0')


class CreditCardFeeConfigDB(Base):
__tablename__ = 'credit_card_fee_config'

Expand Down Expand Up @@ -358,6 +367,13 @@ class UserDB(Base):
server_default='0',
)

addresses: Mapped[list['AddressDB'] | None] = relationship(
'AddressDB',
back_populates='user',
cascade='all, delete',
lazy='joined',
)


class AddressDB(Base):
__tablename__ = 'address'
Expand All @@ -375,6 +391,11 @@ class AddressDB(Base):
uuid: Mapped[str] = mapped_column(nullable=True)
active: Mapped[bool] = mapped_column(default=False)

user: Mapped['UserDB'] = relationship(
'UserDB',
back_populates='addresses',
)


class UserResetPasswordDB(Base):
__tablename__ = 'user_reset_password'
Expand Down
53 changes: 45 additions & 8 deletions app/order/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import math
from typing import Any

from app.entities.user import UserAddressInDB
from app.infra.constants import OrderStatus, PaymentStatus
from fastapi import HTTPException, status
from loguru import logger
from pydantic import TypeAdapter
from sqlalchemy import asc, func, select
from sqlalchemy.orm import Session, lazyload, selectinload
from sqlalchemy.orm import Session, joinedload, lazyload, selectinload
from app.product import repository
from faststream.rabbit import RabbitQueue

Expand All @@ -23,12 +24,14 @@
)
from app.infra.file_upload import optimize_image
from app.infra.models import (
AddressDB,
CategoryDB,
ImageGalleryDB,
InventoryDB,
ProductDB,
OrderDB,
OrderItemsDB,
UserDB,
)
from app.user.services import verify_admin
from app.entities.order import (
Expand Down Expand Up @@ -241,16 +244,19 @@ def get_orders(page, offset, *, db):
"""Get Orders Paid."""
with db().begin() as db:
orders_query = (
select(OrderDB)
.options(selectinload(OrderDB.items))
select(OrderDB).options(
joinedload(OrderDB.user),
joinedload(OrderDB.payment),
selectinload(OrderDB.items),
)
.order_by(OrderDB.order_id.desc())
)
total_records = db.session.scalar(select(func.count(OrderDB.order_id)))
if page > 1:
orders_query = orders_query.offset((page - 1) * offset)
orders_query = orders_query.limit(offset)

orders_db = db.session.execute(orders_query)
orders_db = db.session.execute(orders_query).unique()
adapter = TypeAdapter(list[OrderInDB])
return OrderResponse(
orders=adapter.validate_python(orders_db.scalars().all()),
Expand All @@ -265,7 +271,11 @@ def get_user_order(db: Session, user_id: int) -> list[OrderUserListResponse]:
"""Given order_id return Order with user data."""
with db:
order_query = (
select(OrderDB)
select(OrderDB).options(
joinedload(OrderDB.user),
joinedload(OrderDB.payment),
selectinload(OrderDB.items),
)
.where(OrderDB.user_id == user_id)
.order_by(OrderDB.order_id.desc())
)
Expand Down Expand Up @@ -313,18 +323,45 @@ def get_order(db: Session, order_id: int) -> OrderInDB:
with db:
order_query = (
select(OrderDB)
.options(
joinedload(OrderDB.user),
joinedload(OrderDB.payment),
joinedload(OrderDB.items).joinedload(OrderItemsDB.product),
joinedload(OrderDB.user).joinedload(UserDB.addresses.and_(
AddressDB.address_id == (
select(func.max(AddressDB.address_id))
.where(AddressDB.user_id == OrderDB.user_id)
),
)),
)
.where(OrderDB.order_id == order_id)
)
order = db.scalar(order_query)
return OrderInDB.model_validate(order)
_order = OrderInDB.model_validate(order)
last_address_subquery = (
select(AddressDB)
.where(AddressDB.user_id == order.user_id)
.order_by(AddressDB.address_id.desc())
.limit(1)
)
if order and order.user:
last_address = db.scalar(last_address_subquery)
if last_address:
_order.user.addresses = [UserAddressInDB.model_validate(last_address)]
else:
_order.user.addresses = []
return _order


def delete_order(order_id: int, *, cancel: CancelOrder, db) -> None:
"""Soft delete order."""
with db:
order_query = (
select(OrderDB)
.options(selectinload(OrderDB.items))
select(OrderDB).options(
joinedload(OrderDB.user),
joinedload(OrderDB.payment),
selectinload(OrderDB.items),
)
.where(OrderDB.order_id == order_id)
)
order = db.scalar(order_query)
Expand Down
8 changes: 6 additions & 2 deletions app/report/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from app.entities.user import UserInDB
from app.infra.constants import Roles
from sqlalchemy import select, and_
from sqlalchemy.orm import Session
from sqlalchemy.orm import Session, selectinload
from pydantic import TypeAdapter

from app.infra.models import CoProducerFeeDB, FeeDB, InformUserProductDB, SalesCommissionDB, UserDB
Expand Down Expand Up @@ -76,7 +76,11 @@ async def update_payment_commissions(
async def get_admins(transaction):
"""Get list of admins."""
async with transaction:
query = select(UserDB).where(UserDB.role_id == Roles.ADMIN.value)
query = select(UserDB).options(
selectinload(UserDB.addresses),
).where(
UserDB.role_id == Roles.ADMIN.value,
)
admin_db = await transaction.scalars(query)
adapter = TypeAdapter(list[UserInDB])
return adapter.validate_python(admin_db)
Expand Down
13 changes: 10 additions & 3 deletions app/user/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pydantic import TypeAdapter
from sqlalchemy import asc, func, select, update

from sqlalchemy.orm import selectinload
from sqlalchemy.sql import desc
from app.entities.user import UserFilters, UserInDB, UsersDBResponse
from app.infra import models
Expand All @@ -24,7 +25,9 @@ async def get_user_by_id(
transaction,
) -> models.UserDB:
"""Get an user by its id."""
user_query = select(models.UserDB).where(models.UserDB.user_id == user_id)
user_query = select(models.UserDB).options(
selectinload(models.UserDB.addresses),
).where(models.UserDB.user_id == user_id)
return await transaction.session.scalar(user_query)

async def get_user_by_username(
Expand All @@ -33,7 +36,9 @@ async def get_user_by_username(
transaction,
) -> models.UserDB | None:
"""Get an user by its username."""
user_query = select(models.UserDB).where(
user_query = select(models.UserDB).options(
selectinload(models.UserDB.addresses),
).where(
models.UserDB.username == username,
)
async with transaction:
Expand Down Expand Up @@ -61,7 +66,9 @@ async def get_users(
transaction,
):
"""Select all users."""
query_users = select(models.UserDB)
query_users = select(models.UserDB).options(
selectinload(models.UserDB.addresses),
)
if filters.search_name:
query_users = query_users.where(
models.UserDB.name.like(f'%{filters.search_name}'),
Expand Down
Loading

0 comments on commit 11c696d

Please sign in to comment.