Advertisement
losvilos

clientes.js

Feb 26th, 2025
220
0
20 hours
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. document.addEventListener('DOMContentLoaded', function() {
  2.  
  3.  
  4.     // Función para cargar avenidas (se mantiene sin cambios)
  5.     // clientes.js
  6. function cargarAvenidas(zonaId, avenidaSelectId, avenidaSeleccionada = null) {
  7.     let avenidaSelect = document.getElementById(avenidaSelectId);
  8.     if (!avenidaSelect || !zonaId) return;
  9.  
  10.     avenidaSelect.innerHTML = "<option value=''>Cargando avenidas...</option>";
  11.  
  12.     fetch(`/get_avenidas/${zonaId}/`)
  13.         .then(response => {
  14.             if (!response.ok) throw new Error(`Error ${response.status}`);
  15.             return response.json();
  16.         })
  17.         .then(data => {
  18.             avenidaSelect.innerHTML = "<option value=''>Selecciona una avenida</option>";
  19.             if (data.avenidas && data.avenidas.length > 0) {
  20.                 data.avenidas.forEach(avenida => {
  21.                     let option = document.createElement("option");
  22.                     option.value = avenida.id;
  23.                     option.textContent = avenida.nombre;
  24.                     if (avenidaSeleccionada == avenida.id) option.selected = true;
  25.                     avenidaSelect.appendChild(option);
  26.                 });
  27.             } else {
  28.                 avenidaSelect.innerHTML = "<option value=''>No hay avenidas</option>";
  29.             }
  30.         })
  31.         .catch(error => {
  32.             console.error("Error al cargar avenidas:", error);
  33.             avenidaSelect.innerHTML = "<option value=''>Error al cargar</option>";
  34.         });
  35. }
  36.  
  37.     // Eventos para cargar avenidas (se combinan los listeners repetidos)
  38.     const zonaSelect = document.getElementById("id_zona");
  39.     const editZonaSelect = document.getElementById("edit_zona");
  40.  
  41.     if (zonaSelect) {
  42.         zonaSelect.addEventListener("change", function () {
  43.             let zonaId = this.value;
  44.             console.log(" Cargando avenidas para la zona seleccionada:", zonaId);
  45.             cargarAvenidas(zonaId, "id_avenida");
  46.         });
  47.     }
  48.  
  49.     if (editZonaSelect) {
  50.         editZonaSelect.addEventListener("change", function () {
  51.             let zonaId = this.value;
  52.             console.log(" Cargando avenidas para zona en edición:", zonaId);
  53.             cargarAvenidas(zonaId, "edit_avenida");
  54.         });
  55.     }
  56.  
  57. // --- EDICIÓN DE CLIENTE ---
  58. document.querySelectorAll(".btn-editar").forEach(button => {
  59.     button.addEventListener("click", function () {
  60.         let clienteId = this.getAttribute("data-id");
  61.  
  62.         fetch(`/clientes/${clienteId}/`, { method: "GET" })
  63.         .then(response => {
  64.             if (!response.ok) {
  65.                 throw new Error(`Error ${response.status}: No se pudo obtener la información del cliente.`);
  66.             }
  67.             return response.json();
  68.         })
  69.         .then(data => {
  70.             console.log("Datos recibidos del cliente:", data);
  71.  
  72.             // Llenar los campos del formulario de edición
  73.             document.getElementById("edit_id").value = data.id;
  74.             document.getElementById("edit_documento").value = data.documento;
  75.             document.getElementById("edit_nombre").value = data.nombre;
  76.             document.getElementById("edit_apellido_paterno").value = data.apellido_paterno;
  77.             document.getElementById("edit_apellido_materno").value = data.apellido_materno;
  78.             document.getElementById("edit_fecha_nacimiento").value = data.fecha_nacimiento;
  79.             document.getElementById("edit_sexo").value = data.sexo;
  80.             document.getElementById("edit_telefono").value = data.telefono;
  81.             document.getElementById("edit_email").value = data.email;
  82.  
  83.             // Cargar la dirección, zona y avenida desde el array "direcciones"
  84.             if (data.direcciones && data.direcciones.length > 0) {
  85.                 document.getElementById("edit_direccion").value = data.direcciones[0].direccion;
  86.                 document.getElementById("edit_zona").value = data.direcciones[0].zona_id || "";
  87.                 // Si tienes la función cargarAvenidas, la llamas para actualizar el select de avenidas:
  88.                 cargarAvenidas(data.direcciones[0].zona_id, "edit_avenida", data.direcciones[0].avenida_id);
  89.             } else {
  90.                 document.getElementById("edit_direccion").value = "";
  91.                 document.getElementById("edit_zona").value = "";
  92.                 document.getElementById("edit_avenida").value = "";
  93.             }
  94.  
  95.             // Manejo del campo 'edit_estatus' (cambiar esta línea)
  96.             const estatusElement = document.getElementById("edit_estatus");
  97.             if (estatusElement) {
  98.                 console.log("Elemento 'edit_estatus' encontrado.");
  99.                 estatusElement.value = data.estatus ? "1" : "0"; // Establecer el valor del <select>
  100.             } else {
  101.                 console.error("El elemento 'edit_estatus' no fue encontrado.");
  102.             }
  103.  
  104.             // Mostrar el modal de edición
  105.             $("#modalEditarCliente").modal("show");
  106.  
  107.             // Configurar el submit del formulario de edición
  108.             const formEditarCliente = document.getElementById('formEditarCliente');
  109.             formEditarCliente.action = `/clientes/${clienteId}/`; // URL correcta
  110.  
  111.             formEditarCliente.onsubmit = function(event) {
  112.                 event.preventDefault();
  113.                 const formData = new FormData(formEditarCliente);
  114.  
  115.                 fetch(formEditarCliente.action, {
  116.                     method: 'POST',
  117.                     body: formData,
  118.                     headers: {
  119.                         'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
  120.                     }
  121.                 })
  122.                 .then(response => {
  123.                     if (!response.ok) {
  124.                         return response.json().then(err => {throw new Error(err.error || `Error ${response.status}: No se pudo guardar los cambios del cliente.`)});
  125.                     }
  126.                     return response.json();
  127.                 })
  128.                 .then(data => {
  129.                     console.log("Respuesta del servidor:", data);
  130.                     $('#modalEditarCliente').modal('hide');
  131.                     Swal.fire("Éxito", data.mensaje, "success").then(() => {
  132.                         window.location.reload();
  133.                     });
  134.                 })
  135.                 .catch(error => {
  136.                     console.error("Error al guardar los cambios del cliente:", error);
  137.                     Swal.fire("Error", error.message, "error");
  138.                 });
  139.             };
  140.         })
  141.         .catch(error => {
  142.             console.error("Error al obtener datos del cliente:", error);
  143.             Swal.fire("Error", error.message, "error");
  144.         });
  145.     });
  146. });
  147.  
  148.  
  149.    
  150.  
  151. function editarCliente(clienteId) {
  152.     // Nota: Asegúrate de tener definida "formData" si la usas aquí;
  153.     // de lo contrario, si lo usas sólo en el submit del modal, elimina esta línea.
  154.     fetch(`/clientes/${clienteId}/`, { // URL corregida
  155.         method: 'POST',
  156.         body: formData, // Asegúrate de definir "formData" si es necesario o elimínalo
  157.         headers: {
  158.           'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
  159.         }
  160.       })
  161.     .then(response => {
  162.         if (!response.ok) {
  163.             return response.json().then(err => {throw new Error(err.error || `Error ${response.status}: No se pudo obtener la información del cliente.`)});
  164.         }
  165.         return response.json();
  166.     })
  167.     .then(data => {
  168.         console.log("Datos recibidos del cliente:", data);
  169.  
  170.         document.getElementById("edit_documento").value = data.documento;
  171.         document.getElementById("edit_nombre").value = data.nombre;
  172.         document.getElementById("edit_apellido_paterno").value = data.apellido_paterno;
  173.         document.getElementById("edit_apellido_materno").value = data.apellido_materno;
  174.         document.getElementById("edit_fecha_nacimiento").value = data.fecha_nacimiento;
  175.         document.getElementById("edit_sexo").value = data.sexo;
  176.         document.getElementById("edit_telefono").value = data.telefono;
  177.         document.getElementById("edit_email").value = data.email;
  178.        
  179.         // Reemplazamos la antigua asignación de data.direccion por la lectura del array "direcciones"
  180.         if (data.direcciones && data.direcciones.length > 0) {
  181.             document.getElementById("edit_direccion").value = data.direcciones[0].direccion;
  182.             // Asumiendo que tu vista ahora incluye zona_id y avenida_id en cada dirección
  183.             document.getElementById("edit_zona").value = data.direcciones[0].zona_id || "";
  184.             document.getElementById("edit_avenida").value = data.direcciones[0].avenida_id || "";
  185.         } else {
  186.             document.getElementById("edit_direccion").value = "";
  187.             document.getElementById("edit_zona").value = "";
  188.             document.getElementById("edit_avenida").value = "";
  189.         }
  190.  
  191.         // Manejo de data.estatus (si es numérico)
  192.         const editEstatusCheckbox = document.getElementById("edit_estatus");
  193.         if (typeof data.estatus === 'number') {
  194.             editEstatusCheckbox.checked = data.estatus === 1;
  195.         } else {
  196.             editEstatusCheckbox.checked = data.estatus;
  197.         }
  198.  
  199.         const formEditarCliente = document.getElementById('formEditarCliente');
  200.         formEditarCliente.action = `/clientes/${clienteId}/`; // URL corregida
  201.  
  202.         formEditarCliente.onsubmit = function(event) {
  203.             event.preventDefault();
  204.             const formData = new FormData(formEditarCliente);
  205.             fetch(formEditarCliente.action, {
  206.                 method: 'POST',
  207.                 body: formData,
  208.                 headers: {
  209.                     'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
  210.                 }
  211.             })
  212.             .then(response => {
  213.                 if (!response.ok) {
  214.                     return response.json().then(err => {throw new Error(err.error || `Error ${response.status}: No se pudo guardar los cambios del cliente.`)});
  215.                 }
  216.                 return response.json();
  217.             })
  218.             .then(data => {
  219.                 console.log("Respuesta del servidor:", data);
  220.                 $('#modalEditarCliente').modal('hide');
  221.                 window.location.reload();
  222.                 Swal.fire("Éxito", data.message, "success");
  223.             })
  224.             .catch(error => {
  225.                 console.error("Error al guardar los cambios del cliente:", error);
  226.                 Swal.fire("Error", error.message, "error");
  227.             });
  228.         };
  229.  
  230.         $('#modalEditarCliente').modal('show');
  231.     })
  232.     .catch(error => {
  233.         console.error("Error al obtener datos del cliente:", error);
  234.         Swal.fire("Error", error.message, "error");
  235.     });
  236. }
  237.  
  238.    
  239.    
  240.    // --- ELIMINACIÓN DE CLIENTE ---
  241.    document.querySelectorAll(".btn-eliminar").forEach(btn => {
  242.     btn.addEventListener("click", async function () {
  243.         let clienteId = this.getAttribute("data-id");
  244.  
  245.         Swal.fire({
  246.             title: "¿Estás seguro?",
  247.             text: "Esta acción no se puede deshacer.",
  248.             icon: "warning",
  249.             showCancelButton: true,
  250.             confirmButtonColor: "#d33",
  251.             cancelButtonColor: "#3085d6",
  252.             confirmButtonText: "Sí, eliminar",
  253.             cancelButtonText: "Cancelar"
  254.         }).then(async (result) => {
  255.             if (result.isConfirmed) {
  256.                 try {
  257.                     let response = await fetch(`/clientes/eliminar/${clienteId}/`, {
  258.                         method: "DELETE"
  259.                     });
  260.  
  261.                     let data = await response.json();
  262.  
  263.                     if (response.ok) {
  264.                         Swal.fire("Eliminado", "El cliente ha sido eliminado.", "success");
  265.  
  266.                         //  Eliminar fila de la tabla sin recargar la página
  267.                         let fila = document.querySelector(`tr[data-id="${clienteId}"]`);
  268.                         if (fila) {
  269.                             fila.remove();
  270.                         }
  271.                     } else {
  272.                         Swal.fire("Error", "No se pudo eliminar el cliente.", "error");
  273.                     }
  274.                 } catch (error) {
  275.                     console.error("❌ Error en la solicitud:", error);
  276.                     Swal.fire("Error", "No se pudo eliminar el cliente.", "error");
  277.                 }
  278.             }
  279.         });
  280.     });
  281. });
  282.    
  283.  
  284.  
  285. document.addEventListener("DOMContentLoaded", function () {
  286.     const formNuevoCliente = document.getElementById("formNuevoCliente");
  287.  
  288.     if (formNuevoCliente) {
  289.         formNuevoCliente.addEventListener("submit", async function (event) {
  290.             event.preventDefault(); // Evita el envío tradicional del formulario
  291.  
  292.             try {
  293.                 // Mostrar un indicador de carga
  294.                 Swal.fire({
  295.                     title: "Procesando...",
  296.                     html: "Por favor, espere.",
  297.                     allowOutsideClick: false,
  298.                     didOpen: () => {
  299.                         Swal.showLoading();
  300.                     },
  301.                 });
  302.  
  303.                 // Crear un FormData con los datos del formulario
  304.                 const formData = new FormData(this);
  305.  
  306.                 // Enviar la solicitud al servidor
  307.                 const response = await fetch("/clientes/agregar/", {
  308.                     method: "POST",
  309.                     body: formData,
  310.                     headers: {
  311.                         "X-CSRFToken": "{{ csrf_token }}", // Asegúrate de incluir el token CSRF
  312.                     },
  313.                 });
  314.  
  315.                 // Verificar si la respuesta es exitosa
  316.                 if (response.ok) {
  317.                     const data = await response.json();
  318.  
  319.                     // Mostrar mensaje de éxito
  320.                     Swal.fire({
  321.                         icon: "success",
  322.                         title: "Éxito",
  323.                         text: data.mensaje || "Cliente agregado correctamente.",
  324.                     }).then(() => {
  325.                         // Construir la nueva fila para la tabla
  326.                         const nuevaFila = `
  327.                             <tr data-id="${data.id}">
  328.                                 <td class="documento">${data.documento}</td>
  329.                                 <td class="nombre">${data.nombre} ${data.apellido_paterno} ${
  330.                             data.apellido_materno || ""
  331.                         }</td>
  332.                                 <td class="telefono">${data.telefono}</td>
  333.                                 <td class="email">${data.email || ""}</td>
  334.                                 <td>
  335.                                     <span class="badge estatus ${
  336.                                        data.estatus ? "bg-success" : "bg-danger"
  337.                                    }">
  338.                                         ${data.estatus ? "Activo" : "Inactivo"}
  339.                                     </span>
  340.                                 </td>
  341.                                 <td>
  342.                                     <a class="btn btn-sm btn-primary" href="/clientes/${data.id}/">Ver detalle</a>
  343.                                     <button class="btn btn-info btn-sm btn-editar" data-id="${data.id}">
  344.                                         <i class="fa fa-edit"></i> Editar
  345.                                     </button>
  346.                                     <button class="btn btn-danger btn-sm btn-eliminar" data-id="${data.id}">
  347.                                         <i class="fa fa-trash"></i> Eliminar
  348.                                     </button>
  349.                                 </td>
  350.                             </tr>
  351.                         `;
  352.  
  353.                         // Insertar la nueva fila en la tabla
  354.                         document.querySelector("table tbody").insertAdjacentHTML("beforeend", nuevaFila);
  355.  
  356.                         // Cerrar el modal y limpiar el formulario
  357.                         $("#modalAgregarCliente").modal("hide");
  358.                         formNuevoCliente.reset();
  359.  
  360.                         // Enfocar un elemento visible (opcional)
  361.                         document.querySelector("body").focus();
  362.                     });
  363.                 } else {
  364.                     // Manejar errores de la respuesta
  365.                     const errorData = await response.json();
  366.                     const errorMessage =
  367.                         errorData.error || errorData.message || "No se pudo agregar el cliente.";
  368.                     Swal.fire({
  369.                         icon: "error",
  370.                         title: "Error",
  371.                         text: errorMessage,
  372.                     });
  373.                 }
  374.             } catch (error) {
  375.                 // Manejar errores inesperados
  376.                 console.error("❌ Error en la solicitud:", error);
  377.                 Swal.fire({
  378.                     icon: "error",
  379.                     title: "Error",
  380.                     text: "Ocurrió un error inesperado. Por favor, inténtalo de nuevo.",
  381.                 });
  382.             }
  383.         });
  384.     } else {
  385.         console.error("El formulario 'formNuevoCliente' no fue encontrado.");
  386.     }
  387. });
  388.  
  389.  
  390. document.addEventListener("DOMContentLoaded", function () {
  391.     const direccionesContainer = document.getElementById("direcciones");
  392.     const agregarDireccionBtn = document.getElementById("agregarDireccion");
  393.  
  394.     if (direccionesContainer && agregarDireccionBtn) {
  395.         let contadorDirecciones = 1;
  396.  
  397.         // Función para clonar y modificar nuevas direcciones
  398.         const clonarDireccion = () => {
  399.             contadorDirecciones++;
  400.            
  401.             // 1. Clonar la primera dirección (que ya tiene las zonas procesadas por Django)
  402.             const primeraDireccion = document.querySelector(".direccion");
  403.             const clon = primeraDireccion.cloneNode(true);
  404.            
  405.             // 2. Actualizar elementos del clon
  406.             clon.querySelector("h5").textContent = `Dirección ${contadorDirecciones}`;
  407.            
  408.             // 3. Limpiar valores y agregar eventos
  409.             clon.querySelectorAll("select, input").forEach(elemento => {
  410.                 elemento.value = ""; // Limpiar valores
  411.                
  412.                 // Agregar evento change para zonas
  413.                 if (elemento.name === "zona[]") {
  414.                     elemento.addEventListener("change", function() {
  415.                         const avenidaSelect = this.closest(".direccion").querySelector("select[name='avenida[]']");
  416.                         cargarAvenidas(this.value, avenidaSelect.id);
  417.                     });
  418.                 }
  419.             });
  420.  
  421.             // 4. Agregar al contenedor
  422.             direccionesContainer.appendChild(clon);
  423.         };
  424.  
  425.         // Evento para botón agregar dirección
  426.         agregarDireccionBtn.addEventListener("click", clonarDireccion);
  427.  
  428.         // Cargar avenidas para la primera dirección
  429.         document.querySelectorAll("select[name='zona[]']").forEach(zonaSelect => {
  430.             zonaSelect.addEventListener("change", function() {
  431.                 const avenidaSelect = this.closest(".direccion").querySelector("select[name='avenida[]']");
  432.                 cargarAvenidas(this.value, avenidaSelect.id);
  433.             });
  434.         });
  435.  
  436.     } else {
  437.         console.error("Elementos requeridos no encontrados");
  438.     }
  439. });
  440.  
  441. // Función para cargar avenidas (debe estar definida)
  442. function cargarAvenidas(zonaId, avenidaSelectId) {
  443.     const avenidaSelect = document.getElementById(avenidaSelectId);
  444.     if (!zonaId || !avenidaSelect) return;
  445.  
  446.     avenidaSelect.innerHTML = '<option value="">Cargando...</option>';
  447.    
  448.     fetch(`/get_avenidas/${zonaId}/`)
  449.         .then(response => response.json())
  450.         .then(data => {
  451.             avenidaSelect.innerHTML = '<option value="">Selecciona avenida</option>';
  452.             data.avenidas.forEach(avenida => {
  453.                 const option = document.createElement("option");
  454.                 option.value = avenida.id;
  455.                 option.textContent = avenida.nombre;
  456.                 avenidaSelect.appendChild(option);
  457.             });
  458.         })
  459.         .catch(error => {
  460.             console.error("Error:", error);
  461.             avenidaSelect.innerHTML = '<option value="">Error al cargar</option>';
  462.         });
  463. }
  464.  
  465.  
  466. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement