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