diff --git a/drcr/general_journal/models.py b/drcr/general_journal/models.py index d4a4826..c9c7be5 100644 --- a/drcr/general_journal/models.py +++ b/drcr/general_journal/models.py @@ -45,3 +45,17 @@ class GeneralJournalPosting(Base, Posting): def amount(self): return Amount(self.quantity, self.commodity) + +class BalanceAssertion(Base): + __tablename__ = 'balance_assertions' + + id = Column(Integer, primary_key=True) + + dt = Column(DateTime) + description = Column(String) + account = Column(String) + quantity = Column(Integer) + commodity = Column(String) + + def balance(self): + return Amount(self.quantity, self.commodity) diff --git a/drcr/general_journal/views.py b/drcr/general_journal/views.py index 4378376..3c3655a 100644 --- a/drcr/general_journal/views.py +++ b/drcr/general_journal/views.py @@ -14,11 +14,81 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from flask import render_template +from flask import abort, redirect, render_template, request -from ..webapp import app -from .models import GeneralJournalTransaction +from .. import AMOUNT_DPS +from ..database import db_session +from ..models import TrialBalancer +from ..webapp import all_transactions, app +from .models import BalanceAssertion, GeneralJournalTransaction + +from datetime import datetime @app.route('/general-journal') def general_journal(): - return render_template('general_journal.html', transactions=GeneralJournalTransaction.query.all()) + return render_template('general_journal/general_journal.html', transactions=GeneralJournalTransaction.query.all()) + +@app.route('/balance-assertions') +def balance_assertions(): + assertions = BalanceAssertion.query.all() + + # Check assertion status + transactions = all_transactions() + assertion_status = {} + for assertion in assertions: + # FIXME: This is very inefficient + balancer = TrialBalancer() + balancer.apply_transactions([t for t in transactions if t.dt <= assertion.dt]) + + # TODO: Commodities + if balancer.accounts[assertion.account].quantity == assertion.quantity: + assertion_status[assertion] = True + else: + assertion_status[assertion] = False + + return render_template('general_journal/balance_assertions.html', assertions=assertions, assertion_status=assertion_status) + +@app.route('/balance-assertions/new', methods=['GET', 'POST']) +def balance_assertions_new(): + if request.method == 'GET': + return render_template('general_journal/balance_assertions_edit.html', assertion=None) + + quantity = round(float(request.form['amount']) * (10**AMOUNT_DPS)) + if request.form['sign'] == 'cr': + quantity = -quantity + + # New balance assertion + assertion = BalanceAssertion( + dt=datetime.strptime(request.form['dt'], '%Y-%m-%d'), + description=request.form['description'], + account=request.form['account'], + quantity=quantity, + commodity='$' + ) + db_session.add(assertion) + db_session.commit() + + return redirect('/balance-assertions') + +@app.route('/balance-assertions/edit', methods=['GET', 'POST']) +def balance_assertions_edit(): + assertion = db_session.get(BalanceAssertion, request.args['id']) + if not assertion: + abort(404) + + if request.method == 'GET': + return render_template('general_journal/balance_assertions_edit.html', assertion=assertion) + + quantity = round(float(request.form['amount']) * (10**AMOUNT_DPS)) + if request.form['sign'] == 'cr': + quantity = -quantity + + # Edit balance assertion + assertion.dt = datetime.strptime(request.form['dt'], '%Y-%m-%d') + assertion.description = request.form['description'] + assertion.account = request.form['account'] + assertion.quantity = quantity + + db_session.commit() + + return redirect('/balance-assertions') diff --git a/drcr/templates/general_journal/balance_assertions.html b/drcr/templates/general_journal/balance_assertions.html new file mode 100644 index 0000000..63da64c --- /dev/null +++ b/drcr/templates/general_journal/balance_assertions.html @@ -0,0 +1,54 @@ +{# DrCr: Web-based double-entry bookkeeping framework + Copyright (C) 2022 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 title %}Balance assertions{% endblock %} + +{% block content %} +

Balance assertions

+ + + + + + + + + + + + + + + + + {% for assertion in assertions %} + + + + + + + + + + {% endfor %} + +
DateDescriptionAccountBalanceStatus
{{ assertion.dt.strftime('%Y-%m-%d') }}{{ assertion.description }}{{ assertion.account }}{{ (assertion.balance()|abs).format() }}{{ 'Dr' if assertion.quantity >= 0 else 'Cr' }}{% if assertion_status[assertion] %}{% else %}{% endif %}
+{% endblock %} diff --git a/drcr/templates/general_journal/balance_assertions_edit.html b/drcr/templates/general_journal/balance_assertions_edit.html new file mode 100644 index 0000000..f269309 --- /dev/null +++ b/drcr/templates/general_journal/balance_assertions_edit.html @@ -0,0 +1,61 @@ +{# DrCr: Web-based double-entry bookkeeping framework + Copyright (C) 2022 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 title %}{{ 'Edit' if assertion else 'New' }} balance assertion{% endblock %} + +{% block content %} +

{{ 'Edit' if assertion else 'New' }} balance assertion

+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+
$
+ + +
+
+
+ +
+ +
+
+{% endblock %} diff --git a/drcr/templates/general_journal.html b/drcr/templates/general_journal/general_journal.html similarity index 100% rename from drcr/templates/general_journal.html rename to drcr/templates/general_journal/general_journal.html diff --git a/drcr/templates/index.html b/drcr/templates/index.html index 477e1cd..b831fcc 100644 --- a/drcr/templates/index.html +++ b/drcr/templates/index.html @@ -23,6 +23,7 @@

General reports