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/Repositories/PeriodRepository.php
<?php

namespace App\Repositories;

use App\Models\Period;
use App\Models\EnrollmentPeriod;
use App\Models\Parents;
use App\Models\Student;
use Exception;
use Illuminate\Support\Facades\DB;

class PeriodRepository
{
    public function getAll($onlyActive = false)
    {
        $query = Period::where('deleted', false)->with('enrollmentPeriods');
        if ($onlyActive) {
            $query->where('status', true);
        }
        return $query->orderBy('period_year', 'desc')->get();
    }

    public function getById($id)
    {
        $register = Period::with('enrollmentPeriods')->find($id);
        if (!$register) {
            throw new Exception("Periodo no existe o fue eliminado", 404);
        }
        return $register;
    }

    public function getByYear($year, $id = null)
    {
        $query = Period::where('period_year', $year);
        if ($id > 0) {
            $query->where('id', '!=', $id);
        }
        return $query->first() ?: false;
    }

    public function create($data)
    {
        return DB::transaction(function () use ($data) {
            $period = Period::create([
                'period_year'  => $data->period_year,
                'period'       => $data->period,
                'start_date'   => $data->start_date,
                'end_date'     => $data->end_date,
                'status'       => $data->status == 0 ? false : true,
                'created_at'   => now(),
                'user_created' => auth()->id(),
            ]);

            if (!empty($data->segments)) {
                foreach ($data->segments as $seg) {
                    EnrollmentPeriod::create([
                        'period_id'    => $period->id,
                        'description'  => $seg['description'],
                        'start_date'   => $seg['start_date'],
                        'end_date'     => $seg['end_date'],
                        'status'       => $seg['status'] ?? 1,
                        'created_at'   => now(),
                        'user_created' => auth()->id(),
                    ]);
                }
            }

            return $period->load('enrollmentPeriods');
        });
    }

    public function update($register, $data)
    {
        return DB::transaction(function () use ($register, $data) {
            // Actualizar solo los campos del periodo que vienen en la request
            if ($data->has('period_year')) $register->period_year = $data->period_year;
            if ($data->has('period'))      $register->period      = $data->period;
            if ($data->has('start_date'))  $register->start_date  = $data->start_date;
            if ($data->has('end_date'))    $register->end_date    = $data->end_date;
            if ($data->has('status'))      $register->status      = $data->status == 0 ? false : true;
            $register->updated_at   = now();
            $register->user_updated = auth()->id();
            $register->save();

            // Procesar segmentos
            $segmentIds = [];
            if (!empty($data->segments)) {
                foreach ($data->segments as $seg) {
                    if (!empty($seg['id'])) {
                        // Actualizar segmento existente
                        $segment = EnrollmentPeriod::where('id', $seg['id'])
                            ->where('period_id', $register->id)
                            ->first();

                        if ($segment) {
                            $segment->description  = $seg['description'];
                            $segment->start_date   = $seg['start_date'];
                            $segment->end_date     = $seg['end_date'];
                            $segment->status       = $seg['status'] ?? 1;
                            $segment->updated_at   = now();
                            $segment->user_updated = auth()->id();
                            $segment->save();
                            $segmentIds[] = $segment->id;
                        }
                    } else {
                        // Crear nuevo segmento
                        $newSeg = EnrollmentPeriod::create([
                            'period_id'    => $register->id,
                            'description'  => $seg['description'],
                            'start_date'   => $seg['start_date'],
                            'end_date'     => $seg['end_date'],
                            'status'       => $seg['status'] ?? 1,
                            'created_at'   => now(),
                            'user_created' => auth()->id(),
                        ]);
                        $segmentIds[] = $newSeg->id;
                    }
                }
            }

            // Marcar como eliminados los segmentos que ya no vienen en la request
            EnrollmentPeriod::where('period_id', $register->id)
                ->whereNotIn('id', $segmentIds)
                ->update([
                    'deleted'      => 1,
                    'deleted_at'   => now(),
                    'user_deleted' => auth()->id(),
                ]);

            return $register->load('enrollmentPeriods');
        });
    }


    public function activate($id)
    {
        return DB::transaction(function () use ($id) {
            $period = $this->getById($id);

            if ($period->status) {
                throw new Exception("El periodo seleccionado ya está activo", 400);
            }

            $period->status = 1;
            $period->updated_at = now();
            $period->user_updated = auth()->id();
            $period->save();

            return $period;
        });
    }

    public function deactivate($id)
    {
        return DB::transaction(function () use ($id) {
            $period = $this->getById($id);

            if (!$period->status) {
                throw new Exception("El periodo seleccionado ya está inactivo", 400);
            }

            $period->status = 0;
            $period->updated_at = now();
            $period->user_updated = auth()->id();
            $period->save();

            return $period;
        });
    }

    public function getActive()
    {
        $register = Period::with('enrollmentPeriods')->where('status', true)->where('deleted', false)
            ->orderBy('period_year', 'desc')->first();
        return $register;
    }

    public function getPeriodsForParent($parentId)
    {
        return Period::whereIn('id', function ($query) use ($parentId) {
                $query->select('period_id')
                    ->from('contracts')
                    ->where('financial_parent_id', $parentId)
                    ->distinct();
            })
            ->where('deleted', false)
            ->orderBy('period_year', 'desc')
            ->get();
    }
}