"""Transaction Model.""" from datetime import date, datetime from decimal import Decimal from typing import Optional from sqlalchemy import Enum, ForeignKey, Numeric from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.sql import func from collaborator.connectors import mysql from collaborator.constants.transaction import TransactionType class Transaction(mysql.BaseModel): """A transaction.""" __tablename__ = "transaction" transaction_id: Mapped[int] = mapped_column("id", primary_key=True) collaborator_id: Mapped[int] = mapped_column(ForeignKey("collaborator.id")) date: Mapped[date] transaction_type: Mapped[TransactionType] = mapped_column( "type", Enum(TransactionType) ) description: Mapped[Optional[str]] original_amount: Mapped[Decimal] = mapped_column(Numeric(18, 6)) collaborator_share: Mapped[Optional[float]] chargeable_amount: Mapped[Decimal] = mapped_column(Numeric(18, 6)) transferwise_transaction_id: Mapped[Optional[int]] = mapped_column( ForeignKey("transferwise_transaction.id") ) report_id: Mapped[Optional[int]] created_date: Mapped[datetime] = mapped_column(default=func.now()) voided_transaction_id: Mapped[Optional[int]] = mapped_column( ForeignKey("transaction.id") ) currency: Mapped[str] deleted_date: Mapped[Optional[datetime]] statement_period_id: Mapped[int] = mapped_column(ForeignKey("statement_period.id")) creation_batch_uuid: Mapped[Optional[str]] credited_payment_id: Mapped[Optional[int]] def to_dict(self) -> dict: """Convert the transaction to a dictionary. Returns: dict """ deleted_date_iso_format = ( self.deleted_date.isoformat() if isinstance(self.deleted_date, datetime) else self.deleted_date ) return { "id": self.transaction_id, "collaborator_id": self.collaborator_id, "date": self.date.isoformat(), "type": self.transaction_type, "description": self.description, "original_amount": float(self.original_amount), "collaborator_share": self.collaborator_share, "chargeable_amount": float(self.chargeable_amount), "transferwise_transaction_id": self.transferwise_transaction_id, "report_id": self.report_id, "created_date": self.created_date.isoformat(), "voided_transaction_id": self.voided_transaction_id, "credited_payment_id": self.credited_payment_id, "currency": self.currency, "deleted_date": deleted_date_iso_format, # TODO: remove this once it is no longer expected by GraphQL "current_balance": 0, "statement_period_id": self.statement_period_id, "creation_batch_uuid": self.creation_batch_uuid, }