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 }