Skip to content

Commit

Permalink
chore(api): adds charge_off functionality to FinancialAccounts (#613)
Browse files Browse the repository at this point in the history
- adds `CHARGED_OFF` to `financial_account_states` property
- adds `charged_off_reason` property
- adds `charge_off` method
  • Loading branch information
stainless-app[bot] authored and stainless-bot committed Oct 30, 2024
1 parent 8931217 commit 44895bb
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
configured_endpoints: 154
configured_endpoints: 155
1 change: 1 addition & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ Methods:
- <code title="get /v1/financial_accounts/{financial_account_token}">client.financial_accounts.<a href="./src/lithic/resources/financial_accounts/financial_accounts.py">retrieve</a>(financial_account_token) -> <a href="./src/lithic/types/financial_account.py">FinancialAccount</a></code>
- <code title="patch /v1/financial_accounts/{financial_account_token}">client.financial_accounts.<a href="./src/lithic/resources/financial_accounts/financial_accounts.py">update</a>(financial_account_token, \*\*<a href="src/lithic/types/financial_account_update_params.py">params</a>) -> <a href="./src/lithic/types/financial_account.py">FinancialAccount</a></code>
- <code title="get /v1/financial_accounts">client.financial_accounts.<a href="./src/lithic/resources/financial_accounts/financial_accounts.py">list</a>(\*\*<a href="src/lithic/types/financial_account_list_params.py">params</a>) -> <a href="./src/lithic/types/financial_account.py">SyncSinglePage[FinancialAccount]</a></code>
- <code title="patch /v1/financial_accounts/{financial_account_token}/charge_off">client.financial_accounts.<a href="./src/lithic/resources/financial_accounts/financial_accounts.py">charge_off</a>(financial_account_token, \*\*<a href="src/lithic/types/financial_account_charge_off_params.py">params</a>) -> <a href="./src/lithic/types/financial_accounts/financial_account_credit_config.py">FinancialAccountCreditConfig</a></code>

## Balances

Expand Down
96 changes: 96 additions & 0 deletions src/lithic/resources/financial_accounts/financial_accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
financial_account_list_params,
financial_account_create_params,
financial_account_update_params,
financial_account_charge_off_params,
)
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
from ..._utils import (
Expand Down Expand Up @@ -64,6 +65,7 @@
AsyncFinancialTransactionsWithStreamingResponse,
)
from ...types.financial_account import FinancialAccount
from ...types.financial_accounts.financial_account_credit_config import FinancialAccountCreditConfig

__all__ = ["FinancialAccounts", "AsyncFinancialAccounts"]

Expand Down Expand Up @@ -275,6 +277,47 @@ def list(
model=FinancialAccount,
)

