from datetime import datetime, timezone from fastapi import HTTPException, status from sqlalchemy.orm import Session from ..accounts.models import Account from ..suppliers.models import Supplier from .dto import DocumentCreate, DocumentUpdate from .models import Document def _validate_owner(db: Session, account_id: int | None, supplier_id: int | None, tenant_id: int, company_id: int) -> None: """Un documento debe pertenecer a exactamente un cliente o proveedor existente.""" if (account_id is None) == (supplier_id is None): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="El documento debe asociarse a un cliente O a un proveedor", ) model, _id, msg = ( (Account, account_id, "El cliente asociado no existe") if account_id is not None else (Supplier, supplier_id, "El proveedor asociado no existe") ) exists = ( db.query(model.id) .filter( model.id == _id, model.tenant_id == tenant_id, model.company_id == company_id, model.deleted_at.is_(None), ) .first() ) if not exists: raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=msg) def get_documents( db: Session, tenant_id: int, company_id: int, account_id: int | None = None, supplier_id: int | None = None, ) -> list[Document]: query = db.query(Document).filter( Document.tenant_id == tenant_id, Document.company_id == company_id, Document.deleted_at.is_(None), ) if account_id is not None: query = query.filter(Document.account_id == account_id) if supplier_id is not None: query = query.filter(Document.supplier_id == supplier_id) return query.order_by(Document.created_at.desc()).all() def get_document(db: Session, document_id: int, tenant_id: int, company_id: int) -> Document: document = ( db.query(Document) .filter( Document.id == document_id, Document.tenant_id == tenant_id, Document.company_id == company_id, Document.deleted_at.is_(None), ) .first() ) if not document: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Documento no encontrado") return document def create_document( db: Session, payload: DocumentCreate, tenant_id: int, company_id: int, user_id: str | None = None ) -> Document: _validate_owner(db, payload.account_id, payload.supplier_id, tenant_id, company_id) document = Document( **payload.model_dump(), tenant_id=tenant_id, company_id=company_id, uploaded_by=user_id ) db.add(document) db.commit() db.refresh(document) return document def update_document( db: Session, document_id: int, payload: DocumentUpdate, tenant_id: int, company_id: int ) -> Document: document = get_document(db, document_id, tenant_id, company_id) for field, value in payload.model_dump(exclude_unset=True).items(): setattr(document, field, value) db.commit() db.refresh(document) return document def delete_document(db: Session, document_id: int, tenant_id: int, company_id: int) -> None: document = get_document(db, document_id, tenant_id, company_id) document.deleted_at = datetime.now(timezone.utc) db.commit()