Allow reconciling complex statement line

This commit is contained in:
RunasSudo 2023-01-27 22:19:08 +11:00
parent f1594b2392
commit 9378cf441f
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
2 changed files with 62 additions and 2 deletions

View File

@ -18,10 +18,12 @@ 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 Posting, Transaction from ..models import Amount, Posting, Transaction
from ..webapp import app from ..webapp import app
from .models import StatementLine, StatementLineReconciliation from .models import StatementLine, StatementLineReconciliation
from datetime import datetime
@app.route('/statement-lines') @app.route('/statement-lines')
def statement_lines(): def statement_lines():
# JOIN all associated postings (called in is_complex/charge_account) # JOIN all associated postings (called in is_complex/charge_account)
@ -66,6 +68,64 @@ def statement_line_charge():
return 'OK' return 'OK'
@app.route('/statement-lines/charge-complex', methods=['GET', 'POST'])
def statement_line_charge_complex():
statement_line = db.session.get(StatementLine, request.args['line-id'])
if not statement_line:
abort(404)
if statement_line.reconciliation:
raise Exception('Cannot reconcile an already reconciled statement line')
if request.method == 'GET':
# Create template transaction
posting_source = Posting(account=statement_line.source_account, quantity=statement_line.quantity, commodity=statement_line.commodity)
posting_charge = Posting(account='', quantity=-statement_line.quantity, commodity=statement_line.commodity)
transaction = Transaction(
dt=statement_line.dt,
description=statement_line.description,
postings=[posting_source, posting_charge]
)
return render_template('journal/journal_edit_transaction.html', transaction=transaction)
# New transaction
transaction = Transaction(
dt=datetime.strptime(request.form['dt'], '%Y-%m-%d'),
description=request.form['description'],
postings=[]
)
for account, sign, amount_str in zip(request.form.getlist('account'), request.form.getlist('sign'), request.form.getlist('amount')):
amount = Amount.parse(amount_str)
if sign == 'cr':
amount = -amount
posting = Posting(
account=account,
quantity=amount.quantity,
commodity=amount.commodity
)
transaction.postings.append(posting)
transaction.assert_valid()
db.session.add(transaction)
# Reconcile statement line
posting_source = next((p for p in transaction.postings if p.account == statement_line.source_account and p.quantity == statement_line.quantity and p.commodity == statement_line.commodity), None)
if not posting_source:
raise Exception('Transaction must have posting corresponding to statement line')
reconciliation = StatementLineReconciliation(
statement_line=statement_line,
posting=posting_source
)
db.session.add(reconciliation)
db.session.commit()
return redirect(url_for('statement_lines'))
@app.route('/statement-lines/reconcile-transfer', methods=['POST']) @app.route('/statement-lines/reconcile-transfer', methods=['POST'])
def statement_line_reconcile_transfer(): def statement_line_reconcile_transfer():
line_ids = request.form.getlist('sel-line-id') line_ids = request.form.getlist('sel-line-id')

View File

@ -65,7 +65,7 @@
<td class="charge-account"> <td class="charge-account">
{% if not line.reconciliation %} {% if not line.reconciliation %}
<a href="#" class="text-danger" onclick="classifyLine({{ line.id }});return false;">Unclassified</a> <a href="#" class="text-danger" onclick="classifyLine({{ line.id }});return false;">Unclassified</a>
{# TODO #} <a href="{{ url_for('statement_line_charge_complex') }}?line-id={{ line.id }}" class="text-muted"><i class="bi bi-pencil"></i></a>
{% elif line.is_complex() %} {% elif line.is_complex() %}
<i>(Complex)</i> <i>(Complex)</i>
<a href="{{ url_for('journal_edit_transaction', id=line.reconciliation.posting.transaction.id) }}" class="text-muted"><i class="bi bi-pencil"></i></a> <a href="{{ url_for('journal_edit_transaction', id=line.reconciliation.posting.transaction.id) }}" class="text-muted"><i class="bi bi-pencil"></i></a>