Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions mpt_api_client/resources/billing/billing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from mpt_api_client.http import AsyncHTTPClient, HTTPClient
from mpt_api_client.resources.billing.journals import AsyncJournalsService, JournalsService
from mpt_api_client.resources.billing.ledgers import AsyncLedgersService, LedgersService
from mpt_api_client.resources.billing.statements import AsyncStatementsService, StatementsService


class Billing:
Expand All @@ -19,6 +20,11 @@ def ledgers(self) -> LedgersService:
"""Ledgers service."""
return LedgersService(http_client=self.http_client)

@property
def statements(self) -> StatementsService:
"""Statements service."""
return StatementsService(http_client=self.http_client)


class AsyncBilling:
"""Billing MPT API Module."""
Expand All @@ -35,3 +41,8 @@ def journals(self) -> AsyncJournalsService:
def ledgers(self) -> AsyncLedgersService:
"""Ledgers service."""
return AsyncLedgersService(http_client=self.http_client)

@property
def statements(self) -> AsyncStatementsService:
"""Statements service."""
return AsyncStatementsService(http_client=self.http_client)
166 changes: 166 additions & 0 deletions mpt_api_client/resources/billing/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@


# TODO: Consider moving Regeneratable mixins to http/mixins if publishable and activatable are moved
# TODO: Consider reorganizing functions in mixins to reduce duplication and differences amongst
# different domains
class RegeneratableMixin[Model]:
"""Regeneratable mixin adds the ability to regenerate resources."""

Expand Down Expand Up @@ -174,3 +176,167 @@ async def queue(self, resource_id: str, resource_data: ResourceData | None = Non
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "queue", json=resource_data
)


class IssuableMixin[Model]:
"""Issuable mixin adds the ability to issue resources."""

def issue(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Issue resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "issue", json=resource_data
)

def cancel(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Cancel resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "cancel", json=resource_data
)

def error(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Error resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "error", json=resource_data
)

def pending(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Pending resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "pending", json=resource_data
)

def queue(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Queue resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "queue", json=resource_data
)

def retry(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Retry resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "retry", json=resource_data
)

def recalculate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Recalculate resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "recalculate", json=resource_data
)


class AsyncIssuableMixin[Model]:
"""Issuable mixin adds the ability to issue resources."""

async def issue(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Issue resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "issue", json=resource_data
)

async def cancel(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Cancel resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "cancel", json=resource_data
)

async def error(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Error resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "error", json=resource_data
)

async def pending(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Pending resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "pending", json=resource_data
)

async def queue(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Queue resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "queue", json=resource_data
)

async def retry(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
"""Retry resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "retry", json=resource_data
)

async def recalculate(
self, resource_id: str, resource_data: ResourceData | None = None
) -> Model:
"""Recalculate resource.

Args:
resource_id: Resource ID
resource_data: Resource data will be updated
"""
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
resource_id, "POST", "recalculate", json=resource_data
)
34 changes: 34 additions & 0 deletions mpt_api_client/resources/billing/statements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from mpt_api_client.http import AsyncService, Service
from mpt_api_client.http.mixins import AsyncUpdateMixin, UpdateMixin
from mpt_api_client.models import Model
from mpt_api_client.resources.billing.mixins import AsyncIssuableMixin, IssuableMixin


class Statement(Model):
"""Statement resource."""


class StatementsServiceConfig:
"""Statements service configuration."""

_endpoint = "/public/v1/billing/statements"
_model_class = Statement
_collection_key = "data"


class StatementsService(
UpdateMixin[Statement],
IssuableMixin[Statement],
Service[Statement],
StatementsServiceConfig,
):
"""Statements service."""


class AsyncStatementsService(
AsyncUpdateMixin[Statement],
AsyncIssuableMixin[Statement],
AsyncService[Statement],
StatementsServiceConfig,
):
"""Async Statements service."""
3 changes: 3 additions & 0 deletions tests/resources/billing/test_billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from mpt_api_client.resources.billing.billing import AsyncBilling, Billing
from mpt_api_client.resources.billing.journals import AsyncJournalsService, JournalsService
from mpt_api_client.resources.billing.ledgers import AsyncLedgersService, LedgersService
from mpt_api_client.resources.billing.statements import AsyncStatementsService, StatementsService


@pytest.fixture
Expand All @@ -20,6 +21,7 @@ def async_billing(async_http_client):
[
("journals", JournalsService),
("ledgers", LedgersService),
("statements", StatementsService),
],
)
def test_billing_properties(billing, property_name, expected_service_class):
Expand All @@ -35,6 +37,7 @@ def test_billing_properties(billing, property_name, expected_service_class):
[
("journals", AsyncJournalsService),
("ledgers", AsyncLedgersService),
("statements", AsyncStatementsService),
],
)
def test_async_billing_properties(async_billing, property_name, expected_service_class):
Expand Down
Loading