3.4.09. Gestión de anexos CRUD de anexos - diezMalena/api_FCTFiller GitHub Wiki

Objetivo

  • El objetivo de los CRUD de anexos es tener los anexos pertinentes centralizados en un sitio para poder gestionar su uso y facilitar a los alumnos,tutores, directores o jefes de estudio su obtención, su habilitación/deshabilitación, elimiación, descarga o subida en formato .pdf.

CRUD de Anexos - Docentes

Ver anexos

  • Esto nos permite ver los anexos una vez se entra al crud de anexos.
  • Al entrar al crud de anexos, lo primero que se comprueba es si la persona que accede es un tutor o un director/jefe de estudios
    if (this.usuario!.isTutor()) {
      this.verAnexos();
      this.getArrayAnexos();
    } else {
      this.verGrupos();
      this.getArrayAnexos();
    }
  • En consecuencia, se muestra lo mismo excepto por un desplegable, que se explicara en Extras.

  • En el caso de los tutores, se llama a la función verAnexos(), como parametros, se le envian el dni del tutor y un numero, 1, que quiere decir, que buscamos los anexos habilitados.

  • Después de eso, se llama a la función del servidor verAnexos() al que también se le envia el dni del tutor logueado y 1, que quiere decir, como hemos dicho, habilitado.

  • La funcion verAnexos() consta de las siguientes partes:

    • Primero se declara una variable $datos = array(); que va a contener el array asociativo de anexos que se va a devolver al cliente.
    • En segundo lugar, se va a hacer una llamada a la base de datos por cada anexo que aparezca en este crud y que esté habilitado, no todos aparecen. Cada anexo va a tener su propia #region dentro de la función verAnexos() y casi todos se gestionan de la misma manera, voy a poner el ejemplo del anexo 0 y XV, y esta sería la llamada a la base de datos:
    $Anexos0 = Anexo::select('tipo_anexo', 'firmado_empresa', 'firmado_director', 'ruta_anexo', 'created_at')->where('habilitado', '=',          $habilitado)->whereIn('tipo_anexo', ['Anexo0', 'Anexo0A'])->where('ruta_anexo', 'like', "$dni_tutor%")->get(); 
    
    • Después de almacenar los anexos 0 en una variable Se hace un foreach y se comprueba que el fichero del anexo que vamos a mostrar, existe realmente en un directorio del servidor.
    foreach ($Anexos0 as $a) {
     if (file_exists(public_path($a->ruta_anexo))) {
     }
    }
    
    • Dentro de este foreach primero nos aseguramos de que las barras de la ruta son correctas para el SO en el que nos encontramos y después vamos a crear un array dividiendo el contenido por esas barras
                 $rutaAux = str_replace('/', DIRECTORY_SEPARATOR, $a->ruta_anexo);
                 $rutaAux = explode(DIRECTORY_SEPARATOR, $rutaAux);
    
    • Ahora sacamos el id de la empresa, para posteriormente hacernos con el nombre de esta
                 $id_empresa = Convenio::select('id_empresa')->where('ruta_anexo','like',"$a->ruta_anexo")->get();
    
    • Creamos un array de la variable $empresa_nombre y si la variable $id_empresa no esta vacia, lo que quiere decir que la empresa existe, le asignamos el nombre de la empresa a la variable $empresa_nombre
                 $empresa_nombre = [];
                 if (count($id_empresa) > 0) {
                     $empresa_nombre = Empresa::select('nombre')->where('id', '=', $id_empresa->id_empresa)->get();
                 }
    
    • Sacamos la fecha
                 $fechaAux = explode(':', $a->created_at);
                 $fechaAux = explode(' ', $fechaAux[0]);
    
    • Y por ultimo, según si la empresa existe o no, enviaremos un array asociativo a cliente o otro
                 if (!$empresa_nombre) {
                     $datos[] = [
                         'nombre' => $rutaAux[1],
                         'codigo' => $rutaAux[2],
                         'empresa' => ' ',
                         'alumno' => ' ',
                         'firma_empresa' => $a->firmado_empresa,
                         'firma_centro' => $a->firmado_director,
                         'firma_alumno' => 0,
                         'created_at' => $fechaAux[0]
                     ];
                 } else {
                     $datos[] = [
                         'nombre' => $rutaAux[1],
                         'codigo' => $rutaAux[2],
                         'empresa' => $empresa_nombre[0]->nombre,
                         'alumno' => ' ',
                         'firma_empresa' => $a->firmado_empresa,
                         'firma_centro' => $a->firmado_director,
                         'firma_alumno' => 0,
                         'created_at' => $fechaAux[0]
                     ];
                 }
    
  • El Anexo XV es muy parecido, en lo unico en lo que difiere, es que como en este, no hay empresa, sino que este anexo unicamente es para que el alumno lo firme, las variables cambian de ser para la empresa para ser del alumno y por lo tanto lo que se devuelve no tiene empresa. Asi que sacamos el dni del alumno seccionando el nombre del documento por _ y seleccionando la posición dos que es la que contiene el nombre de este. Después hacempos una consulta a base de datos para sacar el nombre y finalmente, enviamos el array asociativo.

                    $alumno_dni = explode('_', $nombreArchivo[2]);
                    $alumno_dni = $alumno_dni[1];
                    $alumno_nombre = Alumno::select('nombre', 'apellidos')->where('dni', '=', $alumno_dni)->get();

                    $datos[] = [
                        'tipo_anexo' => $a->tipo_anexo,
                        'codigo' => $nombreArchivo[2],
                        'alumno_dni' => $alumno_dni,
                        'alumno_nombre' => $alumno_nombre[0]->nombre . ' ' . $alumno_nombre[0]->apellidos
                    ];

