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/database/seeders/ContractsSeeder.php
<?php

namespace Database\Seeders;

use App\Models\Contract;
use App\Models\ContractFormat;
use App\Models\Parents;
use App\Models\Student;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class ContractsSeeder extends Seeder
{
    public function run(): void
    {
        $contractFormat = ContractFormat::first();
        $parents = Parents::with('user')->get();

        if ($parents->isEmpty()) {
            $this->command->warn('⚠️ No hay apoderados para generar contratos.');
            return;
        }

        $counterContracts = 0;
        $counterDetails = 0;

        foreach ($parents as $index => $parent) {
            $students = Student::where('financial_parent_id', $parent->id)->get();

            if ($students->isEmpty()) {
                $this->command->warn('🔸 Apoderado sin hijos vinculados: ' . $parent->first_name . ' ' . $parent->last_name . ' (' . $parent->rut . ')');
                continue;
            }

            $code = sprintf('CTR-%s-%04d', date('Y'), $parent->id);
            $contract = [
                'code_contract'           => $code,
                'date_contract'           => now()->toDateString(),
                'registration_year'       => now()->year,
                'status_contract_id'      => 1, // En curso
                'status_payment_id'       => 1, // Pendiente de pago
                'status_signature_id'     => 1, // Pendiente de firma
                'total_amount'            => 0,
                'financial_parent_id'     => $parent->id,
                'financial_parent_rut'    => $parent->rut,
                'financial_parent_first_name' => strtoupper($parent->first_name),
                'financial_parent_last_name'  => strtoupper($parent->last_name),
                'financial_parent_email'  => $parent->email,
                'financial_parent_mobile' => $parent->mobile,
                'academic_parent_id'      => $parent->id,
                'academic_parent_rut'     => $parent->rut,
                'academic_parent_first_name' => strtoupper($parent->first_name),
                'academic_parent_last_name'  => strtoupper($parent->last_name),
                'academic_parent_email'   => $parent->email,
                'academic_parent_mobile'  => $parent->mobile,
                'parent_identical'        => true,
                'contract_format_id'      => $contractFormat->id,
                'contract_format_data'    => $contractFormat->description,
                'observation'             => 'Contrato generado automáticamente para pruebas.',
                'file_code'               => null,
                'file_data'               => null,
                'period_id'               => 2,
                'created_at'              => now(),
                'updated_at'              => now(),
            ];

            // Crear o actualizar contrato
            DB::table('contracts')->updateOrInsert(['code_contract' => $code], $contract);
            $contractData = Contract::where('code_contract', $code)->first();
            $counterContracts++;

            $details = [];
            $total = 0;
            $familyConceptsAssigned = [];

            foreach ($students as $student) {
                // === COLEGIATURA (por curso) ===
                $tuition = DB::table('payment_concept_detail_courses as pcdc')
                    ->join('payment_concept_details as pcd', 'pcd.id', '=', 'pcdc.payment_concept_detail_id')
                    ->where('pcdc.course_id', $student->course_id)
                    ->select('pcd.id', 'pcd.price_regular', 'pcd.family_payment', 'pcd.code_toku', 'pcd.description')
                    ->first();

                if ($tuition) {
                    $details[] = [
                        'contract_id' => $contractData->id,
                        'student_id' => $student->id,
                        'payment_concept_detail_id' => $tuition->id,
                        'amount' => $tuition->price_regular,
                        'paid' => 0,
                        'student_religion_classes' => $student->student_religion_classes ?? 0,
                        'student_religion_program' => $student->student_religion_program ?? 0,
                        'student_create_institutional_mail' => $student->student_create_institutional_mail ?? 0,
                        'code_toku' => (!empty($tuition->code_toku) ? $tuition->code_toku . '_' : '') .
                            str_replace('-', '', strtolower($student->rut)),
                        'enrollment_period_id' => 1,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ];
                    $total += $tuition->price_regular;
                } else {
                    $this->command->warn("⚠️ No se encontró concepto de colegiatura para el curso ID {$student->course_id}");
                }

                // === OTROS CONCEPTOS FIJOS ===
                $conceptsFixed = DB::table('payment_concept_details')
                    ->whereNotIn('payment_concept_id', [2]) // Excluye colegiatura
                    ->get();

                foreach ($conceptsFixed as $concept) {
                    $isFamilyConcept = isset($concept->family_payment) && $concept->family_payment == 1;

                    if ($isFamilyConcept && in_array($concept->id, $familyConceptsAssigned)) {
                        continue;
                    }

                    $details[] = [
                        'contract_id' => $contractData->id,
                        'student_id' => $student->id,
                        'payment_concept_detail_id' => $concept->id,
                        'amount' => $concept->price_regular,
                        'paid' => 0,
                        'student_religion_classes' => $student->student_religion_classes ?? 0,
                        'student_religion_program' => $student->student_religion_program ?? 0,
                        'student_create_institutional_mail' => $student->student_create_institutional_mail ?? 0,
                        'code_toku' => (!empty($concept->code_toku) ? $concept->code_toku . '_' : '') .
                            str_replace('-', '', strtolower(
                                ($concept->family_payment == 1 ? $parent->rut : $student->rut)
                            )),
                        'enrollment_period_id' => 1,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ];
                    $total += $concept->price_regular;

                    if ($isFamilyConcept) {
                        $familyConceptsAssigned[] = $concept->id;
                    }
                }
            }

            // Insertar detalles
            foreach ($details as $detail) {
                DB::table('contracts_detail')->insert($detail);
                $counterDetails++;
            }

            // Actualizar total
            DB::table('contracts')
                ->where('id', $contractData->id)
                ->update(['total_amount' => $total]);
        }

        $this->command->info("✅ Generados {$counterContracts} contratos con {$counterDetails} detalles en total.");
    }
}