Commit 2ba7faba authored by Alfonso Rafael Solis Rangel's avatar Alfonso Rafael Solis Rangel
Browse files

Merge branch 'correcciones' into 'main'

Correcciones

See merge request !30
parents 78242d35 6aaab1a1
Loading
Loading
Loading
Loading
+94 −24
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use App\Models\Contacto;
use App\Models\Grupos;

class ContactosExport implements FromCollection, WithHeadings
{
@@ -22,9 +23,6 @@ public function __construct($contactIds, $extraFields = [], $filters = [])
    public function collection()
    {
        $query = Contacto::query();
        if (!empty($this->contactIds)) {
            $query->whereIn('contactos.id', $this->contactIds);
        }

        // Aplicar filtros adicionales usando relaciones
        $this->applyFilters($query);
@@ -33,12 +31,25 @@ public function collection()
        $contactos = $query->with([
            'profesion',
            'cargo',
            'caracteristicas',
            'telefonos',
            'pareja',
            'correos'
        ])->get();

        if (!empty($this->contactIds)) {
            $contactosObligatorios = Contacto::whereIn('id', $this->contactIds)->with([
                'profesion',
                'cargo',
                'telefonos',
                'pareja',
                'correos'
            ])->get();
    
            // Combinar los resultados y eliminar duplicados
            $contactos = $contactos->merge($contactosObligatorios)->unique('id');    

        }

        // Mapear los datos a un formato exportable
        return $contactos->map(function ($contacto) {
            return $this->formatContactoData($contacto);
@@ -54,28 +65,76 @@ public function headings(): array

    private function applyFilters($query)
    {
        if (!empty($this->filters['listas'])) {
            $query->orWhereHas('listas', function ($q) {
                $q->whereIn('listas.id', $this->filters['listas']);
        /* if(!empty($this->filters['subgrupos'])){
            $query->orWhereHas('subgrupos', function ($q) {
                $q->whereIn('subgrupos.id', $this->filters['subgrupos']);
            });
        }
        } */

        if (!empty($this->filters['caracteristicas'])) {
            $query->orWhereHas('caracteristicas', function ($q) {
                $q->whereIn('caracteristicas.id', $this->filters['caracteristicas']);
        if (!empty($this->filters['subgrupos'])) {
            $query->orWhereHas('subgrupos', function ($q) {
                $q->whereIn('subgrupos.id', $this->filters['subgrupos']);
            });
        } elseif (!empty($this->filters['grupos'])) {
            $grupoId = $this->filters['grupos'];
            $subgruposIds = Grupos::find($grupoId)->subgrupos->pluck('id')->toArray();
    
            $query->where(function ($query) use ($grupoId, $subgruposIds) {
                // Contactos directamente en el grupo
                $query->orWhereHas('grupos', function ($q) use ($grupoId) {
                    $q->where('grupos.id', $grupoId);
                });
        }
    
        if (!empty($this->filters['grupos'])) {
            $query->orWhereHas('grupos', function ($q) {
                $q->whereIn('grupos.id', $this->filters['grupos']);
                // Contactos en subgrupos del grupo (solo si hay subgrupos)
                if (!empty($subgruposIds)) {
                    $query->orWhereHas('subgrupos', function ($q) use ($subgruposIds) {
                        $q->whereIn('subgrupos.id', $subgruposIds);
                    });
                }
            });
        }

        if (!empty($this->filters['cargos'])) {
            $query->orWhereHas('cargo', function ($q) {
                $q->whereIn('cargos.id', $this->filters['cargos']);
        if ($this->filters['mesInicio'] != "NaN" && $this->filters['diaInicio'] != "NaN") {
            $mesInicio = $this->filters['mesInicio'];
            $diaInicio = $this->filters['diaInicio'];
    
            if ($this->filters['mesFin'] != "NaN" && $this->filters['diaFin'] != "NaN") {
                $mesFin = $this->filters['mesFin'];
                $diaFin = $this->filters['diaFin'];
    
                if ($mesInicio === $mesFin && $diaInicio === $diaFin) {
                    $query->where('mes_cump', $mesInicio)
                          ->where('dia_cump', $diaInicio);
                } else {
                    $query->where(function ($query) use ($mesInicio, $diaInicio, $mesFin, $diaFin) {
                        // Condición para fechas dentro del mismo mes
                        $query->where(function ($query) use ($mesInicio, $diaInicio, $mesFin, $diaFin) {
                            $query->where('mes_cump', $mesInicio)
                                  ->whereBetween('dia_cump', [$diaInicio, $diaFin]);
                        })
                        // Condición para fechas que abarcan varios meses
                        ->orWhere(function ($query) use ($mesInicio, $diaInicio, $mesFin, $diaFin) {
                            $query->where(function ($query) use ($mesInicio, $diaInicio) {
                                $query->where('mes_cump', '>', $mesInicio)
                                      ->orWhere(function ($query) use ($mesInicio, $diaInicio) {
                                          $query->where('mes_cump', $mesInicio)
                                                ->where('dia_cump', '>=', $diaInicio);
                                      });
                            })
                            ->where(function ($query) use ($mesFin, $diaFin) {
                                $query->where('mes_cump', '<', $mesFin)
                                      ->orWhere(function ($query) use ($mesFin, $diaFin) {
                                          $query->where('mes_cump', $mesFin)
                                                ->where('dia_cump', '<=', $diaFin);
                                      });
                            });
                        });
                    });
                }
            } else {
                $query->where('mes_cump', $mesInicio)
                      ->where('dia_cump', $diaInicio);
            }
        }
    }

@@ -90,7 +149,13 @@ private function formatContactoData($contacto)
        ];

        $extraData = [];
        foreach ($this->extraFields as $field) {
        $fields = $this->extraFields;

        if (in_array('todos', $fields)) {
            $fields = ['domicilio', 'cumpleanos', 'telefonos', 'conyuge', 'email'];
        }

        foreach ($fields as $field) {
            switch ($field) {
                case 'domicilio':
                    $extraData = array_merge($extraData, [
@@ -113,7 +178,6 @@ private function formatContactoData($contacto)
                        'Tipo' => $contacto->telefonos->pluck('tipo')->join(', ') ?? 'N/A',
                        'Estatus' => $contacto->telefonos->pluck('estatus')->join(', ') ?? 'N/A',
                        'Extensión' => $contacto->telefonos->pluck('ext')->join(', ') ?? 'N/A',
                        'ID Radio' => $contacto->telefonos->pluck('id_radio')->join(', ') ?? 'N/A',
                        'Observaciones' => $contacto->telefonos->pluck('observaciones')->join(', ') ?? 'N/A',
                    ]);
                    break;
@@ -137,7 +201,13 @@ private function formatContactoData($contacto)
    private function getExtraHeadings()
    {
        $headings = [];
        foreach ($this->extraFields as $field) {
        $fields = $this->extraFields;

        if (in_array('todos', $fields)) {
            $fields = ['domicilio', 'cumpleanos', 'telefonos', 'conyuge', 'email'];
        }

        foreach ($fields as $field) {
            switch ($field) {
                case 'domicilio':
                    $headings = array_merge($headings, ['Domicilio Oficial', 'Código Postal', 'Localidad Oficial', 'Municipio Oficial', 'Estado', 'País']);
@@ -146,7 +216,7 @@ private function getExtraHeadings()
                    $headings[] = 'Cumpleaños';
                    break;
                case 'telefonos':
                    $headings = array_merge($headings, ['Número de teléfono', 'Tipo', 'Estatus', 'Extensión', 'ID Radio', 'Observaciones']);
                    $headings = array_merge($headings, ['Número de teléfono', 'Tipo', 'Estatus', 'Extensión', 'Observaciones']);
                    break;
                case 'conyuge':
                    $headings[] = 'Cónyuge';
+154 −98
Original line number Diff line number Diff line
@@ -550,6 +550,7 @@ public function viewUpload()

    public function upload(Request $request)
    {
        try{
            $request->validate([
                'csv_file' => 'required|mimes:csv,txt',
            ]);
@@ -562,13 +563,13 @@ public function upload(Request $request)
    
            $data = array_map('str_getcsv', explode("\n", $content));
            $header = array_shift($data);
            $cont = 1;
    
            foreach ($data as $row) {
                if (count($header) !== count($row)) {
                    continue;
                }
                $row = array_combine($header, $row);

                //TODO: Implementar lo mismo para los demas catalogos
    
                $existProfesion = $profesiones->firstWhere('nombre', $row['profesion']);
@@ -609,49 +610,27 @@ public function upload(Request $request)
                $exts = explode(';', $row['ext']);
                $observaciones = explode(';', $row['observaciones']);
    
            for ($i = 0; $i < count($numeros); $i++) {
                if ( $numeros[$i] != 'null') {
                    Telefono::create([
                        'contacto_id' => $contacto->id,
                        'numero' => $numeros[$i],
                        'tipo' => $tipos[$i],
                        'estatus' => $estatuses[$i],
                        'ext' => $exts[$i],
                        'observaciones' => $observaciones[$i],
                    ]);
                }
            }
                $this->validateAndCreateTelefonos($contacto->id, $numeros, $tipos, $estatuses, $exts, $observaciones, $cont);
    
                // Procesar redes sociales
                $redes_sociales = explode(';', $row['red_social']);
                $tipos_redes_sociales = explode(';', $row['tipo_red_social']);
    
            for ($i = 0; $i < count($redes_sociales); $i++) {
                if ($redes_sociales[$i] != 'null' || $tipos_redes_sociales[$i] != 'null') {
                    RedesSociales::create([
                        'contacto_id' => $contacto->id,
                        'red_social' => $redes_sociales[$i],
                        'tipo_red_social' => $tipos_redes_sociales[$i],
                    ]);
                }
            }
                $this->validateAndCreateRS($contacto->id, $redes_sociales, $tipos_redes_sociales, $cont);
    
                // Procesar correos electrónicos
                $correos = explode(';', $row['correo_electronico']);
                $tipos_correos = explode(';', $row['tipo_correo_electronico']);
    
            for ($i = 0; $i < count($correos); $i++) {
                if ($correos[$i] != 'null' || $tipos_correos[$i] != 'null') {
                    CorreoContactos::create([
                        'contacto_id' => $contacto->id,
                        'correo_electronico' => $correos[$i],
                        'tipo_correo_electronico' => $tipos_correos[$i],
                    ]);
                }
            }
                $this->validateAndCreateEmails($contacto->id, $correos, $tipos_correos, $cont);
                $cont++;
            }
    
            return redirect()->route('contacto.get')->with('success', 'Importación de contactos almacenada correctamente');
        }catch(\Throwable $e){
            return redirect()->route('contacto.upload')->withErrors('Error al importar los contactos, favor de revisar el archivo CSV. \n' . $e->getMessage());
        }
        
    }

    public function obtenerEventos(Request $request){
@@ -696,6 +675,83 @@ public function obtenerEventos(Request $request){

        return response()->json($eventos);
    }

    private function validateAndCreateTelefonos($contactoId, $numeros, $tipos, $estatuses, $exts, $observaciones, $cont)
    {
        for ($i = 0; $i < count($numeros); $i++) {
            if ($numeros[$i] != 'null') {
                if(!filter_var($numeros[$i], FILTER_VALIDATE_INT)){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: El número de teléfono debe ser un número entero. Valor actual: ' . $numeros[$i]);
                }
                if(!in_array($tipos[$i], ['Directo', 'Particular', 'Celular', 'Conmutador'])){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: El tipo de teléfono debe ser "Directo", "Particular", "Celular" o "Conmutador". Valor actual: ' . $tipos[$i]);
                }
                if(!in_array($estatuses[$i], ['Público', 'Privado'])){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: El estatus del teléfono debe ser "Público" o "Privado". Valor actual: ' . $estatuses[$i]);
                }
                if(!is_string($exts[$i])){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: La extensión del teléfono debe ser una cadena de texto. Valor actual: ' . $exts[$i]);
                }
                if(!is_string($observaciones[$i])){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: Las observaciones del teléfono deben ser una cadena de texto. Valor actual: ' . $observaciones[$i]);
                }

                if($exts[$i] === 0 || $exts[$i] === '0'){
                    $exts[$i] = "";
                }

                Telefono::create([
                    'contacto_id' => $contactoId,
                    'numero' => $numeros[$i],
                    'tipo' => $tipos[$i],
                    'estatus' => $estatuses[$i],
                    'ext' => $exts[$i],
                    'observaciones' => $observaciones[$i],
                ]);
            }
        }
    }

    private function validateAndCreateRS($contactoId, $redes_sociales, $tipos_redes_sociales, $cont)
    {
        for ($i = 0; $i < count($redes_sociales); $i++) {
            if ($redes_sociales[$i] != 'null') {
                if(!filter_var($redes_sociales[$i], FILTER_VALIDATE_URL)){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: La red social debe ser una URL válida. Valor actual: ' . $redes_sociales[$i]);
                }
                if(!in_array($tipos_redes_sociales[$i], ['Facebook', 'Twitter', 'Instagram', 'LinkedIn', 'Página Web'])){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: El tipo de red social debe ser "Facebook", "Twitter", "Instagram", "LinkedIn" o "Página Web". Valor actual: ' . $tipos_redes_sociales[$i]);
                }

                RedesSociales::create([
                    'contacto_id' => $contactoId,
                    'red_social' => $redes_sociales[$i],
                    'tipo_red_social' => $tipos_redes_sociales[$i],
                ]);
            }
        }
    }

    private function validateAndCreateEmails($contactoId, $correos, $tipos_correos, $cont)
    {
        for ($i = 0; $i < count($correos); $i++) {
            if ($correos[$i] != 'null') {
                if(!filter_var($correos[$i], FILTER_VALIDATE_EMAIL)){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: El correo electrónico debe ser una dirección de correo válida. Valor actual: ' . $correos[$i]);
                }
                if(!in_array($tipos_correos[$i], ['Personal', 'Oficial'])){
                    throw new \Exception('Error en la fila ' . $cont . ' del archivo CSV: El tipo de correo electrónico debe ser "Personal" o "Oficial". Valor actual: ' . $tipos_correos[$i]);
                }

                CorreoContactos::create([
                    'contacto_id' => $contactoId,
                    'correo_electronico' => $correos[$i],
                    'tipo_correo_electronico' => $tipos_correos[$i],
                ]);
            }
        }
        
    }
}

    
 No newline at end of file
+43 −7
Original line number Diff line number Diff line
@@ -10,7 +10,10 @@
use Illuminate\Http\Request;

use App\Exports\ContactosExport;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use ZipArchive;

class ReporteController extends Controller
{
@@ -88,17 +91,50 @@ public function export(Request $request)
            return response()->json(['Error, No seleccionaste un archivo de exportación valido.'], 400);
        }

        // TODO: Traer datos de todos los contactos
        $contactIds = array_column($request->input('contactos', []), 'id');
        $extraFields = $request->input('exportar', []);
        $filters = [
            'listas' => $request->input('listas', []),
            'caracteristicas' => $request->input('caracteristicas', []),
            'grupos' => $request->input('grupos', []),
            'cargos' => $request->input('cargos', []),
            'subgrupos' => $request->input('subgrupos', []),
            'grupos' => $request->input('grupo'),
            'mesInicio' => $request->input('mesInicio'),
            'diaInicio' => $request->input('diaInicio'),
            'mesFin' => $request->input('mesFin'),
            'diaFin' => $request->input('diaFin'),
        ];
        // TODO: Crear archivos de exportacion: PDF, Excel
        return Excel::download(new ContactosExport($contactIds, $extraFields, $filters), 'contactos.xlsx');
        //dd($request->all());
        $export = new ContactosExport($contactIds, $extraFields, $filters);
        if($request->archivo == 'excel'){
            return Excel::download($export, 'contactos.xlsx');
        }else if($request->archivo == 'pdf'){
            $pdf = Pdf::loadView('adminGen.contactos.contactos_pdf', ['contactos' => $export->collection()])->setPaper('A1', 'landscape');;
            return $pdf->download('contactos.pdf');
        }else if($request->archivo == 'ambos'){
            $excelPath = storage_path('app/public/contactos.xlsx');
            $pdfPath = storage_path('app/public/contactos.pdf');

            Excel::store($export, 'public/contactos.xlsx');
            $pdf = Pdf::loadView('adminGen.contactos.contactos_pdf', ['contactos' => $export->collection()])->setPaper('A1', 'landscape');
            Storage::put('public/contactos.pdf', $pdf->output());

            // Crear archivo ZIP
            $zipPath = storage_path('app/public/contactos.zip');
            $zip = new ZipArchive;
            if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
                $zip->addFile($excelPath, 'contactos.xlsx');
                $zip->addFile($pdfPath, 'contactos.pdf');
                $zip->close();
            }

            // Descargar archivo ZIP
            return response()->download($zipPath)->deleteFileAfterSend(true);
        }else{
            return response()->json(['Error, No seleccionaste un archivo de exportación valido.'], 400);
        }
    }

    public function getSubgrupos(Int $id)
    {
        $grupo = Grupos::find($id);
        return response()->json($grupo->subgrupos);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ public function handle(Request $request, Closure $next, ... $roles): Response
                }
            }

            return abort(401);
            return redirect()->back()->withErrors('No tienes los permisos necesarios para acceder a esta página.');
        }else{
            return $next($request);
        }
+5 −0
Original line number Diff line number Diff line
@@ -32,5 +32,10 @@ public function contactos(): BelongsToMany
        return $this->belongsToMany(Contacto::class, 'contactos_grupos', 'contacto_id', 'grupo_id');
    }

    public function subgrupos(): HasMany
    {
        return $this->hasMany(Subgrupo::class, 'grupo_id');
    }
    
    public $timestamps = false;
}
Loading