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) ): """ Создаёт новый документ отправки с обновлёнными статусом и полями. """ # Проверяем, что текущий пользователь — отправитель if str(current_user["_id"]) != payload.sender: raise HTTPException(status_code=403, detail="Не авторизован как отправитель") # Валидация delivery_id try: delivery_id = ObjectId(payload.item) except Exception: raise HTTPException(status_code=400, detail="Неверный delivery ID") 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": payload.sender}, {"_id": 0} ) if not existing: raise HTTPException(status_code=404, detail="Доставка не найдена или не для вас") # Собираем новый документ для вставки notify = await notify_in_profile(NotifyItem( user_id=str(existing['receiver']['_id']), type_item='delivery', title='Доставка картин', link=f'/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 (iserted_id:=result.inserted_id): pass # send email return {"status": "success", "delivery_id": str(iserted_id)} @router.post("/accept") async def accept_delivery( payload: DeliveryAcceptRequest, current_user: dict = Depends(get_current_user) ): """ Создаёт новый документ отправки со статусом 'Получено'. """ try: delivery_id = ObjectId(payload.item) except Exception: raise HTTPException(status_code=400, detail="Неверный delivery ID") # Берём исходный документ, чтобы вставить новый existing = await delivery_collection.find_one( {"_id": delivery_id, "receiver._id": current_user["_id"]}, {"_id": 0} ) if not existing: raise HTTPException(status_code=404, detail="Доставка не найдена или не для вас") notify = await notify_in_profile(NotifyItem( user_id=str(existing['sender']['_id']), type_item='delivery', title='Доставка картин', link=f'/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) await notify_collection.update_one({'_id': existing['notify']}, {'$set': {'read': False}}) return {"status": "success", "delivery_id": str(result.inserted_id)}