<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Carbon;

use Dompdf\Dompdf;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\File;

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;

class PreventiveMaintenanceController extends Controller{
    private $responseController;
    private $encryptionController;
    private $functionsController;
    private $templatesUbic;
    
    public function __construct(){
        $this->responseController = new ResponseController();
        $this->encryptionController = new EncryptionController();
        $this->functionsController = new FunctionsController();
        $this->templatesUbic = "C:\inetpub\wwwroot\sam\storage\app\public\pdf_templates\\01_03_GMPR\\";
    }

    public function registerWorkOrder(Request $request){
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'description' => 'required|string',
            'instructions' => 'required|json',
            'start_date' => 'required|date',
            'start_hour' => 'required|string',
            'end_date' => 'date',
            'end_hour' => 'string',
            'equipment' => 'required|string',
            'inm_time' => 'required|numeric',
            'total_time' => 'required|numeric',
            'teams' => 'required|json',
            'teams_conf' => 'required|json',
            'resources' => 'required|json',
            'activator' => 'required|numeric',
            'attached' => 'json',
            'exists' => 'required|string|in:S,N',
            'id_order' => 'required_if:exists,=,S|string',
            'clasification' => 'required|string|max:100',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $teamsArr = json_decode($form['teams'], true);
        if(empty($teamsArr)){
            return $this->responseController->makeResponse(true, 'El JSON de equipos tiene un formato inválido.', [], 400);
        }

        $teamsConfArr = json_decode($form['teams_conf'], true);
        if(empty($teamsConfArr)){
            return $this->responseController->makeResponse(true, 'El JSON de operadores tiene un formato inválido.', [], 400);
        }

        $resources = json_decode($form['resources'], true);
        if(empty($resources)){
            return $this->responseController->makeResponse(true, 'El JSON de recursos tiene un formato inválido.', [], 400);
        }

        $activator = DB::table('S002V01TACTI')->where([
            ['ACTI_NULI', '=', $form['linea']],
            ['ACTI_IDCO', '=', $form['activator']]
        ])->first();
        
        if(is_null($activator)){
            return $this->responseController->makeResponse(true, 'El activador seleccionado no está registrado.', [], 404);
        }

        $startHourArr = explode(' ', $form['start_hour']);
        if(count($startHourArr) < 2){
            return $this->responseController->makeResponse(true, 'La hora de inicio tiene un formato inválido.', [], 400);
        }else if(!in_array('PM', $startHourArr) && !in_array('AM', $startHourArr)){
            return $this->responseController->makeResponse(true, 'No se pudo determinar el periodo de la hora inicial.', [], 400);
        }

        $hourIniArr = explode(':', $startHourArr[0]);
        if(count($hourIniArr) < 2){
            return $this->responseController->makeResponse(true, 'La hora de inicio tiene un formato inválido.', [], 400);
        }

        $hourIni = intval($hourIniArr[0]);
        if($startHourArr[1] == 'PM' && $hourIni < 12){
            $hourIni += 12;
        }

        $hourIniStr = $hourIni < 10 ? "0$hourIni" : "$hourIni";
        $hourIniStr .= ":$hourIniArr[1]:00";
        $dateTimeStart = new Carbon("$form[start_date] $hourIniStr");

        $ftap = '0001-01-01 00:00:00';
        if(isset($form['end_hour'])){
            $endHourArr = explode(' ', $form['end_hour']);
            if(count($endHourArr) < 2){
                return $this->responseController->makeResponse(true, 'La hora de término tiene un formato inválido.', [], 400);
            }else if(!in_array('PM', $endHourArr) && !in_array('AM', $endHourArr)){
                return $this->responseController->makeResponse(true, 'No se pudo determinar el periodo de la hora final.', [], 400);
            }

            $hourFinArr = explode(':', $endHourArr[0]);
            if(count($hourFinArr) < 2){
                return $this->responseController->makeResponse(true, 'La hora de término tiene un formato inválido.', [], 400);
            }

            $hourFin = intval($hourFinArr[0]);
            if($endHourArr[1] == 'PM' && $hourFin < 12){
                $hourFin += 12;
            }

            $hourFinStr = $hourFin < 10 ? "0$hourFin" : "$hourFin";
            $hourFinStr .= ":$hourFinArr[1]:00";
            $dateTimeEnd = new Carbon("$form[end_date] $hourFinStr");
    
            if($dateTimeStart->gt($dateTimeEnd)){
                return $this->responseController->makeResponse(true, 'La hora de término es menor a la hora de inicio.', [], 400);
            }

            $ftap = $dateTimeEnd->toDateTimeString();
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $fiap = $dateTimeStart->toDateTimeString();
        $done = isset($form['attached']) ? $form['attached'] : null;

        if($form['exists'] == 'S'){
            $idOrder = $this->encryptionController->decrypt($form['id_order']);
            if(!$idOrder){
                return $this->responseController->makeResponse(true, 'El ID de la orden no fue encriptado correctamente.', [], 400);
            }

            $order = DB::table('S002V01TOTPR')->where([
                ['OTPR_IDOT', '=', $idOrder],
                ['OTPR_NULI', '=', $form['linea']]
            ])->first();

            if(is_null($order)){
                return $this->responseController->makeResponse(true, 'La orden enviada no existe.', [], 404);
            }
            
            DB::table('S002V01TOTPR')->where([
                ['OTPR_IDOT', '=', $idOrder],
                ['OTPR_NULI', '=', $form['linea']]
            ])->update([
                'OTPR_DEIN' => $form['description'],
                'OTPR_ININ' => $form['instructions'],
                'OTPR_EQIN' => $form['equipment'],
                'OTPR_FIAP' => $fiap,
                'OTPR_FTAP' => $ftap,
                'OTPR_TIIN' => $form['inm_time'],
                'OTPR_EQIT' => $form['teams'],
                'OTPR_OPPR' => $form['teams_conf'],
                'OTPR_DTIN' => $form['total_time'],
                'OTPR_RHRE' => $form['resources'],
                'OTPR_DONE' => $done,
                'OTPR_ACAS' => $form['activator'],
                'OTPR_CLAS' => $form['clasification'],
                'OTPR_ESTA' => 'R',
                'OTPR_USMO' => $idUser,
                'OTPR_FEMO' => $nowStr,
            ]);
        }else{
            $idOrder = DB::table('S002V01TOTPR')->insertGetId([
                'OTPR_NULI' => $form['linea'],
                'OTPR_DEIN' => $form['description'],
                'OTPR_ININ' => $form['instructions'],
                'OTPR_EQIN' => $form['equipment'],
                'OTPR_FIAP' => $fiap,
                'OTPR_FTAP' => $ftap,
                'OTPR_TIIN' => $form['inm_time'],
                'OTPR_EQIT' => $form['teams'],
                'OTPR_OPPR' => $form['teams_conf'],
                'OTPR_DTIN' => $form['total_time'],
                'OTPR_RHRE' => $form['resources'],
                'OTPR_DONE' => $done,
                'OTPR_ACAS' => $form['activator'],
                'OTPR_CLAS' => $form['clasification'],
                'OTPR_ESTA' => 'R',
                'OTPR_USRE' => $idUser,
                'OTPR_FERE' => $nowStr,
            ]);
        }

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P01ROTR',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró la orden de trabajo #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function getWorkOrders($idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $workOrders = DB::table('S002V01TOTPR')->where('OTPR_NULI', '=', $line)->orderBy('OTPR_IDOT', 'desc')->get()->all();
        $orders = [];
        foreach($workOrders as $order){
            $idOrderEnc = $this->encryptionController->encrypt($order->OTPR_IDOT);
            $startDateTimeArr = explode(' ', $order->OTPR_FIAP);
            $startDate = $startDateTimeArr[0] == '0001-01-01' ? null : $startDateTimeArr[0];
            $startTimeArr = explode(':', $startDateTimeArr[1]);
            $hour = intval($startTimeArr[0]);
            $period = '';

            if($hour > 12){
                $hour -= 12;
                $period = 'PM';
            }else{
                $period = 'AM';
            }

            $startHour = "$hour:$startTimeArr[1] $period";
            $endDateTimeArr = explode(' ', $order->OTPR_FTAP);
            $endDate = $endDateTimeArr[0] == '0001-01-01' ? null : $endDateTimeArr[0];
            $endTimeArr = explode(':', $endDateTimeArr[1]);
            $hour = intval($endTimeArr[0]);
            $period = '';

            if($hour > 12){
                $hour -= 12;
                $period = 'PM';
            }else{
                $period = 'AM';
            }

            $endHour = "$hour:$endTimeArr[1] $period";
            $activatorType = '-';

            if($order->OTPR_ACAS > 0){
                $acti = DB::table('S002V01TACTI')->where([
                    ['ACTI_NULI', '=', $line],
                    ['ACTI_IDCO', '=', $order->OTPR_ACAS]
                ])->first();

                if(!is_null($acti)){
                    $activatorType = $acti->ACTI_TIAC;
                }
            }

            $orders[] = [
                'IDORDEN' => $idOrderEnc,
                'DESCRIPCION' => $order->OTPR_DEIN,
                'EQUIPO' => $order->OTPR_EQIN,
                'FECHAINICIO' => $startDate,
                'HORAINICIO' => $startHour,
                'FECHAFINAL' => $endDate,
                'HORAFINAL' => $endHour,
                'ACTIVATOR' => $order->OTPR_ACAS,
                'TIPOACTIVADOR' => $activatorType,
                'PRIORIDAD' => $acti->ACTI_PRIO,
                'ESTATUS' => $order->OTPR_ESTA
            ];
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P01HOTP',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las órdenes de trabajo registradas.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $orders);
    }

    public function getWorkOrdersByMonth($month, $year, $idUser, $line){
        //PENDIENTE ELIMINAR
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $events = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_ESTA', '!=', 'Eliminado'],
        ])->orderBy(
            'OTPR_FIIN', 'asc'
        )->orderBy(
            'OTPR_HIIN', 'asc'
        )->orderBy(
            'OTPR_PRIO', 'asc'
        )->get()->all();

        try{
            $firstDay = new Carbon("$year-$month-01", 'America/Mexico_city');
            $days = $firstDay->daysInMonth;
            $lastDay = new Carbon("$year-$month-$days", 'America/Mexico_city');
        }catch(\Carbon\Exceptions\InvalidFormatException $e){
            return $this->responseController->makeResponse(true, 'El mes o el año tienen un formato incorrecto', [], 400);
        }

        $eventsArr = [];
        foreach($events as $event){
            $repetition = json_decode($event->OTPR_REPE, true);
            $startDate = new Carbon($event->OTPR_FIIN, 'America/Mexico_city');
            
            switch($repetition['type']){
                case "NR":
                    if($startDate->gte($firstDay) && $startDate->lte($lastDay)){
                        $dateStr = $startDate->toDateString();
                        $exec = DB::table('S002V01TBEOT')->where([
                            ['BEOT_NULI', '=', $line],
                            ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                            ['BEOT_FEPR', '=', $dateStr],
                        ])->first();

                        $esta = 'NE';
                        if(!is_null($exec)){
                            $estatus = $exec->BEOT_TIAC;
                            $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                        }
                        
                        $eventsArr[$dateStr][] = [
                            'IDORDEN' => $event->OTPR_IDOT,
                            'TITULO' => $event->OTPR_TIOR,
                            'ESTATUS' => $esta,
                        ]; 
                    }
                break;
                case "SE":
                    $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                    while($iniAux->lte($lastDay)){
                        $dateStr = $iniAux->toDateString();
                        $exec = DB::table('S002V01TBEOT')->where([
                            ['BEOT_NULI', '=', $line],
                            ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                            ['BEOT_FEPR', '=', $dateStr],
                        ])->first();

                        $esta = 'NE';
                        if(!is_null($exec)){
                            $estatus = $exec->BEOT_TIAC;
                            $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                        }
                        
                        $eventsArr[$dateStr][] = [
                            'IDORDEN' => $event->OTPR_IDOT,
                            'TITULO' => $event->OTPR_TIOR,
                            'ESTATUS' => $esta,
                        ];
                        $iniAux->addWeek();
                    }
                break;
                case "ME":
                    $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                    while($iniAux->lte($lastDay)){
                        $dateStr = $iniAux->toDateString();
                        $exec = DB::table('S002V01TBEOT')->where([
                            ['BEOT_NULI', '=', $line],
                            ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                            ['BEOT_FEPR', '=', $dateStr],
                        ])->first();

                        $esta = 'NE';
                        if(!is_null($exec)){
                            $estatus = $exec->BEOT_TIAC;
                            $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                        }
                        
                        $eventsArr[$dateStr][] = [
                            'IDORDEN' => $event->OTPR_IDOT,
                            'TITULO' => $event->OTPR_TIOR,
                            'ESTATUS' => $esta,
                        ];
                        $iniAux->addMonth();
                    }
                break;
                case "AN":
                    $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                    while($iniAux->lte($lastDay)){
                        $dateStr = $iniAux->toDateString();
                        $exec = DB::table('S002V01TBEOT')->where([
                            ['BEOT_NULI', '=', $line],
                            ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                            ['BEOT_FEPR', '=', $dateStr],
                        ])->first();

                        $esta = 'NE';
                        if(!is_null($exec)){
                            $estatus = $exec->BEOT_TIAC;
                            $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                        }

                        $eventsArr[$dateStr][] = [
                            'IDORDEN' => $event->OTPR_IDOT,
                            'TITULO' => $event->OTPR_TIOR,
                            'ESTATUS' => $esta,
                        ];
                        $iniAux->addYear();
                    }
                break;
                case "TD":
                    $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                    while($iniAux->lte($lastDay)){
                        $dateStr = $iniAux->toDateString();
                        $exec = DB::table('S002V01TBEOT')->where([
                            ['BEOT_NULI', '=', $line],
                            ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                            ['BEOT_FEPR', '=', $dateStr],
                        ])->first();

                        $esta = 'NE';
                        if(!is_null($exec)){
                            $estatus = $exec->BEOT_TIAC;
                            $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                        }

                        $eventsArr[$iniAux->toDateString()][] = [
                            'IDORDEN' => $event->OTPR_IDOT,
                            'TITULO' => $event->OTPR_TIOR,
                            'ESTATUS' => $esta,
                        ];
                        $iniAux->addDay();
                    }
                break;
                case "PE":
                    $periods = ['D', 'W', 'M', 'Y'];
                    $config = json_decode($repetition['config'], true);
                    $repeatEvery = explode('|', $config['repeatEvery']);
                    $endsAt = explode('|', $config['endsAt']);
                    $period = $periods[intval($repeatEvery[1])];

                    switch($endsAt[0]){
                        case "N":
                            $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                            while($iniAux->lte($lastDay)){
                                if($period == 'W'){
                                    $weekStart = (new Carbon($iniAux->toDateTimeString(), 'America/Mexico_city'))->subDays($iniAux->dayOfWeek);
                                    for($i = 0; $i < 7; $i++){
                                        $dayName = $weekStart->dayName;
                                        $dayName = strtolower($dayName);
                                        $dayName = substr($dayName, 0, 3);
                                    
                                        if($config['repeatOn'][$dayName] && $weekStart->gte($startDate)){
                                            $dateStr = $weekStart->toDateString();
                                            $exec = DB::table('S002V01TBEOT')->where([
                                                ['BEOT_NULI', '=', $line],
                                                ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                                                ['BEOT_FEPR', '=', $dateStr],
                                            ])->first();

                                            $esta = 'NE';
                                            if(!is_null($exec)){
                                                $estatus = $exec->BEOT_TIAC;
                                                $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                                            }

                                            $eventsArr[$dateStr][] = [
                                                'IDORDEN' => $event->OTPR_IDOT,
                                                'TITULO' => $event->OTPR_TIOR,
                                                'ESTATUS' => $esta,
                                            ];
                                        }

                                        $weekStart->addDay();
                                    }
                                }else{
                                    $dateStr = $iniAux->toDateString();
                                    $exec = DB::table('S002V01TBEOT')->where([
                                        ['BEOT_NULI', '=', $line],
                                        ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                                        ['BEOT_FEPR', '=', $dateStr],
                                    ])->first();

                                    $esta = 'NE';
                                    if(!is_null($exec)){
                                        $estatus = $exec->BEOT_TIAC;
                                        $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                                    }

                                    $eventsArr[$dateStr][] = [
                                        'IDORDEN' => $event->OTPR_IDOT,
                                        'TITULO' => $event->OTPR_TIOR,
                                        'ESTATUS' => $esta,
                                    ];
                                }

                                if($period == 'D') $iniAux->addDays(intval($repeatEvery[0]));
                                if($period == 'W') $iniAux->addWeeks(intval($repeatEvery[0]));
                                if($period == 'M') $iniAux->addMonths(intval($repeatEvery[0]));
                                if($period == 'Y') $iniAux->addYears(intval($repeatEvery[0]));
                            }
                        break;
                        case "O":
                            $endDateArr = explode('-', $endsAt[1]);
                            $month = intval($endDateArr[1]) + 1 < 10 ? "0" . intval($endDateArr[1]) + 1 : "" . intval($endDateArr[1]) + 1 . "";
                            $endDateStr = "$endDateArr[2]-$month-$endDateArr[0]";
                            $endDate = new Carbon($endDateStr, 'America/Mexico_city');
                            $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                            while($iniAux->lte($lastDay)){
                                if($period == 'W'){
                                    $weekStart = (new Carbon($iniAux->toDateTimeString(), 'America/Mexico_city'))->subDays($iniAux->dayOfWeek);
                                    for($i = 0; $i < 7; $i++){
                                        $dayName = $weekStart->dayName;
                                        $dayName = strtolower($dayName);
                                        $dayName = substr($dayName, 0, 3);
                                    
                                        if($config['repeatOn'][$dayName] && $weekStart->gte($startDate) && $weekStart->lte($endDate)){
                                            $dateStr = $weekStart->toDateString();
                                            $exec = DB::table('S002V01TBEOT')->where([
                                                ['BEOT_NULI', '=', $line],
                                                ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                                                ['BEOT_FEPR', '=', $dateStr],
                                            ])->first();
        
                                            $esta = 'NE';
                                            if(!is_null($exec)){
                                                $estatus = $exec->BEOT_TIAC;
                                                $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                                            }

                                            $eventsArr[$dateStr][] = [
                                                'IDORDEN' => $event->OTPR_IDOT,
                                                'TITULO' => $event->OTPR_TIOR,
                                                'ESTATUS' => $esta,
                                            ];
                                        }

                                        $weekStart->addDay();
                                    }
                                }else{
                                    if($iniAux->lte($endDate)){
                                        $dateStr = $iniAux->toDateString();
                                        $exec = DB::table('S002V01TBEOT')->where([
                                            ['BEOT_NULI', '=', $line],
                                            ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                                            ['BEOT_FEPR', '=', $dateStr],
                                        ])->first();
    
                                        $esta = 'NE';
                                        if(!is_null($exec)){
                                            $estatus = $exec->BEOT_TIAC;
                                            $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                                        }

                                        $eventsArr[$dateStr][] = [
                                            'IDORDEN' => $event->OTPR_IDOT,
                                            'TITULO' => $event->OTPR_TIOR,
                                            'ESTATUS' => $esta,
                                        ];
                                    }
                                }

                                if($period == 'D') $iniAux->addDays(intval($repeatEvery[0]));
                                if($period == 'W') $iniAux->addWeeks(intval($repeatEvery[0]));
                                if($period == 'M') $iniAux->addMonths(intval($repeatEvery[0]));
                                if($period == 'Y') $iniAux->addYears(intval($repeatEvery[0]));
                            }
                        break;
                        case "A":
                            $repeat = intval($endsAt[2]);
                            $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                            $cont = 0;
                            while($iniAux->lte($lastDay)){
                                if($period == 'W'){
                                    $weekStart = (new Carbon($iniAux->toDateTimeString(), 'America/Mexico_city'))->subDays($iniAux->dayOfWeek);
                                    for($i = 0; $i < 7; $i++){
                                        $dayName = $weekStart->dayName;
                                        $dayName = strtolower($dayName);
                                        $dayName = substr($dayName, 0, 3);
                                    
                                        if($config['repeatOn'][$dayName] && $weekStart->gte($startDate) && $cont < $repeat){
                                            $dateStr = $weekStart->toDateString();
                                            $exec = DB::table('S002V01TBEOT')->where([
                                                ['BEOT_NULI', '=', $line],
                                                ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                                                ['BEOT_FEPR', '=', $dateStr],
                                            ])->first();
        
                                            $esta = 'NE';
                                            if(!is_null($exec)){
                                                $estatus = $exec->BEOT_TIAC;
                                                $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                                            }
                                            
                                            $eventsArr[$dateStr][] = [
                                                'IDORDEN' => $event->OTPR_IDOT,
                                                'TITULO' => $event->OTPR_TIOR,
                                                'ESTATUS' => $esta,
                                            ];
                                        }

                                        $weekStart->addDay();
                                    }
                                }else{
                                    if($cont < $repeat){
                                        $dateStr = $iniAux->toDateString();
                                        $exec = DB::table('S002V01TBEOT')->where([
                                            ['BEOT_NULI', '=', $line],
                                            ['BEOT_IDOT', '=', $event->OTPR_IDOT],
                                            ['BEOT_FEPR', '=', $dateStr],
                                        ])->first();
    
                                        $esta = 'NE';
                                        if(!is_null($exec)){
                                            $estatus = $exec->BEOT_TIAC;
                                            $esta = $estatus == 'Ejecucion' ? 'EJ' : ($estatus == 'Finalizado' ? 'FI' : 'CA');
                                        }

                                        $eventsArr[$dateStr][] = [
                                            'IDORDEN' => $event->OTPR_IDOT,
                                            'TITULO' => $event->OTPR_TIOR,
                                            'ESTATUS' => $esta,
                                        ];
                                    }
                                }

                                if($period == 'D') $iniAux->addDays(intval($repeatEvery[0]));
                                if($period == 'W') $iniAux->addWeeks(intval($repeatEvery[0]));
                                if($period == 'M') $iniAux->addMonths(intval($repeatEvery[0]));
                                if($period == 'Y') $iniAux->addYears(intval($repeatEvery[0]));

                                $cont++;
                            }
                        break;
                    }
                break;
            }
        }
        
        $eventsF = [];
        foreach($eventsArr as $fec => $events){
            foreach($events as $event){
                $eventsF[] = [
                    "IDORDEN" => $event['IDORDEN'],
                    "TITULO" => $event['TITULO'],
                    "FECHA" => $fec,
                    'ESTATUS' => array_key_exists('ESTATUS', $event) ? $event['ESTATUS'] : '-',
                ];
            }
        }

        $actions = DB::getQueryLog();
        $nowStr = Carbon::now('America/Mexico_city')->toDateTimeString();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P02COME',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los eventos del mes $month del $year.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $eventsF);
    }