-Cuando este termina de almacenar todos los anexos en el array $datos envia una response con este:

return response()->json($datos, 200);
  • Una vez el cliente este publica lo llegado del array asociativo del servidor en una tabla con un *ngFor
    Screenshot_13

Descargar Todo

  • Para visualizar la guia de descargar todo, ojear este tutorial:
    Descargar Todo

Descargar Anexo

  • Para visualizar la guia de descargar Anexo, ojear este tutorial:
    Descargar Anexo

Subir

  • Para visualizar la guia de subir Anexo, ojear este tutorial:
    Subir

Deshabilitar

  • Este boton sirve para deshabilitar un anexo y enviarlo al historial de anexos
    Screenshot_17

  • Lo primero, es que, cuando se selecciona el boton descargar anexo de un anexo en concreto, este envia una señal a la función deshabilitarAnexo() que recibe como parametro un codigo, este codigo representa el nombre del archivo que vamos a descargar, que ha sido recibido previamente al cargar el CRUD de anexos.

  • A continuación se llama a la función del servidor deshabilitarAnexo() que recibe una Request que contiene, como anteriormente hemos dicho, el nombre del archivo que vamos a deshabilitar. En la función se encuentra lo siguiente:

    • En esta función tenemos esta variable que sería la Request:
       // Request
       $cod_anexo = $val->get('cod_anexo');
    
    • Ahora deshabilitamos el anexo, haciendo una consulta a la base de datos, filtrando por el codigo de anexo y teniendo cuidado, por que delante de este hay mas contenido, por eso ponemos el %
       // Deshabilitamos anexo de Anexos
       Anexo::where('ruta_anexo', 'like', "%$cod_anexo")->update([
           'habilitado' => 0,
       ]);
    
    • Si el anexo que deshabilitamos es el Anexo1, vaciamos su ruta en la tabla FCT
       // Vacio ruta de FCT
       $codAux = explode("_", $cod_anexo);
       if ($codAux[0] == 'Anexo1') {
           FCT::where('ruta_anexo', 'like', "%$cod_anexo")->update([
               'ruta_anexo' => '',
           ]);
       }
    
    • Finalmente devolvemos una response informativa de que todo ha salido bien
       return response()->json(['message' => 'Archivo deshabilitado'], 200);
    

Historial de Anexos - Docentes

  • El Historial de anexos es identico al crud de anexos, excepto por que en el crud de anexos, enviamos como parametro a la funcion del servidor el numero 1 que quiere decir, habilitado y en este caso, enviamos el 0 de deshabilitado. Así nos muestra unicamente los anexos que deberían estar en el historial. Las unicas funciones distintas son las que veremos a continuación:

Descargar Todo

  • Para visualizar la guia de descargar todo, ojear este tutorial:
    Descargar Todo

Descargar Anexo

  • Para visualizar la guia de descargar Anexo, ojear este tutorial:
    Descargar Anexo

