chartManD commited on
Commit
8708a78
·
1 Parent(s): ea65589

Validaciones para finalizar sesion con Catador en nappgin y nappgin con ultra flash

Browse files
tecnicas/controllers/views_controller/sessions_tester/tests_forms/test_napping_controller.py CHANGED
@@ -5,6 +5,7 @@ from django.db.models import F
5
  from tecnicas.models import Participacion, Producto, TecnicaModalidad, DatoPunto, Calificacion, Modalidad, Palabra
6
  from tecnicas.forms import ListWordsForm
7
  from tecnicas.utils import noValidTechnique
 
8
  from .general_test_controller import GenetalTestController
9
 
10
 
@@ -113,3 +114,78 @@ class TestNappingController(GenetalTestController):
113
  words_by_product[product_code] = words_list
114
 
115
  self.context["words_by_product"] = words_by_product
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  from tecnicas.models import Participacion, Producto, TecnicaModalidad, DatoPunto, Calificacion, Modalidad, Palabra
6
  from tecnicas.forms import ListWordsForm
7
  from tecnicas.utils import noValidTechnique
8
+ from tecnicas.controllers import ParticipacionController
9
  from .general_test_controller import GenetalTestController
10
 
11
 
 
114
  words_by_product[product_code] = words_list
115
 
116
  self.context["words_by_product"] = words_by_product
117
+
118
+ def controllPost(self, request: HttpRequest):
119
+ action = request.POST.get("action")
120
+
121
+ if action == "finish_session":
122
+ # Get technique and mode
123
+ technique = self.session.tecnica
124
+ self.participation = Participacion.objects.get(
125
+ tecnica=technique, catador=request.user.user_catador)
126
+
127
+ name_mode_activate = TecnicaModalidad.objects.get(
128
+ tecnica=technique).modalidad.nombre
129
+
130
+ # Validate based on mode
131
+ validation_error = self.validateSessionCompletion(
132
+ technique, name_mode_activate)
133
+
134
+ if validation_error:
135
+ # Return to the appropriate template with error
136
+ if name_mode_activate == "sin modalidad":
137
+ return self.nappingTest(request)
138
+ elif name_mode_activate == "perfil ultra flash":
139
+ return self.nappingPufTest(request)
140
+
141
+ # If validation passes, finish the session
142
+ ParticipacionController.finishSession(self.participation)
143
+ params = {"code_sesion": self.session.codigo_sesion}
144
+ return redirect(reverse(self.previus_directory, kwargs=params))
145
+
146
+ # For other actions, call parent's controllPost
147
+ return super().controllPost(request)
148
+
149
+ def validateSessionCompletion(self, technique, mode_name):
150
+ # Get all products in technique
151
+ products = Producto.objects.filter(id_tecnica=technique)
152
+ product_count = products.count()
153
+
154
+ # Get all ratings for this tester
155
+ ratings = Calificacion.objects.filter(
156
+ num_repeticion=0,
157
+ id_tecnica=technique,
158
+ id_catador=self.participation.catador
159
+ ).select_related('id_producto').prefetch_related('palabras')
160
+
161
+ # Check if all products have ratings
162
+ if ratings.count() != product_count:
163
+ missing_count = product_count - ratings.count()
164
+ return f"Faltan {missing_count} producto(s) por evaluar."
165
+
166
+ # Check if all ratings have DatoPunto (coordinates)
167
+ ratings_with_points = DatoPunto.objects.filter(
168
+ calificacion__in=ratings
169
+ ).values_list('calificacion_id', flat=True)
170
+
171
+ ratings_without_points = ratings.exclude(id__in=ratings_with_points)
172
+ if ratings_without_points.exists():
173
+ missing_products = [
174
+ r.id_producto.codigoProducto for r in ratings_without_points
175
+ ]
176
+ return f"Los siguientes productos no tienen coordenadas: {', '.join(missing_products)}"
177
+
178
+ # Additional validation for "perfil ultra flash" mode
179
+ if mode_name == "perfil ultra flash":
180
+ # Check that each rating has at least one word
181
+ ratings_without_words = []
182
+ for rating in ratings:
183
+ if rating.palabras.count() < 1:
184
+ ratings_without_words.append(
185
+ rating.id_producto.codigoProducto)
186
+
187
+ if ratings_without_words:
188
+ return f"Los siguientes productos deben tener al menos 1 palabra: {', '.join(ratings_without_words)}"
189
+
190
+ # All validations passed
191
+ return None
tecnicas/static/js/test-napping-plane.js CHANGED
@@ -161,24 +161,25 @@ document
161
  ////
162
  */
163
 
164
- // Callback for additional validation before saving (can be set by ultra flash)
165
  window.beforeSaveData = null;
