chartManD commited on
Commit
6bd93b2
·
1 Parent(s): 37215c6

Finalizar sesion comprobando evaluacionses concluidas

Browse files
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
- participations = list(Participacion.objects.filter(**filters))
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 ...models import Tecnica, Presentador, SesionSensorial
4
- from ...utils import controller_error
 
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 ...models import TipoTecnica, CategoriaTecnica, Tecnica, EstiloPalabra
2
  from django.db import DatabaseError
3
- from ...utils import controller_error
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/main_tester_form_controller.py CHANGED
@@ -1,4 +1,4 @@
1
- from ...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,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 = productos * palabras
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/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/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 mb-6">
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
- <button
26
- class="uppercase text-lg max-sm:text-base tracking-wider p-4 rounded-xl bg-ct-error text-white font-bold border-red-800 btn-push">
27
- Finalizar sesión
28
- </button>
 
 
 
 
 
 
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/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
- if req.method == "GET":
8
- controll_view = MonitorSesionController(session_code)
9
 
10
- context = controll_view.monitorView()
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": "#CCECC0",
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
  },