JairoDanielMT commited on
Commit
5e01b01
·
verified ·
1 Parent(s): e853f5f
Files changed (1) hide show
  1. scripts.js +130 -186
scripts.js CHANGED
@@ -1,186 +1,130 @@
1
- $(document).ready(function () {
2
- // Cambiar las categorías según el tipo seleccionado
3
- $('#tipo').change(function () {
4
- const tipo = $(this).val();
5
- $.get('/categorias/' + tipo, function (data) {
6
- $('#categoria').empty();
7
- if (data.length > 0) {
8
- data.forEach(function (categoria) {
9
- $('#categoria').append(
10
- $('<option>', { value: categoria.id_categoria, text: categoria.nombre_categoria })
11
- );
12
- });
13
- $('#categoria').val(data[0].id_categoria).change(); // Selecciona la primera categoría si hay opciones
14
- } else {
15
- $('#categoria').append('<option value="">No hay categorías disponibles</option>');
16
- $('#subcategoria').empty().append('<option value="">Seleccione una categoría primero</option>');
17
- }
18
- });
19
- });
20
-
21
- // Cambiar las subcategorías según la categoría seleccionada
22
- $('#categoria').change(function () {
23
- const categoriaId = $(this).val();
24
- $.get('/subcategorias/' + categoriaId, function (data) {
25
- $('#subcategoria').empty();
26
- if (data.length > 0) {
27
- data.forEach(function (subcategoria) {
28
- $('#subcategoria').append(
29
- $('<option>', { value: subcategoria.id_subcategoria, text: subcategoria.nombre_subcategoria })
30
- );
31
- });
32
- } else {
33
- $('#subcategoria').append('<option value="">No hay subcategorías disponibles</option>');
34
- }
35
- });
36
- });
37
- // Manejar la acción de enviar el formulario
38
- $('#transaccion-form').on('submit', function (e) {
39
- e.preventDefault(); // Prevenir el comportamiento por defecto del formulario
40
- const formData = $(this).serializeArray(); // Serializar los datos del formulario
41
- let jsonData = {}; // Inicializar objeto JSON
42
-
43
- // Obtener la fecha y hora actual en la zona horaria de América/Lima
44
- const datetime = new Date().toLocaleString('es-PE', {
45
- timeZone: 'America/Lima',
46
- hour12: false // 24-hour format
47
- });
48
-
49
- // Convertir el formato de fecha y hora a yyyy-mm-dd hh:mm:ss
50
- const formattedDatetime = datetime.replace(/(\d+)\/(\d+)\/(\d+), (\d+):(\d+):(\d+)/, '$3-$2-$1 $4:$5:$6');
51
-
52
- // Añadir el datetime formateado a los datos del formulario
53
- jsonData['fecha'] = formattedDatetime;
54
-
55
- // Convertir los datos del formulario a un objeto JSON
56
- formData.forEach(function (item) {
57
- jsonData[item.name] = item.value;
58
- });
59
-
60
- mostrarSpinner(); // Mostrar el spinner mientras se envían los datos
61
-
62
- // Realizar la solicitud POST a Google Apps Script
63
- fetch('https://script.google.com/macros/s/AKfycbyoS_q9j7Hixi1-dxVg6S7LKqb9o_Pma2I0mnBPmZ_vlKKSWyPY8lpw66woTMkyaD04/exec', {
64
- method: 'POST',
65
- headers: {
66
- 'Content-Type': 'application/json',
67
- },
68
- body: JSON.stringify([jsonData]), // Enviar los datos como un array de objetos JSON
69
- mode: 'no-cors' // Evitar errores de CORS
70
- })
71
- .then(() => {
72
- // Procesar la respuesta si es necesario, pero sin acceso al contenido de la respuesta
73
- $('#mensaje').html('<div class="bg-green-500 p-3 rounded-lg">¡Transacción registrada exitosamente!</div>');
74
-
75
- // Después de 4 segundos, recargar la página
76
- setTimeout(() => {
77
- location.reload();
78
- }, 4000); // 4000 milisegundos = 4 segundos
79
- })
80
- .catch(error => {
81
- $('#mensaje').html('<div class="bg-red-500 p-3 rounded-lg">Hubo un problema con la solicitud.</div>');
82
- })
83
- .finally(() => {
84
- $('#loading').hide(); // Ocultar el spinner después de la respuesta
85
- });
86
- });
87
-
88
-
89
- });
90
-
91
- // Función para mostrar el spinner
92
- function mostrarSpinner() {
93
- $('#loading').show(); // Mostrar el spinner
94
- }
95
-
96
- /**
97
- * Cargar los datos de los selects de tipo, categoria y subcategoria desde un archivo JSON.
98
- */
99
- let data; // Declarar la variable data globalmente
100
-
101
- // Cargar el archivo JSON y almacenarlo en la variable data
102
- fetch('tipos_categoria_subcategoria.json')
103
- .then(response => response.json())
104
- .then(jsonData => {
105
- data = jsonData; // Asignar los datos JSON a la variable global
106
- cargarTipos(); // Llamar a cargarTipos después de que los datos se hayan cargado
107
- })
108
- .catch(error => console.error('Error al cargar el archivo JSON:', error));
109
-
110
- // Llenar el select de tipos
111
- function cargarTipos() {
112
- const tipoSelect = document.getElementById('tipo');
113
- for (const tipo in data.tipo) {
114
- const option = document.createElement('option');
115
- option.value = tipo;
116
- option.textContent = tipo;
117
- tipoSelect.appendChild(option);
118
- }
119
- }
120
-
121
- // Llenar el select de categorías según el tipo seleccionado
122
- function cargarCategorias() {
123
- const tipoSelect = document.getElementById('tipo');
124
- const categoriaSelect = document.getElementById('categoria');
125
- // Limpiar categorías anteriores
126
- categoriaSelect.innerHTML = '<option value="">Selecciona una categoría</option>';
127
-
128
- if (tipoSelect.value) {
129
- const categorias = Object.keys(data.tipo[tipoSelect.value]);
130
- categorias.forEach(categoria => {
131
- const option = document.createElement('option');
132
- option.value = categoria;
133
- option.textContent = categoria;
134
- categoriaSelect.appendChild(option);
135
- });
136
- }
137
- }
138
-
139
- // Llenar el select de subcategorías según la categoría seleccionada
140
- function cargarSubcategorias() {
141
- const tipoSelect = document.getElementById('tipo');
142
- const categoriaSelect = document.getElementById('categoria');
143
- const subcategoriaSelect = document.getElementById('subcategoria');
144
- // Limpiar subcategorías anteriores
145
- subcategoriaSelect.innerHTML = '<option value="">Selecciona una subcategoría</option>';
146
-
147
- if (categoriaSelect.value) {
148
- const subcategorias = data.tipo[tipoSelect.value][categoriaSelect.value];
149
- subcategorias.forEach(subcategoria => {
150
- const option = document.createElement('option');
151
- option.value = subcategoria;
152
- option.textContent = subcategoria;
153
- subcategoriaSelect.appendChild(option);
154
- });
155
- }
156
- }
157
-
158
- /**
159
- * Cargar usuarios desde un archivo JSON.
160
- */
161
- let usuarios;
162
-
163
- // Cargar el archivo JSON y asignar los datos a la variable global `usuarios`
164
- fetch('usuarios.json')
165
- .then(response => response.json())
166
- .then(jsonData => {
167
- usuarios = jsonData; // Asignar los usuarios del JSON a la variable
168
- cargarUsuarios(); // Llamar a la función para cargar los usuarios en el select
169
- })
170
- .catch(error => console.error('Error al cargar el archivo JSON:', error));
171
-
172
- // Cargar los usuarios en el select
173
- function cargarUsuarios() {
174
- const usuarioSelect = document.getElementById('usuario');
175
-
176
- // Limpiar las opciones existentes antes de agregar nuevas
177
- usuarioSelect.innerHTML = '<option value="">Selecciona un usuario</option>';
178
-
179
- // Agregar las nuevas opciones de usuario
180
- for (const usuario of usuarios.nombre_usuarios) {
181
- const option = document.createElement('option');
182
- option.value = usuario;
183
- option.textContent = usuario;
184
- usuarioSelect.appendChild(option);
185
- }
186
- }
 
