chartManD commited on
Commit
7630d83
·
1 Parent(s): c9de8df

Se mandan datos al api

Browse files
tecnicas/controllers/__init__.py CHANGED
@@ -36,5 +36,5 @@ from .views_controller.sessions_tester.test_cata_controller import TestCataContr
36
  from .views_controller.vocabulary_manage.create_vocabulary_controller import CreateVocabularyController
37
  from .views_controller.vocabulary_manage.list_vocabulary_controller import ListVocabularyController
38
 
39
- from .views_controller.api_rating_controller import ApiRatingController
40
  from .views_controller.tester_list_controller import TesterListController
 
36
  from .views_controller.vocabulary_manage.create_vocabulary_controller import CreateVocabularyController
37
  from .views_controller.vocabulary_manage.list_vocabulary_controller import ListVocabularyController
38
 
39
+ from .api_controller.rating_sacales_controller import RatingScalesController
40
  from .views_controller.tester_list_controller import TesterListController
tecnicas/controllers/api_controller/rating_cata_controller.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from django.http import JsonResponse, HttpRequest
2
+ from django.db import transaction
3
+ from tecnicas.models import Calificacion, Dato, ValorBooleano, Participacion, Palabra
4
+
5
+
6
+ class RatingCataController():
7
+ def __init__(self):
8
+ pass
9
+
10
+ @staticmethod
11
+ def saveRatingWords(request: HttpRequest, data_words: list[dict]):
12
+ try:
13
+ with transaction.atomic():
14
+ participation = Participacion.objects.get(
15
+ id=request.session["id_participation"])
16
+ if not participation:
17
+ raise ValueError("No está autorizado en la sesión")
18
+
19
+ # ids_words = [wo.id for ]
20
+
21
+ words_for_rating = Palabra.objects.filter(id__in=ids_words)
22
+
23
+ technique = participation.tecnica
24
+ rating = Calificacion.objects.get_or_create(
25
+ num_repeticion=technique.repeticion
26
+ id_producto=1
27
+ id_tecnica=1
28
+ id_catador=1
29
+ )
30
+ pass
31
+ except ValueError as e:
32
+ print(f"Error de calificacion: {e}")
33
+ return JsonResponse({"error": e}, statusstatus=500)
tecnicas/controllers/{views_controller/api_rating_controller.py → api_controller/rating_sacales_controller.py} RENAMED
@@ -1,8 +1,8 @@
1
- from ...controllers import CalificacionController, DatoController
2
  from ...utils import controller_error
3
 
4
 
5
- class ApiRatingController():
6
  def __init__(self, rating_controller: CalificacionController, data_controller: DatoController):
7
  self.rating_controller = rating_controller
8
  self.data_controller = data_controller
 
1
+ from .. import CalificacionController, DatoController
2
  from ...utils import controller_error
3
 
4
 
5
+ class RatingScalesController():
6
  def __init__(self, rating_controller: CalificacionController, data_controller: DatoController):
7
  self.rating_controller = rating_controller
8
  self.data_controller = data_controller
