From 4be82b63ad00a6ab2ba6ac1242c0c701a28a1376 Mon Sep 17 00:00:00 2001 From: Justin Flannery Date: Mon, 22 Jan 2024 21:10:14 -0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20transactions=20api=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lunchable/models/_base.py | 5 +- lunchable/models/_descriptions.py | 203 +++++++++++---- lunchable/models/transactions.py | 244 +++++++++++++++--- tests/conftest.py | 6 + .../cassettes/test_get_transaction.yaml | 36 +-- .../cassettes/test_get_transaction_group.yaml | 54 ++++ .../cassettes/test_get_transactions.yaml | 36 +-- .../test_get_uncleared_transactions.yaml | 12 +- .../cassettes/test_split_transaction.yaml | 74 +++--- .../cassettes/test_update_transaction.yaml | 30 ++- tests/models/test_transactions.py | 14 +- 11 files changed, 544 insertions(+), 170 deletions(-) create mode 100644 tests/models/cassettes/test_get_transaction_group.yaml diff --git a/lunchable/models/_base.py b/lunchable/models/_base.py index 677815c1..07c6fef7 100644 --- a/lunchable/models/_base.py +++ b/lunchable/models/_base.py @@ -2,8 +2,7 @@ Base Pydantic Object for Containers """ - -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict class LunchableModel(BaseModel): @@ -11,6 +10,8 @@ class LunchableModel(BaseModel): Hashable Pydantic Model """ + model_config = ConfigDict(extra="allow") + def __hash__(self) -> int: """ Hash Method for Pydantic BaseModels diff --git a/lunchable/models/_descriptions.py b/lunchable/models/_descriptions.py index c359e077..cad5258a 100644 --- a/lunchable/models/_descriptions.py +++ b/lunchable/models/_descriptions.py @@ -387,84 +387,189 @@ class _TransactionDescriptions: Descriptions for TransactionObject """ - amount = """ - Amount of the transaction in numeric format to 4 decimal places + id = """ + Unique identifier for transaction + """ + date = """ + Date of transaction in ISO 8601 format """ payee = """ - Name of payee If recurring_id is not null, this field will show the payee + Name of payee. If recurring_id is not null, this field will show the payee of associated recurring expense instead of the original transaction payee """ + amount = """ + Amount of the transaction in numeric format to 4 decimal places + """ currency = """ Three-letter lowercase currency code of the transaction in ISO 4217 format """ + to_base = """ + The amount converted to the user's primary currency. If the multicurrency + feature is not being used, to_base and amount will be the same. + """ + category_id = """ + Unique identifier of associated category + """ + category_name = """ + Name of category associated with transaction + """ + category_group_id = """ + Unique identifier of associated category group, if any + """ + category_group_name = """ + Name of category group associated with transaction, if any + """ + is_income = """ + Based on the associated category's property, denotes if transaction is + treated as income + """ + exclude_from_budget = """ + Based on the associated category's property, denotes if transaction is + excluded from budget + """ + exclude_from_totals = """ + Based on the associated category's property, denotes if transaction is + excluded from totals + """ + created_at = """ + The date and time of when the transaction was created (in the ISO 8601 + extended format). + """ + updated_at = """ + The date and time of when the transaction was last updated (in the ISO 8601 + extended format). + """ + status = """ + One of the following: + User intervention is required to change this to recurring. + """ + is_pending = """ + Denotes if transaction is pending (not posted) + """ notes = """ User-entered transaction notes If recurring_id is not null, this field will be description of associated recurring expense """ - category_id = """ - Unique identifier of associated category (see Categories) + original_name = """ + The transactions original name before any payee name updates. For synced + transactions, this is the raw original payee name from your bank. + """ + recurring_id = """ + Unique identifier of associated recurring item + """ + recurring_payee = """ + Payee name of associated recurring item + """ + recurring_description = """ + Description of associated recurring item + """ + recurring_cadence = """ + Cadence of associated recurring item (one of `once a week`, `every 2 weeks`, + `twice a month`, `monthly`, `every 2 months`, `every 3 months`, `every 4 months`, + `twice a year`, `yearly`) + """ + recurring_type = """ + Type of associated recurring (one of `cleared`, `suggested`, `dismissed`) + """ + recurring_amount = """ + Amount of associated recurring item + """ + recurring_currency = """ + Currency of associated recurring item + """ + parent_id = """ + Exists if this is a split transaction. Denotes the transaction ID of the + original transaction. Note that the parent transaction is not returned in + this call. + """ + has_children = """ + True if this transaction is a parent transaction and is split into 2 or + more other transactions + """ + group_id = """ + Exists if this transaction is part of a group. Denotes the parent’s + transaction ID + """ + is_group = """ + True if this transaction represents a group of transactions. If so, amount + and currency represent the totalled amount of transactions bearing this + transaction’s id as their group_id. Amount is calculated based on the + user’s primary currency. """ asset_id = """ Unique identifier of associated manually-managed account (see Assets) Note: plaid_account_id and asset_id cannot both exist for a transaction """ + asset_institution_name = """ + Institution name of associated manually-managed account + """ + asset_name = """ + Name of associated manually-managed account + """ + asset_display_name = """ + Display name of associated manually-managed account + """ + asset_status = """ + Status of associated manually-managed account (one of `active`, `closed`) + """ plaid_account_id = """ Unique identifier of associated Plaid account (see Plaid Accounts) Note: plaid_account_id and asset_id cannot both exist for a transaction """ - status = """ - One of the following: cleared: User has reviewed the transaction | uncleared: - User has not yet reviewed the transaction | recurring: Transaction is linked - to a recurring expense | recurring_suggested: Transaction is listed as a - suggested transaction for an existing recurring expense | pending: Imported - transaction is marked as pending. This should be a temporary state. User intervention - is required to change this to recurring. + plaid_account_name = """ + Name of associated Plaid account """ - parent_id = """ - Exists if this is a split transaction. Denotes the transaction ID of the original - transaction. Note that the parent transaction is not returned in this call. + plaid_account_mask = """ + Mask of associated Plaid account """ - is_group = """ - True if this transaction represents a group of transactions. If so, amount - and currency represent the totalled amount of transactions bearing this - transaction's id as their group_id. Amount is calculated based on the - user's primary currency. + institution_name = """ + Institution name of associated Plaid account """ - group_id = """ - Exists if this transaction is part of a group. Denotes the parent's transaction ID + plaid_account_display_name = """ + Display name of associated Plaid account """ - external_id = """ - User-defined external ID for any manually-entered or imported transaction. - External ID cannot be accessed or changed for Plaid-imported transactions. - External ID must be unique by asset_id. Max 75 characters. + plaid_metadata = """ + Metadata associated with imported transaction from Plaid """ - original_name = """ - The transactions original name before any payee name updates. For synced transactions, - this is the raw original payee name from your bank. + source = """ + Source of the transaction (one of `api`, `csv`, `manual`,`merge`,`plaid`, + `recurring`,`rule`,`user`) """ - type = """ - (for synced investment transactions only) The transaction type as set by - Plaid for investment transactions. Possible values include: buy, sell, cash, - transfer and more + display_name = """ + Display name for payee for transaction based on whether or not it is + linked to a recurring item. If linked, returns `recurring_payee` field. + Otherwise, returns the `payee` field. """ - subtype = """ - (for synced investment transactions only) The transaction type as set by Plaid - for investment transactions. Possible values include: management fee, withdrawal, - dividend, deposit and more + display_notes = """ + Display notes for transaction based on whether or not it is linked to a + recurring item. If linked, returns `recurring_notes` field. Otherwise, + returns the `notes` field. """ - fees = """ - (for synced investment transactions only) The fees as set by Plaid for investment - transactions. + account_display_name = """ + Display name for associated account (manual or Plaid). If this is a synced + account, returns `plaid_account_display_name` or `asset_display_name`. """ - price = """ - (for synced investment transactions only) The price as set by Plaid for investment - transactions. + tags = """ + Array of Tag objects """ - quantity = """ - (for synced investment transactions only) The quantity as set by Plaid for investment - transactions. + external_id = """ + User-defined external ID for any manually-entered or imported transaction. + External ID cannot be accessed or changed for Plaid-imported transactions. + External ID must be unique by asset_id. Max 75 characters. """ - to_base = """ - The amount converted to the user's primary currency. If the multicurrency - feature is not being used, to_base and amount will be the same. + children = """ + Array of Transaction objects. Only exists if this transaction is a parent + transaction and is split into 2 or more other transactions. Child transactions + do not contain all of the same fields as parent transactions. + """ + formatted_date = """ + Date of transaction in user's preferred format """ diff --git a/lunchable/models/transactions.py b/lunchable/models/transactions.py index dcae602f..c615c542 100644 --- a/lunchable/models/transactions.py +++ b/lunchable/models/transactions.py @@ -9,7 +9,8 @@ from enum import Enum from typing import Any, Dict, List, Optional, Union -from pydantic import Field +import pydantic_core +from pydantic import Field, field_validator from lunchable import LunchMoneyError from lunchable._config import APIConfig @@ -149,6 +150,25 @@ class FullStatusEnum(str, Enum): pending = "pending" +class TransactionChildObject(TransactionBaseObject): + """ + Child Transaction Object for Transaction Groups + """ + + id: int = Field(description=_TransactionDescriptions.id) + amount: float = Field(description=_TransactionDescriptions.amount) + payee: Optional[str] = Field(None, description=_TransactionDescriptions.payee) + date: datetime.date = Field(description=_TransactionDescriptions.date) + formatted_date: str = Field(description=_TransactionDescriptions.formatted_date) + notes: Optional[str] = Field(None, description=_TransactionDescriptions.notes) + currency: Optional[str] = Field(None, description=_TransactionDescriptions.currency) + asset_id: Optional[int] = Field(None, description=_TransactionDescriptions.asset_id) + plaid_account_id: Optional[int] = Field( + None, description=_TransactionDescriptions.plaid_account_id + ) + to_base: Optional[float] = Field(None, description=_TransactionDescriptions.to_base) + + class TransactionObject(TransactionBaseObject): """ Universal Lunch Money Transaction Object @@ -156,42 +176,137 @@ class TransactionObject(TransactionBaseObject): https://lunchmoney.dev/#transaction-object """ - id: int = Field(description="Unique identifier for transaction") - date: datetime.date = Field(description="Date of transaction in ISO 8601 format") + id: int = Field(description=_TransactionDescriptions.id) + date: datetime.date = Field(description=_TransactionDescriptions.date) payee: Optional[str] = Field(None, description=_TransactionDescriptions.payee) amount: float = Field(description=_TransactionDescriptions.amount) currency: Optional[str] = Field( None, max_length=3, description=_TransactionDescriptions.currency ) - notes: Optional[str] = Field(None, description=_TransactionDescriptions.notes) + to_base: Optional[float] = Field(None, description=_TransactionDescriptions.to_base) category_id: Optional[int] = Field( None, description=_TransactionDescriptions.category_id ) - asset_id: Optional[int] = Field(None, description=_TransactionDescriptions.asset_id) - plaid_account_id: Optional[int] = Field( - None, description=_TransactionDescriptions.plaid_account_id + category_name: Optional[str] = Field( + None, description=_TransactionDescriptions.category_name + ) + category_group_id: Optional[int] = Field( + None, description=_TransactionDescriptions.category_group_id + ) + category_group_name: Optional[str] = Field( + None, description=_TransactionDescriptions.category_group_name + ) + is_income: Optional[bool] = Field( + False, description=_TransactionDescriptions.is_income + ) + exclude_from_budget: Optional[bool] = Field( + False, description=_TransactionDescriptions.exclude_from_budget + ) + exclude_from_totals: Optional[bool] = Field( + False, description=_TransactionDescriptions.exclude_from_totals + ) + created_at: datetime.datetime = Field( + description=_TransactionDescriptions.created_at + ) + updated_at: datetime.datetime = Field( + description=_TransactionDescriptions.updated_at ) status: Optional[str] = Field(None, description=_TransactionDescriptions.status) + is_pending: Optional[bool] = Field( + False, description=_TransactionDescriptions.is_pending + ) + notes: Optional[str] = Field(None, description=_TransactionDescriptions.notes) + original_name: Optional[str] = Field( + None, description=_TransactionDescriptions.original_name + ) + recurring_id: Optional[int] = Field( + None, description=_TransactionDescriptions.recurring_id + ) + recurring_payee: Optional[str] = Field( + None, description=_TransactionDescriptions.recurring_payee + ) + recurring_description: Optional[str] = Field( + None, description=_TransactionDescriptions.recurring_description + ) + recurring_cadence: Optional[str] = Field( + None, description=_TransactionDescriptions.recurring_cadence + ) + recurring_type: Optional[str] = Field( + None, description=_TransactionDescriptions.recurring_type + ) + recurring_amount: Optional[float] = Field( + None, description=_TransactionDescriptions.recurring_amount + ) + recurring_currency: Optional[str] = Field( + None, description=_TransactionDescriptions.recurring_currency + ) parent_id: Optional[int] = Field( None, description=_TransactionDescriptions.parent_id ) + has_children: Optional[bool] = Field( + None, description=_TransactionDescriptions.has_children + ) + group_id: Optional[int] = Field(None, description=_TransactionDescriptions.group_id) is_group: Optional[bool] = Field( None, description=_TransactionDescriptions.is_group ) - group_id: Optional[int] = Field(None, description=_TransactionDescriptions.group_id) + asset_id: Optional[int] = Field(None, description=_TransactionDescriptions.asset_id) + asset_institution_name: Optional[str] = Field( + None, description=_TransactionDescriptions.asset_institution_name + ) + asset_name: Optional[str] = Field( + None, description=_TransactionDescriptions.asset_name + ) + asset_display_name: Optional[str] = Field( + None, description=_TransactionDescriptions.asset_display_name + ) + asset_status: Optional[str] = Field( + None, description=_TransactionDescriptions.asset_status + ) + plaid_account_id: Optional[int] = Field( + None, description=_TransactionDescriptions.plaid_account_id + ) + plaid_account_name: Optional[str] = Field( + None, description=_TransactionDescriptions.plaid_account_name + ) + plaid_account_mask: Optional[str] = Field( + None, description=_TransactionDescriptions.plaid_account_mask + ) + institution_name: Optional[str] = Field( + None, description=_TransactionDescriptions.institution_name + ) + plaid_account_display_name: Optional[str] = Field( + None, description=_TransactionDescriptions.plaid_account_display_name + ) + plaid_metadata: Optional[Dict[str, Any]] = Field( + None, description=_TransactionDescriptions.plaid_metadata + ) + source: Optional[str] = Field(None, description=_TransactionDescriptions.source) + display_name: Optional[str] = Field( + None, description=_TransactionDescriptions.display_name + ) + display_notes: Optional[str] = Field( + None, description=_TransactionDescriptions.display_notes + ) + account_display_name: Optional[str] = Field( + None, description=_TransactionDescriptions.account_display_name + ) tags: Optional[List[TagsObject]] = Field(None, description="Array of Tag objects") external_id: Optional[str] = Field( None, max_length=75, description=_TransactionDescriptions.external_id ) - original_name: Optional[str] = Field( - None, description=_TransactionDescriptions.original_name + children: Optional[List[TransactionChildObject]] = Field( + None, description=_TransactionDescriptions.children ) - type: Optional[str] = Field(None, description=_TransactionDescriptions.type) - subtype: Optional[str] = Field(None, description=_TransactionDescriptions.subtype) - fees: Optional[str] = Field(None, description=_TransactionDescriptions.fees) - price: Optional[str] = Field(None, description=_TransactionDescriptions.price) - quantity: Optional[str] = Field(None, description=_TransactionDescriptions.quantity) - to_base: Optional[float] = Field(None, description=_TransactionDescriptions.to_base) + + @field_validator("plaid_metadata", mode="before") + def to_json(cls, x: Optional[str]) -> Optional[Dict[str, Any]]: + """ + Check a result + """ + if x is None: + return None + return pydantic_core.from_json(x) def get_update_object(self) -> TransactionUpdateObject: """ @@ -240,6 +355,15 @@ def get_insert_object(self) -> TransactionInsertObject: return insert_object +class _TransactionsResponse(LunchableModel): + """ + HTTP Response for Transactions + """ + + transactions: List[TransactionObject] + has_more: bool = False + + class _TransactionParamsGet(LunchableModel): """ https://lunchmoney.dev/#get-all-transactions @@ -333,11 +457,12 @@ def get_transactions( """ Get Transactions Using Criteria - Use this to retrieve all transactions between a date range. Returns list of Transaction - objects. If no query parameters are set, this will return transactions for the - current calendar month. If either start_date or end_date are datetime.datetime objects, - they will be reduced to dates. If a string is provided, it will be attempted to be parsed - as YYYY-MM-DD format. + Use this to retrieve all transactions between a date range (this method handles + pagination automatically unless you specify a limit / offset argument). Returns + list of Transaction objects. If no query parameters are set, this will return + transactions for the current calendar month. If either start_date or end_date are + datetime.datetime objects, they will be reduced to dates. If a string is provided, + it will be attempted to be parsed as YYYY-MM-DD format. Parameters ---------- @@ -365,12 +490,11 @@ def get_transactions( Filter by status (Can be cleared or uncleared. For recurring transactions, use recurring) offset: Optional[int] - Sets the offset for the records returned + Sets the offset for the records returned (disables + automatic pagination) limit: Optional[int] - Sets the maximum number of records to return. Note: The server will not - respond with any indication that there are more records to be returned. - Please check the response length to determine if you should make another - call with an offset to fetch more transactions. + Sets the maximum number of records to return. Defaults to 1000 + (disables automatic pagination) debit_as_negative: Optional[bool] Pass in true if you'd like expenses to be returned as negative amounts and credits as positive amounts. Defaults to false. @@ -414,16 +538,47 @@ def get_transactions( pending=pending, ).model_dump(exclude_none=True) search_params.update(params if params is not None else {}) - response_data = self.make_request( + auto_paginate = all( + [ + offset is None, + search_params.get("offset") is None, + limit is None, + search_params.get("limit") is None, + ] + ) + transactions = self._get_transactions( + search_params=search_params, + paginate=auto_paginate, + ) + return transactions + + def _get_transactions( + self, + search_params: Dict[str, Any], + existing_transactions: Optional[List[TransactionObject]] = None, + paginate: bool = True, + ) -> List[TransactionObject]: + """ + Paginate Transactions + """ + existing_transactions = existing_transactions or [] + transaction_response = self.make_request( method=self.Methods.GET, url_path=APIConfig.LUNCHMONEY_TRANSACTIONS, params=search_params, ) - transactions = response_data[APIConfig.LUNCHMONEY_TRANSACTIONS] - transaction_objects = [ - TransactionObject.model_validate(item) for item in transactions - ] - return transaction_objects + transaction_response = _TransactionsResponse.model_validate( + transaction_response + ) + existing_transactions.extend(transaction_response.transactions) + if transaction_response.has_more and paginate: + search_params["offset"] = len(existing_transactions) + return self._get_transactions( + existing_transactions=existing_transactions, + search_params=search_params, + paginate=True, + ) + return existing_transactions def get_transaction( self, transaction_id: int, debit_as_negative: Optional[bool] = None @@ -776,3 +931,28 @@ def unsplit_transactions( ).model_dump(exclude_none=True), ) return response_data + + def get_transaction_group(self, transaction_id: int) -> TransactionObject: + """ + Get a Transaction Group + + Parameters + ---------- + transaction_id: int + Transaction ID of either the parent or any of the children + in the transaction group + + Returns + ------- + TransactionObject + The transaction group as a `TransactionObject` + """ + response_data = self.make_request( + method=self.Methods.GET, + params={"transaction_id": transaction_id}, + url_path=[ + APIConfig.LUNCHMONEY_TRANSACTIONS, + APIConfig.LUNCHMONEY_TRANSACTION_GROUPS, + ], + ) + return TransactionObject.model_validate(response_data) diff --git a/tests/conftest.py b/tests/conftest.py index edb0b02c..28fcacac 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -88,6 +88,8 @@ def test_transactions() -> List[TransactionObject]: "subtype": None, "tags": None, "type": None, + "created_at": "2021-09-19T20:00:00.000Z", + "updated_at": "2021-09-19T20:00:00.000Z", } transaction_dict_2 = { "amount": 2.0, @@ -111,6 +113,8 @@ def test_transactions() -> List[TransactionObject]: "subtype": None, "tags": None, "type": None, + "created_at": "2021-09-19T20:00:00.000Z", + "updated_at": "2021-09-19T20:00:00.000Z", } transaction_dict_3 = { "amount": 3.0, @@ -134,6 +138,8 @@ def test_transactions() -> List[TransactionObject]: "subtype": None, "tags": None, "type": None, + "created_at": "2021-09-19T20:00:00.000Z", + "updated_at": "2021-09-19T20:00:00.000Z", } transaction_1 = TransactionObject.model_validate(transaction_dict_1) transaction_2 = TransactionObject.model_validate(transaction_dict_2) diff --git a/tests/models/cassettes/test_get_transaction.yaml b/tests/models/cassettes/test_get_transaction.yaml index 2bac6126..d2aaef94 100644 --- a/tests/models/cassettes/test_get_transaction.yaml +++ b/tests/models/cassettes/test_get_transaction.yaml @@ -1,44 +1,48 @@ interactions: - request: - body: + body: '' headers: - Accept: + accept: - '*/*' - Accept-Encoding: + accept-encoding: - gzip, deflate - Connection: - - keep-alive - Content-Type: - - application/json - User-Agent: - - python-requests/2.29.0 authorization: - XXXXXXXXXX + connection: + - keep-alive + content-type: + - application/json + host: + - dev.lunchmoney.app + user-agent: + - lunchable/1.1.2 method: GET uri: https://dev.lunchmoney.app/v1/transactions/546434806 response: - content: '{"id":546434806,"date":"2023-12-12","payee":"Example Restaurant","amount":"120.0000","currency":"usd","to_base":120,"notes":"Saturday Dinner","category_id":null,"recurring_id":null,"asset_id":null,"plaid_account_id":null,"status":"uncleared","is_group":false,"group_id":null,"parent_id":null,"has_children":null,"tags":[],"external_id":null,"original_name":"Example Restaurant","type":null,"subtype":null}' + content: '{"id":546434806,"date":"2024-12-11","amount":"120.0000","currency":"usd","to_base":120,"payee":"Example Restaurant","category_id":null,"category_name":null,"category_group_id":null,"category_group_name":null,"is_income":null,"exclude_from_budget":null,"exclude_from_totals":null,"created_at":"2023-12-12T16:40:12.286Z","updated_at":"2024-01-23T23:19:49.127Z","status":"cleared","is_pending":false,"notes":"Saturday Dinner","original_name":"Example Restaurant","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":true,"group_id":null,"is_group":false,"asset_id":null,"asset_institution_name":null,"asset_name":null,"asset_display_name":null,"asset_status":null,"plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Example Restaurant","display_notes":"Saturday Dinner","account_display_name":" ","tags":[],"external_id":null}' headers: Access-Control-Allow-Credentials: - 'true' Connection: - keep-alive - Content-Length: - - '405' + Content-Encoding: + - gzip Content-Type: - application/json; charset=utf-8 Date: - - Fri, 15 Dec 2023 02:42:54 GMT + - Tue, 23 Jan 2024 23:23:39 GMT Etag: - - W/"195-EpyZHBeZX6gP2/Db89FUjBHiYrU" + - W/"452-JxRED/ZAoEZSX3h3KkuCa/XiEE0" Nel: - '{"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}' Report-To: - - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1702608174&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=8I8dTQbi4FBYy1yARTnn6jLVfvotluoMbjcgkSnyIIo%3D"}]}' + - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1706052219&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=eFqPqlndjy%2F2%2B%2FP0fpYgnnD58U35QSNISXcwx5ZeXMk%3D"}]}' Reporting-Endpoints: - - heroku-nel=https://nel.heroku.com/reports?ts=1702608174&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=8I8dTQbi4FBYy1yARTnn6jLVfvotluoMbjcgkSnyIIo%3D + - heroku-nel=https://nel.heroku.com/reports?ts=1706052219&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=eFqPqlndjy%2F2%2B%2FP0fpYgnnD58U35QSNISXcwx5ZeXMk%3D Server: - Cowboy + Transfer-Encoding: + - chunked Vary: - Origin, Accept-Encoding Via: diff --git a/tests/models/cassettes/test_get_transaction_group.yaml b/tests/models/cassettes/test_get_transaction_group.yaml new file mode 100644 index 00000000..dc32e903 --- /dev/null +++ b/tests/models/cassettes/test_get_transaction_group.yaml @@ -0,0 +1,54 @@ +interactions: +- request: + body: '' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + authorization: + - XXXXXXXXXX + connection: + - keep-alive + content-type: + - application/json + host: + - dev.lunchmoney.app + user-agent: + - lunchable/1.1.2 + method: GET + uri: https://dev.lunchmoney.app/v1/transactions/group?transaction_id=856827078 + response: + content: '{"id":856827078,"date":"2024-01-11","amount":"66.45","currency":"usd","to_base":66.45,"payee":"Skinix","category_id":443125,"category_name":"Home","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2024-01-24T03:15:39.118Z","updated_at":"2024-01-24T03:15:39.118Z","status":"cleared","is_pending":false,"notes":"Phasellus sit amet erat.","original_name":null,"recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":false,"group_id":null,"is_group":true,"asset_id":null,"asset_institution_name":null,"asset_name":null,"asset_display_name":null,"asset_status":null,"plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"user","display_name":"Skinix","display_notes":"Phasellus sit amet erat.","account_display_name":" ","tags":[],"children":[{"id":179018293,"payee":"Skinix","amount":"30.4100","currency":"usd","date":"2024-01-11","formatted_date":"2024-01-11","notes":"Phasellus sit amet erat.","asset_id":49335,"plaid_account_id":null,"to_base":30.41},{"id":179018477,"payee":"Fadeo","amount":"36.0400","currency":"usd","date":"2024-01-10","formatted_date":"2024-01-10","notes":null,"asset_id":49335,"plaid_account_id":null,"to_base":36.04}],"external_id":null}' + headers: + Access-Control-Allow-Credentials: + - 'true' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 24 Jan 2024 03:19:25 GMT + Etag: + - W/"5e1-0z/UXlyVUxPEmy5ZiLGu3uduZqg" + Nel: + - '{"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}' + Report-To: + - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1706066365&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=oJiXq5%2FCJrt%2FxFYEl20oSruOMIz%2Fw0LEQqBpC0Z03xc%3D"}]}' + Reporting-Endpoints: + - heroku-nel=https://nel.heroku.com/reports?ts=1706066365&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=oJiXq5%2FCJrt%2FxFYEl20oSruOMIz%2Fw0LEQqBpC0Z03xc%3D + Server: + - Cowboy + Transfer-Encoding: + - chunked + Vary: + - Origin, Accept-Encoding + Via: + - 1.1 vegur + X-Powered-By: + - Express + http_version: HTTP/1.1 + status_code: 200 +version: 1 diff --git a/tests/models/cassettes/test_get_transactions.yaml b/tests/models/cassettes/test_get_transactions.yaml index 3c8c0feb..dcd76c47 100644 --- a/tests/models/cassettes/test_get_transactions.yaml +++ b/tests/models/cassettes/test_get_transactions.yaml @@ -1,44 +1,48 @@ interactions: - request: - body: + body: '' headers: - Accept: + accept: - '*/*' - Accept-Encoding: + accept-encoding: - gzip, deflate - Connection: - - keep-alive - Content-Type: - - application/json - User-Agent: - - python-requests/2.29.0 authorization: - XXXXXXXXXX + connection: + - keep-alive + content-type: + - application/json + host: + - dev.lunchmoney.app + user-agent: + - lunchable/1.1.2 method: GET uri: https://dev.lunchmoney.app/v1/transactions response: - content: '{"transactions":[{"id":546434806,"date":"2023-12-12","original_date":null,"payee":"Example Restaurant","amount":"120.0000","currency":"usd","to_base":120,"notes":"Saturday Dinner","category_id":null,"recurring_id":null,"asset_id":null,"plaid_account_id":null,"status":"uncleared","is_group":false,"group_id":null,"parent_id":null,"tags":[],"external_id":null,"original_name":"Example Restaurant","type":null,"subtype":null},{"id":546452296,"date":"2023-12-12","original_date":null,"payee":"Example Restaurant","amount":"120.0000","currency":"usd","to_base":120,"notes":"Saturday Dinner","category_id":null,"recurring_id":null,"asset_id":null,"plaid_account_id":null,"status":"uncleared","is_group":false,"group_id":null,"parent_id":null,"tags":[],"external_id":"1234","original_name":"Example Restaurant","type":null,"subtype":null}]}' + content: '{"transactions":[{"id":179018371,"date":"2024-01-01","amount":"114.4800","currency":"usd","to_base":114.48,"payee":"Browsebug","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:54.681Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Browsebug","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Browsebug","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018392,"date":"2024-01-01","amount":"87.9700","currency":"usd","to_base":87.97,"payee":"Babbleblab","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:56.348Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Babbleblab","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":855353975,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Babbleblab","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018398,"date":"2024-01-01","amount":"5.3200","currency":"usd","to_base":5.32,"payee":"Voomm","category_id":443127,"category_name":"Personal Care","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:56.809Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.","original_name":"Voomm","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":855353975,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Voomm","display_notes":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018399,"date":"2024-01-01","amount":"22.5000","currency":"usd","to_base":22.5,"payee":"Fivechat","category_id":443127,"category_name":"Personal Care","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:56.885Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":"Donec vitae nisi.","original_name":"Fivechat","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":855353975,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Fivechat","display_notes":"Donec vitae nisi.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018437,"date":"2024-01-01","amount":"102.3200","currency":"usd","to_base":102.32,"payee":"Skivee","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:59.823Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Skivee","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Skivee","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018458,"date":"2024-01-01","amount":"78.9800","currency":"usd","to_base":78.98,"payee":"Oyoloo","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:09:01.466Z","updated_at":"2024-01-23T23:19:10.517Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Oyoloo","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Oyoloo","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018469,"date":"2024-01-01","amount":"90.2900","currency":"usd","to_base":90.29,"payee":"Quimba","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:09:02.328Z","updated_at":"2024-01-23T23:20:02.345Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Quimba","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Quimba","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":855353975,"date":"2024-01-01","amount":"115.78999999999999","currency":"usd","to_base":115.79,"payee":"Babbleblab","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2024-01-23T22:46:48.656Z","updated_at":"2024-01-23T23:20:01.854Z","status":"uncleared","is_pending":false,"notes":null,"original_name":null,"recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":false,"group_id":null,"is_group":true,"asset_id":null,"asset_institution_name":null,"asset_name":null,"asset_display_name":null,"asset_status":null,"plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"user","display_name":"Babbleblab","display_notes":null,"account_display_name":" ","tags":[],"children":[{"id":179018392,"payee":"Babbleblab","amount":"87.9700","currency":"usd","date":"2024-01-01","formatted_date":"2024-01-01","notes":null,"asset_id":49335,"plaid_account_id":null,"to_base":87.97},{"id":179018398,"payee":"Voomm","amount":"5.3200","currency":"usd","date":"2024-01-01","formatted_date":"2024-01-01","notes":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.","asset_id":49335,"plaid_account_id":null,"to_base":5.32},{"id":179018399,"payee":"Fivechat","amount":"22.5000","currency":"usd","date":"2024-01-01","formatted_date":"2024-01-01","notes":"Donec vitae nisi.","asset_id":49335,"plaid_account_id":null,"to_base":22.5}],"external_id":null},{"id":179018424,"date":"2024-01-05","amount":"2.9100","currency":"usd","to_base":2.91,"payee":"Twitterworks","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:58.822Z","updated_at":"2024-01-23T23:19:11.916Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Twitterworks","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Twitterworks","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018468,"date":"2024-01-07","amount":"42.7600","currency":"usd","to_base":42.76,"payee":"Blogspan","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:09:02.249Z","updated_at":"2024-01-23T23:19:13.193Z","status":"uncleared","is_pending":false,"notes":"Integer ac leo.","original_name":"Blogspan","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Blogspan","display_notes":"Integer ac leo.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018477,"date":"2024-01-10","amount":"36.0400","currency":"usd","to_base":36.04,"payee":"Fadeo","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:09:02.969Z","updated_at":"2024-01-23T23:19:14.338Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Fadeo","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Fadeo","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018293,"date":"2024-01-11","amount":"30.4100","currency":"usd","to_base":30.41,"payee":"Skinix","category_id":443125,"category_name":"Home","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:48.939Z","updated_at":"2024-01-23T23:19:15.467Z","status":"uncleared","is_pending":false,"notes":"Phasellus sit amet erat.","original_name":"Skinix","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Skinix","display_notes":"Phasellus sit amet erat.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018351,"date":"2024-01-11","amount":"72.5000","currency":"usd","to_base":72.5,"payee":"Skaboo","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:53.175Z","updated_at":"2024-01-23T23:19:16.672Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Skaboo","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Skaboo","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018428,"date":"2024-01-11","amount":"150.0000","currency":"usd","to_base":150,"payee":"Livetube","category_id":443127,"category_name":"Personal Care","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:59.122Z","updated_at":"2024-01-23T23:19:17.775Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Livetube","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Livetube","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018320,"date":"2024-01-12","amount":"84.9000","currency":"usd","to_base":84.9,"payee":"Linkbuzz","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:50.896Z","updated_at":"2024-01-23T23:19:18.953Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Linkbuzz","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Linkbuzz","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018356,"date":"2024-01-19","amount":"50.9300","currency":"usd","to_base":50.93,"payee":"Divanoodle","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:53.557Z","updated_at":"2024-01-23T23:19:20.121Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Divanoodle","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Divanoodle","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018330,"date":"2024-01-22","amount":"112.9100","currency":"usd","to_base":112.91,"payee":"Blogpad","category_id":443128,"category_name":"Groceries","category_group_id":658694,"category_group_name":"Test Category Group","is_income":false,"exclude_from_budget":true,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:51.634Z","updated_at":"2024-01-23T23:19:21.239Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Blogpad","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Blogpad","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018374,"date":"2024-01-24","amount":"64.2000","currency":"usd","to_base":64.2,"payee":"Devshare","category_id":443125,"category_name":"Home","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:54.909Z","updated_at":"2024-01-23T23:19:22.372Z","status":"uncleared","is_pending":false,"notes":"Nam nulla.","original_name":"Devshare","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Devshare","display_notes":"Nam nulla.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018343,"date":"2024-01-25","amount":"58.6200","currency":"usd","to_base":58.62,"payee":"Agimba","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:52.582Z","updated_at":"2024-01-23T23:19:23.495Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Agimba","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Agimba","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null}],"has_more":false}' headers: Access-Control-Allow-Credentials: - 'true' Connection: - keep-alive - Content-Length: - - '834' + Content-Encoding: + - gzip Content-Type: - application/json; charset=utf-8 Date: - - Fri, 15 Dec 2023 02:32:27 GMT + - Tue, 23 Jan 2024 23:20:58 GMT Etag: - - W/"342-P2joIYSONqkvyUVRlqWgtQcd1dE" + - W/"5534-/ugOb4U7RUc9/qQHHfMVYPdqD94" Nel: - '{"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}' Report-To: - - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1702607547&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=j4Lm34Pm%2FPJMsdTQ7%2BluAVSR4c0fbNpznidVd%2FrUlns%3D"}]}' + - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1706052057&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=ifKfasFhY%2FtzIamTz%2BqgOilIKCwalX1P45BnuJvMJow%3D"}]}' Reporting-Endpoints: - - heroku-nel=https://nel.heroku.com/reports?ts=1702607547&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=j4Lm34Pm%2FPJMsdTQ7%2BluAVSR4c0fbNpznidVd%2FrUlns%3D + - heroku-nel=https://nel.heroku.com/reports?ts=1706052057&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=ifKfasFhY%2FtzIamTz%2BqgOilIKCwalX1P45BnuJvMJow%3D Server: - Cowboy + Transfer-Encoding: + - chunked Vary: - Origin, Accept-Encoding Via: diff --git a/tests/models/cassettes/test_get_uncleared_transactions.yaml b/tests/models/cassettes/test_get_uncleared_transactions.yaml index e39061a1..58c9dd92 100644 --- a/tests/models/cassettes/test_get_uncleared_transactions.yaml +++ b/tests/models/cassettes/test_get_uncleared_transactions.yaml @@ -15,11 +15,11 @@ interactions: host: - dev.lunchmoney.app user-agent: - - lunchable/0.10.0 + - lunchable/1.1.2 method: GET uri: https://dev.lunchmoney.app/v1/transactions?status=uncleared response: - content: '{"transactions":[{"id":546452296,"date":"2023-12-12","original_date":null,"payee":"Example Restaurant","amount":"120.0000","currency":"usd","to_base":120,"notes":"Updated on 2023-12-14 20:10:09.718861","category_id":658693,"recurring_id":null,"asset_id":null,"plaid_account_id":null,"status":"uncleared","is_group":false,"group_id":null,"parent_id":null,"has_children":null,"tags":[],"external_id":"1234","original_name":"Example Restaurant","type":null,"subtype":null},{"id":561279455,"date":"2023-12-12","original_date":null,"payee":"Example Restaurant","amount":"60.0000","currency":"usd","to_base":60,"notes":"Saturday Dinner","category_id":443126,"recurring_id":null,"asset_id":null,"plaid_account_id":null,"status":"uncleared","is_group":false,"group_id":null,"parent_id":546434806,"has_children":null,"tags":[],"external_id":null,"original_name":null,"type":null,"subtype":null},{"id":561279456,"date":"2023-12-12","original_date":null,"payee":"Example Restaurant","amount":"60.0000","currency":"usd","to_base":60,"notes":"Saturday Dinner","category_id":443127,"recurring_id":null,"asset_id":null,"plaid_account_id":null,"status":"uncleared","is_group":false,"group_id":null,"parent_id":546434806,"has_children":null,"tags":[],"external_id":null,"original_name":null,"type":null,"subtype":null},{"id":561205301,"date":"2023-12-14","original_date":null,"payee":"Random Test","amount":"3.5000","currency":"usd","to_base":3.5,"notes":"Random Test Description: 2023-12-14 20:01:42.588685","category_id":443129,"recurring_id":null,"asset_id":49335,"plaid_account_id":null,"status":"uncleared","is_group":false,"group_id":null,"parent_id":null,"has_children":null,"tags":[],"external_id":null,"original_name":"Random Test","type":null,"subtype":null}]}' + content: '{"transactions":[{"id":179018371,"date":"2024-01-01","amount":"114.4800","currency":"usd","to_base":114.48,"payee":"Browsebug","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:54.681Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Browsebug","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Browsebug","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018392,"date":"2024-01-01","amount":"87.9700","currency":"usd","to_base":87.97,"payee":"Babbleblab","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:56.348Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Babbleblab","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":855353975,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Babbleblab","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018398,"date":"2024-01-01","amount":"5.3200","currency":"usd","to_base":5.32,"payee":"Voomm","category_id":443127,"category_name":"Personal Care","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:56.809Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.","original_name":"Voomm","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":855353975,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Voomm","display_notes":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018399,"date":"2024-01-01","amount":"22.5000","currency":"usd","to_base":22.5,"payee":"Fivechat","category_id":443127,"category_name":"Personal Care","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:56.885Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":"Donec vitae nisi.","original_name":"Fivechat","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":855353975,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Fivechat","display_notes":"Donec vitae nisi.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018437,"date":"2024-01-01","amount":"102.3200","currency":"usd","to_base":102.32,"payee":"Skivee","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:59.823Z","updated_at":"2024-01-23T22:48:31.879Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Skivee","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Skivee","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018458,"date":"2024-01-01","amount":"78.9800","currency":"usd","to_base":78.98,"payee":"Oyoloo","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:09:01.466Z","updated_at":"2024-01-23T23:19:10.517Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Oyoloo","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Oyoloo","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018469,"date":"2024-01-01","amount":"90.2900","currency":"usd","to_base":90.29,"payee":"Quimba","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:09:02.328Z","updated_at":"2024-01-23T23:20:02.345Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Quimba","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Quimba","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":855353975,"date":"2024-01-01","amount":"115.78999999999999","currency":"usd","to_base":115.79,"payee":"Babbleblab","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2024-01-23T22:46:48.656Z","updated_at":"2024-01-23T23:20:01.854Z","status":"uncleared","is_pending":false,"notes":null,"original_name":null,"recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":false,"group_id":null,"is_group":true,"asset_id":null,"asset_institution_name":null,"asset_name":null,"asset_display_name":null,"asset_status":null,"plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"user","display_name":"Babbleblab","display_notes":null,"account_display_name":" ","tags":[],"children":[{"id":179018392,"payee":"Babbleblab","amount":"87.9700","currency":"usd","date":"2024-01-01","formatted_date":"2024-01-01","notes":null,"asset_id":49335,"plaid_account_id":null,"to_base":87.97},{"id":179018398,"payee":"Voomm","amount":"5.3200","currency":"usd","date":"2024-01-01","formatted_date":"2024-01-01","notes":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.","asset_id":49335,"plaid_account_id":null,"to_base":5.32},{"id":179018399,"payee":"Fivechat","amount":"22.5000","currency":"usd","date":"2024-01-01","formatted_date":"2024-01-01","notes":"Donec vitae nisi.","asset_id":49335,"plaid_account_id":null,"to_base":22.5}],"external_id":null},{"id":179018424,"date":"2024-01-05","amount":"2.9100","currency":"usd","to_base":2.91,"payee":"Twitterworks","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:58.822Z","updated_at":"2024-01-23T23:19:11.916Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Twitterworks","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Twitterworks","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018468,"date":"2024-01-07","amount":"42.7600","currency":"usd","to_base":42.76,"payee":"Blogspan","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:09:02.249Z","updated_at":"2024-01-23T23:19:13.193Z","status":"uncleared","is_pending":false,"notes":"Integer ac leo.","original_name":"Blogspan","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Blogspan","display_notes":"Integer ac leo.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018477,"date":"2024-01-10","amount":"36.0400","currency":"usd","to_base":36.04,"payee":"Fadeo","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:09:02.969Z","updated_at":"2024-01-23T23:19:14.338Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Fadeo","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Fadeo","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018293,"date":"2024-01-11","amount":"30.4100","currency":"usd","to_base":30.41,"payee":"Skinix","category_id":443125,"category_name":"Home","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:48.939Z","updated_at":"2024-01-23T23:19:15.467Z","status":"uncleared","is_pending":false,"notes":"Phasellus sit amet erat.","original_name":"Skinix","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Skinix","display_notes":"Phasellus sit amet erat.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018351,"date":"2024-01-11","amount":"72.5000","currency":"usd","to_base":72.5,"payee":"Skaboo","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:53.175Z","updated_at":"2024-01-23T23:19:16.672Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Skaboo","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Skaboo","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018428,"date":"2024-01-11","amount":"150.0000","currency":"usd","to_base":150,"payee":"Livetube","category_id":443127,"category_name":"Personal Care","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:59.122Z","updated_at":"2024-01-23T23:19:17.775Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Livetube","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Livetube","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018320,"date":"2024-01-12","amount":"84.9000","currency":"usd","to_base":84.9,"payee":"Linkbuzz","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:50.896Z","updated_at":"2024-01-23T23:19:18.953Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Linkbuzz","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Linkbuzz","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018356,"date":"2024-01-19","amount":"50.9300","currency":"usd","to_base":50.93,"payee":"Divanoodle","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:53.557Z","updated_at":"2024-01-23T23:19:20.121Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Divanoodle","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Divanoodle","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018330,"date":"2024-01-22","amount":"112.9100","currency":"usd","to_base":112.91,"payee":"Blogpad","category_id":443128,"category_name":"Groceries","category_group_id":658694,"category_group_name":"Test Category Group","is_income":false,"exclude_from_budget":true,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:51.634Z","updated_at":"2024-01-23T23:19:21.239Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Blogpad","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Blogpad","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018374,"date":"2024-01-24","amount":"64.2000","currency":"usd","to_base":64.2,"payee":"Devshare","category_id":443125,"category_name":"Home","category_group_id":null,"category_group_name":null,"is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:54.909Z","updated_at":"2024-01-23T23:19:22.372Z","status":"uncleared","is_pending":false,"notes":"Nam nulla.","original_name":"Devshare","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Devshare","display_notes":"Nam nulla.","account_display_name":" Test Account","tags":[],"external_id":null},{"id":179018343,"date":"2024-01-25","amount":"58.6200","currency":"usd","to_base":58.62,"payee":"Agimba","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:52.582Z","updated_at":"2024-01-23T23:19:23.495Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Agimba","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Agimba","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null}],"has_more":false}' headers: Access-Control-Allow-Credentials: - 'true' @@ -30,15 +30,15 @@ interactions: Content-Type: - application/json; charset=utf-8 Date: - - Sat, 16 Dec 2023 04:58:01 GMT + - Tue, 23 Jan 2024 23:26:11 GMT Etag: - - W/"6d9-Hbzau0mQltfn4+9X1e5HlY8T0Jw" + - W/"5534-/ugOb4U7RUc9/qQHHfMVYPdqD94" Nel: - '{"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}' Report-To: - - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1702702680&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=U8zDcQAjevLxTY7sXga%2BxHDelU1ZdTXuO6MMsBzCYxs%3D"}]}' + - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1706052371&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=v8DgdVmXC7N7fbv0OyaM9Xms0oE%2FX7TUnR6G%2FU3yFL4%3D"}]}' Reporting-Endpoints: - - heroku-nel=https://nel.heroku.com/reports?ts=1702702680&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=U8zDcQAjevLxTY7sXga%2BxHDelU1ZdTXuO6MMsBzCYxs%3D + - heroku-nel=https://nel.heroku.com/reports?ts=1706052371&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=v8DgdVmXC7N7fbv0OyaM9Xms0oE%2FX7TUnR6G%2FU3yFL4%3D Server: - Cowboy Transfer-Encoding: diff --git a/tests/models/cassettes/test_split_transaction.yaml b/tests/models/cassettes/test_split_transaction.yaml index 68cb7dbb..e2ea8b21 100644 --- a/tests/models/cassettes/test_split_transaction.yaml +++ b/tests/models/cassettes/test_split_transaction.yaml @@ -1,44 +1,48 @@ interactions: - request: - body: + body: '' headers: - Accept: + accept: - '*/*' - Accept-Encoding: + accept-encoding: - gzip, deflate - Connection: - - keep-alive - Content-Type: - - application/json - User-Agent: - - python-requests/2.29.0 authorization: - XXXXXXXXXX + connection: + - keep-alive + content-type: + - application/json + host: + - dev.lunchmoney.app + user-agent: + - lunchable/1.1.2 method: GET - uri: https://dev.lunchmoney.app/v1/transactions/546434806 + uri: https://dev.lunchmoney.app/v1/transactions/179018320 response: - content: '{"id":546434806,"date":"2023-12-12","payee":"Example Restaurant","amount":"120.0000","currency":"usd","to_base":120,"notes":"Saturday Dinner","category_id":null,"recurring_id":null,"asset_id":null,"plaid_account_id":null,"status":"uncleared","is_group":false,"group_id":null,"parent_id":null,"has_children":null,"tags":[],"external_id":null,"original_name":"Example Restaurant","type":null,"subtype":null}' + content: '{"id":179018320,"date":"2024-01-12","amount":"84.9000","currency":"usd","to_base":84.9,"payee":"Linkbuzz","category_id":443126,"category_name":"Shopping","category_group_id":680257,"category_group_name":"Sub Shopping","is_income":false,"exclude_from_budget":false,"exclude_from_totals":false,"created_at":"2023-03-07T02:08:50.896Z","updated_at":"2024-01-23T23:19:18.953Z","status":"uncleared","is_pending":false,"notes":null,"original_name":"Linkbuzz","recurring_id":null,"recurring_payee":null,"recurring_description":null,"recurring_cadence":null,"recurring_type":null,"recurring_amount":null,"recurring_currency":null,"parent_id":null,"has_children":null,"group_id":null,"is_group":false,"asset_id":49335,"asset_institution_name":null,"asset_name":"Test Account","asset_display_name":null,"asset_status":"active","plaid_account_id":null,"plaid_account_name":null,"plaid_account_mask":null,"institution_name":null,"plaid_account_display_name":null,"plaid_metadata":null,"source":"api","display_name":"Linkbuzz","display_notes":null,"account_display_name":" Test Account","tags":[],"external_id":null}' headers: Access-Control-Allow-Credentials: - 'true' Connection: - keep-alive - Content-Length: - - '405' + Content-Encoding: + - gzip Content-Type: - application/json; charset=utf-8 Date: - - Fri, 15 Dec 2023 03:20:11 GMT + - Tue, 23 Jan 2024 23:35:23 GMT Etag: - - W/"195-EpyZHBeZX6gP2/Db89FUjBHiYrU" + - W/"44e-mfkledHpOThw11jMES6+wQLrz/c" Nel: - '{"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}' Report-To: - - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1702610411&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=kXFzz6lZ8cTSDiWk3YlUOnt7lsC6SWgxnye%2FRUfUgaM%3D"}]}' + - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1706052922&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=kSc8x3ilVsl5CAvd6qDPkmalC5Nqzc6dSrt79Sfnqlw%3D"}]}' Reporting-Endpoints: - - heroku-nel=https://nel.heroku.com/reports?ts=1702610411&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=kXFzz6lZ8cTSDiWk3YlUOnt7lsC6SWgxnye%2FRUfUgaM%3D + - heroku-nel=https://nel.heroku.com/reports?ts=1706052922&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=kSc8x3ilVsl5CAvd6qDPkmalC5Nqzc6dSrt79Sfnqlw%3D Server: - Cowboy + Transfer-Encoding: + - chunked Vary: - Origin, Accept-Encoding Via: @@ -48,26 +52,28 @@ interactions: http_version: HTTP/1.1 status_code: 200 - request: - body: '{"split": [{"date": "2023-12-12", "notes": "Saturday Dinner", "amount": 60.0}, {"date": "2023-12-12", "notes": "Saturday Dinner", "amount": 60.0}], "debit_as_negative": false, "skip_balance_update": true}' + body: '{"split":[{"date":"2024-01-12","category_id":443126,"amount":42.45},{"date":"2024-01-12","category_id":443126,"amount":42.45}]}' headers: - Accept: + accept: - '*/*' - Accept-Encoding: + accept-encoding: - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '204' - Content-Type: - - application/json - User-Agent: - - python-requests/2.29.0 authorization: - XXXXXXXXXX + connection: + - keep-alive + content-length: + - '127' + content-type: + - application/json + host: + - dev.lunchmoney.app + user-agent: + - lunchable/1.1.2 method: PUT - uri: https://dev.lunchmoney.app/v1/transactions/546434806 + uri: https://dev.lunchmoney.app/v1/transactions/179018320 response: - content: '{"updated":true,"split":[561279455,561279456]}' + content: '{"updated":true,"split":[855616911,855616912]}' headers: Access-Control-Allow-Credentials: - 'true' @@ -78,15 +84,15 @@ interactions: Content-Type: - application/json; charset=utf-8 Date: - - Fri, 15 Dec 2023 03:20:11 GMT + - Tue, 23 Jan 2024 23:35:23 GMT Etag: - - W/"2e-LKGEdHJmkqsaAfR24T71TLwHLOA" + - W/"2e-6YReKqNZ92GDgxDo0hopTaOS3gs" Nel: - '{"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}' Report-To: - - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1702610411&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=kXFzz6lZ8cTSDiWk3YlUOnt7lsC6SWgxnye%2FRUfUgaM%3D"}]}' + - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1706052923&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=w67Q6pk3jzwGCdAlFiRmvUOwzc5ljrEvqHCRySv8o5o%3D"}]}' Reporting-Endpoints: - - heroku-nel=https://nel.heroku.com/reports?ts=1702610411&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=kXFzz6lZ8cTSDiWk3YlUOnt7lsC6SWgxnye%2FRUfUgaM%3D + - heroku-nel=https://nel.heroku.com/reports?ts=1706052923&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=w67Q6pk3jzwGCdAlFiRmvUOwzc5ljrEvqHCRySv8o5o%3D Server: - Cowboy Vary: diff --git a/tests/models/cassettes/test_update_transaction.yaml b/tests/models/cassettes/test_update_transaction.yaml index 97defa43..cfbac8cf 100644 --- a/tests/models/cassettes/test_update_transaction.yaml +++ b/tests/models/cassettes/test_update_transaction.yaml @@ -1,21 +1,23 @@ interactions: - request: - body: '{"debit_as_negative": false, "skip_balance_update": true, "transaction": {"notes": "Updated on 2023-12-14 20:10:09.718861"}}' + body: '{"transaction":{"notes":"Updated on 2024-01-23 16:30:37.701144"}}' headers: - Accept: + accept: - '*/*' - Accept-Encoding: + accept-encoding: - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '124' - Content-Type: - - application/json - User-Agent: - - python-requests/2.29.0 authorization: - XXXXXXXXXX + connection: + - keep-alive + content-length: + - '65' + content-type: + - application/json + host: + - dev.lunchmoney.app + user-agent: + - lunchable/1.1.2 method: PUT uri: https://dev.lunchmoney.app/v1/transactions/546452296 response: @@ -30,15 +32,15 @@ interactions: Content-Type: - application/json; charset=utf-8 Date: - - Fri, 15 Dec 2023 03:10:09 GMT + - Tue, 23 Jan 2024 23:30:37 GMT Etag: - W/"10-dkPpo4JFIcQ3LWuPXbQ1isdU9JU" Nel: - '{"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}' Report-To: - - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1702609809&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=MWgNr9qn4zfBkSPF01eSVezrcmLqqmg85H%2FdTDj8ikg%3D"}]}' + - '{"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1706052637&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=6xx3hIyL%2BdwV%2BHTkQzPYGmuGTj8sQppv0SnpHMYmTKo%3D"}]}' Reporting-Endpoints: - - heroku-nel=https://nel.heroku.com/reports?ts=1702609809&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=MWgNr9qn4zfBkSPF01eSVezrcmLqqmg85H%2FdTDj8ikg%3D + - heroku-nel=https://nel.heroku.com/reports?ts=1706052637&sid=1b10b0ff-8a76-4548-befa-353fc6c6c045&s=6xx3hIyL%2BdwV%2BHTkQzPYGmuGTj8sQppv0SnpHMYmTKo%3D Server: - Cowboy Vary: diff --git a/tests/models/test_transactions.py b/tests/models/test_transactions.py index d6097959..7a122c2f 100644 --- a/tests/models/test_transactions.py +++ b/tests/models/test_transactions.py @@ -9,6 +9,7 @@ from lunchable import LunchMoney from lunchable.models.transactions import ( + TransactionChildObject, TransactionInsertObject, TransactionObject, TransactionSplitObject, @@ -105,7 +106,7 @@ def test_split_transaction(lunch_money_obj: LunchMoney): """ Try to split a transaction """ - transaction_to_split = lunch_money_obj.get_transaction(546434806) + transaction_to_split = lunch_money_obj.get_transaction(179018320) amount_1 = transaction_to_split.amount / 2 split_object = TransactionSplitObject( date=transaction_to_split.date, @@ -160,3 +161,14 @@ def test_204_response(lunch_money_obj: LunchMoney) -> None: ) response = lunch_money_obj.insert_transactions(transactions=test_transaction) assert response == [] + + +@lunchable_cassette +def test_get_transaction_group(lunch_money_obj: LunchMoney) -> None: + """ + Test get_transaction_group + """ + transaction_group = lunch_money_obj.get_transaction_group(transaction_id=856827078) + assert isinstance(transaction_group, TransactionObject) + assert transaction_group.is_group is True + assert isinstance(transaction_group.children[0], TransactionChildObject)