Adds the option for a user to see their 10 most recent transactions. #1

Open
jonny wants to merge 1 commit from jonny/matemat:transaction-list into main
5 changed files with 118 additions and 0 deletions

View file

@ -724,6 +724,40 @@ class MatematDatabase(object):
receipt = Receipt(receipt_id, transactions, user, created, datetime.utcnow())
return receipt
def get_transactions(self, user: User) -> List[Transaction]:
transactions: List[Transaction] = []
with self.db.transaction() as cursor:
cursor.execute('''
SELECT
t.ta_id, t.value, t.old_balance, COALESCE(t.date, 0),
c.ta_id, d.ta_id, m.ta_id, c.product, m.agent, m.reason
FROM transactions AS t
LEFT JOIN consumptions AS c
ON t.ta_id = c.ta_id
LEFT JOIN deposits AS d
ON t.ta_id = d.ta_id
LEFT JOIN modifications AS m
ON t.ta_id = m.ta_id
WHERE t.user_id = :user_id
ORDER BY t.date DESC
LIMIT 10
''', {
'user_id': user.id
})
rows = cursor.fetchall()
for row in rows:
ta_id, value, old_balance, date, c, d, m, c_prod, m_agent, m_reason = row
if c == ta_id:
t: Transaction = Consumption(ta_id, user, value, old_balance, datetime.fromtimestamp(date), c_prod)
elif d == ta_id:
t = Deposit(ta_id, user, value, old_balance, datetime.fromtimestamp(date))
elif m == ta_id:
t = Modification(ta_id, user, value, old_balance, datetime.fromtimestamp(date), m_agent, m_reason)
else:
t = Transaction(ta_id, user, value, old_balance, datetime.fromtimestamp(date))
transactions.append(t)
return transactions
def generate_sales_statistics(self, from_date: datetime, to_date: datetime) -> Dict[str, Any]:
consumptions: Dict[str, Tuple[int, int]] = dict()
total_income: int = 0

View file

@ -18,3 +18,4 @@ from .moduser import moduser
from .modproduct import modproduct
from .userbootstrap import userbootstrap
from .statistics import statistics
from .transactions import transactions_page

View file

@ -0,0 +1,39 @@
from datetime import datetime
from bottle import route, redirect, request
from matemat.db import MatematDatabase
from matemat.webserver import template, session
from matemat.webserver.config import get_app_config, get_stock_provider
@route('/transactions')
def transactions_page():
"""
The transaction history page, showing a list of recent transactions.
"""
config = get_app_config()
session_id: str = session.start()
now = str(int(datetime.utcnow().timestamp()))
with MatematDatabase(config['DatabaseFile']) as db:
# Check whether a user is logged in
if session.has(session_id, 'authenticated_user'):
# Fetch the user id and authentication level (touchkey vs password) from the session storage
uid: int = session.get(session_id, 'authenticated_user')
authlevel: int = session.get(session_id, 'authentication_level')
# Fetch the user object from the database (for name display, price calculation and admin check)
user = db.get_user(uid)
transactions = db.get_transactions(user)
# Prepare a response with a jinja2 template
return template.render('transactions.html',
authuser=user, authlevel=authlevel,
setupname=config['InstanceName'], transactions=transactions)
else:
# If there are no admin users registered, jump to the admin creation procedure
if not db.has_admin_users():
redirect('/userbootstrap')
# If no user is logged in, fetch the list of users and render the userlist template
users = db.list_users(with_touchkey=True)
return template.render('userlist.html',
users=users, setupname=config['InstanceName'], now=now,
signup=(config.get('SignupEnabled', '0') == '1'))

View file

@ -33,6 +33,11 @@
{% endif %}
{% endif %}
{% endif %}
{% if authlevel|default(0) > 0 %}
{% if authuser is defined %}
<a href="/transactions">Transactions</a>
{% endif %}
{% endif %}
</nav>
{% endblock %}
</header>

View file

@ -0,0 +1,39 @@
{% extends "base.html" %}
{% block header %}
{# Show the setup name, as set in the config file, as page title. Don't escape HTML entities. #}
<h1>{{ setupname|safe }}</h1>
{{ super() }}
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
</style>
{% endblock %}
{% block main %}
<div class="transactions-table">
List of 10 most recent transactions.
<table>
<tr>
<th>Date</th>
<th>Description</th>
<th>Value</th>
<th>Message</th>
</tr>
{% for t in transactions %}
<tr>
<td>{{ t.receipt_date }}</td>
<td>{{ t.receipt_description }}</td>
<td>{{ t.receipt_value }}</td>
<td>{{ t.receipt_message }}</td>
</tr>
{% endfor %}
</table>
</div>
{{ super() }}
{% endblock %}