Habilitar

  • Este boton sirve para habilitar un anexo y enviarlo al crud de anexos
    Screenshot_3
  • Al presionar el boton, se llama a la función habilitarAnexo() enviandole el parametro: codigo que es el nombre del archivo.
  • Se llama al servidor a la función habilitarAnexo() que recibe como parametro un $Request con este codigo y el dni del tutor.
        $cod_anexo = $val->get('cod_anexo');
        $dni_tutor = $val->get('dni_tutor');
  • Después se modifican en la base de datos, en la tabla Anexo como habilitado:
        Anexo::where('ruta_anexo', 'like', "%$cod_anexo")->update([
            'habilitado' => 1,
        ]);

-Finalmente, si el anexo, es un Anexo1 le devolvemos su ruta de anexos, ya que al deshabilitar, la hemos eliminado, filtrando por alumno para añadir la ruta al alumno correspondiente de la empresa correspondiente.

        $codAux = explode("_", $cod_anexo);
        //$codAux[0] es el tipo del Anexo
        if ($codAux[0] == 'Anexo1') {
            $ruta_anexo = Anexo::where('ruta_anexo', 'like', "%$cod_anexo%")->first();
            
            //Buscar alumnos del tutor para asegurar modificar la fila de bbdd correcta
            $alumnos_tutor = $this->getAlumnosQueVanAFct($dni_tutor);
            foreach ($alumnos_tutor as $a) {
                    Fct::where('id_empresa', '=', $codAux[1])->where('dni_alumno', '=', $a->dni_alumno)->update([
                        'ruta_anexo' => $ruta_anexo->ruta_anexo,
                    ]);
            }
        }

Eliminar

  • Este boton nos permite eliminar un anexo desde el historial de anexos definitivamente
    Screenshot_4
  • Lo primero que pasa cuando se presiona este boton es que se llama a la funcion eliminarAnexo() en el que se envia la variable codigo, que representa el nombre del anexo correspondiente, que se ha recogido en verAnexo().
  • Esto llama a la función del servidor eliminarAnexo() que recibe como parametro este codigo y el dni del tutor que esta eliminando dicho anexo.
  • Dentro de esta función, primero se desglosa el codigo de anexo,por _, ya que los nombres de los anexos separan sus partes por _, la primera parte [0] siempre es el tipo de anexo, ej: Anexo1
        $codAux = explode("_", $cod_anexo);
  • Eliminamos los anexos de la tabla anexos
        Anexo::where('ruta_anexo', 'like', "%$cod_anexo")->delete();
  • Si el anexo es 1 o 0/0A borraremos de la tabla fct o de la tabla convenios. Tambien se borran los ficheros de las carpetas con unlink().
        if ($codAux[0] == 'Anexo1') {
            //Eliminar un fichero
            FCT::where('ruta_anexo', 'like', "%$cod_anexo")->delete();
            unlink(public_path() . DIRECTORY_SEPARATOR . $dni_tutor . DIRECTORY_SEPARATOR . 'Anexo1' . DIRECTORY_SEPARATOR . $cod_anexo);
        } else {
            if ($codAux[0] == 'Anexo0' || $codAux[0] == 'Anexo0A') {
                unlink(public_path() . DIRECTORY_SEPARATOR . $dni_tutor . DIRECTORY_SEPARATOR . $codAux[0] . DIRECTORY_SEPARATOR . $cod_anexo);
                Convenio::where('ruta_anexo', 'like', "%$cod_anexo")->delete();
            } else {
                unlink(public_path() . DIRECTORY_SEPARATOR . $dni_tutor . DIRECTORY_SEPARATOR . $codAux[0] . DIRECTORY_SEPARATOR . $cod_anexo);
            }
        }
  • Finalmente se retorna un 200 de archivo eliminado, no se comprueba si este existe, por que si el archivo aparece en verAnexos() es por que este existe, ya que esto se comprueba con antelación.
  return response()->json(['message' => 'Archivo eliminado'], 200);

CRUD de Anexos - Alumnos

  • Las funciones Descargar todo y descargar del crud de anexos de alumnos funcionan exactamente igual que las del crud de anexos y el historial de anexos

