From 47be3f39aef6d65c7ff5618d0837434bbf6ee994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szenes=20M=C3=A1rton=20Mikl=C3=B3s?= <szenesmarton@sch.bme.hu> Date: Thu, 8 May 2025 23:38:16 +0200 Subject: [PATCH] first try (html added, endpoint added) --- app/app.py | 27 ++++++++++- app/config.py | 8 ++++ app/routes.py | 85 ++++++++++++++++++++++++++++++++++- app/static/imgs/transfer.png | Bin 0 -> 17096 bytes app/templates/base.html | 1 + app/templates/transfer.html | 65 +++++++++++++++++++++++++++ 6 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 app/static/imgs/transfer.png create mode 100644 app/templates/transfer.html diff --git a/app/app.py b/app/app.py index 0149226..c5433c2 100644 --- a/app/app.py +++ b/app/app.py @@ -134,6 +134,18 @@ with app.app_context(): # Kontextus beállítása db.session.add(topup_icon) db.session.commit() print('[INFO] Topup icon created') + # = Utalás ikon hozzáadása az adatbázishoz = + if not Icon.query.get(TRANSFER_ICON_ID): + transfer_icon = Icon( + id = TRANSFER_ICON_ID, + name = TRANSFER_NAME, + url = TRANSFER_ICON_URL, + data=open(DEFAULT_STATIC_FOLDER + TRANSFER_ICON_URL, "rb").read() + ) + # Adatbázisba írás + db.session.add(transfer_icon) + db.session.commit() + print('[INFO] Transfer icon created') # = Feltöltés termék hozzáadása az adatbázishoz = if not Item.query.get(TOPUP_ITEM_ID): topup_item = Item( @@ -160,4 +172,17 @@ with app.app_context(): # Kontextus beállítása # Adatbázisba írás db.session.add(buy_item) db.session.commit() - print('[INFO] Buy item created') \ No newline at end of file + print('[INFO] Buy item created') + # = Utalás termék hozzáadása az adatbázishoz = + if not Item.query.get(TRANSFER_ITEM_ID): + transfer_item = Item( + id=TRANSFER_ITEM_ID, + name=TRANSFER_NAME, + price=1, + icon_id=TRANSFER_ICON_ID, + stock=INACTIVE_ITEM_STOCK + ) + # Adatbázisba írás + db.session.add(transfer_item) + db.session.commit() + print('[INFO] Transfer item created') \ No newline at end of file diff --git a/app/config.py b/app/config.py index 03b71d1..1573e5e 100644 --- a/app/config.py +++ b/app/config.py @@ -53,6 +53,14 @@ BUY_ITEM_ID = -1 BUY_ICON_ID = DEFAULT_ICON_ID BUY_NAME = 'Vásárlás' +# Az utalás ikonja és itemje, ami a tranzakcióhoz tartozik +TRANSFER_ITEM_ID = -2 +TRANSFER_ICON_ID = -2 +TRANSFER_ICON_URL = 'imgs/transfer.png' +TRANSFER_NAME = 'Utalás' +TRANSFER_UNIT = '' + + # Termékek elérhetőségének kategorizálása a 'Item.stock' property által SOLD_OUT_ITEM_STOCK = 0 INFINITELY_AVALIBLE_ITEM_STOCK = -1 diff --git a/app/routes.py b/app/routes.py index ab3459d..902d484 100644 --- a/app/routes.py +++ b/app/routes.py @@ -95,7 +95,8 @@ def history(uuid): return redirect(url_for('routes.history')) - spendings = selected_user.received_transactions + #sent_trans = selected_user.sent_transactions + spendings = selected_user.received_transactions # + sent_trans.filter(Transaction.item_id == TRANSFER_ITEM_ID).all() searched_spendings = [s for s in spendings if search_field in s.item.name.lower()] @@ -499,6 +500,88 @@ def transactions_export(): response = Response(output.getvalue(), content_type="text/csv; charset=utf-8") response.headers["Content-Disposition"] = "attachment; filename=transactions.csv" return response + +@routing.route('/transfer', methods=['GET', 'POST']) +@token_required() +def transfer(): + """ + Egyenleg utalás oldal és POST feldolgozás + --- + tags: + - Oldalak + summary: Egyenleg utalás másik felhasználónak. + description: A felhasználó ezen az oldalon utalhat egyenleget egy másik felhasználónak. + responses: + 200: + description: Az oldal sikeresen megjelenik vagy az utalás sikeres. + content: + text/html: + schema: + type: string + application/json: + schema: + type: object + properties: + success: + type: boolean + message: + type: string + 400: + description: Hibás kérés vagy érvénytelen adatok. + """ + current_user = get_current_user() + if request.method == 'GET': + # Listázzuk az összes felhasználót, kivéve saját magát és a BOT-ot + users = User.query.filter(User.uuid != current_user.uuid, User.uuid != BOT_USER_UUID).all() + return render_template( + "transfer.html", + current_user=current_user, + release_version=RELEASE_VERSION, + users=users + ) + elif request.method == 'POST': + data = request.get_json() + recipient_uuid = data.get('recipient') + amount = data.get('amount') + note = data.get('note', '') + + if not recipient_uuid or not amount: + return {"success": False, "message": "Hiányzó adat!"}, 400 + + if recipient_uuid == current_user.uuid: + return {"success": False, "message": "Saját magadnak nem utalhatsz!"}, 400 + + try: + amount = int(amount) + except Exception: + return {"success": False, "message": "Az összegnek számnak kell lennie!"}, 400 + + if amount < 1: + return {"success": False, "message": "Az összegnek pozitívnak kell lennie!"}, 400 + + recipient = User.query.get(recipient_uuid) + if not recipient: + return {"success": False, "message": "A címzett nem található!"}, 400 + + if current_user.balance < amount: + return {"success": False, "message": "Nincs elég egyenleged az utaláshoz!"}, 400 + + # Tranzakció létrehozása + transaction = Transaction( + by_user_uuid=current_user.uuid, + to_user_uuid=recipient.uuid, + item_id=TRANSFER_ICON_ID, + amount=amount, + quantity=1, + # date=datetime.now() + # note=note + ) + current_user.balance -= amount + recipient.balance += amount + db.session.add(transaction) + db.session.commit() + return {"success": True, "message": f"Sikeres utalás {recipient.name} részére!"}, 200 + # Hiba oldal @routing.route('/error') def error(): diff --git a/app/static/imgs/transfer.png b/app/static/imgs/transfer.png new file mode 100644 index 0000000000000000000000000000000000000000..e4a80a712864d429c01a1eb0a47052ef096bc77e GIT binary patch literal 17096 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 GLK6TwyG4Ki literal 0 HcmV?d00001 diff --git a/app/templates/base.html b/app/templates/base.html index ee9df97..3d88342 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -61,6 +61,7 @@ {% if current_user.is_authenticated %} <li class="nav-item"><a class="nav-link {% if request.path == '/' %}active{% endif %}" href="/"><i class="bi bi-bag me-1"></i>Vásárlás</a></li> <li class="nav-item"><a class="nav-link {% if '/history' in request.path %}active{% endif %}" href="/history/{{current_user.uuid}}"><i class="bi bi-journal-text me-1"></i>Költések</a></li> + <li class="nav-item"><a class="nav-link {% if '/transfer' in request.path %}active{% endif %}" href="/transfer"><i class="bi bi-arrow-left-right me-1"></i>Utalás</a></li> {% if current_user.role >= 1 %} <li class="nav-item"><a class="nav-link {% if '/bar' in request.path %}active{% endif %}" href="/bar"><i class="bi bi-cup-straw me-1"></i>Pult</a></li> {% endif %} {% if current_user.role == 2 %} diff --git a/app/templates/transfer.html b/app/templates/transfer.html new file mode 100644 index 0000000..fd84e0c --- /dev/null +++ b/app/templates/transfer.html @@ -0,0 +1,65 @@ +{% extends 'base.html' %} +{% block title %}BecskasszaSCH | Egyenleg utalás{% endblock %} + +{% block content %} +<div class="card shadow"> + <div class="card-body"> + <h1 class="mb-4"><i class="bi bi-arrow-left-right me-2"></i>Egyenleg utalás</h1> + <form id="transferForm" onsubmit="transferBalance(event)"> + <div class="mb-3"> + <label for="recipient" class="form-label">Címzett felhasználó</label> + <select class="form-select" id="recipient" name="recipient" required> + <option value="" disabled selected>Válassz felhasználót</option> + {% for user in users %} + {% if user.uuid != current_user.uuid %} + <option value="{{ user.uuid }}">{{ user.name }} ({{ user.balance }} JMF)</option> + {% endif %} + {% endfor %} + </select> + </div> + <div class="mb-3"> + <label for="amount" class="form-label">Utalni kívánt összeg (JMF)</label> + <input type="number" class="form-control" id="amount" name="amount" min="1" placeholder="Add meg az összeget" required> + </div> + <div class="mb-3"> + <label for="note" class="form-label">Megjegyzés (opcionális)</label> + <input type="text" class="form-control" id="note" name="note" maxlength="100" placeholder="Pl.: Szülinap, visszajáró, stb."> + </div> + <div class="d-flex gap-2"> + <button type="submit" class="btn btn-success"><i class="bi bi-send me-1"></i>Utalás</button> + <a href="/" class="btn btn-secondary">Mégsem</a> + </div> + </form> + </div> +</div> + +<script> +function transferBalance(event) { + event.preventDefault(); + const recipient = document.getElementById('recipient').value; + const amount = parseInt(document.getElementById('amount').value); + const note = document.getElementById('note').value; + + if (!recipient || !amount || amount < 1) { + showToast('Hiba', 'Adj meg minden szükséges adatot!', 'danger'); + return; + } + + fetch('/transfer', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ recipient, amount, note }) + }) + .then(res => res.json()) + .then(data => { + if (data.success) { + showToast('Siker', data.message, 'success'); + setTimeout(() => { window.location.href = '/history/{{ current_user.uuid }}'; }, 1500); + } else { + showToast('Hiba', data.message, 'danger'); + } + }) + .catch(() => showToast('Hiba', 'Ismeretlen hiba történt!', 'danger')); +} +</script> +{% endblock %} \ No newline at end of file -- GitLab