    public function getWorkOrdersByDay($day, $month, $year, $idUser, $line){
        //PENDIENTE ELIMINAR
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $events = DB::table('S002V01TOTPR')->select([
            'OTPR_IDOT AS IDORDEN',
            'OTPR_TIOR AS TITULO',
            'OTPR_FIIN AS FECHAINICIO',
            'OTPR_HIIN AS HORAINICIO',
            'OTPR_TIES AS TIEMPOESTIMADO',
            'OTPR_CEIN AS CODIGOEQUIPO',
            'OTPR_CLAS AS CLASIFICACION',
            'OTPR_PRIO AS PRIORIDAD',
            'OTPR_ESTA AS ESTADO',
            'OTPR_REPE AS REPETICION'
        ])->where([
            ['OTPR_NULI', '=', $line]
        ])->orderBy(
            'OTPR_FIIN', 'asc'
        )->orderBy(
            'OTPR_HIIN', 'asc'
        )->orderBy(
            'OTPR_PRIO', 'asc'
        )->get()->all();

        try{
            $consultedDay = new Carbon("$year-$month-$day", 'America/Mexico_city');
            $firstDay = new Carbon("$year-$month-01", 'America/Mexico_city');
            $days = $firstDay->daysInMonth;
            $lastDay = new Carbon("$year-$month-$days", 'America/Mexico_city');
        }catch(\Carbon\Exceptions\InvalidFormatException $e){
            return $this->responseController->makeResponse(true, 'El día, mes o el año tienen un formato incorrecto', [], 400);
        }

        $eventsArr = [];
        foreach($events as $event){
            $repetition = json_decode($event->REPETICION, true);
            $startDate = new Carbon($event->FECHAINICIO, 'America/Mexico_city');
            $startDate = new Carbon($startDate->toDateString(), 'America/Mexico_city');
            
            switch($repetition['type']){
                case "NR":
                    if($consultedDay->eq($startDate)){
                        $eventsArr[$startDate->toDateString()][] = $event; 
                    }
                break;
                case "SE":
                    $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                    while($iniAux->lte($lastDay)){
                        if($consultedDay->eq($iniAux)){
                            $eventsArr[$iniAux->toDateString()][] = $event;
                        }
                        $iniAux->addWeek();
                    }
                break;
                case "ME":
                    $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                    while($iniAux->lte($lastDay)){
                        if($consultedDay->eq($iniAux)){
                            $eventsArr[$iniAux->toDateString()][] = $event;
                        }
                        $iniAux->addMonth();
                    }
                break;
                case "AN":
                    $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                    while($iniAux->lte($lastDay)){
                        if($consultedDay->eq($iniAux)){
                            $eventsArr[$iniAux->toDateString()][] = $event;
                        }
                        $iniAux->addYear();
                    }
                break;
                case "TD":
                    $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                    while($iniAux->lte($lastDay)){
                        if($consultedDay->eq($iniAux)){
                            $eventsArr[$iniAux->toDateString()][] = $event;
                        }
                        $iniAux->addDay();
                    }
                break;
                case "PE":
                    $periods = ['D', 'W', 'M', 'Y'];
                    $config = json_decode($repetition['config'], true);
                    $repeatEvery = explode('|', $config['repeatEvery']);
                    $endsAt = explode('|', $config['endsAt']);
                    $period = $periods[intval($repeatEvery[1])];

                    switch($endsAt[0]){
                        case "N":
                            $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                            while($iniAux->lte($lastDay)){
                                if($period == 'W'){
                                    $weekStart = (new Carbon($iniAux->toDateTimeString(), 'America/Mexico_city'))->subDays($iniAux->dayOfWeek);
                                    for($i = 0; $i < 7; $i++){
                                        $dayName = $weekStart->dayName;
                                        $dayName = strtolower($dayName);
                                        $dayName = substr($dayName, 0, 3);
                                    
                                        if($config['repeatOn'][$dayName] && $weekStart->gte($startDate)){
                                            if($consultedDay->eq($weekStart)){
                                                $eventsArr[$weekStart->toDateString()][] = $event;
                                            }
                                        }

                                        $weekStart->addDay();
                                    }
                                }else{
                                    if($consultedDay->eq($iniAux)){
                                        $eventsArr[$iniAux->toDateString()][] = $event;
                                    }
                                }

                                if($period == 'D') $iniAux->addDays(intval($repeatEvery[0]));
                                if($period == 'W') $iniAux->addWeeks(intval($repeatEvery[0]));
                                if($period == 'M') $iniAux->addMonths(intval($repeatEvery[0]));
                                if($period == 'Y') $iniAux->addYears(intval($repeatEvery[0]));
                            }
                        break;
                        case "O":
                            $endDateArr = explode('-', $endsAt[1]);
                            $month = intval($endDateArr[1]) + 1 < 10 ? "0" . intval($endDateArr[1]) + 1 : "" . intval($endDateArr[1]) + 1 . "";
                            $endDateStr = "$endDateArr[2]-$month-$endDateArr[0]";
                            $endDate = new Carbon($endDateStr, 'America/Mexico_city');
                            $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                            while($iniAux->lte($lastDay)){
                                if($period == 'W'){
                                    $weekStart = (new Carbon($iniAux->toDateTimeString(), 'America/Mexico_city'))->subDays($iniAux->dayOfWeek);
                                    for($i = 0; $i < 7; $i++){
                                        $dayName = $weekStart->dayName;
                                        $dayName = strtolower($dayName);
                                        $dayName = substr($dayName, 0, 3);
                                    
                                        if($config['repeatOn'][$dayName] && $weekStart->gte($startDate) && $weekStart->lte($endDate)){
                                            if($consultedDay->eq($weekStart)){
                                                $eventsArr[$weekStart->toDateString()][] = $event;
                                            }
                                        }

                                        $weekStart->addDay();
                                    }
                                }else{
                                    if($iniAux->lte($endDate)){
                                        if($consultedDay->eq($iniAux)){
                                            $eventsArr[$iniAux->toDateString()][] = $event;
                                        }
                                    }
                                }

                                if($period == 'D') $iniAux->addDays(intval($repeatEvery[0]));
                                if($period == 'W') $iniAux->addWeeks(intval($repeatEvery[0]));
                                if($period == 'M') $iniAux->addMonths(intval($repeatEvery[0]));
                                if($period == 'Y') $iniAux->addYears(intval($repeatEvery[0]));
                            }
                        break;
                        case "A":
                            $repeat = intval($endsAt[2]);
                            $iniAux = new Carbon($startDate->toDateTimeString(), 'America/Mexico_city');
                            $cont = 0;
                            while($iniAux->lte($lastDay)){
                                if($period == 'W'){
                                    $weekStart = (new Carbon($iniAux->toDateTimeString(), 'America/Mexico_city'))->subDays($iniAux->dayOfWeek);
                                    for($i = 0; $i < 7; $i++){
                                        $dayName = $weekStart->dayName;
                                        $dayName = strtolower($dayName);
                                        $dayName = substr($dayName, 0, 3);
                                    
                                        if($config['repeatOn'][$dayName] && $weekStart->gte($startDate) && $cont < $repeat){
                                            if($consultedDay->eq($weekStart)){
                                                $eventsArr[$weekStart->toDateString()][] = $event;
                                            }
                                        }

                                        $weekStart->addDay();
                                    }
                                }else{
                                    if($cont < $repeat){
                                        if($consultedDay->eq($iniAux)){
                                            $eventsArr[$iniAux->toDateString()][] = $event;
                                        }
                                    }
                                }

                                if($period == 'D') $iniAux->addDays(intval($repeatEvery[0]));
                                if($period == 'W') $iniAux->addWeeks(intval($repeatEvery[0]));
                                if($period == 'M') $iniAux->addMonths(intval($repeatEvery[0]));
                                if($period == 'Y') $iniAux->addYears(intval($repeatEvery[0]));

                                $cont++;
                            }
                        break;
                    }
                break;
            }
        }
        
        $eventsF = [];
        foreach($eventsArr as $fec => $events){
            foreach($events as $event){
                $exec = DB::table('S002V01TBEOT')->where([
                    ['BEOT_NULI', '=', $line],
                    ['BEOT_IDOT', '=', $event->IDORDEN],
                    ['BEOT_FEPR', '=', $fec]
                ])->first();

                if(!is_null($exec)){
                    $event->ESTADO = $exec->BEOT_TIAC;
                }

                $eventsF[] = $event;
            }
        }

        $actions = DB::getQueryLog();
        $nowStr = Carbon::now('America/Mexico_city')->toDateTimeString();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P03CODI',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los eventos del día $day de $month del $year.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $eventsF);
    }