Ver anexos

  • Esta funcion nos va a permitir entrar al crud de Anexos de alumnos y poder ver los Anexos correspondientes para el alumno en cuestion.
    Screenshot_8
  • El cliente llamara a la funcion del servidor listaAnexosAlumno() y le enviara como parametro el dni de este.
  • Primero se comprueba que el alumno tiene los anexos correspondientes con la funcion elAlumnoTieneSusAnexosObligatorios(), de momento en este crud solo estan el AnexoV Y el XV y el V se rellena solo en su propia funcionalidad, entonces esta función de momento solo se usa para el AnexoXV.
  • Lo que hace esta funcion, es comprobar que el AnexoXV esta registrado para el alumno en la tabla Anexos de la BBDD y si no existe, le crea el anexo XV plantilla, o sea, sin rellenar, listo para que lo rellenes en el crud de Anexos de alumnos.
        $fecha = Carbon::now();

        //AnexoXV
        //comprobamos que el anexo no exista para añadirlo a la tabla, sino se duplicaran
        //los registros
        $existeAnexo = Anexo::where('tipo_anexo', '=', 'AnexoXV')->where('ruta_anexo', 'like', "%$dni_alumno%")->get();
        if (count($existeAnexo) == 0) {
            $AuxNombre = $dni_alumno . '_' . $fecha->year . '_.docx';
            $rutaDestino = $dni_alumno  . DIRECTORY_SEPARATOR . 'AnexoXV' . DIRECTORY_SEPARATOR . 'AnexoXV_' . $AuxNombre;
            Anexo::create(['tipo_anexo' => 'AnexoXV', 'ruta_anexo' => $rutaDestino, 'habilitado' => 0]);
        }
  • Una vez hecho esto, se obtienen los anexos del alumno que sean de tipo V O XV , si el 5 existe en la base de datos y el fichero también, se añade al array que se va a devolver, en el AnexoXV no hace falta comprobar que existe por que se va a generar después desde el crud, mientras que con el Anexo V si es necesario por que se crea externamente.
  • Se devuelve una response con un array asociativo con los Anexos y el cliente lo recibe y lo muestra con un *NgFor
    public function listaAnexosAlumno($dni_alumno)
    {
        $datos = array();

        // De momento solo es necesario para el anexo XV
        $this->elAlumnoTieneSusAnexosObligatorios($dni_alumno);

        $Anexos = Anexo::where('ruta_anexo', 'like', "$dni_alumno%")->get();

        foreach ($Anexos as $a) {
            //return response($Anexos);
            //Un anexo es habilitado si este esta relleno por completo
            if ($a->tipo_anexo == 'Anexo5' || $a->tipo_anexo == 'AnexoXV') {

                $anexoAux = explode('/', $a->ruta_anexo);

                if ($a->tipo_anexo == 'Anexo5') {
                    if (file_exists(public_path($a->ruta_anexo))) {
                        $datos[] = [
                            'nombre' => $a->tipo_anexo,
                            'relleno' => $a->habilitado,
                            'codigo' => $anexoAux[2],
                            'fecha' => $a->created_at
                        ];
                    }
                } else {
                    $datos[] = [
                        'nombre' => $a->tipo_anexo,
                        'relleno' => $a->habilitado,
                        'codigo' => $anexoAux[2],
                        'fecha' => $a->created_at
                    ];
                }
            }
        }
        return response()->json($datos, 200);
    }

Descargar Todo

  • Para visualizar la guia de descargar todo, ojear este tutorial:
    Descargar Todo

Descargar Anexo

  • Para visualizar la guia de descargar Anexo, ojear este tutorial:
    Descargar Anexo