tecnicas/static/js/created-scale.js CHANGED
@@ -44,7 +44,7 @@ async function sendRating(word) {
44
  const formRatingWord = document.querySelector(`.form-rating-${word}`);
45
 
46
  const dataForm = new FormData(formRatingWord);
47
- const url = "/cata/testers/api/ratingword";
48
 
49
  const codeProduct = document
50
  .querySelector(".ct-product-rating")
 
44
  const formRatingWord = document.querySelector(`.form-rating-${word}`);
45
 
46
  const dataForm = new FormData(formRatingWord);
47
+ const url = "/cata/testers/api/ratingword/escalas";
48
 
49
  const codeProduct = document
50
  .querySelector(".ct-product-rating")
tecnicas/static/js/test-cata.js CHANGED
@@ -1,21 +1,124 @@
1
  document.addEventListener("DOMContentLoaded", () => {
 
 
2
  const form = document.getElementById("wordsForm");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  form.addEventListener("submit", (e) => {
5
- e.preventDefault(); // prevenimos envío por defecto
 
6
  const checkboxes = form.querySelectorAll('input[type="checkbox"]');
7
- const unchecked = Array.from(checkboxes).filter((cb) => !cb.checked);
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- if (unchecked.length > 0) {
10
- const confirmLeaveBlank = confirm(
11
- "Algunas palabras no han sido marcadas. ¿Deseas continuar dejando esas casillas en blanco?"
12
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- if (!confirmLeaveBlank) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  return;
16
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
-
19
- // form.submit();
20
  });
21
  });
 
1
  document.addEventListener("DOMContentLoaded", () => {
2
+ const containFormData = document.querySelector(".words-check-container");
3
+
4
  const form = document.getElementById("wordsForm");
5
+ const csrfToken = document.querySelector("[name=csrfmiddlewaretoken]").value;
6
+ const message = document.getElementById("response-message");
7
+
8
+ const modal = document.getElementById("confirmModal");
9
+ const modalContent = document.getElementById("confirmModalContent");
10
+ const cancelBtn = document.getElementById("cancelBtn");
11
+ const confirmBtn = document.getElementById("confirmBtn");
12
+
13
+ const URL = "/cata/testers/api/ratingword/cata";
14
+
15
+ let wordsData = [];
16
+
17
+ const checkboxes = form.querySelectorAll('input[type="checkbox"]');
18
+ checkboxes.forEach((cb) => (cb.checked = false));
19
 
20
  form.addEventListener("submit", (e) => {
21
+ e.preventDefault();
22
+
23
  const checkboxes = form.querySelectorAll('input[type="checkbox"]');
24
+ wordsData = Array.from(checkboxes).map((cb) => ({
25
+ id: parseInt(cb.dataset.wordId),
26
+ word: cb.dataset.wordName,
27
+ is_check: cb.checked,
28
+ }));
29
+
30
+ showModal(wordsData);
31
+ });
32
+
33
+ function showModal(words) {
34
+ const checkedWords = words.filter((w) => w.is_check);
35
+ const uncheckedWords = words.filter((w) => !w.is_check);
36
 
37
+ modalContent.innerHTML = `
38
+ <div>
39
+ <p class="font-semibold text-green-600">Palabras seleccionadas:</p>
40
+ <ul class="flex flex-wrap gap-2">
41
+ ${
42
+ checkedWords.length > 0
43
+ ? checkedWords
44
+ .map(
45
+ (w) =>
46
+ `<li class="border-r border-b p-1">${w.word}</li>`
47
+ )
48
+ .join("")
49
+ : '<li class="border-b p-1 w-full">Ninguna</li>'
50
+ }
51
+ </ul>
52
+ </div>
53
+ <div class="mt-3">
54
+ <p class="font-semibold text-red-600">Palabras no seleccionadas:</p>
55
+ <ul class="flex flex-wrap gap-2">
56
+ ${
57
+ uncheckedWords.length > 0
58
+ ? uncheckedWords
59
+ .map(
60
+ (w) =>
61
+ `<li class="border-r border-b p-1">${w.word}</li>`
62
+ )
63
+ .join("")
64
+ : '<li class="border-b p-1 w-full">Todas seleccionadas</li>'
65
+ }
66
+ </ul>
67
+ </div>
68
+ `;
69
+ modal.classList.remove("hidden");
70
+ }
71
 
72
+ cancelBtn.addEventListener("click", () => {
73
+ modalContent.innerHTML = "";
74
+ modal.classList.add("hidden");
75
+ });
76
+
77
+ confirmBtn.addEventListener("click", async () => {
78
+ modal.classList.add("hidden");
79
+
80
+ try {
81
+ const response = await fetch(URL, {
82
+ method: "POST",
83
+ headers: {
84
+ "Content-Type": "application/json",
85
+ "X-CSRFToken": csrfToken,
86
+ "X-Requested-With": "XMLHttpRequest",
87
+ },
88
+ body: JSON.stringify({ words: wordsData }),
89
+ });
90
+
91
+ if (!response.ok) {
92
+ message.textContent = "Error en la respuesta del servidor";
93
+ message.classList.remove("hidden");
94
+ throw new Error("Error en la respuesta del servidor");
95
+ }
96
+
97
+ const result = await response.json();
98
+ const messError = result.error;
99
+
100
+ console.log(messError);
101
+
102
+ if (messError) {
103
+ message.textContent = messError;
104
  return;
105
  }
106
+ containFormData.innerHTML = `
107
+ <section class="space-y-4">
108
+ <h3 class="text-xl font-bold">
109
+ Exito al guardar
110
+ </h3>
111
+ <p class="text-sm italic">
112
+ ${result.message}
113
+ </p>
114
+ <button type="button" class="cts-btn-general cts-btn-primary btn-push">
115
+ Siguiente Producto
116
+ </button>
117
+ </section>
118
+ `;
119
+ } catch (err) {
120
+ console.error(err);
121
+ alert("Ocurrió un error al enviar los datos ❌");
122
  }
 
 
123
  });
124
  });
tecnicas/templates/tecnicas/forms_tester/cata.html CHANGED
@@ -6,7 +6,7 @@
6
 
7
  {% block content %}
8
  <article class="cts-container-main">
9
- <article class="cts-wrap-content text-black">
10
  <header class="text-center flex-row max-sm:flex-col w-full items-stretch flex justify-around flex-wrap gap-2">
11
  <h1 class="rounded font-bold text-2xl bg-surface-ligt p-4 flex-1">
12
  Sesión usando <br>técnica
@@ -63,8 +63,13 @@
63
  </section>
64
  </article>
65
 
 
 
 
 
 
66
  <article
67
- class="words-check-container bg-surface-card w-full max-w-3xl mx-auto p-6 bg-base-200 rounded-xl shadow-lg">
68
  <form id="wordsForm" method="POST" class="flex flex-col gap-4">
69
  {% csrf_token %}
70
  <div class="grid lg:grid-cols-4 md:grid-cols-3 grid-cols-2 gap-4">
@@ -72,8 +77,8 @@
72
  <label
73
  class="flex items-center justify-between bg-surface-sweet p-4 gap-2 rounded-lg shadow-sm hover:shadow-md transition-all">
74
  <span class="text-lg font-medium">{{ word }}</span>
75
- <input type="checkbox" name="word_{{ word.id }}" class="checkbox checkbox-md checkbox-secondary"
76
- data-word-id="{{ word.id }}" />
77
  </label>
78
  {% empty %}
79
  <p class="text-center text-gray-500">No hay palabras disponibles.</p>
@@ -84,6 +89,25 @@
84
  </button>
85
  </form>
86
  </article>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  </article>
88
  </article>
89
  {% endblock %}
 
6
 
7
  {% block content %}
8
  <article class="cts-container-main">
9
+ <article class="cts-wrap-content text-black relative">
10
  <header class="text-center flex-row max-sm:flex-col w-full items-stretch flex justify-around flex-wrap gap-2">
11
  <h1 class="rounded font-bold text-2xl bg-surface-ligt p-4 flex-1">
12
  Sesión usando <br>técnica
 
63
  </section>
64
  </article>
65
 
66
+ <p id="response-message"
67
+ class="text-white font-bold text-lg text-center bg-red-400 px-2 py-4 rounded-lg hidden">
68
+ Soy el mensaje para responder
69
+ </p>
70
+
71
  <article
72
+ class="words-check-container bg-surface-card w-full max-w-3xl mx-auto p-6 bg-base-200 rounded-xl shadow-lg text-center">
73
  <form id="wordsForm" method="POST" class="flex flex-col gap-4">
74
  {% csrf_token %}
75
  <div class="grid lg:grid-cols-4 md:grid-cols-3 grid-cols-2 gap-4">
 
77
  <label
78
  class="flex items-center justify-between bg-surface-sweet p-4 gap-2 rounded-lg shadow-sm hover:shadow-md transition-all">
79
  <span class="text-lg font-medium">{{ word }}</span>
80
+ <input type="checkbox" name="word_{{ word.id }}" class="checkbox checkbox-primary"
81
+ data-word-id="{{ word.id }}" data-word-name="{{ word }}" />
82
  </label>
83
  {% empty %}
84
  <p class="text-center text-gray-500">No hay palabras disponibles.</p>
 
89
  </button>
90
  </form>
91
  </article>
92
+
93
+ <section id="confirmModal" class="absolute w-full h-full left-0 top-0 flex justify-center items-center bg-gray-500/70 hidden">
94
+ <div class="absolute max-w-xl bg-surface-card shadow-lg rounded-lg p-4">
95
+ <div class="space-y-4">
96
+ <h3 class="font-bold text-lg mb-4">Confirma tu elección</h3>
97
+ <div id="confirmModalContent" class="space-y-2 max-h-60 overflow-y-auto">
98
+ </div>
99
+ <div>
100
+ <button id="cancelBtn" class="cts-btn-general-compress cts-btn-secondary btn-push py-1 px-4">
101
+ Cancelar
102
+ </button>
103
+ <button id="confirmBtn" class="cts-btn-general-compress cts-btn-primary btn-push py-1 px-4">
104
+ Confirmar
105
+ </button>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </section>
110
+
111
  </article>
112
  </article>
113
  {% endblock %}
tecnicas/urls.py CHANGED
@@ -128,7 +128,11 @@ urlpatterns = [
128
  views.wordsVocabulary,
129
  name="api_palabras_vocabulary"),
130
 
131
- path("testers/api/ratingword",
132
- views.reatingWord,
133
- name="api_rating_word"),
 
 
 
 
134
  ]
 
128
  views.wordsVocabulary,
129
  name="api_palabras_vocabulary"),
130
 
131
+ path("testers/api/ratingword/escalas",
132
+ views.ratingWordScales,
133
+ name="api_rating_word_scalas"),
134
+
135
+ path("testers/api/ratingword/cata",
136
+ views.ratingWordCata,
137
+ name="api_rating_word_cata"),
138
  ]