    public function getWorkOrder($id, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }
        
        $id = $this->encryptionController->shortDec($id);
        if(!$id){
            return $this->responseController->makeResponse(true, 'El ID de la orden no está encriptado correctamente.', [], 400);
        }

        $workOrder = DB::table('S002V01TOTPR')->where([
            ['OTPR_IDOT', '=', $id],
            ['OTPR_NULI', '=', $line],
        ])->first();

        if(is_null($workOrder)){
            return $this->responseController->makeResponse(true, 'La orden de trabajo consultada no existe.', [], 404);
        }

        $activatorTypes = ['Calendario' => 'CA', 'Sintoma' => 'SI', 'Medida' => 'ME', 'Valor' => 'VA'];
        $activator = DB::table('S002V01TACTI')->where([
            ['ACTI_NULI', '=', $line],
            ['ACTI_IDCO', '=', $workOrder->OTPR_ACAS],
        ])->first();

        $startDateTimeArr = explode(' ', $workOrder->OTPR_FIAP);
        $startTimeArr = explode(':', $startDateTimeArr[1]);
        $startHour = intval($startTimeArr[0]);
        $startPeriod = $startHour < 12 ? 'AM' : 'PM';
        $startHour = $startHour > 12 ? $startHour - 12 : $startHour;

        $endDateTimeArr = explode(' ', $workOrder->OTPR_FTAP);
        $endTimeArr = explode(':', $endDateTimeArr[1]);
        $endHour = intval($endTimeArr[0]);
        $endPeriod = $endHour < 12 ? 'AM' : 'PM';
        $endHour = $endHour > 12 ? $endHour - 12 : $endHour;

        $workOrderF = (object) [
            'IDORDEN' => $workOrder->OTPR_IDOT,
            'DESCRIPCION' => $workOrder->OTPR_DEIN == '-' ? '' : $workOrder->OTPR_DEIN,
            'INSTRUCCIONES' => $workOrder->OTPR_ININ,
            'EQUIPAMIENTO' => $workOrder->OTPR_EQIN == '-' ? '' : $workOrder->OTPR_EQIN,
            'FECHAINICIO' => $startDateTimeArr[0] == '0001-01-01' ? '' : $startDateTimeArr[0],
            'HORAINICIO' => "$startHour:$startTimeArr[1] $startPeriod",
            'FECHAFINAL' => $endDateTimeArr[0] == '0001-01-01' ? '' : $endDateTimeArr[0],
            'HORAFINAL' => "$endHour:$endTimeArr[1] $endPeriod",
            'ANALISIS' => $workOrder->OTPR_SEAN,
            'TIEMPOINMOESTI' => $workOrder->OTPR_TIIN,
            'CLASIFICACION' => $workOrder->OTPR_CLAS == '-' ? '' : $workOrder->OTPR_CLAS,
            'PERSONAL' => $workOrder->OTPR_EQIT,
            'OPERARIOS' => $workOrder->OTPR_OPPR,
            'DURACIONTOTAL' => $workOrder->OTPR_DTIN,
            'RECURSOS' => $workOrder->OTPR_RHRE,
            'DOCUMENTOS' => $workOrder->OTPR_DONE,
            'CONTRATOS' => $workOrder->OTPR_RECO,
            'ACTIVADOR' => is_null($activator) ? null : $workOrder->OTPR_ACAS,
            'TIPOACTIVADOR' => is_null($activator) ? null : $activatorTypes[$activator->ACTI_TIAC],
            'ESTADO' => $workOrder->OTPR_ESTA,
            'USUARIOREGISTRA' => $workOrder->OTPR_USRE,
            'FECHAREGISTRO' => $workOrder->OTPR_FERE,
            'USUARIOMODIFICA' => $workOrder->OTPR_USMO,
            'FECHAMODIFICACION' => $workOrder->OTPR_FEMO,
        ];

