"""Recipient Persister. Handles doing CRUD operations on the recipient table. """ from datetime import datetime, timezone from sqlalchemy.orm.session import Session from collaborator.connectors import mysql from collaborator.constants import error from collaborator.models.rds.collaborator import Collaborator from collaborator.models.rds.recipient import Recipient from collaborator.utils.error import OwsError from collaborator.utils.typing import User class RecipientPersister: """Handles high level operations for Recipients.""" @classmethod @mysql.db_session def create_recipient( cls, transferwise_id: int, name: str, currency: str, user: User, session: Session, ) -> dict: """Create a Recipient. Args: transferwise_id (int): External TransferWise ID of the recipient. name (int): Recipient's name. currency (str): Currency code user (User): User that created the recipient. session (sqlalchemy.orm.session.Session): Database session. Returns: dict: the newly created recipient """ recipient = Recipient( transferwise_id=transferwise_id, name=name, currency=currency, created_by=str(user), ) session.add(recipient) session.commit() # so a newly created entry gets an ID return recipient.to_dict() @classmethod @mysql.db_session def delete_recipient(cls, recipient_id: int, user: User, session: Session): """Soft delete a Recipient. Args: recipient_id (int): Primary key of the recipient being deleted. user (User): User that is deleted the recipient. session (sqlalchemy.orm.session.Session): Database session. Returns: Response: Response object with HTTP 204 No Content status """ query = session.query(Recipient).filter_by(recipient_id=recipient_id) recipient = query.first() if not recipient: raise OwsError.not_found( code=error.ERROR_CODE_RECIPIENT_NOT_FOUND, message=error.ERROR_MESSAGE_RECIPIENT_NOT_FOUND, ) deleted_datetime = datetime.now(tz=timezone.utc) query.update({"deleted_by": str(user), "deleted_date": deleted_datetime}) @classmethod @mysql.db_session def get_recipient(cls, recipient_id: int, session: Session) -> dict: """Get a Recipient. Args: recipient_id (int): Primary key for the recipient. Returns: dict: the recipient """ query = session.query(Recipient).filter_by(recipient_id=recipient_id) recipient = query.first() if not recipient: raise OwsError.not_found( code=error.ERROR_CODE_RECIPIENT_NOT_FOUND, message=error.ERROR_MESSAGE_RECIPIENT_NOT_FOUND, ) return recipient.to_dict() @classmethod @mysql.db_session def get_recipients_by_id(cls, recipient_ids: list[int], session: Session) -> list: """Get a list of Recipients by given IDs. Args: recipient_id (int): Primary key for the recipient. Returns: list: the recipients """ results = ( session.query(Recipient) .filter(Recipient.recipient_id.in_(recipient_ids)) .all() ) if not results: raise OwsError.not_found( code=error.ERROR_CODE_RECIPIENT_NOT_FOUND, message=error.ERROR_MESSAGE_RECIPIENT_NOT_FOUND, ) return [item.to_dict() for item in results] @classmethod @mysql.db_session def get_vendor_id_by_transferwise_id( cls, transferwise_id: int, session: Session ) -> dict: """Get the vendor ID for a given recipient's wise recipient ID. Args: transferwise_id (int): Wise recipient ID. Returns: dict: the vendor ID """ query = ( session.query(Collaborator, Recipient) .join(Recipient) .filter( Collaborator.recipient_id == Recipient.recipient_id, Recipient.transferwise_id == transferwise_id, ) ) result = query.first() if not result: raise OwsError.not_found( code=error.ERROR_CODE_RECIPIENT_NOT_FOUND, message=error.ERROR_MESSAGE_RECIPIENT_NOT_FOUND, ) collab, _ = result return collab.to_dict()["vendor_id"]