<?php

namespace App\Http\Controllers;

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

class EquipmentManagementController extends Controller{
    private $responseController;
    private $encryptionController;
    private $functionsController;
    private $templatesUbic;
    private $documentManagementController;
    
    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_05_GEEQ\\";
        $this->documentManagementController = new DocumentManagementController();
    }

    public function registerFamily(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'family_code' => 'required|string',
            'family_name' => 'required|string|max: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);
        }

        $familyCode = $this->encryptionController->decrypt($form['family_code']);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'El código de la familia no fue encriptado correctamente.', [], 400);
        }

        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode],
        ])->get()->all();

        if(count($family) > 0){
            return $this->responseController->makeResponse(true, 'El código de la familia ya se encuentra registrado.', [], 401);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TFAMI')->insert([
            'FAMI_NULI' => $form['linea'],
            'FAMI_COFA' => $familyCode,
            'FAMI_NOFA' => $form['family_name'],
            'FAMI_USRE' => $idUser,
            'FAMI_FERE' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F02DFSU',
            'S002V01P02REFA',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró la familia $form[family_name].",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $families = DB::table('S002V01TFAMI')->select([
            'FAMI_COFA AS CODIGOFAMILIA',
            'FAMI_NOFA AS NOMBREFAMILIA',
            'FAMI_ICON AS ICONO',
            'FAMI_ESTA AS ESTADO',
            'FAMI_USRE AS USRREG',
            'FAMI_FERE AS FECREG',
            'FAMI_USMO AS USRMOD',
            'FAMI_FEMO AS FECMOD'
        ])->where('FAMI_NULI', '=', $line)->get()->all();

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

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

            $subfamilies = DB::table('S002V01TSUBF')->where([
                ['SUBF_NULI', '=', $line],
                ['SUBF_COFA', '=', $val->CODIGOFAMILIA],
            ])->get()->all();
            
            $val->SUBFAMILIAS = count($subfamilies);
            $val->CODIGOFAMILIA = $this->encryptionController->encrypt($val->CODIGOFAMILIA);
            $families[$key] = $val;
        }

        $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,
            'S002V01M07GEEQ',
            'S002V01F02DFSU',
            'S002V01P01COFA',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las familias registradas.",
            $idUser,
            $nowStr,
        );

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

    public function updateFamily(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'family_code' => 'required|string',
            'family_name' => 'required|string|max: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);
        }

        $familyCode = $this->encryptionController->decrypt($form['family_code']);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'El código de la familia no fue encriptado correctamente.', [], 400);
        }

        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode],
        ])->first();
        
        if(is_null($family)){
            return $this->responseController->makeResponse(true, 'La familia que desea actualizar no existe.', [], 404);
        }else if($family->FAMI_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'La familia que desea actualizar está eliminada.', [], 404);
        }
        
        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode],
        ])->update([
            'FAMI_NOFA' => $form['family_name'],
            'FAMI_USMO' => $idUser,
            'FAMI_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F02DFSU',
            'S002V01P02REFA',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó la familia $familyCode.",
            $idUser,
            $nowStr,
        );

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

    public function deleteFamily(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'family_code' => '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);
        }

        $familyCode = $this->encryptionController->decrypt($form['family_code']);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'El código de la familia no fue encriptado correctamente.', [], 400);
        }

        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode],
        ])->first();
        
        if(is_null($family)){
            return $this->responseController->makeResponse(true, 'La familia que desea eliminar no existe.', [], 404);
        }else if($family->FAMI_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'La familia que desea eliminar está eliminada.', [], 404);
        }
        
        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode],
        ])->update([
            'FAMI_ESTA' => 'Eliminado',
            'FAMI_USMO' => $idUser,
            'FAMI_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F02DFSU',
            'S002V01P02REFA',
            'Eliminación',
            "El usuario $name (" . $usr->USUA_IDUS . ") eliminó la familia $familyCode.",
            $idUser,
            $nowStr,
        );

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

    public function registerSubfamily(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'family_code' => 'required|string',
            'subfamily_code' => 'required|string',
            'subfamily_name' => 'required|string|max: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);
        }

        $familyCode = $this->encryptionController->decrypt($form['family_code']);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'El código de la familia relacionada no fue encriptado correctamente.', [], 400);
        }

        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode],
        ])->first();
        
        if(is_null($family)){
            return $this->responseController->makeResponse(true, 'La familia relacionada no existe.', [], 404);
        }else if($family->FAMI_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'La familia relacionada está eliminada.', [], 404);
        }

        $subfamilyCode = $this->encryptionController->decrypt($form['subfamily_code']);
        if(!$subfamilyCode){
            return $this->responseController->makeResponse(true, 'El código de la subfamilia no fue encriptado correctamente.', [], 400);
        }

        $subfamily = DB::table('S002V01TSUBF')->where([
            ['SUBF_NULI', '=', $form['linea']],
            ['SUBF_COFA', '=', $familyCode],
            ['SUBF_COSU', '=', $subfamilyCode],
        ])->get()->all();

        if(count($subfamily) > 0){
            return $this->responseController->makeResponse(true, 'El código de la subfamilia ya se encuentra registrado.', [], 401);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TSUBF')->insert([
            'SUBF_NULI' => $form['linea'],
            'SUBF_COFA' => $familyCode,
            'SUBF_COSU' => $subfamilyCode,
            'SUBF_NOSU' => $form['subfamily_name'],
            'SUBF_USRE' => $idUser,
            'SUBF_FERE' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F02DFSU',
            'S002V01P04RESU',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró la subfamilia $form[subfamily_name].",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $familyCode = $this->encryptionController->decrypt($familyCode);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'El código de la familia relacionada no fue encriptado correctamente.', [], 400);
        }

        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $line],
            ['FAMI_COFA', '=', $familyCode],
        ])->first();
        
        if(is_null($family)){
            return $this->responseController->makeResponse(true, 'La familia relacionada no existe.', [], 404);
        }else if($family->FAMI_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'La familia relacionada está eliminada.', [], 404);
        }

        $subfamilies = DB::table('S002V01TSUBF')->select([
            'SUBF_COFA AS CODIGOFAMILIA',
            'SUBF_COSU AS CODIGOSUBFAMILIA',
            'SUBF_NOSU AS NOMBRESUBFAMILIA',
            'SUBF_ICON AS ICONO',
            'SUBF_ESTA AS ESTADO',
            'SUBF_USRE AS USRREG',
            'SUBF_FERE AS FECREG',
            'SUBF_USMO AS USRMOD',
            'SUBF_FEMO AS FECMOD'
        ])->where([
            ['SUBF_NULI', '=', $line],
            ['SUBF_COFA', '=', $familyCode],
        ])->get()->all();

        foreach($subfamilies as $key=>$val){
            $val->CODIGOFAMILIA = $this->encryptionController->encrypt($val->CODIGOFAMILIA);
            $val->CODIGOSUBFAMILIA = $this->encryptionController->encrypt($val->CODIGOSUBFAMILIA);

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

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

        $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,
            'S002V01M07GEEQ',
            'S002V01F02DFSU',
            'S002V01P03COSU',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las subfamilias relacionadas a la familia $familyCode.",
            $idUser,
            $nowStr,
        );

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

    public function updateSubfamily(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'family_code' => 'required|string',
            'subfamily_code' => 'required|string',
            'subfamily_name' => 'required|string|max: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);
        }

        $familyCode = $this->encryptionController->decrypt($form['family_code']);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'El código de la familia relacionada no fue encriptado correctamente.', [], 400);
        }

        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode],
        ])->first();
        
        if(is_null($family)){
            return $this->responseController->makeResponse(true, 'La familia relacionada no existe.', [], 404);
        }else if($family->FAMI_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'La familia relacionada está eliminada.', [], 404);
        }

        $subfamilyCode = $this->encryptionController->decrypt($form['subfamily_code']);
        if(!$subfamilyCode){
            return $this->responseController->makeResponse(true, 'El código de la subfamilia no fue encriptado correctamente.', [], 400);
        }

        $subfamily = DB::table('S002V01TSUBF')->where([
            ['SUBF_NULI', '=', $form['linea']],
            ['SUBF_COFA', '=', $familyCode],
            ['SUBF_COSU', '=', $subfamilyCode],
        ])->first();
        
        if(is_null($subfamily)){
            return $this->responseController->makeResponse(true, 'La subfamilia que desea actualizar no existe.', [], 404);
        }else if($subfamily->SUBF_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'La subfamilia que desea actualizar está eliminada.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TSUBF')->where([
            'SUBF_NULI' => $form['linea'],
            'SUBF_COFA' => $familyCode,
            'SUBF_COSU' => $subfamilyCode,
        ])->update([
            'SUBF_NOSU' => $form['subfamily_name'],
            'SUBF_USMO' => $idUser,
            'SUBF_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F02DFSU',
            'S002V01P04RESU',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó la subfamilia $subfamilyCode de la familia $familyCode.",
            $idUser,
            $nowStr,
        );

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

    public function deleteSubfamily(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'family_code' => 'required|string',
            'subfamily_code' => '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);
        }

        $familyCode = $this->encryptionController->decrypt($form['family_code']);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'El código de la familia relacionada no fue encriptado correctamente.', [], 400);
        }

        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode],
        ])->first();
        
        if(is_null($family)){
            return $this->responseController->makeResponse(true, 'La familia relacionada no existe.', [], 404);
        }else if($family->FAMI_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'La familia relacionada está eliminada.', [], 404);
        }

        $subfamilyCode = $this->encryptionController->decrypt($form['subfamily_code']);
        if(!$subfamilyCode){
            return $this->responseController->makeResponse(true, 'El código de la subfamilia no fue encriptado correctamente.', [], 400);
        }

        $subfamily = DB::table('S002V01TSUBF')->where([
            ['SUBF_NULI', '=', $form['linea']],
            ['SUBF_COFA', '=', $familyCode],
            ['SUBF_COSU', '=', $subfamilyCode],
        ])->first();
        
        if(is_null($subfamily)){
            return $this->responseController->makeResponse(true, 'La subfamilia que desea eliminar no existe.', [], 404);
        }else if($subfamily->SUBF_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'La subfamilia que desea eliminar está eliminada.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TSUBF')->where([
            'SUBF_NULI' => $form['linea'],
            'SUBF_COFA' => $familyCode,
            'SUBF_COSU' => $subfamilyCode,
        ])->update([
            'SUBF_ESTA' => 'Eliminado',
            'SUBF_USMO' => $idUser,
            'SUBF_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F02DFSU',
            'S002V01P04RESU',
            'Eliminación',
            "El usuario $name (" . $usr->USUA_IDUS . ") eliminó la subfamilia $subfamilyCode de la familia $familyCode.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $locationsEnc = file_get_contents($ubic . "locations.sam");
        $locationsDec = $this->encryptionController->decrypt($locationsEnc);
        $locationsArr = json_decode($locationsDec, true);

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó el arreglo de ubicaciones de la línea.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $occupationAreasEnc = file_get_contents($ubic . "occupation-areas.sam");
        $occupationAreasDec = $this->encryptionController->decrypt($occupationAreasEnc);
        $occupationAreasArr = json_decode($occupationAreasDec, true);

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las áreas de ocupación.",
            $idUser,
            $nowStr,
        );

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

    public function registerOccupation(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'area' => 'required|string',
            'description' => 'required|string|min:15|max:150',
        ]);
 
        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);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $occupationAreasEnc = file_get_contents($ubic . "occupation-areas.sam");
        $occupationAreasDec = $this->encryptionController->decrypt($occupationAreasEnc);
        $occupationAreasArr = json_decode($occupationAreasDec, true);
        $occupationAreasArrDec = [];

        foreach($occupationAreasArr as $area){
            $occupationAreasArrDec[] = [
                'CODE' => $this->encryptionController->decrypt($area['CODE']),
                'AREA' => $this->encryptionController->decrypt($area['AREA'])
            ];
        }

        $areaCode = $this->encryptionController->decrypt($form['area']);
        if(!$areaCode){
            return $this->responseController->makeResponse(true, 'El área de ocupación no fue encriptada correctamente.', [], 400);
        }

        $areaCodeExists = array_filter($occupationAreasArrDec, function($v, $k) use ($areaCode) {
            return $v['CODE'] == $areaCode;
        }, ARRAY_FILTER_USE_BOTH);
        
        if(count($areaCodeExists) < 1){
            return $this->responseController->makeResponse(true, 'El área de ocupación seleccionada no existe.', [], 400);
        }
        
        $areaName = end($areaCodeExists)['AREA'] . " ($areaCode)";
        $lastOccupationByArea = DB::table('S002V01TOCUP')->where([
            ['OCUP_NULI', '=', $form['linea']],
            ['OCUP_AREA', '=', $areaCode]
        ])->orderBy('OCUP_IDOC', 'desc')->first();

        $id = 0;
        if(is_null($lastOccupationByArea)){
            $id = 1;
        }else{
            $id = $lastOccupationByArea->OCUP_IDOC + 1;
        }

        if($id > 999){
            return $this->responseController->makeResponse(true, "El área $areaName llegó al límite de 999 elementos.", [], 401);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TOCUP')->insert([
            'OCUP_NULI' => $form['linea'],
            'OCUP_AREA' => $areaCode,
            'OCUP_IDOC' => $id,
            'OCUP_DESC' => $form['description'],
            'OCUP_USRE' => $idUser,
            'OCUP_FERE' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró una nueva ocupación para el área $areaName.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $occupationAreasEnc = file_get_contents($ubic . "occupation-areas.sam");
        $occupationAreasDec = $this->encryptionController->decrypt($occupationAreasEnc);
        $occupationAreasArr = json_decode($occupationAreasDec, true);
        $occupationAreasArrDec = [];

        foreach($occupationAreasArr as $area){
            $occupationAreasArrDec[] = [
                'CODE' => $this->encryptionController->decrypt($area['CODE']),
                'AREA' => $this->encryptionController->decrypt($area['AREA'])
            ];
        }

        $occupations = DB::table('S002V01TOCUP')->where('OCUP_NULI', '=', $line)->get()->all();
        $occupationsFn = [];
        foreach($occupations as $occupation){
            $areaInd = $occupation->OCUP_AREA;
            $areaStr = $areaInd < 10 ? "0$areaInd" : "$areaInd";
            $area = array_filter($occupationAreasArrDec, function($v, $k) use ($areaStr) {
                return $v['CODE'] == $areaStr;
            }, ARRAY_FILTER_USE_BOTH);
            $areaName = end($area)['AREA'] . " (" . end($area)['CODE'] . ")";

            $occupationInd = "" . $occupation->OCUP_IDOC . "";
            $occupationStr = "";
            for($i = strlen($occupationInd); $i < 3; $i++){
                $occupationStr .= '0';
            }

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

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

            $occupationStr = $areaStr . $occupationStr . $occupationInd;
            $occupationsFn[] = [
                "NOMBREAREA" => $areaName,
                "OCUPACION" => $occupationStr,
                "DESCRIPCION" => $occupation->OCUP_DESC,
                "ESTADO" => $occupation->OCUP_ESTA,
                "USRREG" => $usrRegName,
                "FECREG" => $occupation->OCUP_FERE,
                "USRMOD" => $usrModName,
                "FECMOD" => $occupation->OCUP_FEMO,
            ];
        }

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las ocupaciones registradas.",
            $idUser,
            $nowStr,
        );

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

    public function updateOccupation(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'area' => 'required|string',
            'occupation' => 'required|string',
            'description' => 'required|string|min:15|max:150',
        ]);
 
        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);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $occupationAreasEnc = file_get_contents($ubic . "occupation-areas.sam");
        $occupationAreasDec = $this->encryptionController->decrypt($occupationAreasEnc);
        $occupationAreasArr = json_decode($occupationAreasDec, true);
        $occupationAreasArrDec = [];

        foreach($occupationAreasArr as $area){
            $occupationAreasArrDec[] = [
                'CODE' => $this->encryptionController->decrypt($area['CODE']),
                'AREA' => $this->encryptionController->decrypt($area['AREA'])
            ];
        }

        $areaCode = $this->encryptionController->decrypt($form['area']);
        if(!$areaCode){
            return $this->responseController->makeResponse(true, 'El área de ocupación no fue encriptada correctamente.', [], 400);
        }

        $areaCodeExists = array_filter($occupationAreasArrDec, function($v, $k) use ($areaCode) {
            return $v['CODE'] == $areaCode;
        }, ARRAY_FILTER_USE_BOTH);
        
        if(count($areaCodeExists) < 1){
            return $this->responseController->makeResponse(true, 'El área de ocupación relacionada no existe.', [], 400);
        }

        $occupation = $this->encryptionController->decrypt($form['occupation']);
        if(!$occupation){
            return $this->responseController->makeResponse(true, 'La ocupación no fue encriptada correctamente.', [], 400);
        }

        $occupationID = substr($occupation, 2);
        $occupationObj = DB::table('S002V01TOCUP')->where([
            ['OCUP_NULI', '=', $form['linea']],
            ['OCUP_AREA', '=', $areaCode],
            ['OCUP_IDOC', '=', $occupationID],
        ])->first();
        
        if(is_null($occupationObj)){
            return $this->responseController->makeResponse(true, 'La ocupación que desea actualizar no existe.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TOCUP')->where([
            ['OCUP_NULI', '=', $form['linea']],
            ['OCUP_AREA', '=', $areaCode],
            ['OCUP_IDOC', '=', $occupationID],
        ])->update([
            'OCUP_DESC' => $form['description'],
            'OCUP_USMO' => $idUser,
            'OCUP_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó la ocupación $occupation.",
            $idUser,
            $nowStr,
        );

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

    public function deleteOccupation(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'area' => 'required|string',
            'occupation' => '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);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $occupationAreasEnc = file_get_contents($ubic . "occupation-areas.sam");
        $occupationAreasDec = $this->encryptionController->decrypt($occupationAreasEnc);
        $occupationAreasArr = json_decode($occupationAreasDec, true);
        $occupationAreasArrDec = [];

        foreach($occupationAreasArr as $area){
            $occupationAreasArrDec[] = [
                'CODE' => $this->encryptionController->decrypt($area['CODE']),
                'AREA' => $this->encryptionController->decrypt($area['AREA'])
            ];
        }

        $areaCode = $this->encryptionController->decrypt($form['area']);
        if(!$areaCode){
            return $this->responseController->makeResponse(true, 'El área de ocupación no fue encriptada correctamente.', [], 400);
        }

        $areaCodeExists = array_filter($occupationAreasArrDec, function($v, $k) use ($areaCode) {
            return $v['CODE'] == $areaCode;
        }, ARRAY_FILTER_USE_BOTH);
        
        if(count($areaCodeExists) < 1){
            return $this->responseController->makeResponse(true, 'El área de ocupación relacionada no existe.', [], 400);
        }

        $occupation = $this->encryptionController->decrypt($form['occupation']);
        if(!$occupation){
            return $this->responseController->makeResponse(true, 'La ocupación no fue encriptada correctamente.', [], 400);
        }

        $occupationID = substr($occupation, 2);
        $occupationObj = DB::table('S002V01TOCUP')->where([
            ['OCUP_NULI', '=', $form['linea']],
            ['OCUP_AREA', '=', $areaCode],
            ['OCUP_IDOC', '=', $occupationID],
        ])->first();
        
        if(is_null($occupationObj)){
            return $this->responseController->makeResponse(true, 'La ocupación que desea eliminar no existe.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TOCUP')->where([
            ['OCUP_NULI', '=', $form['linea']],
            ['OCUP_AREA', '=', $areaCode],
            ['OCUP_IDOC', '=', $occupationID],
        ])->update([
            'OCUP_ESTA' => 'Eliminado',
            'OCUP_USMO' => $idUser,
            'OCUP_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Eliminación',
            "El usuario $name (" . $usr->USUA_IDUS . ") eliminó la ocupación $occupation.",
            $idUser,
            $nowStr,
        );

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

    public function saveEquipmentPreCodified(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'hierarchy' => 'required|string|in:Padre,Hijo',
            'parent_equipment' => 'required_if:hierarchy,=,Hijo|string',
            'code_type' => 'required|integer|between:1,7',
            'origin_location'   => 'required_unless:code_type,7|string|nullable',
            'origin_level'      => 'required_unless:code_type,7|string|nullable',
            'origin_occupation' => 'required_unless:code_type,7|string|nullable',
            'origin_element'    => 'required_unless:code_type,7|string|max:150|nullable',
            'family' => 'required|string',
            'subfamily' => 'required|string',
            'status' => 'required|string',
            'equipment_type' => 'required|string|max:150',
            'equipment_model' => 'required|string|max:75',
            'images' => 'required|json',
            'documents' => 'required|json',
            'acquisition_date' => 'required|date',
            'warranty_start_date' => 'required|date',
            'warranty_end_date' => 'required|date',
            'equipment_provider' => 'required|string',
            'serial_number' => 'nullable|string',
            'has_software' => 'required|string|in:Si,No',
            'software_name' => 'required_if:has_software,=,Si|string|max:150',
            'software_version' => 'required_if:has_software,=,Si|string|max:75',
            'pre_generated_code' => 'required|string',
            'pcc_intersection' => 'required_if:code_type,=,2|string|max:5',
            'pcc_position' => 'required_if:code_type,=,2|string|max:2',
            'origin_kilometer' => 'required_if:code_type,=,3|numeric',
            'destiny_location' => 'required_if:code_type,=,3|string',
            'destiny_level' => 'required_if:code_type,=,3|string',
            'destiny_occupation' => 'required_if:code_type,=,3|string',
            'destiny_element' => 'required_if:code_type,=,3|string|max:150',
            'destiny_kilometer' => 'required_if:code_type,=,3|string',
            'warehouse' => 'required_if:code_type,=,7|string',
            'area' => 'required_if:code_type,=,7|string',
            'level' => 'required_if:code_type,=,7|string',
            'zone' => 'required_if:code_type,=,7|string',
            'number_items' => 'required|integer',
        ]);
 
        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);
        }

        $eqpa = null;
        if($form['hierarchy'] == 'Hijo'){
            $eqpa = $this->encryptionController->decrypt($form['parent_equipment']);
            if(!$eqpa){
                return $this->responseController->makeResponse(true, 'El ID del equipamiento padre no fue encriptado correctamente.', [], 400);
            }

            $parentEquipment = DB::table('S002V01TEQUI')->where([
                ['EQUI_NULI', '=', $form['linea']],
                ['EQUI_COEQ', '=', $eqpa],
            ])->first();
            
            if(is_null($parentEquipment)){
                return $this->responseController->makeResponse(true, 'El equipamiento padre no existe.', [], 404);
            }
        }
        
        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $locationsEnc = file_get_contents($ubic . "locations.sam");
        $locationsDec = $this->encryptionController->decrypt($locationsEnc);
        $locationsArr = json_decode($locationsDec, true);
        $locationsArrDec = [];
        foreach($locationsArr as $location){
            $locationStr = $this->encryptionController->decrypt($location['LOCATION']);
            $code = $this->encryptionController->decrypt($location['CODE']);

            $locationsArrDec[] = [
                'LOCATION' => $locationStr,
                'CODE' => $code
            ];
        }

        $originLocation = null;
        $originLevel = null;
        $originOccupationStr = null;


        $idWarehouse = null;
        $idArea = null;
        $idLevel = null;
        $idZone = null;

        if ($form['code_type'] !== '7') {
            // Se desencripta la ubicación de origen
            $originLocation = $this->encryptionController->decrypt($form['origin_location']);
            if(!$originLocation){
                return $this->responseController->makeResponse(true, 'La ubicación de origen no fue encriptada correctamente.', [], 400);
            }
            // Se verifica con la información del sistema
            $originLocationFilt = array_filter($locationsArrDec, function($v, $k) use ($originLocation) {
                return $v['CODE'] == $originLocation;
            }, ARRAY_FILTER_USE_BOTH);
            // Se verifica que la ubicacion exista en la información del sistema
            if(count($originLocationFilt) < 1){
                return $this->responseController->makeResponse(true, 'La ubicación de origen no se encuentra registrada en el sistema.', [], 404);
            }

            // Se desencripta el nivel del origen
            $originLevel = $this->encryptionController->decrypt($form['origin_level']);
            if(!$originLevel){
                return $this->responseController->makeResponse(true, 'El nivel de origen no fue encriptado correctamente.', [], 400);
            }
            // Se obtienen los niveles disponibles
            $supportedLevels = [];
            for($i = 5; $i > 0; $i--){
                $supportedLevels[] = "S0$i";
            }

            for($i = 0; $i <= 15; $i++){
                $tag = $i < 10 ? "P0$i" : "P$i";
                $supportedLevels[] = $tag;
            }
            // Se verifica que el origen sea válido
            if(!in_array($originLevel, $supportedLevels)){
                return $this->responseController->makeResponse(true, 'El nivel de origen seleccionado es inválido.', [], 400);
            }

            // Se desencripta la ocupación de orden
            $originOccupationStr = $this->encryptionController->decrypt($form['origin_occupation']);
            if(!$originOccupationStr){
                return $this->responseController->makeResponse(true, 'La ocupación de origen no fue encriptada correctamente.', [], 400);
            }
            // Se obtiene la información de la ocupación
            $originOccupationArea = substr($originOccupationStr, 0, 2);
            $originOccupationID = substr($originOccupationStr, 2);
            $originOccupation = DB::table('S002V01TOCUP')->where([
                ['OCUP_NULI', '=', $form['linea']],
                ['OCUP_AREA', '=', $originOccupationArea],
                ['OCUP_IDOC', '=', $originOccupationID]
            ])->first();
            // Se verifica que exista la ocupació
            if(is_null($originOccupation)){
                return $this->responseController->makeResponse(true, 'La ocupación de origen seleccionada no existe.', [], 404);
            }
        } else {

            $form['origin_element'] = null;

            $idWarehouse = $this->encryptionController->decrypt($form['warehouse']);
            if ($idWarehouse === false) {
                return $this->responseController->makeResponse(true, 'El almacen no está encriptado correctamente.', [], 404);
            }
            $idArea = $this->encryptionController->decrypt($form['area']);
            if ($idArea === false) {
                return $this->responseController->makeResponse(true, 'El área no está encriptado correctamente.', [], 404);
            }
            $idLevel = $this->encryptionController->decrypt($form['level']);
            if ($idLevel === false) {
                return $this->responseController->makeResponse(true, 'El nivel no está encriptado correctamente.', [], 404);
            }
            $idZone = $this->encryptionController->decrypt($form['zone']);
            if ($idZone === false) {
                return $this->responseController->makeResponse(true, 'La zona no está encriptado correctamente.', [], 404);
            }

            try {
                $validateWarehouse = DB::table('S002V01TALMA')
                    ->where('ALMA_COAL', '=', $idWarehouse)
                    ->where('ALMA_NULI', '=', $form['linea'])
                    ->exists();
            } catch (\Throwable $th) {
                return $this->responseController->makeResponse(true, 'Ocurrió un error al validar el almacen.', [], 500);
            }
            if (!$validateWarehouse) {
                return $this->responseController->makeResponse(true, 'El almacen no existe.', [], 500);
            }
           
            try {
                $validateArea = DB::table('S002V01TAREA')
                    ->where('AREA_COAL', '=', $idWarehouse)
                    ->where('AREA_COAR', '=', $idArea)
                    ->where('AREA_NULI', '=', $form['linea'])
                    ->exists();
            } catch (\Throwable $th) {
                return $this->responseController->makeResponse(true, 'Ocurrió un error al validar el almacen.', [], 500);
            }
            if (!$validateArea) {
                return $this->responseController->makeResponse(true, 'El almacen no existe.', [], 500);
            }

            try {
                $validateLevel = DB::table('S002V01TNIVE')
                    ->where('NIVE_COAL', '=', $idWarehouse)
                    ->where('NIVE_COAR', '=', $idArea)
                    ->where('NIVE_CONI', '=', $idLevel)
                    ->where('NIVE_NULI', '=', $form['linea'])
                    ->exists();
            } catch (\Throwable $th) {
                return $this->responseController->makeResponse(true, 'Ocurrió un error al validar el almacen.', [], 500);
            }
            if (!$validateLevel) {
                return $this->responseController->makeResponse(true, 'El almacen no existe.', [], 500);
            }

            try {
                $validateZone = DB::table('S002V01TZONA')
                    ->where('ZONA_COAL', '=', $idWarehouse)
                    ->where('ZONA_COAR', '=', $idArea)
                    ->where('ZONA_CONI', '=', $idLevel)
                    ->where('ZONA_COZO', '=', $idZone)
                    ->where('ZONA_NULI', '=', $form['linea'])
                    ->exists();
            } catch (\Throwable $th) {
                return $this->responseController->makeResponse(true, 'Ocurrió un error al validar el almacen.', [], 500);
            }
            if (!$validateZone) {
                return $this->responseController->makeResponse(true, 'El almacen no existe.', [], 500);
            }
        }

        // Se desencripta la familia 
        $familyCode = $this->encryptionController->decrypt($form['family']);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'La familia del equipamiento no fue encriptada correctamente.', [], 400);
        }
        // Se obtienen los datos de la familia
        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $form['linea']],
            ['FAMI_COFA', '=', $familyCode]
        ])->first();

        // Se verifica que la familia exista
        if(is_null($family)){
            return $this->responseController->makeResponse(true, 'La familia seleccionada no existe.', [], 404);
        }

        // Se desencripta la subfamilia
        $subfamilyCode = $this->encryptionController->decrypt($form['subfamily']);
        if(!$subfamilyCode){
            return $this->responseController->makeResponse(true, 'La subfamilia del equipamiento no fue encriptada correctamente.', [], 400);
        }

        // Se obtienen los datos de la subfamilia
        $subfamily = DB::table('S002V01TSUBF')->where([
            ['SUBF_NULI', '=', $form['linea']],
            ['SUBF_COFA', '=', $familyCode],
            ['SUBF_COSU', '=', $subfamilyCode]
        ])->first();

        // Se verifica que la subfamilia exista
        if(is_null($subfamily)){
            return $this->responseController->makeResponse(true, 'La subfamilia seleccionada no existe.', [], 404);
        }

        // Se inicializa arreglo con los estados disponibles
        $validStatus = ["A", "S", "T", "I", "R", "D"];
        // Se desencripta el estado
        $status = $this->encryptionController->decrypt($form['status']);
        // Se verifica que el estado sea un valor válido
        if(!$status){
            return $this->responseController->makeResponse(true, 'La estado del equipamiento no fue encriptado correctamente.', [], 400);
        }else if(!in_array($status, $validStatus)){
            return $this->responseController->makeResponse(true, 'El estado seleccionado para el equipamiento es inválido.', [], 400);
        }

        // Se obtiene el arreglo de las imagenes
        $imagesArr = json_decode($form['images'], true);
        // Se verifica que el arreglo contenga imagenes
        if(count($imagesArr) < 1){
            return $this->responseController->makeResponse(true, 'El arreglo de la galería de imágenes está vacío.', [], 400);
        }

        $imagesGallery = [];
        // Se iteran las imagenes
        foreach($imagesArr as $imageFile){
            // Se verifica que tenga un formato correcto
            if(!array_key_exists('type', $imageFile)){
                return $this->responseController->makeResponse(true, 'El arreglo de la galería de imágenes tiene un formato inválido.', [], 400);
            // Si la imagen es nueva, entonces...
            }else if($imageFile['type'] == 'Nuevo'){
                // Se obtiene el ID de la imagen
                $tempFileID = $this->encryptionController->decrypt($imageFile['id']);
                // Se obtiene la información registrada en la tabla de archivos temporales
                $tempFile = DB::table('S002V01TARTE')->where([
                    ['ARTE_IDAR', '=', $tempFileID],
                    ['ARTE_NULI', '=', $form['linea']]
                ])->first();
                // La imagen es colocada en su posición final
                $finalFile = $this->documentManagementController->moveFinalFile($form['linea'], 'GEEQ', 'FO', $tempFile, $idUser);
                // Si ocurrió un error, entonces se manda el error
                if(!$finalFile[0]){
                    return $this->responseController->makeResponse(true, $finalFile[1], [], 400);
                }
                // La información es guardada en un arreglo
                $imagesGallery[] = $finalFile[1];
            }else{
                // Se desencripta el id de la imagen
                $fileID = $this->encryptionController->decrypt($imageFile['id']);
                // Es guardada en un arreglo
                $imagesGallery[] = $fileID;
            }
        }

        // El arreglo de las imagenes es pasada en formato string
        $imagesGalleryStr = json_encode($imagesGallery);
        // Se obtiene el arreglo de los documentos
        $documentsArr = json_decode($form['documents'], true);
        if(count($documentsArr) < 1){
            return $this->responseController->makeResponse(true, 'El arreglo de documentos relacionados está vacío.', [], 400);
        }

        $documents = [];
        // Se iteran los documentos
        foreach($documentsArr as $documentFile){
            // Se verifica que tenga un formato correcto
            if(!array_key_exists('type', $documentFile)){
                return $this->responseController->makeResponse(true, 'El arreglo de documentos asociados tiene un formato inválido.', [], 400);
            // Si el documento es nuevo, entonces...
            }else if($documentFile['type'] == 'Nuevo'){
                // Se obtiene el ID del documento
                $tempFileID = $this->encryptionController->decrypt($documentFile['id']);
                // Se obtiene la información registrada en la tabla de archivos temporales
                $tempFile = DB::table('S002V01TARTE')->where([
                    ['ARTE_IDAR', '=', $tempFileID],
                    ['ARTE_NULI', '=', $form['linea']]
                ])->first();
                // El documento es colocada en su posición final
                $finalFile = $this->documentManagementController->moveFinalFile($form['linea'], 'GEEQ', 'IN', $tempFile, $idUser);
                // Si ocurrió un error, entonces se manda el error
                if(!$finalFile[0]){
                    return $this->responseController->makeResponse(true, $finalFile[1], [], 400);
                }
                // La información es guardada en un arreglo
                $documents[] = $finalFile[1];
            }else{
                // Se desencripta el id del documento
                $fileID = $this->encryptionController->decrypt($documentFile['id']);
                // Es guardada en un arreglo
                $documents[] = $fileID;
            }
        }
        
        // El arreglo de los documentos es pasada en formato string
        $documentsStr = json_encode($documents);
        
        // Se obtiene el formato de la fecha en formato manejable
        $acquisitionDate = new Carbon($form['acquisition_date']);
        $warrantyStartDate = new Carbon($form['warranty_start_date']);
        $warrantyEndDate = new Carbon($form['warranty_end_date']);

        // Se verifica que la fecha de inicio de la garantia sea menor a la fecha final de la garantia
        if($warrantyStartDate->lt($acquisitionDate)){
            return $this->responseController->makeResponse(true, 'La fecha de inicio de la grantía no puede ser menor a la fecha de adquisición.', [], 400);
        }else if($warrantyEndDate->lte($acquisitionDate)){
            return $this->responseController->makeResponse(true, 'La fecha de término de la grantía no puede ser menor o igual a la fecha de inicio de la garantía.', [], 400);
        }

        // Se desencripta el numero del proveedor
        $providerID = $this->encryptionController->decrypt($form['equipment_provider']);
        if(!$providerID){
            return $this->responseController->makeResponse(true, 'El proveedor del equipamiento no fue encriptado correctamente.', [], 400);
        }
        // Se obtiene la información del proveedor
        $provider = DB::table('S002V01TPROV')->where([
            ['PROV_NUPR', '=', $providerID],
            ['PROV_NULI', '=', $form['linea']]
        ])->first();
        // Se verifica que el proveedor exista
        if(is_null($provider)){
            return $this->responseController->makeResponse(true, 'La proveedor seleccionada no existe.', [], 404);
        }
        
        // Se desencripta el número de serie
        $serialNumer = $this->encryptionController->decrypt($form['serial_number']);
        if(!$serialNumer){
            return $this->responseController->makeResponse(true, 'El número de serie del equipamiento no fue encriptado correctamente.', [], 400);
        }
        $arrSerialNumber = explode(',', $serialNumer);

        if (intval($form['number_items']) !== count($arrSerialNumber)) {
            return $this->responseController->makeResponse(true, 'La cantidad de número de series no corresponde con la cantidad de artículos a registrar.', [], 400);
        }
        foreach ($arrSerialNumber as $key => $serialNumer) {
            // Se obtiene la información del equipamiento por medio del número de serie
            $serialNmberDB = DB::table('S002V01TEQUI')->where([
                ['EQUI_NULI', '=', $form['linea']],
                ['EQUI_NUSE', '=', $serialNumer]
            ])->first();
            // Se verifica que exista el código de serie
            if(!is_null($serialNmberDB)){
                $serialNumberStr = $serialNmberDB->EQUI_COEQ;
                return $this->responseController->makeResponse(true, "El número de serie $serialNumer enviado ya se encuentra relacionado al equipamiento $serialNumberStr.", [], 401);
            }
        }

        // Se desencripta el código pregenerado en Angular
        $preCode = $this->encryptionController->decrypt($form['pre_generated_code']);
        if(!$preCode){
            return $this->responseController->makeResponse(true, 'El código pre generado no fue encriptado correctamente.', [], 400);
        }

        // Se obtiene el código pregenerado en Laravel
        $codeVerified = $this->verifyPreCode([
            "line" => $form['linea'],
            "originLocation" => $originLocation,
            "originLevel" => $originLevel,
            "originOccupation" => $originOccupationStr,
            "originElement" => $form['origin_element'],
            "warehouse" => $idWarehouse,
            "area" => $idArea,
            "level" => $idLevel,
            "zone" => $idZone,
            "family" => $familyCode,
            "subfamily" => $subfamilyCode,
            "status" => $status,
            "equipmentType" => $form['equipment_type'],
            "equipmentModel" => $form['equipment_model'],
            "equipmentID" => "XXXXX",
            "pccIntersection" => null,
            "pccPosition" => null,
            "originKilometers" => null,
            "destinyLocation" => null,
            "destinyLevel" => null,
            "destinyOccupation" => null,
            "destinyElement" => null,
            "destinyKilometers" => null
        ], $form['code_type'], $form['hierarchy'], $eqpa);

        // Se verifica que el código pregenerado en Angular y el pregenerado en Laravel
        if($codeVerified != $preCode){
            return $this->responseController->makeResponse(true, 'El código generado no coincide con el código verificado a partir de la información del formulario.', [], 400);
        }

        // Se verifica que la información del sfotware
        $deso = isset($form['software_name']) ? $form['software_name'] : null;
        $veso = isset($form['software_version']) ? $form['software_version'] : null;

        // Se obtiene la fecha actual
        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        
        $numberItems = intval($form['number_items']);
        for ($i=0; $i < $numberItems; $i++) { 
            // Se ingresa la información a la tabla de los precódigos de los equipamientos
            DB::table('S002V01TPCEQ')->insert([
                'PCEQ_NULI' => $form['linea'],
                'PCEQ_CPGE' => $preCode,
                'PCEQ_JERA' => $form['hierarchy'],
                'PCEQ_EQPA' => $eqpa,
                'PCEQ_TICO' => $form['code_type'],
                'PCEQ_UBOR' => $originLocation,
                'PCEQ_NIOR' => $originLevel,
                'PCEQ_OCOR' => $originOccupationStr,
                'PCEQ_ELOR' => $form['origin_element'],
                'PCEQ_ALMA' => $idWarehouse,
                'PCEQ_AREA' => $idArea,
                'PCEQ_NIVE' => $idLevel,
                'PCEQ_ZONA' => $idZone,
                'PCEQ_FAMI' => $familyCode,
                'PCEQ_SUBF' => $subfamilyCode,
                'PCEQ_ESEQ' => $status,
                'PCEQ_TIEQ' => $form['equipment_type'],
                'PCEQ_MOEQ' => $form['equipment_model'],
                'PCEQ_IPCC' => null,
                'PCEQ_PPCC' => null,
                'PCEQ_KIOR' => 0.0,
                'PCEQ_UBDE' => '',
                'PCEQ_NIDE' => '',
                'PCEQ_OCDE' => '',
                'PCEQ_ELDE' => '',
                'PCEQ_KIDE' => 0.0,
                'PCEQ_FEAD' => $form['acquisition_date'],
                'PCEQ_FIGA' => $form['warranty_start_date'],
                'PCEQ_FTGA' => $form['warranty_end_date'],
                'PCEQ_PREQ' => $providerID,
                'PCEQ_NUSE' => $arrSerialNumber[$i],
                'PCEQ_DESO' => $deso,
                'PCEQ_VESO' => $veso,
                'PCEQ_GAIM' => $imagesGalleryStr,
                'PCEQ_DORE' => $documentsStr,
                'PCEQ_USRE' => $idUser,
                'PCEQ_FERE' => $nowStr,
            ]);
        }

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            'S002V01P11REEQ',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") solicitó el registro del equipamiento $preCode.",
            $idUser,
            $nowStr,
        );

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

    public function verifyPreCode(array $parameters, string $type, string $mode, string | null $parentCode = '') : string {
        $code = "";

        if($mode == 'Hijo'){
            $code .= $parentCode;
            $equipment = ['equipmentType', 'equipmentModel', 'equipmentID'];
            $equipmentStr = "";
            foreach($equipment as $ctrl){
                $val = $parameters[$ctrl];
                if($ctrl == 'equipmentModel'){
                    $val = $this->processElement($val, 'model');
                }else if($ctrl == 'equipmentType'){
                    $val = $this->processElement($val, 'element');
                }

                $equipmentStr .= $val . '-';
            }
    
            $equipmentStr = substr($equipmentStr, 0, -1);
            $code .= "." . $equipmentStr;
        }else{
            switch($type){
                case "1":
                    //CASO 1: Codificación general
                    $lbs = ['line', 'originLocation', 'originLevel', 'originOccupation', 'originElement'];
                    $lbsStr = "";
                    foreach($lbs as $ctrl){
                        $val = $parameters[$ctrl];
                        if($ctrl == 'line'){
                            $val = intval($val) < 10 ? "0$val" : "$val";
                        }else if($ctrl == 'originElement'){
                            $val = $this->processElement($val, 'element');
                        }
    
                        $lbsStr .= $val . ".";
                    }
    
                    $lbsStr = substr($lbsStr, 0, -1);
                    $pbs = ['family', 'subfamily', 'status'];
                    $pbsStr = "";
                    foreach($pbs as $ctrl){
                        $val = $parameters[$ctrl];
                        $pbsStr .= $val . ".";
                    }
    
                    $pbsStr = substr($pbsStr, 0, -1);
                    $equipment = ['equipmentType', 'equipmentModel', 'equipmentID'];
                    $equipmentStr = "";
                    foreach($equipment as $ctrl){
                        $val = $parameters[$ctrl];
                        if($ctrl == 'equipmentModel'){
                            $val = $this->processElement($val, 'model');
                        }else if($ctrl == 'equipmentType'){
                            $val = $this->processElement($val, 'element');
                        }
    
                        $equipmentStr .= $val . '-';
                    }
    
                    $equipmentStr = substr($equipmentStr, 0, -1);
                    $code = $lbsStr . "_" . $pbsStr . "." . $equipmentStr;
                break;
                case "7":
                    $siteTag = '';
                    $site = ['line', 'area', 'level'];
                    foreach($site as $ctrl){
                        $val = $parameters[$ctrl];
                        if($ctrl == 'line'){
                            $val = intval($val) < 10 ? "0$val" : "$val";
                        }
                        $siteTag .= $val.'.';
                    }
                    $siteTag = substr($siteTag, 0, -1);


                    $areaTag = '';
                    $area = ['warehouse', 'zone'];
                    foreach($area as $ctrl){
                        $val = $parameters[$ctrl];
                        $areaTag .= $val.'.';
                    }
                    $areaTag = substr($areaTag, 0, -1);


                    $technicalSpecificationTag = '';
                    $technicalSpecification = ['family', 'subfamily', 'status'];
                    foreach($technicalSpecification as $ctrl){
                        $val = $parameters[$ctrl];
                        $technicalSpecificationTag .= $val.'.';
                    }
                    $technicalSpecificationTag = substr($technicalSpecificationTag, 0, -1);


                    $equipmentIdentifierTag = '';
                    $equipmentIdentifier = ['equipmentType', 'equipmentModel', 'equipmentID'];
                    foreach($equipmentIdentifier as $ctrl){
                        $val = $parameters[$ctrl];
                        if($ctrl == 'equipmentModel'){
                            $val = $this->processElement($val, 'model');
                        }else if($ctrl == 'equipmentType'){
                            $val = $this->processElement($val, 'element');
                        }

                        $equipmentIdentifierTag .= $val.'-';
                    }
                    $equipmentIdentifierTag = substr($equipmentIdentifierTag, 0, -1);
                    
                    $code = $siteTag.'-'.$areaTag.'_'.$technicalSpecificationTag.'.'.$equipmentIdentifierTag;
                break;
            }
        }

        return $code;
    }

    private function processElement(string $value, string $type) : string {
        $value = strtoupper($value);
        $validVal0 = $this->functionsController->unaccent($value);
        $CONNECTORS = ['DE', 'PARA', 'Y', 'O', 'DEL', 'EL', 'LA', 'LOS', 'POR', 'EN'];
        $valueArr1 = explode(' ', $validVal0);
        $validVal1 = [];

        foreach($valueArr1 as $word){
            if(!in_array($word, $CONNECTORS)){
                $validVal1[] = $word;
            }
        }

        $validLength = count($validVal1);
        $validVal2 = "";

        if($validLength < 1){
            return "ERROR";
        }else if($validLength == 1){
            if(strlen($validVal1[0]) < 5){
                $validVal2 = $validVal1[0];
                for($i = strlen($validVal1[0]); $i < 5; $i++){
                    if($type == 'model'){
                        $validVal2 = "X$validVal2";
                    }else{
                        $validVal2 = $validVal2 . "X";
                    }
                }
            }else{
                $validVal2 = substr($validVal1[0], 0, 5);
            }
        }else if($validLength == 2){
            $word1 = "";
            if(strlen($validVal1[0]) < 2){
                if($type == 'model'){
                    $word1 = "X$validVal1[0]";
                }else{
                    $word1 = $validVal1[0] . "X";
                }
            }else{
                $word1 = substr($validVal1[0], 0, 2);
            }

            $word2 = "";
            if(strlen($validVal1[1]) < 3){
                $word2 = $validVal1[1];
                for($i = strlen($validVal1[1]); $i < 3; $i++){
                    if($type == 'model'){
                        $word2 = "X$word2";
                    }else{
                        $word2 = $word2 . "X";
                    }
                }
            }else{
                $word2 = substr($validVal1[1], 0, 3);
            }

            $validVal2 = $word1 . $word2;
        }else if($validLength == 3){
            $word1 = "";
            if(strlen($validVal1[0]) < 2){
                if($type == 'model'){
                    $word1 = "X$validVal1[0]";
                }else{
                    $word1 = $validVal1[0] . "X";
                }
            }else{
                $word1 = substr($validVal1[0], 0, 2);
            }
            
            $word2 = substr($validVal1[1], 0, 1);

            $word3 = "";
            if(strlen($validVal1[2]) < 2){
                if($type == 'model'){
                    $word3 = "X$validVal1[2]";
                }else{
                    $word3 = $validVal1[2] . "X";
                }
            }else{
                $word3 = substr($validVal1[2], 0, 2);
            }

            $validVal2 = $word1 . $word2 . $word3;
        }else if($validLength == 4){
            $word1 = "";
            if(strlen($validVal1[0]) < 2){
                if($type == 'model'){
                    $word1 = "X$validVal1[0]";
                }else{
                    $word1 = $validVal1[0] . "X";
                }
            }else{
                $word1 = substr($validVal1[0], 0, 2);
            }
            
            $word2 = substr($validVal1[1], 0, 1);
            $word3 = substr($validVal1[2], 0, 1);
            $word4 = substr($validVal1[3], 0, 1);

            $validVal2 = $word1 . $word2 . $word3 . $word4;
        }else if($validLength >= 5){
            $word1 = substr($validVal1[0], 0, 1);
            $word2 = substr($validVal1[1], 0, 1);
            $word3 = substr($validVal1[2], 0, 1);
            $word4 = substr($validVal1[3], 0, 1);
            $word5 = substr($validVal1[4], 0, 1);

            $validVal2 = $word1 . $word2 . $word3 . $word4 . $word5;
        }else{
            return "ERROR";
        }

        return $validVal2;
    }

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $pendingEquipments = DB::table('S002V01TPCEQ')->select([
            'PCEQ_IDPR AS IDREG',
            'PCEQ_CPGE AS CODIGO',
            'PCEQ_TICO AS TIPO_CODIGO',
            'PCEQ_TIEQ AS TIPO_EQUIPAMIENTO',
            'PCEQ_MOEQ AS MODELO_EQUIPAMIENTO',
            'PCEQ_GAIM AS GALERIA_IMAGENES',
            'PCEQ_ESRE AS ESTADO_REGISTRO',
        ])->where([
            ['PCEQ_NULI', '=', $line],
            ['PCEQ_ESRE', '=', 'Revisión'],
        ])->get()->all();

        $idUserEnc = $this->encryptionController->encrypt($idUser);
        foreach($pendingEquipments as $key=>$equipment){
            $equipment->IDREG = $this->encryptionController->encrypt($equipment->IDREG);
            $equipment->CODIGO = $this->encryptionController->encrypt($equipment->CODIGO);

            $imagesGalleryArr = json_decode($equipment->GALERIA_IMAGENES);
            $imagesGalleryFn = [];
            foreach($imagesGalleryArr as $imageCode){
                $imageCodeEnc = $this->encryptionController->encrypt($imageCode);
                $publicUri = $this->documentManagementController->getPublicDocumentURL(
                    $imageCodeEnc,
                    $idUserEnc,
                    $line
                );

                $response = json_decode($publicUri->original, true);
                if($response['error']){
                    return $this->responseController->makeresponse(true, $response['msg'], [], 500);
                }else{
                    $uriEnc = $this->encryptionController->encrypt($response['response']['public_uri']);
                    $imagesGalleryFn[] = $uriEnc;
                }
            }

            $equipment->GALERIA_IMAGENES = json_encode($imagesGalleryFn);
            $equipment->TIPO_EQUIPAMIENTO = $this->encryptionController->encrypt($equipment->TIPO_EQUIPAMIENTO);
            $equipment->MODELO_EQUIPAMIENTO = $this->encryptionController->encrypt($equipment->MODELO_EQUIPAMIENTO);

            $pendingEquipments[$key] = $equipment;
        }

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los equipamientos en revisión.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $idReg = $this->encryptionController->decrypt($idReg);
        if(!$idReg){
            return $this->responseController->makeResponse(true, 'El ID del pre-registro no está encriptado correctamente', [], 400);
        }

        $pendingEquipment = DB::table('S002V01TPCEQ')->select([
            'PCEQ_IDPR AS IDREG',
            'PCEQ_CPGE AS CODIGO',
            'PCEQ_JERA AS JERARQUIA',
            'PCEQ_EQPA AS PADRE',
            'PCEQ_TICO AS TIPO_CODIGO',
            'PCEQ_UBOR AS UBICACION_ORIGEN',
            'PCEQ_NIOR AS NIVEL_ORIGEN',
            'PCEQ_OCOR AS OCUPACION_ORIGEN',
            'PCEQ_ELOR AS ELEMENTO_ORIGEN',
            'PCEQ_FAMI AS FAMILIA',
            'PCEQ_SUBF AS SUBFAMILIA',
            'PCEQ_ESEQ AS ESTADO_EQUIPAMIENTO',
            'PCEQ_TIEQ AS TIPO_EQUIPAMIENTO',
            'PCEQ_MOEQ AS MODELO_EQUIPAMIENTO',
            'PCEQ_IPCC AS INTERSECCION_PCC',
            'PCEQ_PPCC AS POSICION_PCC',
            'PCEQ_KIOR AS KILOMETRO_ORIGEN',
            'PCEQ_UBDE AS UBICACION_DESTINO',
            'PCEQ_NIDE AS NIVEL_DESTINO',
            'PCEQ_OCDE AS OCUPACION_DESTINO',
            'PCEQ_ELDE AS ELEMENTO_DESTINO',
            'PCEQ_KIDE AS KILOMETRO_DESTINO',
            'PCEQ_FEAD AS FECHA_ADQUISICION',
            'PCEQ_FIGA AS FECHA_INICIO_GARANTIA',
            'PCEQ_FTGA AS FECHA_FIN_GARANTIA',
            'PCEQ_PREQ AS PROVEEDOR',
            'PCEQ_NUSE AS NUMERO_SERIAL',
            'PCEQ_DESO AS DENOMINACION_SOFTWARE',
            'PCEQ_VESO AS VERSION_SOFTWARE',
            'PCEQ_GAIM AS GALERIA_IMAGENES',
            'PCEQ_DORE AS DOCUMENTOS',
            'PCEQ_ESRE AS ESTADO_REGISTRO',
            'PCEQ_CORE AS COMENTARIOS_RECHAZO',
            'PCEQ_COAC AS COMENTARIOS_ACEPTACION',
            'PCEQ_USRE AS USUARIO_REGISTRO',
            'PCEQ_FERE AS FECHA_REGISTRO',
            'PCEQ_USMO AS USUARIO_MODIFICO',
            'PCEQ_FEMO AS FECHA_MODIFICACION'
        ])->where([
            ['PCEQ_NULI', '=', $line],
            ['PCEQ_IDPR', '=', $idReg],
            ['PCEQ_ESRE', '=', 'Revisión'],
        ])->first();

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

        $pendingEquipment->IDREG = $this->encryptionController->encrypt($pendingEquipment->IDREG);
        $pendingEquipment->CODIGO = $this->encryptionController->encrypt($pendingEquipment->CODIGO);

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $locationsEnc = file_get_contents($ubic . "locations.sam");
        $locationsDec = $this->encryptionController->decrypt($locationsEnc);
        $locationsArr = json_decode($locationsDec, true);
        $locationsArrDec = [];
        foreach($locationsArr as $location){
            $locationStr = $this->encryptionController->decrypt($location['LOCATION']);
            $code = $this->encryptionController->decrypt($location['CODE']);

            $locationsArrDec[] = [
                'LOCATION' => $locationStr,
                'CODE' => $code
            ];
        }

        $originLocation = $pendingEquipment->UBICACION_ORIGEN;
        $originLocationFilt = array_filter($locationsArrDec, function ($v, $k) use ($originLocation) {
            return $v['CODE'] == $originLocation;
        }, ARRAY_FILTER_USE_BOTH);

        $pendingEquipment->UBICACION_ORIGEN = end($originLocationFilt)['LOCATION'] . " (" . $pendingEquipment->UBICACION_ORIGEN . ")";
        $levelsArr = [];
    
        for($i = 5; $i > 0; $i--){
            $levelsArr[] = [
                'LEVEL' => "Subterráneo S0$i",
                'CODE' => "S0$i",
            ];
        }

        for($i = 0; $i <= 15; $i++){
            $code = $i < 10 ? "P0$i" : "P$i";
            $level = $i == 0 ? "Planta baja P00" : "Piso $code";
            $levelsArr[] = [
                'LEVEL' => $level,
                'CODE' => $code,
            ];
        }

        $originLevel = $pendingEquipment->NIVEL_ORIGEN;
        $originLevelFilt = array_filter($levelsArr, function ($v, $k) use ($originLevel) {
            return $v['CODE'] == $originLevel;
        }, ARRAY_FILTER_USE_BOTH);

        $pendingEquipment->NIVEL_ORIGEN = end($originLevelFilt)['LEVEL'] . " (" . $pendingEquipment->NIVEL_ORIGEN . ")";
        $originOccupationStr = $pendingEquipment->OCUPACION_ORIGEN;
        $originOccupationArea = substr($originOccupationStr, 0, 2);
        $originOccupationID = substr($originOccupationStr, 2);
        $originOccupation = DB::table('S002V01TOCUP')->where([
            ['OCUP_NULI', '=', $line],
            ['OCUP_AREA', '=', $originOccupationArea],
            ['OCUP_IDOC', '=', $originOccupationID]
        ])->first();

        $pendingEquipment->OCUPACION_ORIGEN = $originOccupation->OCUP_DESC . " (" . $originOccupationStr . ")";
        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $line],
            ['FAMI_COFA', '=', $pendingEquipment->FAMILIA],
        ])->first();
        
        $subfamily = DB::table('S002V01TSUBF')->where([
            ['SUBF_NULI', '=', $line],
            ['SUBF_COFA', '=', $pendingEquipment->FAMILIA],
            ['SUBF_COSU', '=', $pendingEquipment->SUBFAMILIA],
        ])->first();

        $pendingEquipment->FAMILIA = $family->FAMI_NOFA . " (" . $pendingEquipment->FAMILIA . ")";
        $pendingEquipment->SUBFAMILIA = $subfamily->SUBF_NOSU . " (" . $pendingEquipment->SUBFAMILIA . ")";

        $validStatus = ["A" => "Adquisición", "S" => "Stock", "T" => "Traslado", "I" => "Instalación", "R" => "Reparación", "D" => "Disposición"];
        $pendingEquipment->ESTADO_EQUIPAMIENTO = $validStatus[$pendingEquipment->ESTADO_EQUIPAMIENTO] . " (" . $pendingEquipment->ESTADO_EQUIPAMIENTO . ")";

        $idUserEnc = $this->encryptionController->encrypt($idUser);
        $imagesGalleryArr = json_decode($pendingEquipment->GALERIA_IMAGENES);
        $imagesGalleryFn = [];
        foreach($imagesGalleryArr as $imageCode){
            $imageCodeEnc = $this->encryptionController->encrypt($imageCode);
            $publicUri = $this->documentManagementController->getPublicDocumentURL(
                $imageCodeEnc,
                $idUserEnc,
                $line
            );

            $response = json_decode($publicUri->original, true);
            if($response['error']){
                return $this->responseController->makeresponse(true, $response['msg'], [], 500);
            }else{
                $uriEnc = $this->encryptionController->encrypt($response['response']['public_uri']);
                $imagesGalleryFn[] = $uriEnc;
            }
        }

        $documentsArr = json_decode($pendingEquipment->DOCUMENTOS);
        $documentsFn = [];
        foreach($documentsArr as $document){
            $codeArr = explode('=',$document);
            $codeArr0 = explode('-', $codeArr[0]);

            $file = DB::table('S002V01TAFAL')->where([
                ['AFAL_NULI', '=', $line],
                ['AFAL_COMO', '=', $codeArr0[1]],
                ['AFAL_CLDO', '=', $codeArr0[2]],
                ['AFAL_FECR', '=', $codeArr0[3]],
                ['AFAL_NUSE', '=', $codeArr0[4]],
                ['AFAL_NUVE', '=', $codeArr[1]],
            ])->first();

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

            $documentsFn[] = [
                'id' => $this->encryptionController->encrypt($document),
                'name' => $document,
                'size' => $file->AFAL_TAMA
            ];
        }

        $pendingEquipment->GALERIA_IMAGENES = json_encode($imagesGalleryFn);
        $pendingEquipment->DOCUMENTOS = json_encode($documentsFn);
        $pendingEquipment->PROVEEDOR = $this->encryptionController->encrypt($pendingEquipment->PROVEEDOR);
        $pendingEquipment->NUMERO_SERIAL = $this->encryptionController->encrypt($pendingEquipment->NUMERO_SERIAL);

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

        $usrRegName = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
        $pendingEquipment->USUARIO_REGISTRO = $usrRegName . " (" . $pendingEquipment->USUARIO_REGISTRO . ")";

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

            $usrModName = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA);
            $pendingEquipment->USUARIO_MODIFICO = $usrModName . " (" . $pendingEquipment->USUARIO_MODIFICO . ")";
        }

        $pendingEquipment->TIPO_EQUIPAMIENTO = $this->encryptionController->encrypt($pendingEquipment->TIPO_EQUIPAMIENTO);
        $pendingEquipment->MODELO_EQUIPAMIENTO = $this->encryptionController->encrypt($pendingEquipment->MODELO_EQUIPAMIENTO);

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó el equipamiento pre codificado $idReg.",
            $idUser,
            $nowStr,
        );

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

    public function changePreCodedEquipmentStatus(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_reg' => 'required|string',
            'status' => 'required|string|in:Aprobado,Rechazado',
            'comments' => 'required|string|min:15',
        ]);
 
        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);
        }

        $idReg = $this->encryptionController->decrypt($form['id_reg']);
        if(!$idReg){
            return $this->responseController->makeResponse(true, 'El ID del pre-registro no está encriptado correctamente', [], 400);
        }

        $pendingEquipment = DB::table('S002V01TPCEQ')->where([
            ['PCEQ_NULI', '=', $form['linea']],
            ['PCEQ_IDPR', '=', $idReg],
        ])->first();

        if(is_null($pendingEquipment)){
            return $this->responseController->makeResponse(true, 'El pre-registro solicitado no existe.', [], 404);
        }else if($pendingEquipment->PCEQ_ESRE == 'Rechazado'){
            return $this->responseController->makeResponse(true, 'El pre-registro se encuentra rechazado.', [], 400);
        }else if($pendingEquipment->PCEQ_ESRE == 'Aprobado'){
            return $this->responseController->makeResponse(true, 'El pre-registro se encuentra aprobado.', [], 400);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        if($form['status'] == 'Rechazado'){
            DB::table('S002V01TPCEQ')->where([
                ['PCEQ_IDPR', '=', $idReg],
                ['PCEQ_NULI', '=', $form['linea']],
            ])->update([
                'PCEQ_ESRE' => $form['status'],
                'PCEQ_CORE' => $form['comments'],
                'PCEQ_USMO' => $idUser,
                'PCEQ_FEMO' => $nowStr,
            ]);
        }else{
            //PASO 1: SE BUSCA EL ÚLTIMO ID DEL EQUIPAMIENTO
            $lastID = DB::table('S002V01TEQUI')->select([
                'EQUI_IDEQ AS LAST_ID'
            ])->where([
                ['EQUI_NULI', '=', $form['linea']],
                ['EQUI_FAMI', '=', $pendingEquipment->PCEQ_FAMI],
                ['EQUI_SUBF', '=', $pendingEquipment->PCEQ_SUBF],
                ['EQUI_TIPO', '=', $pendingEquipment->PCEQ_TIEQ],
                ['EQUI_MODE', '=', $pendingEquipment->PCEQ_MOEQ],
            ])->orderBy('EQUI_IDEQ', 'asc')->first();

            //PASO 2: SE DEFINE EL ID DEL NUEVO EQUIPAMIENTO
            $IDNum = is_null($lastID) ? 1 : $lastID->LAST_ID + 1;

            //PASO 3: SE DEFINE UN ESPACIO PARA RETORNAR EL PROCESO
            doAgain:

            //PASO 4: SE RELLENA EL ID CON CEROS A LA IZQUIERDA PARA DARLE EL FORMATO DE LA CODIFICACIÓN
            $IDStr = "$IDNum";
            for($i = strlen($IDStr); $i < 6; $i++){
                $IDStr = "0$IDStr";
            }

            //PASO 5: SE INTEGRA EL ID AL CÓDIGO PRE-GENERADO
            $preCodeArr = explode('_', $pendingEquipment->PCEQ_CPGE);
            $previewPBS = $preCodeArr[1];
            $previewPBSArr = explode('-', $previewPBS);
            $previewPBSArr = array_reverse($previewPBSArr);

            $previewPBSArr[0] = $IDStr;
            $previewPBSArr = array_reverse($previewPBSArr);
            $previewPBS = implode('-', $previewPBSArr);

            //PASO 6: SE BUSCA SI EL CÓDIGO ESTÁ REGISTRADO EN ALGÚN EQUIPAMIENTO O EN EL HISTORIAL DE CÓDIGOS DE ALGÚN EQUIPAMIENTO
            $previewCode = $preCodeArr[0] . "_" . $previewPBS;
            $registeredCode = DB::table('S002V01TEQUI')->where([
                ['EQUI_NULI', '=', $form['linea']],
                ['EQUI_COEQ', '=', $previewCode]
            ])->first();

            $codeInHistory = DB::table('S002V01TEQUI')
            ->where('EQUI_NULI', '=', $form['linea'])
            ->whereJsonContains('EQUI_HICO', $previewCode)->first();

            //PASO 7: VERIFICAR QUE EL CÓDIGO NO EXISTA, SI EXISTE SE REALIZA NUEVAMENTE EL PROCESO AUMENTANDO EN 1 EL ID
            if(!is_null($registeredCode) || !is_null($codeInHistory)){
                $IDNum++;
                goto doAgain;
            }

            //PASO 8: REALIZAR EL REGISTRO DEL EQUIPAMIENTO
            $hico = json_encode([$previewCode]);
            DB::table('S002V01TEQUI')->insert([
                'EQUI_NULI' => $form['linea'],
                'EQUI_FAMI' => $pendingEquipment->PCEQ_FAMI,
                'EQUI_SUBF' => $pendingEquipment->PCEQ_SUBF,
                'EQUI_TIPO' => $pendingEquipment->PCEQ_TIEQ,
                'EQUI_MODE' => $pendingEquipment->PCEQ_MOEQ,
                'EQUI_IDEQ' => $IDNum,
                'EQUI_ESEQ' => $pendingEquipment->PCEQ_ESEQ,
                'EQUI_COEQ' => $previewCode,
                'EQUI_JERA' => $pendingEquipment->PCEQ_JERA,
                'EQUI_EQPA' => $pendingEquipment->PCEQ_EQPA,
                'EQUI_TICO' => $pendingEquipment->PCEQ_TICO,
                'EQUI_UBOR' => $pendingEquipment->PCEQ_UBOR,
                'EQUI_NIOR' => $pendingEquipment->PCEQ_NIOR,
                'EQUI_OCOR' => $pendingEquipment->PCEQ_OCOR,
                'EQUI_ELOR' => $pendingEquipment->PCEQ_ELOR,
                'EQUI_ALMA' => $pendingEquipment->PCEQ_ALMA,
                'EQUI_AREA' => $pendingEquipment->PCEQ_AREA,
                'EQUI_NIVE' => $pendingEquipment->PCEQ_NIVE,
                'EQUI_ZONA' => $pendingEquipment->PCEQ_ZONA,
                'EQUI_IPCC' => $pendingEquipment->PCEQ_IPCC,
                'EQUI_PPCC' => $pendingEquipment->PCEQ_PPCC,
                'EQUI_KIOR' => $pendingEquipment->PCEQ_KIOR,
                'EQUI_UBDE' => $pendingEquipment->PCEQ_UBDE,
                'EQUI_NIDE' => $pendingEquipment->PCEQ_NIDE,
                'EQUI_OCDE' => $pendingEquipment->PCEQ_OCDE,
                'EQUI_ELDE' => $pendingEquipment->PCEQ_ELDE,
                'EQUI_KIDE' => $pendingEquipment->PCEQ_KIDE,
                'EQUI_FEAD' => $pendingEquipment->PCEQ_FEAD,
                'EQUI_FIGA' => $pendingEquipment->PCEQ_FIGA,
                'EQUI_FTGA' => $pendingEquipment->PCEQ_FTGA,
                'EQUI_PREQ' => $pendingEquipment->PCEQ_PREQ,
                'EQUI_NUSE' => $pendingEquipment->PCEQ_NUSE,
                'EQUI_DESO' => $pendingEquipment->PCEQ_DESO,
                'EQUI_VESO' => $pendingEquipment->PCEQ_VESO,
                'EQUI_HICO' => $hico,
                'EQUI_GAIM' => $pendingEquipment->PCEQ_GAIM,
                'EQUI_DORE' => $pendingEquipment->PCEQ_DORE,
                'EQUI_USRE' => $idUser,
                'EQUI_FERE' => $nowStr,
            ]);

            DB::table('S002V01TPCEQ')->where([
                ['PCEQ_IDPR', '=', $idReg],
                ['PCEQ_NULI', '=', $form['linea']],
            ])->update([
                'PCEQ_ESRE' => $form['status'],
                'PCEQ_CORE' => $form['comments'],
                'PCEQ_USMO' => $idUser,
                'PCEQ_FEMO' => $nowStr,
            ]);
        }

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            'S002V01P11REEQ',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") cambió el estado del pre-registro $idReg a $form[status].",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $equipments = DB::table('S002V01TEQUI')->select([
            'EQUI_COEQ AS CODIGO',
            'EQUI_TIPO AS TIPO',
            'EQUI_MODE AS MODELO',
            'EQUI_IDEQ AS ID_EQUIPO',
            'EQUI_ESFU AS ESTADO_FUNCIONAMIENTO',
            'EQUI_GAIM AS GALERIA_IMAGENES',
            'EQUI_ELOR AS ELEMENTO_ORIGEN',
            'EQUI_TICO AS TIPO_CODIGO',
            'EQUI_EQPA AS EQUIPO_PADRE',
        ])->where('EQUI_NULI', '=', $line)->get()->all();

        $idUserEnc = $this->encryptionController->encrypt($idUser);
        foreach($equipments as $key=>$equipment){
            $children = DB::table('S002V01TEQUI')->where([
                ['EQUI_NULI', '=', $line],
                ['EQUI_EQPA', '=', $equipment->CODIGO],
            ])->get()->all();

            $equipment->CODIGO = $this->encryptionController->encrypt($equipment->CODIGO);
            $equipment->ID_EQUIPO = $this->encryptionController->encrypt($equipment->ID_EQUIPO);
            $equipment->EQUIPO_PADRE = is_null($equipment->EQUIPO_PADRE) ? null : $this->encryptionController->encrypt($equipment->EQUIPO_PADRE);

            $imagesGalleryArr = json_decode($equipment->GALERIA_IMAGENES, true);
            $imagesGalleryFn = [];
            foreach($imagesGalleryArr as $imageCode){
                $imageCodeEnc = $this->encryptionController->encrypt($imageCode);
                $publicUri = $this->documentManagementController->getPublicDocumentURL(
                    $imageCodeEnc,
                    $idUserEnc,
                    $line
                );

                $response = json_decode($publicUri->original, true);
                if($response['error']){
                    return $this->responseController->makeresponse(true, $response['msg'], [], 500);
                }else{
                    $uriEnc = $this->encryptionController->encrypt($response['response']['public_uri']);
                    $imagesGalleryFn[] = $uriEnc;
                }
            }

            $equipment->GALERIA_IMAGENES = json_encode($imagesGalleryFn);
            $equipment->TIENE_HIJOS = count($children) > 0 ? 'Si' : 'No';
            $equipments[$key] = $equipment;
        }

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            'S002V01P01MEEQ',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los equipamientos registrados.",
            $idUser,
            $nowStr,
        );

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

    public function getEquipmentsBySubfamily($familyCode, $subfamilyCode, $idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($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);
        }

        $familyCode = $this->encryptionController->decrypt($familyCode);
        if(!$familyCode){
            return $this->responseController->makeResponse(true, 'El código de la familia no está encriptado correctamente', [], 400);
        }
        
        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $line],
            ['FAMI_COFA', '=', $familyCode],
        ])->first();

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

        $subfamilyCode = $this->encryptionController->decrypt($subfamilyCode);
        if(!$subfamilyCode){
            return $this->responseController->makeResponse(true, 'El código de la subfamilia no está encriptado correctamente', [], 400);
        }

        $subfamily = DB::table('S002V01TSUBF')->where([
            ['SUBF_NULI', '=', $line],
            ['SUBF_COFA', '=', $familyCode],
            ['SUBF_COSU', '=', $subfamilyCode],
        ])->first();

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

        $equipments = DB::table('S002V01TEQUI')->select([
            'EQUI_COEQ AS CODIGO',
            'EQUI_TIPO AS TIPO',
            'EQUI_MODE AS MODELO',
            'EQUI_IDEQ AS ID_EQUIPO',
            'EQUI_ESFU AS ESTADO_FUNCIONAMIENTO',
            'EQUI_GAIM AS GALERIA_IMAGENES',
        ])->where([
            ['EQUI_NULI', '=', $line],
            ['EQUI_FAMI', '=', $familyCode],
            ['EQUI_SUBF', '=', $subfamilyCode],
            ['EQUI_JERA', '=', 'Padre']
        ])->get()->all();

        $idUserEnc = $this->encryptionController->encrypt($idUser);
        foreach($equipments as $key=>$equipment){
            $equipment->CODIGO = $this->encryptionController->encrypt($equipment->CODIGO);
            $equipment->ID_EQUIPO = $this->encryptionController->encrypt($equipment->ID_EQUIPO);

            $imagesGalleryArr = json_decode($equipment->GALERIA_IMAGENES, true);
            $imagesGalleryFn = [];
            foreach($imagesGalleryArr as $imageCode){
                $imageCodeEnc = $this->encryptionController->encrypt($imageCode);
                $publicUri = $this->documentManagementController->getPublicDocumentURL(
                    $imageCodeEnc,
                    $idUserEnc,
                    $line
                );

                $response = json_decode($publicUri->original, true);
                if($response['error']){
                    return $this->responseController->makeresponse(true, $response['msg'], [], 500);
                }else{
                    $uriEnc = $this->encryptionController->encrypt($response['response']['public_uri']);
                    $imagesGalleryFn[] = $uriEnc;
                }
            }

            $equipment->GALERIA_IMAGENES = json_encode($imagesGalleryFn);
            $equipments[$key] = $equipment;
        }

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            'S002V01P01MEEQ',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los equipamientos relacionados a la subfamilia $subfamilyCode de la familia $familyCode.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $parentCode = $this->encryptionController->decrypt($parentCode);
        if(!$parentCode){
            return $this->responseController->makeResponse(true, 'El código del equipamiento padre no está encriptado correctamente', [], 400);
        }

        $equipments = DB::table('S002V01TEQUI')->select([
            'EQUI_COEQ AS CODIGO',
            'EQUI_TIPO AS TIPO',
            'EQUI_MODE AS MODELO',
            'EQUI_IDEQ AS ID_EQUIPO',
            'EQUI_ESFU AS ESTADO_FUNCIONAMIENTO',
            'EQUI_GAIM AS GALERIA_IMAGENES',
            'EQUI_EQPA AS EQUIPO_PADRE',
        ])->where([
            ['EQUI_NULI', '=', $line],
            ['EQUI_JERA', '=', 'Hijo'],
            ['EQUI_EQPA', '=', $parentCode],
        ])->get()->all();

        $idUserEnc = $this->encryptionController->encrypt($idUser);
        foreach($equipments as $key=>$equipment){
            $children = DB::table('S002V01TEQUI')->where([
                ['EQUI_NULI', '=', $line],
                ['EQUI_EQPA', '=', $equipment->CODIGO],
            ])->get()->all();

            $equipment->CODIGO = $this->encryptionController->encrypt($equipment->CODIGO);
            $equipment->ID_EQUIPO = $this->encryptionController->encrypt($equipment->ID_EQUIPO);
            $equipment->EQUIPO_PADRE = is_null($equipment->EQUIPO_PADRE) ? null : $this->encryptionController->encrypt($equipment->EQUIPO_PADRE);

            $imagesGalleryArr = json_decode($equipment->GALERIA_IMAGENES, true);
            $imagesGalleryFn = [];
            foreach($imagesGalleryArr as $imageCode){
                $imageCodeEnc = $this->encryptionController->encrypt($imageCode);
                $publicUri = $this->documentManagementController->getPublicDocumentURL(
                    $imageCodeEnc,
                    $idUserEnc,
                    $line
                );

                $response = json_decode($publicUri->original, true);
                if($response['error']){
                    return $this->responseController->makeresponse(true, $response['msg'], [], 500);
                }else{
                    $uriEnc = $this->encryptionController->encrypt($response['response']['public_uri']);
                    $imagesGalleryFn[] = $uriEnc;
                }
            }

            $equipment->GALERIA_IMAGENES = json_encode($imagesGalleryFn);
            $equipment->TIENE_HIJOS = count($children) > 0 ? 'Si' : 'No';
            $equipments[$key] = $equipment;
        }

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            'S002V01P02DEEQ',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los equipamientos relacionados al equipamiento $parentCode.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $code = $this->encryptionController->decrypt($code);
        if(!$code){
            return $this->responseController->makeResponse(true, 'El código del equipamiento no está encriptado correctamente', [], 400);
        }

        $equipment = DB::table('S002V01TEQUI')->select([
            'EQUI_FAMI AS FAMILIA',
            'EQUI_SUBF AS SUBFAMILIA',
            'EQUI_TIPO AS TIPO_EQUIPAMIENTO',
            'EQUI_MODE AS MODELO',
            'EQUI_IDEQ AS ID_EQUIPAMIENTO',
            'EQUI_ESEQ AS ESTADO',
            'EQUI_COEQ AS CODIGO',
            'EQUI_JERA AS JERARQUIA',
            'EQUI_EQPA AS EQUIPO_PADRE',
            'EQUI_TICO AS TIPO_CODIGO',
            'EQUI_UBOR AS UBICACION_ORIGEN',
            'EQUI_NIOR AS NIVEL_ORIGEN',
            'EQUI_OCOR AS OCUPACION_ORIGEN',
            'EQUI_ELOR AS ELEMENTO_ORIGEN',
            'EQUI_IPCC AS INTERSECCION_PCC',
            'EQUI_PPCC AS POSICION_PCC',
            'EQUI_KIOR AS KILOMETRO_ORIGEN',
            'EQUI_UBDE AS UBICACION_DESTINO',
            'EQUI_NIDE AS NIVEL_DESTINO',
            'EQUI_OCDE AS OCUPACION_DESTINO',
            'EQUI_ELDE AS ELEMENTO_DESTINO',
            'EQUI_KIDE AS KILOMETRO_DESTINO',
            'EQUI_FEAD AS FECHA_ADQUISICION',
            'EQUI_FIGA AS FECHA_INICIO_GARANTIA',
            'EQUI_FTGA AS FECHA_TERMINO_GARANTIA',
            'EQUI_PREQ AS PROVEEDOR',
            'EQUI_NUSE AS NUMERO_SERIAL',
            'EQUI_DESO AS DENOMINACION_SOFTWARE',
            'EQUI_VESO AS VERSION_SOFTWARE',
            'EQUI_HICO AS HISTORIAL_CODIGOS',
            'EQUI_GAIM AS GALERIA_IMAGENES',
            'EQUI_DORE AS DOCUMENTOS',
            'EQUI_ESFU AS ESTADO_FUNCIONAMIENTO',
            'EQUI_USRE AS USUARIO_REGISTRO',
            'EQUI_FERE AS FECHA_REGISTRO',
            'EQUI_USMO AS USUARIO_MODIFICACION',
            'EQUI_FEMO AS FECHA_MODIFICACION',
        ])->where([
            ['EQUI_NULI', '=', $line],
            ['EQUI_COEQ', '=', $code],
        ])->first();

        $family = DB::table('S002V01TFAMI')->where([
            ['FAMI_NULI', '=', $line],
            ['FAMI_COFA', '=', $equipment->FAMILIA]
        ])->first();

        $subfamily = DB::table('S002V01TSUBF')->where([
            ['SUBF_NULI', '=', $line],
            ['SUBF_COFA', '=', $equipment->FAMILIA],
            ['SUBF_COSU', '=', $equipment->SUBFAMILIA]
        ])->first();

        $equipment->FAMILIA = $family->FAMI_NOFA . " (" . $equipment->FAMILIA . ")";
        $equipment->SUBFAMILIA = $subfamily->SUBF_NOSU . " (" . $equipment->SUBFAMILIA . ")";
        $equipment->ID_EQUIPAMIENTO = $this->encryptionController->encrypt($equipment->ID_EQUIPAMIENTO);
        $equipment->CODIGO = $this->encryptionController->encrypt($equipment->CODIGO);

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $locationsEnc = file_get_contents($ubic . "locations.sam");
        $locationsDec = $this->encryptionController->decrypt($locationsEnc);
        $locationsArr = json_decode($locationsDec, true);
        $locationsArrDec = [];
        foreach($locationsArr as $location){
            $locationStr = $this->encryptionController->decrypt($location['LOCATION']);
            $code = $this->encryptionController->decrypt($location['CODE']);

            $locationsArrDec[] = [
                'LOCATION' => $locationStr,
                'CODE' => $code
            ];
        }

        $originLocation = $equipment->UBICACION_ORIGEN;
        $originLocationFilt = array_filter($locationsArrDec, function ($v, $k) use ($originLocation) {
            return $v['CODE'] == $originLocation;
        }, ARRAY_FILTER_USE_BOTH);

        $equipment->UBICACION_ORIGEN = end($originLocationFilt)['LOCATION'] . " (" . $equipment->UBICACION_ORIGEN . ")";
        $levelsArr = [];
    
        for($i = 5; $i > 0; $i--){
            $levelsArr[] = [
                'LEVEL' => "Subterráneo S0$i",
                'CODE' => "S0$i",
            ];
        }

        for($i = 0; $i <= 15; $i++){
            $code = $i < 10 ? "P0$i" : "P$i";
            $level = $i == 0 ? "Planta baja P00" : "Piso $code";
            $levelsArr[] = [
                'LEVEL' => $level,
                'CODE' => $code,
            ];
        }

        $originLevel = $equipment->NIVEL_ORIGEN;
        $originLevelFilt = array_filter($levelsArr, function ($v, $k) use ($originLevel) {
            return $v['CODE'] == $originLevel;
        }, ARRAY_FILTER_USE_BOTH);

        $equipment->NIVEL_ORIGEN = end($originLevelFilt)['LEVEL'] . " (" . $equipment->NIVEL_ORIGEN . ")";
        $originOccupationStr = $equipment->OCUPACION_ORIGEN;
        $originOccupationArea = substr($originOccupationStr, 0, 2);
        $originOccupationID = substr($originOccupationStr, 2);
        $originOccupation = DB::table('S002V01TOCUP')->where([
            ['OCUP_NULI', '=', $line],
            ['OCUP_AREA', '=', $originOccupationArea],
            ['OCUP_IDOC', '=', $originOccupationID]
        ])->first();

        $validStatus = ["A" => "Adquisición", "S" => "Stock", "T" => "Traslado", "I" => "Instalación", "R" => "Reparación", "D" => "Disposición"];
        $equipment->ESTADO = $validStatus[$equipment->ESTADO] . " (" . $equipment->ESTADO . ")";
        $equipment->OCUPACION_ORIGEN = $originOccupation->OCUP_DESC . " (" . $originOccupationStr . ")";

        $idUserEnc = $this->encryptionController->encrypt($idUser);
        $imagesGalleryArr = json_decode($equipment->GALERIA_IMAGENES);
        $imagesGalleryFn = [];
        foreach($imagesGalleryArr as $imageCode){
            $imageCodeEnc = $this->encryptionController->encrypt($imageCode);
            $publicUri = $this->documentManagementController->getPublicDocumentURL(
                $imageCodeEnc,
                $idUserEnc,
                $line
            );

            $response = json_decode($publicUri->original, true);
            if($response['error']){
                return $this->responseController->makeresponse(true, $response['msg'], [], 500);
            }else{
                $uriEnc = $this->encryptionController->encrypt($response['response']['public_uri']);
                $imagesGalleryFn[] = $uriEnc;
            }
        }

        $documentsArr = json_decode($equipment->DOCUMENTOS);
        $documentsFn = [];
        foreach($documentsArr as $document){
            $codeArr = explode('=',$document);
            $codeArr0 = explode('-', $codeArr[0]);

            $file = DB::table('S002V01TAFAL')->where([
                ['AFAL_NULI', '=', $line],
                ['AFAL_COMO', '=', $codeArr0[1]],
                ['AFAL_CLDO', '=', $codeArr0[2]],
                ['AFAL_FECR', '=', $codeArr0[3]],
                ['AFAL_NUSE', '=', $codeArr0[4]],
                ['AFAL_NUVE', '=', $codeArr[1]],
            ])->first();

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

            $documentsFn[] = [
                'id' => $this->encryptionController->encrypt($document),
                'name' => $document,
                'size' => $file->AFAL_TAMA
            ];
        }

        $equipment->GALERIA_IMAGENES = json_encode($imagesGalleryFn);
        $equipment->DOCUMENTOS = json_encode($documentsFn);

        $provider = DB::table('S002V01TPROV')->where([
            ['PROV_NULI', '=', $line],
            ['PROV_NUPR', '=', $equipment->PROVEEDOR],
        ])->first();
        
        $equipment->PROVEEDOR = $provider->PROV_NOCO . " (" . $equipment->PROVEEDOR . ")";
        $equipment->NUMERO_SERIAL = $this->encryptionController->encrypt($equipment->NUMERO_SERIAL);

        $codesHistory = json_decode($equipment->HISTORIAL_CODIGOS, true);
        $codesHistoryFn = [];
        foreach($codesHistory as $code){
            $codeEnc = $this->encryptionController->encrypt($code);
            $codesHistoryFn[] = $codeEnc;
        }

        $equipment->HISTORIAL_CODIGOS = json_encode($codesHistoryFn);
        $usrReg = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $equipment->USUARIO_REGISTRO]
        ])->first();

        $usrRegName = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
        $equipment->USUARIO_REGISTRO = $usrRegName . " (" . $equipment->USUARIO_REGISTRO . ")";

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

            $usrModName = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA);
            $equipment->USUARIO_MODIFICACION = $usrModName . " (" . $equipment->USUARIO_MODIFICACION . ")";
        }

        $equipment->TIPO_EQUIPAMIENTO = $this->encryptionController->encrypt($equipment->TIPO_EQUIPAMIENTO);
        $equipment->MODELO = $this->encryptionController->encrypt($equipment->MODELO);

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            'S002V01P01MEEQ',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó el equipamiento $code.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $trainOccupationsEnc = file_get_contents($ubic . "train-occupations.sam");
        $trainOccupationsDec = $this->encryptionController->decrypt($trainOccupationsEnc);
        $trainOccupationsArr = json_decode($trainOccupationsDec, true);

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las ocupaciones de tren.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $trainOccupation = $this->encryptionController->decrypt($trainOccupation);
        if(!$trainOccupation){
            return $this->responseController->makeResponse(true, 'La ocupación no fue encriptada correctamente.', [], 400);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $carAreasEnc = file_get_contents($ubic . "car-areas.sam");
        $carAreasDec = $this->encryptionController->decrypt($carAreasEnc);
        $carAreasArr = json_decode($carAreasDec, true);
        $carAreasArrDec = [];

        foreach($carAreasArr as $key=>$val){
            $keyDec = $this->encryptionController->decrypt($key);
            $carAreasArrDec[$keyDec] = $val;
        }

        if(!array_key_exists($trainOccupation, $carAreasArrDec)){
            return $this->responseController->makeResponse(true, "La ocupación $trainOccupation no existe.", [], 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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las áreas de la ocupación $trainOccupation de tren.",
            $idUser,
            $nowStr,
        );

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

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

        $idUser = $this->encryptionController->decrypt($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);
        }

        $ubic = $this->templatesUbic;
        $ubic = str_replace("pdf_templates\\01_05_GEEQ", "global_resources", $ubic);

        $trainElementsEnc = file_get_contents($ubic . "train-elements.sam");
        $trainElementsDec = $this->encryptionController->decrypt($trainElementsEnc);
        $trainElementsArr = json_decode($trainElementsDec, true);

        $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,
            'S002V01M07GEEQ',
            'S002V01F01ADEQ',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los elementos de tren.",
            $idUser,
            $nowStr,
        );

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