- Nueva tabla isr_tables y isr_brackets en BD - Controlador IsrController para CRUD de tablas ISR - Integración con pestaña ISR en settings - Soporte para importación via CSV - Captura manual de brackets
169 lines
7.6 KiB
PHP
169 lines
7.6 KiB
PHP
<div class="row">
|
|
<div class="col-12">
|
|
<h4 class="mb-3">
|
|
<i class="bi bi-calculator text-primary"></i> Tablas ISR
|
|
</h4>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Lista de Tablas ISR -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-primary text-white">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h6 class="mb-0">
|
|
<i class="bi bi-table"></i> Tablas ISR Existentes
|
|
</h6>
|
|
<span class="badge bg-light text-dark">{{ $isrTables->count() }} tabla(s)</span>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
@if($isrTables->isEmpty())
|
|
<div class="alert alert-info mb-0">
|
|
<i class="bi bi-info-circle"></i> No hay tablas ISR configuradas. Crea una nueva tabla para comenzar.
|
|
</div>
|
|
@else
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Año</th>
|
|
<th>Brackets</th>
|
|
<th>Última Actualización</th>
|
|
<th class="text-center">Acciones</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($isrTables as $table)
|
|
<tr>
|
|
<td>
|
|
<span class="badge bg-primary fs-6">{{ $table->year }}</span>
|
|
</td>
|
|
<td>
|
|
<span class="text-muted">{{ $table->brackets->count() }} rango(s)</span>
|
|
</td>
|
|
<td>
|
|
<small class="text-muted">
|
|
@if($table->brackets->isNotEmpty())
|
|
{{ $table->brackets->max('updated_at')->format('d/m/Y H:i') }}
|
|
@else
|
|
<em>Sin datos</em>
|
|
@endif
|
|
</small>
|
|
</td>
|
|
<td class="text-center">
|
|
<div class="btn-group btn-group-sm" role="group">
|
|
<a href="{{ route('settings.isr.edit', $table) }}" class="btn btn-primary" title="Editar">
|
|
<i class="bi bi-pencil"></i> Editar
|
|
</a>
|
|
<form method="POST" action="{{ route('settings.isr.destroy', $table) }}" class="d-inline" onsubmit="return confirm('¿Estás seguro de eliminar la tabla ISR {{ $table->year }}?')">
|
|
@csrf
|
|
@method('DELETE')
|
|
<button type="submit" class="btn btn-danger" title="Eliminar">
|
|
<i class="bi bi-trash"></i> Eliminar
|
|
</button>
|
|
</form>
|
|
<button type="button" class="btn btn-success" onclick="showUploadModal({{ $table->id }}, {{ $table->year }})" title="Subir CSV">
|
|
<i class="bi bi-upload"></i> Subir CSV
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Crear Nueva Tabla ISR -->
|
|
<div class="card">
|
|
<div class="card-header bg-success text-white">
|
|
<h6 class="mb-0">
|
|
<i class="bi bi-plus-circle"></i> Nueva Tabla ISR
|
|
</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="POST" action="{{ route('settings.isr.store') }}">
|
|
@csrf
|
|
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="year" class="form-label">Año</label>
|
|
<input type="number" class="form-control @error('year') is-invalid @enderror"
|
|
id="isr_year" name="year"
|
|
value="{{ old('year', now()->year) }}"
|
|
min="2000" max="2100"
|
|
placeholder="Ej: 2026" required>
|
|
@error('year')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
<small class="text-muted">Año para el cual aplica la tabla de ISR</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 d-flex align-items-end">
|
|
<div class="mb-3">
|
|
<button type="submit" class="btn btn-success">
|
|
<i class="bi bi-plus-circle"></i> Nueva Tabla ISR
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Subir CSV -->
|
|
<div class="modal fade" id="uploadCsvModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-success text-white">
|
|
<h5 class="modal-title">
|
|
<i class="bi bi-upload"></i> Subir CSV - Año <span id="modalYear"></span>
|
|
</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Cerrar"></button>
|
|
</div>
|
|
<form method="POST" id="uploadCsvForm" enctype="multipart/form-data">
|
|
@csrf
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label for="csv_file" class="form-label">Archivo CSV</label>
|
|
<input type="file" class="form-control @error('csv_file') is-invalid @enderror"
|
|
id="csv_file" name="csv_file"
|
|
accept=".csv,.txt" required>
|
|
@error('csv_file')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
<small class="text-muted">
|
|
Formato esperado: Límite Inferior, Límite Superior, Cuota Fija, Tasa (%)<br>
|
|
La primera línea puede contener encabezados (se ignorará).
|
|
</small>
|
|
</div>
|
|
<div class="alert alert-info mb-0">
|
|
<i class="bi bi-info-circle"></i>
|
|
<strong>Nota:</strong> Si la tabla ya tiene datos, estos serán reemplazados por el contenido del CSV.
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
|
<button type="submit" class="btn btn-success">
|
|
<i class="bi bi-upload"></i> Importar
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@push('scripts')
|
|
<script>
|
|
function showUploadModal(tableId, year) {
|
|
document.getElementById('modalYear').textContent = year;
|
|
document.getElementById('uploadCsvForm').action = '/settings/isr/' + tableId + '/upload';
|
|
|
|
var modal = new bootstrap.Modal(document.getElementById('uploadCsvModal'));
|
|
modal.show();
|
|
}
|
|
</script>
|
|
@endpush |