Implement editing general journal transactions

This commit is contained in:
RunasSudo 2022-12-24 20:41:33 +11:00
parent a474fc89d7
commit 371e7f39c4
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
5 changed files with 120 additions and 46 deletions

View File

@ -28,7 +28,7 @@ class GeneralJournalTransaction(Base, Transaction):
dt = Column(DateTime) dt = Column(DateTime)
description = Column(String) description = Column(String)
postings = relationship('GeneralJournalPosting', back_populates='transaction', cascade='all, delete') postings = relationship('GeneralJournalPosting', back_populates='transaction', cascade='all, delete-orphan')
class GeneralJournalPosting(Base, Posting): class GeneralJournalPosting(Base, Posting):
__tablename__ = 'general_journal_postings' __tablename__ = 'general_journal_postings'

View File

@ -59,6 +59,38 @@ def general_journal_new():
return redirect('/general-journal') return redirect('/general-journal')
@app.route('/general-journal/edit', methods=['GET', 'POST'])
def general_journal_edit():
transaction = db_session.get(GeneralJournalTransaction, request.args['id'])
if not transaction:
abort(404)
if request.method == 'GET':
return render_template('general_journal/general_journal_edit.html', transaction=transaction)
# Edit transaction
transaction.dt = datetime.strptime(request.form['dt'], '%Y-%m-%d')
transaction.description = request.form['description']
transaction.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 = GeneralJournalPosting(
account=account,
quantity=amount.quantity,
commodity=amount.commodity
)
transaction.postings.append(posting)
transaction.assert_valid()
db_session.commit()
return redirect('/general-journal')
@app.route('/balance-assertions') @app.route('/balance-assertions')
def balance_assertions(): def balance_assertions():
assertions = BalanceAssertion.query.all() assertions = BalanceAssertion.query.all()

View File

@ -81,7 +81,12 @@ class Amount:
return '{1:,.{dps}f} {0}'.format(self.commodity, self.quantity / (10**AMOUNT_DPS), dps=AMOUNT_DPS) return '{1:,.{dps}f} {0}'.format(self.commodity, self.quantity / (10**AMOUNT_DPS), dps=AMOUNT_DPS)
def quantity_string(self): def quantity_string(self):
return '{:.{dps}f}'.format(self.quantity / (10**AMOUNT_DPS), dps=AMOUNT_DPS) if self.commodity == '$':
return '{:.{dps}f}'.format(self.quantity / (10**AMOUNT_DPS), dps=AMOUNT_DPS)
elif len(self.commodity) == 1:
return '{0}{1:.{dps}f}'.format(self.commodity, self.quantity / (10**AMOUNT_DPS), dps=AMOUNT_DPS)
else:
return '{1:.{dps}f} {0}'.format(self.commodity, self.quantity / (10**AMOUNT_DPS), dps=AMOUNT_DPS)
def as_cost(self): def as_cost(self):
"""Convert commodity to reporting currency in cost basis""" """Convert commodity to reporting currency in cost basis"""

View File

@ -38,7 +38,7 @@
{% for transaction in transactions %} {% for transaction in transactions %}
<tr> <tr>
<td>{{ transaction.dt.strftime('%Y-%m-%d') }}</td> <td>{{ transaction.dt.strftime('%Y-%m-%d') }}</td>
<td colspan="2">{{ transaction.description }}</td> <td colspan="2">{{ transaction.description }} <a href="/general-journal/edit?id={{ transaction.id }}"><i class="bi bi-pencil text-muted"></i></a></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>

View File

