diff --git a/drcr/models.py b/drcr/models.py index 6761c11..deabf2b 100644 --- a/drcr/models.py +++ b/drcr/models.py @@ -185,3 +185,12 @@ class TrialBalancer: # FIXME: Handle commodities self.accounts[destination_account].quantity += self.accounts[source_account].quantity del self.accounts[source_account] + +class AccountConfiguration(db.Model): + __tablename__ = 'account_configurations' + + id = db.Column(db.Integer, primary_key=True) + + account = db.Column(db.String) + kind = db.Column(db.String) + data = db.Column(db.JSON) diff --git a/drcr/templates/chart_of_accounts.html b/drcr/templates/chart_of_accounts.html new file mode 100644 index 0000000..7cd67ec --- /dev/null +++ b/drcr/templates/chart_of_accounts.html @@ -0,0 +1,67 @@ +{# DrCr: Web-based double-entry bookkeeping framework + Copyright (C) 2022–2023 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 %}Chart of accounts{% endblock %} + +{% block content %} +

Chart of accounts

+ +
+
+
+ +
+
+ +
+
+ + + + + + + + + + + {% for account in accounts %} + + + + + + {% endfor %} + +
AccountAssociated types
{{ account }} + {% if account in account_configurations %} +
    + {% for account_configuration in account_configurations[account] %} +
  • {{ account_configuration.kind }}
  • + {% endfor %} +
+ {% endif %} +
+
+{% endblock %} diff --git a/drcr/templates/index.html b/drcr/templates/index.html index 4073922..374583a 100644 --- a/drcr/templates/index.html +++ b/drcr/templates/index.html @@ -24,6 +24,7 @@
  • Journal
  • Statement lines
  • Balance assertions
  • +
  • Chart of accounts
  • General reports

    diff --git a/drcr/views.py b/drcr/views.py index a885c8b..d9fb282 100644 --- a/drcr/views.py +++ b/drcr/views.py @@ -1,5 +1,5 @@ # DrCr: Web-based double-entry bookkeeping framework -# Copyright (C) 2022 Lee Yingtong Li (RunasSudo) +# Copyright (C) 2022–2023 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 @@ -14,15 +14,39 @@ # 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, request +from flask import redirect, render_template, request -from .models import Amount, Balance, TrialBalancer +from .database import db +from .models import AccountConfiguration, Amount, Balance, Posting, TrialBalancer from .webapp import all_transactions, app +from itertools import groupby + @app.route('/') def index(): return render_template('index.html') +@app.route('/chart-of-accounts') +def chart_of_accounts(): + accounts = sorted(db.session.execute(db.select(Posting.account)).unique().scalars().all()) + + # Get existing AccountConfiguration's + account_configurations = db.session.execute(db.select(AccountConfiguration).order_by(AccountConfiguration.account)).scalars() + account_configurations = {v: list(g) for v, g in groupby(account_configurations, lambda c: c.account)} + + # TODO: Handle orphans + return render_template('chart_of_accounts.html', accounts=accounts, account_configurations=account_configurations) + +@app.route('/chart-of-accounts/add-kind', methods=['POST']) +def account_add_kind(): + for account in request.form.getlist('sel-account'): + account_configuration = AccountConfiguration(account=account, kind=request.form['kind']) + db.session.add(account_configuration) + + db.session.commit() + + return redirect('/chart-of-accounts') + @app.route('/general-ledger') def general_ledger(): return render_template(