Files
badoHair_be/app/routers/admin/orders.py
belviskhoremk d2dc43b16f Initial Commit
2026-05-12 00:34:21 +00:00

90 lines
2.7 KiB
Python

import csv
import io
from datetime import date
from typing import Annotated
from fastapi import APIRouter, Depends, Query
from fastapi.responses import StreamingResponse
import asyncpg
from app.core.pagination import pagination_params
from app.core.responses import ok, paginated
from app.dependencies import get_db, require_admin
from app.models.orders import UpdateOrderStatus, RefundRequest
from app.services import order_service
router = APIRouter(prefix="/orders", tags=["Admin — Orders"])
@router.get("")
async def list_orders(
pagination: Annotated[tuple, Depends(pagination_params)],
status: str | None = Query(None),
from_date: date | None = Query(None),
to_date: date | None = Query(None),
db: asyncpg.Connection = Depends(get_db),
_: dict = Depends(require_admin),
):
page, per_page, offset = pagination
orders, total = await order_service.list_orders(db, page, per_page, offset, status=status)
return paginated(orders, total, page, per_page)
@router.get("/export")
async def export_orders(
status: str | None = Query(None),
db: asyncpg.Connection = Depends(get_db),
_: dict = Depends(require_admin),
):
rows = await db.fetch(
"""
SELECT o.id, p.email, p.full_name, o.status, o.total_amount, o.created_at
FROM orders o
JOIN profiles p ON p.id = o.user_id
ORDER BY o.created_at DESC
"""
)
output = io.StringIO()
writer = csv.writer(output)
writer.writerow(["ID", "Email", "Name", "Status", "Total", "Date"])
for r in rows:
writer.writerow([r["id"], r["email"], r["full_name"], r["status"], r["total_amount"], r["created_at"]])
output.seek(0)
return StreamingResponse(
iter([output.getvalue()]),
media_type="text/csv",
headers={"Content-Disposition": "attachment; filename=orders.csv"},
)
@router.get("/{order_id}")
async def get_order(
order_id: str,
db: asyncpg.Connection = Depends(get_db),
_: dict = Depends(require_admin),
):
order = await order_service.get_order(db, order_id)
return ok(order)
@router.patch("/{order_id}/status")
async def update_status(
order_id: str,
body: UpdateOrderStatus,
db: asyncpg.Connection = Depends(get_db),
admin: dict = Depends(require_admin),
):
order = await order_service.update_order_status(db, order_id, body.status, str(admin["id"]))
return ok(order)
@router.post("/{order_id}/refund")
async def refund_order(
order_id: str,
body: RefundRequest,
db: asyncpg.Connection = Depends(get_db),
admin: dict = Depends(require_admin),
):
order = await order_service.refund_order(db, order_id, str(admin["id"]), body.amount, body.reason)
return ok(order)