From ac8a5348dd304c8e3c8388c3a60cd42f9d7d5396 Mon Sep 17 00:00:00 2001 From: Shiro-Nek0 Date: Fri, 20 Mar 2026 00:21:02 -0300 Subject: [PATCH] pervenir boton de volver si se cerro sesion, colores, navbar, calculo tarjeta + mp --- README.md | 2 - app.py | 54 ++++++++++++++------- static/style.css | 30 ++++++++---- static/themeStuff.js | 6 +-- templates/admin_workers.html | 4 +- templates/index.html | 10 ++++ templates/macros/navbar.html | 21 ++++---- templates/worker_dashboard.html | 85 +++++++++++++++++++++++++++------ 8 files changed, 153 insertions(+), 59 deletions(-) create mode 100644 templates/index.html diff --git a/README.md b/README.md index 54fdc66..935db9e 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,6 @@ services: # TODO peppermint: ## formulario -- añadir total ventas (todos los medios de pago) -- total tarjetas + mp - cantidad de boletas por metodod de pago - añadir segunda persona a cargo - verificar que todos los campos esten rellenos diff --git a/app.py b/app.py index 8eaecd6..27f788b 100644 --- a/app.py +++ b/app.py @@ -140,6 +140,13 @@ def admin_required(f): return f(*args, **kwargs) return decorated_function +@app.after_request +def add_header(response): + response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" + response.headers["Pragma"] = "no-cache" + response.headers["Expires"] = "0" + return response + # --- Routes --- @app.route('/', methods=['GET', 'POST']) @@ -187,7 +194,7 @@ def worker_dashboard(): conn = sqlite3.connect(DB_NAME) c = conn.cursor() - # 1. Identify the worker and their assigned location + # 1. Identificar al trabajador y su zona asignada c.execute('''SELECT w.modulo_id, m.name, z.id, z.name FROM workers w JOIN modulos m ON w.modulo_id = m.id @@ -201,35 +208,49 @@ def worker_dashboard(): modulo_id, modulo_name, zona_id, zona_name = worker_info - # 2. Handle form submission + # 2. Manejo del envío del formulario if request.method == 'POST': fecha = request.form.get('fecha') turno = request.form.get('turno') - # Clean the money inputs (strip dots) - def clean_money(val): - return int(val.replace('.', '')) if val else 0 - - tarjeta = clean_money(request.form.get('venta_tarjeta')) - mp = clean_money(request.form.get('venta_mp')) - efectivo = clean_money(request.form.get('venta_efectivo')) - gastos = clean_money(request.form.get('gastos')) + # Función para limpiar puntos y validar presencia de datos + def clean_and_validate(val): + if val is None or val.strip() == "": + return None + try: + return int(val.replace('.', '')) + except ValueError: + return None + + # Captura y validación de campos obligatorios + tarjeta = clean_and_validate(request.form.get('venta_tarjeta')) + mp = clean_and_validate(request.form.get('venta_mp')) + efectivo = clean_and_validate(request.form.get('venta_efectivo')) + gastos = clean_and_validate(request.form.get('gastos')) or 0 obs = request.form.get('observaciones', '').strip() - # Insert Header + # VERIFICACIÓN: Todos los campos de venta deben estar rellenos + if tarjeta is None or mp is None or efectivo is None or not fecha or not turno: + flash("Error: Todos los campos (Fecha, Turno, Tarjeta, MP y Efectivo) son obligatorios. Use 0 si no hubo ventas.", "danger") + return redirect(url_for('worker_dashboard')) + + # CÁLCULOS ADICIONALES (Para lógica de negocio o auditoría futura) + total_digital = tarjeta + mp + total_ventas_general = total_digital + efectivo + + # Insertar Cabecera de Rendición c.execute('''INSERT INTO rendiciones (worker_id, modulo_id, fecha, turno, venta_tarjeta, venta_mp, venta_efectivo, gastos, observaciones) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)''', (session['user_id'], modulo_id, fecha, turno, tarjeta, mp, efectivo, gastos, obs)) rendicion_id = c.lastrowid - # Insert Products (Only those with a quantity > 0) + # Insertar Productos (Solo aquellos con cantidad > 0) for key, value in request.form.items(): if key.startswith('qty_') and value and int(value) > 0: prod_id = int(key.split('_')[1]) cantidad = int(value) - # Fetch current price/commission to snapshot it c.execute("SELECT price, commission FROM productos WHERE id = ?", (prod_id,)) prod_data = c.fetchone() @@ -240,15 +261,14 @@ def worker_dashboard(): (rendicion_id, prod_id, cantidad, prod_data[0], prod_data[1])) conn.commit() - flash("Rendición enviada exitosamente.", "success") + flash(f"Rendición enviada exitosamente. Total General Declarado: ${total_ventas_general:,}".replace(',', '.'), "success") return redirect(url_for('worker_dashboard')) - # 3. Load Products for the GET request + # 3. Cargar Productos para la solicitud GET c.execute("SELECT id, name, price, commission FROM productos WHERE zona_id = ? ORDER BY name", (zona_id,)) productos = c.fetchall() conn.close() - # Determine if this module uses commissions (Peppermint) or not (Candy) has_commission = any(prod[3] > 0 for prod in productos) return render_template('worker_dashboard.html', @@ -257,7 +277,7 @@ def worker_dashboard(): productos=productos, has_commission=has_commission, today=date.today().strftime('%Y-%m-%d')) - + @app.route('/admin/workers', methods=['GET', 'POST']) @admin_required def manage_workers(): diff --git a/static/style.css b/static/style.css index 80d8fba..67647a6 100644 --- a/static/style.css +++ b/static/style.css @@ -54,13 +54,25 @@ } @media (max-width: 576px) { - .col-barcode { - display: none; - } - - .btn-edit-sm, - .btn-del-sm { - padding: 4px 7px; - font-size: 0.75rem; - } + .col-barcode { + display: none; } + + .btn-edit-sm, + .btn-del-sm { + padding: 4px 7px; + font-size: 0.75rem; + } +} + +[data-bs-theme="light"] #theme-icon.bi-moon-stars { + color: #5856d6; /* Un color índigo vibrante para que resalte en el fondo claro */ +} + +[data-bs-theme="dark"] #theme-icon.bi-sun { + color: #ffc107; /* Amarillo cálido de Bootstrap */ +} + +#theme-switcher.nav-link { + color: inherit !important; +} \ No newline at end of file diff --git a/static/themeStuff.js b/static/themeStuff.js index 3c408b7..855836e 100644 --- a/static/themeStuff.js +++ b/static/themeStuff.js @@ -4,13 +4,9 @@ function applyTheme(t) { const isDark = (t === 'dark'); const themeIcon = document.getElementById('theme-icon'); - const themeLabel = document.getElementById('theme-label'); if (themeIcon) { - themeIcon.className = isDark ? 'bi bi-sun me-2' : 'bi bi-moon-stars me-2'; - } - if (themeLabel) { - themeLabel.innerText = isDark ? 'Modo Claro' : 'Modo Oscuro'; + themeIcon.className = isDark ? 'bi bi-sun fs-5' : 'bi bi-moon-stars fs-5'; } } diff --git a/templates/admin_workers.html b/templates/admin_workers.html index 55ad3f9..973807c 100644 --- a/templates/admin_workers.html +++ b/templates/admin_workers.html @@ -106,6 +106,8 @@ +{% endblock %} +{% block scripts %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..6cd4454 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,10 @@ +{% extends "macros/base.html" %} + +{% block title %}Dashboad?{% endblock %} + +{% block content %} +

Poner algo aqui?

+{% endblock %} + +{% block scripts %} +{% endblock %} \ No newline at end of file diff --git a/templates/macros/navbar.html b/templates/macros/navbar.html index abd56db..1589f4f 100644 --- a/templates/macros/navbar.html +++ b/templates/macros/navbar.html @@ -1,12 +1,14 @@ -