"""Direct Payments Payment Model.""" from datetime import datetime from decimal import Decimal import enum from typing import Optional from sqlalchemy import Enum, ForeignKey, Numeric, String from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.sql import func from collaborator.connectors import mysql class PayoneerEventType(str, enum.Enum): """Type of event received from Abacus Payoneer lambda.""" PAYMENT_ACCEPTED = "payment_accepted" PAYMENT_COMPLETED = "payment_completed" PAYMENT_CANCELLED = "payment_cancelled" IACH_FAILED = "iach_failed" class PayoneerPaymentStatus(str, enum.Enum): """Payoneer payment status values stored in dp_payment.payoneer_payment_status.""" INIT = "init" RUNNING = "running" ERROR = "error" COMPLETE = "complete" REJECTED = "rejected" class DpPayment(mysql.BaseModel): """Encapsulates DP payment data. Represents dp_payment in the collaborator database. """ __tablename__ = "dp_payment" dp_payment_id: Mapped[int] = mapped_column("id", primary_key=True) abacus_statement_period_id: Mapped[int] abacus_statement_period_name: Mapped[str] collaborator_id: Mapped[int] = mapped_column( ForeignKey("collaborator.id", ondelete="RESTRICT", onupdate="CASCADE"), ) collaborator_name: Mapped[str] amount: Mapped[Decimal] = mapped_column(Numeric(18, 6)) currency: Mapped[str] payee_id: Mapped[int] payoneer_program_id: Mapped[str] payoneer_program_name: Mapped[str] payoneer_client_reference_id: Mapped[Optional[str]] created_date: Mapped[Optional[datetime]] = mapped_column(default=func.now()) created_by: Mapped[Optional[str]] approved_date: Mapped[Optional[datetime]] approved_by: Mapped[Optional[str]] updated_date: Mapped[Optional[datetime]] = mapped_column( default=func.now(), onupdate=func.now() ) updated_by: Mapped[Optional[str]] account_id: Mapped[int] account_name: Mapped[str] collaborator_transaction_id: Mapped[Optional[int]] = mapped_column( ForeignKey("transaction.id", ondelete="RESTRICT", onupdate="CASCADE"), ) agreement_type: Mapped[Optional[str]] payoneer_payment_id: Mapped[Optional[str]] = mapped_column(String(255), unique=True) # Use enum values (e.g. "init"), instead of SQLAlchemy default of names (e.g. "INIT") payoneer_payment_status: Mapped[Optional[PayoneerPaymentStatus]] = mapped_column( Enum(PayoneerPaymentStatus, values_callable=lambda x: [i.value for i in x]), ) latest_payoneer_event: Mapped[Optional[PayoneerEventType]] = mapped_column( Enum(PayoneerEventType, values_callable=lambda x: [i.value for i in x]), ) latest_payoneer_event_reason: Mapped[Optional[str]] = mapped_column(String(255))