Apply custom accounts combobox to other simple forms

This commit is contained in:
RunasSudo 2024-04-06 01:42:34 +11:00
parent 3083117730
commit af2818b6ae
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
8 changed files with 69 additions and 34 deletions

View File

@ -33,8 +33,9 @@
<input type="date" class="bordered-field" name="acquisition_date" id="acquisition_date" value="{{ adjustment.acquisition_date.strftime('%Y-%m-%d') if adjustment else request.args.get('acquisition_date', '') }}"> <input type="date" class="bordered-field" name="acquisition_date" id="acquisition_date" value="{{ adjustment.acquisition_date.strftime('%Y-%m-%d') if adjustment else request.args.get('acquisition_date', '') }}">
</div> </div>
<label for="account" class="block text-gray-900 pr-4">Account</label> <label for="account" class="block text-gray-900 pr-4">Account</label>
<div> <div class="relative combobox">
<input type="text" class="bordered-field" name="account" id="account" value="{{ adjustment.account if adjustment else request.args.get('account', '') }}"> <input type="text" class="bordered-field peer" name="account" id="account" value="{{ adjustment.account if adjustment else request.args.get('account', '') }}" autocomplete="off">
{% include 'components/accounts_combobox_inner.html' %}
</div> </div>
<label for="asset" class="block text-gray-900 pr-4">Asset</label> <label for="asset" class="block text-gray-900 pr-4">Asset</label>
<div> <div>
@ -66,3 +67,7 @@
</form> </form>
</div> </div>
{% endblock %} {% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/combobox.js') }}"></script>
{% endblock %}

View File

@ -29,8 +29,9 @@
<h2 class="col-span-2 text-xl text-gray-900 font-semibold">CGT assets</h2> <h2 class="col-span-2 text-xl text-gray-900 font-semibold">CGT assets</h2>
<label for="account" class="block text-gray-900 pr-4">Account</label> <label for="account" class="block text-gray-900 pr-4">Account</label>
<div> <div class="relative combobox">
<input type="text" class="bordered-field" name="account" id="account" value="{{ account or '' }}"> <input type="text" class="bordered-field peer" name="account" id="account" value="{{ account or '' }}" autocomplete="off">
{% include 'components/accounts_combobox_inner.html' %}
</div> </div>
<label for="commodity" class="block text-gray-900 pr-4">Commodity</label> <label for="commodity" class="block text-gray-900 pr-4">Commodity</label>
<div> <div>
@ -75,3 +76,7 @@
</form> </form>
</div> </div>
{% endblock %} {% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/combobox.js') }}"></script>
{% endblock %}

View File

@ -19,7 +19,7 @@ from flask import redirect, render_template, request, url_for
from drcr.models import AccountConfiguration, Amount, Posting, Transaction from drcr.models import AccountConfiguration, Amount, Posting, Transaction
from drcr.database import db from drcr.database import db
from drcr.plugins import render_plugin_template from drcr.plugins import render_plugin_template
from drcr.webapp import app, eofy_date from drcr.webapp import all_accounts, app, eofy_date
from .models import CGTAsset, CGTCostAdjustment from .models import CGTAsset, CGTCostAdjustment
from .reports import tax_summary_report from .reports import tax_summary_report
@ -45,7 +45,7 @@ def cgt_adjustments():
@app.route('/tax/cgt-adjustments/new', methods=['GET', 'POST']) @app.route('/tax/cgt-adjustments/new', methods=['GET', 'POST'])
def cgt_adjustment_new(): def cgt_adjustment_new():
if request.method == 'GET': if request.method == 'GET':
return render_plugin_template('austax', 'cgt_adjustments_edit.html', adjustment=None) return render_plugin_template('austax', 'cgt_adjustments_edit.html', adjustment=None, all_accounts=all_accounts())
asset = Amount.parse(request.form['asset']) asset = Amount.parse(request.form['asset'])
adjustment = CGTCostAdjustment( adjustment = CGTCostAdjustment(
@ -65,7 +65,7 @@ def cgt_adjustment_new():
@app.route('/tax/cgt-adjustments/edit', methods=['GET', 'POST']) @app.route('/tax/cgt-adjustments/edit', methods=['GET', 'POST'])
def cgt_adjustment_edit(): def cgt_adjustment_edit():
if request.method == 'GET': if request.method == 'GET':
return render_plugin_template('austax', 'cgt_adjustments_edit.html', adjustment=db.session.get(CGTCostAdjustment, request.args['id'])) return render_plugin_template('austax', 'cgt_adjustments_edit.html', adjustment=db.session.get(CGTCostAdjustment, request.args['id']), all_accounts=all_accounts())
asset = Amount.parse(request.form['asset']) asset = Amount.parse(request.form['asset'])
adjustment = db.session.get(CGTCostAdjustment, request.args['id']) adjustment = db.session.get(CGTCostAdjustment, request.args['id'])
@ -91,7 +91,8 @@ def cgt_adjustment_multinew():
commodity=None, commodity=None,
dt=None, dt=None,
description=None, description=None,
cost_adjustment=None cost_adjustment=None,
all_accounts=all_accounts()
) )
# TODO: Preview mode? # TODO: Preview mode?

View File

@ -146,7 +146,7 @@ def balance_assertions():
@app.route('/balance-assertions/new', methods=['GET', 'POST']) @app.route('/balance-assertions/new', methods=['GET', 'POST'])
def balance_assertions_new(): def balance_assertions_new():
if request.method == 'GET': if request.method == 'GET':
return render_template('journal/balance_assertions_edit.html', assertion=None, accounts=all_accounts()) return render_template('journal/balance_assertions_edit.html', assertion=None, all_accounts=all_accounts())
quantity = round(float(request.form['amount']) * (10**AMOUNT_DPS)) quantity = round(float(request.form['amount']) * (10**AMOUNT_DPS))
if request.form['sign'] == 'cr': if request.form['sign'] == 'cr':
@ -172,7 +172,7 @@ def balance_assertions_edit():
abort(404) abort(404)
if request.method == 'GET': if request.method == 'GET':
return render_template('journal/balance_assertions_edit.html', assertion=assertion, accounts=all_accounts()) return render_template('journal/balance_assertions_edit.html', assertion=assertion, all_accounts=all_accounts())
if request.form.get('action', None) == 'delete': if request.form.get('action', None) == 'delete':
# Delete balance assertion # Delete balance assertion

View File

@ -19,7 +19,7 @@ from flask import abort, redirect, render_template, request, url_for
from .. import AMOUNT_DPS from .. import AMOUNT_DPS
from ..database import db from ..database import db
from ..models import Amount, Posting, Transaction from ..models import Amount, Posting, Transaction
from ..webapp import app from ..webapp import all_accounts, app
from .models import StatementLine, StatementLineReconciliation from .models import StatementLine, StatementLineReconciliation
from datetime import datetime from datetime import datetime
@ -39,7 +39,7 @@ def statement_lines():
page = db.paginate(statement_lines, per_page=int(request.args.get('per_page', 1000))) page = db.paginate(statement_lines, per_page=int(request.args.get('per_page', 1000)))
return render_template('statements/statement_lines.html', page=page) return render_template('statements/statement_lines.html', page=page, all_accounts=all_accounts())
@app.route('/statement-lines/charge', methods=['POST']) @app.route('/statement-lines/charge', methods=['POST'])
def statement_line_charge(): def statement_line_charge():
@ -172,7 +172,7 @@ def statement_line_reconcile_transfer():
@app.route('/statement-lines/import', methods=['GET', 'POST']) @app.route('/statement-lines/import', methods=['GET', 'POST'])
def statement_lines_import(): def statement_lines_import():
if request.method == 'GET': if request.method == 'GET':
return render_template('statements/import.html') return render_template('statements/import.html', all_accounts=all_accounts())
# Import using importer # Import using importer
if request.form['format'] == 'ofx1': if request.form['format'] == 'ofx1':

View File

@ -0,0 +1,34 @@
{# DrCr: Web-based double-entry bookkeeping framework
Copyright (C) 2022–2024 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/>.
#}
<button type="button" class="absolute inset-y-0 right-0 flex items-center px-2 focus:outline-none">
<svg class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 3a.75.75 0 01.55.24l3.25 3.5a.75.75 0 11-1.1 1.02L10 4.852 7.3 7.76a.75.75 0 01-1.1-1.02l3.25-3.5A.75.75 0 0110 3zm-3.76 9.2a.75.75 0 011.06.04l2.7 2.908 2.7-2.908a.75.75 0 111.1 1.02l-3.25 3.5a.75.75 0 01-1.1 0l-3.25-3.5a.75.75 0 01.04-1.06z" clip-rule="evenodd" />
</svg>
</button>
<ul class="hidden peer-focus:block absolute z-10 mt-1 max-h-60 w-full overflow-auto bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{% for account in all_accounts %}
<li class="group relative cursor-default select-none py-1 pl-3 pr-9 text-gray-900 hover:text-white hover:bg-indigo-600">
<span class="combobox-text block truncate group-data-[selected=selected]:font-semibold">{{ account }}</span>
<span class="hidden group-data-[selected=selected]:flex absolute inset-y-0 right-0 items-center pr-4 text-indigo-600 group-hover:text-white">
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" />
</svg>
</span>
</li>
{% endfor %}
</ul>

View File

@ -37,23 +37,7 @@
<label for="account" class="block text-gray-900 pr-4">Account</label> <label for="account" class="block text-gray-900 pr-4">Account</label>
<div class="relative combobox"> <div class="relative combobox">
<input type="text" class="bordered-field peer" name="account" id="account" value="{{ assertion.account if assertion else '' }}" autocomplete="off"> <input type="text" class="bordered-field peer" name="account" id="account" value="{{ assertion.account if assertion else '' }}" autocomplete="off">
<button type="button" class="absolute inset-y-0 right-0 flex items-center px-2 focus:outline-none"> {% include 'components/accounts_combobox_inner.html' %}
<svg class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 3a.75.75 0 01.55.24l3.25 3.5a.75.75 0 11-1.1 1.02L10 4.852 7.3 7.76a.75.75 0 01-1.1-1.02l3.25-3.5A.75.75 0 0110 3zm-3.76 9.2a.75.75 0 011.06.04l2.7 2.908 2.7-2.908a.75.75 0 111.1 1.02l-3.25 3.5a.75.75 0 01-1.1 0l-3.25-3.5a.75.75 0 01.04-1.06z" clip-rule="evenodd" />
</svg>
</button>
<ul class="hidden peer-focus:block absolute z-10 mt-1 max-h-60 w-full overflow-auto bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{% for account in accounts %}
<li class="group relative cursor-default select-none py-1 pl-3 pr-9 text-gray-900 hover:text-white hover:bg-indigo-600">
<span class="combobox-text block truncate group-data-[selected=selected]:font-semibold">{{ account }}</span>
<span class="hidden group-data-[selected=selected]:flex absolute inset-y-0 right-0 items-center pr-4 text-indigo-600 group-hover:text-white">
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" />
</svg>
</span>
</li>
{% endfor %}
</ul>
</div> </div>
<label for="amount" class="block text-gray-900 pr-4">Balance</label> <label for="amount" class="block text-gray-900 pr-4">Balance</label>
<div class="relative shadow-sm"> <div class="relative shadow-sm">

View File

@ -28,8 +28,9 @@
<form method="POST" enctype="multipart/form-data"> <form method="POST" enctype="multipart/form-data">
<input type="hidden" name="format" value="ofx1"> <input type="hidden" name="format" value="ofx1">
<div class="flex"> <div class="flex">
<div class="grow mr-2"> <div class="grow mr-2 relative combobox">
<input type="text" class="bordered-field" name="source-account" placeholder="Source account"> <input type="text" class="bordered-field peer" name="source-account" placeholder="Source account" autocomplete="off">
{% include 'components/accounts_combobox_inner.html' %}
</div> </div>
<div class="flex"> <div class="flex">
</div> </div>
@ -51,8 +52,9 @@
<form method="POST" enctype="multipart/form-data"> <form method="POST" enctype="multipart/form-data">
<input type="hidden" name="format" value="ofx2"> <input type="hidden" name="format" value="ofx2">
<div class="flex"> <div class="flex">
<div class="grow mr-2"> <div class="grow mr-2 relative combobox">
<input type="text" class="bordered-field" name="source-account" placeholder="Source account"> <input type="text" class="bordered-field peer" name="source-account" placeholder="Source account" autocomplete="off">
{% include 'components/accounts_combobox_inner.html' %}
</div> </div>
<div class="flex"> <div class="flex">
</div> </div>
@ -69,3 +71,7 @@
</div> </div>
</form> </form>
{% endblock %} {% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/combobox.js') }}"></script>
{% endblock %}