From c6440e819e8520380ae976bc95b8ac73b55037e6 Mon Sep 17 00:00:00 2001 From: SekiDesu0 Date: Sun, 22 Mar 2026 19:30:10 -0300 Subject: [PATCH] modified: app.py new file: templates/admin_report_modulo.html new file: templates/admin_reportes_index.html new file: templates/admin_reportes_menu.html modified: templates/macros/navbar.html --- app.py | 118 ++++++++++++++++++++++ templates/admin_report_modulo.html | 147 ++++++++++++++++++++++++++++ templates/admin_reportes_index.html | 52 ++++++++++ templates/admin_reportes_menu.html | 117 ++++++++++++++++++++++ templates/macros/navbar.html | 5 + 5 files changed, 439 insertions(+) create mode 100644 templates/admin_report_modulo.html create mode 100644 templates/admin_reportes_index.html create mode 100644 templates/admin_reportes_menu.html diff --git a/app.py b/app.py index 131da12..4979b78 100644 --- a/app.py +++ b/app.py @@ -6,6 +6,7 @@ import random import string from functools import wraps from datetime import date +from collections import defaultdict app = Flask(__name__) app.secret_key = "super_secret_dev_key" @@ -848,6 +849,123 @@ def edit_rendicion(id): flash("Rendición actualizada correctamente.", "success") return redirect(url_for('admin_rendiciones')) + +@app.route('/admin/reportes') +@admin_required # Asumo que usas este decorador +def admin_reportes_index(): + conn = sqlite3.connect(DB_NAME) + c = conn.cursor() + + # Ahora hacemos un JOIN con zonas para poder agruparlos en la vista + c.execute(''' + SELECT m.id, m.name, z.name + FROM modulos m + JOIN zonas z ON m.zona_id = z.id + ORDER BY z.name, m.name + ''') + modulos = c.fetchall() + conn.close() + + return render_template('admin_reportes_index.html', modulos=modulos) + +@app.route('/admin/reportes/modulo//menu') +@admin_required +def admin_reportes_menu_modulo(modulo_id): + # Esta ruta muestra las opciones de reporte para un módulo específico + conn = sqlite3.connect(DB_NAME) + c = conn.cursor() + + c.execute("SELECT name FROM modulos WHERE id = ?", (modulo_id,)) + modulo_info = c.fetchone() + conn.close() + + if not modulo_info: + flash("Módulo no encontrado.", "danger") + return redirect(url_for('admin_reportes_index')) + + modulo_name = modulo_info[0] + + return render_template('admin_reportes_menu.html', modulo_id=modulo_id, modulo_name=modulo_name) + +@app.route('/admin/reportes/modulo/') +@admin_required +def report_modulo_periodo(modulo_id): + # Por defecto, mes actual + mes_actual = date.today().month + anio_actual = date.today().year + dias_en_periodo = [f'{d:02}' for d in range(1, 32)] # Rango de 31 días + + conn = sqlite3.connect(DB_NAME) + c = conn.cursor() + + c.execute("SELECT name FROM modulos WHERE id = ?", (modulo_id,)) + modulo_info = c.fetchone() + if not modulo_info: + conn.close() + flash("Módulo no encontrado.", "danger") + return redirect(url_for('admin_reportes_index')) + modulo_name = modulo_info[0] + + # 1. Obtener finanzas (pagos y gastos) agrupadas por día + c.execute(''' + SELECT strftime('%d', fecha) as dia, + SUM(venta_debito), SUM(venta_credito), SUM(venta_mp), SUM(venta_efectivo), SUM(gastos) + FROM rendiciones + WHERE modulo_id = ? AND strftime('%m', fecha) = ? AND strftime('%Y', fecha) = ? + GROUP BY dia + ''', (modulo_id, f'{mes_actual:02}', str(anio_actual))) + finanzas_db = c.fetchall() + + # 2. Obtener comisiones agrupadas por día + c.execute(''' + SELECT strftime('%d', r.fecha) as dia, + SUM(ri.cantidad * ri.comision_historica) as comision_total + FROM rendicion_items ri + JOIN rendiciones r ON ri.rendicion_id = r.id + WHERE r.modulo_id = ? AND strftime('%m', r.fecha) = ? AND strftime('%Y', r.fecha) = ? + GROUP BY dia + ''', (modulo_id, f'{mes_actual:02}', str(anio_actual))) + comisiones_db = c.fetchall() + + conn.close() + + # 3. Estructurar los datos para la tabla web + data_por_dia = {dia: {'debito': 0, 'credito': 0, 'mp': 0, 'efectivo': 0, 'gastos': 0, 'comision': 0, 'venta_total': 0} for dia in dias_en_periodo} + + for row in finanzas_db: + dia, debito, credito, mp, efectivo, gastos = row + venta_total = (debito or 0) + (credito or 0) + (mp or 0) + (efectivo or 0) + data_por_dia[dia].update({ + 'debito': debito or 0, + 'credito': credito or 0, + 'mp': mp or 0, + 'efectivo': efectivo or 0, + 'gastos': gastos or 0, + 'venta_total': venta_total + }) + + for row in comisiones_db: + dia, comision = row + data_por_dia[dia]['comision'] = comision or 0 + + # 4. Calcular totales del mes para el Footer y las Tarjetas (KPIs) + totales_mes = {'debito': 0, 'credito': 0, 'mp': 0, 'efectivo': 0, 'gastos': 0, 'comision': 0, 'venta_total': 0} + dias_activos = 0 + + for dia, datos in data_por_dia.items(): + if datos['venta_total'] > 0 or datos['gastos'] > 0: + dias_activos += 1 + for k in totales_mes.keys(): + totales_mes[k] += datos[k] + + return render_template('admin_report_modulo.html', + modulo_name=modulo_name, + mes_nombre=f'{mes_actual:02}/{anio_actual}', + dias_en_periodo=dias_en_periodo, + data_por_dia=data_por_dia, + totales_mes=totales_mes, + dias_activos=dias_activos) + if __name__ == '__main__': init_db() app.run(host='0.0.0.0', port=5000, debug=True) \ No newline at end of file diff --git a/templates/admin_report_modulo.html b/templates/admin_report_modulo.html new file mode 100644 index 0000000..2292673 --- /dev/null +++ b/templates/admin_report_modulo.html @@ -0,0 +1,147 @@ +{% extends "macros/base.html" %} + +{% block title %}Reporte: Finanzas - {{ modulo_name }}{% endblock %} + +{% block styles %} + +{% endblock %} + +{% block content %} +
+
+ + Volver al Menú + +

