This commit is contained in:
xds
2026-03-22 12:40:33 +03:00
commit 28a5d51389
61 changed files with 6085 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
import logging
import uuid
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.models.calculation import Calculation
from app.models.material import Material
from app.models.order import Order
from app.schemas.order import OrderCreate, OrderResponse
from app.services.telegram_notify import notify_new_order
logger = logging.getLogger("app.routers.orders")
router = APIRouter()
async def generate_order_id(db: AsyncSession) -> str:
year = datetime.now().year
result = await db.execute(
select(func.count(Order.id)).where(Order.order_id.like(f"ORD-{year}-%"))
)
count = result.scalar() or 0
order_id = f"ORD-{year}-{count + 1:04d}"
logger.debug("Generated order_id: %s (existing count: %d)", order_id, count)
return order_id
@router.post("/orders", response_model=OrderResponse)
async def create_order(order_data: OrderCreate, db: AsyncSession = Depends(get_db)):
logger.info("===== POST /api/orders =====")
logger.info("Client: name=%s, phone=%s, email=%s, company=%s",
order_data.client_name, order_data.client_phone,
order_data.client_email, order_data.client_company)
logger.info("Calculation ID: %s", order_data.calculation_id)
logger.info("Delivery: %s, comment: %s", order_data.delivery_method, order_data.comment)
# Get calculation
try:
calc_uuid = uuid.UUID(order_data.calculation_id)
except ValueError:
logger.warning("Invalid calculation_id format: %s", order_data.calculation_id)
raise HTTPException(400, "Некорректный calculation_id")
logger.info("Looking up calculation: %s", calc_uuid)
result = await db.execute(select(Calculation).where(Calculation.id == calc_uuid))
calc = result.scalar_one_or_none()
if not calc:
logger.warning("Calculation not found: %s", calc_uuid)
raise HTTPException(404, "Расчёт не найден")
logger.info("Calculation found: total=%.2f RUB, material_id=%d, estimated_days=%s",
calc.total_rub, calc.material_id, calc.estimated_days)
# Get material name for notification
logger.debug("Looking up material id=%d for notification...", calc.material_id)
mat_result = await db.execute(select(Material).where(Material.id == calc.material_id))
material = mat_result.scalar_one_or_none()
material_name = material.name if material else "Неизвестный"
logger.info("Material for notification: %s", material_name)
order_id = await generate_order_id(db)
estimated_ready = datetime.now() + timedelta(days=calc.estimated_days or 3)
logger.info("Order ID: %s, estimated ready: %s", order_id, estimated_ready.strftime("%Y-%m-%d"))
order = Order(
order_id=order_id,
calculation_id=calc.id,
client_name=order_data.client_name,
client_phone=order_data.client_phone,
client_email=order_data.client_email,
client_company=order_data.client_company,
delivery_method=order_data.delivery_method,
comment=order_data.comment,
total_rub=calc.total_rub,
)
db.add(order)
await db.commit()
await db.refresh(order)
logger.info("Order saved to database: id=%d, order_id=%s", order.id, order_id)
# Send Telegram notification
logger.info("Sending Telegram notification...")
try:
await notify_new_order(
order_id=order_id,
client_name=order_data.client_name,
client_phone=order_data.client_phone,
material_name=material_name,
total_rub=calc.total_rub,
comment=order_data.comment,
)
logger.info("Telegram notification sent successfully")
except Exception:
logger.exception("Telegram notification failed (order still created)")
logger.info("===== Order created: %s -> %.2f RUB =====", order_id, calc.total_rub)
return OrderResponse(
order_id=order_id,
status="pending",
total_rub=calc.total_rub,
estimated_ready_date=estimated_ready.strftime("%Y-%m-%d"),
)