File: /var/www/api_matriculas/app/Services/PostulationService.php
<?php
namespace App\Services;
use App\Repositories\PeriodRepository;
use App\Repositories\PostulationRepository;
use App\Repositories\StudentRepository;
use Exception;
class PostulationService
{
protected $postulationRepository;
public function __construct(PostulationRepository $postulationRepository)
{
$this->postulationRepository = $postulationRepository;
}
public function list($periodId = null, $userCreated = null, $limit = null)
{
$registers = $this->postulationRepository->getAll($periodId, $userCreated, $limit);
if ($registers->count() < 1) return [];
return $registers->map(fn($r) => $this->mapperData($r, true));
}
public function listByRut($rut)
{
$registers = $this->postulationRepository->getByRut($rut, true);
if ($registers->count() < 1) return [];
return $registers->map(fn($r) => $this->mapperData($r, true));
}
public function store($request)
{
$this->validatePeriod();
$studentRut = formatterRut($request->student_rut, false);
if ($this->postulationRepository->getByRut($studentRut, false)) {
throw new Exception("Ya existe una postulación asociada al RUT del estudiante.", 409);
}
$studentRepository = new StudentRepository();
if ($studentRepository->getByRut($studentRut)) {
throw new Exception("El RUT del alumno ya corresponde a un estudiante del colegio.", 409);
}
$register = $this->postulationRepository->create((object)$request);
if (!$register) {
throw new Exception("Ha ocurrido un error al crear la postulación.", 500);
}
return null;
}
public function update($request, $id)
{
$this->validatePeriod();
$register = $this->show($id, true, true);
$studentRut = formatterRut($request->student_rut, false);
if ($this->postulationRepository->getByRut($studentRut, false, $id)) {
throw new Exception("Ya existe una postulación asociada al RUT del estudiante.", 409);
}
$studentRepository = new StudentRepository();
if ($studentRepository->getByRut($studentRut)) {
throw new Exception("El RUT del alumno ya corresponde a un estudiante del colegio.", 409);
}
$update = $this->postulationRepository->update($register, $request);
if (!$update) {
throw new Exception("Ha ocurrido un error al actualizar la postulación.", 500);
}
return true;
}
public function show($id, $allData = true, $editMode = false)
{
$register = $this->postulationRepository->getById($id);
if (!$register) throw new Exception("Postulación no existe o fue eliminada", 404);
if ($editMode) return $register;
return (object) $this->mapperData($register, $allData);
}
public function delete($id)
{
$register = $this->show($id, true, true);
$register->deleted = true;
$register->deleted_at = now();
$register->user_deleted = auth()->id();
if (!$register->save()) {
throw new Exception("Ha ocurrido un error al eliminar la postulación.", 500);
}
return true;
}
// ----------------- PRIVATE ----------------- //
private function mapperData($data, $allData = true)
{
$studentFullName = trim("{$data->student_first_name} {$data->student_second_name} {$data->student_last_name} {$data->student_second_last_name}");
$parentFullName = trim("{$data->parent_first_name} {$data->parent_second_name} {$data->parent_last_name} {$data->parent_second_last_name}");
$mapped = [
'id' => $data->id,
'code_postulation' => $data->code_postulation,
'period' => !empty($data->period) ? [
'period_year' => $data->period->period_year,
'description' => $data->period->period,
] : null,
'status_postulation' => [
'description' => $data->statusPostulation->description,
'code' => $data->statusPostulation->code,
'background' => $data->statusPostulation->background,
],
// === Estudiante extendido ===
'student' => [
'first_name' => $data->student_first_name,
'second_name' => $data->student_second_name ?? '',
'last_name' => $data->student_last_name,
'second_last_name' => $data->student_second_last_name ?? '',
'full_name' => $studentFullName,
'rut' => $data->student_rut,
'email' => $data->student_email,
'mobile' => $data->student_mobile,
'address' => $data->student_address,
// === Relaciones extendidas del estudiante ===
'gender' => $data->student_gender_id > 0 ? [
'id' => $data->studentGender->id,
'name' => $data->studentGender->gender,
] : null,
'country' => $data->student_country_id > 0 ? [
'id' => $data->studentCountry->id,
'name' => $data->studentCountry->country,
] : null,
'region' => $data->student_region_id > 0 ? [
'id' => $data->studentRegion->id,
'region' => $data->studentRegion->region,
'long_name' => $data->studentRegion->long_name ?? null,
] : null,
'commune' => $data->student_commune_id > 0 ? [
'id' => $data->studentCommune->id,
'commune' => $data->studentCommune->commune,
] : null,
],
// === Curso ===
'course' => $data->course_id > 0 ? [
'id' => $data->course->id,
'name' => $data->course->course,
] : null,
// === Apoderado extendido ===
'parent' => [
'first_name' => $data->parent_first_name,
'second_name' => $data->parent_second_name ?? '',
'last_name' => $data->parent_last_name,
'second_last_name' => $data->parent_second_last_name ?? '',
'full_name' => $parentFullName,
'email' => $data->parent_email,
'mobile' => $data->parent_mobile,
'profession' => $data->parent_profession,
'address' => $data->parent_address,
'relationship' => $data->parent_relationship_id > 0 ? [
'id' => $data->parentRelationship->id,
'name' => $data->parentRelationship->relationship,
] : null,
'gender' => $data->parent_gender_id > 0 ? [
'id' => $data->parentGender->id,
'name' => $data->parentGender->gender,
] : null,
'country' => $data->parent_country_id > 0 ? [
'id' => $data->parentCountry->id,
'name' => $data->parentCountry->country,
] : null,
'region' => $data->parent_region_id > 0 ? [
'id' => $data->parentRegion->id,
'region' => $data->parentRegion->region,
'long_name' => $data->parentRegion->long_name ?? null,
] : null,
'commune' => $data->parent_commune_id > 0 ? [
'id' => $data->parentCommune->id,
'commune' => $data->parentCommune->commune,
] : null,
],
// === Información académica / adicional ===
'previous_school' => $data->previous_school,
'special_needs' => $data->special_needs,
'siblings' => $data->siblings,
'date_entry' => $data->date_entry,
];
if ($allData) {
$mapped['created_at'] = sort_datetimeHuman($data->created_at);
$mapped['updated_at'] = sort_datetimeHuman($data->updated_at);
$mapped['user_created'] = $data->createdBy->username ?? null;
$mapped['user_updated'] = $data->updatedBy->username ?? null;
}
return $mapped;
}
private function validatePeriod()
{
$periodRepository = new PeriodRepository();
$periodActive = $periodRepository->getActive();
if (empty($periodActive)) {
throw new Exception("Actualmente no hay períodos de matrícula disponibles para realizar una postulación.");
}
if ($periodActive->finished) {
throw new Exception("La postulación no puede ser editada porque el período de matrícula ya finalizó.");
}
return true;
}
}