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

namespace App\Services;

use App\Http\Resources\ParentPublicResource;
use App\Http\Resources\ParentResource;
use App\Repositories\ParentRepository;

use App\Repositories\UserRepository;
use Exception;

class ParentService
{

    protected $parentRepository;
    protected $userRepository;



    public function __construct(
        ParentRepository $parentRepository,
        UserRepository $userRepository
        )
    {
        $this->parentRepository = $parentRepository;
        $this->userRepository = $userRepository;
    }

    public function list($publicData = false, $periodId = null)
    {
        $registers = $periodId
            ? $this->parentRepository->getAvailableForPeriod($periodId)
            : $this->parentRepository->getAll();

        if ($registers->count() < 1) {
            return [];
        }
        $data = $registers->map(function ($register) use ($publicData) {
            if ($publicData) {
                return new ParentPublicResource($register);
            }
            return new ParentResource($register, true);
        });

        return $data;
    }

    public function store($request)
    {
        $documentType = $request->document_type ?? 'RUT';
        $isPassport = $documentType === 'PASSPORT';

        $identifier = $isPassport ? strUpper($request->rut) : formatterRut($request->rut, false);
        $email = strLower($request->email);

        // Bloquear uso del RUT genérico de Toku
        if (!$isPassport) {
            $tokuConfig = getConfiguration('toku');
            $genericRut = !empty($tokuConfig['generic_rut']) ? formatterRut($tokuConfig['generic_rut'], false) : null;
            if ($genericRut && $identifier === $genericRut) {
                throw new Exception("Este RUT está reservado como RUT genérico de Toku y no puede ser utilizado para registrar apoderados", 409);
            }
        }

        $validateField = $this->parentRepository->getByRut($identifier);
        if ($validateField) {
            $label = $isPassport ? 'Pasaporte' : 'RUT';
            throw new Exception("{$label} de apoderado ya existe en la base de datos", 409);
        }

        $validateUsername = $this->userRepository->getByUsername($email);
        if ($validateUsername) {
            throw new Exception("Correo electrónico ya está asociado a un usuario", 409);
        }

        $request->password = generateSecurePassword();
        $request->activation_token = getToken();
        $register = $this->parentRepository->create((object)$request);
        if (!$register) {
            throw new Exception("Ocurrió un problema al registrar apoderado", 500);
        }

        //TODO: ENVIAR CORREO
        // $mailService = new MailService();
        // $mailService->registerParent((object)$register);

        return null;
    }


    public function update($request, $id)
    {
        $register = $this->show($id, true, true);

        $documentType = $request->document_type ?? $register->document_type ?? 'RUT';
        $isPassport = $documentType === 'PASSPORT';

        $identifier = $isPassport ? strUpper($request->rut) : formatterRut($request->rut, false);
        $email = strLower($request->email);

        // Bloquear uso del RUT genérico de Toku
        if (!$isPassport) {
            $tokuConfig = getConfiguration('toku');
            $genericRut = !empty($tokuConfig['generic_rut']) ? formatterRut($tokuConfig['generic_rut'], false) : null;
            if ($genericRut && $identifier === $genericRut) {
                throw new Exception("Este RUT está reservado como RUT genérico de Toku y no puede ser utilizado para registrar apoderados", 409);
            }
        }

        $validateField = $this->parentRepository->getByRut($identifier, $id);
        if ($validateField) {
            $label = $isPassport ? 'Pasaporte' : 'RUT';
            throw new Exception("{$label} de apoderado ya existe en la base de datos", 409);
        }

        $validateUsername = $this->userRepository->getByUsername($email, $register->user_id);
        if ($validateUsername) {
            throw new Exception("Correo electrónico ya está asociado a un usuario", 409);
        }


        $update = $this->parentRepository->update($register, $request);
        if (!$update) {
            throw new Exception("Ocurrió un problema al actualizar registro", 500);
        }
        return true;
    }

    public function show($id, $allData = true, $allDataEdit = false)
    {
        $register = $this->parentRepository->getById($id);

        if (!$register) {
            throw new Exception("Apoderado no existe o fue eliminado", 400);
        }

        if ($allDataEdit) {
            return $register;
        }
        return (object)(new ParentResource($register, $allData))->resolve();
    }

    /**
     * createOrUpdate masivo para API v1
     */
    public function createOrUpdateBatch(array $parents)
    {
        $results = [];

        foreach ($parents as $parentData) {
            try {
                $result = $this->parentRepository->createOrUpdateByRut((object)$parentData);
                $results[] = [
                    'success' => true,
                    'id' => $result['parent']->id,
                    'key' => $parentData['parent_rut'] ?? $parentData['parent_passport'] ?? '',
                    'operation' => $result['operation'],
                    'errors' => '',
                ];
            }
            catch (Exception $e) {
                $results[] = [
                    'success' => false,
                    'id' => null,
                    'key' => $parentData['parent_rut'] ?? $parentData['parent_passport'] ?? '',
                    'operation' => 'error',
                    'errors' => $e->getMessage(),
                ];
            }
        }

        return $results;
    }

    /**
     * Obtener apoderado por RUT (API v1)
     */
    public function getByRut($rut)
    {
        $formattedRut = formatterRut($rut, false);
        $register = $this->parentRepository->getByRut($formattedRut);

        if (!$register) {
            throw new Exception("Apoderado no encontrado", 404);
        }

        return (object)(new ParentResource($register, true))->resolve();
    }

    public function delete($id)
    {
        $register = $this->show($id, true, true);
        $register->deleted = 1;
        $register->deleted_at = now();
        $register->user_deleted = auth()->user()->id;
        if (!$register->save()) {
            throw new Exception("Ocurrió un problema al eliminar registro", 500);
        }
        return true;
    }
}