Resumen Financiero y Medios de Pago

+
+
+
{{ modulo_name }}
+
Período: {{ mes_nombre }}
+
+
+ +
+
+
+
+
Venta Total Mensual
+

${{ "{:,.0f}".format(totales_mes.venta_total).replace(',', '.') }}

+
+
+
+
+
+
+
Comisiones Generadas
+

${{ "{:,.0f}".format(totales_mes.comision).replace(',', '.') }}

+
+
+
+
+
+
+
Total Gastos
+

-${{ "{:,.0f}".format(totales_mes.gastos).replace(',', '.') }}

+
+
+
+
+
+
+
Días Trabajados
+

{{ dias_activos }} / 31

+
+
+
+
+ +
+
+ Desglose Diario + + +
+
+
+ + + + + + + + + + + + + + + + + + {% for dia in dias_en_periodo %} + {% set d = data_por_dia[dia] %} + + + + + + + + + + + + + {% endfor %} + + + + + + + + + + + + + + +
DíaVENTA TOTALCOMISIÓNGASTOSMEDIOS DE PAGO
CréditoDébitoMercado PagoEfectivo/Dep.
{{ dia }} + {{ ("$" ~ "{:,.0f}".format(d.venta_total).replace(',', '.')) if d.venta_total > 0 else "-" }} + + {{ ("$" ~ "{:,.0f}".format(d.comision).replace(',', '.')) if d.comision > 0 else "-" }} + + {{ ("-$" ~ "{:,.0f}".format(d.gastos).replace(',', '.')) if d.gastos > 0 else "-" }} + {{ ("$" ~ "{:,.0f}".format(d.credito).replace(',', '.')) if d.credito > 0 else "-" }}{{ ("$" ~ "{:,.0f}".format(d.debito).replace(',', '.')) if d.debito > 0 else "-" }}{{ ("$" ~ "{:,.0f}".format(d.mp).replace(',', '.')) if d.mp > 0 else "-" }}{{ ("$" ~ "{:,.0f}".format(d.efectivo).replace(',', '.')) if d.efectivo > 0 else "-" }}
TOTAL + ${{ "{:,.0f}".format(totales_mes.venta_total).replace(',', '.') }} + + ${{ "{:,.0f}".format(totales_mes.comision).replace(',', '.') }} + + -${{ "{:,.0f}".format(totales_mes.gastos).replace(',', '.') }} + ${{ "{:,.0f}".format(totales_mes.credito).replace(',', '.') }}${{ "{:,.0f}".format(totales_mes.debito).replace(',', '.') }}${{ "{:,.0f}".format(totales_mes.mp).replace(',', '.') }}${{ "{:,.0f}".format(totales_mes.efectivo).replace(',', '.') }}
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/admin_reportes_index.html b/templates/admin_reportes_index.html new file mode 100644 index 0000000..ddb531c --- /dev/null +++ b/templates/admin_reportes_index.html @@ -0,0 +1,52 @@ +{% extends "macros/base.html" %} + +{% block title %}Panel de Reportes{% endblock %} + +{% block content %} +
+

