Skip to content

Commit 3cd2a85

Browse files
authored
Merge pull request #56 from RadCod3/fix/54-keyerror-txtools
Add Account type field and refactor Transaction handling
2 parents c3aedb1 + c813439 commit 3cd2a85

File tree

3 files changed

+42
-29
lines changed

3 files changed

+42
-29
lines changed

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ quote-style = "single"
3232
indent-style = "tab"
3333
docstring-code-format = true
3434

35+
[tool.ruff.lint]
36+
extend-select = ["I"]
37+
3538
[tool.datamodel-codegen]
3639
input = "firefly-iii-6.4.14-v1.yaml"
3740
output = "src/lampyrid/models/firefly_models.py"

src/lampyrid/models/lampyrid_models.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from datetime import date, datetime, timezone
2-
from enum import Enum
3-
from typing import List, Optional, Literal
2+
from typing import List, Literal, Optional
43

54
from pydantic import BaseModel, Field, model_validator
65

76
from .firefly_models import (
87
AccountRead,
98
AccountTypeFilter,
109
BudgetRead,
10+
ShortAccountTypeProperty,
1111
TransactionArray,
1212
TransactionRead,
1313
TransactionSingle,
@@ -25,6 +25,9 @@ def utc_now():
2525
class Account(BaseModel):
2626
id: str = Field(..., description='Unique identifier for the account', examples=['2'])
2727
name: str = Field(..., description='Display name of the account', examples=['Cash'])
28+
type: ShortAccountTypeProperty = Field(
29+
..., description='Type of the account', examples=['asset']
30+
)
2831
currency_code: Optional[str] = Field(
2932
None, description='Currency code (ISO 4217) for the account', examples=['GBP']
3033
)
@@ -38,6 +41,7 @@ def from_account_read(cls, account_read: 'AccountRead') -> 'Account':
3841
return cls(
3942
id=account_read.id,
4043
name=account_read.attributes.name,
44+
type=account_read.attributes.type,
4145
currency_code=account_read.attributes.currency_code,
4246
current_balance=(
4347
float(account_read.attributes.current_balance)
@@ -76,17 +80,11 @@ def from_budget_read(cls, budget_read: 'BudgetRead') -> 'Budget':
7680
)
7781

7882

79-
class TransactionType(Enum):
80-
withdrawal = 'withdrawal'
81-
deposit = 'deposit'
82-
transfer = 'transfer'
83-
84-
8583
class Transaction(BaseModel):
8684
id: Optional[str] = Field(None, description='Transaction ID')
8785
amount: float = Field(..., description='Amount of the transaction')
8886
description: str = Field(..., description='Description of the transaction')
89-
type: TransactionType = Field(..., description='Type of the transaction')
87+
type: TransactionTypeProperty = Field(..., description='Type of the transaction')
9088
date: datetime = Field(
9189
default_factory=datetime.now, description='Date and time of the transaction'
9290
)
@@ -111,7 +109,7 @@ def from_transaction_single(cls, trx: TransactionSingle) -> 'Transaction':
111109
id=trx.data.id,
112110
amount=float(inner_trx.amount),
113111
description=inner_trx.description,
114-
type=TransactionType[inner_trx.type.value],
112+
type=inner_trx.type,
115113
date=inner_trx.date,
116114
source_id=inner_trx.source_id,
117115
destination_id=inner_trx.destination_id,
@@ -131,9 +129,7 @@ def from_transaction_read(cls, transaction_read: TransactionRead) -> 'Transactio
131129
description=first_trx.description,
132130
amount=float(first_trx.amount),
133131
date=first_trx.date,
134-
type=TransactionType[first_trx.type.value]
135-
if first_trx.type
136-
else TransactionType.withdrawal,
132+
type=first_trx.type,
137133
source_id=first_trx.source_id,
138134
destination_id=first_trx.destination_id,
139135
source_name=first_trx.source_name,
@@ -145,7 +141,7 @@ def from_transaction_read(cls, transaction_read: TransactionRead) -> 'Transactio
145141

146142
def to_transaction_split_store(self) -> TransactionSplitStore:
147143
return TransactionSplitStore(
148-
type=TransactionTypeProperty(self.type.value),
144+
type=self.type,
149145
date=self.date,
150146
amount=str(self.amount),
151147
description=self.description,
@@ -545,6 +541,20 @@ class CreateBulkTransactionsRequest(BaseModel):
545541
max_length=100,
546542
)
547543

544+
@model_validator(mode='after')
545+
def validate_transactions(self):
546+
"""Ensure transactions are only of allowed types."""
547+
for trx in self.transactions:
548+
if trx.type not in {
549+
TransactionTypeProperty.withdrawal,
550+
TransactionTypeProperty.deposit,
551+
TransactionTypeProperty.transfer,
552+
}:
553+
raise ValueError(
554+
f'Invalid transaction type: {trx.type}. Only withdrawal, deposit, and transfer are allowed.'
555+
)
556+
return self
557+
548558

549559
class UpdateTransactionRequest(BaseModel):
550560
"""Update an existing transaction."""

uv.lock

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)