Compare commits

...

3 Commits

4 changed files with 41 additions and 20 deletions

View File

@ -49,13 +49,16 @@ def plugin_init():
drcr.plugins.transaction_providers.append(make_tax_transactions) drcr.plugins.transaction_providers.append(make_tax_transactions)
@assert_aud @assert_aud
def make_tax_transactions(): def make_tax_transactions(start_date=None, end_date=None):
report = tax_summary_report()
tax_amount = report.by_id('total_tax').amount
# Get EOFY date # Get EOFY date
dt = eofy_date() dt = eofy_date()
if (start_date is not None and start_date > dt) or (end_date is not None and end_date < dt):
return []
report = tax_summary_report()
tax_amount = report.by_id('total_tax').amount - report.by_id('offsets').amount
# Estimated tax payable # Estimated tax payable
transactions = [Transaction( transactions = [Transaction(
dt=dt, dt=dt,

View File

@ -241,12 +241,13 @@ class TrialBalancer:
# First SELECT the last applicable dt by account # First SELECT the last applicable dt by account
# Then, among the transactions with that dt, SELECT the last applicable transaction_id # Then, among the transactions with that dt, SELECT the last applicable transaction_id
# Then extract the running_balance for each account at that transaction_id # Then extract the running_balance for each account at that transaction_id
# NB: We need to specify DATE(...) otherwise SQLite appears to do a string comparison which doesn't work properly with SQLAlchemy's prepared statement?
running_balances = db.session.execute(''' running_balances = db.session.execute('''
SELECT p3.account, running_balance FROM SELECT p3.account, running_balance FROM
( (
SELECT p1.account, max(p2.transaction_id) AS max_tid FROM SELECT p1.account, max(p2.transaction_id) AS max_tid FROM
( (
SELECT account, max(dt) AS max_dt FROM postings JOIN transactions ON postings.transaction_id = transactions.id WHERE dt < :start_date GROUP BY account SELECT account, max(dt) AS max_dt FROM postings JOIN transactions ON postings.transaction_id = transactions.id WHERE DATE(dt) < DATE(:start_date) GROUP BY account
) p1 ) p1
JOIN postings p2 ON p1.account = p2.account AND p1.max_dt = transactions.dt JOIN transactions ON p2.transaction_id = transactions.id GROUP BY p2.account JOIN postings p2 ON p1.account = p2.account AND p1.max_dt = transactions.dt JOIN transactions ON p2.transaction_id = transactions.id GROUP BY p2.account
) p3 ) p3
@ -282,7 +283,7 @@ class TrialBalancer:
( (
SELECT p1.account, max(p2.transaction_id) AS max_tid FROM SELECT p1.account, max(p2.transaction_id) AS max_tid FROM
( (
SELECT account, max(dt) AS max_dt FROM postings JOIN transactions ON postings.transaction_id = transactions.id WHERE dt <= :end_date GROUP BY account SELECT account, max(dt) AS max_dt FROM postings JOIN transactions ON postings.transaction_id = transactions.id WHERE DATE(dt) <= DATE(:end_date) GROUP BY account
) p1 ) p1
JOIN postings p2 ON p1.account = p2.account AND p1.max_dt = transactions.dt JOIN transactions ON p2.transaction_id = transactions.id GROUP BY p2.account JOIN postings p2 ON p1.account = p2.account AND p1.max_dt = transactions.dt JOIN transactions ON p2.transaction_id = transactions.id GROUP BY p2.account
) p3 ) p3

View File

@ -22,6 +22,7 @@ from .plugins import account_kinds, advanced_reports, data_sources
from .reports import balance_sheet_report, income_statement_report from .reports import balance_sheet_report, income_statement_report
from .webapp import all_transactions, api_transactions, app from .webapp import all_transactions, api_transactions, app
from datetime import datetime
from itertools import groupby from itertools import groupby
@app.route('/') @app.route('/')
@ -69,8 +70,10 @@ def general_ledger():
@app.route('/trial-balance') @app.route('/trial-balance')
def trial_balance(): def trial_balance():
balancer = TrialBalancer.from_cached() dt = datetime.strptime(request.args['date'], '%Y-%m-%d') if 'date' in request.args else None
balancer.apply_transactions(api_transactions())
balancer = TrialBalancer.from_cached(end_date=dt)
balancer.apply_transactions(api_transactions(end_date=dt))
total_dr = Amount(sum(v.quantity for v in balancer.accounts.values() if v.quantity > 0), reporting_commodity()) total_dr = Amount(sum(v.quantity for v in balancer.accounts.values() if v.quantity > 0), reporting_commodity())
total_cr = Amount(sum(v.quantity for v in balancer.accounts.values() if v.quantity < 0), reporting_commodity()) total_cr = Amount(sum(v.quantity for v in balancer.accounts.values() if v.quantity < 0), reporting_commodity())
@ -126,5 +129,13 @@ def balance_sheet():
@app.route('/income-statement') @app.route('/income-statement')
def income_statement(): def income_statement():
report = income_statement_report() if 'end_date' in request.args:
start_date = datetime.strptime(request.args['start_date'], '%Y-%m-%d') if 'start_date' in request.args else datetime.min
end_date = datetime.strptime(request.args['end_date'], '%Y-%m-%d')
print(end_date)
else:
start_date, end_date = None, None
report = income_statement_report(start_date=start_date, end_date=end_date)
return render_template('report.html', report=report) return render_template('report.html', report=report)

View File

@ -32,23 +32,29 @@ import time
app.config['SQLALCHEMY_RECORD_QUERIES'] = app.debug app.config['SQLALCHEMY_RECORD_QUERIES'] = app.debug
db.init_app(app) db.init_app(app)
def limit_query_dt(query, field, start_date=None, end_date=None):
"""Helper function to limit the query between the start and end dates"""
if start_date and end_date:
return query.where((field >= start_date) & (field <= end_date))
if start_date:
return query.where(field >= start_date)
if end_date:
return query.where(field <= end_date)
return query
def all_transactions(start_date=None, end_date=None, join_postings=True): def all_transactions(start_date=None, end_date=None, join_postings=True):
"""Return all transactions, including from DB and API""" """Return all transactions, including from DB and API"""
# All Transactions in database between start_date and end_date # All Transactions in database between start_date and end_date
query = db.select(Transaction) query = db.select(Transaction)
if start_date and end_date: query = limit_query_dt(query, Transaction.dt, start_date, end_date)
query = query.where((Transaction.dt >= start_date) & (Transaction.dt <= end_date))
elif start_date:
query = query.where(Transaction.dt >= start_date)
elif end_date:
query = query.where(Transaction.dt <= end_date)
if join_postings: if join_postings:
query = query.options(db.selectinload(Transaction.postings)) query = query.options(db.selectinload(Transaction.postings))
transactions = db.session.scalars(query).all() transactions = db.session.scalars(query).all()
transactions.extend(api_transactions(start_date, end_date)) transactions.extend(api_transactions(start_date=start_date, end_date=end_date))
return transactions return transactions
@ -58,13 +64,13 @@ def api_transactions(start_date=None, end_date=None):
transactions = [] transactions = []
# Unreconciled StatementLines # Unreconciled StatementLines
# FIXME: Filter by start_date and end_date query = db.select(StatementLine).where(StatementLine.reconciliation == None)
transactions.extend(line.into_transaction() for line in StatementLine.query.filter(StatementLine.reconciliation == None)) query = limit_query_dt(query, StatementLine.dt, start_date, end_date)
transactions.extend(line.into_transaction() for line in db.session.scalars(query).all())
# Plugins # Plugins
# FIXME: Filter by start_date and end_date
for transaction_provider in transaction_providers: for transaction_provider in transaction_providers:
transactions.extend(transaction_provider()) transactions.extend(transaction_provider(start_date=start_date, end_date=end_date))
return transactions return transactions