def charge_off(
self,
financial_account_token: str,
*,
reason: Literal["DELINQUENT", "FRAUD"],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> FinancialAccountCreditConfig:
"""
Update issuing account state to charged off
Args:
reason: Reason for the financial account being marked as Charged Off
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
if not financial_account_token:
raise ValueError(
f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}"
)
return self._patch(
f"/v1/financial_accounts/{financial_account_token}/charge_off",
body=maybe_transform(
{"reason": reason}, financial_account_charge_off_params.FinancialAccountChargeOffParams
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=FinancialAccountCreditConfig,
)


class AsyncFinancialAccounts(AsyncAPIResource):
@cached_property
Expand Down Expand Up @@ -485,6 +528,47 @@ def list(
model=FinancialAccount,
)

async def charge_off(
self,
financial_account_token: str,
*,
reason: Literal["DELINQUENT", "FRAUD"],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> FinancialAccountCreditConfig:
"""
Update issuing account state to charged off
Args:
reason: Reason for the financial account being marked as Charged Off
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
if not financial_account_token:
raise ValueError(
f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}"
)
return await self._patch(
f"/v1/financial_accounts/{financial_account_token}/charge_off",
body=await async_maybe_transform(
{"reason": reason}, financial_account_charge_off_params.FinancialAccountChargeOffParams
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=FinancialAccountCreditConfig,
)


class FinancialAccountsWithRawResponse:
def __init__(self, financial_accounts: FinancialAccounts) -> None:
Expand All @@ -502,6 +586,9 @@ def __init__(self, financial_accounts: FinancialAccounts) -> None:
self.list = _legacy_response.to_raw_response_wrapper(
financial_accounts.list,
)
self.charge_off = _legacy_response.to_raw_response_wrapper(
financial_accounts.charge_off,
)

@cached_property
def balances(self) -> BalancesWithRawResponse:
Expand Down Expand Up @@ -540,6 +627,9 @@ def __init__(self, financial_accounts: AsyncFinancialAccounts) -> None:
self.list = _legacy_response.async_to_raw_response_wrapper(
financial_accounts.list,
)
self.charge_off = _legacy_response.async_to_raw_response_wrapper(
financial_accounts.charge_off,
)

@cached_property
def balances(self) -> AsyncBalancesWithRawResponse:
Expand Down Expand Up @@ -578,6 +668,9 @@ def __init__(self, financial_accounts: FinancialAccounts) -> None:
self.list = to_streamed_response_wrapper(
financial_accounts.list,
)
self.charge_off = to_streamed_response_wrapper(
financial_accounts.charge_off,
)

@cached_property
def balances(self) -> BalancesWithStreamingResponse:
Expand Down Expand Up @@ -616,6 +709,9 @@ def __init__(self, financial_accounts: AsyncFinancialAccounts) -> None:
self.list = async_to_streamed_response_wrapper(
financial_accounts.list,
)
self.charge_off = async_to_streamed_response_wrapper(
financial_accounts.charge_off,
)

@cached_property
def balances(self) -> AsyncBalancesWithStreamingResponse:
Expand Down
1 change: 1 addition & 0 deletions src/lithic/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
from .external_bank_account_create_params import ExternalBankAccountCreateParams as ExternalBankAccountCreateParams
from .external_bank_account_list_response import ExternalBankAccountListResponse as ExternalBankAccountListResponse
from .external_bank_account_update_params import ExternalBankAccountUpdateParams as ExternalBankAccountUpdateParams
from .financial_account_charge_off_params import FinancialAccountChargeOffParams as FinancialAccountChargeOffParams
from .management_operation_reverse_params import ManagementOperationReverseParams as ManagementOperationReverseParams
from .transaction_simulate_clearing_params import TransactionSimulateClearingParams as TransactionSimulateClearingParams
from .transaction_simulate_return_response import TransactionSimulateReturnResponse as TransactionSimulateReturnResponse
Expand Down
11 changes: 8 additions & 3 deletions src/lithic/types/financial_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@


class CreditConfiguration(BaseModel):
charged_off_reason: Optional[Literal["DELINQUENT", "FRAUD"]] = None
"""Reason for the financial account being marked as Charged Off"""

credit_limit: Optional[int] = None

credit_product_token: Optional[str] = None
"""Globally unique identifier for the credit product"""

external_bank_account_token: Optional[str] = None

financial_account_state: Optional[Literal["PENDING", "CURRENT", "DELINQUENT", "CHARGED_OFF"]] = None
"""State of the financial account"""

is_spend_blocked: bool

tier: Optional[str] = None
"""Tier assigned to the financial account"""

financial_account_state: Optional[Literal["PENDING", "CURRENT", "DELINQUENT"]] = None
"""State of the financial account"""


class FinancialAccount(BaseModel):
token: str
Expand Down
12 changes: 12 additions & 0 deletions src/lithic/types/financial_account_charge_off_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from __future__ import annotations

from typing_extensions import Literal, Required, TypedDict

__all__ = ["FinancialAccountChargeOffParams"]


class FinancialAccountChargeOffParams(TypedDict, total=False):
reason: Required[Literal["DELINQUENT", "FRAUD"]]
"""Reason for the financial account being marked as Charged Off"""
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@ class FinancialAccountCreditConfig(BaseModel):
account_token: str
"""Globally unique identifier for the account"""

charged_off_reason: Optional[Literal["DELINQUENT", "FRAUD"]] = None
"""Reason for the financial account being marked as Charged Off"""

credit_limit: Optional[int] = None

credit_product_token: Optional[str] = None
"""Globally unique identifier for the credit product"""

external_bank_account_token: Optional[str] = None

tier: Optional[str] = None
"""Tier assigned to the financial account"""

financial_account_state: Optional[Literal["PENDING", "CURRENT", "DELINQUENT"]] = None
financial_account_state: Literal["PENDING", "CURRENT", "DELINQUENT", "CHARGED_OFF"]
"""State of the financial account"""

is_spend_blocked: Optional[bool] = None
is_spend_blocked: bool

tier: Optional[str] = None
"""Tier assigned to the financial account"""
89 changes: 89 additions & 0 deletions tests/api_resources/test_financial_accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
FinancialAccount,
)
from lithic.pagination import SyncSinglePage, AsyncSinglePage
from lithic.types.financial_accounts import FinancialAccountCreditConfig