tecnicas/views/__init__.py CHANGED
@@ -25,7 +25,8 @@ from .vocabulary_management.list_vocabulary import listVocabulary
25
  from .apis.api_tag import newTag
26
  from .apis.api_words import words
27
  from .apis.api_words import wordsVocabulary
28
- from .apis.rating_word import reatingWord
 
29
 
30
  from .tester_forms.init_tester_form import initTesterForm
31
  from .tester_forms.panel_main_tester import mainPanelTester
@@ -33,4 +34,3 @@ from .tester_forms.login_session import loginSessionTester
33
  from .tester_forms.sessions_list_tester import sessionsListTester
34
  from .tester_forms.convencional_scales import convencionalScales
35
  from .tester_forms.cata_test import cataTest
36
-
 
25
  from .apis.api_tag import newTag
26
  from .apis.api_words import words
27
  from .apis.api_words import wordsVocabulary
28
+ from .apis.rating_word_scales import ratingWordScales
29
+ from .apis.rating_word_cata import ratingWordCata
30
 
31
  from .tester_forms.init_tester_form import initTesterForm
32
  from .tester_forms.panel_main_tester import mainPanelTester
 
34
  from .tester_forms.sessions_list_tester import sessionsListTester
35
  from .tester_forms.convencional_scales import convencionalScales
