Spaces:
Sleeping
Sleeping
File size: 3,437 Bytes
c27aa86 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 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
|