Subir

  • En la función subir, lo unico en lo que difiere del crud de anexos es que al subir un AnexoXV, que solo puede ser subido en este crud, es distinta a la de los demás por que en esta, necesitamos almacenar el archivo en base de datos para el profesor al igual que lo esta para el alumno. Y También necesitamos almacenar el anexo en la carpeta del profesor, por lo que hay variables para el profesor y el alumno que apuntan a las carpetas de cada uno y peticiónes a la base de datos en las que pasa lo mismo.
            //Alumno
            $rutaParaBBDAlumno = $rutaCarpetaAlumno . DIRECTORY_SEPARATOR . $nombreArchivo;
            $rutaParaBBDDSinExtensionAlumno = $rutaCarpetaAlumno . DIRECTORY_SEPARATOR . $archivoNombreSinExtension[0];

            //Profesor
            $rutaParaBBDDProfesor = $rutaCarpeta . DIRECTORY_SEPARATOR . $nombreArchivo;
            $rutaParaBBDDSinExtension = $rutaCarpeta . DIRECTORY_SEPARATOR . $archivoNombreSinExtension[0];


            //Base de datos
            //Solo busco por una ruta, por que si este anexo existe para el profesor, es por que el alumno ya lo ha creado
            $existeAnexo = Anexo::where('tipo_anexo', '=', $tipoAnexo)->where('ruta_anexo', 'like', "$rutaParaBBDDSinExtension%")->get();


            if (count($existeAnexo) == 0) {
                Anexo::create(['tipo_anexo' => $tipoAnexo, 'ruta_anexo' => $rutaParaBBDDProfesor]); //Profesor
                $this->firmarAnexo($rutaParaBBDDProfesor, $extension);
            } else {
                Anexo::where('ruta_anexo', 'like', "$rutaParaBBDDSinExtensionAlumno%")->update([ //Alumno
                    'ruta_anexo' => $rutaParaBBDAlumno,
                ]);
                Anexo::where('ruta_anexo', 'like', "$rutaParaBBDDSinExtension%")->update([ //Profesor
                    'ruta_anexo' => $rutaParaBBDDProfesor,
                ]);

                $this->firmarAnexo($rutaParaBBDAlumno, $extension);
                $this->firmarAnexo($rutaParaBBDDProfesor, $extension);
            }
  • Para ver el resto de la función ojear este tutorial: Subir

Rellenar

  • Este boton sirve para rellenar un anexo que necesite de ello, hay anexos que se rellenan en su propia pantalla con poner datos o pulsar un boton , pero hay anexos como el XV que carecen de eso y por ello existe este boton, Para rellenarlo.
    Screenshot_5

  • Al pulsar el boton, se llama a la funcion abrirRelleno() como parametros se le envia el codigo, que es el nombre del fichero que vamos a rellenar y el tipo de anexo. estos datos se almacenan en SessionStorage y se abre un modal:

    sessionStorage.setItem('tipoAnexo', nombre);
    sessionStorage.setItem('codigo', codigo);
    this.modal.open(ModalTipoAnexoComponent, { size: 'md' });
  • El modal debe ser diferente segun el anexo que enviemos, según lo que queramos, de momento solo esta hecho para el AnexoXV
    Screenshot_6

  • En el caso del AnexoXV al presionar el boton, sucede lo señalado en este manual: AnexoXV

Funciones Compartidas

Descargar todo

  • Este boton nos permite descargar todos los anexos que han sido generados por una persona
    Screenshot_14

  • Al presionar el boton de descargar Todo, este te envia a la función descargarTodo(), después, esta llama a la función descargarTodo() del servidor, que recibe como parametro una $Request que contiene el dni de la persona que hace la petición y se le envia 1, si esta petición esta hecha desde el crud de anexos y 0 si esta hecha desde el historial.

  • En dicha función nos encontraremos lo siguiente:

    • Estas variables, en orden, son: 7 Digitos random para complementar el nombre del zip, el dni de la persona que hace la petición , si los anexos de los que se va a hacer el zip están habilitados o no, la ruta en el servidor donde se va a almacenar y el nombre del zip.
        $AuxNombre = Str::random(7);
        $dni = $val->get('dni_tutor');
        $habilitado =  $val->get('habilitado');
        $rutaZip = 'tmp' . DIRECTORY_SEPARATOR . 'anexos' . DIRECTORY_SEPARATOR . 'myzip_' . $AuxNombre . '.zip';
        $nombreZip = $this->montarZipConCondicion($dni, $rutaZip, $habilitado);
  • Ahora se monta el zip que va a permitirnos descrgar todos los anexos
    Montar Zip

  • Finalmente, el zip llega al cliente y gracias a estas lineas en la función descargarTodo() que se encuentra en el cliente, nos permite almacenar el zip, usamos const current = new Date(); para generar un nombre asociado al tiempo.

          import * as FileSaver from 'file-saver';

          const current = new Date();
          const blob = new Blob([res], { type: 'application/octet-stream' });
          FileSaver.saveAs(blob, 'backup_' + current.getTime() + '.zip');
          this.toastr.success('Anexos Descargados', 'Descarga');

