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.");
}
}