from datetime import datetime, timezone from fastapi import HTTPException, status from sqlalchemy.orm import Session from ..accounts.models import Account from .dto import ContactCreate, ContactUpdate from .models import Contact def _validate_account(db: Session, account_id: int | None, tenant_id: int, company_id: int) -> None: """Verifica que la cuenta referenciada exista dentro del tenant/company.""" if account_id is None: return exists = ( db.query(Account.id) .filter( Account.id == account_id, Account.tenant_id == tenant_id, Account.company_id == company_id, Account.deleted_at.is_(None), ) .first() ) if not exists: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="La cuenta asociada no existe", ) def get_contacts( db: Session, tenant_id: int, company_id: int, search: str | None = None, account_id: int | None = None, ) -> list[Contact]: query = db.query(Contact).filter( Contact.tenant_id == tenant_id, Contact.company_id == company_id, Contact.deleted_at.is_(None), ) if account_id is not None: query = query.filter(Contact.account_id == account_id) if search: pattern = f"%{search}%" query = query.filter( Contact.first_name.ilike(pattern) | Contact.last_name.ilike(pattern) | Contact.email.ilike(pattern) ) return query.order_by(Contact.first_name.asc()).all() def get_contact(db: Session, contact_id: int, tenant_id: int, company_id: int) -> Contact: contact = ( db.query(Contact) .filter( Contact.id == contact_id, Contact.tenant_id == tenant_id, Contact.company_id == company_id, Contact.deleted_at.is_(None), ) .first() ) if not contact: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Contacto no encontrado") return contact def create_contact(db: Session, payload: ContactCreate, tenant_id: int, company_id: int) -> Contact: _validate_account(db, payload.account_id, tenant_id, company_id) contact = Contact(**payload.model_dump(), tenant_id=tenant_id, company_id=company_id) db.add(contact) db.commit() db.refresh(contact) return contact def update_contact( db: Session, contact_id: int, payload: ContactUpdate, tenant_id: int, company_id: int ) -> Contact: contact = get_contact(db, contact_id, tenant_id, company_id) data = payload.model_dump(exclude_unset=True) if "account_id" in data: _validate_account(db, data["account_id"], tenant_id, company_id) for field, value in data.items(): setattr(contact, field, value) db.commit() db.refresh(contact) return contact def delete_contact(db: Session, contact_id: int, tenant_id: int, company_id: int) -> None: contact = get_contact(db, contact_id, tenant_id, company_id) contact.deleted_at = datetime.now(timezone.utc) db.commit()