fund: Text output readability improvements.
Make it look more like the spreadsheets: * Don't normalize Expenses negative. * Consistent account order: Income, then Expenses, then Equity. * Include a bottom line divider for each fund.
This commit is contained in:
parent
cc1767a09d
commit
58954aab23
2 changed files with 21 additions and 11 deletions
|
@ -82,7 +82,7 @@ from .. import data
|
|||
AccountsMap = Mapping[data.Account, core.PeriodPostings]
|
||||
FundPosts = Tuple[MetaValue, AccountsMap]
|
||||
|
||||
EQUITY_ACCOUNTS = ['Equity', 'Income', 'Expenses']
|
||||
EQUITY_ACCOUNTS = ['Income', 'Expenses', 'Equity']
|
||||
INFO_ACCOUNTS = [
|
||||
'Assets:Receivable',
|
||||
'Assets:Prepaid',
|
||||
|
@ -106,7 +106,7 @@ class ODSReport(core.BaseODS[FundPosts, None]):
|
|||
headers = [["Fund"], ["Balance as of", self.start_date.isoformat()]]
|
||||
if expanded:
|
||||
sheet_name = "With Breakdowns"
|
||||
headers += [["Income"], ["Expenses"], ["Equity"]]
|
||||
headers.extend([acct] for acct in EQUITY_ACCOUNTS)
|
||||
else:
|
||||
sheet_name = "Fund Report"
|
||||
headers += [["Additions"], ["Releases from", "Restrictions"]]
|
||||
|
@ -176,10 +176,9 @@ class ODSReport(core.BaseODS[FundPosts, None]):
|
|||
self.sheet = start_sheet
|
||||
|
||||
def _row_balances(self, accounts_map: AccountsMap) -> Iterator[core.Balance]:
|
||||
acct_order = ['Income', 'Expenses', 'Equity']
|
||||
key_order = [core.OPENING_BALANCE_NAME, *acct_order, core.ENDING_BALANCE_NAME]
|
||||
key_order = [core.OPENING_BALANCE_NAME, *EQUITY_ACCOUNTS, core.ENDING_BALANCE_NAME]
|
||||
balances: Dict[str, core.Balance] = {key: core.MutableBalance() for key in key_order}
|
||||
for acct_s, balance in core.account_balances(accounts_map, acct_order):
|
||||
for acct_s, balance in core.account_balances(accounts_map, EQUITY_ACCOUNTS):
|
||||
if acct_s in balances:
|
||||
balances[acct_s] = balance
|
||||
else:
|
||||
|
@ -242,7 +241,9 @@ class TextReport:
|
|||
acct_s = total_fmt.format(self.start_date.isoformat())
|
||||
elif acct_s is core.ENDING_BALANCE_NAME:
|
||||
acct_s = total_fmt.format(self.stop_date.isoformat())
|
||||
yield acct_s, (-balance).format(None, sep='\0').split('\0')
|
||||
if not acct_s.startswith('Expenses:'):
|
||||
balance = -balance
|
||||
yield acct_s, balance.format(None, sep='\0').split('\0')
|
||||
for _, account in core.sort_and_filter_accounts(account_map, INFO_ACCOUNTS):
|
||||
balance = account_map[account].stop_bal
|
||||
if not balance.is_zero():
|
||||
|
@ -262,14 +263,19 @@ class TextReport:
|
|||
print(line_fmt.replace('{:>', '{:^').format("ACCOUNT", "BALANCE"),
|
||||
file=self.out_file)
|
||||
fund_start = f' balance as of {self.start_date.isoformat()}'
|
||||
fund_end = f' balance as of {self.stop_date.isoformat()}'
|
||||
for acct_s, bal_seq in output:
|
||||
if acct_s.endswith(fund_start):
|
||||
print(line_fmt.format('―' * acct_width, '―' * bal_width),
|
||||
is_end_bal = acct_s.endswith(fund_end)
|
||||
if is_end_bal or acct_s.endswith(fund_start):
|
||||
print(line_fmt.format('─' * acct_width, '─' * bal_width),
|
||||
file=self.out_file)
|
||||
bal_iter = iter(bal_seq)
|
||||
print(line_fmt.format(acct_s, next(bal_iter)), file=self.out_file)
|
||||
for bal_s in bal_iter:
|
||||
print(line_fmt.format('', bal_s), file=self.out_file)
|
||||
if is_end_bal:
|
||||
print(line_fmt.format('═' * acct_width, '═' * bal_width),
|
||||
file=self.out_file)
|
||||
|
||||
|
||||
class ReportType(enum.Enum):
|
||||
|
|
|
@ -111,11 +111,13 @@ def check_text_balances(actual, expected, *expect_accounts):
|
|||
balance = Decimal()
|
||||
for expect_account in expect_accounts:
|
||||
expect_amount = expected[expect_account]
|
||||
balance += expect_amount
|
||||
if expect_account.startswith('Expenses:'):
|
||||
expect_amount *= -1
|
||||
if expect_amount:
|
||||
actual_account, actual_amount = next(actual)
|
||||
assert actual_account == expect_account
|
||||
assert actual_amount == format_amount(expect_amount)
|
||||
balance += expect_amount
|
||||
return balance
|
||||
|
||||
def check_text_report(output, project, start_date, stop_date):
|
||||
|
@ -142,17 +144,19 @@ def check_text_report(output, project, start_date, stop_date):
|
|||
assert open_amt == format_amount(balance_amount)
|
||||
balance_amount += check_text_balances(
|
||||
actual, expected,
|
||||
'Income:Other',
|
||||
'Expenses:Other',
|
||||
'Equity:Funds:Restricted',
|
||||
'Equity:Funds:Unrestricted',
|
||||
'Equity:Realized:CurrencyConversion',
|
||||
'Income:Other',
|
||||
'Expenses:Other',
|
||||
)
|
||||
next(actual)
|
||||
end_acct, end_amt = next(actual)
|
||||
assert end_acct == "{} balance as of {}".format(
|
||||
project, stop_date.isoformat(),
|
||||
)
|
||||
assert end_amt == format_amount(balance_amount)
|
||||
next(actual)
|
||||
balance_amount += check_text_balances(
|
||||
actual, expected,
|
||||
'Assets:Receivable:Accounts',
|
||||
|
|
Loading…
Reference in a new issue