diff --git a/ledger_pyreport/__init__.py b/ledger_pyreport/__init__.py index 967c455..d34464d 100644 --- a/ledger_pyreport/__init__.py +++ b/ledger_pyreport/__init__.py @@ -98,6 +98,14 @@ def balance(): return flask.render_template('balance.html', ledger=l, balance_sheets=balance_sheets, accounts=accounts, config=config, report_currency=report_currency) +def describe_period(date_end, date_beg): + if date_end == (date_beg.replace(year=date_beg.year + 1) - timedelta(days=1)): + return 'year ended {}'.format(date_end.strftime('%d %B %Y')) + elif date_beg == ledger.financial_year(date_end): + return 'financial year to {}'.format(date_end.strftime('%d %B %Y')) + else: + return 'period from {} to {}'.format(date_beg.strftime('%d %B %Y'), date_end.strftime('%d %B %Y')) + @app.route('/pandl') def pandl(): date_beg = datetime.strptime(flask.request.args['date_beg'], '%Y-%m-%d') @@ -118,14 +126,7 @@ def pandl(): if all(p.get_balance(account) == 0 and p.get_total(account) == 0 for p in pandls): accounts.remove(account) - if date_end == (date_beg.replace(year=date_beg.year + 1) - timedelta(days=1)): - period = 'year ended {}'.format(date_end.strftime('%d %B %Y')) - elif date_beg == ledger.financial_year(date_end): - period = 'financial year to {}'.format(date_end.strftime('%d %B %Y')) - else: - period = 'period from {} to {}'.format(date_beg.strftime('%d %B %Y'), date_end.strftime('%d %B %Y')) - - return flask.render_template('pandl.html', period=period, ledger=l, pandls=pandls, accounts=accounts, config=config, report_currency=report_currency) + return flask.render_template('pandl.html', period=describe_period(date_end, date_beg), ledger=l, pandls=pandls, accounts=accounts, config=config, report_currency=report_currency) @app.route('/transactions') def transactions(): @@ -154,7 +155,7 @@ def transactions(): opening_balance = accounting.trial_balance(l, pstart, pstart).get_balance(account).exchange(report_currency, True) closing_balance = accounting.trial_balance(l, date, pstart).get_balance(account).exchange(report_currency, True) - return flask.render_template('transactions.html', date=date, pstart=pstart, account=account, ledger=l, transactions=transactions, opening_balance=opening_balance, closing_balance=closing_balance, report_currency=report_currency) + return flask.render_template('transactions.html', date=date, pstart=pstart, period=describe_period(date, pstart), account=account, ledger=l, transactions=transactions, opening_balance=opening_balance, closing_balance=closing_balance, report_currency=report_currency, timedelta=timedelta) @app.template_filter('a') def filter_amount(amt): diff --git a/ledger_pyreport/jinja2/balance.html b/ledger_pyreport/jinja2/balance.html index 05ee774..3444223 100644 --- a/ledger_pyreport/jinja2/balance.html +++ b/ledger_pyreport/jinja2/balance.html @@ -16,6 +16,8 @@ along with this program. If not, see . #} +{% extends 'base_report.html' %} + {% macro print_rows(account, invert=False, level=0) %} @@ -80,40 +82,33 @@ {% endmacro %} - - - - - Balance Sheet as at {{ balance_sheets[0].date.strftime('%d %B %Y') }} - - - - -

Balance Sheet

-

As at {{ balance_sheets[0].date.strftime('%d %B %Y') }}

+{% block title %}Balance Sheet as at {{ balance_sheets[0].date.strftime('%d %B %Y') }}{% endblock %} + +{% block report %} +

Balance Sheet

+

As at {{ balance_sheets[0].date.strftime('%d %B %Y') }}

