Repository navigation
Support Qonto as first bank integration - #13124
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #13124 +/- ##
===========================================
- Coverage 85.30% 85.29% -0.02%
===========================================
Files 3440 3456 +16
Lines 212647 213767 +1120
Branches 28484 28650 +166
===========================================
+ Hits 181405 182325 +920
- Misses 26605 26805 +200
Partials 4637 4637
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Add Qonto as the first bank integration into rotki. Part of rotki#13052
Scrolling the virtualised entry type menu by hand depended on which wrapper overflows, which differs between Chromium builds and left swap event unrendered in CI. Move the highlight with the arrow keys instead, so the menu scrolls the option into view through its own virtual list.
| def _cursor_updater(self, account_id: str, value: Timestamp) -> Callable[[DBCursor], None]: | ||
| def update(write_cursor: DBCursor) -> None: | ||
| self.set_cursor(write_cursor=write_cursor, account_id=account_id, value=value) | ||
| return update |
There was a problem hiding this comment.
is the wrapper needed? why not use a lambda?
| if new_name is not None: | ||
| write_cursor.execute( # keep the exchange-style range bookkeeping in sync | ||
| 'UPDATE used_query_ranges SET name=? WHERE name=?', | ||
| (f'{location!s}_history_events_{new_name}', f'{location!s}_history_events_{name}'), | ||
| ) | ||
| # and the per-connection caches (cursors, session) | ||
| old_prefix = f'{location!s}_{name}_' | ||
| escaped_prefix = ( | ||
| old_prefix.replace('\\', '\\\\').replace('%', '\\%').replace('_', '\\_') | ||
| ) | ||
| write_cursor.execute( | ||
| 'UPDATE key_value_cache SET name=? || substr(name, ?) ' | ||
| "WHERE name LIKE ? ESCAPE '\\'", | ||
| (f'{location!s}_{new_name}_', len(old_prefix) + 1, f'{escaped_prefix}%'), | ||
| ) |
There was a problem hiding this comment.
existing events also need to be renamed so their location label points to the new name
| escaped_prefix = ( | ||
| old_prefix.replace('\\', '\\\\').replace('%', '\\%').replace('_', '\\_') | ||
| ) |
There was a problem hiding this comment.
if there are to accounts with the same prefix, for example Buisness and Buisness Savings then renaming Buisness will change the name to both
There was a problem hiding this comment.
The escaping fixes SQL wildcard matching, but the prefix is still ambiguous when a connection name contains underscores. With connections named Business and Business_US, renaming Business to Renamed also renames qonto_Business_US_account_last_query_ts to qonto_Renamed_US_account_last_query_ts.
Could you check this case and add a regression test ensuring that renaming one connection leaves the other connection’s caches unchanged?
| event_queue.flush( | ||
| events=events, | ||
| cursor_update=self._cursor_updater(account_id=account.identifier, value=newest), | ||
| ) |
There was a problem hiding this comment.
it performs an update or ignore but if there are changes in the data we want an insert or update. Not sure if it is intentional but leaving it as question. I'm thinking on the case of repulling a range
| def bank_transaction_to_events( | ||
| transaction: BankTransaction, | ||
| location: Location, | ||
| location_label: str, | ||
| ) -> list[BankTransactionEvent]: | ||
| """Map a normalized bank transaction onto rotki history events. |
There was a problem hiding this comment.
why return a list instead of single event? Later we do extend and we could do appeand instead
| changed = super().edit_exchange_credentials(credentials) | ||
| if changed: | ||
| self._set_auth_header() |
There was a problem hiding this comment.
nit: can use the walrus operator here
| f'Qonto rate limited the {endpoint} query', | ||
| retry_after=retry_after, | ||
| ) | ||
| wait = retry_after if retry_after is not None else 2.0 ** (3 - retries_left) |
There was a problem hiding this comment.
amounts smaller than a second are expected? when retries_left > 3
| asset = self._resolve_fiat(entry['currency']) | ||
| if asset is None: | ||
| return None |
|
|
||
| if next_page is None or len(rows) == 0: | ||
| break | ||
| params['current_page'] = next_page |
yabirgb
left a comment
There was a problem hiding this comment.
I believe it looks fine already. LGMT
Add Qonto as the first bank integration into rotki. Part of #13052
Some screenshots


