From 77d23cb7b4962ed4d010cec71bf9cfb468e77c33 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Sat, 24 Dec 2022 16:16:47 +1100 Subject: [PATCH] Allow reconciling two statement lines together as a transfer between accounts --- drcr/statements/models.py | 9 ++- drcr/statements/views.py | 44 ++++++++--- .../templates/statements/statement_lines.html | 76 ++++++++++--------- 3 files changed, 82 insertions(+), 47 deletions(-) diff --git a/drcr/statements/models.py b/drcr/statements/models.py index 780021d..1d6b61d 100644 --- a/drcr/statements/models.py +++ b/drcr/statements/models.py @@ -17,7 +17,7 @@ from sqlalchemy import Column, DateTime, ForeignKey, Integer, String from sqlalchemy.orm import relationship -from ..database import Base +from ..database import Base, db_session from ..models import Amount, Posting, Transaction class StatementLine(Base): @@ -63,6 +63,13 @@ class StatementLine(Base): return True return False + + def delete_postings(self): + """Delete existing StatementLineTransactions with postings for this StatementLine""" + + for posting in self.postings: + # TODO: Will be wonky if transaction covers multiple StatementLines + db_session.delete(posting.transaction) class StatementLineTransaction(Base, Transaction): __tablename__ = 'statement_line_transactions' diff --git a/drcr/statements/views.py b/drcr/statements/views.py index 5688d86..50d1d91 100644 --- a/drcr/statements/views.py +++ b/drcr/statements/views.py @@ -37,14 +37,7 @@ def statement_line_charge(): abort(404) # Delete existing postings - if len(statement_line.postings) > 0: - for posting in statement_line.postings: - if len(posting.transaction.postings) > 2: - # Complex posting - raise Exception('Cannot automatically delete a StatementLineTransaction with >2 postings') - - # Queue for deletion - db_session.delete(posting.transaction) + statement_line.delete_postings() transaction = StatementLineTransaction( dt=statement_line.dt, @@ -78,10 +71,7 @@ def statement_line_edit_transaction(): return render_template('statements/statement_line_edit_transaction.html', statement_line=statement_line, transaction=statement_line.postings[0].transaction) # Delete existing postings - if len(statement_line.postings) > 0: - for posting in statement_line.postings: - # Queue for deletion - db_session.delete(posting.transaction) + statement_line.delete_postings() if len(request.form.getlist('charge-account')) == 1: # Simple transaction @@ -113,3 +103,33 @@ def statement_line_edit_transaction(): db_session.commit() return redirect('/statement-lines') + +@app.route('/statement-lines/reconcile-transfer', methods=['POST']) +def statement_line_reconcile_transfer(): + line_ids = request.form.getlist('sel-line-id') + if len(line_ids) != 2: + raise Exception('Must select exactly 2 statement lines') + + line1 = db_session.get(StatementLine, line_ids[0]) + line2 = db_session.get(StatementLine, line_ids[1]) + + # Check same amount + if line1.quantity != -line2.quantity or line1.commodity != line2.commodity: + raise Exception('Selected statement line debits/credits must equal') + + # Delete existing postings + line1.delete_postings() + line2.delete_postings() + + transaction = StatementLineTransaction( + dt=line1.dt, + description=line1.description, + postings=[ + StatementLinePosting(statement_line=line1, description=line1.description, account=line1.source_account, quantity=line1.quantity, commodity=line1.commodity), + StatementLinePosting(statement_line=line2, description=line2.description, account=line2.source_account, quantity=line2.quantity, commodity=line2.commodity) + ] + ) + db_session.add(transaction) + db_session.commit() + + return redirect('/statement-lines') diff --git a/drcr/templates/statements/statement_lines.html b/drcr/templates/statements/statement_lines.html index f4711d2..b997a0b 100644 --- a/drcr/templates/statements/statement_lines.html +++ b/drcr/templates/statements/statement_lines.html @@ -22,41 +22,49 @@

Statement lines

- - - - - - - - - - - - - - {% for line in statement_lines %} - - - - - - - - + +
+ +
+ +
Source accountDateDescriptionCharged toDrCrBalance
{{ line.source_account }}{{ line.dt.strftime('%Y-%m-%d') }}{{ line.description }}{{ line.amount().format() if line.quantity >= 0 else '' }}{{ (line.amount()|abs).format() if line.quantity < 0 else '' }}{{ line.balance or '' }}
+ + + + + + + + + + - {% endfor %} - -
Source accountDateDescriptionCharged toDrCrBalance
+ + + {% for line in statement_lines %} + + + {{ line.source_account }} + {{ line.dt.strftime('%Y-%m-%d') }} + {{ line.description }} + + {% if line.postings|length == 0 %} + Unclassified + {% elif line.is_complex() %} + (Complex) + {% else %} + {{ line.postings[0].transaction.charge_account(line.source_account) }} + {% endif %} + + + {{ line.amount().format() if line.quantity >= 0 else '' }} + {{ (line.amount()|abs).format() if line.quantity < 0 else '' }} + {{ line.balance or '' }} + + {% endfor %} + + +