dashboard trabajador
This commit is contained in:
62
app.py
62
app.py
@@ -286,13 +286,61 @@ def logout():
|
|||||||
session.clear()
|
session.clear()
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
@app.route('/dashboard', methods=['GET', 'POST'])
|
@app.route('/dashboard')
|
||||||
@login_required
|
@login_required
|
||||||
def worker_dashboard():
|
def worker_dashboard():
|
||||||
|
# Este es el nuevo historial principal del trabajador
|
||||||
|
conn = sqlite3.connect(DB_NAME)
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
user_id = session['user_id']
|
||||||
|
|
||||||
|
c.execute('''
|
||||||
|
SELECT r.id, r.fecha, w.name, m.name,
|
||||||
|
r.venta_debito, r.venta_credito, r.venta_mp, r.venta_efectivo, r.gastos, r.observaciones,
|
||||||
|
c_w.name, r.worker_id, r.companion_id, r.modulo_id
|
||||||
|
FROM rendiciones r
|
||||||
|
JOIN workers w ON r.worker_id = w.id
|
||||||
|
JOIN modulos m ON r.modulo_id = m.id
|
||||||
|
LEFT JOIN workers c_w ON r.companion_id = c_w.id
|
||||||
|
WHERE r.worker_id = ? OR r.companion_id = ?
|
||||||
|
ORDER BY r.fecha DESC, r.id DESC
|
||||||
|
''', (user_id, user_id))
|
||||||
|
rendiciones_basicas = c.fetchall()
|
||||||
|
|
||||||
|
rendiciones_completas = []
|
||||||
|
for r in rendiciones_basicas:
|
||||||
|
c.execute('''
|
||||||
|
SELECT p.name, ri.cantidad, ri.precio_historico, ri.comision_historica,
|
||||||
|
(ri.cantidad * ri.precio_historico) as total_linea,
|
||||||
|
(ri.cantidad * ri.comision_historica) as total_comision
|
||||||
|
FROM rendicion_items ri
|
||||||
|
JOIN productos p ON ri.producto_id = p.id
|
||||||
|
WHERE ri.rendicion_id = ?
|
||||||
|
''', (r[0],))
|
||||||
|
items = c.fetchall()
|
||||||
|
|
||||||
|
total_calculado = sum(item[4] for item in items)
|
||||||
|
comision_total = sum(item[5] for item in items)
|
||||||
|
|
||||||
|
# Determinar el rol para mostrarlo en la tabla
|
||||||
|
rol = "Titular" if r[11] == user_id else "Acompañante"
|
||||||
|
|
||||||
|
# Items en 14, total en 15, comision en 16, rol en 17
|
||||||
|
r_completa = r + (items, total_calculado, comision_total, rol)
|
||||||
|
rendiciones_completas.append(r_completa)
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
return render_template('worker_history.html', rendiciones=rendiciones_completas)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/rendicion/nueva', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def new_rendicion():
|
||||||
|
# Este es el formulario de creación (tu antiguo dashboard)
|
||||||
conn = sqlite3.connect(DB_NAME)
|
conn = sqlite3.connect(DB_NAME)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
|
||||||
# 1. Identificar al trabajador y su zona asignada
|
|
||||||
c.execute('''SELECT w.modulo_id, m.name, z.id, z.name
|
c.execute('''SELECT w.modulo_id, m.name, z.id, z.name
|
||||||
FROM workers w
|
FROM workers w
|
||||||
JOIN modulos m ON w.modulo_id = m.id
|
JOIN modulos m ON w.modulo_id = m.id
|
||||||
@@ -306,7 +354,6 @@ def worker_dashboard():
|
|||||||
|
|
||||||
modulo_id, modulo_name, zona_id, zona_name = worker_info
|
modulo_id, modulo_name, zona_id, zona_name = worker_info
|
||||||
|
|
||||||
# 2. Manejo del envío del formulario
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
fecha = request.form.get('fecha')
|
fecha = request.form.get('fecha')
|
||||||
hora_entrada = request.form.get('hora_entrada')
|
hora_entrada = request.form.get('hora_entrada')
|
||||||
@@ -337,7 +384,7 @@ def worker_dashboard():
|
|||||||
|
|
||||||
if debito is None or credito is None or mp is None or efectivo is None or not fecha or not hora_entrada or not hora_salida:
|
if debito is None or credito is None or mp is None or efectivo is None or not fecha or not hora_entrada or not hora_salida:
|
||||||
flash("Error: Todos los campos obligatorios deben estar rellenos.", "danger")
|
flash("Error: Todos los campos obligatorios deben estar rellenos.", "danger")
|
||||||
return redirect(url_for('worker_dashboard'))
|
return redirect(url_for('new_rendicion'))
|
||||||
|
|
||||||
total_digital = debito + credito + mp
|
total_digital = debito + credito + mp
|
||||||
total_ventas_general = total_digital + efectivo
|
total_ventas_general = total_digital + efectivo
|
||||||
@@ -350,7 +397,6 @@ def worker_dashboard():
|
|||||||
debito, credito, mp, efectivo, gastos, obs))
|
debito, credito, mp, efectivo, gastos, obs))
|
||||||
rendicion_id = c.lastrowid
|
rendicion_id = c.lastrowid
|
||||||
|
|
||||||
# Insertar Productos (Solo aquellos con cantidad > 0)
|
|
||||||
for key, value in request.form.items():
|
for key, value in request.form.items():
|
||||||
if key.startswith('qty_') and value and int(value) > 0:
|
if key.startswith('qty_') and value and int(value) > 0:
|
||||||
prod_id = int(key.split('_')[1])
|
prod_id = int(key.split('_')[1])
|
||||||
@@ -367,9 +413,8 @@ def worker_dashboard():
|
|||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
flash(f"Rendición enviada exitosamente. Total General Declarado: ${total_ventas_general:,}".replace(',', '.'), "success")
|
flash(f"Rendición enviada exitosamente. Total General Declarado: ${total_ventas_general:,}".replace(',', '.'), "success")
|
||||||
return redirect(url_for('worker_dashboard'))
|
return redirect(url_for('worker_dashboard')) # Redirige al historial
|
||||||
|
|
||||||
# 3. Cargar Productos para la solicitud GET
|
|
||||||
c.execute('''
|
c.execute('''
|
||||||
SELECT id, name FROM workers
|
SELECT id, name FROM workers
|
||||||
WHERE id != ? AND modulo_id = ? AND is_admin = 0
|
WHERE id != ? AND modulo_id = ? AND is_admin = 0
|
||||||
@@ -377,7 +422,6 @@ def worker_dashboard():
|
|||||||
''', (session['user_id'], modulo_id))
|
''', (session['user_id'], modulo_id))
|
||||||
otros_trabajadores = c.fetchall()
|
otros_trabajadores = c.fetchall()
|
||||||
|
|
||||||
# Cargar Productos (código existente)
|
|
||||||
c.execute("SELECT id, name, price, commission FROM productos WHERE zona_id = ? ORDER BY name", (zona_id,))
|
c.execute("SELECT id, name, price, commission FROM productos WHERE zona_id = ? ORDER BY name", (zona_id,))
|
||||||
productos = c.fetchall()
|
productos = c.fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
@@ -391,7 +435,7 @@ def worker_dashboard():
|
|||||||
has_commission=has_commission,
|
has_commission=has_commission,
|
||||||
otros_trabajadores=otros_trabajadores,
|
otros_trabajadores=otros_trabajadores,
|
||||||
today=date.today().strftime('%Y-%m-%d'))
|
today=date.today().strftime('%Y-%m-%d'))
|
||||||
|
|
||||||
@app.route('/admin/workers', methods=['GET', 'POST'])
|
@app.route('/admin/workers', methods=['GET', 'POST'])
|
||||||
@admin_required
|
@admin_required
|
||||||
def manage_workers():
|
def manage_workers():
|
||||||
|
|||||||
@@ -10,7 +10,12 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
<h2>Rendición de Caja</h2>
|
<div>
|
||||||
|
<a href="{{ url_for('worker_dashboard') }}" class="btn btn-outline-secondary btn-sm mb-2">
|
||||||
|
<i class="bi bi-arrow-left"></i> Volver al Historial
|
||||||
|
</a>
|
||||||
|
<h2>Nueva Rendición de Caja</h2>
|
||||||
|
</div>
|
||||||
<div class="text-end text-muted">
|
<div class="text-end text-muted">
|
||||||
<div><strong>Módulo:</strong> <span class="badge bg-primary">{{ modulo_name }}</span></div>
|
<div><strong>Módulo:</strong> <span class="badge bg-primary">{{ modulo_name }}</span></div>
|
||||||
<div><small>Zona: {{ zona_name }}</small></div>
|
<div><small>Zona: {{ zona_name }}</small></div>
|
||||||
|
|||||||
74
templates/worker_history.html
Normal file
74
templates/worker_history.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
{% extends "macros/base.html" %}
|
||||||
|
{% from 'macros/modals.html' import rendicion_detail_modal %}
|
||||||
|
|
||||||
|
{% block title %}Mis Rendiciones{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h2>Mis Rendiciones</h2>
|
||||||
|
<a href="{{ url_for('new_rendicion') }}" class="btn btn-success shadow-sm">
|
||||||
|
<i class="bi bi-plus-circle me-2"></i>Nueva Rendición
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
|
{% if messages %}
|
||||||
|
{% for category, message in messages %}
|
||||||
|
<div class="alert alert-{{ category }}">{{ message|safe }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
|
<div class="card shadow-sm border-0">
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<table class="table table-striped table-hover mb-0">
|
||||||
|
<thead class="table-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Fecha</th>
|
||||||
|
<th>Mi Rol</th>
|
||||||
|
<th>Módulo</th>
|
||||||
|
<th>Total Declarado</th>
|
||||||
|
<th>Gastos</th>
|
||||||
|
<th class="text-end">Acciones</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for r in rendiciones %}
|
||||||
|
<tr>
|
||||||
|
<td class="align-middle">{{ r[1] }}</td>
|
||||||
|
<td class="align-middle">
|
||||||
|
{% if r[17] == 'Titular' %}
|
||||||
|
<span class="badge bg-primary">Titular</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-secondary">Acompañante</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="align-middle"><span class="badge bg-info text-dark">{{ r[3] }}</span></td>
|
||||||
|
|
||||||
|
<td class="align-middle fw-bold text-success">
|
||||||
|
${{ "{:,.0f}".format((r[4] or 0) + (r[5] or 0) + (r[6] or 0) + (r[7] or 0)).replace(',', '.') }}
|
||||||
|
</td>
|
||||||
|
<td class="align-middle text-danger">
|
||||||
|
${{ "{:,.0f}".format(r[8] or 0).replace(',', '.') }}
|
||||||
|
</td>
|
||||||
|
<td class="text-end">
|
||||||
|
<button type="button" class="btn btn-sm btn-info text-white" data-bs-toggle="modal" data-bs-target="#viewRendicion{{ r[0] }}" title="Ver Detalle">
|
||||||
|
<i class="bi bi-eye"></i> Ver Detalle
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{{ rendicion_detail_modal(r, r[14], r[15], r[16]) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-center py-5 text-muted">
|
||||||
|
<i class="bi bi-inbox fs-2 d-block mb-2"></i>
|
||||||
|
Aún no tienes rendiciones registradas.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user