        $usrReg = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $workOrderF->USUARIOREGISTRA],
        ])->first();

        $nameReg = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
        $workOrderF->USUARIOREGISTRA = $nameReg . " (" . $workOrderF->USUARIOREGISTRA . ")";

        if(!is_null($workOrderF->USUARIOMODIFICA)){
            $usrMod = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $workOrderF->USUARIOMODIFICA],
            ])->first();

            $nameMod = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA);
            $workOrderF->USUARIOMODIFICA = $nameMod . " (" . $workOrderF->USUARIOMODIFICA . ")";
        }

        if(!is_null($workOrderF->ANALISIS)){
            $analysisArr = json_decode($workOrderF->ANALISIS, true);
            $teamsConf = $analysisArr['teamsConf'];

            foreach($teamsConf as $team=>$conf){
                $cont = 0;
                foreach($conf as $val){
                    $usrInfo = DB::table('S002V01TUSUA')->where([
                        ['USUA_NULI', '=', $line],
                        ['USUA_IDUS', '=', $val['USER']],
                    ])->first();
                    
                    $usrInfoName = $this->functionsController->joinName($usrInfo->USUA_NOMB, $usrInfo->USUA_APPA, $usrInfo->USUA_APMA) . " ($val[USER])";
                    $val['USER'] = $usrInfoName;
                    $conf[$cont] = $val;

                    $cont++;
                }

                $teamsConf[$team] = $conf;
            }

            $analysisArr['teamsConf'] = $teamsConf;
            $workOrderF->ANALISIS = json_encode($analysisArr);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P04COIN',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó la orden de trabajo #$id.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $workOrderF);
    }

    public function executePreventiveWorkOrder(Request $request){
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|integer',
            'execution_date' => 'required|date'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $workOrder = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $form['id_order']]
        ])->first();
        
        if(is_null($workOrder)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }else if($workOrder->OTPR_ESTA != 'A'){
            return $this->responseController->makeResponse(true, 'La orden solicitada no está activa.', [], 401);
        }

        $execDate = new Carbon($form['execution_date']);
        $fecIni = new Carbon($workOrder->OTPR_FIAP);

        if($fecIni->gt($execDate)){
            $tmp = $fecIni->toDateTimeString() . '|' . $execDate->toDateTimeString();
            return $this->responseController->makeResponse(true, 'La fecha de ejecución es menor a la fecha de inicio.' . $tmp, [], 400);
        }

        $execDateStr = $execDate->toDateString();
        $execution = DB::table('S002V01TBEOT')->where([
            ['BEOT_NULI', '=', $form['linea']],
            ['BEOT_IDOT', '=', $form['id_order']],
            ['BEOT_FEPR', '=', $execDateStr]
        ])->first();

        if(!is_null($execution)){
            $estatus = $execution->BEOT_TIAC;
            if($estatus == 'Ejecucion'){
                return $this->responseController->makeResponse(true, "La ejecución de la orden para la fecha $execDateStr ya fue realizada.", [], 401);
            }else if($estatus == 'Cancelacion'){
                return $this->responseController->makeResponse(true, "La ejecución de la orden para la fecha $execDateStr fue cancelada.", [], 401);
            }else if($estatus == 'Finalizado'){
                return $this->responseController->makeResponse(true, "La ejecución de la orden para la fecha $execDateStr ya ha finalizado.", [], 401);
            }
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TBEOT')->insert([
            'BEOT_NULI' => $form['linea'],
            'BEOT_IDOT' => $form['id_order'],
            'BEOT_FEPR' => $execDateStr,
            'BEOT_TIAC' => 'Ejecucion',
            'BEOT_FEEJ' => $nowStr,
            'BEOT_USEJ' => $idUser,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F02EMOT',
            '-',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") ejecutó la orden de trabajo #$form[id_order] programada para la fecha $execDateStr.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function cancelWorkOrder(Request $request){
        //PENDIENTE REVISAR
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|integer',
            'execution_date' => 'required|date',
            'observations' => 'required|string',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $workOrder = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $form['id_order']]
        ])->first();
        
        if(is_null($workOrder)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe', [], 404);
        }

        $execDate = new Carbon($form['execution_date']);
        $fecIni = new Carbon($workOrder->OTPR_FIAP);

        if($fecIni->gt($execDate)){
            return $this->responseController->makeResponse(true, 'La fecha de ejecución es menor a la fecha de inicio.', [], 400);
        }

        $execDateStr = $execDate->toDateString();
        $execution = DB::table('S002V01TBEOT')->where([
            ['BEOT_NULI', '=', $form['linea']],
            ['BEOT_IDOT', '=', $form['id_order']],
            ['BEOT_FEPR', '=', $execDateStr]
        ])->first();

        if(!is_null($execution)){
            $estatus = $execution->BEOT_TIAC;
            if($estatus == 'Ejecucion'){
                return $this->responseController->makeResponse(true, "La programación de la orden para la fecha $execDateStr no se puede cancelar porque ya se ha iniciado su ejecución.", [], 401);
            }else if($estatus == 'Finalizado'){
                return $this->responseController->makeResponse(true, "La programación de la orden para la fecha $execDateStr no se puede cancelar porque ya se ha finalizado.", [], 401);
            }else if($estatus == 'Cancelacion'){
                return $this->responseController->makeResponse(true, "La ejecución de la orden para la fecha $execDateStr ya ha sido cancelada.", [], 401);
            }
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        DB::table('S002V01TBEOT')->insert([
            'BEOT_NULI' => $form['linea'],
            'BEOT_IDOT' => $form['id_order'],
            'BEOT_FEPR' => $execDateStr,
            'BEOT_TIAC' => 'Cancelacion',
            'BEOT_OBSE' => $form['observations'],
            'BEOT_FEEJ' => $nowStr,
            'BEOT_USEJ' => $idUser,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F02EMOT',
            '-',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") canceló la orden de trabajo #$form[id_order] programada para la fecha $execDateStr.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function deleteWorkOrder(Request $request){
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no fue encriptado correctamente.', [], 400);
        }

        $workOrder = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $idOrder]
        ])->first();
        
        if(is_null($workOrder)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe', [], 404);
        }else if($workOrder->OTPR_ESTA == 'E'){
            return $this->responseController->makeResponse(true, 'La orden solicitada está eliminada', [], 401);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TOTPR')->where([
            ['OTPR_IDOT', '=', $idOrder],
            ['OTPR_NULI', '=', $form['linea']]
        ])->update([
            'OTPR_ESTA' => 'E',
            'OTPR_USMO' => $idUser,
            'OTPR_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F04EOTP',
            '-',
            'Eliminación',
            "El usuario $name (" . $usr->USUA_IDUS . ") eliminó la orden de trabajo #$form[id_order].",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function updateWorkOrder(Request $request){
        //PENDIENTE ELIMINAR
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|integer',
            'title' => 'required|string',
            'repeat' => 'required|json',
            'start_date' => 'required|date',
            'start_hour' => 'required|string',
            'inm_time' => 'required|numeric',
            'description' => 'required|string|max:100',
            'clasification' => 'required|string|max:50',
            'priority' => 'required|string|in:1,2,3',
            'equipment' => 'required|string',
            'analisis' => 'required|string',
            'specialties' => 'required|json',
            'attached' => 'json',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $workOrder = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $form['id_order']]
        ])->first();
        
        if(is_null($workOrder)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe', [], 404);
        }

        $repeArr = json_decode($form['repeat'], true);
        if(empty($repeArr)){
            return $this->responseController->makeResponse(true, 'El JSON de repetición tiene un formato inválido.', [], 400);
        }else if(!array_key_exists('type', $repeArr)){
            return $this->responseController->makeResponse(true, 'El campo type no fue enviado en el JSON de repetición.', [], 400);
        }else if(!array_key_exists('config', $repeArr)){
            return $this->responseController->makeResponse(true, 'El campo config no fue enviado en el JSON de repetición.', [], 400);
        }
        
        $hourArr = explode(' ', $form['start_hour']);
        $timeArr = '';
        if(count($hourArr) < 2){
            return $this->responseController->makeResponse(true, 'La hora de inicio tiene un formato inválido.', [], 400);
        }else if($hourArr[1] == 'PM'){
            $hour = explode(':', $hourArr[0]);

            $h = intval($hour[0]);
            if($h != 12){
                $h = $h + 12;
            }

            $hourStr = "$h:$hour[1]:00";
            $timeArr .= " $hourStr";
        }else if($hourArr[1] == 'AM'){
            $hour = explode(':', $hourArr[0]);

            $h = intval($hour[0]);
            $hStr = $h < 10 ? "0$h" : "$h";
            $hStr .= ":$hour[1]:00";
            $timeArr .= " $hStr";
        }else{
            return $this->responseController->makeResponse(true, 'No se pudo determinar el periodo del horario.', [], 400);
        }

        $specialtiesArr = json_decode($form['specialties'], true);

        if(empty($specialtiesArr)){
            return $this->responseController->makeResponse(true, 'El JSON de especialidades tiene un formato inválido.', [], 400);
        }

        foreach($specialtiesArr as $specialty){
            if(!array_key_exists('specialty', $specialty)){
                return $this->responseController->makeResponse(true, 'El campo specialty no fue enviado en el JSON de especialidad.', [], 400);
            }else if(!array_key_exists('type', $specialty)){
                return $this->responseController->makeResponse(true, 'El campo type no fue enviado en el JSON de especialidad.', [], 400);
            }else if(!array_key_exists('staff', $specialty)){
                return $this->responseController->makeResponse(true, 'El campo staff no fue enviado en el JSON de especialidad.', [], 400);
            }
        }

        $documents = isset($form['attached']) ? $form['attached'] : null;
        $nowStr = Carbon::now('America/Mexico_city')->toDateTimeString();
        DB::table('S002V01TOTPR')->where([
            ['OTPR_IDOT', '=', $form['id_order']],
            ['OTPR_NULI', '=', $form['linea']],
        ])->update([
            'OTPR_TIOR' => $form['title'],
            'OTPR_REPE' => $form['repeat'],
            'OTPR_FIIN' => $form['start_date'],
            'OTPR_HIIN' => $timeArr,
            'OTPR_TIES' => $form['inm_time'],
            'OTPR_DEIN' => $form['description'],
            'OTPR_ANIN' => $form['analisis'],
            'OTPR_CEIN' => $form['equipment'],
            'OTPR_PERE' => $form['specialties'],
            'OTPR_CLAS' => $form['clasification'],
            'OTPR_PRIO' => $form['priority'],
            'OTPR_DONE' => $documents,
            'OTPR_USRE' => $idUser,
            'OTPR_FERE' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P01ROTR',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó la orden de trabajo $form[title] ($form[id_order]).",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function geStartedtWorkOrders($idUser, $line){
        //PENDIENTE REVISAR
        DB::enableQueryLog();
        
        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser]
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $startedWorkOrders = DB::table('S002V01TBEOT')->select([
            'BEOT_IDRE AS IDREGISTRO',
            'BEOT_IDOT AS IDORDEN',
            'BEOT_FEPR AS FECHAPROGRAMA',
            'BEOT_FEEJ AS FECHAEJECUCION',
            'BEOT_USEJ AS USUARIOEJECUCION',
            'BEOT_TIAC AS ESTADO',
            'OTPR_TIOR AS TITULOORDEN',
            'OTPR_HIIN AS HORAPROGRAMA',
            'OTPR_TIES AS TIEMPOESTIMADO',
            'OTPR_PRIO AS PRIORIDAD',
        ])->join('S002V01TOTPR', 'OTPR_IDOT', '=', 'BEOT_IDOT')->where([
            ['BEOT_NULI', '=', $line],
        ])->get()->all();

        foreach($startedWorkOrders as $workOrder){
            $usrEje = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $workOrder->USUARIOEJECUCION]
            ])->first();

            $nameEje = $this->functionsController->joinName($usrEje->USUA_NOMB, $usrEje->USUA_APPA, $usrEje->USUA_APMA);
            $workOrder->USUARIOEJECUCION = $nameEje . " (" . $workOrder->USUARIOEJECUCION . ")";
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F05BEOT',
            'S002V01P01HOEJ',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las órdenes de trabajo en ejecución.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $startedWorkOrders);
    }

    public function endOrderExecution(Request $request){
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|integer',
            'id_reg' => 'required|integer',
            'observations' => 'required|string|min:50',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $workOrder = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $form['id_order']]
        ])->first();
        
        if(is_null($workOrder)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe', [], 404);
        }

        $register = DB::table('S002V01TBEOT')->where([
            ['BEOT_NULI', '=', $form['linea']],
            ['BEOT_IDRE', '=', $form['id_reg']],
            ['BEOT_IDOT', '=', $form['id_order']]
        ])->first();
        
        if(is_null($register)){
            return $this->responseController->makeResponse(true, 'El registro solicitado no existe', [], 404);
        }else if($register->BEOT_TIAC == 'Cancelacion'){
            return $this->responseController->makeResponse(true, 'El registro solicitado fue cancelado', [], 401);
        }else if($register->BEOT_TIAC == 'Finalizado'){
            return $this->responseController->makeResponse(true, 'El registro solicitado ya fue finalizado', [], 401);
        }

        $now = $this->functionsController->now();
        $executionDate = new Carbon($register->BEOT_FEEJ);

        $diff = $now->diffInMilliseconds($executionDate); //Milisegundos
        $diff = $diff / 1000;                             //Segundos
        $diff = $diff / 60;                               //Minutos
        $diff = $diff / 60;                               //Horas

        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TBEOT')->where([
            ['BEOT_NULI', '=', $form['linea']],
            ['BEOT_IDRE', '=', $form['id_reg']],
            ['BEOT_IDOT', '=', $form['id_order']]
        ])->update([
            "BEOT_TIAC" => 'Finalizado',
            "BEOT_DTEJ" => $diff,
            "BEOT_OBSE" => $form['observations'],
            "BEOT_FEFI" => $nowStr,
            "BEOT_USFI" => $idUser,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F05SEOR',
            '-',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") finalizó la ejecución del día ". $register->BEOT_FEPR ." de la orden #$form[id_order].",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function getExecRegister($date, $idOrder, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $workOrder = DB::table('S002V01TOTPR')->where([
            ['OTPR_IDOT', '=', $idOrder],
            ['OTPR_NULI', '=', $line],
        ])->first();

        if(is_null($workOrder)){
            return $this->responseController->makeResponse(true, 'La orden de trabajo solicitada no existe.', [], 404);
        }

        $validDate = $this->functionsController->validDate($date);
        if(!$validDate){
            return $this->responseController->makeResponse(true, 'La fecha enviada tiene un formato inválido.', [], 400);
        }
        
        $exec = DB::table('S002V01TBEOT')->where([
            ['BEOT_NULI', '=', $line],
            ['BEOT_IDOT', '=', $idOrder],
            ['BEOT_FEPR', '=', $date], 
        ])->first();

        $res = [
            'DESCRIPCION' => $workOrder->OTPR_DEIN,
            'EQUIPAMIENTO' => $workOrder->OTPR_EQIN,
            'FECHAINICIO' => $workOrder->OTPR_FIAP,
            'ESTADODEEJECUCION' => is_null($exec) ? 'Programada' : $exec->BEOT_TIAC,
            'IDREG' => is_null($exec) ? null : $exec->BEOT_IDRE,
            'OBSERVACIONES' => is_null($exec) ? null : $exec->BEOT_OBSE,
        ];

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F08VCPR',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó el estado de la ejecución de la orden #$idOrder para la fecha $date.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $res);
    }

    public function copyWorkOrder(Request $request){
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|integer',
            'equipment' => 'required|string',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }
        
        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser],
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $workOrder = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $form['id_order']]
        ])->first();
        
        if(is_null($workOrder)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }

        $idEq = $this->encryptionController->decrypt($form['equipment']);
        if(!$idEq){
            return $this->responseController->makeResponse(true, 'El ID del equipo no fue encriptado correctamente.', [], 400);
        }

        if($idEq == $workOrder->OTPR_EQIN){
            return $this->responseController->makeResponse(true, 'El equipo seleccionado es igual al de la orden copiada.', [], 400);
        }

        //Verificar que el equipamiento exista
        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $idOrder = DB::table('S002V01TOTPR')->insertGetId([
            "OTPR_NULI" => $form['linea'],
            "OTPR_DEIN" => $workOrder->OTPR_DEIN,
            "OTPR_ININ" => $workOrder->OTPR_ININ,
            "OTPR_EQIN" => $idEq,
            "OTPR_FIAP" => $workOrder->OTPR_FIAP,
            "OTPR_FTAP" => $workOrder->OTPR_FTAP,
            "OTPR_SEAN" => $workOrder->OTPR_SEAN,
            "OTPR_TIIN" => $workOrder->OTPR_TIIN,
            "OTPR_EQIT" => $workOrder->OTPR_EQIT,
            "OTPR_OPPR" => $workOrder->OTPR_OPPR,
            "OTPR_DTIN" => $workOrder->OTPR_DTIN,
            "OTPR_RHRE" => $workOrder->OTPR_RHRE,
            "OTPR_DONE" => '[]',
            "OTPR_RECO" => $workOrder->OTPR_RECO,
            "OTPR_ACAS" => $workOrder->OTPR_ACAS,
            "OTPR_CLAS" => $workOrder->OTPR_CLAS,
            "OTPR_ESTA" => 'R',
            "OTPR_USRE" => $idUser, 
            "OTPR_FERE" => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F06COVE',
            '-',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") copió la orden #$form[id_order] para el equipo $idEq dentro de la orden #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function savePresetWorkOrder(Request $request){
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'exists' => 'required|string|in:S,N',
            'id_order' => 'required_if:exists,=,S|string',
            'description' => 'required|string',
            'instructions' => 'required|string',
            'startDate' => 'required|string',
            'startHour' => 'required|string',
            'endDate' => 'required|string',
            'endHour' => 'required|string',
            'equipment' => 'required|string',
            'inmTime' => 'required|string',
            'totalTime' => 'required|string',
            'teams' => 'required|string',
            'teamsConf' => 'required|string',
            'tools' => 'required|string',
            'toolsConf' => 'required|string',
            'spareParts' => 'required|string',
            'sparePartsConf' => 'required|string',
            'attached' => 'required|string',
            'activatorType' => 'required|string',
            'activator' => 'required|string',
            'clasification' => 'required|string|max:100',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }
 
        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser],
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        $dein = $form['description'];
        $eqin = $form['equipment'];

        $startDate = '0001-01-01';
        if($form['startDate'] != '-'){
            $startDate = $form['startDate'];
        }

        $startHour = '00:00:00';
        if($form['startHour'] != '-'){
            $hourArr = explode(' ', $form['startHour']);
            $arr = explode(':', $hourArr[0]);
            $hour = intval($arr[0]);

            if($hourArr[1] == 'PM' && $hour < 12){
                $hour += 12;
            }

            $timeStr = $hour < 10 ? "0$hour" : "$hour";
            $startHour = "$timeStr:$arr[1]:00";
        }

        $fiap = "$startDate $startHour";
        $endDate = '0001-01-01';
        if($form['endDate'] != '-'){
            $endDate = $form['endDate'];
        }

        $endHour = '00:00:00';
        if($form['endHour'] != '-'){
            $hourArr = explode(' ', $form['endHour']);
            $arr = explode(':', $hourArr[0]);
            $hour = intval($arr[0]);

            if($hourArr[1] == 'PM' && $hour < 12){
                $hour += 12;
            }

            $timeStr = $hour < 10 ? "0$hour" : "$hour";
            $endHour = "$timeStr:$arr[1]:00";
        }

        $ftap = "$endDate $endHour";
        $tiin = $form['inmTime'] == '-' ? 0 : floatval($form['inmTime']);
        $eqit = $form['teams'] == '-' ? '{}' : $form['teams'];
        $oppr = $form['teamsConf'] == '-' ? '{}' : $form['teamsConf'];
        $dtin = $form['inmTime'] == '-' ? 0 : floatval($form['inmTime']);

        $toolsParts = [];
        if($form['tools'] != '-'){
            $toolsArr = json_decode($form['tools'], true);
            $toolsConfArr = json_decode($form['toolsConf'], true);
            
            foreach($toolsConfArr as $tool=>$conf){
                if(in_array($tool, $toolsArr)){
                    $toolsParts[] = [
                        'ID' => $tool,
                        'TYPE' => 'T',
                        'REQ' => $conf,
                    ];
                }
            }
        }

        if($form['spareParts'] != '-'){
            $sparePartsArr = json_decode($form['spareParts'], true);
            $sparePartsConfArr = json_decode($form['sparePartsConf'], true);

            foreach($sparePartsConfArr as $part=>$conf){
                if(in_array($part, $sparePartsArr)){
                    $toolsParts[] = [
                        'ID' => $part,
                        'TYPE' => 'S',
                        'REQ' => $conf,
                    ];
                }
            }
        }

        $rhre = json_encode($toolsParts);
        $done = $form['attached'] == '-' ? null : $form['attached'];
        $acas = $form['activator'] == '-' ? 0 : $form['activator'];
        $inin = $form['instructions'] == '-' ? '{}' : $form['instructions'];
        $clas = $form['clasification'];

        if($form['exists'] == 'N'){
            $idOrder = DB::table('S002V01TOTPR')->insertGetId([
                'OTPR_NULI' => $form['linea'],
                'OTPR_DEIN' => $dein,
                'OTPR_ININ' => $inin,
                'OTPR_EQIN' => $eqin,
                'OTPR_FIAP' => $fiap,
                'OTPR_FTAP' => $ftap,
                'OTPR_TIIN' => $tiin,
                'OTPR_EQIT' => $eqit,
                'OTPR_OPPR' => $oppr,
                'OTPR_DTIN' => $dtin,
                'OTPR_RHRE' => $rhre,
                'OTPR_DONE' => $done,
                'OTPR_ACAS' => $acas,
                'OTPR_CLAS' => $clas,
                'OTPR_ESTA' => 'B',
                'OTPR_USRE' => $idUser,
                'OTPR_FERE' => $nowStr,
            ]);
        }else{
            $idOrder = $this->encryptionController->decrypt($form['id_order']);
            if(!$idOrder){
                return $this->responseController->makeResponse(true, 'El ID de la orden no fue encriptado correctamente.', [], 400);
            }

            $order = DB::table('S002V01TOTPR')->where([
                ['OTPR_NULI', '=', $form['linea']],
                ['OTPR_IDOT', '=', $idOrder],
            ])->first();
        
            if(is_null($order)){
                return $this->responseController->makeResponse(true, 'La orden enviada no existe.', [], 404);
            }

            DB::table('S002V01TOTPR')->where([
                ['OTPR_NULI', '=', $form['linea']],
                ['OTPR_IDOT', '=', $idOrder]
            ])->update([
                'OTPR_DEIN' => $dein,
                'OTPR_ININ' => $inin,
                'OTPR_EQIN' => $eqin,
                'OTPR_FIAP' => $fiap,
                'OTPR_FTAP' => $ftap,
                'OTPR_TIIN' => $tiin,
                'OTPR_EQIT' => $eqit,
                'OTPR_OPPR' => $oppr,
                'OTPR_DTIN' => $dtin,
                'OTPR_RHRE' => $rhre,
                'OTPR_DONE' => $done,
                'OTPR_ACAS' => $acas,
                'OTPR_CLAS' => $clas,
                'OTPR_USMO' => $idUser,
                'OTPR_FEMO' => $nowStr,
            ]);
        }

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);

        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P02ROTP',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró un borrador para la orden de trabajo #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeresponse(false, "EXITO");
    }

    public function getActiveOrders($idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser]
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $activeWorkOrders = DB::table('S002V01TOTPR')->select([
            'OTPR_IDOT AS IDORDEN',
            'OTPR_EQIN AS EQUIPAMIENTO',
            'OTPR_FIAP AS FECHAINICIO',
            'OTPR_FTAP AS FECHATERMINO',
            'OTPR_TIIN AS TIEMPOESTIMADO',
            'OTPR_DTIN AS TIEMPOTOTAL',
            'OTPR_CLAS AS CLASIFICACION',
            'OTPR_ACAS AS ACTIVADOR',
            'ACTI_PRIO AS PRIORIDAD',
            'ACTI_TIAC AS TIPOACTIVADOR'
        ])->join('S002V01TACTI', 'ACTI_IDCO', '=', 'OTPR_ACAS')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_ESTA', '=', 'A']
        ])->get()->all();

        $actions = DB::getQueryLog();
        $nowStr = Carbon::now('America/Mexico_city')->toDateTimeString();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F01ACMA',
            'S002V01P01OTAC',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las órdenes de mantenimiento preventivo activas.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $activeWorkOrders);
    }

    public function getPreventiveCalendar($fecIni, $fecFin, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        if(!$this->functionsController->validDate($fecIni)){
            return $this->responseController->makeResponse(true, 'La fecha de inicio es inválida.', [], 400);
        }

        if(!$this->functionsController->validDate($fecFin)){
            return $this->responseController->makeResponse(true, 'La fecha final es inválida.', [], 400);
        }

        $fecIniObj = new Carbon($fecIni . ' 00:00:00');
        $fecFinObj = new Carbon($fecFin . ' 23:59:59');

        $workOrders = DB::table('S002V01TOTPR')->join('S002V01TACTI', 'ACTI_IDCO', '=', 'OTPR_ACAS')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_ESTA', '=', 'A'],
        ])->get()->all();

        $programmedWorkOrders = [];
        foreach($workOrders as $order){
            $orderStart = new Carbon($order->OTPR_FIAP);
            if($order->ACTI_TIAC == 'Calendario' || $order->ACTI_TIAC == 'Sintoma'){
                $repeatConfig = json_decode($order->ACTI_COAC, true);
                switch($repeatConfig['repeat']){
                    case 'AN':
                        while ($orderStart->lte($fecFinObj)){
                            if($orderStart->gte($fecIniObj)){
                                $reg = DB::table('S002V01TBEOT')->where([
                                    ['BEOT_NULI', '=', $line],
                                    ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                    ['BEOT_FEPR', '=', $orderStart->toDateString()]
                                ])->first();
                                
                                $programmedWorkOrders[] = [
                                    "IDORDEN" => $order->OTPR_IDOT,
                                    "EVENTCOLOR" => $repeatConfig['color'],
                                    "DATE" => $orderStart->toDateString(),
                                    "TYPE" => $order->ACTI_TIAC,
                                    "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                                ];
                            }
                            $orderStart->addYear();
                        }
                    break;
                    case 'ME':
                        while ($orderStart->lte($fecFinObj)){
                            if($orderStart->gte($fecIniObj)){
                                $reg = DB::table('S002V01TBEOT')->where([
                                    ['BEOT_NULI', '=', $line],
                                    ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                    ['BEOT_FEPR', '=', $orderStart->toDateString()]
                                ])->first();
                                
                                $programmedWorkOrders[] = [
                                    "IDORDEN" => $order->OTPR_IDOT,
                                    "EVENTCOLOR" => $repeatConfig['color'],
                                    "DATE" => $orderStart->toDateString(),
                                    "TYPE" => $order->ACTI_TIAC,
                                    "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                                ];
                            }
                            $orderStart->addMonth();
                        }
                    break;
                    case 'SE':
                        while ($orderStart->lte($fecFinObj)){
                            if($orderStart->gte($fecIniObj)){
                                $reg = DB::table('S002V01TBEOT')->where([
                                    ['BEOT_NULI', '=', $line],
                                    ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                    ['BEOT_FEPR', '=', $orderStart->toDateString()]
                                ])->first();
                                
                                $programmedWorkOrders[] = [
                                    "IDORDEN" => $order->OTPR_IDOT,
                                    "EVENTCOLOR" => $repeatConfig['color'],
                                    "DATE" => $orderStart->toDateString(),
                                    "TYPE" => $order->ACTI_TIAC,
                                    "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                                ];
                            }
                            $orderStart->addWeek();
                        }
                    break;
                    case 'TD':
                        while ($orderStart->lte($fecFinObj)){
                            if($orderStart->gte($fecIniObj)){
                                $reg = DB::table('S002V01TBEOT')->where([
                                    ['BEOT_NULI', '=', $line],
                                    ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                    ['BEOT_FEPR', '=', $orderStart->toDateString()]
                                ])->first();
                                
                                $programmedWorkOrders[] = [
                                    "IDORDEN" => $order->OTPR_IDOT,
                                    "EVENTCOLOR" => $repeatConfig['color'],
                                    "DATE" => $orderStart->toDateString(),
                                    "TYPE" => $order->ACTI_TIAC,
                                    "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                                ];
                            }
                            $orderStart->addDay();
                        }
                    break;
                    case 'NR':
                        if($orderStart->gte($fecIniObj) && $orderStart->lte($fecFinObj)){
                            $reg = DB::table('S002V01TBEOT')->where([
                                ['BEOT_NULI', '=', $line],
                                ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                ['BEOT_FEPR', '=', $orderStart->toDateString()]
                            ])->first();
                            
                            $programmedWorkOrders[] = [
                                "IDORDEN" => $order->OTPR_IDOT,
                                "EVENTCOLOR" => $repeatConfig['color'],
                                "DATE" => $orderStart->toDateString(),
                                "TYPE" => $order->ACTI_TIAC,
                                "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                            ];
                        }
                    break;
                    case 'PE':
                        $customRepeat = json_decode($repeatConfig['customRepeat'], true);
                        $repeatEvery = explode('|', $customRepeat['repeatEvery']);
                        switch($repeatEvery[1]){
                            case '0':
                                //Repeticiones por día
                                $days = intval($repeatEvery[0]);
                                while ($orderStart->lte($fecFinObj)){
                                    if($orderStart->gte($fecIniObj)){
                                        $reg = DB::table('S002V01TBEOT')->where([
                                            ['BEOT_NULI', '=', $line],
                                            ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                            ['BEOT_FEPR', '=', $orderStart->toDateString()]
                                        ])->first();
                                        
                                        $programmedWorkOrders[] = [
                                            "IDORDEN" => $order->OTPR_IDOT,
                                            "EVENTCOLOR" => $repeatConfig['color'],
                                            "DATE" => $orderStart->toDateString(),
                                            "TYPE" => $order->ACTI_TIAC,
                                            "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                                        ];
                                    }
                                    $orderStart->addDays($days);
                                }
                            break;
                            case '1':
                                //Repeticiones por semana
                                $weeks = intval($repeatEvery[0]);
                                $orderStartAux = new Carbon($orderStart->toDateTimeString());
                                $repeatOn = $customRepeat['repeatOn'];
                                while ($orderStart->lte($fecFinObj)){
                                    $dayInd = $orderStartAux->dayOfWeek;
                                    for($i = $dayInd; $i < 7; $i++){
                                        $dayName = strtolower($orderStartAux->dayName);
                                        $dayKey = substr($dayName, 0, 3);
                                        $shouldRepeat = $repeatOn[$dayKey];

                                        if($shouldRepeat && $orderStartAux->lte($fecFinObj) && $orderStartAux->gte($fecIniObj)){
                                            $reg = DB::table('S002V01TBEOT')->where([
                                                ['BEOT_NULI', '=', $line],
                                                ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                                ['BEOT_FEPR', '=', $orderStart->toDateString()]
                                            ])->first();
                                            
                                            $programmedWorkOrders[] = [
                                                "IDORDEN" => $order->OTPR_IDOT,
                                                "EVENTCOLOR" => $repeatConfig['color'],
                                                "DATE" => $orderStartAux->toDateString(),
                                                "TYPE" => $order->ACTI_TIAC,
                                                "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                                            ];
                                        }

                                        $orderStartAux->addDay();
                                    }
                                    $orderStartAux->addWeeks($weeks);
                                    $orderStart->addWeeks($weeks);
                                }
                            break;
                            case '2':
                                //Repeticiones por mes
                                $months = intval($repeatEvery[0]);
                                while ($orderStart->lte($fecFinObj)){
                                    if($orderStart->gte($fecIniObj)){
                                        $reg = DB::table('S002V01TBEOT')->where([
                                            ['BEOT_NULI', '=', $line],
                                            ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                            ['BEOT_FEPR', '=', $orderStart->toDateString()]
                                        ])->first();
                                        
                                        $programmedWorkOrders[] = [
                                            "IDORDEN" => $order->OTPR_IDOT,
                                            "EVENTCOLOR" => $repeatConfig['color'],
                                            "DATE" => $orderStart->toDateString(),
                                            "TYPE" => $order->ACTI_TIAC,
                                            "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                                        ];
                                    }
                                    $orderStart->addMonths($months);
                                }
                            break;
                            case '3':
                                //Repeticiones por año
                                $years = intval($repeatEvery[0]);
                                while ($orderStart->lte($fecFinObj)){
                                    if($orderStart->gte($fecIniObj)){
                                        $reg = DB::table('S002V01TBEOT')->where([
                                            ['BEOT_NULI', '=', $line],
                                            ['BEOT_IDOT', '=', $order->OTPR_IDOT],
                                            ['BEOT_FEPR', '=', $orderStart->toDateString()]
                                        ])->first();

                                        $programmedWorkOrders[] = [
                                            "IDORDEN" => $order->OTPR_IDOT,
                                            "EVENTCOLOR" => $repeatConfig['color'],
                                            "DATE" => $orderStart->toDateString(),
                                            "TYPE" => $order->ACTI_TIAC,
                                            "REGEST" => is_null($reg) ? 'Programada' : $reg->BEOT_TIAC,
                                        ];
                                    }
                                    $orderStart->addYears($years);
                                }
                            break;
                        }
                    break;
                }
            }
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F08VCPR',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los eventos programados entre las fechas $fecIni y $fecFin.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $programmedWorkOrders);
    }

    public function newUnprogrammedOrder(Request $request){
        DB::enableQueryLog();

        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'equipment' => 'required|string',
            'teams' => 'required|json',
            'resources' => 'required|json',
            'comments' => 'required|string|min:35',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        $teamsArr = json_decode($form['teams'], true);
        if(empty($teamsArr)){
            return $this->responseController->makeResponse(true, 'El JSON de equipos tiene un formato inválido.', [], 400);
        }

        $resources = json_decode($form['resources'], true);
        if(empty($resources)){
            return $this->responseController->makeResponse(true, 'El JSON de recursos tiene un formato inválido.', [], 400);
        }

        $commentsArr = [
            'CI' => $form['comments']
        ];

        $commentsStr = json_encode($commentsArr);
        $idVisit = DB::table('S002V01TRVTN')->insertGetId([
            'RVTN_NULI' => $form['linea'],
            'RVTN_EQRE' => $form['equipment'],
            'RVTN_PEIN' => $form['teams'],
            'RVTN_MAUT' => $form['resources'],
            'RVTN_COME' => $commentsStr,
            'RVTN_USRE' => $idUser,
            'RVTN_FERE' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F11RVTP',
            'S002V01P01REVI',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró la visita no programada #$idVisit.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function getUnprogrammedVisits($status, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $status = $this->encryptionController->shortDec($status);
        if(!$status){
            return $this->responseController->makeResponse(true, 'El arreglo de estados no está encriptado correctamente.', [], 400);
        }

        $statusArr = json_decode($status, true);
        $whereArr = [
            ['RVTN_NULI', '=', $line],
        ];

        foreach($statusArr as $k=>$v){
            if(!$v){
                $whereArr[] = ['RVTN_ESTA', '!=', $k];
            }
        }

        $visits = DB::table('S002V01TRVTN')->select([
            'RVTN_IDVI AS IDVISITA',
            'RVTN_EQRE AS EQUIPAMIENTO',
            'RVTN_ESTA AS ESTATUS',
            'RVTN_USRE AS USRREG',
            'RVTN_FERE AS FECREG',
            'RVTN_UARE AS USAURE',
            'RVTN_FARE AS FEAURE',
            'RVTN_USCA AS USRCAN',
            'RVTN_FECA AS FECCAN',
            'RVTN_USFI AS USRFIN',
            'RVTN_FEFI AS FECFIN',
            'RVTN_USMO AS USRMOD',
            'RVTN_FEMO AS FECMOD',
        ])->where($whereArr)->get()->all();

        foreach($visits as $visit){
            $usrReg = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $visit->USRREG]
            ])->first();
            $nameReg = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
            $nameReg .= " (" . $visit->USRREG . ")";

            $visit->USRREG = $nameReg;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F11RVTP',
            'S002V01P02COVI',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó la lista de visitas no programadas.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $visits);
    }

    public function getUnprogrammedVisit($idVisit, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_IDUS', '=', $idUser],
            ['USUA_NULI', '=', $line]
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }
        
        $idVisit = $this->encryptionController->shortDec($idVisit);
        if(!$idVisit){
            return $this->responseController->makeResponse(true, 'El ID de la visita solicitada no está encriptado correctamente.', [], 400);
        }

        $visit = DB::table('S002V01TRVTN')->select([
            'RVTN_IDVI AS IDVISITA',
            'RVTN_EQRE AS EQUIPAMIENTO',
            'RVTN_PEIN AS PERSONAL',
            'RVTN_MAUT AS MATERIAL',
            'RVTN_COME AS COMENTARIOS',
            'RVTN_ESTA AS ESTADO',
            'RVTN_USRE AS USRREG',
            'RVTN_FERE AS FECREG',
            'RVTN_UARE AS USAURE',
            'RVTN_FARE AS FEAURE',
            'RVTN_USCA AS USRCAN',
            'RVTN_FECA AS FECCAN',
            'RVTN_USFI AS USUFIN',
            'RVTN_FEFI AS FECFIN',
            'RVTN_USMO AS USRMOD',
            'RVTN_FEMO AS FECMOD',
        ])->where([
            ['RVTN_IDVI', '=', $idVisit],
            ['RVTN_NULI', '=', $line]
        ])->first();

        if(is_null($visit)){
            return $this->responseController->makeResponse(true, 'La visita consultada no existe.', [], 404);
        }

        $usrReg = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $visit->USRREG],
        ])->first();
        $nameReg = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA) . " (" . $visit->USRREG . ")";
        $visit->USRREG = $nameReg;

        if(!is_null($visit->USAURE)){
            $usaure = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $visit->USAURE],
            ])->first();
            $nameUre = $this->functionsController->joinName($usaure->USUA_NOMB, $usaure->USUA_APPA, $usaure->USUA_APMA) . " (" . $visit->USAURE . ")";
            $visit->USAURE = $nameUre;
        }

        if(!is_null($visit->USRCAN)){
            $usrCan = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $visit->USRCAN],
            ])->first();
            $nameCan = $this->functionsController->joinName($usrCan->USUA_NOMB, $usrCan->USUA_APPA, $usrCan->USUA_APMA) . " (" . $visit->USRCAN . ")";
            $visit->USRCAN = $nameCan;
        }

        if(!is_null($visit->USUFIN)){
            $usrFin = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $visit->USUFIN],
            ])->first();
            $nameFin = $this->functionsController->joinName($usrFin->USUA_NOMB, $usrFin->USUA_APPA, $usrFin->USUA_APMA) . " (" . $visit->USUFIN . ")";
            $visit->USUFIN = $nameFin;
        }

        if(!is_null($visit->USRMOD)){
            $usrMod = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $visit->USRMOD],
            ])->first();
            $nameMod = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA) . " (" . $visit->USRMOD . ")";
            $visit->USRMOD = $nameMod;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F11RVTP',
            'S002V01P02COVI',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó la visita no programada #$idVisit.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $visit);
    }

    public function updateVisitStatus(Request $request){
        DB::enableQueryLog();

        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_visit' => 'required|string',
            'comments' => 'required|string|min:35',
            'status' => 'required|string|in:C,R,A,F'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idVisit = $this->encryptionController->decrypt($form['id_visit']);
        if(!$idVisit){
            return $this->responseController->makeResponse(true, 'El ID de la visita solicitada no está encriptado correctamente.', [], 400);
        }

        $visit = DB::table('S002V01TRVTN')->where([
            ['RVTN_NULI', '=', $form['linea']],
            ['RVTN_IDVI', '=', $idVisit],
        ])->first();

        $commentsArr = json_decode($visit->RVTN_COME, true);
        $commentsArr["C$form[status]"] = $form['comments'];
        $commentsStr = json_encode($commentsArr);

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        $updateArr = [
            'RVTN_ESTA' => $form['status'],
            'RVTN_COME' => $commentsStr,
            'RVTN_USMO' => $idUser,
            'RVTN_FEMO' => $nowStr,
        ];

        if($form['status'] == 'A' || $form['status'] == 'R'){
            $updateArr['RVTN_UARE'] = $idUser;
            $updateArr['RVTN_FARE'] = $nowStr;
        }

        if($form['status'] == 'F'){
            $updateArr['RVTN_USFI'] = $idUser;
            $updateArr['RVTN_FEFI'] = $nowStr;
        }

        if($form['status'] == 'C'){
            $updateArr['RVTN_USCA'] = $idUser;
            $updateArr['RVTN_FECA'] = $nowStr;
        }

        DB::table('S002V01TRVTN')->where([
            ['RVTN_NULI', '=', $form['linea']],
            ['RVTN_IDVI', '=', $idVisit],          
        ])->update($updateArr);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F11RVTP',
            'S002V01P01REVI',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó la visita no programada #$idVisit.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function updateOrderStatus(Request $request){
        DB::enableQueryLog();

        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string',
            'status' => 'required|string|in:B,R,A,E'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $idOrder],
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }

        if($form['status'] == 'A' && $order->OTPR_SEAN == null){
            return $this->responseController->makeResponse(true, 'La orden no puede ser aprobada sin la asignación del análisis presupuestario.', [], 401);
        }

        $statusStr = '';
        switch($form['status']){
            case 'B': $statusStr = 'Borrador'; break;
            case 'R': $statusStr = 'Revisión'; break;
            case 'A': $statusStr = 'Aprobado'; break;
            case 'E': $statusStr = 'Eliminado'; break;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $idOrder],
        ])->update([
            'OTPR_ESTA' => $form['status'],
            'OTPR_USMO' => $idUser,
            'OTPR_FEMO' => $nowStr
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P01HOTP',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó el estado de la orden #$idOrder a $statusStr.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function setBudgetAnalysis(Request $request){
        DB::enableQueryLog();

        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string',
            'analysis' => 'required|json'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $idOrder]
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden consultada no está registrada.', [], 404);
        }

        $analysisArr = json_decode($form['analysis'], true);
        if(empty($analysisArr)){
            return $this->responseController->makeResponse(true, 'El JSON de análisis no contiene información.', [], 400);
        }else if(!array_key_exists('teamsConf', $analysisArr)){
            return $this->responseController->makeResponse(true, 'La información de la configuración de los equipos no se envió en el JSON.', [], 400);
        }else if(!is_array($analysisArr['teamsConf'])){
            return $this->responseController->makeResponse(true, 'La configuración de los equipos tiene un formato inválido.', [], 400);
        }

        $teamsConf = $analysisArr['teamsConf'];
        $contracts = [];
        foreach($teamsConf as $team=>$conf){
            //Verificar la existencia de los equipos
            foreach($conf as $user){
                $usrEx = DB::table('S002V01TUSUA')->where([
                    ['USUA_NULI', '=', $form['linea']],
                    ['USUA_IDUS', '=', $user['USER']],
                ])->first();

                if(is_null($usrEx)){
                    return $this->responseController->makeResponse(true, "El usuario $user[USER] no existe.", [], 404);
                }

                //verificar si se necesita la referencia del contrato del usuario
            }
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $contractsStr = json_encode($contracts);
        DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $idOrder],
        ])->update([
            'OTPR_SEAN' => $form['analysis'],
            'OTPR_RECO' => $contractsStr,
            'OTPR_USMO' => $idUser,
            'OTPR_FEMO' => $nowStr
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F01COTP',
            'S002V01P01HOTP',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") asignó el análisis presupuestario de la orden #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function getMaintenanceSimulation($idOrder, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->shortDec($idOrder);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->select([
            'OTPR_IDOT AS IDORDER',
            'OTPR_DEIN AS DESCRIPCION',
            'OTPR_ININ AS INSTRUCCIONES',
            'OTPR_EQIN AS EQUIPAMIENTO',
            'OTPR_FIAP AS FECHAINICIO',
            'OTPR_FTAP AS FECHAFINAL',
            'OTPR_SEAN AS ANALISIS',
            'OTPR_TIIN AS TIEINMEST',
            'OTPR_EQIT AS PERSONAL',
            'OTPR_OPPR AS OPERARIOS',
            'OTPR_DTIN AS TIETOTEST',
            'OTPR_RHRE AS RECURSOS',
            'OTPR_ACAS AS ACTIVADOR',
            'OTPR_ESTA AS ESTADO',
            'ACTI_PRIO AS PRIORIDAD',
            'ACTI_TIAC AS TIPOACTIVADOR',
            'ACTI_COAC AS CONFIGACTI'
        ])->join('S002V01TACTI', 'ACTI_IDCO', '=', 'OTPR_ACAS')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_IDOT', '=', $idOrder]
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }else if($order->ESTADO == 'B'){
            return $this->responseController->makeResponse(true, 'La orden solicitada no puede ejecutarse porque se encuentra en borradores.', [], 401);
        }else if($order->ESTADO == 'R'){
            return $this->responseController->makeResponse(true, 'La orden solicitada no puede ejecutarse porque se encuentra en revisión.', [], 401);
        }else if($order->ESTADO == 'E'){
            return $this->responseController->makeResponse(true, 'La orden solicitada no puede ejecutarse porque ha sido eliminado.', [], 401);
        }

        $analisisArr = json_decode($order->ANALISIS, true);
        $teamsConf = $analisisArr['teamsConf'];
        foreach($teamsConf as $k0=>$v0){
            foreach($v0 as $k1=>$v1){
                $usrID = $v1['USER'];
                $usrObj = DB::table('S002V01TUSUA')->where([
                    ['USUA_NULI', '=', $line],
                    ['USUA_IDUS', '=', $usrID],
                ])->first();

                $usrAnaName = $this->functionsController->joinName($usrObj->USUA_NOMB, $usrObj->USUA_APPA, $usrObj->USUA_APMA) . " ($usrID)";
                $v1['USER'] = $usrAnaName;
                $v0[$k1] = $v1;
            }
            $teamsConf[$k0] = $v0;
        }

        $analisisArr['teamsConf'] = $teamsConf;
        $order->ANALISIS = json_encode($analisisArr);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F06SPMA',
            'S002V01P02VSPM',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó la simulación de la orden #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $order);
    }

    public function getOrderWithActivator($idOrder, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->shortDec($idOrder);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->select([
            'OTPR_IDOT AS IDORDEN',
            'OTPR_DEIN AS DESCRIPCION',
            'OTPR_ININ AS INSTRUCCIONES',
            'OTPR_EQIN AS EQUIPAMIENTO',
            'OTPR_FIAP AS FECHAINICIO',
            'OTPR_FTAP AS FECHAFINAL',
            'OTPR_TIIN AS TIEINMEST',
            'OTPR_DTIN AS TIETOTEST',
            'OTPR_ACAS AS ACTIVADOR',
            'OTPR_CLAS AS CLASIFICACION',
            'OTPR_ESTA AS ESTADO',
            'ACTI_PRIO AS PRIORIDAD',
            'ACTI_TIAC AS TIPOACTIVADOR',
            'ACTI_COAC AS CONFIGACTIVADOR',
        ])->join('S002V01TACTI', 'ACTI_IDCO', '=', 'OTPR_ACAS')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_IDOT', '=', $idOrder],
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no está registrada.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F02AFDT',
            'S002V01P01OTAT',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó la información de la orden #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $order);
    }

    public function updateOrderWithActivator(Request $request){
        DB::enableQueryLog();

        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string',
            'id_activator' => 'required|string',
            'start_date' => 'required|date',
            'end_date' => 'required|date',
            'activator_type' => 'required|string|in:Calendario,Sintoma,Medida,Valor',
            'priority' => 'required|string|in:1,2,3,4',
            'config_activator' => 'required|json',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_IDUS', '=', $idUser],
            ['USUA_NULI', '=', $form['linea']],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $idOrder],
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden de trabajo solicitada no existe.', [], 404);
        }

        $idActivator = $this->encryptionController->decrypt($form['id_activator']);
        if(!$idActivator){
            return $this->responseController->makeResponse(true, 'El ID del activador solicitado no está encriptado correctamente.', [], 400);
        }

        $activator = DB::table('S002V01TACTI')->where([
            ['ACTI_IDCO', '=', $idActivator],
            ['ACTI_NULI', '=', $form['linea']]
        ])->first();

        if(is_null($activator)){
            return $this->responseController->makeResponse(true, 'El activador solicitado no existe.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $idOrder],
        ])->update([
            'OTPR_ACAS' => $idActivator,
            'OTPR_FIAP' => $form['start_date'],
            'OTPR_FTAP' => $form['end_date'],
            'OTPR_USMO' => $idUser,
            'OTPR_FEMO' => $nowStr,
        ]);

        DB::table('S002V01TACTI')->where([
            ['ACTI_IDCO', '=', $idActivator],
            ['ACTI_NULI', '=', $form['linea']]
        ])->update([
            'ACTI_PRIO' => $form['priority'],
            'ACTI_TIAC' => $form['activator_type'],
            'ACTI_COAC' => $form['config_activator'],
            'ACTI_USMO' => $idUser,
            'ACTI_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F02AFDT',
            'S002V01P02ACAC',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó la orden #$idOrder y el activador #$idActivator.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function printOrderSimulation($idOrder, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->shortDec($idOrder);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_IDOT', '=', $idOrder]
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no está registrada.', [], 404);
        }

        $simulation = DB::table('S002V01TRESI')->where([
            ['RESI_NULI', '=', $line],
            ['RESI_IDOT', '=', $idOrder]
        ])->first();

        if(is_null($simulation)){
            return $this->responseController->makeResponse(true, "La orden #$idOrder aún no ha sido simulada.", [], 401);
        }

        $content = json_decode($simulation->RESI_CUSI, true);
        $html = "
        <html>
            <head>
                <link href=\"https://fonts.googleapis.com/icon?family=Material+Icons\" rel=\"stylesheet\">
                <style>
                    .main-icon-cell{
                        width: 50px;
                        height: 50px;
                    }
                    .main-icon-container{
                        width: 50px;
                        height: 50px;
                        border-radius: 64px;
                        border-style: solid;
                        padding-left: 8px;
                        padding-top: 8px;
                        border-color: rgba(0, 0, 0, 0.8);
                    }
                    .icon-container{
                        padding-left: 8px;
                        width: 42px;
                        height: 42px;
                    }
                    .instruction-font{
                        color: rgba(0, 0, 0, 0.8);
                        font-size: 24px;
                        padding-left: 8px;
                        font-weight: 600;
                    }
                    .space-cell{
                        width: 50px;
                    }
                </style>
            </head>
            <body>
                <table width=\"100%\">  
        ";

        foreach($content as $item){
            $imgContent = file_get_contents("C:\inetpub\wwwroot\sam\storage\app\\files\\$item[icon].png");
            $imgB64 = "data:image/png;base64, " . base64_encode($imgContent);
            
            $html .= "
            <tr>
            "; 

            if(!$item['isMain']){
                $html .= '<td class="space-cell"></td>';
            }

            $html .= "
            <td class=\"main-icon-cell\">
            <div class=\"
            "; 
            
            if($item['isMain']){
                $html .= 'main-icon-container">';
            }else{
                $html .= 'icon-container ">';
            }

            $html .= "
            <img src=\"$imgB64\" width=\"42\" height=\"42\">
            </div>
            </td>
            <td class=\"instruction-font\" colspan=\"
            ";

            if($item['isMain']){
                $html .= '2';
            }

            $html .= "
            \">$item[label]</td>
            </tr>
            "; 
        }

        $html .= "
                </table>
            </body>
        </html>";

        $filePath = 'C:\inetpub\wwwroot\sam\public_files\\';
        $noar = "simulacion_orden_$idOrder";
        $exte = "pdf";

        $line = intval($line);
        $line = $line < 10 ? "0$line" : "$line";
        $como = "GMPR";
        $cldo = "OR";

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $nowArr = explode(" ", $nowStr);
        $dateArr = explode("-", $nowArr[0]);

        $year = substr($dateArr[0], 2);
        $fecr = $year . $dateArr[1] .$dateArr[2];

        $sec = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $line],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
        ])->orderBy('AFAL_NUSE', 'desc')->first();

        $nuse = is_null($sec) ? "1" : "" . intval($sec->AFAL_NUSE) + 1 . "";
        for($i = strlen($nuse); $i < 6; $i++){
            $nuse = "0$nuse";
        }

        $ver = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $line],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
            ['AFAL_NOAR', '=', $noar],
            ['AFAL_EXTE', '=', $exte],
        ])->orderBy('AFAL_NUVE', 'desc')->first();

        $nuve = is_null($ver) ? "1" : "" . intval($ver->AFAL_NUVE) + 1 . "";
        for($i = strlen($nuve); $i < 2; $i++){
            $nuve = "0$nuve";
        }

        $fileName = "$line-$como-$cldo-$fecr-$nuse=$nuve=$noar.$exte";

        $dompdf = new Dompdf();
        $dompdf ->loadHtml($html);
        $dompdf->setPaper('A4', 'portrait');
        $dompdf->render();

        $output = $dompdf->output();
        
        $tempFile = $filePath . $fileName;
        if(!file_exists($tempFile)){
            fopen($tempFile, 'w');
        }

        file_put_contents($tempFile, $output);
        $ubic = Storage::putFile('files', new File($tempFile));
        $ubic = str_replace("/", "\\", $ubic);
        $ubic = "C:\inetpub\wwwroot\sam\storage\app\\" . $ubic;
        $tama = filesize($ubic);
        $usac = json_encode([$idUser]);
        unlink($tempFile);

        DB::table('S002V01TAFAL')->insert([
            'AFAL_NULI' => $line,
            'AFAL_COMO' => $como,
            'AFAL_CLDO' => $cldo,
            'AFAL_FECR' => $fecr,
            'AFAL_NUSE' => $nuse,
            'AFAL_NUVE' => $nuve,
            'AFAL_NOAR' => $noar,
            'AFAL_EXTE' => $exte,
            'AFAL_TAMA' => $tama,
            'AFAL_UBIC' => $ubic,
            'AFAL_USAC' => $usac,
            'AFAL_USRE' => $idUser,
            'AFAL_FERE' => $nowStr,
        ]);

        $filesArr = json_decode($order->OTPR_DONE, true);
        $filesArr[] = $fileName;
        $filesStr = json_encode($filesArr);

        DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_IDOT', '=', $idOrder]
        ])->update([
            'OTPR_DONE' => $filesStr,
            'OTPR_USMO' => $idUser,
            'OTPR_FEMO' => $nowStr
        ]);


        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F06SPMA',
            'S002V01P02VSPM',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") generó el archivo de simulación de la orden #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', ['fileID' => $fileName]);
    }

    public function saveOrderSimulation(Request $request){
        DB::enableQueryLog();

        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string',
            'content' => 'required|json',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $form['linea']],
            ['OTPR_IDOT', '=', $idOrder],
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden consultada no está registrada.', [], 404);
        }

        $simulation = DB::table('S002V01TRESI')->where([
            ['RESI_NULI', '=', $form['linea']],
            ['RESI_IDOT', '=', $idOrder],
        ])->first();

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        if(is_null($simulation)){
            DB::table('S002V01TRESI')->insert([
                'RESI_NULI' => $form['linea'],
                'RESI_IDOT' => $idOrder,
                'RESI_CUSI' => $form['content'],
                'RESI_FUSI' => $nowStr,
                'RESI_UUSI' => $idUser,
            ]);
        }else{
            $timestamp = $now->timestamp;
            $history = $simulation->RESI_HISI == null ? [] : json_decode($simulation->RESI_HISI, true);
            $history[$timestamp] = [
                'USUARIO' => $simulation->RESI_UUSI,
                'FECHA' => $simulation->RESI_FUSI,
                'CONTENIDO' => $simulation->RESI_CUSI,
            ];

            $historyStr = json_encode($history);
            DB::table('S002V01TRESI')->where([
                ['RESI_NULI', '=', $form['linea']],
                ['RESI_IDOT', '=', $idOrder],
            ])->update([
                'RESI_CUSI' => $form['content'],
                'RESI_FUSI' => $nowStr,
                'RESI_UUSI' => $idUser,
                'RESI_HISI' => $historyStr,
            ]);
        }

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M10GMPR',
            'S002V01F06SPMA',
            'S002V01P02VSPM',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró una simulación para la orden #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function printOrderDetails($idOrder, $idUser, $line){
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser]
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->shortDec($idOrder);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->join(
            'S002V01TACTI', 'OTPR_ACAS', '=', 'ACTI_IDCO',
        )->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_IDOT', '=', $idOrder]
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no está registrada.', [], 404);
        }

        $html = "
        <html>
            <head>
                <style>
                    table{
                        border-collapse: separate;
                        border-spacing: 0;
                        width: 100%;
                    }
                    .cell-title{
                        font-size: 12px;
                        font-weight: bold;
                        padding: 8px 8px 4px 8px;
                    }
                    .top-corners-radius{
                        border-radius: 4px 4px 0 0;
                    }
                    .left-bottom-corner-radius{
                        border-radius: 0 0 0 4px;
                    }
                    .right-bottom-corner-radius{
                        border-radius: 0 0 4px 0;
                    }
                    .cell-content{
                        padding: 4px 8px 8px 8px;
                        font-size: 16px;
                        color: rgba(0, 0, 0, 0.7);
                    }
                    .border-top{ border-top: 1px solid #dddddd; }
                    .border-left{ border-left: 1px solid #dddddd; }
                    .border-right{ border-right: 1px solid #dddddd; }
                    .border-bottom{ border-bottom: 1px solid #dddddd; }
                </style>
            </head>
            <body>
                <table>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title top-corners-radius border-top border-left border-right\">Descripción</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">" . $order->OTPR_DEIN . "</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title border-top border-left border-right\">Instrucciones</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">
        ";

        $instructions = json_decode($order->OTPR_ININ, true);
        $cont = 1;
        foreach($instructions as $instruction){
            $html .= $cont . ".- " . $instruction['INSTRUCCION'] . "<br>";
            $cont++;
        }

        $startDate = $this->functionsController->formatDateTime($order->OTPR_FIAP);
        $endDate = $this->functionsController->formatDateTime($order->OTPR_FTAP);
        $html .= "
                    </td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title border-top border-left border-right\">Equipamiento relacionado</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">" . $order->OTPR_EQIN . "</td></tr>
                    <tr>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-title border-top border-left border-right\">Fecha y hora de inicio</td>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-title border-top border-right\">Fecha y hora final</td>
                    </tr>
                    <tr>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-content border-left border-right\">$startDate</td>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-content border-right\">$endDate</td>
                    </tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title border-top border-left border-right\">Análisis presupuestario</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">
        ";

        $analisis = $order->OTPR_SEAN == null ? 'Sin configuración' : json_decode($order->OTPR_SEAN, true);
        if(gettype($analisis) == 'array'){
            //PENDIENTE
            $teamsConf = $analisis['teamsConf'];
            foreach($teamsConf as $key=>$team){
                /*var_dump($key);
                echo "<br>";*/
            }
            $html .= "
                        PENDIENTE
                    </td></tr>
            ";
        }else{
            $html .= "
                        $analisis
                    </td></tr>
            ";
        }

        $html .= "
                    <tr>
                        <td width=\"33%\" colspan=\"2\" class=\"cell-title border-top border-left border-right\">Clasificación</td>
                        <td width=\"34%\" colspan=\"2\" class=\"cell-title border-top border-right\">Duración total estimada</td>
                        <td width=\"33%\" colspan=\"2\" class=\"cell-title border-top border-right\">Tiempo de inmovilización estimado</td>
                    </tr>
                    <tr>
                        <td width=\"33%\" colspan=\"2\" class=\"cell-content border-left border-right\">" . $order->OTPR_CLAS . "</td>
                        <td width=\"34%\" colspan=\"2\" class=\"cell-content border-right\">" . $order->OTPR_DTIN . " hora(s)</td>
                        <td width=\"33%\" colspan=\"2\" class=\"cell-content border-right\">" . $order->OTPR_TIIN . " hora(s)</td>
                    </tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title border-top border-left border-right\">Personal involucrado</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">PENDIENTE</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title border-top border-left border-right\">Recursos requerido</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">PENDIENTE</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title border-top border-left border-right\">Documentos requeridos</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">PENDIENTE</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title border-top border-left border-right\">Contratos requeridos</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">PENDIENTE</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-title border-top border-left border-right\">Información del activador</td></tr>
                    <tr><td width=\"100%\" colspan=\"6\" class=\"cell-content border-left border-right\">PENDIENTE</td></tr>
                    <tr>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-title border-top border-left border-right\">Usuario que registró</td>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-title border-top border-right\">Fecha de registro</td>
                    </tr>
                    <tr>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-content border-left border-right\">PENDIENTE</td>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-content border-right\">PENDIENTE</td>
                    </tr>
                    <tr>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-title border-top border-left border-right\">Usuario de la última modificación</td>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-title border-top border-right\">Fecha de la última modificación</td>
                    </tr>
                    <tr>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-content border-left border-right border-bottom left-bottom-corner-radius\">PENDIENTE</td>
                        <td width=\"50%\" colspan=\"3\" class=\"cell-content border-right border-bottom right-bottom-corner-radius\">PENDIENTE</td>
                    </tr>
                </table>
            </body>
        </html>
        ";

        $filePath = 'C:\inetpub\wwwroot\sam\public_files\\';
        $noar = "detalles_orden_$idOrder";
        $exte = "pdf";

        $line = intval($line);
        $line = $line < 10 ? "0$line" : "$line";
        $como = "GMPR";
        $cldo = "OR";

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $nowArr = explode(" ", $nowStr);
        $dateArr = explode("-", $nowArr[0]);

        $year = substr($dateArr[0], 2);
        $fecr = $year . $dateArr[1] .$dateArr[2];

        $sec = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $line],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
        ])->orderBy('AFAL_NUSE', 'desc')->first();

        $nuse = is_null($sec) ? "1" : "" . intval($sec->AFAL_NUSE) + 1 . "";
        for($i = strlen($nuse); $i < 6; $i++){
            $nuse = "0$nuse";
        }

        $ver = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $line],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
            ['AFAL_NOAR', '=', $noar],
            ['AFAL_EXTE', '=', $exte],
        ])->orderBy('AFAL_NUVE', 'desc')->first();

        $nuve = is_null($ver) ? "1" : "" . intval($ver->AFAL_NUVE) + 1 . "";
        for($i = strlen($nuve); $i < 2; $i++){
            $nuve = "0$nuve";
        }

        $fileName = "$line-$como-$cldo-$fecr-$nuse=$nuve=$noar.$exte";

        $dompdf = new Dompdf();
        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4', 'portrait');
        $dompdf->render();

        $output = $dompdf->output();
        
        $tempFile = $filePath . $fileName;
        if(!file_exists($tempFile)){
            fopen($tempFile, 'w');
        }

        file_put_contents($tempFile, $output);
        $ubic = Storage::putFile('files', new File($tempFile));
        $ubic = str_replace("/", "\\", $ubic);
        $ubic = "C:\inetpub\wwwroot\sam\storage\app\\" . $ubic;
        $tama = filesize($ubic);
        $usac = json_encode([$idUser]);
        unlink($tempFile);

        DB::table('S002V01TAFAL')->insert([
            'AFAL_NULI' => $line,
            'AFAL_COMO' => $como,
            'AFAL_CLDO' => $cldo,
            'AFAL_FECR' => $fecr,
            'AFAL_NUSE' => $nuse,
            'AFAL_NUVE' => $nuve,
            'AFAL_NOAR' => $noar,
            'AFAL_EXTE' => $exte,
            'AFAL_TAMA' => $tama,
            'AFAL_UBIC' => $ubic,
            'AFAL_USAC' => $usac,
            'AFAL_USRE' => $idUser,
            'AFAL_FERE' => $nowStr,
        ]);

        $filesArr = json_decode($order->OTPR_DONE, true);
        $filesArr[] = $fileName;
        $filesStr = json_encode($filesArr);

        DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_IDOT', '=', $idOrder]
        ])->update([
            'OTPR_DONE' => $filesStr,
            'OTPR_USMO' => $idUser,
            'OTPR_FEMO' => $nowStr
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F06SPMA',
            'S002V01P02VSPM',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") generó el archivo de simulación de la orden #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', ['fileID' => $fileName]);
    }
    
    public function extractMaintenancePlan($idOrder, $idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }
        
        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->shortDec($idOrder);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->join(
            'S002V01TACTI', 'OTPR_ACAS', '=', 'ACTI_IDCO',
        )->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_IDOT', '=', $idOrder]
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no está registrada.', [], 404);
        }

        $html = file_get_contents($this->templatesUbic . "01-GMPR-PL-010101-000003=01=PDF_PLAN_MANTENIMIENTO.html");
        $logo = file_get_contents("C:\inetpub\wwwroot\sam\storage\app\public\global_resources\sam-short-logo.png");
        $logoStr = "data:image/svg+xml;base64," . base64_encode($logo);

        $html = str_replace("%stcImage%", $logoStr, $html);
        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $currentDate = $this->functionsController->buildHumanCurrentDate($nowStr);

        $html = str_replace("%currentDate%", $currentDate, $html);
        $html = str_replace("%idOrder%", $order->OTPR_IDOT, $html);
        
        $startDateTimeArr = explode(" ", $order->OTPR_FIAP);
        $startTimeArr = explode(":", $startDateTimeArr[1]);
        $startHour = intval($startTimeArr[0]);
        $startPeriod = $startHour < 12 ? 'AM' : 'PM';
        $startHour = $startHour > 12 ? $startHour - 12 : $startHour;
        $startTimeStr = "$startHour:$startTimeArr[1] $startPeriod";

        $html = str_replace("%startTime%", $startTimeStr, $html);
        $startDateTimeObj = new Carbon($order->OTPR_FIAP);
        $totalDuration = floatval($order->OTPR_DTIN);

        $totalDurationHours = intval($totalDuration);
        $startDateTimeObj->addHours($totalDuration);

        $totalDurationFloatMinutes = $this->functionsController->floatSub($totalDuration, $totalDurationHours);
        $totalDurationFloatMinutes = $this->functionsController->floatMul($totalDurationFloatMinutes, 60);
        $totalDurationMinutes = ceil($totalDurationFloatMinutes);
        $startDateTimeObj->addMinutes($totalDurationMinutes);

        $endDateTimeArr = explode(" ", $startDateTimeObj->toDateTimeString());
        $endTimeArr = explode(":", $endDateTimeArr[1]);
        $endHour = intval($endTimeArr[0]);
        $endPeriod = $startHour < 12 ? 'AM' : 'PM';
        $endHour = $endHour > 12 ? $endHour - 12 : $endHour;
        $endTimeStr = "$endHour:$endTimeArr[1] $endPeriod";

        $html = str_replace("%endTime%", $endTimeStr, $html);
        $html = str_replace("%inmTime%", $order->OTPR_TIIN . " h", $html);
        $html = str_replace("%totalTime%", $order->OTPR_DTIN . " h", $html);
        $html = str_replace("%equipment%", $order->OTPR_EQIN, $html);
        $html = str_replace("%description%", $order->OTPR_DEIN, $html);

        $instructions = json_decode($order->OTPR_ININ, true);
        $teams = json_decode($order->OTPR_EQIT, true);
        $activitiesTableBody = "";
        foreach($instructions as $k=>$v){
            $key = $k + 1;
            $activitiesTableBody .= "<tr>";
            $activitiesTableBody .= "<td>$key</td>";
            $activitiesTableBody .= "<td>$v[INSTRUCCION]</td>";
            $activitiesTableBody .= "<td>";

            foreach($v['ESPECIALIDADES'] as $v0){
                $team = array_filter($teams, function($v1) use ($v0) {
                    return ($v1['ID'] == $v0);
                });
                $activitiesTableBody .= end($team)['ESP'] . "<br>";
            }

            $activitiesTableBody .= "</td>";
            $activitiesTableBody .= "</tr>";
        }
        
        $html = str_replace("%activitiesTableBody%", $activitiesTableBody, $html);
        $personalArr = json_decode($order->OTPR_OPPR, true);
        $constConf = json_decode($order->OTPR_SEAN, true);
        $cont = 1;
        $specialtiesTableBody = "";
        foreach($personalArr as $k=>$v){
            $team = array_filter($teams, function($v1) use ($k) {
                return ($v1['ID'] == $k);
            });
            
            $specialtiesTableBody .= "<tr>";
            $specialtiesTableBody .= "<td>$cont</td>";
            $specialtiesTableBody .= "<td>" . end($team)['ESP'] . "</td>";
            $specialtiesTableBody .= "<td>";

            foreach($constConf['teamsConf'][$k] as $v0){
                $usrID = $v0['USER'];
                $usrInv = DB::table('S002V01TUSUA')->where([
                    ['USUA_NULI', '=', $line],
                    ['USUA_IDUS', '=', $usrID],
                ])->first();

                $invName = $this->functionsController->joinName($usrInv->USUA_NOMB, $usrInv->USUA_APPA, $usrInv->USUA_APMA) . " ($usrID)";
                $specialtiesTableBody .= $invName . "<br>";
            }

            $specialtiesTableBody .= "</td>";
            $specialtiesTableBody .= "</tr>";

            $cont++;
        }
        
        $html = str_replace("%specialtiesTableBody%", $specialtiesTableBody, $html);
        $como = 'GMPR';
        $cldo = 'OR';
        $noar = "plan_de_mantenimiento_preventivo_orden_$idOrder";
        $exte = "pdf";
        $line = $line < 10 ? "0$line" : "$line";

        $nowArr = explode(" ", $nowStr);
        $dateArr = explode("-", $nowArr[0]);
        $year = substr($dateArr[0], 2);
        $fecr = $year . $dateArr[1] .$dateArr[2];

        $sec = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $line],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
        ])->orderBy('AFAL_NUSE', 'desc')->first();

        $nuse = is_null($sec) ? "1" : "" . intval($sec->AFAL_NUSE) + 1 . "";
        for($i = strlen($nuse); $i < 6; $i++){
            $nuse = "0$nuse";
        }

        $ver = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $line],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
            ['AFAL_NOAR', '=', $noar],
            ['AFAL_EXTE', '=', $exte],
        ])->orderBy('AFAL_NUVE', 'desc')->first();

        $nuve = is_null($ver) ? "1" : "" . intval($ver->AFAL_NUVE) + 1 . "";
        for($i = strlen($nuve); $i < 2; $i++){
            $nuve = "0$nuve";
        }

        $filePath = 'C:\inetpub\wwwroot\sam\public_files\\';
        $fileName = "$line-$como-$cldo-$fecr-$nuse=$nuve=$noar.$exte";

        $dompdf = new Dompdf();
        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4', 'portrait');
        $dompdf->render();

        $output = $dompdf->output();
        
        $tempFile = $filePath . $fileName;
        if(!file_exists($tempFile)){
            fopen($tempFile, 'w');
        }

        file_put_contents($tempFile, $output);
        $ubic = Storage::putFile('files', new File($tempFile));
        $ubic = str_replace("/", "\\", $ubic);
        $ubic = "C:\inetpub\wwwroot\sam\storage\app\\" . $ubic;
        $tama = filesize($ubic);
        $usac = json_encode([$idUser]);
        unlink($tempFile);

        DB::table('S002V01TAFAL')->insert([
            'AFAL_NULI' => $line,
            'AFAL_COMO' => $como,
            'AFAL_CLDO' => $cldo,
            'AFAL_FECR' => $fecr,
            'AFAL_NUSE' => $nuse,
            'AFAL_NUVE' => $nuve,
            'AFAL_NOAR' => $noar,
            'AFAL_EXTE' => $exte,
            'AFAL_TAMA' => $tama,
            'AFAL_UBIC' => $ubic,
            'AFAL_USAC' => $usac,
            'AFAL_USRE' => $idUser,
            'AFAL_FERE' => $nowStr,
        ]);

        $filesArr = json_decode($order->OTPR_DONE, true);
        $filesArr[] = $fileName;
        $filesStr = json_encode($filesArr);

        DB::table('S002V01TOTPR')->where([
            ['OTPR_NULI', '=', $line],
            ['OTPR_IDOT', '=', $idOrder]
        ])->update([
            'OTPR_DONE' => $filesStr,
            'OTPR_USMO' => $idUser,
            'OTPR_FEMO' => $nowStr
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F07EPMA',
            'S002V01P02DPMA',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") generó el archivo de plan de mantenimiento de la orden #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', ['fileID' => $fileName]);
    }

    public function getMaintenancePlanAnalysis($idFile, $idUser, $line) {
        DB::enableQueryLog();
        
        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_IDUS', '=', $idUser],
            ['USUA_NULI', '=', $line]
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idFile = $this->encryptionController->shortDec($idFile);
        if(!$idFile){
            return $this->responseController->makeResponse(true, 'El ID del archivo solicitado no está encriptado correctamente.', [], 400);
        }

        $tempFile = DB::table('S002V01TARTE')->where([
            ['ARTE_NULI', '=', $line],
            ['ARTE_IDAR', '=', $idFile]
        ])->first();

        if(is_null($tempFile)){
            return $this->responseController->makeResponse(true, 'El archivo solicitado no está registrado.', [], 404);
        }

        $fileColumns = ['Id', 'Activo', 'Modo de tarea', 'Nombre', 'Duración', 'Comienzo', 'Fin', 'Trabajo_Programado', 'Costo', 'Duración de línea base estimada',
        'Comienzo previsto', 'Fin de línea base', 'Trabajo previsto', 'Costo de línea base', 'Variación de duración', 'Variación de trabajo', 'Variación de costo'];
        $MONTHS = ['enero' => '01', 'febrero' => '02', 'marzo' => '03', 'abril' => '04', 'mayo' => '05', 'junio' => '06', 'julio' => '07', 'agosto' => '08', 
        'septiembre' => '09', 'octubre' => '10', 'noviembre' => '11', 'diciembre' => '12'];

        $spreadsheet = IOFactory::load($tempFile->ARTE_UBTE);
        $workSheet = $spreadsheet->getActiveSheet();
        $maxColStr = $workSheet->getHighestColumn();
        $maxCol = Coordinate::columnIndexFromString($maxColStr);

        for($i = 1; $i <= $maxCol; $i++){
            $colStr = Coordinate::stringFromColumnIndex($i);
            $cell = $workSheet->getCell($colStr . "1");
            $val = $cell->getValue();

            if(!in_array($val, $fileColumns)){
                return $this->responseController->makeResponse(true, 'El archivo tiene un formato inválido.', [], 400);
            }
        }

        $instructions = [];
        $maxRow = $workSheet->getHighestRow();
        for($row = 2; $row <= $maxRow; $row++){
            $activo = $workSheet->getCell("B$row")->getValue();
            if($activo == 'Sí' || $activo == 'Si'){
                $durationStr = $workSheet->getCell("E$row")->getValue();
                $durationArr = explode(" ", $durationStr);
                $duration = 0;

                if($durationArr[1] == 'días' || $durationArr[1] == 'dias' || $durationArr[1] == 'día' || $durationArr[1] == 'dia'){
                    $daysFloat = floatval($durationArr[0]);
                    $daysInt = intval($daysFloat);
                    $duration += $daysInt * 24;

                    $hoursDec = $this->functionsController->floatSub($daysFloat, $daysInt);
                    $hoursFloat = $this->functionsController->floatMul($hoursDec, 24);
                    $duration = $this->functionsController->floatAdd($duration, $hoursFloat);
                }

                if($durationArr[1] == 'mins' || $durationArr[1] == 'min'){
                    $minsFloat = floatval($durationArr[0]);
                    $hoursFloat = $this->functionsController->floatDiv($minsFloat, 60);
                    $duration = $this->functionsController->floatAdd($duration, $hoursFloat);
                }

                $duration = round($duration, 5);

                $startDateStr = $workSheet->getCell("F$row")->getValue();
                $startDateArr = explode(" ", $startDateStr);
                $startMonth = $MONTHS[$startDateArr[1]];
                $startPeriod = $startDateArr[4] . $startDateArr[5];
                $startPeriod = str_replace('.', '', $startPeriod);
                $startHourArr = explode(":", $startDateArr[3]);
                $startHour = intval($startHourArr[0]);
                $startHour = $startPeriod == 'pm' && $startHour < 12 ? $startHour + 12 : $startHour;
                $startHourStr = $startHour < 10 ? "0$startHour" : "$startHour";
                $startDateTime = "$startDateArr[2]-$startMonth-$startDateArr[0] $startHourStr:$startHourArr[1]:00";
                $startDateTimeObj = new Carbon($startDateTime);
                $startTimestamp = $startDateTimeObj->timestamp;

                $endDateStr = $workSheet->getCell("G$row")->getValue();
                $endDateArr = explode(" ", $endDateStr);
                $endMonth = $MONTHS[$endDateArr[1]];
                $endPeriod = $endDateArr[4] . $endDateArr[5];
                $endPeriod = str_replace('.', '', $endPeriod);
                $endHourArr = explode(":", $endDateArr[3]);
                $endHour = intval($endHourArr[0]);
                $endHour = $endPeriod == 'pm' && $endHour < 12 ? $endHour + 12 : $endHour;
                $endHourStr = $endHour < 10 ? "0$endHour" : "$endHour";
                $endDateTime = "$endDateArr[2]-$endMonth-$endDateArr[0] $endHourStr:$endHourArr[1]:00";
                $endDateTimeObj = new Carbon($endDateTime);
                $endTimestamp = $endDateTimeObj->timestamp;

                $difference = $endTimestamp - $startTimestamp;
                $minutes = $this->functionsController->floatDiv($difference, 60);
                $hours = $this->functionsController->floatDiv($minutes, 60);
                $duration = round($hours, 5);

                $instructions[] = [
                    "INSTRUCTION" => $workSheet->getCell("D$row")->getValue(),
                    "DURATION" => $duration,
                    "START" => $startDateTime,
                    "END" => $endDateTime,
                    "COST" => $workSheet->getCell("I$row")->getValue(),
                ];
            }
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M10GMPR',
            'S002V01F10DIBI',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó el plan de mantenimiento para una nueva orden desde MS Project.",
            $idUser,
            $nowStr,
            'S002V01S02AOTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $instructions);
    }

    public function getFileToMSProject($idOrder, $idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->shortDec($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->shortDec($idOrder);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTPR')->where([
            ['OTPR_IDOT', '=', $idOrder],
            ['OTPR_NULI', '=', $line]
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden consultada no está registrada.', [], 404);
        }

        $cols = ['Id', 'Activo', 'Modo de tarea', 'Nombre', 'Duración', 'Comienzo', 'Fin', 'Trabajo_Programado', 'Costo', 'Duración de línea base estimada',
        'Comienzo previsto', 'Fin de línea base', 'Trabajo previsto', 'Costo de línea base', 'Variación de duración', 'Variación de trabajo', 'Variación de costo'];
        $analysis = json_decode($order->OTPR_SEAN, true);
        $instructionsConf = $analysis['instructionsConf'];
        $instructions = json_decode($order->OTPR_ININ, true);
        $arrCols = [];
        $cont = 1;

        foreach($instructions as $instruction){
            $projectDuration = "";
            if($instruction['DURACION'] < 24){
                $duration = $instruction['DURACION'] * 60;
                $projectDuration = "$duration min";

                if($duration > 1){
                    $projectDuration .= "s";
                }
            }else{
                $duration = $this->functionsController->floatDiv($instruction['DURACION'], 24);
                $duration = round($duration, 2);
                
                $projectDuration = "$duration día";
                if($duration > 1){
                    $projectDuration .= "s";
                }
            }

            $projectStartDate = $this->functionsController->buildProjectDate($instruction['INICIO']);
            $projectEndDate = $this->functionsController->buildProjectDate($instruction['FIN']);
            $cost = $instruction['ISFROMFILE'] ? $instruction['COSTO'] : $instructionsConf[$instruction['ID']];

            $arrCol = [
                "A" => $cont,
                "B" => 'Sí',
                "C" => 'Programada manualmente',
                "D" => $instruction['INSTRUCCION'],
                "E" => $projectDuration,
                "F" => $projectStartDate,
                "G" => $projectEndDate,
                "H" => "0h",
                "I" => $cost,
                "J" => "0d",
                "K" => "NOD",
                "L" => "NOD",
                "M" => "0h",
                "N" => "0",
                "O" => $projectDuration,
                "P" => "0h",
                "Q" => "0",
            ];

            $arrCols[] = $arrCol;
        }
        var_dump($arrCols);
    }
}