3.4.16. CRUD de alumnos - diezMalena/api_FCTFiller GitHub Wiki

Planteamiento

Con el CRUD de alumnos, los directores de los centros educativos o los tutores de ciclos formativos podrán gestionar la creación, eliminación o edición de datos de los alumnos, así como tener acceso a la descarga de los anexos propios que dependen de los datos del alumno (FEM05)

Cuando el usuario que ha iniciado sesión en la aplicación es el director del centro educativo, se muestran los alumnos de todo el centro; cuando el usuario es tutor de ciclo formativo, los alumnos a los cuales tutoriza.

Los datos que se pueden gestionar en el CRUD de alumnos son los siguientes:

  • Foto del alumno
  • Código del alumno
  • DNI
  • Nombre
  • Apellidos
  • Fecha de nacimiento
  • Domicilio
  • Teléfono
  • Móvil
  • Correo electrónico
  • Contraseña de acceso a la aplicación
  • Provincia
  • Localidad
  • Currículum en formato PDF
  • Cuenta bancaria
  • Matrícula de coche
  • Código de matrícula (en el curso actual)
  • Grupo
  • Check que indica si va o no a FCT

Lectura de datos

Aplicable al resto del CRUD, se crea un servicio llamado CrudAlumnosService en el cliente Angular que gestiona todas las llamadas a la API REST Laravel.

Así, al iniciar la carga de la página, se invoca al método listarAlumnos(dni) de este servicio, que recibe por parámetro el DNI de la persona logeada en el sistema y realiza una petición HTTP a la ruta API api/listarAlumnos [get] que devuelve un JSON de un listado de alumnos con los datos anteriormente mencionados.

Tras recoger la información que entrega la llamada, se hace una suscripción .next([...]) a un objeto del tipo Subject<any> que actúa como observador y observable, dándose cuenta de los cambios que sucedan dentro del array de alumnos y pudiendo actualizar los datos en la tabla.

Por último, se invoca a la carga del componente DataTable en Angular, que implementa add-ons como la ordenación de columnas y la paginación en la tabla mostrada.

Creación de un alumno

Se crea un alumno mediante el modal ModalAlumnoComponent. Este modal mostrará información de sólo lectura o permitirá la inserción de un nuevo alumno con campos editables mediante el uso del enum ModoEdicion, que puede tener los valores siguientes:

export enum ModoEdicion {
  editar = 0,
  nuevo = 1,
  detalle = 2,
}

Cuando se terminan de informar los campos (al menos los marcados con un asterisco rojo) y se pulsa sobre el botón "Guardar", el componente comprueba antes de llamar al servicio que lanza la petición si los campos cumplen con las restricciones de obligatoriedad aplicadas. Si no, aparece un mensaje debajo de cada campo indicando al usuario que se han de cumplimentar dichos campos.

Si el formulario es válido, se recogen los datos del nuevo alumno, se invoca al método registrarAlumno(alumno: Alumno) del servicio y se llama a la ruta API api/addAlumno [post]. Si todo ha salido bien, el servidor devuelve un código HTTP estándar 200. Si algo ha fallado, se devuelve un error HTTP estándar 400.

Cuando se finaliza la invocación al servicio, se lleva a cabo el mismo procedimiento que en el caso de la lectura, realizando la petición de listado, suscribiéndose al observable, cerrándose el modal y apareciendo el nuevo alumno en la tabla.

Modificación de datos de un alumno

Al modificar a un alumno, sucede lo mismo que al crearlo, con la diferencia de que el modo de edición en este caso es 2, por lo que se precarga la información del alumno. Esta precarga de datos se lleva a cabo suscribiendo al alumno a una variable del servicio del tipo EventEmitter<any>. Al iniciar el modal, se consulta a este objeto si tiene un parámetro del tipo Alumno, cargando la información sin necesidad de realizar una petición al servidor.

Si el formulario es válido, se recogen los nuevos datos del alumno, se invoca al método actualizarAlumno(alumno: Alumno) del servicio y se llama a la ruta API api/modificarAlumno [post]. Si todo ha salido bien, el servidor devuelve un código HTTP estándar 200. Si algo ha fallado, se devuelve un error HTTP estándar 400.

Cuando se finaliza la invocación al servicio, se lleva a cabo el mismo procedimiento que en el caso de la lectura, realizando la petición de listado, suscribiéndose al observable, cerrándose el modal y apareciendo los nuevos datos del alumno en la tabla.

Eliminación de un alumno

Se invoca al método del servicio borrarAlumno(dni: string), que recibe por parámetro el DNI del alumno a eliminar. Este método llama a la ruta api api/eliminarAlumno/{dni} [delete].

Cuando se finaliza la invocación al servicio, se lleva a cabo el mismo procedimiento que en el caso de la lectura, realizando la petición de listado, suscribiéndose al observable, cerrándose el modal y desapareciendo el alumno de la tabla.

Subida de ficheros

Este CRUD tiene de especial la forma en la que se ha implementado la subida de ficheros. Se explicará de forma generalizada, puesto que con el currículum y la foto de perfil el procedimiento es similar.

Recuperación de datos del lado del servidor

Durante la consulta a la BBDD, el servidor recupera la ruta completa donde se aloja el fichero. Sin embargo, a la hora de devolver el array de objetos, se sustituye esta variable por una ruta hacia el servidor (api/descargarFotoPerfil/{$dni_alumno}/{$uuid} [get] o bien api/descargarCV/{$dni_alumno}/{$uuid} [get]) para que se pueda llamar a esta ruta API desde el atributo src del elemento img de la ficha o se pueda invocar desde el servicio la descarga del CV.

Subida de datos del lado cliente

El botón que se muestra no es más que un elemento label con clases de Bootstrap para que parezca un botón, con la propiedad for apuntando a un elmento input type="file" que está oculto. Esto es posible aprovechando las virtudes de HTML, ya que si se tiene un label relacionado con un input, al hacer click sobre el label el foco se pondrá sobre el input al que hace referencia.

Para hacernos con el fichero, debemos usar el siguiente código con el que obtenemos la cadena en base64 del archivo que se ha elegido:

let fileReader = new FileReader();
fileReader.readAsDataURL(event.target.files[0]);
fileReader.onload = function () {
 let element: any = document.getElementById('foto');
 //Para previsualizar la imagen, asignamos this.result (cadena en base64 del fichero) al src del elemento img 
 element.src = this.result;
 //Esta cadena en base64 es lo que recogerá el servidor y tratará de guardar como un fichero
 formulario['foto'].setValue(this.result)
};

Subida de datos del lado servidor

Una vez obtenemos el objeto Alumno a través de la petición, obtenemos la cadena base64 mediante la propiedad $request->foto o $request->curriculum

Tras ello, se llama a la función auxiliar Auxiliar::guardarFichero($path, $nombreFichero, $fichero), que devolverá la localización del fichero en el servidor en caso de que se haya guardado correctamente el fichero y false si se ha producido un error y no se ha guardado. Esta función auxiliar es capaz de reconocer la extensión del fichero, excepto para documentos del tipo Microsoft Office Open XML (.docx, .pptx, .xlsx, ...). Este bug se plantea arreglar en futuras versiones.

Una vez obtenida la carpeta física dónde se localiza el fichero, esta se guarda en el campo correspondiente de la base de datos.

⚠️ **GitHub.com Fallback** ⚠️