From 30770b9d875138763285f3a15fefa1337a497b58 Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Wed, 7 Oct 2026 17:36:59 -0500 Subject: [PATCH] feat(connections): entity_id on the Plaid and Mercury connection configs Regenerated from the server after the native-versus-synced rule moved to the entity (robosystems #1724). A bank feed can now name the entity whose books its accounts land on; omitted, it is the group parent. Claude-Session: https://claude.ai/code/session_01BY3uYE5zMjjFHnjiZfiJu8 --- .../robo_ledger_setup/link_bank_account.py | 12 ++++--- .../models/mercury_connection_config.py | 22 +++++++++++++ .../models/plaid_connection_config.py | 31 ++++++++++++++++--- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/robosystems_client/api/robo_ledger_setup/link_bank_account.py b/robosystems_client/api/robo_ledger_setup/link_bank_account.py index f049fe94..25cd91c4 100644 --- a/robosystems_client/api/robo_ledger_setup/link_bank_account.py +++ b/robosystems_client/api/robo_ledger_setup/link_bank_account.py @@ -118,7 +118,8 @@ def sync_detailed( books the feed's lines go into, so this is also how a feed account is bound to a subsidiary. Lines still in the inbox move with it (across an entity change their suggestion is resolved again on the new chart, and a classification that named the old entity's account is dropped); posted entries stay - where they were posted. An account another connection already feeds is refused. An account the feed + where they were posted. An account another connection already feeds is refused, as is an entity + whose books QuickBooks keeps (the group parent, while QuickBooks is connected). An account the feed created and then left stays on its chart as an ordinary account. A sync already in flight when the link moves can still land a line or two on the old account; running this again moves them. Read the group's accounts with the `bankAccounts` GraphQL field. @@ -172,7 +173,8 @@ def sync( books the feed's lines go into, so this is also how a feed account is bound to a subsidiary. Lines still in the inbox move with it (across an entity change their suggestion is resolved again on the new chart, and a classification that named the old entity's account is dropped); posted entries stay - where they were posted. An account another connection already feeds is refused. An account the feed + where they were posted. An account another connection already feeds is refused, as is an entity + whose books QuickBooks keeps (the group parent, while QuickBooks is connected). An account the feed created and then left stays on its chart as an ordinary account. A sync already in flight when the link moves can still land a line or two on the old account; running this again moves them. Read the group's accounts with the `bankAccounts` GraphQL field. @@ -221,7 +223,8 @@ async def asyncio_detailed( books the feed's lines go into, so this is also how a feed account is bound to a subsidiary. Lines still in the inbox move with it (across an entity change their suggestion is resolved again on the new chart, and a classification that named the old entity's account is dropped); posted entries stay - where they were posted. An account another connection already feeds is refused. An account the feed + where they were posted. An account another connection already feeds is refused, as is an entity + whose books QuickBooks keeps (the group parent, while QuickBooks is connected). An account the feed created and then left stays on its chart as an ordinary account. A sync already in flight when the link moves can still land a line or two on the old account; running this again moves them. Read the group's accounts with the `bankAccounts` GraphQL field. @@ -273,7 +276,8 @@ async def asyncio( books the feed's lines go into, so this is also how a feed account is bound to a subsidiary. Lines still in the inbox move with it (across an entity change their suggestion is resolved again on the new chart, and a classification that named the old entity's account is dropped); posted entries stay - where they were posted. An account another connection already feeds is refused. An account the feed + where they were posted. An account another connection already feeds is refused, as is an entity + whose books QuickBooks keeps (the group parent, while QuickBooks is connected). An account the feed created and then left stays on its chart as an ordinary account. A sync already in flight when the link moves can still land a line or two on the old account; running this again moves them. Read the group's accounts with the `bankAccounts` GraphQL field. diff --git a/robosystems_client/models/mercury_connection_config.py b/robosystems_client/models/mercury_connection_config.py index 1327415f..f7eb902a 100644 --- a/robosystems_client/models/mercury_connection_config.py +++ b/robosystems_client/models/mercury_connection_config.py @@ -30,11 +30,15 @@ class MercuryConnectionConfig: include_treasury (bool | Unset): Capture treasury-account activity alongside checking/savings. Default: True. api_key (None | str | Unset): A personal read-only Mercury API token, for deployments that allow the api_key credential mode. Omit to connect over OAuth. + entity_id (None | str | Unset): The entity whose books the feed's accounts land on: a subsidiary's id, or omit + for the group parent. Required when QuickBooks keeps the parent's books. Each account can be moved to another + entity later with `link-bank-account`. """ since_date: datetime.date | None | Unset = UNSET include_treasury: bool | Unset = True api_key: None | str | Unset = UNSET + entity_id: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -54,6 +58,12 @@ def to_dict(self) -> dict[str, Any]: else: api_key = self.api_key + entity_id: None | str | Unset + if isinstance(self.entity_id, Unset): + entity_id = UNSET + else: + entity_id = self.entity_id + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) @@ -63,6 +73,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["include_treasury"] = include_treasury if api_key is not UNSET: field_dict["api_key"] = api_key + if entity_id is not UNSET: + field_dict["entity_id"] = entity_id return field_dict @@ -98,10 +110,20 @@ def _parse_api_key(data: object) -> None | str | Unset: api_key = _parse_api_key(d.pop("api_key", UNSET)) + def _parse_entity_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + entity_id = _parse_entity_id(d.pop("entity_id", UNSET)) + mercury_connection_config = cls( since_date=since_date, include_treasury=include_treasury, api_key=api_key, + entity_id=entity_id, ) mercury_connection_config.additional_properties = d diff --git a/robosystems_client/models/plaid_connection_config.py b/robosystems_client/models/plaid_connection_config.py index 035d1cd6..09c0791f 100644 --- a/robosystems_client/models/plaid_connection_config.py +++ b/robosystems_client/models/plaid_connection_config.py @@ -16,19 +16,24 @@ class PlaidConnectionConfig: """Plaid bank-feed connection configuration. - A bank feed is native accounting: the graph must already have a chart of - accounts and no live QuickBooks connection. The connection is created - `pending_oauth`; `POST /oauth/init` returns a `link_token` for Plaid - Link, and the `public_token` Link hands back completes it through + A bank feed is native accounting: the entity its accounts land on must + already have a chart of accounts and must not be the one QuickBooks keeps + (the group parent, while QuickBooks is connected). The connection is + created `pending_oauth`; `POST /oauth/init` returns a `link_token` for + Plaid Link, and the `public_token` Link hands back completes it through `POST /oauth/callback/plaid` (as `code`). One connection per institution login; a graph can hold several. Attributes: since_date (datetime.date | None | Unset): First day of the backfill (ISO 8601), and how much history Plaid is asked to pull for the new Item (at most two years). Defaults to 1 January of last year. + entity_id (None | str | Unset): The entity whose books the feed's accounts land on: a subsidiary's id, or omit + for the group parent. Required when QuickBooks keeps the parent's books. Each account can be moved to another + entity later with `link-bank-account`. """ since_date: datetime.date | None | Unset = UNSET + entity_id: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -40,11 +45,19 @@ def to_dict(self) -> dict[str, Any]: else: since_date = self.since_date + entity_id: None | str | Unset + if isinstance(self.entity_id, Unset): + entity_id = UNSET + else: + entity_id = self.entity_id + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) if since_date is not UNSET: field_dict["since_date"] = since_date + if entity_id is not UNSET: + field_dict["entity_id"] = entity_id return field_dict @@ -69,8 +82,18 @@ def _parse_since_date(data: object) -> datetime.date | None | Unset: since_date = _parse_since_date(d.pop("since_date", UNSET)) + def _parse_entity_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + entity_id = _parse_entity_id(d.pop("entity_id", UNSET)) + plaid_connection_config = cls( since_date=since_date, + entity_id=entity_id, ) plaid_connection_config.additional_properties = d