diff --git a/matemat/db/facade.py b/matemat/db/facade.py index 522dfd4..7fca74c 100644 --- a/matemat/db/facade.py +++ b/matemat/db/facade.py @@ -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 diff --git a/matemat/webserver/pagelets/__init__.py b/matemat/webserver/pagelets/__init__.py index b17da36..ab36e99 100644 --- a/matemat/webserver/pagelets/__init__.py +++ b/matemat/webserver/pagelets/__init__.py @@ -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 diff --git a/matemat/webserver/pagelets/transactions.py b/matemat/webserver/pagelets/transactions.py new file mode 100644 index 0000000..a7e1c26 --- /dev/null +++ b/matemat/webserver/pagelets/transactions.py @@ -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')) diff --git a/templates/base.html b/templates/base.html index dce01a1..b766db2 100644 --- a/templates/base.html +++ b/templates/base.html @@ -33,6 +33,11 @@ {% endif %} {% endif %} {% endif %} + {% if authlevel|default(0) > 0 %} + {% if authuser is defined %} + Transactions + {% endif %} + {% endif %} {% endblock %} diff --git a/templates/transactions.html b/templates/transactions.html new file mode 100644 index 0000000..a561bea --- /dev/null +++ b/templates/transactions.html @@ -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. #} +

{{ setupname|safe }}

+ {{ super() }} + +{% endblock %} + +{% block main %} + +
+ List of 10 most recent transactions. + + + + + + + + {% for t in transactions %} + + + + + + + {% endfor %} +
DateDescriptionValueMessage
{{ t.receipt_date }}{{ t.receipt_description }}{{ t.receipt_value }}{{ t.receipt_message }}
+
+ + {{ super() }} + +{% endblock %}