36
  from .tester_forms.cata_test import cataTest
 
tecnicas/views/apis/rating_word_cata.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from django.http import HttpRequest, JsonResponse
2
+ from tecnicas.utils import general_error
3
+ import json
4
+
5
+
6
+ def ratingWordCata(req: HttpRequest):
7
+ if req.method == "POST":
8
+ try:
9
+ data = json.loads(req.body.decode("utf-8"))
10
+ words = data.get("words", [])
11
+
12
+ print(words)
13
+
14
+ return JsonResponse({"message": "Datos recibidos correctamente"})
15
+ except Exception as e:
16
+ print("Error:", e)
17
+ return JsonResponse({"error": "Error procesando datos"}, status=400)
18
+
19
+ else:
20
+ return JsonResponse({"error": "Método no permitido"}, status=405)
tecnicas/views/apis/{rating_word.py → rating_word_scales.py} RENAMED
@@ -28,12 +28,12 @@
28
  * Calquier otro metodo que se maneje mandar un error
29
  '''
30
  from django.http import HttpRequest, JsonResponse
31
- from tecnicas.controllers import ApiRatingController, CalificacionController, DatoController
32
  from tecnicas.utils import general_error
33
  import json
34
 
35
 
36
- def reatingWord(req: HttpRequest):
37
  if req.method == "POST":
38
  if not req.POST["rating-word"] or not req.POST["id-word"] or not req.POST["id-product"]:
39
  return JsonResponse({"error": "No se mandó información necesaria para la calificación"})
@@ -43,7 +43,7 @@ def reatingWord(req: HttpRequest):
43
  received_id_product = json.loads(req.POST.get("id-product"))
44
  id_technique = json.loads(req.POST.get("id-technique"))
45
 
46
- view_controller = ApiRatingController(
47
  rating_controller=CalificacionController(
48
  technique=id_technique,
49
  product=received_id_product,
@@ -60,4 +60,4 @@ def reatingWord(req: HttpRequest):
60
 
61
  return JsonResponse(response_data)
62
  else:
63
- return general_error("No puede usar este método aquí")
 
28
  * Calquier otro metodo que se maneje mandar un error
29
  '''
30
  from django.http import HttpRequest, JsonResponse
31
+ from tecnicas.controllers import RatingScalesController, CalificacionController, DatoController
32
  from tecnicas.utils import general_error
33
  import json
34
 
35
 
36
+ def ratingWordScales(req: HttpRequest):
37
  if req.method == "POST":
38
  if not req.POST["rating-word"] or not req.POST["id-word"] or not req.POST["id-product"]:
39
  return JsonResponse({"error": "No se mandó información necesaria para la calificación"})
 
43
  received_id_product = json.loads(req.POST.get("id-product"))
44
  id_technique = json.loads(req.POST.get("id-technique"))
45
 
46
+ view_controller = RatingScalesController(
47
  rating_controller=CalificacionController(
48
  technique=id_technique,
49
  product=received_id_product,
 
60
 
61
  return JsonResponse(response_data)
62
  else:
63
+ return general_error("No puede usar este método aquí")