Combine like postings in non-commodity transaction views

This commit is contained in:
RunasSudo 2020-06-07 23:57:26 +10:00
parent 281ba65331
commit d87d49fc00
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
3 changed files with 27 additions and 17 deletions

View File

@ -50,14 +50,13 @@
<th style="text-align: right; min-width: 5em;">Cr</th>
</tr>
{% for posting in transaction.postings %}
{% set amount = posting.exchange(report_commodity, transaction.date) %}
{% for posting in transaction.exchange(report_commodity).postings %}
{% set trn_url = '/transaction?' + {'tid': transaction.id, 'cash': 'on' if cash else ''}|urlencode %}
<tr>
<td>{{ posting.comment }}</td>
<td><a href="/transactions?{{ {'date_end': transaction.date.strftime('%Y-%m-%d'), 'date_beg': transaction.date.strftime('%Y-%m-%d'), 'account': posting.account.name}|urlencode }}">{{ (posting.account.name|e).__str__().replace(':', ':<wbr>')|safe }}</a></td>
<td style="text-align: right;">{% if amount > 0 %}{{ amount|b }}{% endif %}</td>
<td style="text-align: right;">{% if amount < 0 %}{{ -amount|b }}{% endif %}</td>
<td style="text-align: right;">{% if posting.amount > 0 %}{{ posting.amount|b }}{% endif %}</td>
<td style="text-align: right;">{% if posting.amount < 0 %}{{ -posting.amount|b }}{% endif %}</td>
</tr>
{% endfor %}

View File

@ -99,8 +99,7 @@
{% endif %}
{% endif %}
{% for posting in transaction.postings if posting.account != account %}
{% set amount = posting.exchange(report_commodity, transaction.date) %}
{% for posting in transaction.exchange(report_commodity).postings if posting.account != account %}
{% set trn_first = not transaction.has_comment_detail and loop.first %}
{% set trn_last = loop.last %}
@ -116,9 +115,9 @@
<td><a href="/transactions?{{ {'date_end': date_end.strftime('%Y-%m-%d'), 'date_beg': date_beg.strftime('%Y-%m-%d'), 'account': posting.account.name, 'cash': 'on' if cash else ''}|urlencode }}">{{ (posting.account.name|e).__str__().replace(':', ':<wbr>')|safe }}</a></td>
{% if account %}
{# Reverse Dr/Cr so it's from the "perspective" of this account #}
{% set ns.balance = ns.balance - amount %}
<td style="text-align: right;">{% if amount < 0 %}{{ -amount|b }}{% endif %}</td>
<td style="text-align: right;">{% if amount > 0 %}{{ amount|b }}{% endif %}</td>
{% set ns.balance = ns.balance - posting.amount %}
<td style="text-align: right;">{% if posting.amount < 0 %}{{ -posting.amount|b }}{% endif %}</td>
<td style="text-align: right;">{% if posting.amount > 0 %}{{ posting.amount|b }}{% endif %}</td>
<td style="text-align: right;">
{% if loop.last %}
{% if ns.balance >= 0 %}
@ -129,8 +128,8 @@
{% endif %}
</td>
{% else %}
<td style="text-align: right;">{% if amount > 0 %}{{ amount|b }}{% endif %}</td>
<td style="text-align: right;">{% if amount < 0 %}{{ -amount|b }}{% endif %}</td>
<td style="text-align: right;">{% if posting.amount > 0 %}{{ posting.amount|b }}{% endif %}</td>
<td style="text-align: right;">{% if posting.amount < 0 %}{{ -posting.amount|b }}{% endif %}</td>
{% endif %}
</tr>
{% endfor %}

View File

@ -19,6 +19,7 @@ from .config import config
from decimal import Decimal
from enum import Enum
import functools
import itertools
class Ledger:
def __init__(self, date):
@ -78,6 +79,10 @@ class Transaction:
def __repr__(self):
return '<Transaction {} "{}">'.format(self.id, self.description)
@property
def has_comment_detail(self):
return any(p.comment for p in self.postings)
def describe(self):
result = ['{:%Y-%m-%d} {}'.format(self.date, self.description)]
for posting in self.postings:
@ -89,9 +94,16 @@ class Transaction:
result.postings = [Posting(p.transaction, p.account, -p.amount, p.comment, p.state) for p in self.postings]
return result
@property
def has_comment_detail(self):
return any(p.comment for p in self.postings)
def exchange(self, commodity):
result = Transaction(self.ledger, self.id, self.date, self.description, self.code, self.uuid)
# Combine like postings
for k, g in itertools.groupby(self.postings, key=lambda p: (p.account, p.comment, p.state)):
account, comment, state = k
posting = Posting(result, account, sum(p.exchange(commodity).amount for p in g), comment, state)
result.postings.append(posting)
return result
class Posting:
class State(Enum):
@ -109,11 +121,11 @@ class Posting:
def __repr__(self):
return '<Posting "{}" {}>'.format(self.account.name, self.amount.tostr(False))
def exchange(self, commodity, date):
def exchange(self, commodity):
if self.amount.commodity.name == commodity.name:
return Amount(self.amount)
return self
return self.amount.exchange(commodity, True) # Cost basis
return Posting(self.transaction, self.account, self.amount.exchange(commodity, True), self.comment, self.state) # Cost basis
class Account:
def __init__(self, ledger, name):