Add basic plugin API
This commit is contained in:
parent
3f496abeb9
commit
ebb70896a2
28
drcr/plugins.py
Normal file
28
drcr/plugins.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .config import PLUGINS
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
|
||||||
|
advanced_reports = [] # list of tuplet (url, label)
|
||||||
|
account_kinds = [] # list of tuplet (id, label)
|
||||||
|
transaction_providers = [] # list of callable
|
||||||
|
|
||||||
|
def init_plugins():
|
||||||
|
for plugin in PLUGINS:
|
||||||
|
module = importlib.import_module(plugin)
|
||||||
|
module.plugin_init()
|
@ -30,6 +30,9 @@
|
|||||||
<option value="drcr.income">Income</option>
|
<option value="drcr.income">Income</option>
|
||||||
<option value="drcr.expense">Expense</option>
|
<option value="drcr.expense">Expense</option>
|
||||||
<option value="drcr.equity">Equity</option>
|
<option value="drcr.equity">Equity</option>
|
||||||
|
{% for account_kind in account_kinds %}
|
||||||
|
<option value="{{ account_kind[0] }}">{{ account_kind[1] }}</option>
|
||||||
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
<h1 class="h2 my-4">Advanced reports</h1>
|
<h1 class="h2 my-4">Advanced reports</h1>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/tax/summary">Tax summary</a></li>
|
{% for report in advanced_reports %}
|
||||||
|
<li><a href="{{ report[0] }}">{{ report[1] }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -18,12 +18,13 @@ from flask import redirect, render_template, request
|
|||||||
|
|
||||||
from .database import db
|
from .database import db
|
||||||
from .models import AccountConfiguration, Amount, Balance, Posting, TrialBalancer
|
from .models import AccountConfiguration, Amount, Balance, Posting, TrialBalancer
|
||||||
|
from .plugins import account_kinds, advanced_reports
|
||||||
from .reports import balance_sheet_report, income_statement_report
|
from .reports import balance_sheet_report, income_statement_report
|
||||||
from .webapp import all_transactions, app
|
from .webapp import all_transactions, app
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
return render_template('index.html')
|
return render_template('index.html', advanced_reports=advanced_reports)
|
||||||
|
|
||||||
@app.route('/chart-of-accounts')
|
@app.route('/chart-of-accounts')
|
||||||
def chart_of_accounts():
|
def chart_of_accounts():
|
||||||
@ -34,7 +35,7 @@ def chart_of_accounts():
|
|||||||
account_configurations = AccountConfiguration.get_all()
|
account_configurations = AccountConfiguration.get_all()
|
||||||
|
|
||||||
# TODO: Handle orphans
|
# TODO: Handle orphans
|
||||||
return render_template('chart_of_accounts.html', accounts=accounts, account_configurations=account_configurations)
|
return render_template('chart_of_accounts.html', accounts=accounts, account_configurations=account_configurations, account_kinds=account_kinds)
|
||||||
|
|
||||||
@app.route('/chart-of-accounts/add-kind', methods=['POST'])
|
@app.route('/chart-of-accounts/add-kind', methods=['POST'])
|
||||||
def account_add_kind():
|
def account_add_kind():
|
||||||
|
@ -19,6 +19,7 @@ from flask_sqlalchemy.record_queries import get_recorded_queries
|
|||||||
|
|
||||||
from .database import db
|
from .database import db
|
||||||
from .models import Transaction
|
from .models import Transaction
|
||||||
|
from .plugins import init_plugins, transaction_providers
|
||||||
from .statements.models import StatementLine
|
from .statements.models import StatementLine
|
||||||
from .tax import aus_tax
|
from .tax import aus_tax
|
||||||
|
|
||||||
@ -31,15 +32,23 @@ app.config['SQLALCHEMY_RECORD_QUERIES'] = app.debug
|
|||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
|
|
||||||
def all_transactions():
|
def all_transactions():
|
||||||
return (
|
# All Transactions in database
|
||||||
Transaction.query.all() +
|
transactions = db.session.scalars(db.select(Transaction)).all()
|
||||||
[line.into_transaction() for line in StatementLine.query.filter(StatementLine.reconciliation == None)] +
|
|
||||||
[aus_tax.tax_transaction(aus_tax.taxable_income())]
|
# Unreconciled StatementLines
|
||||||
)
|
transactions.extend(line.into_transaction() for line in StatementLine.query.filter(StatementLine.reconciliation == None))
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
for transaction_provider in transaction_providers:
|
||||||
|
transactions.extend(transaction_provider())
|
||||||
|
|
||||||
|
return transactions
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
from .journal import views
|
from .journal import views
|
||||||
from .statements import views
|
from .statements import views
|
||||||
|
|
||||||
|
init_plugins()
|
||||||
from .tax import views
|
from .tax import views
|
||||||
|
|
||||||
@app.cli.command('initdb')
|
@app.cli.command('initdb')
|
||||||
|
Loading…
Reference in New Issue
Block a user