Panel de Reportes

+
+ +
+

Selecciona un módulo para ver sus reportes disponibles.

+
+ +{% for zona_name, lista_modulos in modulos|groupby(2) %} +
+

+ Zona: {{ zona_name }} +

+ +
+ {% for mod in lista_modulos %} + + {% endfor %} +
+
+{% else %} +
No hay módulos registrados en el sistema.
+{% endfor %} + + +{% endblock %} \ No newline at end of file diff --git a/templates/admin_reportes_menu.html b/templates/admin_reportes_menu.html new file mode 100644 index 0000000..26f6022 --- /dev/null +++ b/templates/admin_reportes_menu.html @@ -0,0 +1,117 @@ +{% extends "macros/base.html" %} + +{% block title %}Menú de Reportes - {{ modulo_name }}{% endblock %} + +{% block content %} +
+
+ + Volver a Módulos + +

Reportes: {{ modulo_name }}

+
+
+ +
+
+
+
+
+
+ +
+
Detalle de Ventas y Medios de Pago
+
+

Análisis detallado de ventas diarias, productos vendidos y consolidado mensual.

+ Generar Reporte +
+
+
+ +
+
+
+
+
+ +
+
Comisiones
+
+

Cálculo de comisiones generadas por los trabajadores en este módulo.

+ +
+
+
+ +
+
+
+
+
+ +
+
Control de Horarios
+
+

Registro de horas de entrada y salida de los trabajadores y acompañantes.

+ +
+
+
+ +
+
+
+
+
+ +
+
Centros Comerciales
+
+

Reporte de datos exigidos por la administración del centro comercial.

+ +
+
+
+ +
+
+
+
+
+ +
+
Cálculo de IVA
+
+

Proyección de impuestos basados en las ventas declaradas.

+ +
+
+
+ +
+
+
+
+
+ +
+
Robos y Mermas
+
+

Cuadratura de inventario y registro de pérdida de productos.

+ +
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/macros/navbar.html b/templates/macros/navbar.html index f35dd02..eeb7425 100644 --- a/templates/macros/navbar.html +++ b/templates/macros/navbar.html @@ -40,6 +40,11 @@ Productos + {% else %}