Descargar Anexo

  • Esta función nos permite descargar un anexo en concreto
    Screenshot_16
  • Lo primero, es que, cuando se selecciona el boton descargar anexo de un anexo en concreto, este envia una señal a la función descargarAnexo() que recibe como parametro un codigo, este codigo representa el nombre del archivo que vamos a descargar, que ha sido recibido previamente al cargar el CRUD de anexos y también recibe el dni de la persona solicitante.
  • Seguidamente, se llama a la función descargarTodo() del servidor, este recibe como parametro una Request. Esta request contiene el codigo y el dni del que hablabamos antes.
  • Estas Son las variables de esta función:
        // Request
        $dni_tutor = $val->get('dni_tutor');
        $cod_anexo = $val->get('codigo');

        // Otras variables
        $codAux = explode("_", $cod_anexo);
        $rutaOriginal = '';
        $rutaOriginal = public_path($dni_tutor . DIRECTORY_SEPARATOR . $codAux[0] . DIRECTORY_SEPARATOR . $cod_anexo);
        $rutaOriginal  = str_replace('/', DIRECTORY_SEPARATOR, $rutaOriginal);
  • En orden, serían:
    • La Request de la que se hablaba
    • $codAux es un array que ha sido generado al usar _ como separación
    • $rutaOriginal es la ruta de la carpeta donde se encuentra el anexo a descargar, después de esto, nos aseguramos de que tenemos una ruta adecuada para el SO que usamos
  • Finalmente, enviamos una response con la descarga
return Response::download($rutaOriginal);
  • En el cliente, al igual que en Descargar Todo, podemos descargarnos automaticamente nuestro anexo gracias a estas lineas, que esta vez se encuentran en el cliente, en la función descargarAnexo(), la unica diferencia, es que en descargarTodo, generamos un nombre para el zip que descarga el usuario con const current = new Date();.
          import * as FileSaver from 'file-saver';

          const blob = new Blob([res], { type: 'application/octet-stream' });
          FileSaver.saveAs(blob, codigo);
          this.toastr.success('Anexo Descargado', 'Descarga');

Subir

  • Este boton sirve para subir un Anexo1 que ya haya sido creado, pero que ha sido firmado o editado en .pdf o .docx
    Screenshot_1
  • En el caso del Crud de anexos de alumnos se vería asi:
    Screenshot_2

-Primero hacemos click sobre el boton con el icono de subir archivo y este abre un modal, almacenando en un SessionStorage un codigo, el codigo es el nombre que se le va a poner posteriormente al archivo del anexo, independientemente de si llamas a tu archivo Patata.docx o Ventana.pdf , este es recogido cuando se carga la pantalla principal en la cuál estas presionando el boton de subirAnexo.

  • Ya en el modal se selecciona un documento, al subir un documento se llama a la función upload() y se le envia un $event que es el fichero seleccionado, esta función transformará ese fichero en base64 y se almacenara en un SessionStorage. cuando lo hayamos subido pulsaremos el boton aceptar.
  • Ese boton Aceptar llama a la función enviarAnexo() en esa función se gestiona el nombre y la extensión de este. la variable extension, almacena la extension del archivo subido, nombreSinExtension es el nombre sin exensión del anexo y nombreArchivo() es el nombre final que se le dará al archivo, compuesto por el nombre sin extension + extension.
  • Al archivo que recibimos por SessionStorage lo reformulamos para que contenga la extension adecuada al tipo de archivo que queremos enviar.
    let nombreArchivo: any;
    let nombreSinExtension: any;
    let extension: any;

    //Gestion de nombre
    extension = this.evento.name.split('.');
    extension = '.' + extension[extension.length - 1];
    nombreSinExtension = sessionStorage.getItem('codigoAnexo')!.split('.');
    nombreSinExtension = nombreSinExtension[0];
    nombreArchivo = nombreSinExtension + extension;
  • Se genera un objeto AnexoUpload que contiene:
  • El fichero, el tipo de Anexo que vamos a subir (Anexo1,2,4....), el nombre del archivo generado y el dni del usuario
    let datos = new AnexoUpload(
      sessionStorage.getItem('fichero')!,
      this.tipoAnexo,
      nombreArchivo,
      this.dni_usuario!
    );
  • Ahora se va a llamar a la función subirAnexoEspecifico() del servidor y este recibe una $Request, esta $Request contiene el objeto que hemos enviado:
        //Request
        $fichero = $req->get('file');
        $dni = $req->get('dni');
        $tipoAnexo = $req->get('tipoAnexo');
        $nombreArchivo = $req->get('nombreArchivo');
  • Se llama al controlador de Alumnos por que necesitamos funciónes que se hacen alli
        //Controlador
        $controlador = new ControladorAlumno();
  • Tenemos una variable que almacena la carpeta donde se va a subir el anexo
        //Archivos
        $rutaCarpeta = $dni . DIRECTORY_SEPARATOR . $tipoAnexo;
  • Controlamos el tipo de anexo que vamos a subir, el AnexoXV se sube en otra función y los demás en la misma
  • Comprobamos que existe la carpeta donde lo vamos a depositar, y sino existe, se crea
