diff options
| -rw-r--r-- | generalresearch/managers/thl/wallet/user_payout.py | 10 | ||||
| -rw-r--r-- | generalresearch/models/thl/wallet/cashout_method.py | 44 | ||||
| -rw-r--r-- | tests/managers/thl/test_payout.py | 12 | ||||
| -rw-r--r-- | tests/managers/thl/test_wallet/test_user_payout.py | 6 |
4 files changed, 47 insertions, 25 deletions
diff --git a/generalresearch/managers/thl/wallet/user_payout.py b/generalresearch/managers/thl/wallet/user_payout.py index 59d850b..88658f9 100644 --- a/generalresearch/managers/thl/wallet/user_payout.py +++ b/generalresearch/managers/thl/wallet/user_payout.py @@ -26,7 +26,7 @@ from generalresearch.models.thl.wallet.cashout_method import ( CashMailCashoutMethodRequestData, CashMailOrderData, CashoutMethod, - CashoutRequestInfo, + CashoutRequestDetail, PaypalCashoutMethodRequestData, TangoCashoutMethodRequestData, ) @@ -74,7 +74,7 @@ class UserPayoutEventManager(PayoutEventManager): return pe - def get_payout_detail(self, pe_uuid: UUIDStr) -> CashoutRequestInfo: + def get_payout_detail(self, pe_uuid: UUIDStr) -> CashoutRequestDetail: # This gets the payout event and then extracts information to return # to the user. pe = self.get_by_uuid(pe_uuid=pe_uuid) @@ -97,16 +97,16 @@ class UserPayoutEventManager(PayoutEventManager): ): transaction_info = order.model_dump(mode="json") - return CashoutRequestInfo( + return CashoutRequestDetail( id=pe_uuid, status=pe.status, description=pe.description or "", transaction_info=transaction_info, - message="", product_id=pe.user.product_id, product_user_id=pe.user.product_user_id, - amount=pe.amount, + amount=USDCent(pe.amount), payout_type=pe.payout_type, + created=pe.created ) def filter_by( diff --git a/generalresearch/models/thl/wallet/cashout_method.py b/generalresearch/models/thl/wallet/cashout_method.py index 2dd135b..af3dcda 100644 --- a/generalresearch/models/thl/wallet/cashout_method.py +++ b/generalresearch/models/thl/wallet/cashout_method.py @@ -5,7 +5,7 @@ import logging from datetime import UTC, datetime from decimal import Decimal from enum import StrEnum -from typing import Any, Literal, Self +from typing import TYPE_CHECKING, Any, Literal, Self from pydantic import ( BaseModel, @@ -31,6 +31,9 @@ from generalresearch.models.thl.user_identifiers import BPUIDStr from generalresearch.models.thl.user_ref import UserRef from generalresearch.models.thl.wallet.definitions import Currency, PayoutType +if TYPE_CHECKING: + from generalresearch.models.thl.payout import UserPayoutEvent + logger = logging.getLogger() example_cashout_method = { @@ -398,44 +401,61 @@ class CreateCashoutRequest(BaseModel): ) -class CashoutRequestInfo(BaseModel): +class CashoutRequestSummary(BaseModel): """See models.thl.payout: PayoutEvent. We've confused a CashOut and a Payout. This is used only in the API response. """ - id: UUIDStr | None = Field( - description="Unique ID for this cashout. This may be NULL if the " - "status is REJECTED or FAILED, which may happen if the " - "request is invalid.", + id: UUIDStr = Field( + description="Unique ID for this cashout", examples=["3ceb847aaf9f40f4bd15b2b5e083abf6"], ) description: str = Field( description="This is the name of the cashout method.", examples=["Visa® Prepaid Card USD"], ) - message: str | None = Field(default=None) status: PayoutStatus | None = Field( default=PayoutStatus.PENDING, description=PayoutStatus.as_openapi(), examples=[PayoutStatus.PENDING], ) - transaction_info: dict[str, Any] | None = Field(default=None) product_id: UUIDStr = Field() product_user_id: BPUIDStr = Field() payout_type: PayoutType = Field( description=PayoutType.as_openapi(), examples=[PayoutType.ACH] ) - amount: PositiveInt = Field( - lt=2**63 - 1, + amount: USDCent = Field( strict=True, - description="The USDCent amount int. This cannot be 0 or negative", + description="The amount in USD Cents", examples=[531], ) + created: AwareDatetimeISO = Field() + + @classmethod + def from_payout_event(cls, pe: UserPayoutEvent) -> Self: + return cls( + id=pe.uuid, + description=pe.description or "", + status=pe.status, + product_id=pe.user.product_id, + product_user_id=pe.user.product_user_id, + payout_type=pe.payout_type, + amount=USDCent(pe.amount), + created=pe.created, + ) + + +class CashoutRequestDetail(CashoutRequestSummary): + transaction_info: dict[str, Any] | None = Field(default=None) class CashoutRequestResponse(StatusResponse): - cashout: CashoutRequestInfo = Field() + cashout: CashoutRequestDetail = Field() + + +class CashoutRequestsResponse(StatusResponse): + cashouts: list[CashoutRequestSummary] = Field() example_foreign_value = { diff --git a/tests/managers/thl/test_payout.py b/tests/managers/thl/test_payout.py index be121d8..d5cc9e3 100644 --- a/tests/managers/thl/test_payout.py +++ b/tests/managers/thl/test_payout.py @@ -189,6 +189,7 @@ class TestPayout: thl_ledger_manager: ThlLedgerManager, product: Product, user: User, + user_factory, user_payout_event_manager: UserPayoutEventManager, utc_now: datetime, ): @@ -196,7 +197,8 @@ class TestPayout: from generalresearch.models.thl.wallet.definitions import PayoutType user_account = thl_ledger_manager.get_account_or_create_user_wallet(user=user) - bp_account = thl_ledger_manager.get_account_or_create_bp_wallet(product=product) + user2 = user_factory(product=user.product) + user_account2 = thl_ledger_manager.get_account_or_create_user_wallet(user=user2) user_payout_event_manager.create( status=PayoutStatus.PENDING, @@ -209,7 +211,7 @@ class TestPayout: user_payout_event_manager.create( status=PayoutStatus.PENDING, - debit_account_uuid=bp_account.uuid, + debit_account_uuid=user_account2.uuid, payout_type=PayoutType.PAYPAL, cashout_method_uuid=cashout_method_uuid, amount=200, @@ -222,12 +224,12 @@ class TestPayout: assert 1 == len(pes) pes = user_payout_event_manager.filter_by( - debit_account_uuids=[bp_account.uuid], created=utc_now + debit_account_uuids=[user_account2.uuid], created=utc_now ) assert 1 == len(pes) pes = user_payout_event_manager.filter_by( - debit_account_uuids=[bp_account.uuid], amount=123 + debit_account_uuids=[user_account2.uuid], amount=123 ) assert 0 == len(pes) @@ -237,7 +239,7 @@ class TestPayout: assert 0 == len(pes) pes = user_payout_event_manager.filter_by(product_ids=[user.product_id]) - assert 1 == len(pes) + assert 2 == len(pes) pes = user_payout_event_manager.filter_by( cashout_types=[PayoutType.PAYPAL], diff --git a/tests/managers/thl/test_wallet/test_user_payout.py b/tests/managers/thl/test_wallet/test_user_payout.py index bbc97a3..2a89c97 100644 --- a/tests/managers/thl/test_wallet/test_user_payout.py +++ b/tests/managers/thl/test_wallet/test_user_payout.py @@ -23,7 +23,7 @@ from generalresearch.models.thl.user import User from generalresearch.models.thl.wallet.cashout_method import ( CashMailCashoutMethodData, CashMailCashoutMethodRequestData, - CashoutRequestInfo, + CashoutRequestDetail, PaypalCashoutMethodData, PaypalCashoutMethodRequestData, USDeliveryAddress, @@ -103,7 +103,7 @@ class TestUserPayoutEventManager: ) res = user_payout_event_manager.get_payout_detail(pe_uuid=pe.uuid) - assert isinstance(res, CashoutRequestInfo) + assert isinstance(res, CashoutRequestDetail) def test_get_payout_detail_paypal( self, @@ -129,7 +129,7 @@ class TestUserPayoutEventManager: ) res = user_payout_event_manager.get_payout_detail(pe_uuid=pe.uuid) - assert isinstance(res, CashoutRequestInfo) + assert isinstance(res, CashoutRequestDetail) class TestUserRequestRedeem: |
