add admin summary view, fix product id calculation

master
informatic 2024-03-07 18:51:59 +01:00
parent ef71d8732a
commit e4d7404a45
No known key found for this signature in database
7 changed files with 56 additions and 12 deletions

View File

@ -10,11 +10,13 @@ from flask import (
url_for, url_for,
session, session,
abort, abort,
current_app,
) )
from flask_login import current_user, fresh_login_required from flask_login import current_user, fresh_login_required
from bitvend import dev, spaceauth from bitvend import dev, spaceauth
from bitvend.models import db, Transaction from bitvend.models import db, Transaction
from sqlalchemy import func
from bitvend.forms import ManualForm from bitvend.forms import ManualForm
from spaceauth import cap_required from spaceauth import cap_required
@ -25,7 +27,8 @@ def get_user_groups():
groups_ts = session.get("groups_ts", 0) groups_ts = session.get("groups_ts", 0)
if not groups or groups_uid != current_user.uid or time.time() - groups_ts >= 60.0: if not groups or groups_uid != current_user.uid or time.time() - groups_ts >= 60.0:
groups = spaceauth.remote.get("/api/1/userinfo").data.get("groups") resp = spaceauth.remote.get("/api/1/userinfo")
groups = resp.data.get("groups")
session["groups"] = groups session["groups"] = groups
session["groups_ts"] = time.time() session["groups_ts"] = time.time()
@ -39,6 +42,9 @@ def admin_required(fn):
@wraps(fn) @wraps(fn)
def wrapped(*args, **kwargs): def wrapped(*args, **kwargs):
groups = get_user_groups() groups = get_user_groups()
if not groups:
return current_app.login_manager.unauthorized()
if "vending-admin" not in groups: if "vending-admin" not in groups:
abort(403) abort(403)
@ -50,7 +56,14 @@ def admin_required(fn):
bp = Blueprint("admin", __name__) bp = Blueprint("admin", __name__)
@bp.route("/manual", methods=["GET", "POST"]) @bp.route("/")
@fresh_login_required
@admin_required
def admin_index():
return redirect(url_for("admin.manual"))
@bp.route("/manual/", methods=["GET", "POST"])
@fresh_login_required @fresh_login_required
@admin_required @admin_required
def manual(): def manual():
@ -60,7 +73,13 @@ def manual():
db.session.commit() db.session.commit()
flash("Operation successful.", "success") flash("Operation successful.", "success")
return render_template("admin/manual.html", form=form) return render_template(
"admin/manual.html",
form=form,
summary=db.session.query(func.sum(Transaction.amount))
.filter(Transaction.uid != "__bitcoin__")
.scalar(),
)
@bp.route("/transactions/", defaults={"page": 1}) @bp.route("/transactions/", defaults={"page": 1})

View File

@ -31,7 +31,7 @@ class BitvendCashlessMDBDevice(CashlessMDBDevice):
if self.current_tx_id: if self.current_tx_id:
with self.app.app_context(): with self.app.app_context():
tx = Transaction.query.get(self.current_tx_id) tx = Transaction.query.get(self.current_tx_id)
tx.product_id = product tx.product_id = product + 9
tx.product_value = value tx.product_value = value
if tx.amount is None: if tx.amount is None:

View File

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block body %}
<div class="row">
<div class="col-md-2">
<div class="list-group">
{% macro link(endpoint) %}<a href="{{ url_for(endpoint) }}" class="list-group-item{% if request.endpoint == endpoint %} active{%endif %}">{{ caller() }}</a>{% endmacro %}
{% call link('admin.manual') %}Dashboard{% endcall %}
{% call link('admin.transactions') %}Transactions{% endcall %}
</div>
</div>
<div class="col-md-10">{% block content %}{% endblock %}</div>
</div>
{% endblock %}

View File

@ -1,9 +1,17 @@
{% extends "base.html" %} {% extends "admin/base.html" %}
{% from "_helpers.html" import render_field, render_submit %} {% from "_helpers.html" import render_field, render_submit, format_currency %}
{% block content %} {% block content %}
<h1 class="page-header">Manual transaction </h1> <div class="row">
<div class="col-md-6">
<div class="well text-right">
<h3><small class="pull-left">Cash summary</small> {{ format_currency(summary) }}</h3>
</div>
</div>
</div>
<h1 class="page-header">Manual transaction</h1>
<p class="text-muted">Creates manual transaction for current user. Use this when filling machine with money.</p> <p class="text-muted">Creates manual transaction for current user. Use this when filling machine with money.</p>
<div class="row"> <div class="row">
<form action="{{ url_for('.manual') }}" method="POST" class="form-horizontal col-md-6 col-md-offset-3"> <form action="{{ url_for('.manual') }}" method="POST" class="form-horizontal col-md-6 col-md-offset-3">

View File

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "admin/base.html" %}
{% from "_helpers.html" import format_currency, render_pagination %} {% from "_helpers.html" import format_currency, render_pagination %}
{% set _tx_styles = { {% set _tx_styles = {

View File

@ -85,7 +85,10 @@
{% endfor %} {% endfor %}
{% endwith %} {% endwith %}
{% block content %}{% endblock %} {% block body %}
{% block content %}
{% endblock %}
{% endblock %}
<hr> <hr>
<footer class="row"><big>made by <a href="https://wiki.hackerspace.pl/people:informatic:start">inf</a></big> <footer class="row"><big>made by <a href="https://wiki.hackerspace.pl/people:informatic:start">inf</a></big>
<span class="pull-right text-right">1infuHrvt7tuGY8nJcfTwB3wwAR1XwUcW &bull; <a href="https://code.hackerspace.pl/informatic/bitvend">sauce</a><br />report any issues to <a href="mailto:informatic@hackerspace.pl">informatic@hackerspace.pl</a></span> <span class="pull-right text-right">1infuHrvt7tuGY8nJcfTwB3wwAR1XwUcW &bull; <a href="https://code.hackerspace.pl/informatic/bitvend">sauce</a><br />report any issues to <a href="mailto:informatic@hackerspace.pl">informatic@hackerspace.pl</a></span>

View File

@ -220,10 +220,9 @@ class CashlessMDBDevice(MDBDevice):
elif req.command == CASHLESS_VEND: elif req.command == CASHLESS_VEND:
if req.data[0] == 0x00: # vend request if req.data[0] == 0x00: # vend request
self.logger.info("VEND: request %r", req) self.logger.info("VEND: request %r", req)
value, product_bcd = struct.unpack(">xhhx", req.data) value, product = struct.unpack(">xhhx", req.data)
product = bcd_decode(product_bcd)
self.logger.info( self.logger.info(
"VEND: requested %d (%04x) for %d", product, product_bcd, value "VEND: requested %d (%04x) for %d", product, product, value
) )
if self.vend_request(product, value): if self.vend_request(product, value):
# accept. two latter bytes are value subtracted from balance # accept. two latter bytes are value subtracted from balance