Auxiliar::existeCarpeta($rutaCarpeta);
  • Abrimos el flujo de escritura para guardar el fichero
$flujo = fopen($rutaCarpeta . DIRECTORY_SEPARATOR .  $nombreArchivo, 'wb');
  • Dividimos el string en comas
               // $datos[ 0 ] == "data:type/extension;base64"
                // $datos[ 1 ] == <actual base64 file>

                $datos = explode(',', $fichero);

                if (count($datos) > 1) {
                    fwrite($flujo, base64_decode($datos[1]));
                } else {
                    return false;
                }
                fclose($flujo);

  • También hay que añadir dicho anexo a la base de datos, pero no, sin antes comprobar si existe, por que sino, se duplicarian los datos,lo buscamos sin extension, por que si existe, se actualizara con la nueva ruta y si no existe,se crea, asi si es un .pdf u otra extension se actualiza
                $extension = explode('/', mime_content_type($fichero))[1];
                $rutaParaBBDD = $rutaCarpeta . DIRECTORY_SEPARATOR . $nombreArchivo;
                $archivoNombreSinExtension = explode('.', $nombreArchivo);
                $rutaParaBBDDSinExtension = $rutaCarpeta . DIRECTORY_SEPARATOR . $archivoNombreSinExtension[0];
                $existeAnexo = Anexo::where('tipo_anexo', '=', $tipoAnexo)->where('ruta_anexo', 'like', "$rutaParaBBDDSinExtension%")->get();

  • Excluyo los nombres de archivos Anexos2.docx y 4.docx por que esto ya lo hacen ellos de manera especifica en su propia función, si se envian asi los nombres significa que estos dos anexos es la primera vez que se crean y no que se están resubiendo.
                if ($nombreArchivo != 'Anexo2.docx' && $nombreArchivo != 'Anexo4.docx') {
                    if (count($existeAnexo) == 0) {
                        Anexo::create(['tipo_anexo' => $tipoAnexo, 'ruta_anexo' => $rutaParaBBDD]);

                        //Firma
                        $this->firmarAnexo($dni, $rutaParaBBDD, $extension);
                    } else {

                        Anexo::where('ruta_anexo', 'like', "$rutaParaBBDDSinExtension%")->update([
                            'ruta_anexo' => $rutaParaBBDD,
                        ]);

                        //Añadidos a BBDD especiales
                        if ($tipoAnexo == 'Anexo1') {
                            FCT::where('ruta_anexo', 'like', "$rutaParaBBDDSinExtension%")->update([
                                'ruta_anexo' => $rutaParaBBDD,
                            ]);
                        } else {
                            if ($tipoAnexo == 'Anexo0' || $tipoAnexo == 'Anexo0A') {
                                Convenio::where('ruta_anexo', 'like', "$rutaParaBBDDSinExtension%")->update([
                                    'ruta_anexo' => $rutaParaBBDD,
                                ]);
                            }
                        }
  • Finalmente firmamos los anexos en la base de datos
                        //Firma
                        $this->firmarAnexo($dni, $rutaParaBBDD, $extension);
  • Aquí se especifica como funciona esta función:
    Firma

Funciones Auxiliares del crud

Montar Zip

  • Hay varias funciones que montan Zip, vamos a hablar de ellas:

montarZipConCondicion

  • Esta función recibe los parametros que contienen , la ruta donde estan los archivos , el objeto zip y la ruta donde se depositará el zip
  • Primero se crea el zip y se abre
if ($zip->open(public_path($rutaZip), ZipArchive::CREATE)) {
} 
  • Se interceptan los archivos de la carpeta de la que se va a formar el zip
$files = File::files(public_path($rutaArchivo));
  • Se hace un foreach para recorrer los archivos
foreach ($files as $value) {
}
  • Se va interceptando el nombre de cada archivo en la variable $relativeNameZipFile
$relativeNameZipFile = basename($value);
  • Gracias a que interceptamos el nombre, comprobamos si este archivo existe en la base de datos
$existeAnexo = Anexo::where('ruta_anexo', 'like', "%$relativeNameZipFile%")->where('habilitado', '=', 1)->first();
if ($existeAnexo) {
 }
  • Si existe, lo añadimos al zip
$zip->addFile($value, $relativeNameZipFile);
  • Cuando esto termina, se cierra el zip
$zip->close();
  • Finalmente se retorna el Zip
return $rutaZip;

montarZip

  • Es igual que montarZipConCondicion , pero sin comprobar que el archivo existe en las carpetas, sirve por ejemplo, cuando se genera el Anexo 2 o 4, que se acaban de crear y por obligación existen

montarZipCrud

  • No recibe el objeto zip, este se crea dentro, pero si recibe el parametro $habilitado, estamos comprobando si los anexos del cual hacemos el zip estan habilitados o no
  • Se crea el objeto zip y se interceptan los distintos tipos de Anexo que existen en la base de datos
 $zip = new ZipArchive;
        $tipo_anexos_existentes = Anexo::select('tipo_anexo')->where('habilitado', '=', $habilitado)->distinct()->get();
  • Se crea el zip y se abre
if ($zip->open(public_path($rutaZip), ZipArchive::CREATE)) {
} 
  • Recorremos los distintos tipos Anexos existentes
 foreach ($tipo_anexos_existentes as $a) {
}
  • Comprobamos que existen las distintas carpetas por cada tipo de anexo para la persona solicitante, y sino, se crean
Auxiliar::existeCarpeta(public_path($dni_tutor . DIRECTORY_SEPARATOR . $a->tipo_anexo));
  • Se interceptan los archivos de la carpeta de la que se va a formar el zip
$files = File::files(public_path($dni_tutor . DIRECTORY_SEPARATOR .  $a->tipo_anexo));
  • Se hace un foreach para recorrer los archivos
foreach ($files as $value) {
}
  • Se genera la ruta completa para ir interceptando archivo por archivo
$ruta_completa = public_path($dni_tutor . DIRECTORY_SEPARATOR . $a->tipo_anexo . DIRECTORY_SEPARATOR . basename($value));
  • Comprobamos si el archivo existe
if (file_exists($ruta_completa)) {
}
  • Si este existe interceptamos el archivo en una variable, comprobamos que existe en la base de datos, y si existe lo añadimos al zip, comprobando asi, en conjunto con todos estos pasos, que el archivo existe en base de datos y en archivo.
$nombreAux = basename($value);
$existeAnexo = Anexo::where('tipo_anexo', '=', $a->tipo_anexo)->where('habilitado', '=', $habilitado)->where('ruta_anexo', 'like', "%$nombreAux%")->first();

if ($existeAnexo) {
$zip->addFile($value, $nombreAux);
}
  • Cuando esto termina, se cierra el zip
$zip->close();
  • Finalmente se retorna el Zip
return $rutaZip

Firmar

  • Esta funcion firma los Anexos, hay dos tipos de funciones firmarAnexo, una es para los alumnos y otra para los docentes.
  • En las dos, esta funcion recibe como parametros, el dni(del alumno o tutor), la ruta de registrada en base de datos del archivo firmado y la extension del archivo.

Docentes:

  • Tenemos tres variables, en una buscamos los alumnos, en otra los profesores y en la ultima, las empresas segun el dni de la persona que este haciendo la peticion, sabremos que rol tiene esta persona.
        $alumno = Alumno::where('dni', '=', $dni)->get();
        $profesor = Profesor::where('dni', '=', $dni)->get();
        $empresa = Trabajador::where('dni', '=', $dni)->get();
  • Comprobamos si el archivo es .pdf o .docx

  • Si es .pdf y la persona solicitante es cualquiera de estos roles, según cual sea, se modificará en consecuencia la firma correspondiente en la tabla Anexos, por ejemplo, si es un alumno, la firma_alumno se firmará.

  • Sin embargo, si el archivo es .docx este eliminará su firma.

Alumnos:

  • Hace exactamente lo mismo que con los docentes, pero con la diferencia de que no comprueba si el usuario firmante es profesor o empresario. Siempre es alumno.
        if ($extension == 'pdf') {
            Anexo::where('ruta_anexo', 'like', "$rutaParaBBDD")->update([
                'firmado_alumno' => 1,
            ]);
        } else {
            Anexo::where('ruta_anexo', 'like', "$rutaParaBBDD")->update([
                'firmado_alumno' => 0,
            ]);
        }