183 lines
9.4 KiB
Plaintext
183 lines
9.4 KiB
Plaintext
@model foundation_system.Models.ViewModels.AsistenciaGridViewModel
|
|
@{
|
|
Layout = null;
|
|
ViewData["Title"] = "Reporte Individual de Asistencia";
|
|
var nino = Model.Expedientes.First();
|
|
|
|
var diasSeleccionadosList = new List<string>();
|
|
if (!string.IsNullOrEmpty(Model.DiasSemanaSeleccionados))
|
|
{
|
|
diasSeleccionadosList = Model.DiasSemanaSeleccionados
|
|
.Split(',', StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(d => d.Trim())
|
|
.ToList();
|
|
}
|
|
|
|
var diasAMostrar = Model.DiasDelMes
|
|
.Where(d => diasSeleccionadosList.Count == 0 ||
|
|
diasSeleccionadosList.Contains(((int)d.DayOfWeek).ToString()))
|
|
.ToList();
|
|
}
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>@ViewData["Title"]</title>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" />
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css" />
|
|
<style>
|
|
@@media print {
|
|
.no-print { display: none !important; }
|
|
body { padding: 0; margin: 0; }
|
|
.container { width: 100%; max-width: none; padding: 0; }
|
|
@@page { size: portrait; margin: 1.5cm; }
|
|
}
|
|
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: white; color: #333; }
|
|
.report-header { border-bottom: 3px solid #2c3e50; margin-bottom: 30px; padding-bottom: 15px; }
|
|
.foundation-name { font-size: 28px; font-weight: bold; color: #2c3e50; }
|
|
.report-title { font-size: 20px; color: #7f8c8d; text-transform: uppercase; letter-spacing: 1px; }
|
|
.info-card { background-color: #f8f9fa; border: 1px solid #dee2e6; border-radius: 8px; padding: 20px; margin-bottom: 30px; }
|
|
.info-label { font-weight: bold; color: #2c3e50; width: 150px; display: inline-block; }
|
|
.attendance-table { border: 1px solid #dee2e6; }
|
|
.attendance-table th { background-color: #2c3e50; color: white; text-align: center; }
|
|
.attendance-table td { text-align: center; vertical-align: middle; }
|
|
.state-badge { padding: 5px 10px; border-radius: 4px; font-weight: bold; font-size: 0.9rem; }
|
|
.bg-P { background-color: #d1e7dd; color: #0f5132; }
|
|
.bg-F { background-color: #f8d7da; color: #842029; }
|
|
.bg-T { background-color: #fff3cd; color: #664d03; }
|
|
.bg-J { background-color: #cff4fc; color: #055160; }
|
|
.bg-E { background-color: #e2e3e5; color: #41464b; }
|
|
.summary-box { border: 2px solid #2c3e50; border-radius: 8px; padding: 15px; }
|
|
.summary-item { display: flex; justify-content: space-between; margin-bottom: 5px; border-bottom: 1px dashed #dee2e6; }
|
|
.summary-item:last-child { border-bottom: none; }
|
|
.signature-section { margin-top: 80px; }
|
|
.signature-line { border-top: 1px solid #000; width: 250px; margin: 0 auto; margin-top: 50px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container py-5">
|
|
<div class="no-print mb-4 text-end">
|
|
<button onclick="window.print()" class="btn btn-primary shadow-sm">
|
|
<i class="bi bi-printer"></i> Imprimir Reporte
|
|
</button>
|
|
<button onclick="window.close()" class="btn btn-outline-secondary shadow-sm">
|
|
<i class="bi bi-x-lg"></i> Cerrar
|
|
</button>
|
|
</div>
|
|
|
|
<div class="report-header d-flex justify-content-between align-items-end">
|
|
<div>
|
|
<div class="foundation-name">FUNDACIÓN MIES</div>
|
|
<div class="report-title">Registro Individual de Asistencia</div>
|
|
</div>
|
|
<div class="text-end">
|
|
<div class="h5 mb-0">PERIODO: @Model.NombreMes @Model.Año</div>
|
|
<div class="small text-muted">Fecha de emisión: @DateTime.Now.ToString("dd/MM/yyyy")</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-card shadow-sm">
|
|
<h5 class="border-bottom pb-2 mb-3"><i class="bi bi-person-badge"></i> Información del Niño/a</h5>
|
|
<div class="row">
|
|
<div class="col-md-7">
|
|
<p><span class="info-label">Nombre Completo:</span> <span class="h6">@nino.Persona.Nombres @nino.Persona.Apellidos</span></p>
|
|
<p><span class="info-label">Código:</span> <span>@nino.CodigoInscripcion</span></p>
|
|
<p><span class="info-label">Estado:</span> <span class="badge bg-success">@nino.Estado</span></p>
|
|
</div>
|
|
<div class="col-md-5">
|
|
@{
|
|
var totalP = 0; var totalT = 0; var totalF = 0; var totalJ = 0; var totalE = 0;
|
|
foreach (var dia in diasAMostrar) {
|
|
var key = $"{nino.Id}_{dia:yyyy-MM-dd}";
|
|
var estado = Model.Asistencias.ContainsKey(key) ? Model.Asistencias[key] : "";
|
|
switch(estado) {
|
|
case "P": totalP++; break;
|
|
case "T": totalT++; break;
|
|
case "F": totalF++; break;
|
|
case "J": totalJ++; break;
|
|
case "E": totalE++; break;
|
|
}
|
|
}
|
|
var totalRegistros = totalP + totalT + totalF + totalJ + totalE;
|
|
var porcentaje = totalRegistros > 0 ? (totalP * 100.0 / totalRegistros) : 0;
|
|
}
|
|
<div class="summary-box">
|
|
<h6 class="text-center mb-3">Resumen de Asistencia</h6>
|
|
<div class="summary-item"><span>Presentes (P):</span> <strong>@totalP</strong></div>
|
|
<div class="summary-item"><span>Tardes (T):</span> <strong>@totalT</strong></div>
|
|
<div class="summary-item"><span>Faltas (F):</span> <strong>@totalF</strong></div>
|
|
<div class="summary-item"><span>Justificados (J):</span> <strong>@totalJ</strong></div>
|
|
<div class="summary-item"><span>Enfermos (E):</span> <strong>@totalE</strong></div>
|
|
<div class="summary-item mt-2 pt-2 border-top border-dark">
|
|
<span>Asistencia Efectiva:</span>
|
|
<strong class="@(porcentaje >= 80 ? "text-success" : "text-danger")">@porcentaje.ToString("F1")%</strong>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<table class="table table-bordered attendance-table shadow-sm">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 20%;">Fecha</th>
|
|
<th style="width: 20%;">Día</th>
|
|
<th style="width: 30%;">Estado</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var dia in diasAMostrar)
|
|
{
|
|
var key = $"{nino.Id}_{dia:yyyy-MM-dd}";
|
|
var estado = Model.Asistencias.ContainsKey(key) ? Model.Asistencias[key] : "";
|
|
var nombreDia = dia.ToString("dddd", new System.Globalization.CultureInfo("es-ES"));
|
|
var esFinDeSemana = dia.DayOfWeek == DayOfWeek.Saturday || dia.DayOfWeek == DayOfWeek.Sunday;
|
|
|
|
<tr class="@(esFinDeSemana ? "bg-light" : "")">
|
|
<td>@dia.ToString("dd/MM/yyyy")</td>
|
|
<td class="text-capitalize">@nombreDia</td>
|
|
<td>
|
|
@if (!string.IsNullOrEmpty(estado))
|
|
{
|
|
<span class="state-badge bg-@estado">
|
|
@(estado switch {
|
|
"P" => "PRESENTE",
|
|
"T" => "TARDE",
|
|
"F" => "AUSENTE",
|
|
"J" => "JUSTIFICADO",
|
|
"E" => "ENFERMO",
|
|
_ => ""
|
|
})
|
|
</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="text-muted small">- Sin registro -</span>
|
|
}
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row signature-section text-center">
|
|
<div class="col-6">
|
|
<div class="signature-line"></div>
|
|
<div class="mt-2 fw-bold">Firma del Responsable</div>
|
|
<div class="small text-muted">Control de Asistencia</div>
|
|
</div>
|
|
<div class="col-6">
|
|
<div class="signature-line"></div>
|
|
<div class="mt-2 fw-bold">Sello de la Institución</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|