@ -33,52 +33,89 @@
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><input type="date" name="dt" class="form-control"></td> <td><input type="date" name="dt" class="form-control" value="{{ transaction.dt.strftime('%Y-%m-%d') if transaction else '' }}"></td>
<td colspan="2"><input type="text" name="description" value="" class="form-control"></td> <td colspan="2"><input type="text" name="description" value="{{ transaction.description if transaction else '' }}" class="form-control"></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> {% if transaction %}
<td></td> {% for posting in transaction.postings %}
<td></td> <tr>
<td> <td></td>
<div class="input-group"> <td></td>
<select class="form-select" name="sign" style="flex-grow:0;min-width:5em" onchange="changeDrCr(this)"> <td>
<option value="dr" selected>Dr</option> <div class="input-group">
<option value="cr">Cr</option> <select class="form-select" name="sign" style="flex-grow:0;min-width:5em" onchange="changeDrCr(this)">
</select> <option value="dr"{% if posting.quantity >= 0 %} selected{% endif %}>Dr</option>
<input type="text" name="account" class="form-control"> <option value="cr"{% if posting.quantity < 0 %} selected{% endif %}>Cr</option>
<a class="btn btn-outline-primary" href="#" onclick="addPosting(this);return false;"><i class="bi bi-plus-circle-fill"></i></a> </select>
</div> <input type="text" name="account" class="form-control" value="{{ posting.account }}">
</td> <a class="btn btn-outline-primary" href="#" onclick="addPosting(this);return false;"><i class="bi bi-plus-circle-fill"></i></a>
<td class="amount-dr has-amount"> </div>
<div class="input-group"> </td>
<div class="input-group-text">$</div> {% if posting.quantity >= 0 %}
<input type="text" name="amount" value="" class="form-control"> <td class="amount-dr has-amount">
</div> <div class="input-group">
<td class="amount-cr"></td> <div class="input-group-text">$</div>
</tr> <input type="text" name="amount" value="{{ posting.amount().quantity_string() }}" class="form-control">
<tr> </div>
<td></td> </td>
<td></td> <td class="amount-cr"></td>
<td> {% else %}
<div class="input-group"> <td class="amount-cr"></td>
<select class="form-select" name="sign" style="flex-grow:0;min-width:5em" onchange="changeDrCr(this)"> <td class="amount-cr has-amount">
<option value="dr">Dr</option> <div class="input-group">
<option value="cr" selected>Cr</option> <div class="input-group-text">$</div>
</select> <input type="text" name="amount" value="{{ (posting.amount()|abs).quantity_string() }}" class="form-control">
<input type="text" name="account" class="form-control"> </div>
<a class="btn btn-outline-primary" href="#" onclick="addPosting(this);return false;"><i class="bi bi-plus-circle-fill"></i></a> </td>
</div> {% endif %}
</td> </tr>
<td class="amount-dr"></td> {% endfor %}
<td class="amount-cr has-amount"> {% else %}
<div class="input-group"> <tr>
<div class="input-group-text">$</div> <td></td>
<input type="text" name="amount" value="" class="form-control"> <td></td>
</div> <td>
</td> <div class="input-group">
</tr> <select class="form-select" name="sign" style="flex-grow:0;min-width:5em" onchange="changeDrCr(this)">
<option value="dr" selected>Dr</option>
<option value="cr">Cr</option>
</select>
<input type="text" name="account" class="form-control">
<a class="btn btn-outline-primary" href="#" onclick="addPosting(this);return false;"><i class="bi bi-plus-circle-fill"></i></a>
</div>
</td>
<td class="amount-dr has-amount">
<div class="input-group">
<div class="input-group-text">$</div>
<input type="text" name="amount" value="" class="form-control">
</div>
</td>
<td class="amount-cr"></td>
</tr>
<tr>
<td></td>
<td></td>
<td>
<div class="input-group">
<select class="form-select" name="sign" style="flex-grow:0;min-width:5em" onchange="changeDrCr(this)">
<option value="dr">Dr</option>
<option value="cr" selected>Cr</option>
</select>
<input type="text" name="account" class="form-control">
<a class="btn btn-outline-primary" href="#" onclick="addPosting(this);return false;"><i class="bi bi-plus-circle-fill"></i></a>
</div>
</td>
<td class="amount-dr"></td>
<td class="amount-cr has-amount">
<div class="input-group">
<div class="input-group-text">$</div>
<input type="text" name="amount" value="" class="form-control">
</div>
</td>
</tr>
{% endif %}
</tbody> </tbody>
</table> </table>