Refactors journal entry lines to use single amount
Simplifies the representation of journal entry lines by replacing separate debit and credit fields with a single 'amount' field. Positive amounts represent debits, while negative amounts represent credits, aligning with Beancount's approach. This change improves code readability and simplifies calculations for balancing entries.
This commit is contained in:
parent
d0bec3ea5a
commit
4ae6a8f7d2
5 changed files with 35 additions and 45 deletions
|
|
@ -61,8 +61,7 @@ class ImmutableEntryLine(NamedTuple):
|
|||
id: str
|
||||
journal_entry_id: str
|
||||
account_id: str
|
||||
debit: int
|
||||
credit: int
|
||||
amount: int # Beancount-style: positive = debit, negative = credit
|
||||
description: Optional[str]
|
||||
metadata: dict[str, Any]
|
||||
flag: Optional[str] # Like Beancount: '!', '*', etc.
|
||||
|
|
@ -145,15 +144,14 @@ class CastlePlugin(Protocol):
|
|||
__plugins__ = ('check_all_balanced',)
|
||||
|
||||
def check_all_balanced(entries, settings, config):
|
||||
"""Verify all journal entries have debits = credits"""
|
||||
"""Verify all journal entries balance (sum of amounts = 0)"""
|
||||
errors = []
|
||||
for entry in entries:
|
||||
total_debits = sum(line.debit for line in entry.lines)
|
||||
total_credits = sum(line.credit for line in entry.lines)
|
||||
if total_debits != total_credits:
|
||||
total_amount = sum(line.amount for line in entry.lines)
|
||||
if total_amount != 0:
|
||||
errors.append({
|
||||
'entry_id': entry.id,
|
||||
'message': f'Unbalanced entry: debits={total_debits}, credits={total_credits}',
|
||||
'message': f'Unbalanced entry: sum of amounts={total_amount} (must equal 0)',
|
||||
'severity': 'error'
|
||||
})
|
||||
return entries, errors
|
||||
|
|
@ -184,7 +182,7 @@ def check_receivable_limits(entries, settings, config):
|
|||
for line in entry.lines:
|
||||
if 'Accounts Receivable' in line.account_name:
|
||||
user_id = extract_user_from_account(line.account_name)
|
||||
receivables[user_id] = receivables.get(user_id, 0) + line.debit - line.credit
|
||||
receivables[user_id] = receivables.get(user_id, 0) + line.amount
|
||||
|
||||
for user_id, amount in receivables.items():
|
||||
if amount > max_per_user:
|
||||
|
|
@ -367,22 +365,15 @@ async def get_user_inventory(user_id: str) -> CastleInventory:
|
|||
# Add as position
|
||||
metadata = json.loads(line.metadata) if line.metadata else {}
|
||||
|
||||
if line.debit > 0:
|
||||
if line.amount != 0:
|
||||
# Beancount-style: positive = debit, negative = credit
|
||||
# Adjust sign for cost amount based on amount direction
|
||||
cost_sign = 1 if line.amount > 0 else -1
|
||||
inventory.add_position(CastlePosition(
|
||||
currency="SATS",
|
||||
amount=Decimal(line.debit),
|
||||
amount=Decimal(line.amount),
|
||||
cost_currency=metadata.get("fiat_currency"),
|
||||
cost_amount=Decimal(metadata.get("fiat_amount", 0)),
|
||||
date=line.created_at,
|
||||
metadata=metadata
|
||||
))
|
||||
|
||||
if line.credit > 0:
|
||||
inventory.add_position(CastlePosition(
|
||||
currency="SATS",
|
||||
amount=-Decimal(line.credit),
|
||||
cost_currency=metadata.get("fiat_currency"),
|
||||
cost_amount=-Decimal(metadata.get("fiat_amount", 0)),
|
||||
cost_amount=cost_sign * Decimal(metadata.get("fiat_amount", 0)),
|
||||
date=line.created_at,
|
||||
metadata=metadata
|
||||
))
|
||||
|
|
@ -840,17 +831,16 @@ class UnbalancedEntryError(NamedTuple):
|
|||
async def validate_journal_entry(entry: CreateJournalEntry) -> list[CastleError]:
|
||||
errors = []
|
||||
|
||||
total_debits = sum(line.debit for line in entry.lines)
|
||||
total_credits = sum(line.credit for line in entry.lines)
|
||||
# Beancount-style: sum of amounts must equal 0
|
||||
total_amount = sum(line.amount for line in entry.lines)
|
||||
|
||||
if total_debits != total_credits:
|
||||
if total_amount != 0:
|
||||
errors.append(UnbalancedEntryError(
|
||||
source={'created_by': entry.created_by},
|
||||
message=f"Entry does not balance: debits={total_debits}, credits={total_credits}",
|
||||
message=f"Entry does not balance: sum of amounts={total_amount} (must equal 0)",
|
||||
entry=entry.dict(),
|
||||
total_debits=total_debits,
|
||||
total_credits=total_credits,
|
||||
difference=total_debits - total_credits
|
||||
total_amount=total_amount,
|
||||
difference=total_amount
|
||||
))
|
||||
|
||||
return errors
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue