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
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote

import httpx

from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.error_response import ErrorResponse
from ...models.operation_envelope_ownership_change_response import (
OperationEnvelopeOwnershipChangeResponse,
)
from ...models.record_ownership_change_request import RecordOwnershipChangeRequest
from ...types import UNSET, Response, Unset


def _get_kwargs(
graph_id: str,
*,
body: RecordOwnershipChangeRequest,
idempotency_key: None | str | Unset = UNSET,
) -> dict[str, Any]:
headers: dict[str, Any] = {}
if not isinstance(idempotency_key, Unset):
headers["Idempotency-Key"] = idempotency_key

_kwargs: dict[str, Any] = {
"method": "post",
"url": "/extensions/roboledger/{graph_id}/operations/record-ownership-change".format(
graph_id=quote(str(graph_id), safe=""),
),
}

_kwargs["json"] = body.to_dict()

headers["Content-Type"] = "application/json"

_kwargs["headers"] = headers
return _kwargs


def _parse_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> ErrorResponse | OperationEnvelopeOwnershipChangeResponse | None:
if response.status_code == 200:
response_200 = OperationEnvelopeOwnershipChangeResponse.from_dict(response.json())

return response_200

if response.status_code == 400:
response_400 = ErrorResponse.from_dict(response.json())

return response_400

if response.status_code == 401:
response_401 = ErrorResponse.from_dict(response.json())

return response_401

if response.status_code == 403:
response_403 = ErrorResponse.from_dict(response.json())

return response_403

if response.status_code == 404:
response_404 = ErrorResponse.from_dict(response.json())

return response_404

if response.status_code == 409:
response_409 = ErrorResponse.from_dict(response.json())

return response_409

if response.status_code == 422:
response_422 = ErrorResponse.from_dict(response.json())

return response_422

if response.status_code == 429:
response_429 = ErrorResponse.from_dict(response.json())

return response_429

if response.status_code == 500:
response_500 = ErrorResponse.from_dict(response.json())

return response_500

if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(response.status_code, response.content)
else:
return None