+ + + {# Assets #} + + {{ do_accounts(ledger.get_account(config['assets_account']), 'Assets', False, True) }} + -
Assets
 
- {# Assets #} - - {{ do_accounts(ledger.get_account(config['assets_account']), 'Assets', False, True) }} - - - {# Liabilities #} - - {{ do_accounts(ledger.get_account(config['liabilities_account']), 'Liabilities', True, False) }} - - - {# Equity #} - - - {% for account in ledger.get_account(config['equity_account']).children if account in accounts %} - {{ print_rows(account, invert=True) }} - {% endfor %} - - - - {% for balance_sheet in balance_sheets %}{% endfor %} - -
Assets
 
Liabilities
 
Equity
Total Equity{{ -balance_sheet.get_total(ledger.get_account(config['equity_account'])).exchange(report_currency, True)|a }}
- - + {# Liabilities #} + Liabilities + {{ do_accounts(ledger.get_account(config['liabilities_account']), 'Liabilities', True, False) }} +   + + {# Equity #} + Equity + + {% for account in ledger.get_account(config['equity_account']).children if account in accounts %} + {{ print_rows(account, invert=True) }} + {% endfor %} + + + Total Equity + {% for balance_sheet in balance_sheets %}{{ -balance_sheet.get_total(ledger.get_account(config['equity_account'])).exchange(report_currency, True)|a }}{% endfor %} + + +{% endblock %} diff --git a/ledger_pyreport/jinja2/base.html b/ledger_pyreport/jinja2/base.html new file mode 100644 index 0000000..6f66a01 --- /dev/null +++ b/ledger_pyreport/jinja2/base.html @@ -0,0 +1,30 @@ +{# + ledger-pyreport + Copyright © 2020 Lee Yingtong Li (RunasSudo) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +#} + + + + + + {% block title %}{% endblock %} + + + + + {% block body %}{% endblock %} + + diff --git a/ledger_pyreport/jinja2/base_report.html b/ledger_pyreport/jinja2/base_report.html new file mode 100644 index 0000000..3f65983 --- /dev/null +++ b/ledger_pyreport/jinja2/base_report.html @@ -0,0 +1,26 @@ +{# + ledger-pyreport + Copyright © 2020 Lee Yingtong Li (RunasSudo) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +#} + +{% extends 'base.html' %} + +{% block body %} + Home + + {% block report %} + {% endblock %} +{% endblock %} diff --git a/ledger_pyreport/jinja2/index.html b/ledger_pyreport/jinja2/index.html index 54768c4..0eea14b 100644 --- a/ledger_pyreport/jinja2/index.html +++ b/ledger_pyreport/jinja2/index.html @@ -16,60 +16,57 @@ along with this program. If not, see . #} - - - - - ledger-pyreport - - -
    -
  • - - - - - {##} -
  • - -
  • - - - - - {##} -
  • - -
  • - - - - - {##} -
  • - -
  • - - - - {##} -
  • -
+{% extends 'base.html' %} + +{% block title %}ledger-pyreport{% endblock %} + +{% block body %} +
    +
  • + + + + + {##} +
  • - - - + } + +{% endblock %} diff --git a/ledger_pyreport/jinja2/pandl.html b/ledger_pyreport/jinja2/pandl.html index 45fa1bc..5ca3f13 100644 --- a/ledger_pyreport/jinja2/pandl.html +++ b/ledger_pyreport/jinja2/pandl.html @@ -16,6 +16,8 @@ along with this program. If not, see . #} +{% extends 'base_report.html' %} + {% macro print_rows(account, invert=False, level=0) %} @@ -57,29 +59,22 @@ {% endmacro %} - - - - - Income Statement for the {{ period }} - - - - -

    Income Statement

    -

    For the {{ period }}

    +{% block title %}Income Statement for the {{ period }}{% endblock %} + +{% block report %} +

    Income Statement

    +

    For the {{ period }}

    + + + {{ do_accounts(ledger.get_account(config['income_account']), 'Income', True, True) }} + -
     
    - {{ do_accounts(ledger.get_account(config['income_account']), 'Income', True, True) }} - - - {{ do_accounts(ledger.get_account(config['expenses_account']), 'Expenses', False, False) }} - - - - - {% for pandl in pandls %}{% endfor %} - -
     
     
    Net Surplus (Loss){{ -(pandl.get_total(ledger.get_account(config['income_account'])) + pandl.get_total(ledger.get_account(config['expenses_account']))).exchange(report_currency, True)|a }}
    - - + {{ do_accounts(ledger.get_account(config['expenses_account']), 'Expenses', False, False) }} +   + + + Net Surplus (Loss) + {% for pandl in pandls %}{{ -(pandl.get_total(ledger.get_account(config['income_account'])) + pandl.get_total(ledger.get_account(config['expenses_account']))).exchange(report_currency, True)|a }}{% endfor %} + + +{% endblock %} diff --git a/ledger_pyreport/jinja2/transactions.html b/ledger_pyreport/jinja2/transactions.html index cecca86..f5d5495 100644 --- a/ledger_pyreport/jinja2/transactions.html +++ b/ledger_pyreport/jinja2/transactions.html @@ -16,105 +16,102 @@ along with this program. If not, see . #} - - - - - {% if account %}Account Transactions{% else %}General Ledger{% endif %} as at {{ date.strftime('%d %B %Y') }} - - - - - {% if account %} -

    Account Transactions

    -

    For {{ account.name }}

    - {% else %} -

    General Ledger

    - {% endif %} -

    As at {{ date.strftime('%d %B %Y') }}

    +{% extends 'base_report.html' %} + +{% block title %}{% if account %}Account Transactions{% else %}General Ledger{% endif %} as at {{ date.strftime('%d %B %Y') }}{% endblock %} + +{% block report %} + {% if account %} +

    Account Transactions

    +

    For {{ account.name }}

    + {% else %} +

    General Ledger

    + {% endif %} +

    For the {{ period }}

    + + + + + + + + + {% if account %}{% endif %} + -
    DateDescriptionAccountDrCrBalance
    - - - - - - - {% if account %}{% endif %} - - - {% set ns = namespace(balance=None) %} - {% if account %} - - - - - - - + + + + + + - - {% set ns.balance = opening_balance %} - {% endif %} - - {% for transaction in transactions %} - {% for posting in transaction.postings if (posting.amount.amount >= 0.05 or posting.amount.amount < -0.05) and posting.account != account %} - {% set amount = posting.exchange(report_currency, transaction.date) %} - - - - - {% if account %} - {# Reverse Dr/Cr so it's from the "perspective" of this account #} - {% set ns.balance = ns.balance - amount %} - - - + + {% set ns.balance = opening_balance %} + {% endif %} + + {% for transaction in transactions %} + {% for posting in transaction.postings if (posting.amount.amount >= 0.05 or posting.amount.amount < -0.05) and posting.account != account %} + {% set amount = posting.exchange(report_currency, transaction.date) %} + + + + + {% if account %} + {# Reverse Dr/Cr so it's from the "perspective" of this account #} + {% set ns.balance = ns.balance - amount %} + + + - {% else %} - - - {% endif %} - - {% endfor %} + {% endif %} + + {% else %} + + + {% endif %} + {% endfor %} - - {% if account %} - - - - - - - - - {% else %} - - - - - - - - {% endif %} -
    DateDescriptionAccountDrCrBalance
    {{ pstart.strftime('%Y-%m-%d') }}Opening Balance + {% set ns = namespace(balance=None) %} + {% if account %} +
    {{ pstart.strftime('%Y-%m-%d') }}Opening Balance + {% if opening_balance >= 0 %} {{ opening_balance|b }} Dr {% else %} {{ -opening_balance|b }} Cr {% endif %} -
    {% if loop.first %}{{ transaction.date.strftime('%Y-%m-%d') }}{% endif %}{% if loop.first %}{{ transaction.description }}{% endif %}{{ (posting.account.name|e).__str__().replace(':', ':')|safe }}{% if amount < 0 %}{{ -amount|b }}{% endif %}{% if amount > 0 %}{{ amount|b }}{% endif %} - {% if loop.last %} - {% if ns.balance >= 0 %} - {{ ns.balance|b }} Dr - {% else %} - {{ -ns.balance|b }} Cr - {% endif %} + +
    {% if loop.first %}{{ transaction.date.strftime('%Y-%m-%d') }}{% endif %}{% if loop.first %}{{ transaction.description }}{% endif %}{{ (posting.account.name|e).__str__().replace(':', ':')|safe }}{% if amount < 0 %}{{ -amount|b }}{% endif %}{% if amount > 0 %}{{ amount|b }}{% endif %} + {% if loop.last %} + {% if ns.balance >= 0 %} + {{ ns.balance|b }} Dr + {% else %} + {{ -ns.balance|b }} Cr {% endif %} - {% if amount > 0 %}{{ amount|b }}{% endif %}{% if amount < 0 %}{{ -amount|b }}{% endif %}
    {% if amount > 0 %}{{ amount|b }}{% endif %}{% if amount < 0 %}{{ -amount|b }}{% endif %}
    {{ date.strftime('%Y-%m-%d') }}Closing Balance - {% if closing_balance >= 0 %} - {{ closing_balance|b }} Dr - {% else %} - {{ -closing_balance|b }} Cr - {% endif %} -
    {{ date.strftime('%Y-%m-%d') }}Total{{ total_dr|b }}{{ -total_cr|b }}
    - - + {% endfor %} + + {% if account %} + + {{ date.strftime('%Y-%m-%d') }} + Closing Balance + + + + + {% if closing_balance >= 0 %} + {{ closing_balance|b }} Dr + {% else %} + {{ -closing_balance|b }} Cr + {% endif %} + + + {% else %} + + {{ date.strftime('%Y-%m-%d') }} + Total + + {{ total_dr|b }} + {{ -total_cr|b }} + + {% endif %} + +{% endblock %} diff --git a/ledger_pyreport/jinja2/trial.html b/ledger_pyreport/jinja2/trial.html index 5b73652..bec3ce8 100644 --- a/ledger_pyreport/jinja2/trial.html +++ b/ledger_pyreport/jinja2/trial.html @@ -16,41 +16,36 @@ along with this program. If not, see . #} - - - - - Trial Balance as at {{ trial_balance.date.strftime('%d %B %Y') }} - - - - -

    Trial Balance

    -

    As at {{ trial_balance.date.strftime('%d %B %Y') }}

    - - - - - - - - {% for account in accounts %} - {# Display in "cost basis" as we have already accounted for unrealised gains #} - {% set balance = trial_balance.get_balance(account).exchange(report_currency, True) %} - {% set trn_url = "/transactions?" + {'date': trial_balance.date.strftime('%Y-%m-%d'), 'pstart': trial_balance.pstart.strftime('%Y-%m-%d'), 'account': account.name}|urlencode %} - {% if balance != 0 %} - - - - - - {% endif %} - {% endfor %} - - - - - -
    DrCr
    {{ account.name }}{% if balance > 0 %}{{ balance|b }}{% endif %}{% if balance < 0 %}{{ -balance|b }}{% endif %}
    {{ total_dr|b }}{{ total_cr|b }}
    - - +{% extends 'base_report.html' %} + +{% block title %}Trial Balance as at {{ trial_balance.date.strftime('%d %B %Y') }}{% endblock %} + +{% block report %} +

    Trial Balance

    +

    As at {{ trial_balance.date.strftime('%d %B %Y') }}

    + + + + + + + + {% for account in accounts %} + {# Display in "cost basis" as we have already accounted for unrealised gains #} + {% set balance = trial_balance.get_balance(account).exchange(report_currency, True) %} + {% set trn_url = "/transactions?" + {'date': trial_balance.date.strftime('%Y-%m-%d'), 'pstart': trial_balance.pstart.strftime('%Y-%m-%d'), 'account': account.name}|urlencode %} + {% if balance != 0 %} + + + + + + {% endif %} + {% endfor %} + + + + + +
    DrCr
    {{ account.name }}{% if balance > 0 %}{{ balance|b }}{% endif %}{% if balance < 0 %}{{ -balance|b }}{% endif %}
    {{ total_dr|b }}{{ total_cr|b }}
    +{% endblock %} diff --git a/ledger_pyreport/jinja2/trial_multiple.html b/ledger_pyreport/jinja2/trial_multiple.html index c290067..a572d69 100644 --- a/ledger_pyreport/jinja2/trial_multiple.html +++ b/ledger_pyreport/jinja2/trial_multiple.html @@ -16,32 +16,27 @@ along with this program. If not, see . #} - - - - - Trial Balance as at {{ trial_balances[0].date.strftime('%d %B %Y') }} - - - - -

    Trial Balance

    -

    As at {{ trial_balances[0].date.strftime('%d %B %Y') }}

    - - +{% extends 'base_report.html' %} + +{% block title %}Trial Balance as at {{ trial_balances[0].date.strftime('%d %B %Y') }}{% endblock %} + +{% block report %} +

    Trial Balance

    +

    As at {{ trial_balances[0].date.strftime('%d %B %Y') }}

    + +
    + + + {% for trial_balance in trial_balances %}{% endfor %} + + {% for account in accounts %} - - {% for trial_balance in trial_balances %}{% endfor %} + + {% for trial_balance in trial_balances %} + {% set balance = trial_balance.get_balance(account).exchange(report_currency, True) %} + + {% endfor %} - {% for account in accounts %} - - - {% for trial_balance in trial_balances %} - {% set balance = trial_balance.get_balance(account).exchange(report_currency, True) %} - - {% endfor %} - - {% endfor %} -
    {{ trial_balance.date.strftime('%Y') }} 
    {{ trial_balance.date.strftime('%Y') }} {{ account.name }}{% if balance != 0 %}{{ balance|a }}{% endif %}
    {{ account.name }}{% if balance != 0 %}{{ balance|a }}{% endif %}
    - - + {% endfor %} + +{% endblock %} diff --git a/ledger_pyreport/static/main.css b/ledger_pyreport/static/main.css index a18162b..d23e6d8 100644 --- a/ledger_pyreport/static/main.css +++ b/ledger_pyreport/static/main.css @@ -72,8 +72,21 @@ table.ledger a:hover { text-decoration: underline; } +a.homelink { + color: #888; + position: absolute; + top: 0; + left: 0; +} + @media screen { body { padding: 2em; } } + +@media print { + a.homelink { + display: none; + } +}