base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")

Expand Down Expand Up @@ -186,6 +187,50 @@ def test_streaming_response_list(self, client: Lithic) -> None:

assert cast(Any, response.is_closed) is True

@parametrize
def test_method_charge_off(self, client: Lithic) -> None:
financial_account = client.financial_accounts.charge_off(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
reason="DELINQUENT",
)
assert_matches_type(FinancialAccountCreditConfig, financial_account, path=["response"])

@parametrize
def test_raw_response_charge_off(self, client: Lithic) -> None:
response = client.financial_accounts.with_raw_response.charge_off(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
reason="DELINQUENT",
)

assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
financial_account = response.parse()
assert_matches_type(FinancialAccountCreditConfig, financial_account, path=["response"])

@parametrize
def test_streaming_response_charge_off(self, client: Lithic) -> None:
with client.financial_accounts.with_streaming_response.charge_off(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
reason="DELINQUENT",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

financial_account = response.parse()
assert_matches_type(FinancialAccountCreditConfig, financial_account, path=["response"])

assert cast(Any, response.is_closed) is True

@parametrize
def test_path_params_charge_off(self, client: Lithic) -> None:
with pytest.raises(
ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''"
):
client.financial_accounts.with_raw_response.charge_off(
financial_account_token="",
reason="DELINQUENT",
)


class TestAsyncFinancialAccounts:
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
Expand Down Expand Up @@ -355,3 +400,47 @@ async def test_streaming_response_list(self, async_client: AsyncLithic) -> None:
assert_matches_type(AsyncSinglePage[FinancialAccount], financial_account, path=["response"])

assert cast(Any, response.is_closed) is True

@parametrize
async def test_method_charge_off(self, async_client: AsyncLithic) -> None:
financial_account = await async_client.financial_accounts.charge_off(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
reason="DELINQUENT",
)
assert_matches_type(FinancialAccountCreditConfig, financial_account, path=["response"])

@parametrize
async def test_raw_response_charge_off(self, async_client: AsyncLithic) -> None:
response = await async_client.financial_accounts.with_raw_response.charge_off(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
reason="DELINQUENT",
)

assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
financial_account = response.parse()
assert_matches_type(FinancialAccountCreditConfig, financial_account, path=["response"])

@parametrize
async def test_streaming_response_charge_off(self, async_client: AsyncLithic) -> None:
async with async_client.financial_accounts.with_streaming_response.charge_off(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
reason="DELINQUENT",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

financial_account = await response.parse()
assert_matches_type(FinancialAccountCreditConfig, financial_account, path=["response"])

assert cast(Any, response.is_closed) is True

@parametrize
async def test_path_params_charge_off(self, async_client: AsyncLithic) -> None:
with pytest.raises(
ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''"
):
await async_client.financial_accounts.with_raw_response.charge_off(
financial_account_token="",
reason="DELINQUENT",
)

0 comments on commit 44895bb

Please sign in to comment.