File: /var/www/matriculas_api_dev/app/Repositories/ParentRepository.php
<?php
namespace App\Repositories;
use App\Models\Parents;
use App\Models\Profile;
use App\Models\User;
use Exception;
use Illuminate\Support\Facades\DB;
class ParentRepository
{
public function getByCodeToku($code_toku, $id = null)
{
$query = Parents::where('code_toku', $code_toku)->where('deleted', false);
if ($id > 0) {
$query->where('id', '!=', $id);
}
$register = $query->first();
if (!$register) {
return false;
}
return $register;
}
public function getByRut($rut, $id = null)
{
$query = Parents::where('rut', $rut)->where('deleted', false);
if ($id > 0) {
$query->where('id', '!=', $id);
}
$register = $query->first();
if (!$register) {
return false;
}
return $register;
}
public function getProfile()
{
$profileData = Profile::where('code', 'parent')->first();
if (!$profileData) {
throw new Exception("Perfil de apoderado no existe o fue eliminado", 404);
}
return $profileData->id;
}
public function getAll()
{
$registers = Parents::where('deleted', false);
return $registers->orderBy('first_name', 'asc')->get();
}
/**
* Obtener apoderados disponibles para crear matrÃcula en un periodo.
* Solo retorna apoderados que tengan al menos un estudiante:
* 1. Habilitado en student_period para ese periodo
* 2. Que NO tenga ya un contrato para ese periodo
*/
public function getAvailableForPeriod($periodId)
{
return Parents::where('deleted', false)
->whereExists(function ($query) use ($periodId) {
$query->select(DB::raw(1))
->from('students')
->whereColumn('students.financial_parent_id', 'parents.id')
->where('students.deleted', false)
->where('students.status', true)
// Estudiante debe estar en student_period para este periodo
->whereExists(function ($spQuery) use ($periodId) {
$spQuery->select(DB::raw(1))
->from('student_period')
->whereColumn('student_period.student_id', 'students.id')
->where('student_period.period_id', $periodId);
})
// Estudiante NO debe tener contrato para este periodo
->whereNotExists(function ($cdQuery) use ($periodId) {
$cdQuery->select(DB::raw(1))
->from('contracts_detail')
->join('contracts', 'contracts.id', '=', 'contracts_detail.contract_id')
->whereColumn('contracts_detail.student_id', 'students.id')
->where('contracts.period_id', $periodId);
});
})
->orderBy('first_name', 'asc')
->get();
}
public function getById($id, $validateProfile = true)
{
$profileId = $this->getProfile();
$query = Parents::whereHas('user', function ($q) use ($profileId, $validateProfile) {
if ($validateProfile) {
$q->where('profile_id', '=', $profileId);
}
$q->where('deleted', false);
})->where('deleted', false)->where('id', $id);
$register = $query->first();
if (!$register) {
throw new Exception("Apoderado no existe o fue eliminado", 404);
}
return $register;
}
public function create($data)
{
$profileId = $this->getProfile();
$documentType = $data->document_type ?? 'RUT';
$isPassport = $documentType === 'PASSPORT';
// Determinar identificador
if ($isPassport) {
$identifier = !empty($data->rut) ? strUpper($data->rut) : null;
} else {
$identifier = !empty($data->rut) ? formatterRut($data->rut, false) : null;
}
// Crear usuario
$password = bcrypt($data->password);
$createUserData = [
'name' => strUpper($data->first_name . ' ' . $data->last_name),
'username' => $identifier ?: strLower($data->email),
'rut' => $identifier,
'email' => strLower($data->email),
'password' => $password,
'activation_token' => ($data->activation_token && !empty($data->activation_token)) ? ($data->activation_token) : null,
'account_confirmed' => $data->account_confirmed ?? false,
'account_confirmed_at' => $data->account_confirmed_at ?? null,
'status' => true,
'profile_id' => $profileId,
'created_at' => now(),
'updated_at' => now(),
];
if (auth()->check()) {
$createUserData['user_created'] = auth()->user()->id;
$createUserData['user_updated'] = auth()->user()->id;
}
$user = User::create($createUserData);
if (!$user) {
throw new Exception("Ocurrió un error al crear usuario para apoderado", 500);
}
// Crear registro en parents
$createParentData = [
'relationship_id' => $data->relationship ?? null,
'document_type' => $documentType,
'rut' => $identifier,
'first_name' => strUpper($data->first_name),
'second_name' => $data->second_name ? strUpper($data->second_name) : null,
'last_name' => strUpper($data->last_name),
'second_last_name' => $data->second_last_name ? strUpper($data->second_last_name) : null,
'email' => strLower($data->email),
'mobile' => $data->mobile ?? null,
'home_phone' => $data->home_phone ?? null,
'work_phone' => $data->work_phone ?? null,
'birth_date' => $data->birth_date ?? null,
'gender_id' => $data->gender ?? null,
'country_id' => $data->country ?? null,
'region_id' => $data->region ?? null,
'commune_id' => $data->commune ?? null,
'address' => $data->address ?? null,
'profession' => $data->profession ?? null,
'status' => true,
'user_id' => $user->id,
'created_at' => now(),
'updated_at' => now(),
];
if (auth()->check()) {
$createParentData['user_created'] = auth()->user()->id;
$createParentData['user_updated'] = auth()->user()->id;
}
$parent = Parents::create($createParentData);
return $parent;
}
/**
* createOrUpdate para API v1 (clave: parent_rut o passport)
*/
public function createOrUpdateByRut($data)
{
$documentType = $data->document_type ?? 'RUT';
$isPassport = $documentType === 'PASSPORT';
if ($isPassport) {
$identifier = strUpper($data->parent_rut);
} else {
$identifier = formatterRut($data->parent_rut, false);
}
$existing = $this->getByRut($identifier);
if ($existing) {
// Update existing parent
if (!empty($data->first_name)) $existing->first_name = strUpper($data->first_name);
if (!empty($data->second_name)) $existing->second_name = strUpper($data->second_name);
if (!empty($data->last_name)) $existing->last_name = strUpper($data->last_name);
if (!empty($data->second_last_name)) $existing->second_last_name = strUpper($data->second_last_name);
if (!empty($data->email)) $existing->email = strLower($data->email);
if (!empty($data->mobile)) $existing->mobile = $data->mobile;
if (!empty($data->birth_date)) $existing->birth_date = $data->birth_date;
if (!empty($data->address)) $existing->address = $data->address;
if (isset($data->family_relationship_id)) $existing->relationship_id = $data->family_relationship_id;
if (!empty($data->external_id)) $existing->external_id = $data->external_id;
$existing->document_type = $documentType;
$existing->updated_at = now();
$existing->save();
// Update associated user email/name
if ($existing->user_id) {
$user = User::find($existing->user_id);
if ($user) {
$user->name = strUpper($existing->first_name . ' ' . $existing->last_name);
if (!empty($data->email)) {
$user->email = strLower($data->email);
}
$user->updated_at = now();
$user->save();
}
}
return ['operation' => 'update', 'parent' => $existing];
}
// Create new parent with user
$profileId = $this->getProfile();
$email = strLower($data->email ?? '');
$password = bcrypt('1234');
$activationToken = getToken();
$user = User::create([
'name' => strUpper(($data->first_name ?? '') . ' ' . ($data->last_name ?? '')),
'username' => $identifier ?: $email,
'rut' => $identifier,
'email' => $email,
'password' => $password,
'activation_token' => $activationToken,
'account_confirmed' => false,
'status' => true,
'profile_id' => $profileId,
'created_at' => now(),
'updated_at' => now(),
]);
$parent = Parents::create([
'external_id' => $data->external_id ?? null,
'relationship_id' => $data->family_relationship_id ?? null,
'document_type' => $documentType,
'rut' => $identifier,
'first_name' => strUpper($data->first_name ?? ''),
'second_name' => !empty($data->second_name) ? strUpper($data->second_name) : null,
'last_name' => strUpper($data->last_name ?? ''),
'second_last_name' => !empty($data->second_last_name) ? strUpper($data->second_last_name) : null,
'email' => $email,
'mobile' => $data->mobile ?? null,
'birth_date' => $data->birth_date ?? null,
'address' => $data->address ?? null,
'status' => true,
'user_id' => $user->id,
'created_at' => now(),
'updated_at' => now(),
]);
return ['operation' => 'create', 'parent' => $parent];
}
public function update($registerData, $data)
{
$userId = $registerData->user_id;
$documentType = $data->document_type ?? $registerData->document_type ?? 'RUT';
$isPassport = $documentType === 'PASSPORT';
// Determinar identificador
if (!empty($data->rut)) {
$identifier = $isPassport ? strUpper($data->rut) : formatterRut($data->rut, false);
} else {
$identifier = $registerData->rut;
}
// Actualizar datos de parent
$registerData->relationship_id = $data->relationship ?? $registerData->relationship_id;
$registerData->document_type = $documentType;
$registerData->rut = $identifier;
$registerData->first_name = strUpper($data->first_name ?? $registerData->first_name);
$registerData->second_name = $data->second_name ? strUpper($data->second_name) : $registerData->second_name;
$registerData->last_name = strUpper($data->last_name ?? $registerData->last_name);
$registerData->second_last_name = $data->second_last_name ? strUpper($data->second_last_name) : $registerData->second_last_name;
$registerData->email = strLower($data->email ?? $registerData->email);
$registerData->mobile = $data->mobile ?? $registerData->mobile;
$registerData->home_phone = $data->home_phone ?? $registerData->home_phone;
$registerData->work_phone = $data->work_phone ?? $registerData->work_phone;
$registerData->birth_date = $data->birth_date ?? $registerData->birth_date;
$registerData->gender_id = $data->gender ?? $registerData->gender_id;
$registerData->country_id = $data->country ?? $registerData->country_id;
$registerData->region_id = $data->region ?? $registerData->region_id;
$registerData->commune_id = $data->commune ?? $registerData->commune_id;
$registerData->address = $data->address ?? $registerData->address;
$registerData->profession = $data->profession ?? $registerData->profession;
$registerData->status = $data->status == 1 ? true : false;
$registerData->user_updated = auth()->check() ? auth()->user()->id : $registerData->user_updated;
$registerData->updated_at = now();
if ($registerData->save()) {
// Actualizar usuario asociado
$userData = User::find($userId);
if ($userData) {
$userData->name = strUpper($data->first_name . ' ' . $data->last_name);
$userData->email = strLower($data->email ?? $userData->email);
$userData->rut = $identifier;
$userData->status = $data->status == 1 ? true : false;
$userData->updated_at = now();
if (auth()->check()) {
$userData->user_updated = auth()->user()->id;
}
$userData->save();
}
}
return true;
}
}