avtopost.kultmost.ru/delivery_router.py
2026-08-27 08:39:48 -04:00

145 lines
5.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import APIRouter, Depends, HTTPException
from bson import ObjectId
from datetime import datetime
from models import DeliveryAcceptRequest, DeliverySendRequest
from db import delivery_collection, notify_collection
from auth import get_current_user
from tasks import notify_in_profile
from models import NotifyItem
router = APIRouter(prefix="/api/delivery", tags=["delivery"])
@router.post("/send")
async def send_delivery(
payload: DeliverySendRequest,
current_user: dict = Depends(get_current_user)
):
"""
Массовая отправка: создаёт новый документ для каждого выбранного item.
"""
results = []
errors = []
for entry in payload.items:
# Проверяем, что текущий пользователь — отправитель
if str(current_user["_id"]) != entry.sender:
errors.append({"item": entry.item, "error": "Не авторизован как отправитель"})
continue
# Валидация delivery_id
try:
delivery_id = ObjectId(entry.item)
except Exception:
errors.append({"item": entry.item, "error": "Неверный delivery ID"})
continue
update_data = {
"status": "Ожидает получения",
"delivery_type": payload.delivery_type,
"sent_at": datetime.utcnow(),
"updated_at": datetime.utcnow(),
}
# Добавляем трек только для СДЭК
if payload.delivery_type == "СДЭК" and payload.track:
update_data["track"] = payload.track
# Ищем существующую запись
existing = await delivery_collection.find_one(
{"_id": delivery_id, "sender._id": entry.sender},
{"_id": 0}
)
if not existing:
errors.append({"item": entry.item, "error": "Доставка не найдена или не для вас"})
continue
# Уведомление получателю
notify = await notify_in_profile(NotifyItem(
user_id=str(existing["receiver"]["_id"]),
type_item="delivery",
title="Доставка картин",
link="/profile/delivery",
text=f"{str(existing['sender']['username'])} — прислал вам картины."
))
new_doc = {**existing, **update_data, "notify": notify.upserted_id}
result = await delivery_collection.insert_one(new_doc)
if result.inserted_id:
# TODO: send email
results.append({
"item": entry.item,
"delivery_id": str(result.inserted_id)
})
return {
"status": "success" if not errors else "partial",
"processed": results,
"errors": errors
}
@router.post("/accept")
async def accept_delivery(
payload: DeliveryAcceptRequest,
current_user: dict = Depends(get_current_user)
):
"""
Массовое получение: создаёт новый документ со статусом 'Получено' для каждого item.
"""
results = []
errors = []
for item_id in payload.items:
try:
delivery_id = ObjectId(item_id)
except Exception:
errors.append({"item": item_id, "error": "Неверный delivery ID"})
continue
existing = await delivery_collection.find_one(
{"_id": delivery_id, "receiver._id": current_user["_id"]},
{"_id": 0}
)
if not existing:
errors.append({"item": item_id, "error": "Доставка не найдена или не для вас"})
continue
# Уведомление отправителю
notify = await notify_in_profile(NotifyItem(
user_id=str(existing["sender"]["_id"]),
type_item="delivery",
title="Доставка картин",
link="/profile/delivery",
text=f"Картина «{existing['title']}» получена — {str(existing['receiver']['username'])}."
))
new_doc = {
**existing,
"status": "Получено",
"notify": notify.upserted_id,
"received_at": datetime.utcnow(),
"updated_at": datetime.utcnow(),
}
result = await delivery_collection.insert_one(new_doc)
# Помечаем предыдущее уведомление как непрочитанное (если нужно)
if existing.get("notify"):
await notify_collection.update_one(
{"_id": existing["notify"]},
{"$set": {"read": False}}
)
results.append({
"item": item_id,
"delivery_id": str(result.inserted_id)
})
return {
"status": "success" if not errors else "partial",
"processed": results,
"errors": errors
}