Spaces:
Sleeping
Sleeping
Monitoero con PF y controlador para terminar sesion
Browse files- tecnicas/controllers/__init__.py +2 -0
- tecnicas/controllers/views_controller/session_management/details_pf_controller.py +35 -1
- tecnicas/controllers/views_controller/session_management/monitor_escalas_controller.py +0 -3
- tecnicas/controllers/views_controller/session_management/monitor_pf_controller.py +75 -0
- tecnicas/controllers/views_controller/session_management/monitor_rata_controller.py +0 -3
- tecnicas/migrations/0022_alter_sesionsensorial_codigo_sesion.py +19 -0
- tecnicas/migrations/0023_alter_sesionsensorial_codigo_sesion_listapalabras.py +30 -0
- tecnicas/models/__init__.py +3 -1
- tecnicas/models/lista_palabras.py +15 -0
- tecnicas/templates/tecnicas/manage_sesions/monitor-session-pf.html +126 -0
- tecnicas/views/sessions_management/session_details.py +7 -2
- tecnicas/views/sessions_management/session_monitor.py +19 -2
tecnicas/controllers/__init__.py
CHANGED
|
@@ -23,9 +23,11 @@ from .views_controller.session_management.details_escala_controller import Detal
|
|
| 23 |
from .views_controller.session_management.details_rata_controller import DetallesRATAController
|
| 24 |
from .views_controller.session_management.details_cata_controller import DetallesCATAController
|
| 25 |
from .views_controller.session_management.details_pf_controller import DetallesPFController
|
|
|
|
| 26 |
from .views_controller.session_management.monitor_controller import MonitorController
|
| 27 |
from .views_controller.session_management.monitor_escalas_controller import MonitorEscalasController
|
| 28 |
from .views_controller.session_management.monitor_rata_controller import MonitorRATAController
|
|
|
|
| 29 |
|
| 30 |
from .views_controller.sessions_tester.login_session_tester_controller import LoginSessionTesterController
|
| 31 |
from .views_controller.sessions_tester.init_session_tester_controller import InitSessionTesterController
|
|
|
|
| 23 |
from .views_controller.session_management.details_rata_controller import DetallesRATAController
|
| 24 |
from .views_controller.session_management.details_cata_controller import DetallesCATAController
|
| 25 |
from .views_controller.session_management.details_pf_controller import DetallesPFController
|
| 26 |
+
|
| 27 |
from .views_controller.session_management.monitor_controller import MonitorController
|
| 28 |
from .views_controller.session_management.monitor_escalas_controller import MonitorEscalasController
|
| 29 |
from .views_controller.session_management.monitor_rata_controller import MonitorRATAController
|
| 30 |
+
from .views_controller.session_management.monitor_pf_controller import MonitorPFController
|
| 31 |
|
| 32 |
from .views_controller.sessions_tester.login_session_tester_controller import LoginSessionTesterController
|
| 33 |
from .views_controller.sessions_tester.init_session_tester_controller import InitSessionTesterController
|
tecnicas/controllers/views_controller/session_management/details_pf_controller.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
| 1 |
-
from
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
from .details_controller import DetallesController
|
| 3 |
|
| 4 |
|
|
@@ -28,6 +32,36 @@ class DetallesPFController(DetallesController):
|
|
| 28 |
|
| 29 |
return self.context
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
def getStatus(self, rep: int, activate: bool):
|
| 32 |
status = ""
|
| 33 |
|
|
|
|
| 1 |
+
from django.http import HttpRequest
|
| 2 |
+
from django.shortcuts import redirect
|
| 3 |
+
from django.urls import reverse
|
| 4 |
+
from tecnicas.models import SesionSensorial, Presentador, Participacion
|
| 5 |
+
from tecnicas.controllers import ParticipacionController
|
| 6 |
from .details_controller import DetallesController
|
| 7 |
|
| 8 |
|
|
|
|
| 32 |
|
| 33 |
return self.context
|
| 34 |
|
| 35 |
+
def startRepetition(self, presenter: Presentador, request: HttpRequest):
|
| 36 |
+
creator = presenter
|
| 37 |
+
technique = self.session.tecnica
|
| 38 |
+
|
| 39 |
+
if creator.user.username != self.session.creadoPor.user.username:
|
| 40 |
+
return self.getResponse(error="Solo el presentador que crea la sesión puede iniciar la repetición o fase", request=request)
|
| 41 |
+
elif self.session.activo:
|
| 42 |
+
return self.getResponse(error="La sesión ya está activada", request=request)
|
| 43 |
+
|
| 44 |
+
there_participacions = Participacion.objects.filter(
|
| 45 |
+
tecnica=technique).exists()
|
| 46 |
+
|
| 47 |
+
if there_participacions:
|
| 48 |
+
(is_update_participations,
|
| 49 |
+
message) = ParticipacionController.outAllInSession(self.session)
|
| 50 |
+
if not is_update_participations:
|
| 51 |
+
return self.getResponse(error=message, request=request)
|
| 52 |
+
|
| 53 |
+
self.session.activo = True
|
| 54 |
+
technique.repeticion = technique.repeticion + 1
|
| 55 |
+
|
| 56 |
+
technique.save()
|
| 57 |
+
self.session.save()
|
| 58 |
+
|
| 59 |
+
parameters = {
|
| 60 |
+
"session_code": self.session.codigo_sesion
|
| 61 |
+
}
|
| 62 |
+
return redirect(
|
| 63 |
+
reverse(self.url_next, kwargs=parameters))
|
| 64 |
+
|
| 65 |
def getStatus(self, rep: int, activate: bool):
|
| 66 |
status = ""
|
| 67 |
|
tecnicas/controllers/views_controller/session_management/monitor_escalas_controller.py
CHANGED
|
@@ -1,6 +1,3 @@
|
|
| 1 |
-
from django.http import HttpRequest
|
| 2 |
-
from django.shortcuts import render, redirect
|
| 3 |
-
from django.urls import reverse
|
| 4 |
from tecnicas.models import Dato, Participacion
|
| 5 |
from tecnicas.controllers import SesionController
|
| 6 |
from .monitor_controller import MonitorController
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from tecnicas.models import Dato, Participacion
|
| 2 |
from tecnicas.controllers import SesionController
|
| 3 |
from .monitor_controller import MonitorController
|
tecnicas/controllers/views_controller/session_management/monitor_pf_controller.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.http import HttpRequest
|
| 2 |
+
from django.shortcuts import render, redirect
|
| 3 |
+
from django.urls import reverse
|
| 4 |
+
from tecnicas.models import Dato, Participacion, Catador, ListaPalabras, Producto
|
| 5 |
+
from tecnicas.controllers import SesionController
|
| 6 |
+
from .monitor_controller import MonitorController
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class MonitorPFController(MonitorController):
|
| 10 |
+
def __init__(self, session: SesionController):
|
| 11 |
+
super().__init__(session)
|
| 12 |
+
self.url_view = "tecnicas/manage_sesions/monitor-session-pf.html"
|
| 13 |
+
self.previus_view = "cata_system:detalles_sesion"
|
| 14 |
+
|
| 15 |
+
def checkAllFinish(self):
|
| 16 |
+
rep = self.sensorial_session.tecnica.repeticion
|
| 17 |
+
|
| 18 |
+
finish_data = ()
|
| 19 |
+
|
| 20 |
+
if rep == 1 or rep == 2:
|
| 21 |
+
finish_data = self.checkFinishFirstPhase()
|
| 22 |
+
elif rep >= 3:
|
| 23 |
+
finish_data = self.checkFinishRepetition()
|
| 24 |
+
|
| 25 |
+
return finish_data
|
| 26 |
+
|
| 27 |
+
def checkFinishFirstPhase(self):
|
| 28 |
+
num_paricipations = Participacion.objects.filter(
|
| 29 |
+
tecnica=self.sensorial_session.tecnica).count()
|
| 30 |
+
if num_paricipations < self.sensorial_session.tecnica.limite_catadores:
|
| 31 |
+
return (False, "No se ha alcanzado el número máximo de catadores")
|
| 32 |
+
|
| 33 |
+
unfinished_participations = Participacion.objects.filter(
|
| 34 |
+
tecnica=self.sensorial_session.tecnica, finalizado=False).count()
|
| 35 |
+
if not unfinished_participations or len(unfinished_participations) > 0:
|
| 36 |
+
return (False, "No todos los catadores han finalizado su evaluación")
|
| 37 |
+
|
| 38 |
+
return (True, "Puedes finalizar la sesión")
|
| 39 |
+
|
| 40 |
+
def checkFinishRepetition(self) -> tuple[bool, str]:
|
| 41 |
+
technique = self.sensorial_session.tecnica
|
| 42 |
+
|
| 43 |
+
# Revisar numero de catadores sea alcanzado
|
| 44 |
+
all_participations = list(
|
| 45 |
+
Participacion.objects.filter(tecnica=technique))
|
| 46 |
+
if len(all_participations) < technique.limite_catadores:
|
| 47 |
+
return (False, "No se ha alcanzado el número máximo de Catadores")
|
| 48 |
+
|
| 49 |
+
# Revisar que cada catador haya terminado de calificar sus palabras
|
| 50 |
+
for particiapation in all_participations:
|
| 51 |
+
expected_ratings_repetition = self.getExpectedRatings(
|
| 52 |
+
tester=particiapation.catador)
|
| 53 |
+
|
| 54 |
+
num_ratings_now = Dato.objects.filter(
|
| 55 |
+
id_calificacion__num_repeticion=technique.repeticion,
|
| 56 |
+
id_calificacion__id_catador=particiapation.catador,
|
| 57 |
+
id_calificacion__id_tecnica=technique
|
| 58 |
+
).count()
|
| 59 |
+
|
| 60 |
+
if num_ratings_now < expected_ratings_repetition:
|
| 61 |
+
return (False, "No todos los catadores han finalizado su evaluación")
|
| 62 |
+
|
| 63 |
+
return (True, "Puedes finalizar la sesión")
|
| 64 |
+
|
| 65 |
+
def getExpectedRatings(self, tester: Catador):
|
| 66 |
+
num_words = ListaPalabras.objects.get(
|
| 67 |
+
tecnica=self.sensorial_session.tecnica,
|
| 68 |
+
catador=tester,
|
| 69 |
+
es_final=True
|
| 70 |
+
).palabras.all().count()
|
| 71 |
+
|
| 72 |
+
num_products = Producto.objects.filter(
|
| 73 |
+
id_tecnica=self.sensorial_session.tecnica).count()
|
| 74 |
+
|
| 75 |
+
return num_products * num_words
|
tecnicas/controllers/views_controller/session_management/monitor_rata_controller.py
CHANGED
|
@@ -1,6 +1,3 @@
|
|
| 1 |
-
from django.http import HttpRequest
|
| 2 |
-
from django.shortcuts import render, redirect
|
| 3 |
-
from django.urls import reverse
|
| 4 |
from tecnicas.models import Dato, Participacion
|
| 5 |
from tecnicas.controllers import SesionController
|
| 6 |
from .monitor_controller import MonitorController
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from tecnicas.models import Dato, Participacion
|
| 2 |
from tecnicas.controllers import SesionController
|
| 3 |
from .monitor_controller import MonitorController
|
tecnicas/migrations/0022_alter_sesionsensorial_codigo_sesion.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated by Django 5.2.1 on 2025-11-12 20:16
|
| 2 |
+
|
| 3 |
+
import shortuuid.main
|
| 4 |
+
from django.db import migrations, models
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class Migration(migrations.Migration):
|
| 8 |
+
|
| 9 |
+
dependencies = [
|
| 10 |
+
('tecnicas', '0021_rename_nomre_vocabulario_vocabulario_nombre_vocabulario_and_more'),
|
| 11 |
+
]
|
| 12 |
+
|
| 13 |
+
operations = [
|
| 14 |
+
migrations.AlterField(
|
| 15 |
+
model_name='sesionsensorial',
|
| 16 |
+
name='codigo_sesion',
|
| 17 |
+
field=models.CharField(default=shortuuid.main.ShortUUID.uuid, editable=False, max_length=22, primary_key=True, serialize=False),
|
| 18 |
+
),
|
| 19 |
+
]
|
tecnicas/migrations/0023_alter_sesionsensorial_codigo_sesion_listapalabras.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated by Django 5.2.1 on 2025-11-12 20:24
|
| 2 |
+
|
| 3 |
+
import django.db.models.deletion
|
| 4 |
+
import shortuuid.main
|
| 5 |
+
from django.db import migrations, models
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class Migration(migrations.Migration):
|
| 9 |
+
|
| 10 |
+
dependencies = [
|
| 11 |
+
('tecnicas', '0022_alter_sesionsensorial_codigo_sesion'),
|
| 12 |
+
]
|
| 13 |
+
|
| 14 |
+
operations = [
|
| 15 |
+
migrations.AlterField(
|
| 16 |
+
model_name='sesionsensorial',
|
| 17 |
+
name='codigo_sesion',
|
| 18 |
+
field=models.CharField(default=shortuuid.main.ShortUUID.uuid, editable=False, max_length=22, primary_key=True, serialize=False),
|
| 19 |
+
),
|
| 20 |
+
migrations.CreateModel(
|
| 21 |
+
name='ListaPalabras',
|
| 22 |
+
fields=[
|
| 23 |
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
| 24 |
+
('es_final', models.BooleanField(default=False)),
|
| 25 |
+
('catador', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='catador_lista', to='tecnicas.catador')),
|
| 26 |
+
('palabras', models.ManyToManyField(related_name='lista_palabras', to='tecnicas.palabra')),
|
| 27 |
+
('tecnica', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tecnica_lista', to='tecnicas.tecnica')),
|
| 28 |
+
],
|
| 29 |
+
),
|
| 30 |
+
]
|
tecnicas/models/__init__.py
CHANGED
|
@@ -27,4 +27,6 @@ from .dato_valor import ValorBooleano
|
|
| 27 |
from .orden import Orden
|
| 28 |
from .orden import Posicion
|
| 29 |
|
| 30 |
-
from .participacion import Participacion
|
|
|
|
|
|
|
|
|
| 27 |
from .orden import Orden
|
| 28 |
from .orden import Posicion
|
| 29 |
|
| 30 |
+
from .participacion import Participacion
|
| 31 |
+
|
| 32 |
+
from .lista_palabras import ListaPalabras
|
tecnicas/models/lista_palabras.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.db import models
|
| 2 |
+
from tecnicas.models import Tecnica, Catador, Palabra
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
class ListaPalabras(models.Model):
|
| 6 |
+
tecnica = models.ForeignKey(
|
| 7 |
+
Tecnica, on_delete=models.CASCADE, related_name="tecnica_lista")
|
| 8 |
+
catador = models.ForeignKey(
|
| 9 |
+
Catador, on_delete=models.CASCADE, related_name="catador_lista")
|
| 10 |
+
es_final = models.BooleanField(default=False)
|
| 11 |
+
palabras = models.ManyToManyField(
|
| 12 |
+
Palabra, related_name="lista_palabras")
|
| 13 |
+
|
| 14 |
+
def __str__(self):
|
| 15 |
+
return f"{self.tecnica.codigo_sesion} - {self.catador.user.username}"
|
tecnicas/templates/tecnicas/manage_sesions/monitor-session-pf.html
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'tecnicas/layouts/base.html' %}
|
| 2 |
+
{% load static %}
|
| 3 |
+
|
| 4 |
+
{% block title %}Monitoreo{% endblock %}
|
| 5 |
+
|
| 6 |
+
{% block content %}
|
| 7 |
+
<article class="cts-container-main">
|
| 8 |
+
<article class="cts-wrap-content">
|
| 9 |
+
<header class="text-center">
|
| 10 |
+
<h1 class="text-3xl font-bold text-black">Sesión sensorial en curso</h1>
|
| 11 |
+
</header>
|
| 12 |
+
|
| 13 |
+
<section class="flex flex-col sm:flex-row justify-between items-center gap-10">
|
| 14 |
+
<p class="text-xl text-center bg-surface-card p-4 text-black rounded-lg shadow-lg">
|
| 15 |
+
Código de sesión:<br>
|
| 16 |
+
<span class="font-mono text-2xl font-bold">{{ code_session }}</span>
|
| 17 |
+
</p>
|
| 18 |
+
<div class="flex flex-col gap-2">
|
| 19 |
+
<button class="uppercase cts-btn-general-compress cts-btn-secondary py-2 px-6 btn-push"
|
| 20 |
+
onclick="finishSession()">
|
| 21 |
+
Finalizar sesión
|
| 22 |
+
</button>
|
| 23 |
+
<a href="{% url 'cata_system:detalles_sesion' session_code=code_session %}" class="w-full">
|
| 24 |
+
<button class="uppercase cts-btn-general-compress cts-btn-error py-2 px-6 btn-push w-full">
|
| 25 |
+
Regresar
|
| 26 |
+
</button>
|
| 27 |
+
</a>
|
| 28 |
+
</div>
|
| 29 |
+
</section>
|
| 30 |
+
|
| 31 |
+
<form action="" method="post" class="hidden action-form">
|
| 32 |
+
<input type="hidden" name="action">
|
| 33 |
+
{% csrf_token %}
|
| 34 |
+
</form>
|
| 35 |
+
|
| 36 |
+
{% if error %}
|
| 37 |
+
{% include "../components/error-message.html" with message=error %}
|
| 38 |
+
{% endif %}
|
| 39 |
+
|
| 40 |
+
{% if message %}
|
| 41 |
+
{% include "../components/error-message.html" with message=message %}
|
| 42 |
+
{% endif %}
|
| 43 |
+
|
| 44 |
+
<section aria-labelledby="catadores-titulo">
|
| 45 |
+
<article
|
| 46 |
+
class="flex max-sm:flex-col justify-around bg-surface-card border border-gray-300 rounded-md p-3 mb-4 items-center shadow-lg">
|
| 47 |
+
<button class="uppercase cts-btn-general-compress cts-btn-tertiary py-2 px-6 btn-push"
|
| 48 |
+
onclick="reloadPage()">
|
| 49 |
+
Actualizar lista
|
| 50 |
+
</button>
|
| 51 |
+
<h2 id="catadores-titulo" class="text-2xl text-center font-bold rounded-lg text-gray-700 py-2 px-3">
|
| 52 |
+
Catadores activos
|
| 53 |
+
</h2>
|
| 54 |
+
</article>
|
| 55 |
+
|
| 56 |
+
<article
|
| 57 |
+
class="flex flex-col justify-center gap-3 bg-surface-card border border-gray-300 rounded-md p-3 mb-4 text-lg max-sm:text-sm text-gray-700 shadow-lg">
|
| 58 |
+
<div class="flex justify-center items-center">
|
| 59 |
+
<h2 class="text-xl font-semibold">Participantes</h2>
|
| 60 |
+
</div>
|
| 61 |
+
<section class="flex flex-wrap justify-around items-center">
|
| 62 |
+
<div class="flex flex-col sm:flex-row sm:items-center sm:gap-2">
|
| 63 |
+
<span class="font-semibold">Máximo:</span>
|
| 64 |
+
<span>{{ max_testers }}</span>
|
| 65 |
+
</div>
|
| 66 |
+
<div class="flex flex-col sm:flex-row sm:items-center sm:gap-2">
|
| 67 |
+
<span class="font-semibold">
|
| 68 |
+
Actuales:
|
| 69 |
+
</span>
|
| 70 |
+
<span>{{ current_testers }}</span>
|
| 71 |
+
</div>
|
| 72 |
+
<div class="flex flex-col sm:flex-row sm:items-center sm:gap-2">
|
| 73 |
+
<span class="font-semibold">Activos:</span>
|
| 74 |
+
<span class="text-green-600 font-semibold">{{ active_testers }}</span>
|
| 75 |
+
</div>
|
| 76 |
+
</section>
|
| 77 |
+
</article>
|
| 78 |
+
|
| 79 |
+
<article class="max-sm:overflow-x-auto shadow-lg">
|
| 80 |
+
<div class="min-w-[400px] sm:min-w-0">
|
| 81 |
+
<div
|
| 82 |
+
class="grid grid-cols-4 bg-surface-sweet text-center font-semibold text-black text-sm rounded-t-lg max-sm:w-full [&_>*]:px-2">
|
| 83 |
+
<div class="py-2 border-r border-gray-400">Usuario</div>
|
| 84 |
+
<div class="py-2 border-r border-gray-400">Nombre</div>
|
| 85 |
+
<div class="py-2 border-r border-gray-400">Estado</div>
|
| 86 |
+
<div class="py-2">Finalizado</div>
|
| 87 |
+
</div>
|
| 88 |
+
|
| 89 |
+
<ul class="divide-y divide-gray-400 max-sm:w-full text-black">
|
| 90 |
+
{% for parti in participations %}
|
| 91 |
+
<li class="grid grid-cols-4 text-center bg-surface-card py-2 [&_>*]:px-2">
|
| 92 |
+
<p class="border-r border-gray-400">{{ parti.catador.user.username }}</p>
|
| 93 |
+
<p class="border-r border-gray-400">
|
| 94 |
+
{{ parti.catador.user.first_name }}
|
| 95 |
+
{{ parti.catador.user.last_name}}
|
| 96 |
+
</p>
|
| 97 |
+
|
| 98 |
+
{% if parti.activo %}
|
| 99 |
+
<p class="border-r border-gray-400 text-green-600 font-semibold">Activo</p>
|
| 100 |
+
{% else %}
|
| 101 |
+
<p class="border-r border-gray-400 text-red-500 font-semibold">No activo</p>
|
| 102 |
+
{% endif %}
|
| 103 |
+
|
| 104 |
+
{% if parti.finalizado %}
|
| 105 |
+
<p class="text-green-600 font-semibold">Si</p>
|
| 106 |
+
{% else %}
|
| 107 |
+
<p class="text-red-500 font-semibold">No</p>
|
| 108 |
+
{% endif %}
|
| 109 |
+
</li>
|
| 110 |
+
{% endfor %}
|
| 111 |
+
</ul>
|
| 112 |
+
</div>
|
| 113 |
+
</article>
|
| 114 |
+
</section>
|
| 115 |
+
</article>
|
| 116 |
+
</article>
|
| 117 |
+
{% endblock %}
|
| 118 |
+
|
| 119 |
+
{% block extra_js %}
|
| 120 |
+
<script>
|
| 121 |
+
function reloadPage () {
|
| 122 |
+
location.reload()
|
| 123 |
+
}
|
| 124 |
+
</script>
|
| 125 |
+
<script src="{% static 'js/finish-session.js' %}"></script>
|
| 126 |
+
{% endblock %}
|
tecnicas/views/sessions_management/session_details.py
CHANGED
|
@@ -55,16 +55,21 @@ def sessionDetails(req: HttpRequest, session_code: str):
|
|
| 55 |
if req.POST["action"] == "start_session":
|
| 56 |
response = controller_view.startRepetition(
|
| 57 |
presenter=req.user.user_presentador, request=req)
|
|
|
|
| 58 |
elif req.POST.get("action") == "delete_session":
|
| 59 |
controller_view.deleteSesorialSession()
|
| 60 |
response = redirect(
|
| 61 |
reverse("cata_system:panel_sesiones", kwargs={"page": 1}))
|
|
|
|
| 62 |
else:
|
| 63 |
response = controller_view.getResponse(
|
| 64 |
error="No se reconoce la acción a realizar")
|
|
|
|
| 65 |
elif use_techinique == "perfil flash":
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
| 68 |
else:
|
| 69 |
response = noValidTechnique()
|
| 70 |
|
|
|
|
| 55 |
if req.POST["action"] == "start_session":
|
| 56 |
response = controller_view.startRepetition(
|
| 57 |
presenter=req.user.user_presentador, request=req)
|
| 58 |
+
|
| 59 |
elif req.POST.get("action") == "delete_session":
|
| 60 |
controller_view.deleteSesorialSession()
|
| 61 |
response = redirect(
|
| 62 |
reverse("cata_system:panel_sesiones", kwargs={"page": 1}))
|
| 63 |
+
|
| 64 |
else:
|
| 65 |
response = controller_view.getResponse(
|
| 66 |
error="No se reconoce la acción a realizar")
|
| 67 |
+
|
| 68 |
elif use_techinique == "perfil flash":
|
| 69 |
+
controller_view = DetallesPFController(session=sensorial_session)
|
| 70 |
+
response = controller_view.startRepetition(
|
| 71 |
+
presenter=req.user.user_presentador, request=req)
|
| 72 |
+
|
| 73 |
else:
|
| 74 |
response = noValidTechnique()
|
| 75 |
|
tecnicas/views/sessions_management/session_monitor.py
CHANGED
|
@@ -3,12 +3,11 @@ Para finalizar la sesion se debe realizar lo siguiente
|
|
| 3 |
# Obtener todas las participaciones
|
| 4 |
|
| 5 |
'''
|
| 6 |
-
|
| 7 |
from django.http import HttpRequest, JsonResponse
|
| 8 |
from django.shortcuts import render, redirect
|
| 9 |
from django.urls import reverse
|
| 10 |
from tecnicas.models import SesionSensorial
|
| 11 |
-
from tecnicas.controllers import MonitorEscalasController, MonitorRATAController
|
| 12 |
from tecnicas.utils import noValidTechnique
|
| 13 |
|
| 14 |
|
|
@@ -21,6 +20,11 @@ def sessionMonitor(req: HttpRequest, session_code: str):
|
|
| 21 |
if use_techinique == "escalas" or use_techinique == "rata" or use_techinique == "cata":
|
| 22 |
controll_view = MonitorEscalasController(sensorial_session)
|
| 23 |
response = controll_view.controllGetResponse(request=req)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
else:
|
| 25 |
response = noValidTechnique(
|
| 26 |
params={
|
|
@@ -47,6 +51,7 @@ def sessionMonitor(req: HttpRequest, session_code: str):
|
|
| 47 |
else:
|
| 48 |
response = controll_view.controlGetResponse(
|
| 49 |
request=req, error="No se ha definido la acción a realizar")
|
|
|
|
| 50 |
elif use_techinique == "rata" or use_techinique == "cata":
|
| 51 |
controll_view = MonitorRATAController(sensorial_session)
|
| 52 |
action = req.POST["action"]
|
|
@@ -57,6 +62,18 @@ def sessionMonitor(req: HttpRequest, session_code: str):
|
|
| 57 |
else:
|
| 58 |
response = controll_view.controlGetResponse(
|
| 59 |
request=req, error="No se ha definido la acción a realizar")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
else:
|
| 61 |
response = noValidTechnique(
|
| 62 |
params={
|
|
|
|
| 3 |
# Obtener todas las participaciones
|
| 4 |
|
| 5 |
'''
|
|
|
|
| 6 |
from django.http import HttpRequest, JsonResponse
|
| 7 |
from django.shortcuts import render, redirect
|
| 8 |
from django.urls import reverse
|
| 9 |
from tecnicas.models import SesionSensorial
|
| 10 |
+
from tecnicas.controllers import MonitorEscalasController, MonitorRATAController, MonitorPFController
|
| 11 |
from tecnicas.utils import noValidTechnique
|
| 12 |
|
| 13 |
|
|
|
|
| 20 |
if use_techinique == "escalas" or use_techinique == "rata" or use_techinique == "cata":
|
| 21 |
controll_view = MonitorEscalasController(sensorial_session)
|
| 22 |
response = controll_view.controllGetResponse(request=req)
|
| 23 |
+
|
| 24 |
+
elif use_techinique == "perfil flash":
|
| 25 |
+
controll_view = MonitorPFController(sensorial_session)
|
| 26 |
+
response = controll_view.controllGetResponse(request=req)
|
| 27 |
+
|
| 28 |
else:
|
| 29 |
response = noValidTechnique(
|
| 30 |
params={
|
|
|
|
| 51 |
else:
|
| 52 |
response = controll_view.controlGetResponse(
|
| 53 |
request=req, error="No se ha definido la acción a realizar")
|
| 54 |
+
|
| 55 |
elif use_techinique == "rata" or use_techinique == "cata":
|
| 56 |
controll_view = MonitorRATAController(sensorial_session)
|
| 57 |
action = req.POST["action"]
|
|
|
|
| 62 |
else:
|
| 63 |
response = controll_view.controlGetResponse(
|
| 64 |
request=req, error="No se ha definido la acción a realizar")
|
| 65 |
+
|
| 66 |
+
elif use_techinique == "perfil flash":
|
| 67 |
+
controll_view = MonitorPFController(sensorial_session)
|
| 68 |
+
action = req.POST["action"]
|
| 69 |
+
|
| 70 |
+
if action == "finish_session":
|
| 71 |
+
response = controll_view.controllPostFinishSession(
|
| 72 |
+
request=req)
|
| 73 |
+
else:
|
| 74 |
+
response = controll_view.controlGetResponse(
|
| 75 |
+
request=req, error="No se ha definido la acción a realizar")
|
| 76 |
+
|
| 77 |
else:
|
| 78 |
response = noValidTechnique(
|
| 79 |
params={
|