Skip to content

Commit

Permalink
Merge pull request #972 from guivaloz:guivaloz/filtros-entradas-salidas
Browse files Browse the repository at this point in the history
Filtros bitacoras entradas_salidas
  • Loading branch information
guivaloz authored Apr 29, 2024
2 parents a1ce54d + fe02701 commit 0ca7518
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,36 @@

{% block content %}
{% call list.card() %}
<!-- Filtros bitacoras -->
<div class="row">
<div class="col">
<form class="row g-1 mb-3" id="filtradorForm" onsubmit="filtrosBitacoras.buscar(); return false;">
<div class="col-4">
<div class="form-floating">
<input id="filtroBitacoraUsuarioEmail" type="text" class="form-control" aria-label="e-mail">
<label for="filtroBitacoraUsuarioEmail">e-mail</label>
</div>
</div>
<div class="col-4">
<div class="form-floating">
<input id="filtroBitacoraModuloNombre" type="text" class="form-control" aria-label="Módulo" style="text-transform: uppercase;">
<label for="filtroBitacoraModuloNombre">Módulo</label>
</div>
</div>
<div class="col-4 text-end">
<button title="Buscar" class="btn btn-primary btn-lg" onclick="filtrosBitacoras.buscar(); return false;" id="button-buscar"><span class="iconify" data-icon="mdi:magnify"></span></button>
<button title="Limpiar" class="btn btn-warning btn-lg" type="reset" onclick="filtrosBitacoras.limpiar();" id="button-limpiar"><span class="iconify" data-icon="mdi:broom"></span></button>
</div>
</form>
</div>
</div>
<!-- Datatable bitacoras -->
<table id="bitacoras_datatable" class="table display nowrap" style="width:100%">
<thead>
<tr>
<th>Tiempo</th>
<th>Usuario</th>
<th>Modulo</th>
<th>Descripción</th>
</tr>
</thead>
Expand All @@ -30,13 +55,18 @@
{% endblock %}

{% block custom_javascript %}
{{ list.config_datatable() }}
<script src="/static/js/datatables-constructor.js"></script>
<script src="/static/js/datatables-filtros.js"></script>
<script>
// DataTable bitacoras
const constructorDataTable = new ConfigDataTable( '{{ csrf_token() }}' );
let configDataTable = constructorDataTable.config();
configDataTable['ajax']['url'] = '/bitacoras/datatable_json';
configDataTable['ajax']['data'] = {}; // Sin filtros
configDataTable['columns'] = [
{ data: "creado" },
{ data: "usuario" },
{ data: "modulo" },
{ data: "vinculo" }
];
configDataTable['columnDefs'] = [
Expand All @@ -55,13 +85,24 @@
}
},
{
targets: 2, // vinculo
targets: 2, // modulo
data: null,
render: function(data, type, row, meta) {
return '<a href="' + data.url + '">' + data.nombre + '</a>';
}
},
{
targets: 3, // vinculo
data: null,
render: function(data, type, row, meta) {
return '<a href="' + data.url + '" target="_blank">' + data.descripcion + ' <span class="iconify" data-icon="mdi:open-in-new"></span></a>';
}
}
];
$('#bitacoras_datatable').DataTable(configDataTable);
// Filtros bitacoras
const filtrosBitacoras = new FiltrosDataTable('#bitacoras_datatable', configDataTable);
filtrosBitacoras.agregarInput('filtroBitacoraUsuarioEmail', 'usuario_email');
filtrosBitacoras.agregarInput('filtroBitacoraModuloNombre', 'modulo_nombre');
filtrosBitacoras.precargar();
</script>
{% endblock %}
56 changes: 44 additions & 12 deletions plataforma_web/blueprints/bitacoras/views.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,78 @@
"""
Bitácoras, vistas
"""
from flask import Blueprint, render_template, url_for
from flask_login import login_required

from lib.datatables import get_datatable_parameters, output_datatable_json
from flask import Blueprint, render_template, request, url_for
from flask_login import current_user, login_required

