This repository has been archived on 2024-11-09. You can view files and clone it, but cannot push or open issues or pull requests.
ledger-pyreport/ledger_pyreport/__init__.py

154 lines
6.0 KiB
Python
Raw Normal View History

2020-01-14 00:06:14 +11:00
# 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 <https://www.gnu.org/licenses/>.
from . import accounting
2020-01-14 00:06:14 +11:00
from . import ledger
from datetime import datetime, timedelta
from decimal import Decimal
2020-01-14 00:06:14 +11:00
import flask
app = flask.Flask(__name__, template_folder='jinja2')
@app.route('/')
def index():
date = datetime.now()
pstart = ledger.financial_year(date)
return flask.render_template('index.html', date=date, pstart=pstart)
@app.route('/trial')
def trial():
date = datetime.strptime(flask.request.args['date'], '%Y-%m-%d')
pstart = datetime.strptime(flask.request.args['pstart'], '%Y-%m-%d')
compare = int(flask.request.args['compare'])
#cash = flask.request.args.get('cash', False)
2020-01-14 00:06:14 +11:00
if compare == 0:
# Get trial balance
trial_balance = ledger.trial_balance(date, pstart)
total_dr = Decimal(0)
total_cr = Decimal(0)
for account in trial_balance.accounts.values():
balance = trial_balance.get_balance(account.name)
if balance > 0:
total_dr += balance
else:
total_cr -= balance
2020-02-15 15:50:33 +11:00
return flask.render_template('trial.html', trial_balance=trial_balance, total_dr=total_dr, total_cr=total_cr)
else:
# Get multiple trial balances for comparison
dates = [date.replace(year=date.year - i) for i in range(0, compare + 1)]
pstarts = [pstart.replace(year=pstart.year - i) for i in range(0, compare + 1)]
trial_balances = [ledger.trial_balance(d, p) for d, p in zip(dates, pstarts)]
# Delete accounts with always zero balances
accounts = list(trial_balances[0].accounts.values())
for account in accounts[:]:
if all(t.get_balance(account.name) == 0 for t in trial_balances):
accounts.remove(account)
2020-02-15 15:50:33 +11:00
return flask.render_template('trial_multiple.html', trial_balances=trial_balances, accounts=accounts)
2020-01-14 00:06:14 +11:00
@app.route('/balance')
def balance():
date = datetime.strptime(flask.request.args['date'], '%Y-%m-%d')
pstart = datetime.strptime(flask.request.args['pstart'], '%Y-%m-%d')
compare = int(flask.request.args['compare'])
#cash = flask.request.args.get('cash', False)
2020-01-14 00:06:14 +11:00
dates = [date.replace(year=date.year - i) for i in range(0, compare + 1)]
pstarts = [pstart.replace(year=pstart.year - i) for i in range(0, compare + 1)]
2020-01-14 00:06:14 +11:00
balance_sheets = [accounting.balance_sheet(d, p) for d, p in zip(dates, pstarts)]
2020-01-14 00:06:14 +11:00
# Delete accounts with always zero balances
accounts = list(balance_sheets[0].accounts.values())
for account in accounts[:]:
if all(b.get_balance(account.name) == 0 and b.get_total(account.name) == 0 for b in balance_sheets):
accounts.remove(account)
2020-01-14 00:06:14 +11:00
2020-02-15 15:50:33 +11:00
return flask.render_template('balance.html', balance_sheets=balance_sheets, accounts=accounts, config=ledger.config)
2020-01-14 00:06:14 +11:00
@app.route('/pandl')
def pandl():
date_beg = datetime.strptime(flask.request.args['date_beg'], '%Y-%m-%d')
date_end = datetime.strptime(flask.request.args['date_end'], '%Y-%m-%d')
compare = int(flask.request.args['compare'])
#cash = flask.request.args.get('cash', False)
dates_beg = [date_beg.replace(year=date_beg.year - i) for i in range(0, compare + 1)]
dates_end = [date_end.replace(year=date_end.year - i) for i in range(0, compare + 1)]
pandls = [ledger.trial_balance(de, db) for de, db in zip(dates_end, dates_beg)]
2020-01-14 00:06:14 +11:00
# Delete accounts with always zero balances
accounts = list(pandls[0].accounts.values())
for account in accounts[:]:
if all(p.get_balance(account.name) == 0 and p.get_total(account.name) == 0 for p in pandls):
accounts.remove(account)
2020-01-14 00:06:14 +11:00
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'))
2020-01-14 00:06:14 +11:00
2020-02-15 15:50:33 +11:00
return flask.render_template('pandl.html', period=period, pandls=pandls, accounts=accounts, config=ledger.config)
@app.route('/transactions')
def transactions():
date = datetime.strptime(flask.request.args['date'], '%Y-%m-%d')
pstart = datetime.strptime(flask.request.args['pstart'], '%Y-%m-%d')
trial_balance_pstart = ledger.trial_balance(pstart, pstart)
account = trial_balance_pstart.get_account(flask.request.args['account'])
opening_balance = trial_balance_pstart.get_balance(account.name)
balance = opening_balance
transactions = account.get_transactions(date, pstart)
for transaction in transactions:
for posting in transaction.postings[:]:
if posting.account == account.name:
transaction.postings.remove(posting)
else:
posting.amount = -posting.amount # In terms of effect on this account
balance += posting.amount
posting.balance = balance
trial_balance = ledger.trial_balance(date, pstart)
closing_balance = trial_balance.get_balance(account.name)
return flask.render_template('transactions.html', date=date, pstart=pstart, account=account, transactions=transactions, opening_balance=opening_balance, closing_balance=closing_balance)
2020-01-14 00:06:14 +11:00
@app.template_filter('a')
def filter_amount(amt):
if amt < 0.005 and amt >= -0.005:
return flask.Markup('0.00&nbsp;')
elif amt > 0:
2020-01-31 10:13:20 +11:00
return flask.Markup('{:,.2f}&nbsp;'.format(amt).replace(',', '&#8239;')) # Narrow no-break space
2020-01-14 00:06:14 +11:00
else:
2020-01-31 10:13:20 +11:00
return flask.Markup('({:,.2f})'.format(-amt).replace(',', '&#8239;'))
2020-01-14 00:06:14 +11:00
@app.template_filter('b')
def filter_amount_positive(amt):
2020-01-31 10:13:20 +11:00
return flask.Markup('{:,.2f}'.format(amt).replace(',', '&#8239;'))