diff --git a/robosystems_client/clients/ledger_client.py b/robosystems_client/clients/ledger_client.py index 06b95efb..2cf2c4d0 100644 --- a/robosystems_client/clients/ledger_client.py +++ b/robosystems_client/clients/ledger_client.py @@ -132,6 +132,9 @@ from ..api.robo_ledger_information_blocks.evaluate_rules import ( sync_detailed as op_evaluate_rules, ) +from ..api.robo_ledger_setup.create_entity import ( + sync_detailed as op_create_entity, +) from ..api.robo_ledger_setup.update_entity import ( sync_detailed as op_update_entity, ) @@ -465,6 +468,7 @@ from ..models.add_publish_list_members_operation import AddPublishListMembersOperation from ..models.auto_map_elements_operation import AutoMapElementsOperation from ..models.create_agent_request import CreateAgentRequest +from ..models.create_entity_request import CreateEntityRequest from ..models.create_event_block_request import CreateEventBlockRequest from ..models.create_event_block_request_event_category import ( CreateEventBlockRequestEventCategory, @@ -710,6 +714,12 @@ def _get_graphql_client(self) -> GraphQLClient: # ── Helpers ───────────────────────────────────────────────────────── + @staticmethod + def _scope(entity_id: str | None) -> dict[str, Any] | None: + """Variables for a read that takes only the entity scope. ``None`` is the + group parent, and sends no variables, as before entities were an axis.""" + return {"entityId": entity_id} if entity_id else None + def _query( self, graph_id: str, @@ -844,18 +854,25 @@ def _build_event_block_request( # ── Entity ────────────────────────────────────────────────────────── - def get_entity(self, graph_id: str) -> LedgerEntity | None: - """Get the entity (company/organization) for this graph. + def get_entity( + self, graph_id: str, entity_id: str | None = None + ) -> LedgerEntity | None: + """Get an entity of this graph: the group parent, or the one ``entity_id`` + names. Returns None when the ledger has no entity yet. """ - data = self._query(graph_id, GET_LEDGER_ENTITY_GQL) + data = self._query(graph_id, GET_LEDGER_ENTITY_GQL, self._scope(entity_id)) return GetLedgerEntity.model_validate(data).entity def list_entities( self, graph_id: str, source: str | None = None ) -> list[ListLedgerEntitiesEntities]: - """List all entities for this graph, optionally filtered by source system.""" + """List the graph's entities, optionally filtered by source system. + + The group parent is the row with ``is_parent``; a subsidiary names its + ``parent_entity_id`` and may carry an ``ownership_pct``. + """ data = self._query(graph_id, LIST_LEDGER_ENTITIES_GQL, {"source": source}) return ListLedgerEntities.model_validate(data).entities @@ -868,15 +885,32 @@ def update_entity( envelope = self._call_op("Update entity", response) return self._typed_result("Update entity", envelope, LedgerEntityResponse) + def create_entity(self, graph_id: str, body: dict[str, Any]) -> LedgerEntityResponse: + """Create an entity in this graph. + + A graph's first entity becomes the group parent; every later one is a + subsidiary of the parent unless ``parent_entity_id`` names another + entity. ``ticker`` prefixes the entity's account names and is unique in + the graph (derived from the name's initials when omitted). + """ + request = CreateEntityRequest.from_dict(body) + response = op_create_entity( + graph_id=graph_id, body=request, client=self._get_client() + ) + envelope = self._call_op("Create entity", response) + return self._typed_result("Create entity", envelope, LedgerEntityResponse) + # ── Summary ──────────────────────────────────────────────────────── - def get_summary(self, graph_id: str) -> LedgerSummary | None: + def get_summary( + self, graph_id: str, entity_id: str | None = None + ) -> LedgerSummary | None: """Ledger rollup counts + QB sync metadata. Returns the codegen-typed ``LedgerSummary`` model (attribute access, snake_case) rather than a dict. """ - data = self._query(graph_id, GET_LEDGER_SUMMARY_GQL) + data = self._query(graph_id, GET_LEDGER_SUMMARY_GQL, self._scope(entity_id)) return GetLedgerSummary.model_validate(data).summary # ── Accounts ──────────────────────────────────────────────────────── @@ -888,6 +922,7 @@ def list_accounts( is_active: bool | None = None, limit: int = 100, offset: int = 0, + entity_id: str | None = None, ) -> LedgerAccountsPage | None: """List CoA accounts with optional filters and pagination.""" data = self._query( @@ -898,13 +933,16 @@ def list_accounts( "isActive": is_active, "limit": limit, "offset": offset, + "entityId": entity_id, }, ) return ListLedgerAccounts.model_validate(data).accounts - def get_account_tree(self, graph_id: str) -> LedgerAccountTree | None: + def get_account_tree( + self, graph_id: str, entity_id: str | None = None + ) -> LedgerAccountTree | None: """Hierarchical Chart of Accounts (up to 4 levels deep).""" - data = self._query(graph_id, GET_LEDGER_ACCOUNT_TREE_GQL) + data = self._query(graph_id, GET_LEDGER_ACCOUNT_TREE_GQL, self._scope(entity_id)) return GetLedgerAccountTree.model_validate(data).account_tree def get_account_rollups( @@ -913,12 +951,18 @@ def get_account_rollups( mapping_id: str | None = None, start_date: str | None = None, end_date: str | None = None, + entity_id: str | None = None, ) -> LedgerAccountRollups | None: """Accounts rolled up to reporting concepts via a mapping structure.""" data = self._query( graph_id, GET_LEDGER_ACCOUNT_ROLLUPS_GQL, - {"mappingId": mapping_id, "startDate": start_date, "endDate": end_date}, + { + "mappingId": mapping_id, + "startDate": start_date, + "endDate": end_date, + "entityId": entity_id, + }, ) return GetLedgerAccountRollups.model_validate(data).account_rollups @@ -932,6 +976,7 @@ def list_transactions( end_date: str | None = None, limit: int = 100, offset: int = 0, + entity_id: str | None = None, ) -> LedgerTransactionsPage | None: """List transactions with optional type + date filters and pagination.""" data = self._query( @@ -943,6 +988,7 @@ def list_transactions( "endDate": end_date, "limit": limit, "offset": offset, + "entityId": entity_id, }, ) return ListLedgerTransactions.model_validate(data).transactions @@ -969,6 +1015,7 @@ def list_journal_entries( transaction_id: str | None = None, limit: int = 100, offset: int = 0, + entity_id: str | None = None, ) -> LedgerJournalEntriesPage | None: """List journal entries with their line items, newest first. @@ -995,6 +1042,7 @@ def list_journal_entries( "transactionId": transaction_id, "limit": limit, "offset": offset, + "entityId": entity_id, }, ) return ListLedgerJournalEntries.model_validate(data).journal_entries @@ -1012,6 +1060,7 @@ def list_event_blocks( limit: int = 50, offset: int = 0, is_reconciling_item: bool | None = None, + entity_id: str | None = None, ) -> list[ListLedgerEventBlocksEventBlocks]: """List captured event blocks (inbox surface). @@ -1030,6 +1079,7 @@ def list_event_blocks( "isReconcilingItem": is_reconciling_item, "limit": limit, "offset": offset, + "entityId": entity_id, }, ) return ListLedgerEventBlocks.model_validate(data).event_blocks @@ -1076,12 +1126,13 @@ def get_trial_balance( graph_id: str, start_date: str | None = None, end_date: str | None = None, + entity_id: str | None = None, ) -> TrialBalance | None: """Trial balance by raw CoA account.""" data = self._query( graph_id, GET_LEDGER_TRIAL_BALANCE_GQL, - {"startDate": start_date, "endDate": end_date}, + {"startDate": start_date, "endDate": end_date, "entityId": entity_id}, ) return GetLedgerTrialBalance.model_validate(data).trial_balance @@ -1725,18 +1776,23 @@ def get_period_close_status( graph_id: str, period_start: str, period_end: str, + entity_id: str | None = None, ) -> PeriodCloseStatus | None: """Close status for all schedules in a fiscal period.""" data = self._query( graph_id, GET_LEDGER_PERIOD_CLOSE_STATUS_GQL, - {"periodStart": period_start, "periodEnd": period_end}, + {"periodStart": period_start, "periodEnd": period_end, "entityId": entity_id}, ) return GetLedgerPeriodCloseStatus.model_validate(data).period_close_status - def list_period_drafts(self, graph_id: str, period: str) -> PeriodDrafts | None: + def list_period_drafts( + self, graph_id: str, period: str, entity_id: str | None = None + ) -> PeriodDrafts | None: """All draft entries in a period, fully expanded for review pre-close.""" - data = self._query(graph_id, GET_LEDGER_PERIOD_DRAFTS_GQL, {"period": period}) + data = self._query( + graph_id, GET_LEDGER_PERIOD_DRAFTS_GQL, {"period": period, "entityId": entity_id} + ) return GetLedgerPeriodDrafts.model_validate(data).period_drafts def create_closing_entry( @@ -2104,22 +2160,30 @@ def build_fact_grid(self, graph_id: str, request: dict[str, Any]) -> ViewRespons # ── Closing book ─────────────────────────────────────────────────── - def get_closing_book_structures(self, graph_id: str) -> ClosingBookStructures | None: + def get_closing_book_structures( + self, graph_id: str, entity_id: str | None = None + ) -> ClosingBookStructures | None: """Grouped closing book structures for the close-screen sidebar.""" - data = self._query(graph_id, GET_LEDGER_CLOSING_BOOK_STRUCTURES_GQL) + data = self._query( + graph_id, GET_LEDGER_CLOSING_BOOK_STRUCTURES_GQL, self._scope(entity_id) + ) return GetLedgerClosingBookStructures.model_validate(data).closing_book_structures # ── Fiscal Calendar ──────────────────────────────────────────────── - def get_fiscal_calendar(self, graph_id: str) -> FiscalCalendar | None: - """Current fiscal calendar state — pointers, gap, closeable status.""" - data = self._query(graph_id, GET_LEDGER_FISCAL_CALENDAR_GQL) + def get_fiscal_calendar( + self, graph_id: str, entity_id: str | None = None + ) -> FiscalCalendar | None: + """Current fiscal calendar state — pointers, gap, closeable status — for + the group parent, or for the entity ``entity_id`` names.""" + data = self._query(graph_id, GET_LEDGER_FISCAL_CALENDAR_GQL, self._scope(entity_id)) return GetLedgerFiscalCalendar.model_validate(data).fiscal_calendar def initialize_ledger( self, graph_id: str, *, + entity_id: str | None = None, closed_through: str | None = None, fiscal_year_start_month: int | None = None, earliest_data_period: str | None = None, @@ -2128,6 +2192,7 @@ def initialize_ledger( ) -> InitializeLedgerResponse: """One-time ledger initialization — seed fiscal calendar + periods.""" body = InitializeLedgerRequest( + entity_id=entity_id if entity_id is not None else UNSET, closed_through=closed_through if closed_through is not None else UNSET, fiscal_year_start_month=( fiscal_year_start_month if fiscal_year_start_month is not None else UNSET @@ -2158,6 +2223,7 @@ def initialize_chart_of_accounts( graph_id: str, template: InitializeChartOfAccountsRequestTemplate | str, *, + entity_id: str | None = None, entity_type: str | None = None, name: str | None = None, ) -> InitializeChartOfAccountsResponse: @@ -2172,6 +2238,7 @@ def initialize_chart_of_accounts( """ body = InitializeChartOfAccountsRequest( template=InitializeChartOfAccountsRequestTemplate(template), + entity_id=entity_id if entity_id is not None else UNSET, entity_type=entity_type if entity_type is not None else UNSET, name=name if name is not None else UNSET, ) @@ -2188,11 +2255,14 @@ def set_close_target( graph_id: str, period: str, note: str | None = None, + *, + entity_id: str | None = None, ) -> FiscalCalendarResponse: """Set the user-controlled close target (YYYY-MM).""" body = SetCloseTargetOperation( period=period, note=note if note is not None else UNSET, + entity_id=entity_id if entity_id is not None else UNSET, ) response = op_set_close_target( graph_id=graph_id, body=body, client=self._get_client() @@ -2210,8 +2280,10 @@ def close_period( allow_stranded_obligations: bool | None = None, allow_reconciling_items: bool | None = None, allow_unposted_source_events: bool | None = None, + entity_id: str | None = None, ) -> ClosePeriodResponse: - """Close a fiscal period — the final commit action. + """Close a fiscal period — the final commit action — on the group parent, + or on the entity ``entity_id`` names. Each entity closes on its own. Each ``allow_*`` flag closes despite one blocker and is recorded in the close audit note; prefer clearing the blocker. @@ -2231,6 +2303,7 @@ def flag(value: bool | None) -> bool | Unset: body = ClosePeriodOperation( period=period, + entity_id=entity_id if entity_id is not None else UNSET, note=note if note is not None else UNSET, allow_stale_sync=flag(allow_stale_sync), allow_unreconciled_accounts=flag(allow_unreconciled_accounts), @@ -2248,12 +2321,15 @@ def reopen_period( period: str, reason: str, note: str | None = None, + *, + entity_id: str | None = None, ) -> FiscalCalendarResponse: """Reopen a closed fiscal period. Requires a reason for the audit log.""" body = ReopenPeriodOperation( period=period, reason=reason, note=note if note is not None else UNSET, + entity_id=entity_id if entity_id is not None else UNSET, ) response = op_reopen_period(graph_id=graph_id, body=body, client=self._get_client()) envelope = self._call_op("Reopen period", response) @@ -2357,7 +2433,7 @@ def resolve_reconciling_item( # ── Reconciliations ───────────────────────────────────────────────── def list_reconciliations( - self, graph_id: str, period: str + self, graph_id: str, period: str, entity_id: str | None = None ) -> ReconciliationList | None: """Every reconciliation block's standing at a period end (``YYYY-MM``). @@ -2365,7 +2441,11 @@ def list_reconciliations( Comparisons are recorded by `refresh_reconciliations` and `record_statement_balance`. """ - data = self._query(graph_id, LIST_LEDGER_RECONCILIATIONS_GQL, {"period": period}) + data = self._query( + graph_id, + LIST_LEDGER_RECONCILIATIONS_GQL, + {"period": period, "entityId": entity_id}, + ) return ListLedgerReconciliations.model_validate(data).reconciliations def preview_reconciliations( @@ -2539,7 +2619,10 @@ def create_report( return self._typed_result("Create report", envelope, ReportResponse) def list_reports( - self, graph_id: str, lifecycle: str | None = None + self, + graph_id: str, + lifecycle: str | None = None, + entity_id: str | None = None, ) -> list[ListLedgerReportsReportsReports]: """List reports for a graph (includes received shared reports). @@ -2549,9 +2632,12 @@ def list_reports( reports out, ``"archived"`` returns only those, ``"all"`` every report. The enum names ``"CURRENT"`` / ``"ARCHIVED"`` / ``"ALL"`` are also accepted. + entity_id: one entity's reports; the group parent's when omitted. """ - variables = {"lifecycle": lifecycle.upper()} if lifecycle else None - data = self._query(graph_id, LIST_LEDGER_REPORTS_GQL, variables) + variables = strip_none_vars( + {"lifecycle": lifecycle.upper() if lifecycle else None, "entityId": entity_id} + ) + data = self._query(graph_id, LIST_LEDGER_REPORTS_GQL, variables or None) page = ListLedgerReports.model_validate(data).reports return page.reports if page else [] diff --git a/robosystems_client/graphql/generated/client.py b/robosystems_client/graphql/generated/client.py index 8194210c..31f48e46 100644 --- a/robosystems_client/graphql/generated/client.py +++ b/robosystems_client/graphql/generated/client.py @@ -271,12 +271,14 @@ def get_ledger_account_rollups( mapping_id: Union[Optional[str], UnsetType] = UNSET, start_date: Union[Optional[str], UnsetType] = UNSET, end_date: Union[Optional[str], UnsetType] = UNSET, + entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any, ) -> GetLedgerAccountRollups: variables: dict[str, object] = { "mappingId": mapping_id, "startDate": start_date, "endDate": end_date, + "entityId": entity_id, } response = self.execute( query=GET_LEDGER_ACCOUNT_ROLLUPS_GQL, @@ -287,8 +289,10 @@ def get_ledger_account_rollups( data = self.get_data(response) return GetLedgerAccountRollups.model_validate(data) - def get_ledger_account_tree(self, **kwargs: Any) -> GetLedgerAccountTree: - variables: dict[str, object] = {} + def get_ledger_account_tree( + self, entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any + ) -> GetLedgerAccountTree: + variables: dict[str, object] = {"entityId": entity_id} response = self.execute( query=GET_LEDGER_ACCOUNT_TREE_GQL, operation_name="GetLedgerAccountTree", @@ -310,9 +314,9 @@ def get_ledger_agent(self, id: str, **kwargs: Any) -> GetLedgerAgent: return GetLedgerAgent.model_validate(data) def get_ledger_closing_book_structures( - self, **kwargs: Any + self, entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any ) -> GetLedgerClosingBookStructures: - variables: dict[str, object] = {} + variables: dict[str, object] = {"entityId": entity_id} response = self.execute( query=GET_LEDGER_CLOSING_BOOK_STRUCTURES_GQL, operation_name="GetLedgerClosingBookStructures", @@ -322,8 +326,10 @@ def get_ledger_closing_book_structures( data = self.get_data(response) return GetLedgerClosingBookStructures.model_validate(data) - def get_ledger_entity(self, **kwargs: Any) -> GetLedgerEntity: - variables: dict[str, object] = {} + def get_ledger_entity( + self, entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any + ) -> GetLedgerEntity: + variables: dict[str, object] = {"entityId": entity_id} response = self.execute( query=GET_LEDGER_ENTITY_GQL, operation_name="GetLedgerEntity", @@ -344,8 +350,10 @@ def get_ledger_event_block(self, id: str, **kwargs: Any) -> GetLedgerEventBlock: data = self.get_data(response) return GetLedgerEventBlock.model_validate(data) - def get_ledger_fiscal_calendar(self, **kwargs: Any) -> GetLedgerFiscalCalendar: - variables: dict[str, object] = {} + def get_ledger_fiscal_calendar( + self, entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any + ) -> GetLedgerFiscalCalendar: + variables: dict[str, object] = {"entityId": entity_id} response = self.execute( query=GET_LEDGER_FISCAL_CALENDAR_GQL, operation_name="GetLedgerFiscalCalendar", @@ -401,11 +409,16 @@ def get_ledger_mapping_coverage( return GetLedgerMappingCoverage.model_validate(data) def get_ledger_period_close_status( - self, period_start: str, period_end: str, **kwargs: Any + self, + period_start: str, + period_end: str, + entity_id: Union[Optional[str], UnsetType] = UNSET, + **kwargs: Any, ) -> GetLedgerPeriodCloseStatus: variables: dict[str, object] = { "periodStart": period_start, "periodEnd": period_end, + "entityId": entity_id, } response = self.execute( query=GET_LEDGER_PERIOD_CLOSE_STATUS_GQL, @@ -417,9 +430,9 @@ def get_ledger_period_close_status( return GetLedgerPeriodCloseStatus.model_validate(data) def get_ledger_period_drafts( - self, period: str, **kwargs: Any + self, period: str, entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any ) -> GetLedgerPeriodDrafts: - variables: dict[str, object] = {"period": period} + variables: dict[str, object] = {"period": period, "entityId": entity_id} response = self.execute( query=GET_LEDGER_PERIOD_DRAFTS_GQL, operation_name="GetLedgerPeriodDrafts", @@ -511,8 +524,10 @@ def get_ledger_statement( data = self.get_data(response) return GetLedgerStatement.model_validate(data) - def get_ledger_summary(self, **kwargs: Any) -> GetLedgerSummary: - variables: dict[str, object] = {} + def get_ledger_summary( + self, entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any + ) -> GetLedgerSummary: + variables: dict[str, object] = {"entityId": entity_id} response = self.execute( query=GET_LEDGER_SUMMARY_GQL, operation_name="GetLedgerSummary", @@ -539,9 +554,14 @@ def get_ledger_trial_balance( self, start_date: Union[Optional[str], UnsetType] = UNSET, end_date: Union[Optional[str], UnsetType] = UNSET, + entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any, ) -> GetLedgerTrialBalance: - variables: dict[str, object] = {"startDate": start_date, "endDate": end_date} + variables: dict[str, object] = { + "startDate": start_date, + "endDate": end_date, + "entityId": entity_id, + } response = self.execute( query=GET_LEDGER_TRIAL_BALANCE_GQL, operation_name="GetLedgerTrialBalance", @@ -593,6 +613,7 @@ def list_ledger_accounts( offset: int, classification: Union[Optional[str], UnsetType] = UNSET, is_active: Union[Optional[bool], UnsetType] = UNSET, + entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any, ) -> ListLedgerAccounts: variables: dict[str, object] = { @@ -600,6 +621,7 @@ def list_ledger_accounts( "isActive": is_active, "limit": limit, "offset": offset, + "entityId": entity_id, } response = self.execute( query=LIST_LEDGER_ACCOUNTS_GQL, @@ -698,6 +720,7 @@ def list_ledger_event_blocks( agent_id: Union[Optional[str], UnsetType] = UNSET, source: Union[Optional[str], UnsetType] = UNSET, is_reconciling_item: Union[Optional[bool], UnsetType] = UNSET, + entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any, ) -> ListLedgerEventBlocks: variables: dict[str, object] = { @@ -709,6 +732,7 @@ def list_ledger_event_blocks( "isReconcilingItem": is_reconciling_item, "limit": limit, "offset": offset, + "entityId": entity_id, } response = self.execute( query=LIST_LEDGER_EVENT_BLOCKS_GQL, @@ -729,6 +753,7 @@ def list_ledger_journal_entries( type_: Union[Optional[str], UnsetType] = UNSET, provenance: Union[Optional[str], UnsetType] = UNSET, transaction_id: Union[Optional[str], UnsetType] = UNSET, + entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any, ) -> ListLedgerJournalEntries: variables: dict[str, object] = { @@ -740,6 +765,7 @@ def list_ledger_journal_entries( "transactionId": transaction_id, "limit": limit, "offset": offset, + "entityId": entity_id, } response = self.execute( query=LIST_LEDGER_JOURNAL_ENTRIES_GQL, @@ -775,9 +801,9 @@ def list_ledger_publish_lists( return ListLedgerPublishLists.model_validate(data) def list_ledger_reconciliations( - self, period: str, **kwargs: Any + self, period: str, entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any ) -> ListLedgerReconciliations: - variables: dict[str, object] = {"period": period} + variables: dict[str, object] = {"period": period, "entityId": entity_id} response = self.execute( query=LIST_LEDGER_RECONCILIATIONS_GQL, operation_name="ListLedgerReconciliations", @@ -788,9 +814,12 @@ def list_ledger_reconciliations( return ListLedgerReconciliations.model_validate(data) def list_ledger_reports( - self, lifecycle: Union[Optional[ReportLifecycle], UnsetType] = UNSET, **kwargs: Any + self, + lifecycle: Union[Optional[ReportLifecycle], UnsetType] = UNSET, + entity_id: Union[Optional[str], UnsetType] = UNSET, + **kwargs: Any, ) -> ListLedgerReports: - variables: dict[str, object] = {"lifecycle": lifecycle} + variables: dict[str, object] = {"lifecycle": lifecycle, "entityId": entity_id} response = self.execute( query=LIST_LEDGER_REPORTS_GQL, operation_name="ListLedgerReports", @@ -839,6 +868,7 @@ def list_ledger_transactions( type_: Union[Optional[str], UnsetType] = UNSET, start_date: Union[Optional[str], UnsetType] = UNSET, end_date: Union[Optional[str], UnsetType] = UNSET, + entity_id: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any, ) -> ListLedgerTransactions: variables: dict[str, object] = { @@ -847,6 +877,7 @@ def list_ledger_transactions( "endDate": end_date, "limit": limit, "offset": offset, + "entityId": entity_id, } response = self.execute( query=LIST_LEDGER_TRANSACTIONS_GQL, diff --git a/robosystems_client/graphql/generated/get_ledger_entity.py b/robosystems_client/graphql/generated/get_ledger_entity.py index d6c93f03..0f6eb4d5 100644 --- a/robosystems_client/graphql/generated/get_ledger_entity.py +++ b/robosystems_client/graphql/generated/get_ledger_entity.py @@ -26,11 +26,13 @@ class GetLedgerEntityEntity(BaseModel): lei: Optional[str] industry: Optional[str] entity_type: Optional[str] = Field(alias="entityType") + reporting_style_id: Optional[str] = Field(alias="reportingStyleId") phone: Optional[str] website: Optional[str] status: str is_parent: bool = Field(alias="isParent") parent_entity_id: Optional[str] = Field(alias="parentEntityId") + ownership_pct: Optional[float] = Field(alias="ownershipPct") source: str source_id: Optional[str] = Field(alias="sourceId") source_graph_id: Optional[str] = Field(alias="sourceGraphId") diff --git a/robosystems_client/graphql/generated/get_ledger_fiscal_calendar.py b/robosystems_client/graphql/generated/get_ledger_fiscal_calendar.py index 281b466d..6784a798 100644 --- a/robosystems_client/graphql/generated/get_ledger_fiscal_calendar.py +++ b/robosystems_client/graphql/generated/get_ledger_fiscal_calendar.py @@ -13,6 +13,7 @@ class GetLedgerFiscalCalendar(BaseModel): class GetLedgerFiscalCalendarFiscalCalendar(BaseModel): graph_id: str = Field(alias="graphId") + entity_id: Optional[str] = Field(alias="entityId") fiscal_year_start_month: int = Field(alias="fiscalYearStartMonth") closed_through: Optional[str] = Field(alias="closedThrough") close_target: Optional[str] = Field(alias="closeTarget") diff --git a/robosystems_client/graphql/generated/get_ledger_report.py b/robosystems_client/graphql/generated/get_ledger_report.py index a1effdf9..4939f282 100644 --- a/robosystems_client/graphql/generated/get_ledger_report.py +++ b/robosystems_client/graphql/generated/get_ledger_report.py @@ -11,6 +11,7 @@ class GetLedgerReport(BaseModel): class GetLedgerReportReport(BaseModel): id: str + entity_id: Optional[str] = Field(alias="entityId") name: str taxonomy_id: str = Field(alias="taxonomyId") generation_status: str = Field(alias="generationStatus") diff --git a/robosystems_client/graphql/generated/get_ledger_summary.py b/robosystems_client/graphql/generated/get_ledger_summary.py index 3c8147c1..d155d12e 100644 --- a/robosystems_client/graphql/generated/get_ledger_summary.py +++ b/robosystems_client/graphql/generated/get_ledger_summary.py @@ -11,6 +11,7 @@ class GetLedgerSummary(BaseModel): class GetLedgerSummarySummary(BaseModel): graph_id: str = Field(alias="graphId") + entity_id: Optional[str] = Field(alias="entityId") account_count: int = Field(alias="accountCount") transaction_count: int = Field(alias="transactionCount") entry_count: int = Field(alias="entryCount") diff --git a/robosystems_client/graphql/generated/list_ledger_entities.py b/robosystems_client/graphql/generated/list_ledger_entities.py index e0e237bf..3a6483ca 100644 --- a/robosystems_client/graphql/generated/list_ledger_entities.py +++ b/robosystems_client/graphql/generated/list_ledger_entities.py @@ -20,6 +20,7 @@ class ListLedgerEntitiesEntities(BaseModel): status: str is_parent: bool = Field(alias="isParent") parent_entity_id: Optional[str] = Field(alias="parentEntityId") + ownership_pct: Optional[float] = Field(alias="ownershipPct") source: str source_graph_id: Optional[str] = Field(alias="sourceGraphId") connection_id: Optional[str] = Field(alias="connectionId") diff --git a/robosystems_client/graphql/generated/list_ledger_reports.py b/robosystems_client/graphql/generated/list_ledger_reports.py index 49e41abd..4e0a2ee1 100644 --- a/robosystems_client/graphql/generated/list_ledger_reports.py +++ b/robosystems_client/graphql/generated/list_ledger_reports.py @@ -15,6 +15,7 @@ class ListLedgerReportsReports(BaseModel): class ListLedgerReportsReportsReports(BaseModel): id: str + entity_id: Optional[str] = Field(alias="entityId") name: str taxonomy_id: str = Field(alias="taxonomyId") generation_status: str = Field(alias="generationStatus") diff --git a/robosystems_client/graphql/generated/operations.py b/robosystems_client/graphql/generated/operations.py index a5c00cd8..5b6bf5f5 100644 --- a/robosystems_client/graphql/generated/operations.py +++ b/robosystems_client/graphql/generated/operations.py @@ -438,8 +438,13 @@ """ GET_LEDGER_ACCOUNT_ROLLUPS_GQL = """ -query GetLedgerAccountRollups($mappingId: String, $startDate: Date, $endDate: Date) { - accountRollups(mappingId: $mappingId, startDate: $startDate, endDate: $endDate) { +query GetLedgerAccountRollups($mappingId: String, $startDate: Date, $endDate: Date, $entityId: String) { + accountRollups( + mappingId: $mappingId + startDate: $startDate + endDate: $endDate + entityId: $entityId + ) { mappingId mappingName totalMapped @@ -465,8 +470,8 @@ """ GET_LEDGER_ACCOUNT_TREE_GQL = """ -query GetLedgerAccountTree { - accountTree { +query GetLedgerAccountTree($entityId: String) { + accountTree(entityId: $entityId) { totalAccounts roots { id @@ -538,8 +543,8 @@ """ GET_LEDGER_CLOSING_BOOK_STRUCTURES_GQL = """ -query GetLedgerClosingBookStructures { - closingBookStructures { +query GetLedgerClosingBookStructures($entityId: String) { + closingBookStructures(entityId: $entityId) { hasData categories { label @@ -557,8 +562,8 @@ """ GET_LEDGER_ENTITY_GQL = """ -query GetLedgerEntity { - entity { +query GetLedgerEntity($entityId: String) { + entity(entityId: $entityId) { id name legalName @@ -575,11 +580,13 @@ lei industry entityType + reportingStyleId phone website status isParent parentEntityId + ownershipPct source sourceId sourceGraphId @@ -627,9 +634,10 @@ """ GET_LEDGER_FISCAL_CALENDAR_GQL = """ -query GetLedgerFiscalCalendar { - fiscalCalendar { +query GetLedgerFiscalCalendar($entityId: String) { + fiscalCalendar(entityId: $entityId) { graphId + entityId fiscalYearStartMonth closedThrough closeTarget @@ -739,8 +747,12 @@ """ GET_LEDGER_PERIOD_CLOSE_STATUS_GQL = """ -query GetLedgerPeriodCloseStatus($periodStart: Date!, $periodEnd: Date!) { - periodCloseStatus(periodStart: $periodStart, periodEnd: $periodEnd) { +query GetLedgerPeriodCloseStatus($periodStart: Date!, $periodEnd: Date!, $entityId: String) { + periodCloseStatus( + periodStart: $periodStart + periodEnd: $periodEnd + entityId: $entityId + ) { fiscalPeriodStart fiscalPeriodEnd periodStatus @@ -760,8 +772,8 @@ """ GET_LEDGER_PERIOD_DRAFTS_GQL = """ -query GetLedgerPeriodDrafts($period: String!) { - periodDrafts(period: $period) { +query GetLedgerPeriodDrafts($period: String!, $entityId: String) { + periodDrafts(period: $period, entityId: $entityId) { period periodStart periodEnd @@ -825,6 +837,7 @@ query GetLedgerReport($reportId: String!) { report(reportId: $reportId) { id + entityId name taxonomyId generationStatus @@ -1090,9 +1103,10 @@ """ GET_LEDGER_SUMMARY_GQL = """ -query GetLedgerSummary { - summary { +query GetLedgerSummary($entityId: String) { + summary(entityId: $entityId) { graphId + entityId accountCount transactionCount entryCount @@ -1147,8 +1161,8 @@ """ GET_LEDGER_TRIAL_BALANCE_GQL = """ -query GetLedgerTrialBalance($startDate: Date, $endDate: Date) { - trialBalance(startDate: $startDate, endDate: $endDate) { +query GetLedgerTrialBalance($startDate: Date, $endDate: Date, $entityId: String) { + trialBalance(startDate: $startDate, endDate: $endDate, entityId: $entityId) { totalDebits totalCredits rows { @@ -1322,12 +1336,13 @@ """ LIST_LEDGER_ACCOUNTS_GQL = """ -query ListLedgerAccounts($classification: String, $isActive: Boolean, $limit: Int! = 100, $offset: Int! = 0) { +query ListLedgerAccounts($classification: String, $isActive: Boolean, $limit: Int! = 100, $offset: Int! = 0, $entityId: String) { accounts( classification: $classification isActive: $isActive limit: $limit offset: $offset + entityId: $entityId ) { accounts { id @@ -1462,6 +1477,7 @@ status isParent parentEntityId + ownershipPct source sourceGraphId connectionId @@ -1472,7 +1488,7 @@ """ LIST_LEDGER_EVENT_BLOCKS_GQL = """ -query ListLedgerEventBlocks($eventType: String, $eventCategory: String, $status: String, $agentId: String, $source: String, $isReconcilingItem: Boolean, $limit: Int! = 50, $offset: Int! = 0) { +query ListLedgerEventBlocks($eventType: String, $eventCategory: String, $status: String, $agentId: String, $source: String, $isReconcilingItem: Boolean, $limit: Int! = 50, $offset: Int! = 0, $entityId: String) { eventBlocks( eventType: $eventType eventCategory: $eventCategory @@ -1482,6 +1498,7 @@ isReconcilingItem: $isReconcilingItem limit: $limit offset: $offset + entityId: $entityId ) { id eventType @@ -1512,7 +1529,7 @@ """ LIST_LEDGER_JOURNAL_ENTRIES_GQL = """ -query ListLedgerJournalEntries($startDate: Date, $endDate: Date, $status: String, $type: String, $provenance: String, $transactionId: String, $limit: Int! = 100, $offset: Int! = 0) { +query ListLedgerJournalEntries($startDate: Date, $endDate: Date, $status: String, $type: String, $provenance: String, $transactionId: String, $limit: Int! = 100, $offset: Int! = 0, $entityId: String) { journalEntries( startDate: $startDate endDate: $endDate @@ -1522,6 +1539,7 @@ transactionId: $transactionId limit: $limit offset: $offset + entityId: $entityId ) { entries { id @@ -1600,8 +1618,8 @@ """ LIST_LEDGER_RECONCILIATIONS_GQL = """ -query ListLedgerReconciliations($period: String!) { - reconciliations(period: $period) { +query ListLedgerReconciliations($period: String!, $entityId: String) { + reconciliations(period: $period, entityId: $entityId) { period asOf notes @@ -1666,10 +1684,11 @@ """ LIST_LEDGER_REPORTS_GQL = """ -query ListLedgerReports($lifecycle: ReportLifecycle) { - reports(lifecycle: $lifecycle) { +query ListLedgerReports($lifecycle: ReportLifecycle, $entityId: String) { + reports(lifecycle: $lifecycle, entityId: $entityId) { reports { id + entityId name taxonomyId generationStatus @@ -1739,13 +1758,14 @@ """ LIST_LEDGER_TRANSACTIONS_GQL = """ -query ListLedgerTransactions($type: String, $startDate: Date, $endDate: Date, $limit: Int! = 100, $offset: Int! = 0) { +query ListLedgerTransactions($type: String, $startDate: Date, $endDate: Date, $limit: Int! = 100, $offset: Int! = 0, $entityId: String) { transactions( type: $type startDate: $startDate endDate: $endDate limit: $limit offset: $offset + entityId: $entityId ) { transactions { id diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerAccountRollups.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerAccountRollups.graphql index 7fac4483..a706b708 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerAccountRollups.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerAccountRollups.graphql @@ -2,11 +2,13 @@ query GetLedgerAccountRollups( $mappingId: String $startDate: Date $endDate: Date + $entityId: String ) { accountRollups( mappingId: $mappingId startDate: $startDate endDate: $endDate + entityId: $entityId ) { mappingId mappingName diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerAccountTree.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerAccountTree.graphql index 30a84f09..89247737 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerAccountTree.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerAccountTree.graphql @@ -1,5 +1,5 @@ -query GetLedgerAccountTree { - accountTree { +query GetLedgerAccountTree($entityId: String) { + accountTree(entityId: $entityId) { totalAccounts roots { id code name trait accountType balanceType depth isActive diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerClosingBookStructures.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerClosingBookStructures.graphql index 4d225b24..f528be66 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerClosingBookStructures.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerClosingBookStructures.graphql @@ -1,5 +1,5 @@ -query GetLedgerClosingBookStructures { - closingBookStructures { +query GetLedgerClosingBookStructures($entityId: String) { + closingBookStructures(entityId: $entityId) { hasData categories { label diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerEntity.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerEntity.graphql index 8f0a47bf..872ed709 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerEntity.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerEntity.graphql @@ -1,5 +1,5 @@ -query GetLedgerEntity { - entity { +query GetLedgerEntity($entityId: String) { + entity(entityId: $entityId) { id name legalName @@ -16,11 +16,13 @@ query GetLedgerEntity { lei industry entityType + reportingStyleId phone website status isParent parentEntityId + ownershipPct source sourceId sourceGraphId diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerFiscalCalendar.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerFiscalCalendar.graphql index 4d63a94b..a80309ab 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerFiscalCalendar.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerFiscalCalendar.graphql @@ -1,6 +1,6 @@ -query GetLedgerFiscalCalendar { - fiscalCalendar { - graphId fiscalYearStartMonth closedThrough closeTarget +query GetLedgerFiscalCalendar($entityId: String) { + fiscalCalendar(entityId: $entityId) { + graphId entityId fiscalYearStartMonth closedThrough closeTarget gapPeriods catchUpSequence closeableNow blockers pendingObligationCount pendingObligationSample { eventId scheduleId scheduleName period } diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerPeriodCloseStatus.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerPeriodCloseStatus.graphql index b4d10177..1297e3c6 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerPeriodCloseStatus.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerPeriodCloseStatus.graphql @@ -1,5 +1,9 @@ -query GetLedgerPeriodCloseStatus($periodStart: Date!, $periodEnd: Date!) { - periodCloseStatus(periodStart: $periodStart, periodEnd: $periodEnd) { +query GetLedgerPeriodCloseStatus( + $periodStart: Date! + $periodEnd: Date! + $entityId: String +) { + periodCloseStatus(periodStart: $periodStart, periodEnd: $periodEnd, entityId: $entityId) { fiscalPeriodStart fiscalPeriodEnd periodStatus totalDraft totalPosted schedules { structureId structureName amount status diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerPeriodDrafts.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerPeriodDrafts.graphql index bcff4749..9537df4b 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerPeriodDrafts.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerPeriodDrafts.graphql @@ -1,5 +1,5 @@ -query GetLedgerPeriodDrafts($period: String!) { - periodDrafts(period: $period) { +query GetLedgerPeriodDrafts($period: String!, $entityId: String) { + periodDrafts(period: $period, entityId: $entityId) { period periodStart periodEnd draftCount totalDebit totalCredit allBalanced qbWritebackConnectionId qbWritePolicy qbPublishCount localOnlyCount diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerReport.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerReport.graphql index b1c0afd2..bfc38a5d 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerReport.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerReport.graphql @@ -1,6 +1,6 @@ query GetLedgerReport($reportId: String!) { report(reportId: $reportId) { - id name taxonomyId generationStatus periodType + id entityId name taxonomyId generationStatus periodType periodStart periodEnd comparative mappingId aiGenerated createdAt lastGenerated entityName filingStatus filedAt filedBy supersedesId supersededById diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerSummary.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerSummary.graphql index 1a07c33e..8fa5c93d 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerSummary.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerSummary.graphql @@ -1,6 +1,7 @@ -query GetLedgerSummary { - summary { +query GetLedgerSummary($entityId: String) { + summary(entityId: $entityId) { graphId + entityId accountCount transactionCount entryCount diff --git a/robosystems_client/graphql/operations/ledger/GetLedgerTrialBalance.graphql b/robosystems_client/graphql/operations/ledger/GetLedgerTrialBalance.graphql index a3e14c4e..ccbbce3e 100644 --- a/robosystems_client/graphql/operations/ledger/GetLedgerTrialBalance.graphql +++ b/robosystems_client/graphql/operations/ledger/GetLedgerTrialBalance.graphql @@ -1,5 +1,5 @@ -query GetLedgerTrialBalance($startDate: Date, $endDate: Date) { - trialBalance(startDate: $startDate, endDate: $endDate) { +query GetLedgerTrialBalance($startDate: Date, $endDate: Date, $entityId: String) { + trialBalance(startDate: $startDate, endDate: $endDate, entityId: $entityId) { totalDebits totalCredits rows { diff --git a/robosystems_client/graphql/operations/ledger/ListLedgerAccounts.graphql b/robosystems_client/graphql/operations/ledger/ListLedgerAccounts.graphql index df05e1ae..ecac6fa4 100644 --- a/robosystems_client/graphql/operations/ledger/ListLedgerAccounts.graphql +++ b/robosystems_client/graphql/operations/ledger/ListLedgerAccounts.graphql @@ -3,12 +3,14 @@ query ListLedgerAccounts( $isActive: Boolean $limit: Int! = 100 $offset: Int! = 0 + $entityId: String ) { accounts( classification: $classification isActive: $isActive limit: $limit offset: $offset + entityId: $entityId ) { accounts { id diff --git a/robosystems_client/graphql/operations/ledger/ListLedgerEntities.graphql b/robosystems_client/graphql/operations/ledger/ListLedgerEntities.graphql index 71238f5c..e6f0fabf 100644 --- a/robosystems_client/graphql/operations/ledger/ListLedgerEntities.graphql +++ b/robosystems_client/graphql/operations/ledger/ListLedgerEntities.graphql @@ -10,6 +10,7 @@ query ListLedgerEntities($source: String) { status isParent parentEntityId + ownershipPct source sourceGraphId connectionId diff --git a/robosystems_client/graphql/operations/ledger/ListLedgerEventBlocks.graphql b/robosystems_client/graphql/operations/ledger/ListLedgerEventBlocks.graphql index ceca383c..c82a5b74 100644 --- a/robosystems_client/graphql/operations/ledger/ListLedgerEventBlocks.graphql +++ b/robosystems_client/graphql/operations/ledger/ListLedgerEventBlocks.graphql @@ -7,6 +7,7 @@ query ListLedgerEventBlocks( $isReconcilingItem: Boolean $limit: Int! = 50 $offset: Int! = 0 + $entityId: String ) { eventBlocks( eventType: $eventType @@ -17,6 +18,7 @@ query ListLedgerEventBlocks( isReconcilingItem: $isReconcilingItem limit: $limit offset: $offset + entityId: $entityId ) { id eventType eventCategory eventClass status occurredAt effectiveAt source externalId externalUrl amount currency description metadata diff --git a/robosystems_client/graphql/operations/ledger/ListLedgerJournalEntries.graphql b/robosystems_client/graphql/operations/ledger/ListLedgerJournalEntries.graphql index 0504f45d..ad36a557 100644 --- a/robosystems_client/graphql/operations/ledger/ListLedgerJournalEntries.graphql +++ b/robosystems_client/graphql/operations/ledger/ListLedgerJournalEntries.graphql @@ -7,6 +7,7 @@ query ListLedgerJournalEntries( $transactionId: String $limit: Int! = 100 $offset: Int! = 0 + $entityId: String ) { journalEntries( startDate: $startDate @@ -17,6 +18,7 @@ query ListLedgerJournalEntries( transactionId: $transactionId limit: $limit offset: $offset + entityId: $entityId ) { entries { id number transactionId type status postingDate memo diff --git a/robosystems_client/graphql/operations/ledger/ListLedgerReconciliations.graphql b/robosystems_client/graphql/operations/ledger/ListLedgerReconciliations.graphql index 1a599f66..cc61263c 100644 --- a/robosystems_client/graphql/operations/ledger/ListLedgerReconciliations.graphql +++ b/robosystems_client/graphql/operations/ledger/ListLedgerReconciliations.graphql @@ -1,5 +1,5 @@ -query ListLedgerReconciliations($period: String!) { - reconciliations(period: $period) { +query ListLedgerReconciliations($period: String!, $entityId: String) { + reconciliations(period: $period, entityId: $entityId) { period asOf notes reconciliations { structureId name scope method elementId diff --git a/robosystems_client/graphql/operations/ledger/ListLedgerReports.graphql b/robosystems_client/graphql/operations/ledger/ListLedgerReports.graphql index bc0be1cb..e9092212 100644 --- a/robosystems_client/graphql/operations/ledger/ListLedgerReports.graphql +++ b/robosystems_client/graphql/operations/ledger/ListLedgerReports.graphql @@ -1,7 +1,7 @@ -query ListLedgerReports($lifecycle: ReportLifecycle) { - reports(lifecycle: $lifecycle) { +query ListLedgerReports($lifecycle: ReportLifecycle, $entityId: String) { + reports(lifecycle: $lifecycle, entityId: $entityId) { reports { - id name taxonomyId generationStatus filingStatus periodType + id entityId name taxonomyId generationStatus filingStatus periodType periodStart periodEnd comparative mappingId aiGenerated createdAt lastGenerated entityName sourceGraphId sourceReportId sharedAt diff --git a/robosystems_client/graphql/operations/ledger/ListLedgerTransactions.graphql b/robosystems_client/graphql/operations/ledger/ListLedgerTransactions.graphql index 90a36e08..76ddbc92 100644 --- a/robosystems_client/graphql/operations/ledger/ListLedgerTransactions.graphql +++ b/robosystems_client/graphql/operations/ledger/ListLedgerTransactions.graphql @@ -4,6 +4,7 @@ query ListLedgerTransactions( $endDate: Date $limit: Int! = 100 $offset: Int! = 0 + $entityId: String ) { transactions( type: $type @@ -11,6 +12,7 @@ query ListLedgerTransactions( endDate: $endDate limit: $limit offset: $offset + entityId: $entityId ) { transactions { id number type category amount currency date dueDate diff --git a/tests/test_ledger_client.py b/tests/test_ledger_client.py index 1ba61942..c1890d03 100644 --- a/tests/test_ledger_client.py +++ b/tests/test_ledger_client.py @@ -100,11 +100,13 @@ def test_get_entity_returns_typed_model(self, mock_execute, mock_config, graph_i "lei": None, "industry": None, "entityType": "corporation", + "reportingStyleId": None, "phone": None, "website": None, "status": "active", "isParent": False, "parentEntityId": None, + "ownershipPct": None, "source": "qb", "sourceId": None, "sourceGraphId": None, @@ -150,6 +152,7 @@ def test_list_entities(self, mock_execute, mock_config, graph_id): "status": "active", "isParent": True, "parentEntityId": None, + "ownershipPct": None, "source": "qb", "sourceGraphId": None, "connectionId": None, @@ -209,7 +212,7 @@ def test_list_reports_default_leaves_lifecycle_to_the_server( client = LedgerClient(mock_config) assert client.list_reports(graph_id) == [] query, variables = mock_execute.call_args[0][1], mock_execute.call_args[0][2] - assert "reports(lifecycle: $lifecycle)" in query + assert "reports(lifecycle: $lifecycle, entityId: $entityId)" in query assert "filingStatus" in query assert not variables @@ -273,6 +276,7 @@ def test_get_fiscal_calendar(self, mock_execute, mock_config, graph_id): mock_execute.return_value = { "fiscalCalendar": { "graphId": graph_id, + "entityId": None, "fiscalYearStartMonth": 1, "closedThrough": "2026-02", "closeTarget": "2026-03", @@ -320,6 +324,7 @@ def test_get_fiscal_calendar_names_blocking_obligations( mock_execute.return_value = { "fiscalCalendar": { "graphId": graph_id, + "entityId": None, "fiscalYearStartMonth": 1, "closedThrough": "2026-02", "closeTarget": "2026-03", @@ -897,6 +902,7 @@ def test_get_summary(self, mock_execute, mock_config, graph_id): mock_execute.return_value = { "summary": { "graphId": graph_id, + "entityId": None, "accountCount": 120, "transactionCount": 500, "entryCount": 300, @@ -3060,3 +3066,135 @@ def test_a_refusal_carries_the_server_response(self, mock_op, mock_config, graph with pytest.raises(RuntimeError, match="Nothing to reconcile"): client.refresh_reconciliations(graph_id, "2026-08") + + +# ── Entity scope (multi-entity) ───────────────────────────────────────── + + +@pytest.mark.unit +class TestEntityScope: + """``entity_id`` names one entity of the reporting group; omitted, a call + is about the group parent and sends exactly what it sent before.""" + + @patch("robosystems_client.graphql.client.GraphQLClient.execute") + def test_get_entity_reads_the_group_parent_by_default( + self, mock_execute, mock_config, graph_id + ): + mock_execute.return_value = {"entity": None} + client = LedgerClient(mock_config) + assert client.get_entity(graph_id) is None + assert mock_execute.call_args[0][2] is None + + @patch("robosystems_client.graphql.client.GraphQLClient.execute") + def test_get_entity_forwards_entity_id(self, mock_execute, mock_config, graph_id): + mock_execute.return_value = {"entity": None} + client = LedgerClient(mock_config) + client.get_entity(graph_id, entity_id="ent_2") + assert mock_execute.call_args[0][2] == {"entityId": "ent_2"} + + @patch("robosystems_client.graphql.client.GraphQLClient.execute") + def test_get_fiscal_calendar_forwards_entity_id( + self, mock_execute, mock_config, graph_id + ): + mock_execute.return_value = {"fiscalCalendar": None} + client = LedgerClient(mock_config) + client.get_fiscal_calendar(graph_id, entity_id="ent_2") + assert mock_execute.call_args[0][2] == {"entityId": "ent_2"} + + @patch("robosystems_client.graphql.client.GraphQLClient.execute") + def test_get_period_close_status_forwards_entity_id( + self, mock_execute, mock_config, graph_id + ): + mock_execute.return_value = {"periodCloseStatus": None} + client = LedgerClient(mock_config) + client.get_period_close_status( + graph_id, "2026-03-01", "2026-03-31", entity_id="ent_2" + ) + assert mock_execute.call_args[0][2] == { + "periodStart": "2026-03-01", + "periodEnd": "2026-03-31", + "entityId": "ent_2", + } + + @patch("robosystems_client.graphql.client.GraphQLClient.execute") + def test_list_accounts_strips_an_omitted_entity_id( + self, mock_execute, mock_config, graph_id + ): + mock_execute.return_value = {"accounts": None} + client = LedgerClient(mock_config) + client.list_accounts(graph_id) + assert "entityId" not in mock_execute.call_args[0][2] + client.list_accounts(graph_id, entity_id="ent_2") + assert mock_execute.call_args[0][2]["entityId"] == "ent_2" + + @patch("robosystems_client.graphql.client.GraphQLClient.execute") + def test_list_reports_forwards_entity_id(self, mock_execute, mock_config, graph_id): + mock_execute.return_value = {"reports": {"reports": []}} + client = LedgerClient(mock_config) + client.list_reports(graph_id, entity_id="ent_2") + assert mock_execute.call_args[0][2] == {"entityId": "ent_2"} + + @patch("robosystems_client.clients.ledger_client.op_close_period") + def test_close_period_sends_entity_id_only_when_named( + self, mock_op, mock_config, graph_id + ): + result = {"period": "2026-03", "entries_posted": 0, "fiscal_calendar": {}} + mock_op.return_value = _mock_response(_envelope("close-period", result)) + client = LedgerClient(mock_config) + client.close_period(graph_id, "2026-03") + assert "entity_id" not in mock_op.call_args.kwargs["body"].to_dict() + client.close_period(graph_id, "2026-03", entity_id="ent_2") + assert mock_op.call_args.kwargs["body"].entity_id == "ent_2" + + @patch("robosystems_client.clients.ledger_client.op_set_close_target") + def test_set_close_target_sends_entity_id(self, mock_op, mock_config, graph_id): + mock_op.return_value = _mock_response(_envelope("set-close-target", {})) + client = LedgerClient(mock_config) + client.set_close_target(graph_id, "2026-03", entity_id="ent_2") + assert mock_op.call_args.kwargs["body"].to_dict() == { + "period": "2026-03", + "entity_id": "ent_2", + } + + @patch("robosystems_client.clients.ledger_client.op_reopen_period") + def test_reopen_period_sends_entity_id(self, mock_op, mock_config, graph_id): + mock_op.return_value = _mock_response(_envelope("reopen-period", {})) + client = LedgerClient(mock_config) + client.reopen_period(graph_id, "2026-03", "late invoice", entity_id="ent_2") + assert mock_op.call_args.kwargs["body"].to_dict() == { + "period": "2026-03", + "reason": "late invoice", + "entity_id": "ent_2", + } + + @patch("robosystems_client.clients.ledger_client.op_create_entity") + def test_create_entity_posts_the_body_and_unwraps_the_envelope( + self, mock_op, mock_config, graph_id + ): + created = { + "id": "ent_2", + "name": "Driftline Café LLC", + "entity_type": "llc", + "ticker": "DCL", + "is_parent": False, + "parent_entity_id": "ent_1", + "ownership_pct": 100, + } + mock_op.return_value = _mock_response(_envelope("create-entity", created)) + client = LedgerClient(mock_config) + entity = client.create_entity( + graph_id, + {"name": "Driftline Café LLC", "entity_type": "llc", "ownership_pct": 100}, + ) + assert mock_op.call_args.kwargs["graph_id"] == graph_id + assert mock_op.call_args.kwargs["body"].to_dict() == { + "name": "Driftline Café LLC", + "entity_type": "llc", + "ownership_pct": 100, + } + # A dict mock comes back as a dict (see ``_typed_result``); the SDK's + # parsed envelope gives the attrs model in production. + assert entity["id"] == "ent_2" + assert entity["parent_entity_id"] == "ent_1" + assert entity["ownership_pct"] == 100 + assert entity["is_parent"] is False