Spaces:
Sleeping
Sleeping
Merge pull request #13 from CascoArcilla/HU4
Browse files- tecnicas/controllers/models_controller/calificacion_controller.py +2 -7
- tecnicas/controllers/models_controller/dato_controller.py +25 -2
- tecnicas/controllers/models_controller/particiapacion_controller.py +30 -7
- tecnicas/controllers/models_controller/sesion_controller.py +23 -3
- tecnicas/controllers/models_controller/tecnica_controller.py +2 -2
- tecnicas/controllers/views_controller/detalles_sesion_controller.py +59 -13
- tecnicas/controllers/views_controller/main_tester_form_controller.py +2 -5
- tecnicas/controllers/views_controller/monitor_sesion_controller.py +52 -2
- tecnicas/models/dato.py +8 -2
- tecnicas/models/dato_valor.py +8 -4
- tecnicas/static/js/finish-session.js +5 -0
- tecnicas/templates/tecnicas/components/error-message.html +5 -0
- tecnicas/templates/tecnicas/components/table-convencional.html +47 -0
- tecnicas/templates/tecnicas/manage_sesions/detalles-sesion.html +14 -17
- tecnicas/templates/tecnicas/manage_sesions/monitor-sesion.html +23 -7
- tecnicas/templates/tecnicas/manage_sesions/sesiones-panel.html +1 -1
- tecnicas/utils/__init__.py +2 -1
- tecnicas/utils/to_dict.py +9 -0
- tecnicas/views/sessions_management/session_details.py +5 -3
- tecnicas/views/sessions_management/session_monitor.py +32 -5
- theme/static_src/tailwind.config.js +1 -1
tecnicas/controllers/models_controller/calificacion_controller.py
CHANGED
|
@@ -48,14 +48,9 @@ class CalificacionController():
|
|
| 48 |
if not repetition:
|
| 49 |
return {"error": "sin datos calficados aun"}
|
| 50 |
|
| 51 |
-
|
| 52 |
|
| 53 |
-
|
| 54 |
-
response_data = Calificacion.objects.filter(
|
| 55 |
-
id_tecnica=technique, num_repeticion=i+1)
|
| 56 |
-
data_rating[f"repeticion_{i+1}"] = response_data
|
| 57 |
-
|
| 58 |
-
return data_rating
|
| 59 |
|
| 60 |
@staticmethod
|
| 61 |
def getRatings(
|
|
|
|
| 48 |
if not repetition:
|
| 49 |
return {"error": "sin datos calficados aun"}
|
| 50 |
|
| 51 |
+
ratings = list(Calificacion.objects.filter(id_tecnica=technique))
|
| 52 |
|
| 53 |
+
return ratings
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
@staticmethod
|
| 56 |
def getRatings(
|
tecnicas/controllers/models_controller/dato_controller.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
-
from ...models import Calificacion, Dato, Palabra, ValorDecimal, ValorBooleano
|
| 2 |
from ...utils import controller_error, getId
|
| 3 |
from django.core.exceptions import ValidationError
|
|
|
|
| 4 |
|
| 5 |
|
| 6 |
class DatoController():
|
|
@@ -36,7 +37,7 @@ class DatoController():
|
|
| 36 |
|
| 37 |
def setInstanceValue(self):
|
| 38 |
technique = self.data.id_calificacion.id_tecnica
|
| 39 |
-
|
| 40 |
if technique.tipo_tecnica == "cata":
|
| 41 |
self.value_data = ValorBooleano(
|
| 42 |
id_dato=self.data,
|
|
@@ -72,3 +73,25 @@ class DatoController():
|
|
| 72 |
id_calificacion_id__in=ids_ratings))
|
| 73 |
|
| 74 |
return recoreded_data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from ...models import Calificacion, Dato, Palabra, ValorDecimal, ValorBooleano, Tecnica
|
| 2 |
from ...utils import controller_error, getId
|
| 3 |
from django.core.exceptions import ValidationError
|
| 4 |
+
from django.db.models import F
|
| 5 |
|
| 6 |
|
| 7 |
class DatoController():
|
|
|
|
| 37 |
|
| 38 |
def setInstanceValue(self):
|
| 39 |
technique = self.data.id_calificacion.id_tecnica
|
| 40 |
+
|
| 41 |
if technique.tipo_tecnica == "cata":
|
| 42 |
self.value_data = ValorBooleano(
|
| 43 |
id_dato=self.data,
|
|
|
|
| 73 |
id_calificacion_id__in=ids_ratings))
|
| 74 |
|
| 75 |
return recoreded_data
|
| 76 |
+
|
| 77 |
+
@staticmethod
|
| 78 |
+
def getWordValuesForConvecional(technique: Tecnica, ratings: list[Calificacion]):
|
| 79 |
+
model = ValorBooleano if technique.tipo_tecnica == "cata" else ValorDecimal
|
| 80 |
+
|
| 81 |
+
ids_ratings = [rat.id for rat in ratings]
|
| 82 |
+
|
| 83 |
+
result = (
|
| 84 |
+
model.objects
|
| 85 |
+
.filter(id_dato__id_calificacion_id__in=ids_ratings)
|
| 86 |
+
.values(
|
| 87 |
+
nombre_palabra=F("id_dato__id_palabra__nombre_palabra"),
|
| 88 |
+
repeticion=F("id_dato__id_calificacion__num_repeticion"),
|
| 89 |
+
producto_code=F(
|
| 90 |
+
"id_dato__id_calificacion__id_producto__codigoProducto"),
|
| 91 |
+
usuarioCatador=F(
|
| 92 |
+
"id_dato__id_calificacion__id_catador__usuarioCatador"),
|
| 93 |
+
dato_valor=F("valor")
|
| 94 |
+
)
|
| 95 |
+
)
|
| 96 |
+
|
| 97 |
+
return list(result)
|
tecnicas/controllers/models_controller/particiapacion_controller.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
from ...models import Participacion, Tecnica
|
| 2 |
from ...utils import controller_error
|
| 3 |
|
| 4 |
|
|
@@ -13,7 +13,7 @@ class ParticipacionController():
|
|
| 13 |
return participation
|
| 14 |
except Participacion.DoesNotExist:
|
| 15 |
return controller_error("No se ha encontrado la participación")
|
| 16 |
-
|
| 17 |
@staticmethod
|
| 18 |
def finishSession(id_participation: int):
|
| 19 |
try:
|
|
@@ -24,7 +24,7 @@ class ParticipacionController():
|
|
| 24 |
return participation
|
| 25 |
except Participacion.DoesNotExist:
|
| 26 |
return controller_error("No se ha encontrado la participación")
|
| 27 |
-
|
| 28 |
@staticmethod
|
| 29 |
def outSession(id_participation: int):
|
| 30 |
try:
|
|
@@ -34,9 +34,33 @@ class ParticipacionController():
|
|
| 34 |
return participation
|
| 35 |
except Participacion.DoesNotExist:
|
| 36 |
return controller_error("No se ha encontrado la participación")
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
@staticmethod
|
| 39 |
-
def getParticipationsInTechinique(technique: Tecnica| int):
|
| 40 |
filters = {}
|
| 41 |
|
| 42 |
if isinstance(technique, int):
|
|
@@ -44,5 +68,4 @@ class ParticipacionController():
|
|
| 44 |
else:
|
| 45 |
filters["tecnica"] = technique
|
| 46 |
|
| 47 |
-
|
| 48 |
-
return participations
|
|
|
|
| 1 |
+
from ...models import Participacion, Tecnica, SesionSensorial
|
| 2 |
from ...utils import controller_error
|
| 3 |
|
| 4 |
|
|
|
|
| 13 |
return participation
|
| 14 |
except Participacion.DoesNotExist:
|
| 15 |
return controller_error("No se ha encontrado la participación")
|
| 16 |
+
|
| 17 |
@staticmethod
|
| 18 |
def finishSession(id_participation: int):
|
| 19 |
try:
|
|
|
|
| 24 |
return participation
|
| 25 |
except Participacion.DoesNotExist:
|
| 26 |
return controller_error("No se ha encontrado la participación")
|
| 27 |
+
|
| 28 |
@staticmethod
|
| 29 |
def outSession(id_participation: int):
|
| 30 |
try:
|
|
|
|
| 34 |
return participation
|
| 35 |
except Participacion.DoesNotExist:
|
| 36 |
return controller_error("No se ha encontrado la participación")
|
| 37 |
+
|
| 38 |
+
@staticmethod
|
| 39 |
+
def outAllInSession(session: SesionSensorial | str):
|
| 40 |
+
try:
|
| 41 |
+
if isinstance(session, str):
|
| 42 |
+
use_session = SesionSensorial.objects.get(
|
| 43 |
+
codigo_sesion=session)
|
| 44 |
+
else:
|
| 45 |
+
use_session = session
|
| 46 |
+
|
| 47 |
+
participations = Participacion.objects.filter(
|
| 48 |
+
tecnica=use_session.tecnica)
|
| 49 |
+
|
| 50 |
+
if not participations.exists():
|
| 51 |
+
message = "No se encontraron participaciones en la sesión"
|
| 52 |
+
return (False, message)
|
| 53 |
+
|
| 54 |
+
participations.update(finalizado=False)
|
| 55 |
+
|
| 56 |
+
message = "Participaciones actualizadas a finalizadas"
|
| 57 |
+
return (True, message)
|
| 58 |
+
except Exception as e:
|
| 59 |
+
print(f"Error al actualizar las participaciones: {str(e)}")
|
| 60 |
+
return (False, "Error al actualizar las participaciones")
|
| 61 |
+
|
| 62 |
@staticmethod
|
| 63 |
+
def getParticipationsInTechinique(technique: Tecnica | int):
|
| 64 |
filters = {}
|
| 65 |
|
| 66 |
if isinstance(technique, int):
|
|
|
|
| 68 |
else:
|
| 69 |
filters["tecnica"] = technique
|
| 70 |
|
| 71 |
+
return list(Participacion.objects.filter(**filters))
|
|
|
tecnicas/controllers/models_controller/sesion_controller.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
| 1 |
from django.db import DatabaseError
|
| 2 |
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
| 3 |
-
from
|
| 4 |
-
from
|
|
|
|
| 5 |
|
| 6 |
|
| 7 |
class SesionController():
|
|
@@ -91,7 +92,7 @@ class SesionController():
|
|
| 91 |
return session
|
| 92 |
except SesionSensorial.DoesNotExist:
|
| 93 |
return controller_error("La sesión ya no existe")
|
| 94 |
-
|
| 95 |
@staticmethod
|
| 96 |
def getSessionByCode(code: str):
|
| 97 |
try:
|
|
@@ -111,3 +112,22 @@ class SesionController():
|
|
| 111 |
return number_sessions/9
|
| 112 |
except Presentador.DoesNotExist:
|
| 113 |
return controller_error("presentador invalido")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from django.db import DatabaseError
|
| 2 |
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
| 3 |
+
from tecnicas.models import Tecnica, Presentador, SesionSensorial
|
| 4 |
+
from tecnicas.utils import controller_error
|
| 5 |
+
from ..models_controller.particiapacion_controller import ParticipacionController
|
| 6 |
|
| 7 |
|
| 8 |
class SesionController():
|
|
|
|
| 92 |
return session
|
| 93 |
except SesionSensorial.DoesNotExist:
|
| 94 |
return controller_error("La sesión ya no existe")
|
| 95 |
+
|
| 96 |
@staticmethod
|
| 97 |
def getSessionByCode(code: str):
|
| 98 |
try:
|
|
|
|
| 112 |
return number_sessions/9
|
| 113 |
except Presentador.DoesNotExist:
|
| 114 |
return controller_error("presentador invalido")
|
| 115 |
+
|
| 116 |
+
@staticmethod
|
| 117 |
+
def finishRepetion(session: SesionSensorial | str):
|
| 118 |
+
if isinstance(session, str):
|
| 119 |
+
use_session = SesionSensorial.objects.get(codigo_sesion=session)
|
| 120 |
+
else:
|
| 121 |
+
use_session = session
|
| 122 |
+
|
| 123 |
+
(is_update_participations,
|
| 124 |
+
message) = ParticipacionController.outAllInSession(use_session)
|
| 125 |
+
|
| 126 |
+
if not is_update_participations:
|
| 127 |
+
return controller_error(message)
|
| 128 |
+
|
| 129 |
+
use_session.activo = False
|
| 130 |
+
|
| 131 |
+
use_session.save()
|
| 132 |
+
|
| 133 |
+
return session
|
tecnicas/controllers/models_controller/tecnica_controller.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
-
from
|
| 2 |
from django.db import DatabaseError
|
| 3 |
-
from
|
| 4 |
|
| 5 |
|
| 6 |
class TecnicaController():
|
|
|
|
| 1 |
+
from tecnicas.models import TipoTecnica, CategoriaTecnica, Tecnica, EstiloPalabra
|
| 2 |
from django.db import DatabaseError
|
| 3 |
+
from tecnicas.utils import controller_error
|
| 4 |
|
| 5 |
|
| 6 |
class TecnicaController():
|
tecnicas/controllers/views_controller/detalles_sesion_controller.py
CHANGED
|
@@ -1,24 +1,70 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
from .. import CalificacionController, PalabrasController
|
| 3 |
from ...utils import controller_error
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
|
| 6 |
class DetallesSesionController():
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
|
|
|
|
|
|
| 10 |
|
| 11 |
-
|
| 12 |
-
context["sesion"] = session
|
| 13 |
|
| 14 |
-
words = PalabrasController.getWordsInTechnique(
|
| 15 |
-
|
|
|
|
| 16 |
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
context["calificaciones"] = rating
|
| 20 |
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
@staticmethod
|
| 24 |
def startRepetition(session_code: str, username: str):
|
|
@@ -45,5 +91,5 @@ class DetallesSesionController():
|
|
| 45 |
|
| 46 |
technique.save()
|
| 47 |
session.save()
|
| 48 |
-
|
| 49 |
return session
|
|
|
|
| 1 |
+
'''
|
| 2 |
+
|
| 3 |
+
Para Tecnicas Convencionales, CATA, RATA, Escala Hedonica
|
| 4 |
+
Encabezados de como deben de aparecer los datos por repeticion
|
| 5 |
+
|
| 6 |
+
| Repeticion: R
|
| 7 |
+
| Codigo Producto | Catador | P1 | P2 | P3 | Pn |
|
| 8 |
+
|
| 9 |
+
Encabezados de como deben de aparecer los datos juntos
|
| 10 |
+
|
| 11 |
+
| Repeticion | Codigo Producto | Catador | P1 | P2 | P3 | Pn |
|
| 12 |
+
|
| 13 |
+
'''
|
| 14 |
+
|
| 15 |
+
from ...models import SesionSensorial, Presentador, Tecnica, Palabra
|
| 16 |
from .. import CalificacionController, PalabrasController
|
| 17 |
from ...utils import controller_error
|
| 18 |
+
from collections import defaultdict
|
| 19 |
+
from tecnicas.controllers import DatoController
|
| 20 |
+
from tecnicas.utils import defaultdict_to_dict
|
| 21 |
|
| 22 |
|
| 23 |
class DetallesSesionController():
|
| 24 |
+
def __init__(self, session_code: str):
|
| 25 |
+
self.session = SesionSensorial.objects.get(codigo_sesion=session_code)
|
| 26 |
+
|
| 27 |
+
def getContextForView(self):
|
| 28 |
+
self.context = {}
|
| 29 |
|
| 30 |
+
self.context["sesion"] = self.session
|
|
|
|
| 31 |
|
| 32 |
+
self.words = PalabrasController.getWordsInTechnique(
|
| 33 |
+
self.session.tecnica)
|
| 34 |
+
self.context["palabras"] = [word.nombre_palabra for word in self.words]
|
| 35 |
|
| 36 |
+
def getContextWithData(self):
|
| 37 |
+
ratings_for_repetition = []
|
|
|
|
| 38 |
|
| 39 |
+
ratings = CalificacionController.getRatingsByTechnique(
|
| 40 |
+
technique=self.session.tecnica)
|
| 41 |
+
|
| 42 |
+
if isinstance(ratings, dict) or not ratings:
|
| 43 |
+
self.context["calificaciones"] = ratings_for_repetition
|
| 44 |
+
self.context["existen_calificaciones"] = False
|
| 45 |
+
return self.context
|
| 46 |
+
|
| 47 |
+
data = DatoController.getWordValuesForConvecional(
|
| 48 |
+
ratings=ratings, technique=self.session.tecnica)
|
| 49 |
+
|
| 50 |
+
ratings_for_repetition = defaultdict(
|
| 51 |
+
lambda: defaultdict(lambda: defaultdict(list)))
|
| 52 |
+
|
| 53 |
+
for item in data:
|
| 54 |
+
user = item["usuarioCatador"]
|
| 55 |
+
rep = item["repeticion"]
|
| 56 |
+
prod = item["producto_code"]
|
| 57 |
+
|
| 58 |
+
ratings_for_repetition[rep][user][prod].append({
|
| 59 |
+
"nombre_palabra": item["nombre_palabra"],
|
| 60 |
+
"dato_valor": item["dato_valor"]
|
| 61 |
+
})
|
| 62 |
+
|
| 63 |
+
self.context["calificaciones"] = defaultdict_to_dict(
|
| 64 |
+
ratings_for_repetition)
|
| 65 |
+
self.context["existen_calificaciones"] = True
|
| 66 |
+
|
| 67 |
+
return self.context
|
| 68 |
|
| 69 |
@staticmethod
|
| 70 |
def startRepetition(session_code: str, username: str):
|
|
|
|
| 91 |
|
| 92 |
technique.save()
|
| 93 |
session.save()
|
| 94 |
+
|
| 95 |
return session
|
tecnicas/controllers/views_controller/main_tester_form_controller.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
from
|
| 2 |
from ...utils import controller_error, shuffleArray
|
| 3 |
from django.db import transaction
|
| 4 |
|
|
@@ -45,15 +45,12 @@ class MainTesterFormController():
|
|
| 45 |
return controller_error("Catador sin orden")
|
| 46 |
|
| 47 |
def isEndedSession(self, id_participation: int, repetition: int):
|
| 48 |
-
if not self.order or not id_participation:
|
| 49 |
-
return controller_error("Se requieren datos para comprobar la finalización")
|
| 50 |
-
|
| 51 |
try:
|
| 52 |
participation = Participacion.objects.get(id=id_participation)
|
| 53 |
|
| 54 |
# ////////////////////////////////////////////////////////////// #
|
| 55 |
#
|
| 56 |
-
# Si numero_calificaciones_esperadas =
|
| 57 |
# Es igual a numero_calificaciones_actuales en la repetcion R
|
| 58 |
# Ha terminado la repeticion
|
| 59 |
#
|
|
|
|
| 1 |
+
from tecnicas.models import Catador, SesionSensorial, Orden, Participacion, Producto, EsAtributo, Calificacion, EsVocabulario
|
| 2 |
from ...utils import controller_error, shuffleArray
|
| 3 |
from django.db import transaction
|
| 4 |
|
|
|
|
| 45 |
return controller_error("Catador sin orden")
|
| 46 |
|
| 47 |
def isEndedSession(self, id_participation: int, repetition: int):
|
|
|
|
|
|
|
|
|
|
| 48 |
try:
|
| 49 |
participation = Participacion.objects.get(id=id_participation)
|
| 50 |
|
| 51 |
# ////////////////////////////////////////////////////////////// #
|
| 52 |
#
|
| 53 |
+
# Si numero_calificaciones_esperadas = num_productos * num_palabras
|
| 54 |
# Es igual a numero_calificaciones_actuales en la repetcion R
|
| 55 |
# Ha terminado la repeticion
|
| 56 |
#
|
tecnicas/controllers/views_controller/monitor_sesion_controller.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
-
from tecnicas.models import SesionSensorial
|
| 2 |
-
from tecnicas.controllers import ParticipacionController
|
| 3 |
from tecnicas.utils import controller_error
|
| 4 |
|
| 5 |
|
|
@@ -7,6 +7,10 @@ class MonitorSesionController():
|
|
| 7 |
def __init__(self, session_code: str):
|
| 8 |
self.code_session = session_code
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
def monitorView(self):
|
| 11 |
try:
|
| 12 |
self.sensorial_session = SesionSensorial.objects.select_related(
|
|
@@ -30,3 +34,49 @@ class MonitorSesionController():
|
|
| 30 |
}
|
| 31 |
|
| 32 |
return context
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from tecnicas.models import SesionSensorial, EsAtributo, EsVocabulario, Producto, Calificacion
|
| 2 |
+
from tecnicas.controllers import ParticipacionController, SesionController
|
| 3 |
from tecnicas.utils import controller_error
|
| 4 |
|
| 5 |
|
|
|
|
| 7 |
def __init__(self, session_code: str):
|
| 8 |
self.code_session = session_code
|
| 9 |
|
| 10 |
+
def defineSession(self):
|
| 11 |
+
self.session = SesionSensorial.objects.get(
|
| 12 |
+
codigo_sesion=self.code_session)
|
| 13 |
+
|
| 14 |
def monitorView(self):
|
| 15 |
try:
|
| 16 |
self.sensorial_session = SesionSensorial.objects.select_related(
|
|
|
|
| 34 |
}
|
| 35 |
|
| 36 |
return context
|
| 37 |
+
|
| 38 |
+
def getExpectedRatings(self):
|
| 39 |
+
num_products = Producto.objects.filter(
|
| 40 |
+
id_tecnica=self.session.tecnica).count()
|
| 41 |
+
|
| 42 |
+
style_words = self.session.tecnica.id_estilo
|
| 43 |
+
|
| 44 |
+
num_words: int
|
| 45 |
+
|
| 46 |
+
if style_words.nombre_estilo == "atributos":
|
| 47 |
+
num_words = EsAtributo.objects.get(
|
| 48 |
+
id_tecnica=self.session.tecnica).palabras.count()
|
| 49 |
+
elif style_words.nombre_estilo == "vocabulario":
|
| 50 |
+
num_words = EsVocabulario.objects.get(
|
| 51 |
+
id_tecnica=self.session.tecnica).id_vocabulario.palabras.count()
|
| 52 |
+
|
| 53 |
+
return num_products * num_words
|
| 54 |
+
|
| 55 |
+
def checkAllParticipantsEnded(self):
|
| 56 |
+
self.defineSession()
|
| 57 |
+
|
| 58 |
+
technique = self.session.tecnica
|
| 59 |
+
|
| 60 |
+
expected_ratings_repetition = self.getExpectedRatings()
|
| 61 |
+
|
| 62 |
+
all_participations = ParticipacionController.getParticipationsInTechinique(
|
| 63 |
+
technique=technique)
|
| 64 |
+
|
| 65 |
+
if len(all_participations) < technique.limite_catadores:
|
| 66 |
+
return (False, "No se ha alcanzado el número máximo de Catadores")
|
| 67 |
+
|
| 68 |
+
for particiapation in all_participations:
|
| 69 |
+
num_ratings_now = Calificacion.objects.filter(
|
| 70 |
+
id_tecnica=technique, id_catador=particiapation.catador, num_repeticion=technique.repeticion).count()
|
| 71 |
+
|
| 72 |
+
if num_ratings_now < expected_ratings_repetition:
|
| 73 |
+
return (False, "No todos los catadores han finalizado su evaluación")
|
| 74 |
+
|
| 75 |
+
return (True, "Puedes finalizar la sesión")
|
| 76 |
+
|
| 77 |
+
def finishSession(self):
|
| 78 |
+
response = SesionController.finishRepetion(self.session)
|
| 79 |
+
if isinstance(response, dict):
|
| 80 |
+
return controller_error(response["error"])
|
| 81 |
+
self.defineSession()
|
| 82 |
+
return self.session
|
tecnicas/models/dato.py
CHANGED
|
@@ -3,6 +3,12 @@ from django.db import models
|
|
| 3 |
from .palabra import Palabra
|
| 4 |
from .calificacion import Calificacion
|
| 5 |
|
|
|
|
| 6 |
class Dato(models.Model):
|
| 7 |
-
id_palabra = models.ForeignKey(
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
from .palabra import Palabra
|
| 4 |
from .calificacion import Calificacion
|
| 5 |
|
| 6 |
+
|
| 7 |
class Dato(models.Model):
|
| 8 |
+
id_palabra = models.ForeignKey(
|
| 9 |
+
Palabra, on_delete=models.CASCADE, related_name="dato_palabra")
|
| 10 |
+
id_calificacion = models.ForeignKey(
|
| 11 |
+
Calificacion, on_delete=models.CASCADE, related_name="dato_calificacion")
|
| 12 |
+
|
| 13 |
+
def __str__(self):
|
| 14 |
+
return f"{self.id_palabra.nombre_palabra} - {self.id_calificacion.id_producto.codigoProducto} - {self.id_calificacion.id_catador.usuarioCatador}"
|
tecnicas/models/dato_valor.py
CHANGED
|
@@ -2,16 +2,20 @@ from django.db import models
|
|
| 2 |
|
| 3 |
from .dato import Dato
|
| 4 |
|
|
|
|
| 5 |
class ValorDecimal(models.Model):
|
| 6 |
-
id_dato = models.OneToOneField(
|
|
|
|
| 7 |
valor = models.FloatField()
|
| 8 |
|
| 9 |
def __str__(self):
|
| 10 |
-
return f"{self.id} - {self.id_dato.id_palabra}: {self.valor}"
|
|
|
|
| 11 |
|
| 12 |
class ValorBooleano(models.Model):
|
| 13 |
-
id_dato = models.OneToOneField(
|
|
|
|
| 14 |
valor = models.BooleanField()
|
| 15 |
|
| 16 |
def __str__(self):
|
| 17 |
-
return f"{self.id} - {self.id_dato.id_palabra}: {self.valor}"
|
|
|
|
| 2 |
|
| 3 |
from .dato import Dato
|
| 4 |
|
| 5 |
+
|
| 6 |
class ValorDecimal(models.Model):
|
| 7 |
+
id_dato = models.OneToOneField(
|
| 8 |
+
Dato, on_delete=models.CASCADE, related_name="dato_decimal")
|
| 9 |
valor = models.FloatField()
|
| 10 |
|
| 11 |
def __str__(self):
|
| 12 |
+
return f"{self.id} - {self.id_dato.id_palabra}: {self.valor} - {self.id_dato.id_calificacion.id_catador.usuarioCatador}"
|
| 13 |
+
|
| 14 |
|
| 15 |
class ValorBooleano(models.Model):
|
| 16 |
+
id_dato = models.OneToOneField(
|
| 17 |
+
Dato, on_delete=models.CASCADE, related_name="dato_boolean")
|
| 18 |
valor = models.BooleanField()
|
| 19 |
|
| 20 |
def __str__(self):
|
| 21 |
+
return f"{self.id} - {self.id_dato.id_palabra}: {self.valor} - {self.id_dato.id_calificacion.id_catador.usuarioCatador}"
|
tecnicas/static/js/finish-session.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
function finishSession() {
|
| 2 |
+
const form = document.querySelector(".action-form");
|
| 3 |
+
form.querySelector("input").value = "finish_session";
|
| 4 |
+
form.submit();
|
| 5 |
+
}
|
tecnicas/templates/tecnicas/components/error-message.html
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<article class="bg-surface-ligt border-b-2 border-ct-success p-4 text-black rounded cts-message shadow-lg">
|
| 2 |
+
<p class="font-sans text-xl text-center">
|
| 3 |
+
{{ message }}
|
| 4 |
+
</p>
|
| 5 |
+
</article>
|
tecnicas/templates/tecnicas/components/table-convencional.html
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<section>
|
| 2 |
+
<h2 class="text-lg font-bold mb-3">Repetición {{ repeticion }}</h2>
|
| 3 |
+
|
| 4 |
+
<div class="overflow-x-auto rounded-lg border border-surface-general">
|
| 5 |
+
<table class="min-w-max w-full text-sm text-center border-collapse">
|
| 6 |
+
<thead class="bg-surface-sweet text-black font-semibold">
|
| 7 |
+
<tr>
|
| 8 |
+
<th class="py-2 px-3 border border-surface-general">Usuario</th>
|
| 9 |
+
<th class="py-2 px-3 border border-surface-general">Producto</th>
|
| 10 |
+
{% for palabra in palabras %}
|
| 11 |
+
<th class="py-2 px-3 border border-surface-general uppercase">{{ palabra }}</th>
|
| 12 |
+
{% endfor %}
|
| 13 |
+
</tr>
|
| 14 |
+
</thead>
|
| 15 |
+
<tbody class="bg-surface-ligt divide-y divide-gray-200">
|
| 16 |
+
{% for usuario, productos in catadores.items %}
|
| 17 |
+
{% for codigo, valores in productos.items %}
|
| 18 |
+
<tr>
|
| 19 |
+
<td class="py-2 px-3 border border-surface-general">{{ usuario }}</td>
|
| 20 |
+
<td class="py-2 px-3 border border-surface-general">{{ codigo }}</td>
|
| 21 |
+
{% for palabra in palabras %}
|
| 22 |
+
<td class="py-2 px-3 border border-surface-general">
|
| 23 |
+
{% with match=None %}
|
| 24 |
+
{% for valor in valores %}
|
| 25 |
+
{% if valor.nombre_palabra == palabra %}
|
| 26 |
+
{{ palabra }} <br>
|
| 27 |
+
{{ valor.dato_valor }}
|
| 28 |
+
{% with match=True %}{% endwith %}
|
| 29 |
+
{% endif %}
|
| 30 |
+
{% endfor %}
|
| 31 |
+
{% if not match %}0{% endif %}
|
| 32 |
+
{% endwith %}
|
| 33 |
+
</td>
|
| 34 |
+
{% endfor %}
|
| 35 |
+
</tr>
|
| 36 |
+
{% endfor %}
|
| 37 |
+
{% endfor %}
|
| 38 |
+
</tbody>
|
| 39 |
+
</table>
|
| 40 |
+
</div>
|
| 41 |
+
|
| 42 |
+
<div class="flex justify-end mt-3">
|
| 43 |
+
<button class="cts-btn-general cts-btn-primary btn-push">
|
| 44 |
+
Descargar CSV
|
| 45 |
+
</button>
|
| 46 |
+
</div>
|
| 47 |
+
</section>
|
tecnicas/templates/tecnicas/manage_sesions/detalles-sesion.html
CHANGED
|
@@ -6,20 +6,17 @@
|
|
| 6 |
{% block content %}
|
| 7 |
<article class="cts-container-main">
|
| 8 |
<article class="cts-wrap-content">
|
| 9 |
-
<header class="text-center flex-row w-full flex justify-around items-center flex-wrap gap-10">
|
| 10 |
<h1 class="text-black rounded-xl font-bold text-2xl bg-surface-card shadow-lg p-4 flex-1">
|
| 11 |
Detalles de la sesión
|
| 12 |
</h1>
|
| 13 |
-
<
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
Volver a las Sesiones
|
| 17 |
-
</button>
|
| 18 |
-
</a>
|
| 19 |
</header>
|
| 20 |
|
| 21 |
{% if error %}
|
| 22 |
-
<article class="bg-red-600 p-4 text-white rounded-xl ct-notification-error">
|
| 23 |
<p class="block font-sans text-white text-xl antialiased font-bold uppercase tracking-wider text-center">
|
| 24 |
{{ error }}
|
| 25 |
</p>
|
|
@@ -111,7 +108,7 @@
|
|
| 111 |
</section>
|
| 112 |
|
| 113 |
<section>
|
| 114 |
-
<p class="font-
|
| 115 |
Rep. Max:
|
| 116 |
</p>
|
| 117 |
<p class="font-sans text-lg max-sm:text-base font-normal">
|
|
@@ -137,7 +134,7 @@
|
|
| 137 |
{% for palabra in palabras %}
|
| 138 |
<section>
|
| 139 |
<p class="block text-black text-xl antialiased font-medium">
|
| 140 |
-
{{ palabra
|
| 141 |
</p>
|
| 142 |
</section>
|
| 143 |
{% endfor %}
|
|
@@ -182,16 +179,16 @@
|
|
| 182 |
Datos obtenidos
|
| 183 |
</p>
|
| 184 |
|
| 185 |
-
{% if
|
| 186 |
-
<article class="bg-surface-card p-4 text-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
</article>
|
| 191 |
{% else %}
|
| 192 |
-
|
| 193 |
-
</article>
|
| 194 |
{% endif %}
|
|
|
|
| 195 |
<form action="" method="post" class="form-action-session hidden">
|
| 196 |
{% csrf_token %}
|
| 197 |
</form>
|
|
|
|
| 6 |
{% block content %}
|
| 7 |
<article class="cts-container-main">
|
| 8 |
<article class="cts-wrap-content">
|
| 9 |
+
<header class="text-center flex-row max-sm:flex-col w-full flex justify-around items-center flex-wrap gap-10">
|
| 10 |
<h1 class="text-black rounded-xl font-bold text-2xl bg-surface-card shadow-lg p-4 flex-1">
|
| 11 |
Detalles de la sesión
|
| 12 |
</h1>
|
| 13 |
+
<button class="cts-btn-general cts-btn-error btn-push" onclick="window.history.back()">
|
| 14 |
+
Volver a las Sesiones
|
| 15 |
+
</button>
|
|
|
|
|
|
|
|
|
|
| 16 |
</header>
|
| 17 |
|
| 18 |
{% if error %}
|
| 19 |
+
<article class=" bg-red-600 p-4 text-white rounded-xl ct-notification-error">
|
| 20 |
<p class="block font-sans text-white text-xl antialiased font-bold uppercase tracking-wider text-center">
|
| 21 |
{{ error }}
|
| 22 |
</p>
|
|
|
|
| 108 |
</section>
|
| 109 |
|
| 110 |
<section>
|
| 111 |
+
<p class="font-bold">
|
| 112 |
Rep. Max:
|
| 113 |
</p>
|
| 114 |
<p class="font-sans text-lg max-sm:text-base font-normal">
|
|
|
|
| 134 |
{% for palabra in palabras %}
|
| 135 |
<section>
|
| 136 |
<p class="block text-black text-xl antialiased font-medium">
|
| 137 |
+
{{ palabra }}
|
| 138 |
</p>
|
| 139 |
</section>
|
| 140 |
{% endfor %}
|
|
|
|
| 179 |
Datos obtenidos
|
| 180 |
</p>
|
| 181 |
|
| 182 |
+
{% if existen_calificaciones %}
|
| 183 |
+
<article class="bg-surface-card p-4 max-sm:px-2 text-black rounded">
|
| 184 |
+
{% for repeticion, catadores in calificaciones.items %}
|
| 185 |
+
{% include "../components/table-convencional.html" with repeticion=repeticion catadores=catadores palabras=palabras %}
|
| 186 |
+
{% endfor %}
|
| 187 |
</article>
|
| 188 |
{% else %}
|
| 189 |
+
{% include "../components/error-message.html" with message='Sin calificaciones que mostrar aún' %}
|
|
|
|
| 190 |
{% endif %}
|
| 191 |
+
|
| 192 |
<form action="" method="post" class="form-action-session hidden">
|
| 193 |
{% csrf_token %}
|
| 194 |
</form>
|
tecnicas/templates/tecnicas/manage_sesions/monitor-sesion.html
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
{% extends 'tecnicas/layouts/base.html' %}
|
|
|
|
| 2 |
|
| 3 |
{% block title %}Monitoreo{% endblock %}
|
| 4 |
|
|
@@ -17,22 +18,36 @@
|
|
| 17 |
</article>
|
| 18 |
{% endif %}
|
| 19 |
|
| 20 |
-
<section class="flex flex-col sm:flex-row justify-between items-center gap-10
|
| 21 |
<p class="text-xl text-center bg-surface-card p-4 text-black rounded-lg shadow-lg">
|
| 22 |
Código de sesión:<br>
|
| 23 |
<span class="font-mono text-2xl font-bold">{{ code_session }}</span>
|
| 24 |
</p>
|
| 25 |
-
<
|
| 26 |
-
class="uppercase
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
</section>
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
<section aria-labelledby="catadores-titulo">
|
| 32 |
<article
|
| 33 |
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">
|
| 34 |
-
<button
|
| 35 |
-
class="uppercase text-lg max-sm:text-base tracking-wider p-2 px-3 transition-all rounded-xl bg-btn-secondary font-bold btn-push border-pink-800"
|
| 36 |
onclick="reloadPage()">
|
| 37 |
Actualizar lista
|
| 38 |
</button>
|
|
@@ -108,4 +123,5 @@
|
|
| 108 |
location.reload()
|
| 109 |
}
|
| 110 |
</script>
|
|
|
|
| 111 |
{% endblock %}
|
|
|
|
| 1 |
{% extends 'tecnicas/layouts/base.html' %}
|
| 2 |
+
{% load static %}
|
| 3 |
|
| 4 |
{% block title %}Monitoreo{% endblock %}
|
| 5 |
|
|
|
|
| 18 |
</article>
|
| 19 |
{% endif %}
|
| 20 |
|
| 21 |
+
<section class="flex flex-col sm:flex-row justify-between items-center gap-10">
|
| 22 |
<p class="text-xl text-center bg-surface-card p-4 text-black rounded-lg shadow-lg">
|
| 23 |
Código de sesión:<br>
|
| 24 |
<span class="font-mono text-2xl font-bold">{{ code_session }}</span>
|
| 25 |
</p>
|
| 26 |
+
<div class="flex flex-col gap-2">
|
| 27 |
+
<button class="uppercase cts-btn-general-compress cts-btn-secondary py-2 px-6 btn-push"
|
| 28 |
+
onclick="finishSession()">
|
| 29 |
+
Finalizar sesión
|
| 30 |
+
</button>
|
| 31 |
+
<button class="uppercase cts-btn-general-compress cts-btn-error py-2 px-6 btn-push"
|
| 32 |
+
onclick="window.history.back()">
|
| 33 |
+
Regresar
|
| 34 |
+
</button>
|
| 35 |
+
</div>
|
| 36 |
</section>
|
| 37 |
|
| 38 |
+
<form action="" method="post" class="hidden action-form">
|
| 39 |
+
<input type="hidden" name="action">
|
| 40 |
+
{% csrf_token %}
|
| 41 |
+
</form>
|
| 42 |
+
|
| 43 |
+
{% if message %}
|
| 44 |
+
{% include "../components/error-message.html" with message=message %}
|
| 45 |
+
{% endif %}
|
| 46 |
+
|
| 47 |
<section aria-labelledby="catadores-titulo">
|
| 48 |
<article
|
| 49 |
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">
|
| 50 |
+
<button class="uppercase cts-btn-general-compress cts-btn-tertiary py-2 px-6 btn-push"
|
|
|
|
| 51 |
onclick="reloadPage()">
|
| 52 |
Actualizar lista
|
| 53 |
</button>
|
|
|
|
| 123 |
location.reload()
|
| 124 |
}
|
| 125 |
</script>
|
| 126 |
+
<script src="{% static 'js/finish-session.js' %}"></script>
|
| 127 |
{% endblock %}
|
tecnicas/templates/tecnicas/manage_sesions/sesiones-panel.html
CHANGED
|
@@ -22,7 +22,7 @@
|
|
| 22 |
<section class="grid grid-cols-3 max-lg:grid-cols-2 max-sm:grid-cols-1 w-full gap-4 justify-center">
|
| 23 |
{% for sesion in sessions %}
|
| 24 |
<div class="card bg-surface-card shadow-lg text-black sm:max-w-80 w-full flex justify-center items-center">
|
| 25 |
-
<div class="card-body flex flex-col justify-between">
|
| 26 |
<div class="flex flex-col gap-1 [&>*]:first:text-xl [&>*]:first:font-bold [&>*]:first:border-b">
|
| 27 |
{% if sesion.nombre_sesion %}
|
| 28 |
<h2>{{ sesion.nombre_sesion }}</h2>
|
|
|
|
| 22 |
<section class="grid grid-cols-3 max-lg:grid-cols-2 max-sm:grid-cols-1 w-full gap-4 justify-center">
|
| 23 |
{% for sesion in sessions %}
|
| 24 |
<div class="card bg-surface-card shadow-lg text-black sm:max-w-80 w-full flex justify-center items-center">
|
| 25 |
+
<div class="card-body flex flex-col justify-between w-full">
|
| 26 |
<div class="flex flex-col gap-1 [&>*]:first:text-xl [&>*]:first:font-bold [&>*]:first:border-b">
|
| 27 |
{% if sesion.nombre_sesion %}
|
| 28 |
<h2>{{ sesion.nombre_sesion }}</h2>
|
tecnicas/utils/__init__.py
CHANGED
|
@@ -2,4 +2,5 @@ from .code_generate import generarCodigo
|
|
| 2 |
from .code_generate import generarCodigos
|
| 3 |
from .personal_errors import general_error, controller_error
|
| 4 |
from .shuffle_arrays import shuffleArray
|
| 5 |
-
from .general_controllers import getId
|
|
|
|
|
|
| 2 |
from .code_generate import generarCodigos
|
| 3 |
from .personal_errors import general_error, controller_error
|
| 4 |
from .shuffle_arrays import shuffleArray
|
| 5 |
+
from .general_controllers import getId
|
| 6 |
+
from .to_dict import defaultdict_to_dict
|
tecnicas/utils/to_dict.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from collections import defaultdict
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
def defaultdict_to_dict(d):
|
| 5 |
+
if isinstance(d, defaultdict):
|
| 6 |
+
d = {k: defaultdict_to_dict(v) for k, v in d.items()}
|
| 7 |
+
elif isinstance(d, dict):
|
| 8 |
+
d = {k: defaultdict_to_dict(v) for k, v in d.items()}
|
| 9 |
+
return d
|
tecnicas/views/sessions_management/session_details.py
CHANGED
|
@@ -5,19 +5,21 @@ from ...controllers import DetallesSesionController
|
|
| 5 |
|
| 6 |
|
| 7 |
def sessionDetails(req: HttpRequest, session_code: str):
|
| 8 |
-
|
|
|
|
| 9 |
|
| 10 |
if req.method == "GET":
|
|
|
|
| 11 |
return render(req, "tecnicas/manage_sesions/detalles-sesion.html", context)
|
| 12 |
elif req.method == "POST":
|
| 13 |
if req.POST["action"] == "start_session":
|
| 14 |
response = DetallesSesionController.startRepetition(
|
| 15 |
session_code=session_code, username=req.POST["username"])
|
| 16 |
if isinstance(response, dict):
|
|
|
|
| 17 |
context["error"] = response["error"]
|
| 18 |
return render(req, "tecnicas/manage_sesions/detalles-sesion.html", context)
|
| 19 |
-
|
| 20 |
-
return render(req, "tecnicas/manage_sesions/detalles-sesion.html", context)
|
| 21 |
elif req.POST.get("action") == "delete_session":
|
| 22 |
pass
|
| 23 |
elif req.POST.get("action") == "monitor_session":
|
|
|
|
| 5 |
|
| 6 |
|
| 7 |
def sessionDetails(req: HttpRequest, session_code: str):
|
| 8 |
+
controller_view = DetallesSesionController(session_code)
|
| 9 |
+
context = controller_view.getContextForView()
|
| 10 |
|
| 11 |
if req.method == "GET":
|
| 12 |
+
context = controller_view.getContextWithData()
|
| 13 |
return render(req, "tecnicas/manage_sesions/detalles-sesion.html", context)
|
| 14 |
elif req.method == "POST":
|
| 15 |
if req.POST["action"] == "start_session":
|
| 16 |
response = DetallesSesionController.startRepetition(
|
| 17 |
session_code=session_code, username=req.POST["username"])
|
| 18 |
if isinstance(response, dict):
|
| 19 |
+
context = controller_view.getContextWithData()
|
| 20 |
context["error"] = response["error"]
|
| 21 |
return render(req, "tecnicas/manage_sesions/detalles-sesion.html", context)
|
| 22 |
+
return redirect(reverse("cata_system:monitor_sesion"))
|
|
|
|
| 23 |
elif req.POST.get("action") == "delete_session":
|
| 24 |
pass
|
| 25 |
elif req.POST.get("action") == "monitor_session":
|
tecnicas/views/sessions_management/session_monitor.py
CHANGED
|
@@ -1,17 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from django.http import HttpRequest, JsonResponse
|
| 2 |
-
from django.shortcuts import render
|
|
|
|
| 3 |
from tecnicas.controllers import MonitorSesionController
|
|
|
|
| 4 |
|
| 5 |
|
| 6 |
def sessionMonitor(req: HttpRequest, session_code: str):
|
| 7 |
-
|
| 8 |
-
|
| 9 |
|
| 10 |
-
|
| 11 |
if "error" in context:
|
| 12 |
return render(req, "tecnicas/manage_sesions/monitor-sesion.html", context)
|
| 13 |
-
|
| 14 |
context["code_session"] = session_code
|
| 15 |
return render(req, "tecnicas/manage_sesions/monitor-sesion.html", context)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
else:
|
| 17 |
return JsonResponse({"error": "Método no permitido"})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'''
|
| 2 |
+
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.controllers import MonitorSesionController
|
| 11 |
+
from tecnicas.utils import general_error
|
| 12 |
|
| 13 |
|
| 14 |
def sessionMonitor(req: HttpRequest, session_code: str):
|
| 15 |
+
controll_view = MonitorSesionController(session_code)
|
| 16 |
+
context = controll_view.monitorView()
|
| 17 |
|
| 18 |
+
if req.method == "GET":
|
| 19 |
if "error" in context:
|
| 20 |
return render(req, "tecnicas/manage_sesions/monitor-sesion.html", context)
|
| 21 |
+
|
| 22 |
context["code_session"] = session_code
|
| 23 |
return render(req, "tecnicas/manage_sesions/monitor-sesion.html", context)
|
| 24 |
+
elif req.method == "POST":
|
| 25 |
+
action = req.POST["action"]
|
| 26 |
+
if action == "finish_session":
|
| 27 |
+
return actionFinishSession(context=context, session_code=session_code, controll_view=controll_view, req=req)
|
| 28 |
+
else:
|
| 29 |
+
return general_error("No se ha especificado la acción")
|
| 30 |
else:
|
| 31 |
return JsonResponse({"error": "Método no permitido"})
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def actionFinishSession(context: dict, session_code: str, controll_view: MonitorSesionController, req: HttpRequest):
|
| 35 |
+
context["code_session"] = session_code
|
| 36 |
+
(is_all_end, message) = controll_view.checkAllParticipantsEnded()
|
| 37 |
+
context["message"] = message
|
| 38 |
+
if not is_all_end:
|
| 39 |
+
return render(req, "tecnicas/manage_sesions/monitor-sesion.html", context)
|
| 40 |
+
response = controll_view.finishSession()
|
| 41 |
+
if isinstance(response, dict):
|
| 42 |
+
context["message"] = response["error"]
|
| 43 |
+
return render(req, "tecnicas/manage_sesions/monitor-sesion.html", context)
|
| 44 |
+
return redirect(reverse("cata_system:detalles_sesion", kwargs={"session_code": session_code}))
|
theme/static_src/tailwind.config.js
CHANGED
|
@@ -16,7 +16,7 @@ module.exports = {
|
|
| 16 |
"surface-alter-card": "#91C4C3",
|
| 17 |
"btn-primary": "#4CAF50",
|
| 18 |
"btn-secondary": "#E45A92",
|
| 19 |
-
"btn-tertiary": "#
|
| 20 |
"ct-success": "#2E7D32",
|
| 21 |
"ct-error": "#E62727",
|
| 22 |
},
|
|
|
|
| 16 |
"surface-alter-card": "#91C4C3",
|
| 17 |
"btn-primary": "#4CAF50",
|
| 18 |
"btn-secondary": "#E45A92",
|
| 19 |
+
"btn-tertiary": "#88EE88",
|
| 20 |
"ct-success": "#2E7D32",
|
| 21 |
"ct-error": "#E62727",
|
| 22 |
},
|