HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux Bradford-Sitios 6.14.0-1017-azure #17~24.04.1-Ubuntu SMP Mon Dec 1 20:10:50 UTC 2025 x86_64
User: www-data (33)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/gestion-formularios.bdfschool/app/Http/Controllers/DamageRecordsController.php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Areas;
use App\Models\Courses;
use App\Models\DamageRecords;
use App\Models\Parents;
use App\Models\ReasonsRequest;
use App\Models\Students;
use App\Models\TypesRequest;
use App\Models\Users;
use App\Services\BrevoService\BrevoMailer;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;

class DamageRecordsController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth.users')->except('logout', 'public_damage');
        $this->middleware('auth.users:LIST_DAMAGE_RECORDS, LIST_ALL_DAMAGE_RECORDS')->only(['index', 'detail']);
        $this->middleware('auth.users:ADD_DAMAGE_RECORDS')->only(['create', 'store']);
        $this->middleware('auth.users:EDIT_DAMAGE_RECORDS')->only(['update']);
        $this->middleware('auth.users:CANCEL_DAMAGE_RECORDS')->only(['cancel']);
    }

    public function index()
    {
        $sidenav = 'damages_records';
        $sidenav_item = 'damages_records_list';
        $title = 'Gestión de Registros de Daños';
        $title_table = 'Listado de Registros de Daños';
        if (auth()->user()->profile_id == 1) {
            // Administrador: muestra todos los registros
            $list_data = DamageRecords::all();
        } elseif (auth()->user()->is_head_of_area) {
            // Jefe de área: muestra los registros del área y los creados por el usuario
            $list_data = DamageRecords::where('area_id', auth()->user()->area_id)
                ->orWhere('user_created', auth()->user()->id)
                ->get();
        } else {
            // Usuario normal: muestra solo los registros creados por el usuario
            $list_data = DamageRecords::where('user_created', auth()->user()->id)->get();
        }
        return view('admin.damage_records.damage_records_list', compact(
            'title',
            'sidenav',
            'sidenav_item',
            'title_table',
            'list_data'
        ));
    }

    public function create()
    {
        $sidenav = 'damages_records';
        $sidenav_item = 'damages_records_new';
        $title = 'Nuevo Registro de Daño';
        $title_form = 'Formulario de Registro de Daño';
        $areas_data = Areas::where('deleted', false)->where('status', true)->get();
        $courses_data = Courses::where('deleted', false)->get();
        $departaments_inventory_data = DB::connection('mysql2')->table('hc_departaments')->where('deleted', false)->where('status', true)->where('company_id', 13)->get();
        $products_inventory_data = DB::connection('mysql2')->table('hc_products')->where('deleted', false)->where('status', true)->where('fixed_asset', true)->where('company_id', 13)->get();
        $floors_inventory_data = DB::connection('mysql2')->table('hc_floors')->where('deleted', false)->where('status', true)->where('company_id', 13)->get();

        return view(
            'admin.damage_records.damage_records_new',
            compact(
                'title',
                'sidenav',
                'sidenav_item',
                'title_form',
                'areas_data',
                'courses_data',
                'departaments_inventory_data',
                'products_inventory_data',
                'floors_inventory_data',
            )
        );
    }

    public function store(Request $request)
    {
        $this->validateData($request);
        $files = $request->file('image_evidence');
        if ($files) {
            $request->validate([
                'image_evidence.*' => 'file|mimes:jpg,png,jpeg,webp,pdf,txt,xls,xlsx|max:5120',
            ], [
                'image_evidence.*.mimes' => 'Formato de archivo no permitido.',
                'image_evidence.*.max' => 'El archivo no debe superar los 5MB.',
            ]);
        }
        $register_data = $this->createOrUpdate($request, '');
        if ($register_data > 0) {
            $files = $request->file('image_evidence');
            $filePaths = [];
            if ($files) {
                foreach ($files as $file) {
                    $path = $file->store('uploads/damage_records/damage_record_' . $register_data, 'public');

                    $filePaths[] = [
                        'url' => Storage::url($path),
                        'name' => $file->getClientOriginalName()
                    ];
                }
                $register = DamageRecords::find($register_data);
                $register->image_evidence = !empty($filePaths) ? json_encode($filePaths) : null;
                $register->updated_at =  ahoraServidor();
                $register->user_updated = auth()->user()->id;
                $register->save();
            }
            return redirect(route('damages-records'))->with(['success_message' => 'Registro Creado Correctamente'])->with(['success_message_title' => 'REPORTE DE DAÑOS']);
        }
        return back()->with(['danger_message' => 'Ha Ocurrido un error al crear. Intente Nuevamente'])->with(['danger_message_title' => 'ERROR INTERNO'])->withInput();
    }

    private function validateData(Request $request)
    {

        $this->validate($request, [
            'record_date' => 'required|date',
            'area' => 'required',
            'department' => 'required',
            'reported_person' => 'required|string|min:3',
            'is_student' => 'required|boolean',
            'incident_sector' => 'required',
            'specific_place' => 'required|string|min:3',
            'dependency' => 'required|string|min:3',
            'fixed_asset' => 'required',
            'damage_description' => 'required|string|min:3',
            'course' => 'required_if:is_student,1'
        ], [
            'record_date.required' => 'Fecha de registro Requerida',
            'record_date.date' => 'La fecha de registro debe ser una fecha válida',
            'area.required' => 'Área Requerida',
            'department.required' => 'Departamento Requerido',
            'reported_person.required' => 'Persona denunciada Requerida',
            'reported_person.string' => 'La persona denunciada debe ser un texto',
            'reported_person.min' => 'El nombre de la persona denunciada debe tener al menos 3 caracteres',
            'is_student.required' => 'Debe especificar si es estudiante',
            'is_student.boolean' => 'El valor de si es estudiante debe ser Si o No',
            'incident_sector.required' => 'Sector del incidente Requerido',
            'specific_place.required' => 'Lugar específico Requerido',
            'specific_place.string' => 'El lugar específico debe ser un texto',
            'specific_place.min' => 'El lugar específico debe tener al menos 3 caracteres',
            'dependency.required' => 'Dependencia Requerida',
            'dependency.string' => 'La dependencia debe ser un texto',
            'dependency.min' => 'La dependencia debe tener al menos 3 caracteres',
            'fixed_asset.required' => 'Activo fijo dañado Requerido',
            'damage_description.required' => 'Descripción de daños generados Requerida',
            'damage_description.string' => 'La descripción de daños generados debe ser un texto',
            'damage_description.min' => 'La descripción de daños generados debe tener al menos 3 caracteres',
            'course.required_if' => 'El curso es requerido si es estudiante'
        ]);
    }

    private function createOrUpdate(Request $request, $register_data = '')
    {
        try {
            if (empty($register_data)) {
                $register_data = new DamageRecords();
                $register_data->created_at =  ahoraServidor();
                $register_data->user_created = auth()->user()->id;
                $register_data->user_charge_id = auth()->user()->user_charge_id;
            }
            $register_data->record_date =  !empty($request->record_date) ? $request->record_date : date('Y-m-d');
            $register_data->area_id = $request->area;
            $register_data->department = !empty($request->department) ? $request->department :  null;
            $register_data->reported_person = strUpper($request->reported_person);
            $register_data->is_student = $request->is_student == 1 ? true : false;
            $register_data->course_id = $request->is_student == 1 ? $request->course : null;
            $register_data->incident_sector = !empty($request->incident_sector) ? $request->incident_sector :  null;
            $register_data->specific_place = !empty($request->specific_place) ? $request->specific_place :  null;
            $register_data->dependency = !empty($request->dependency) ? $request->dependency :  null;
            $register_data->fixed_asset = !empty($request->fixed_asset) ? $request->fixed_asset :  null;
            $register_data->status_damage_record_id = 3;
            $register_data->damage_description =  !empty($request->damage_description) ? $request->damage_description :  null;
            $register_data->updated_at =  ahoraServidor();
            $register_data->user_updated = auth()->user()->id;
            if ($register_data->save()) {
                return $register_data->id;
            }
            return 0;
        } catch (Exception $e) {
            return $e->getMessage();
        }
    }

    private function validateExists($register_id)
    {
        $error = false;
        if (!is_numeric($register_id)) {
            $error = true;
        }

        $register_data = [];
        if (!$error) {
            $register_data = DamageRecords::find($register_id);
            if (empty($register_data)) {
                $error = true;
            }
        }
        return $register_data;
    }

    public function detail(Request $request, $register_id)
    {
        if ($request->session()->pull('from_email', false)) {
            $register_id = $request->session()->pull('register_id');
            return redirect()->route('damages-record-detail', ['id' => $register_id]);
        }
        $form_data = $this->validateExists($register_id);
        if (empty($form_data)) {
            return redirect(route('damages-records'))->with(['danger_message' => 'Registro No existe o fue Eliminado'])->with(['danger_message_title' => 'ERROR DE VALIDACIÓN']);
        }
        if ($form_data->status_damage_record_id < 3) {
            return redirect(route('damages-records'))->with(['danger_message' => 'Solicitud aún se encuentra en curso o no ha sido procesada'])->with(['danger_message_title' => 'ERROR DE VALIDACIÓN']);
        }
        $sidenav = 'damages_records';
        $sidenav_item = 'damages_records_list';
        $title = 'Detalle de Registro de Daños #' . $register_id;
        $title_form = 'Detalle de Registro de Daños #' . $register_id;
        return view(
            'admin.damage_records.damage_records_detail',
            compact(
                'title',
                'sidenav',
                'sidenav_item',
                'title_form',
                'form_data'
            )
        );
    }

    public function update(Request $request, $register_id)
    {

        $register_data = $this->validateExists($register_id);

        if (empty($register_data)) {
            return redirect(route('damages-records'))->with(['danger_message' => 'Registro No existe o fue Eliminado'])->with(['danger_message_title' => 'ERROR DE VALIDACIÓN']);
        }


        if (!empty($request->status_damage_record)) {
            $this->validateDataUpdate($request);
        }
        $files = $request->file('quatations');

        if ($files) {
            $files_add = !empty($register_data->quotation_files) ? count(json_decode($register_data->quotation_files, TRUE)) : 0;
            $files_diff = count($files) + $files_add;
            if ($files_add == 5 && $files_diff > 5) {
                return back()->with(['danger_message' => 'Cotizaciones superan la cantidad máx. de 5 permitidas'])->with(['danger_message_title' => 'ERROR INTERNO'])->withInput();
            }

            $request->validate([
                'quatations.*' => 'file|mimes:jpg,png,jpeg,webp,pdf,txt,xls,xlsx|max:5120',
            ], [
                'quatations.*.mimes' => 'Formato de archivo no permitido.',
                'quatations.*.max' => 'El archivo no debe superar los 5MB.',
            ]);
            $filePaths = [];
            foreach ($files as $file) {
                $path = $file->store('uploads/damage_records/damage_record_' . $register_id . '/quatations', 'public');

                $filePaths[] = [
                    'url' => Storage::url($path),
                    'name' => $file->getClientOriginalName()
                ];
            }
            $register_data->quotation_files = !empty($filePaths) ? json_encode($filePaths) : null;
        }

        $register_data->action_type =  !empty($request->action_type) ? $request->action_type : null;
        $register_data->required_collection =  $request->required_collection == 1 ? true : false;
        $register_data->damage_amount =  !empty($request->damage_amount) ? limpiaMoneda($request->damage_amount) : null;
        $register_data->number_inventory_id =  !empty($request->number_inventory_id) ? limpiaMoneda($request->number_inventory_id) : null;
        $register_data->required_authorization =  $request->required_authorization == 1 ? true : false;
        $register_data->updated_at =  ahoraServidor();
        $register_data->user_updated = auth()->user()->id;
        $register_data->email_head = !empty($request->email_head) ? strLower($request->email_head) : null;

        $msg = 'Solicitud Modificada Correctamente';
        $public_hash = sha1($register_id . date('YmdHis'));
        if (!empty($request->status_damage_record)) {
            $register_data->status_damage_record_id = 5;
            $register_data->finished_at =  ahoraServidor();
            $register_data->user_finished = auth()->user()->id;
            $register_data->public_hash = $public_hash;
            $msg = 'Solicitud Terminada Correctamente';
        }

        if ($register_data->save()) {
            if (!empty($request->status_damage_record)) {
                if (!empty($request->email_head)) {
                    $email = strLower($request->email_head);
                    try {
                        BrevoMailer::send(
                            $email,
                            'Registro de Daños #' . $register_id . ' - Bradford School',
                            'templates_email.finish_damage_records',
                            [
                                'data' =>
                                [
                                    'name' => '',
                                    'damage_record_id' => $register_id,
                                    'comment' => $register_data->damage_description,
                                    'url' => route('damages-record-public') . '?public_hash=' . $public_hash
                                ]
                            ],
                        );
                    } catch (Exception $e) {
                    }
                }

                $heads_of_area = Users::where('is_head_of_area', 1)->where('area_id', $register_data->area_id)->get();
                foreach ($heads_of_area as $key => $hof) {
                    $hof = (object)$hof;
                    $email = strLower($hof->email_head);
                    try {
                        BrevoMailer::send(
                            $email,
                            'Registro de Daños #' . $register_id . ' - Bradford School',
                            'templates_email.finish_damage_records',
                            [
                                'data' =>
                                [
                                    'name' => $hof->name,
                                    'damage_record_id' => $register_id,
                                    'comment' => $register_data->damage_description,
                                    'url' => route('damages-record-detail', ['id' => $register_id]) . '?from_email=true&id=' . $register_id
                                ]
                            ],
                        );
                    } catch (Exception $e) {
                    }
                }
                return redirect(route('damages-records'))->with(['success_message' => $msg])->with(['success_message_title' => 'REGISTROS DE DAÑOS']);
            }
            return redirect(route('damages-record-detail', ['id' => $register_id]))->with(['success_message' => $msg])->with(['success_message_title' => 'REGISTROS DE DAÑOS']);
        }
        return back()->with(['danger_message' => 'Ha Ocurrido un error al modificar. Intente Nuevamente'])->with(['danger_message_title' => 'ERROR INTERNO'])->withInput();
    }


    private function validateDataUpdate(Request $request)
    {

        $rules = [
            'action_type' => 'required',
            'required_collection' => 'required|boolean',
            'damage_amount' => 'required',
            'number_inventory_id' => 'required|integer',
            'required_authorization' => 'required|boolean',
            'email_head' => 'required|email',
        ];

        $messages = [
            'action_type.required' => ' Tipo de acción es Requerida',
            'required_collection.required' => ' Afecto a cobro es Requerido',
            'required_collection.boolean' => ' El valor de Afecto a cobro debe ser SI o NO',
            'damage_amount.required' => ' Valor de daño es Requerido',
            'number_inventory_id.required' => ' N° Doc. Inventory es Requerido',
            'number_inventory_id.integer' => ' N° Doc. Inventory debe ser un número entero',
            'required_authorization.required' => ' Requiere autorización es Requerido',
            'required_authorization.boolean' => ' El valor de Requiere autorización debe ser SI o NO',
            'email_head.required' => ' Correo electrónico jefe Requerido',
            'email_head.email' => ' Correo electrónico jefe debe ser un correo válido',
        ];

        $this->validate($request, $rules, $messages);
    }


    public function cancel(Request $request)
    {
        $this->validate($request, [
            'id_modal' => 'required',
            'reason' => 'required',
        ], [
            'id_modal.required' => 'Id de registro Requerido',
            'reason.required' => 'Motivo de cancelación requerido Requerido',
        ]);

        $register_data = $this->validateExists($request->id_modal);
        if (empty($register_data)) {
            return redirect(route('damages-records'))->with(['danger_message' => 'Registro No existe o fue Eliminado'])->with(['danger_message_title' => 'ERROR DE VALIDACIÓN']);
        }
        $register_data->status_damage_record_id = 4;
        $register_data->cancelled_at =  ahoraServidor();
        $register_data->user_cancelled = auth()->user()->id;
        $register_data->reason_cancellation = $request->reason;
        if ($register_data->save()) {
            return redirect(route('damages-records'))->with(['success_message' => 'Registro Cancelado Correctamente'])->with(['success_message_title' => 'REGISTROS DE DAÑOS']);
        }
        return back()->with(['danger_message' => 'Ha Ocurrido un error al cancelar. Intente Nuevamente'])->with(['danger_message_title' => 'ERROR INTERNO']);
    }

    public function public_damage(Request $request)
    {

        if (!$request->query('public_hash') || empty($request->query('public_hash'))) {
            return redirect(route('login'))->with(['danger_message' => 'Registro No existe o fue Eliminado'])->with(['danger_message_title' => 'ERROR DE VALIDACIÓN']);
        }

        $public_hash =  $request->query('public_hash');
        $form_data = DamageRecords::where('public_hash', $public_hash)->first();
        if (empty($form_data)) {
            return redirect(route('login'))->with(['danger_message' => 'Registro No existe o fue Eliminado'])->with(['danger_message_title' => 'ERROR DE VALIDACIÓN']);
        }

        $sidenav = 'damages_records';
        $sidenav_item = 'damages_records_list';
        $title = 'Detalle de Registro de Daños #' . $form_data->id;
        $title_form = 'Detalle de Registro de Daños #' . $form_data->id;
        return view(
            'admin.damage_records.damage_records_public',
            compact(
                'title',
                'sidenav',
                'sidenav_item',
                'title_form',
                'form_data'
            )
        );
    }
}