def _build_response(
*, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[ErrorResponse | OperationEnvelopeOwnershipChangeResponse]:
return Response(
status_code=HTTPStatus(response.status_code),
content=response.content,
headers=response.headers,
parsed=_parse_response(client=client, response=response),
)


def sync_detailed(
graph_id: str,
*,
client: AuthenticatedClient,
body: RecordOwnershipChangeRequest,
idempotency_key: None | str | Unset = UNSET,
) -> Response[ErrorResponse | OperationEnvelopeOwnershipChangeResponse]:
"""Record Ownership Change

Record the parent buying more of a member consolidated in full from its outside owners: the share it
holds from a month (`ownership_pct`, staying 50 or more) and what it paid them in cents, with the
basis. It sets the member's share from that month and writes a draft in the consolidation entity,
dated the month's first day, that its close posts: ASC 810 makes it an equity transaction, so the
price above the book value of the capital bought goes against the investment, the share bought of
the member's results since it joined comes out of the outside owners' interest, and the difference
is the parent's equity, with no gain or loss. preview-consolidation-entries then reads the price as
part of the parent's investment and the new share from that month. Changes are recorded in order;
recording a month again replaces its draft, and a posted one is reversed first. A sale, or a change
across consolidation methods, is not supported yet.

**Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours
return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict.

Args:
graph_id (str):
idempotency_key (None | str | Unset):
body (RecordOwnershipChangeRequest): The parent buys more of a member from its outside
owners, staying on the
same consolidation method: the share it holds from a month, and what it
paid. ASC 810 makes it an equity transaction, never a gain or loss.

Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.

Returns:
Response[ErrorResponse | OperationEnvelopeOwnershipChangeResponse]
"""

kwargs = _get_kwargs(
graph_id=graph_id,
body=body,
idempotency_key=idempotency_key,
)

response = client.get_httpx_client().request(
**kwargs,
)

return _build_response(client=client, response=response)


def sync(
graph_id: str,
*,
client: AuthenticatedClient,
body: RecordOwnershipChangeRequest,
idempotency_key: None | str | Unset = UNSET,
) -> ErrorResponse | OperationEnvelopeOwnershipChangeResponse | None:
"""Record Ownership Change

Record the parent buying more of a member consolidated in full from its outside owners: the share it
holds from a month (`ownership_pct`, staying 50 or more) and what it paid them in cents, with the
basis. It sets the member's share from that month and writes a draft in the consolidation entity,
dated the month's first day, that its close posts: ASC 810 makes it an equity transaction, so the
price above the book value of the capital bought goes against the investment, the share bought of
the member's results since it joined comes out of the outside owners' interest, and the difference
is the parent's equity, with no gain or loss. preview-consolidation-entries then reads the price as
part of the parent's investment and the new share from that month. Changes are recorded in order;
recording a month again replaces its draft, and a posted one is reversed first. A sale, or a change
across consolidation methods, is not supported yet.

**Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours
return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict.

Args:
graph_id (str):
idempotency_key (None | str | Unset):
body (RecordOwnershipChangeRequest): The parent buys more of a member from its outside
owners, staying on the
same consolidation method: the share it holds from a month, and what it
paid. ASC 810 makes it an equity transaction, never a gain or loss.

Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.

Returns:
ErrorResponse | OperationEnvelopeOwnershipChangeResponse
"""

return sync_detailed(
graph_id=graph_id,
client=client,
body=body,
idempotency_key=idempotency_key,
).parsed


async def asyncio_detailed(
graph_id: str,
*,
client: AuthenticatedClient,
body: RecordOwnershipChangeRequest,
idempotency_key: None | str | Unset = UNSET,
) -> Response[ErrorResponse | OperationEnvelopeOwnershipChangeResponse]:
"""Record Ownership Change

Record the parent buying more of a member consolidated in full from its outside owners: the share it
holds from a month (`ownership_pct`, staying 50 or more) and what it paid them in cents, with the
basis. It sets the member's share from that month and writes a draft in the consolidation entity,
dated the month's first day, that its close posts: ASC 810 makes it an equity transaction, so the
price above the book value of the capital bought goes against the investment, the share bought of
the member's results since it joined comes out of the outside owners' interest, and the difference
is the parent's equity, with no gain or loss. preview-consolidation-entries then reads the price as
part of the parent's investment and the new share from that month. Changes are recorded in order;
recording a month again replaces its draft, and a posted one is reversed first. A sale, or a change
across consolidation methods, is not supported yet.

**Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours
return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict.

Args:
graph_id (str):
idempotency_key (None | str | Unset):
body (RecordOwnershipChangeRequest): The parent buys more of a member from its outside
owners, staying on the
same consolidation method: the share it holds from a month, and what it
paid. ASC 810 makes it an equity transaction, never a gain or loss.

Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.

Returns:
Response[ErrorResponse | OperationEnvelopeOwnershipChangeResponse]
"""

kwargs = _get_kwargs(
graph_id=graph_id,
body=body,
idempotency_key=idempotency_key,
)

response = await client.get_async_httpx_client().request(**kwargs)

return _build_response(client=client, response=response)


async def asyncio(
graph_id: str,
*,
client: AuthenticatedClient,
body: RecordOwnershipChangeRequest,
idempotency_key: None | str | Unset = UNSET,
) -> ErrorResponse | OperationEnvelopeOwnershipChangeResponse | None:
"""Record Ownership Change

Record the parent buying more of a member consolidated in full from its outside owners: the share it
holds from a month (`ownership_pct`, staying 50 or more) and what it paid them in cents, with the
basis. It sets the member's share from that month and writes a draft in the consolidation entity,
dated the month's first day, that its close posts: ASC 810 makes it an equity transaction, so the
price above the book value of the capital bought goes against the investment, the share bought of
the member's results since it joined comes out of the outside owners' interest, and the difference
is the parent's equity, with no gain or loss. preview-consolidation-entries then reads the price as
part of the parent's investment and the new share from that month. Changes are recorded in order;
recording a month again replaces its draft, and a posted one is reversed first. A sale, or a change
across consolidation methods, is not supported yet.

**Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours
return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict.

Args:
graph_id (str):
idempotency_key (None | str | Unset):
body (RecordOwnershipChangeRequest): The parent buys more of a member from its outside
owners, staying on the
same consolidation method: the share it holds from a month, and what it
paid. ASC 810 makes it an equity transaction, never a gain or loss.

Raises:
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
httpx.TimeoutException: If the request takes longer than Client.timeout.

Returns:
ErrorResponse | OperationEnvelopeOwnershipChangeResponse
"""

return (
await asyncio_detailed(
graph_id=graph_id,
client=client,
body=body,
idempotency_key=idempotency_key,
)
).parsed
35 changes: 35 additions & 0 deletions robosystems_client/clients/ledger_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
from ..api.robo_ledger_ledger_events.record_acquisition import (
sync_detailed as op_record_acquisition,
)
from ..api.robo_ledger_ledger_events.record_ownership_change import (
sync_detailed as op_record_ownership_change,
)
from ..api.robo_ledger_ledger_events.record_statement_balance import (
sync_detailed as op_record_statement_balance,
)
Expand Down Expand Up @@ -622,6 +625,8 @@
from ..models.acquisition_allocation import AcquisitionAllocation
from ..models.acquisition_response import AcquisitionResponse
from ..models.record_acquisition_request import RecordAcquisitionRequest
from ..models.ownership_change_response import OwnershipChangeResponse
from ..models.record_ownership_change_request import RecordOwnershipChangeRequest
from ..models.live_financial_statement_request import LiveFinancialStatementRequest
from ..models.financial_statement_analysis_response import (
FinancialStatementAnalysisResponse,
Expand Down Expand Up @@ -2489,6 +2494,36 @@ def record_acquisition(
envelope = self._call_op("Record acquisition", response)
return self._typed_result("Record acquisition", envelope, AcquisitionResponse)

def record_ownership_change(
self,
graph_id: str,
*,
entity_id: str,
period: str,
ownership_pct: float,
consideration: int,
basis: str,
) -> OwnershipChangeResponse:
"""Record the parent buying more of a member from its outside owners,
staying on full consolidation: the share it holds from ``period``
(``YYYY-MM``) and the price paid in cents, with the ``basis``. Sets the
member's share from that month and writes a draft in the consolidation
entity that its close posts — an equity transaction under ASC 810."""
body = RecordOwnershipChangeRequest(
entity_id=entity_id,
period=period,
ownership_pct=ownership_pct,
consideration=consideration,
basis=basis,
)
response = op_record_ownership_change(
graph_id=graph_id, body=body, client=self._get_client()
)
envelope = self._call_op("Record ownership change", response)
return self._typed_result(
"Record ownership change", envelope, OwnershipChangeResponse
)

# ── Event blocks (generic preview + status transitions) ──────────────

def create_event_block(
Expand Down
10 changes: 6 additions & 4 deletions robosystems_client/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -815,10 +815,12 @@ type Query {
): PublishListDetail

"""
The outside owners' share of a member's result for one month: the
pro-rata figure its ownership gives, the override set with
`set-allocation-override` if any, and the share the consolidating
entries use.
The outside owners' share of a member's result for one month.

The pro-rata figure its ownership gives, the override set with
`set-allocation-override` if any, and the share the consolidating entries
use. Null for an entity that is not a member consolidated in full that
month: its outside owners have no share the engine allocates.
"""
allocationShare(
"""The member."""
Expand Down
Loading
Loading