1
+ $(document).ready(function () {
2
+ // Cacheo de selectores
3
+ const $selectors = {
4
+ tipo: $('#tipo'),
5
+ categoria: $('#categoria'),
6
+ subcategoria: $('#subcategoria'),
7
+ usuario: $('#usuario'),
8
+ form: $('#transaccion-form'),
9
+ mensaje: $('#mensaje'),
10
+ loading: $('#loading')
11
+ };
12
+
13
+ // Variables de estado
14
+ let appData = {
15
+ tipos: null,
16
+ usuarios: null
17
+ };
18
+
19
+ // Carga inicial de datos
20
+ Promise.all([
21
+ fetch('tipos_categoria_subcategoria.json').then(r => r.json()),
22
+ fetch('usuarios.json').then(r => r.json())
23
+ ])
24
+ .then(([tipos, usuarios]) => {
25
+ appData.tipos = tipos;
26
+ appData.usuarios = usuarios;
27
+ initSelects();
28
+ })
29
+ .catch(error => showError('Error cargando datos iniciales', error));
30
+
31
+ // Inicialización de selects
32
+ function initSelects() {
33
+ populateSelect($selectors.tipo, Object.keys(appData.tipos.tipo), 'Selecciona un tipo');
34
+ populateSelect($selectors.usuario, appData.usuarios.nombre_usuarios, 'Selecciona un usuario');
35
+ initEventHandlers();
36
+ }
37
+
38
+ // Configuración de manejadores de eventos
39
+ function initEventHandlers() {
40
+ $selectors.tipo.on('change', handleTipoChange);
41
+ $selectors.categoria.on('change', handleCategoriaChange);
42
+ $selectors.form.on('submit', handleFormSubmit);
43
+ }
44
+
45
+ // Manejador de cambio de tipo
46
+ function handleTipoChange() {
47
+ const tipo = $(this).val();
48
+ const categorias = tipo ? Object.keys(appData.tipos.tipo[tipo]) : [];
49
+
50
+ populateSelect($selectors.categoria, categorias, 'Selecciona una categoría');
51
+ populateSelect($selectors.subcategoria, [], 'Selecciona una subcategoría');
52
+ }
53
+
54
+ // Manejador de cambio de categoría
55
+ function handleCategoriaChange() {
56
+ const tipo = $selectors.tipo.val();
57
+ const categoria = $(this).val();
58
+ const subcategorias = (tipo && categoria) ?
59
+ appData.tipos.tipo[tipo][categoria] : [];
60
+
61
+ populateSelect($selectors.subcategoria, subcategorias, 'Selecciona una subcategoría');
62
+ }
63
+
64
+ // Manejador de envío de formulario
65
+ async function handleFormSubmit(e) {
66
+ e.preventDefault();
67
+
68
+ try {
69
+ $selectors.loading.show();
70
+ const formData = getFormData();
71
+
72
+ await sendData(formData);
73
+
74
+ showSuccess('¡Transacción registrada exitosamente!');
75
+ setTimeout(() => location.reload(), 4000);
76
+ } catch (error) {
77
+ showError('Error al enviar formulario', error);
78
+ } finally {
79
+ $selectors.loading.hide();
80
+ }
81
+ }
82
+
83
+ // Helpers
84
+ function populateSelect($select, items, defaultText) {
85
+ const options = items.length > 0 ?
86
+ items.map(item => `<option value="${item}">${item}</option>`) :
87
+ [`<option value="">${defaultText}</option>`];
88
+
89
+ $select.html([`<option value="">${defaultText}</option>`, ...options]);
90
+ }
91
+
92
+ function getFormData() {
93
+ const formData = Object.fromEntries($selectors.form.serializeArray().map(x => [x.name, x.value]));
94
+
95
+ // Formato de fecha para América/Lima
96
+ const now = new Date().toLocaleString('es-PE', {
97
+ timeZone: 'America/Lima',
98
+ year: 'numeric',
99
+ month: '2-digit',
100
+ day: '2-digit',
101
+ hour: '2-digit',
102
+ minute: '2-digit',
103
+ second: '2-digit',
104
+ hour12: false
105
+ });
106
+
107
+ const [fecha, hora] = now.split(', ');
108
+ return { ...formData, fecha: `${fecha.split('/').reverse().join('-')} ${hora}` };
109
+ }
110
+
111
+ async function sendData(data) {
112
+ const response = await fetch('https://script.google.com/macros/s/AKfycbyoS_q9j7Hixi1-dxVg6S7LKqb9o_Pma2I0mnBPmZ_vlKKSWyPY8lpw66woTMkyaD04/exec', {
113
+ method: 'POST',
114
+ headers: { 'Content-Type': 'application/json' },
115
+ body: JSON.stringify([data]),
116
+ mode: 'no-cors'
117
+ });
118
+
119
+ if (!response.ok) throw new Error('Error en la respuesta del servidor');
120
+ }
121
+
122
+ function showSuccess(message) {
123
+ $selectors.mensaje.html(`<div class="bg-green-500 p-3 rounded-lg">${message}</div>`);
124
+ }
125
+
126
+ function showError(context, error) {
127
+ console.error(`${context}:`, error);
128
+ $selectors.mensaje.html(`<div class="bg-red-500 p-3 rounded-lg">${error.message}</div>`);
129
+ }
130
+ });