hisham-cmd's picture
Upload routers/orders.py
c27aa86 verified
Raw
History Blame Contribute Delete
3.44 kB
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from typing import List
from database.session import get_db
from database.models import Order as OrderModel, User as UserModel, Service as ServiceModel
from auth import get_current_user
import schemas
router = APIRouter(
prefix="/orders",
tags=["orders"]
)
@router.post("/", response_model=schemas.Order, status_code=status.HTTP_201_CREATED)
async def create_order(
order: schemas.OrderCreate,
current_user: UserModel = Depends(get_current_user),
db: AsyncSession = Depends(get_db)
):
"""
Create a new order. Deducts balance from user.
"""
# 1. Check if service exists and is active
result = await db.execute(select(ServiceModel).where(ServiceModel.id == order.service_id))
service = result.scalar_one_or_none()
if not service or not service.is_active:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Service not found or inactive")
# 2. Validate quantity limits
if order.quantity < service.min_quantity or order.quantity > service.max_quantity:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Quantity must be between {service.min_quantity} and {service.max_quantity}"
)
# 3. Calculate charge
charge = (service.price / 1000) * order.quantity
# 4. Check user balance
if current_user.balance < charge:
raise HTTPException(status_code=status.HTTP_402_PAYMENT_REQUIRED, detail="Insufficient balance")
# 5. Deduct balance
current_user.balance -= charge
current_user.spent += charge
# 6. Create order
new_order = OrderModel(
user_id=current_user.id,
service_id=service.id,
link=order.link,
quantity=order.quantity,
charge=charge,
remains=order.quantity,
status="Pending",
api_provider_id=service.api_provider_id
)
db.add(new_order)
# 7. Update service stats
service.total_orders += 1
await db.commit()
await db.refresh(new_order)
return new_order
@router.get("/", response_model=List[schemas.Order])
async def get_orders(
skip: int = 0,
limit: int = 100,
current_user: UserModel = Depends(get_current_user),
db: AsyncSession = Depends(get_db)
):
"""
Get user's orders.
"""
result = await db.execute(
select(OrderModel)
.where(OrderModel.user_id == current_user.id)
.order_by(OrderModel.created_at.desc())
.offset(skip)
.limit(limit)
)
return result.scalars().all()
@router.get("/{order_id}", response_model=schemas.Order)
async def get_order(
order_id: int,
current_user: UserModel = Depends(get_current_user),
db: AsyncSession = Depends(get_db)
):
"""
Get specific order details.
"""
result = await db.execute(
select(OrderModel)
.where(OrderModel.id == order_id)
.where(OrderModel.user_id == current_user.id)
)
order = result.scalar_one_or_none()
if not order:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Order not found")
return order