166
 
167
- // Function to get extra data for each product (can be set by ultra flash)
168
  window.getExtraDataForSave = null;
169
 
170
- window.saveData = async function () {
171
  const codeProducts = Object.keys(window.placedPoints);
172
  const data = [];
173
 
174
- if (products.length != codeProducts.length) {
175
- spanNotifaction("Por favor, coloca todos los puntos")
176
- return;
 
177
  }
178
 
179
  // Call beforeSaveData callback if it exists (for ultra flash validation)
180
  if (window.beforeSaveData && typeof window.beforeSaveData === 'function') {
181
- const validationResult = window.beforeSaveData();
182
  if (validationResult === false) {
183
  return false;
184
  }
@@ -236,6 +237,17 @@ window.saveData = async function () {
236
  }
237
  }
238
 
 
 
 
 
 
 
 
 
 
 
 
239
  document
240
  .getElementById("save-progress")
241
- .addEventListener("click", window.saveData);
 
161
  ////
162
  */
163
 
164
+ // Callback for additional validation before saving
165
  window.beforeSaveData = null;
166
 
167
+ // Function to get extra data for each product
168
  window.getExtraDataForSave = null;
169
 
170
+ window.saveData = async function (isFinishSession = false) {
171
  const codeProducts = Object.keys(window.placedPoints);
172
  const data = [];
173
 
174
+ // Only validate all products placed if finishing session
175
+ if (isFinishSession && products.length != codeProducts.length) {
176
+ spanNotifaction("Por favor, coloca todos los puntos antes de finalizar la sesión")
177
+ return false;
178
  }
179
 
180
  // Call beforeSaveData callback if it exists (for ultra flash validation)
181
  if (window.beforeSaveData && typeof window.beforeSaveData === 'function') {
182
+ const validationResult = window.beforeSaveData(isFinishSession);
183
  if (validationResult === false) {
184
  return false;
185
  }
 
237
  }
238
  }
239
 
240
+ // Function to finish session with validation
241
+ window.finishSession = async function () {
242
+ const success = await window.saveData(true);
243
+ if (success) {
244
+ // Submit the form to finish session
245
+ const formFinish = document.getElementById("form-finish-session")
246
+ formFinish.action = ""
247
+ formFinish.submit();
248
+ }
249
+ }
250
+
251
  document
252
  .getElementById("save-progress")
253
+ .addEventListener("click", () => window.saveData(false));
tecnicas/static/js/test-napping-ultra-flash.js CHANGED
@@ -79,6 +79,9 @@ function initUltraFlash() {
79
  document.querySelectorAll('.item-product').forEach(p => {
80
  p.classList.remove('ring-4', 'ring-primary');
81
  });
 
 
 
82
  }
83
 
84
  // Handle Point Click for Description
@@ -197,25 +200,34 @@ function initUltraFlash() {
197
 
198
  // Set up callbacks to extend the base saveData function
199
  // Validation callback - runs before saving
200
- window.beforeSaveData = function () {
201
- // If in description phase, validate words (minimum 1 per product)
202
- if (isDescriptionPhase) {
 
203
  const codeProducts = Object.keys(window.placedPoints);
 
 
 
 
 
 
 
 
204
  for (const code of codeProducts) {
205
  const words = productWords[code] || [];
206
  if (words.length < 1) {
207
- spanNotifaction(`El producto ${code} debe tener al menos 1 palabra.`);
208
  return false;
209
  }
210
  }
211
  }
 
212
  return true;
213
  };
214
 
215
  // Data extension callback - adds words to each product's data
216
  window.getExtraDataForSave = function (code) {
217
  const words = productWords[code] || [];
218
- console.log(`Getting words for ${code}:`, words);
219
  return {
220
  words: words
221
  };
 
79
  document.querySelectorAll('.item-product').forEach(p => {
80
  p.classList.remove('ring-4', 'ring-primary');
81
  });
82
+
83
+ // Auto-save positions when transitioning to description phase
84
+ window.saveData(false);
85
  }
86
 
87
  // Handle Point Click for Description
 
200
 
201
  // Set up callbacks to extend the base saveData function
202
  // Validation callback - runs before saving
203
+ window.beforeSaveData = function (isFinishSession = false) {
204
+ // If finishing session, validate all products placed and have words
205
+ if (isFinishSession) {
206
+ const totalProducts = document.querySelectorAll('.item-product').length;
207
  const codeProducts = Object.keys(window.placedPoints);
208
+
209
+ // Check all products are placed
210
+ if (codeProducts.length !== totalProducts) {
211
+ spanNotifaction("Por favor, coloca todos los productos antes de finalizar la sesión.");
212
+ return false;
213
+ }
214
+
215
+ // Check each product has at least 1 word
216
  for (const code of codeProducts) {
217
  const words = productWords[code] || [];
218
  if (words.length < 1) {
219
+ spanNotifaction(`El producto ${code} debe tener al menos 1 palabra para finalizar la sesión.`);
220
  return false;
221
  }
222
  }
223
  }
224
+ // For progress save, no validation needed
225
  return true;
226
  };
227
 
228
  // Data extension callback - adds words to each product's data
229
  window.getExtraDataForSave = function (code) {
230
  const words = productWords[code] || [];
 
231
  return {
232
  words: words
233
  };
tecnicas/templates/tecnicas/forms_tester/test_napping.html CHANGED
@@ -18,10 +18,11 @@
18
  </header>
19
 
20
  <article class="hidden">
21
- <form action="{% url 'cata_system:catador_init_session' code_sesion=session.codigo_sesion %}" method="post"
 
22
  class="form-actions">
23
  {% csrf_token %}
24
- <input type="hidden" name="action" class="action-input">
25
  </form>
26
  </article>
27
 
@@ -133,7 +134,7 @@
133
  ¿Finalizar sesión?
134
  </button>
135
  <button id="finish-session" class="cts-btn-general cts-btn-tertiary btn-push hidden flex-1"
136
- onclick="finishSession('form-actions')">
137
  Finalizar
138
  </button>
139
  <button id="cancel-save" class="cts-btn-general cts-btn-error btn-push hidden flex-1">
 
18
  </header>
19
 
20
  <article class="hidden">
21
+ <form id="form-finish-session"
22
+ action="{% url 'cata_system:catador_init_session' code_sesion=session.codigo_sesion %}" method="post"
23
  class="form-actions">
24
  {% csrf_token %}
25
+ <input type="hidden" name="action" value="finish_session" class="action-input">
26
  </form>
27
  </article>
28
 
 
134
  ¿Finalizar sesión?
135
  </button>
136
  <button id="finish-session" class="cts-btn-general cts-btn-tertiary btn-push hidden flex-1"
137
+ onclick="window.finishSession()">
138
  Finalizar
139
  </button>
140
  <button id="cancel-save" class="cts-btn-general cts-btn-error btn-push hidden flex-1">
tecnicas/templates/tecnicas/forms_tester/test_napping_puf.html CHANGED
@@ -18,10 +18,11 @@
18
  </header>
19
 
20
  <article class="hidden">
21
- <form action="{% url 'cata_system:catador_init_session' code_sesion=session.codigo_sesion %}" method="post"
 
22
  class="form-actions">
23
  {% csrf_token %}
24
- <input type="hidden" name="action" class="action-input">
25
  </form>
26
  </article>
27
 
@@ -146,7 +147,7 @@
146
  ¿Finalizar sesión?
147
  </button>
148
  <button id="finish-session" class="cts-btn-general cts-btn-tertiary btn-push hidden flex-1"
149
- onclick="finishSession('form-actions')">
150
  Finalizar
151
  </button>
152
  <button id="cancel-save" class="cts-btn-general cts-btn-error btn-push hidden flex-1">
 
18
  </header>
19
 
20
  <article class="hidden">
21
+ <form id="form-finish-session"
22
+ action="{% url 'cata_system:catador_init_session' code_sesion=session.codigo_sesion %}" method="post"
23
  class="form-actions">
24
  {% csrf_token %}
25
+ <input type="hidden" name="action" value="finish_session" class="action-input">
26
  </form>
27
  </article>
28
 
 
147
  ¿Finalizar sesión?
148
  </button>
149
  <button id="finish-session" class="cts-btn-general cts-btn-tertiary btn-push hidden flex-1"
150
+ onclick="window.finishSession()">
151
  Finalizar
152
  </button>
153
  <button id="cancel-save" class="cts-btn-general cts-btn-error btn-push hidden flex-1">
tecnicas/templates/tecnicas/manage_sesions/details-session-napping.html CHANGED
@@ -192,8 +192,7 @@
192
  </p>
193
 
194
  {% if there_data %}
195
- {% include "../components/table-napping-no-mode.html" with testers=testers
196
- coordinates_no_mode=coordinates_no_mode %}
197
  {% else %}
198
  {% include "../components/error-message.html" with message='Sin datos por mostrar aún' %}
199
  {% endif %}
 
192
  </p>
193
 
194
  {% if there_data %}
195
+ {% include "../components/table-napping-no-mode.html" with testers=testers coordinates_no_mode=coordinates_no_mode %}
 
196
  {% else %}
197
  {% include "../components/error-message.html" with message='Sin datos por mostrar aún' %}
198
  {% endif %}