File: /var/www/matriculas_api_dev/app/Models/ExcelUploadLine.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class ExcelUploadLine extends Model
{
protected $table = 'excel_upload_lines';
protected $fillable = [
'upload_id',
'line_number',
'status',
'data',
'original_data',
'error_message',
'warning_message',
'editable',
'edited',
'edited_by',
'edited_at',
'related_id',
'related_type',
];
protected $casts = [
'data' => 'array',
'original_data' => 'array',
'editable' => 'boolean',
'edited' => 'boolean',
'edited_at' => 'datetime',
];
/**
* Relación con el upload principal
*/
public function upload(): BelongsTo
{
return $this->belongsTo(ExcelUpload::class, 'upload_id');
}
/**
* Usuario que editó la línea
*/
public function editedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'edited_by');
}
/**
* Relación polimórfica con el registro relacionado
* (Parent, Student, Teacher, etc.)
*/
public function related(): MorphTo
{
return $this->morphTo('related');
}
/**
* Scope para obtener solo líneas con éxito
*/
public function scopeSuccess($query)
{
return $query->where('status', 'SUCCESS');
}
/**
* Scope para obtener solo líneas con error
*/
public function scopeError($query)
{
return $query->where('status', 'ERROR');
}
/**
* Scope para obtener solo líneas con advertencia
*/
public function scopeWarning($query)
{
return $query->where('status', 'WARNING');
}
/**
* Scope para obtener solo líneas editables
*/
public function scopeEditable($query)
{
return $query->where('editable', true);
}
/**
* Scope para obtener solo líneas editadas
*/
public function scopeEdited($query)
{
return $query->where('edited', true);
}
/**
* Verificar si la línea tiene errores
*/
public function hasError(): bool
{
return $this->status === 'ERROR' && !empty($this->error_message);
}
/**
* Verificar si la línea tiene advertencias
*/
public function hasWarning(): bool
{
return $this->status === 'WARNING' && !empty($this->warning_message);
}
/**
* Marcar línea como editada
*/
public function markAsEdited(int $userId): void
{
$this->update([
'edited' => true,
'edited_by' => $userId,
'edited_at' => now(),
]);
}
/**
* Actualizar datos de la línea
*/
public function updateData(array $newData, int $userId): void
{
// Guardar datos originales si no existen
if (empty($this->original_data)) {
$this->original_data = $this->data;
}
$this->update([
'data' => $newData,
'edited' => true,
'edited_by' => $userId,
'edited_at' => now(),
]);
}
/**
* Cambiar estado de la línea
*/
public function changeStatus(string $status, ?string $message = null): void
{
$updates = ['status' => $status];
if ($status === 'ERROR') {
$updates['error_message'] = $message;
$updates['warning_message'] = null;
} elseif ($status === 'WARNING') {
$updates['warning_message'] = $message;
$updates['error_message'] = null;
} else {
$updates['error_message'] = null;
$updates['warning_message'] = null;
}
$this->update($updates);
}
/**
* Vincular con un registro creado/actualizado
*/
public function linkToRecord(Model $model): void
{
$this->update([
'related_id' => $model->id,
'related_type' => get_class($model),
]);
}
/**
* Obtener valor de un campo específico del data
*/
public function getDataValue(string $key, $default = null)
{
return $this->data[$key] ?? $default;
}
/**
* Verificar si tiene cambios respecto al original (renombrado para evitar conflicto)
*/
public function hasDataChanges(): bool
{
if (empty($this->original_data)) {
return false;
}
return $this->data !== $this->original_data;
}
/**
* Obtener diferencias entre datos originales y actuales
*/
public function getDataDifferences(): array
{
if (empty($this->original_data)) {
return [];
}
$differences = [];
foreach ($this->data as $key => $value) {
$originalValue = $this->original_data[$key] ?? null;
if ($value !== $originalValue) {
$differences[$key] = [
'original' => $originalValue,
'current' => $value,
];
}
}
return $differences;
}
/**
* Restaurar datos originales
*/
public function restoreOriginalData(): void
{
if (!empty($this->original_data)) {
$this->update([
'data' => $this->original_data,
'edited' => false,
'edited_by' => null,
'edited_at' => null,
]);
}
}
/**
* Verificar si la línea fue modificada desde su creación
*/
public function wasEdited(): bool
{
return $this->edited && !empty($this->edited_at);
}
}