from lib.datatables import get_datatable_parameters, output_datatable_json
from lib.safe_string import safe_email, safe_string
from plataforma_web.blueprints.bitacoras.models import Bitacora
from plataforma_web.blueprints.modulos.models import Modulo
from plataforma_web.blueprints.permisos.models import Permiso
from plataforma_web.blueprints.usuarios.decorators import permission_required
from plataforma_web.blueprints.usuarios.models import Usuario

MODULO = "BITACORAS"

bitacoras = Blueprint("bitacoras", __name__, template_folder="templates")


@bitacoras.route("/bitacoras/datatable_json", methods=["GET", "POST"])
@bitacoras.before_request
@login_required
@permission_required(MODULO, Permiso.VER)
def before_request():
"""Permiso por defecto"""


@bitacoras.route("/bitacoras/datatable_json", methods=["GET", "POST"])
def datatable_json():
"""DataTable JSON para listado de listado de bitácoras"""
# Tomar parámetros de Datatables
draw, start, rows_per_page = get_datatable_parameters()
# Consultar
consulta = Bitacora.query
# Primero filtrar por columnas propias
if "estatus" in request.form:
consulta = consulta.filter_by(estatus=request.form["estatus"])
else:
consulta = consulta.filter_by(estatus="A")
if "modulo_id" in request.form:
consulta = consulta.filter_by(modulo_id=request.form["modulo_id"])
if "usuario_id" in request.form:
consulta = consulta.filter_by(usuario_id=request.form["usuario_id"])
# Luego filtrar por columnas de otras tablas
if "modulo_nombre" in request.form:
modulo_nombre = safe_string(request.form["modulo_nombre"], save_enie=True)
if modulo_nombre != "":
consulta = consulta.join(Modulo).filter(Modulo.nombre.contains(modulo_nombre))
if "usuario_email" in request.form:
try:
usuario_email = safe_email(request.form["usuario_email"], search_fragment=True)
if usuario_email != "":
consulta = consulta.join(Usuario).filter(Usuario.email.contains(usuario_email))
except ValueError:
pass
# Ordenar y paginar
registros = consulta.order_by(Bitacora.id.desc()).offset(start).limit(rows_per_page).all()
total = consulta.count()
# Elaborar un listado de diccionarios
data = []
for bitacora in registros:
for resultado in registros:
data.append(
{
"creado": bitacora.creado.strftime("%Y-%m-%d %H:%M:%S"),
"creado": resultado.creado.strftime("%Y-%m-%d %H:%M:%S"),
"usuario": {
"email": bitacora.usuario.email,
"url": url_for("usuarios.detail", usuario_id=bitacora.usuario_id),
"email": resultado.usuario.email,
"url": (url_for("usuarios.detail", usuario_id=resultado.usuario_id) if current_user.can_view("USUARIOS") else ""),
},
"modulo": {
"nombre": resultado.modulo.nombre,
"url": url_for("modulos.detail", modulo_id=resultado.modulo_id) if current_user.can_view("MODULOS") else "",
},
"vinculo": {
"descripcion": bitacora.descripcion,
"url": bitacora.url,
"descripcion": resultado.descripcion,
"url": resultado.url,
},
}
)
Expand All @@ -47,8 +81,6 @@ def datatable_json():


@bitacoras.route("/bitacoras")
@login_required
@permission_required(MODULO, Permiso.VER)
def list_active():
"""Listado de bitácoras"""
return render_template("bitacoras/list.jinja2")
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@

{% block content %}
{% call list.card() %}
<!-- Filtros entradas_salidas -->
<div class="row">
<div class="col">
<form class="row g-1 mb-3" id="filtradorForm" onsubmit="filtrosEntradasSalidas.buscar(); return false;">
<div class="col-6">
<div class="form-floating">
<input id="filtroEntradaSalidaUsuarioEmail" type="text" class="form-control" aria-label="e-mail">
<label for="filtroEntradaSalidaUsuarioEmail">e-mail</label>
</div>
</div>
<div class="col-6 text-end">
<button title="Buscar" class="btn btn-primary btn-lg" onclick="filtrosEntradasSalidas.buscar(); return false;" id="button-buscar"><span class="iconify" data-icon="mdi:magnify"></span></button>
<button title="Limpiar" class="btn btn-warning btn-lg" type="reset" onclick="filtrosEntradasSalidas.limpiar();" id="button-limpiar"><span class="iconify" data-icon="mdi:broom"></span></button>
</div>
</form>
</div>
</div>
<!-- Datatable entradas_salidas -->
<table id="entradas_salidas_datatable" class="table display nowrap" style="width:100%">
<thead>
<tr>
Expand All @@ -30,8 +48,12 @@
{% endblock %}

