Spaces:
Sleeping
Sleeping
| 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"] | |
| ) | |
| 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 | |
| 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() | |
| 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 | |