{% block custom_javascript %}
{{ list.config_datatable() }}
<script src="/static/js/datatables-constructor.js"></script>
<script src="/static/js/datatables-filtros.js"></script>
<script>
// DataTable entradas_salidas
const constructorDataTable = new ConfigDataTable( '{{ csrf_token() }}' );
let configDataTable = constructorDataTable.config();
configDataTable['ajax']['url'] = '/entradas_salidas/datatable_json';
configDataTable['ajax']['data'] = {}; // Sin filtros
configDataTable['columns'] = [
Expand All @@ -55,6 +77,9 @@
}
}
];
$('#entradas_salidas_datatable').DataTable(configDataTable);
// Filtros bitacoras
const filtrosEntradasSalidas = new FiltrosDataTable('#entradas_salidas_datatable', configDataTable);
filtrosEntradasSalidas.agregarInput('filtroEntradaSalidaUsuarioEmail', 'usuario_email');
filtrosEntradasSalidas.precargar();
</script>
{% endblock %}
32 changes: 26 additions & 6 deletions plataforma_web/blueprints/entradas_salidas/views.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
"""
Entradas-Salidas, vistas
"""
from flask import Blueprint, render_template
from flask.helpers import url_for

from flask import Blueprint, render_template, request, url_for
from flask_login import login_required

from lib.datatables import get_datatable_parameters, output_datatable_json

from lib.safe_string import safe_email
from plataforma_web.blueprints.entradas_salidas.models import EntradaSalida
from plataforma_web.blueprints.permisos.models import Permiso
from plataforma_web.blueprints.usuarios.decorators import permission_required
from plataforma_web.blueprints.usuarios.models import Usuario

MODULO = "ENTRADAS SALIDAS"

entradas_salidas = Blueprint("entradas_salidas", __name__, template_folder="templates")


@entradas_salidas.route("/entradas_salidas/datatable_json", methods=["GET", "POST"])
@entradas_salidas.before_request
@login_required
@permission_required(MODULO, Permiso.VER)
def before_request():
"""Permiso por defecto"""


@entradas_salidas.route("/entradas_salidas/datatable_json", methods=["GET", "POST"])
def datatable_json():
"""DataTable JSON para listado de entradas y salidas"""
# Tomar parámetros de Datatables
draw, start, rows_per_page = get_datatable_parameters()
# Consultar
consulta = EntradaSalida.query
# Primero filtrar por columnas propias
if "estatus" in request.form:
consulta = consulta.filter_by(estatus=request.form["estatus"])
else:
consulta = consulta.filter_by(estatus="A")
if "usuario_id" in request.form:
consulta = consulta.filter_by(usuario_id=request.form["usuario_id"])
# Luego filtrar por columnas de otras tablas
if "usuario_email" in request.form:
try:
usuario_email = safe_email(request.form["usuario_email"], search_fragment=True)
if usuario_email != "":
consulta = consulta.join(Usuario).filter(Usuario.email.contains(usuario_email))
except ValueError:
pass
# Ordenar y paginar
registros = consulta.order_by(EntradaSalida.id.desc()).offset(start).limit(rows_per_page).all()
total = consulta.count()
# Elaborar datos para DataTable
Expand All @@ -45,8 +67,6 @@ def datatable_json():


@entradas_salidas.route("/entradas_salidas")
@login_required
@permission_required(MODULO, Permiso.VER)
def list_active():
"""Listado de entradas y salidas"""
return render_template("entradas_salidas/list.jinja2")

0 comments on commit 0ca7518

Please sign in to comment.