Files
Antifraude.Net/Antifraude.Net/GestionaDenunciasAN/Components/Pages/Pendientes.razor
2026-06-08 12:58:30 +02:00

1502 lines
63 KiB
Plaintext
Raw Blame History

@page "/Pendientes"
@rendermode InteractiveServer
@attribute [Authorize]
@using GestionaDenuncias.Shared.Models
@using System.Globalization
@using System.IO
@using System.Linq
@using System.Text
@using GestionaDenuncias.Shared.Helpers
@using GestionaDenunciasAN.Services
@attribute [StreamRendering]
@inject GestionaDenunciasAN.Models.UserState userState
@inject NavigationManager Navigation
@inject IHostEnvironment HostEnvironment
@inject IDenunciaStore DenunciaStore
@inject ApiDenunciasClient ApiDenuncias
@inject UiBusyService Busy
<PageTitle>Denuncias Pendientes</PageTitle>
<style>
.seleccionar-col {
width: 50px;
text-align: center;
vertical-align: middle;
}
.pendientes-list {
margin-top: 20px;
}
.collapse-card {
margin-bottom: 1rem;
border: 1px solid #ccc;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
overflow: hidden;
transition: transform 0.3s ease, box-shadow 0.3s ease;
background-color: #fff;
}
.collapse-card:hover {
transform: scale(1.02);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.collapse-card .card-header {
padding: 0.75rem 1.25rem;
cursor: pointer;
background-color: #f7f7f7;
transition: background-color 0.3s ease;
}
.collapse-card .card-header:hover {
background-color: #e2e2e2;
}
.section-heading {
text-align: center;
font-weight: bold;
text-decoration: underline;
font-size: 1.1em;
margin: 1rem 0 0.5rem;
}
.custom-modal {
background: rgba(0, 0, 0, 0.5);
}
.custom-modal-dialog {
max-width: 500px;
margin: 2rem auto;
}
.custom-modal-content {
border-radius: 0.5rem;
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
border: none;
}
.custom-modal-header {
background-color: #007bff;
color: white;
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
padding: 1rem;
}
.custom-modal-body {
padding: 1.5rem;
background-color: #f8f9fa;
}
.custom-modal-footer {
border-top: none;
padding: 1rem;
}
.modal-section-heading {
font-weight: bold;
font-size: 1.1em;
margin-bottom: 0.5rem;
border-bottom: 2px solid #007bff;
padding-bottom: 0.25rem;
}
.custom-file-list .list-group-item {
transition: background-color 0.2s ease;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
}
.custom-file-list .list-group-item:hover {
background-color: #e9ecef;
}
.custom-file-list .list-group-item.active {
background-color: #007bff;
color: white;
border-color: #007bff;
}
.preselect-btn {
background: none;
border: none;
padding: 0;
margin: 0;
font-size: 1.2rem;
cursor: pointer;
}
.preselect-btn i {
transition: color 0.3s ease;
}
.preselect-btn.selected i {
color: #28a745;
}
.preselect-btn:not(.selected) i {
color: #6c757d;
}
/* Modal expedientes a la derecha en pantallas grandes */
.expedientes-modal .modal-dialog {
margin-left: auto;
margin-right: 2rem;
}
</style>
<h1>Denuncias Pendientes</h1>
@if (!string.IsNullOrWhiteSpace(loadError))
{
<div class="alert alert-danger">@loadError</div>
}
@if (!string.IsNullOrWhiteSpace(operationNotice))
{
<div class="alert alert-warning">@operationNotice</div>
}
<input type="text"
class="form-control"
placeholder="Buscar denuncias..."
@bind="busqueda"
@bind:event="oninput"
style="margin-bottom:20px;" />
@if (!hasLoaded)
{
<div class="alert alert-info">Cargando datos...</div>
}
else if (pendientes == null || !pendientes.Any())
{
<p>No hay denuncias pendientes.</p>
}
else
{
<div class="pendientes-list">
@foreach (var denuncia in pendientes.Where(d =>
string.IsNullOrWhiteSpace(busqueda) ||
d.Id_Denuncia.ToString().Contains(busqueda) ||
(!string.IsNullOrEmpty(d.Asunto) && d.Asunto.Contains(busqueda, StringComparison.OrdinalIgnoreCase)) ||
(!string.IsNullOrEmpty(d.Nombre) && d.Nombre.Contains(busqueda, StringComparison.OrdinalIgnoreCase)) ||
(!string.IsNullOrEmpty(d.Apellidos) && d.Apellidos.Contains(busqueda, StringComparison.OrdinalIgnoreCase)) ||
(!string.IsNullOrEmpty(d.RazonSocial) && d.RazonSocial.Contains(busqueda, StringComparison.OrdinalIgnoreCase))
))
{
var collapseId = $"collapse{denuncia.Id_Denuncia}";
<div class="card mb-2 collapse-card">
<div class="card-header d-flex justify-content-between align-items-center"
data-bs-toggle="collapse"
data-bs-target="#@collapseId"
aria-expanded="false"
aria-controls="@collapseId">
<h5 class="mb-0">Denuncia ID: @denuncia.Id_Denuncia</h5>
<div>
<button type="button"
class="btn btn-success btn-sm me-2"
@onclick:stopPropagation="true"
@onclick="() => OpenEnviarAGestionaModal(denuncia)">
Configurar subida
</button>
<!-- Enviar a Actualizaciones -->
<button type="button"
class="btn btn-outline-warning btn-sm me-2"
title="Mover esta denuncia a la cola de Actualizaciones"
@onclick:stopPropagation="true"
@onclick="() => MoverAActualizaciones(denuncia)">
Enviar a Actualizaciones
</button>
<button type="button"
class="btn btn-danger btn-sm"
@onclick:stopPropagation="true"
@onclick="() => OpenRechazarModal(denuncia)">
Rechazar denuncia
</button>
</div>
</div>
<div id="@collapseId" class="collapse">
<div class="card-body">
<h5 class="section-heading">Datos Generales</h5>
<dl class="row">
@if (denuncia.Id_RegistroDenuncia != 0)
{
<dt class="col-sm-3">ID Registro Denuncia</dt>
<dd class="col-sm-9">@denuncia.Id_RegistroDenuncia</dd>
}
@if (denuncia.Id_Denuncia != 0)
{
<dt class="col-sm-3">ID Denuncia</dt>
<dd class="col-sm-9">@denuncia.Id_Denuncia</dd>
}
@if (denuncia.Fecha != DateTime.MinValue)
{
<dt class="col-sm-3">Fecha</dt>
<dd class="col-sm-9">@denuncia.Fecha.ToString("dd/MM/yyyy HH:mm")</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.ExpedienteGestionaMostrable))
{
<dt class="col-sm-3">N<> expediente Gestiona</dt>
<dd class="col-sm-9">@denuncia.ExpedienteGestionaMostrable</dd>
}
@if (denuncia.Id_Persona_Gestiona != 0)
{
<dt class="col-sm-3">ID Persona Gestiona</dt>
<dd class="col-sm-9">@denuncia.Id_Persona_Gestiona</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Etiqueta))
{
<dt class="col-sm-3">Etiqueta</dt>
<dd class="col-sm-9">@denuncia.Etiqueta</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Estado))
{
<dt class="col-sm-3">Estado</dt>
<dd class="col-sm-9">@denuncia.Estado</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Tipo_Denuncia))
{
<dt class="col-sm-3">Tipo Denuncia</dt>
<dd class="col-sm-9">@denuncia.Tipo_Denuncia</dd>
}
</dl>
@if (!string.IsNullOrWhiteSpace(denuncia.NombreResuelto) ||
!string.IsNullOrWhiteSpace(denuncia.ApellidosResueltos) ||
!string.IsNullOrWhiteSpace(denuncia.RazonSocialResuelta) ||
!string.IsNullOrWhiteSpace(denuncia.Sexo) ||
!string.IsNullOrWhiteSpace(denuncia.DocumentoResuelto))
{
<h5 class="section-heading">Datos del Denunciante</h5>
<dl class="row">
@if (!string.IsNullOrWhiteSpace(denuncia.TipoDenunciante))
{
<dt class="col-sm-3">Tipo de denunciante</dt>
<dd class="col-sm-9">@denuncia.TipoDenunciante</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.RazonSocialResuelta))
{
<dt class="col-sm-3">Raz<61>n social</dt>
<dd class="col-sm-9">@denuncia.RazonSocialResuelta</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.NombreResuelto))
{
<dt class="col-sm-3">Nombre</dt>
<dd class="col-sm-9">@denuncia.NombreResuelto</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.PrimerApellidoResuelto))
{
<dt class="col-sm-3">1<> Apellido</dt>
<dd class="col-sm-9">@denuncia.PrimerApellidoResuelto</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.SegundoApellidoResuelto))
{
<dt class="col-sm-3">2<> Apellido</dt>
<dd class="col-sm-9">@denuncia.SegundoApellidoResuelto</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.ApellidosResueltos))
{
<dt class="col-sm-3">Apellidos</dt>
<dd class="col-sm-9">@denuncia.ApellidosResueltos</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Sexo))
{
<dt class="col-sm-3">Sexo</dt>
<dd class="col-sm-9">@denuncia.Sexo</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.DocumentoResuelto))
{
<dt class="col-sm-3">@GetDocumentoLabel(denuncia)</dt>
<dd class="col-sm-9">@denuncia.DocumentoResuelto</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.PaisOrigen))
{
<dt class="col-sm-3">Pa<50>s de origen</dt>
<dd class="col-sm-9">@denuncia.PaisOrigen</dd>
}
</dl>
}
<h5 class="section-heading">Detalles de la Denuncia</h5>
<dl class="row">
<dt class="col-sm-3">Asunto</dt>
<dd class="col-sm-9">@denuncia.Asunto</dd>
<dt class="col-sm-3">A Quien Denuncia</dt>
<dd class="col-sm-9">@denuncia.A_Quien_Denuncia</dd>
@if (!string.IsNullOrWhiteSpace(denuncia.DenunciadoDetalle))
{
<dt class="col-sm-3">Detalle denunciado</dt>
<dd class="col-sm-9">@denuncia.DenunciadoDetalle</dd>
}
<dt class="col-sm-3">Descripci<63>n Denuncia</dt>
<dd class="col-sm-9">@denuncia.Descripcion_Denuncia</dd>
<dt class="col-sm-3">Denunciado Ante Inst</dt>
<dd class="col-sm-9">@denuncia.Denunciado_Ante_Inst</dd>
@if (!string.IsNullOrWhiteSpace(denuncia.OrganismoDenunciado))
{
<dt class="col-sm-3">Organismo previo</dt>
<dd class="col-sm-9">@denuncia.OrganismoDenunciado</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.SolicitaProteccion))
{
<dt class="col-sm-3">Solicita protecci<63>n</dt>
<dd class="col-sm-9">@denuncia.SolicitaProteccion</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.MedidasProteccionSolicitadas))
{
<dt class="col-sm-3">Medidas solicitadas</dt>
<dd class="col-sm-9">@denuncia.MedidasProteccionSolicitadas</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Modalidad_Informacion))
{
<dt class="col-sm-3">Modalidad Informaci<63>n</dt>
<dd class="col-sm-9">@denuncia.Modalidad_Informacion</dd>
}
<dt class="col-sm-3">Lugar Hechos</dt>
<dd class="col-sm-9">@denuncia.Lugar_Hechos</dd>
@if (denuncia.Fecha_Hechos != DateTime.MinValue)
{
<dt class="col-sm-3">Fecha Hechos</dt>
<dd class="col-sm-9">@denuncia.Fecha_Hechos.ToString("dd/MM/yyyy")</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.AutorizaRemision))
{
<dt class="col-sm-3">Autoriza remisi<73>n</dt>
<dd class="col-sm-9">@denuncia.AutorizaRemision</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.PreferenciaRemision))
{
<dt class="col-sm-3">Datos al remitir</dt>
<dd class="col-sm-9">@denuncia.PreferenciaRemision</dd>
}
</dl>
<h5 class="section-heading">Datos de Notificaci<63>n</h5>
<dl class="row">
@if (!string.IsNullOrWhiteSpace(denuncia.Notificacion_Preferencia))
{
<dt class="col-sm-3">Notificaci<63>n Preferencia</dt>
<dd class="col-sm-9">@denuncia.Notificacion_Preferencia</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Notificacion_Electronica))
{
<dt class="col-sm-3">Notificaci<63>n Electr<74>nica</dt>
<dd class="col-sm-9">@denuncia.Notificacion_Electronica</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.SeguimientoOnline))
{
<dt class="col-sm-3">Seguimiento Online</dt>
<dd class="col-sm-9">@denuncia.SeguimientoOnline</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.NotificacionPostal))
{
<dt class="col-sm-3">Correo Postal</dt>
<dd class="col-sm-9">@denuncia.NotificacionPostal</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Correo_Electronico))
{
<dt class="col-sm-3">Correo Electr<74>nico</dt>
<dd class="col-sm-9">@denuncia.Correo_Electronico</dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Notificacion_Sms))
{
<dt class="col-sm-3">Notificaci<63>n SMS</dt>
<dd class="col-sm-9">@denuncia.Notificacion_Sms</dd>
}
@if (HasPostalAddress(denuncia))
{
<dt class="col-sm-3">Direcci<63>n postal</dt>
<dd class="col-sm-9">@BuildPostalAddressSummary(denuncia)</dd>
}
</dl>
<h5 class="section-heading">Otros</h5>
<dl class="row">
@if (denuncia.Condiciones)
{
<dt class="col-sm-3">Condiciones</dt>
<dd class="col-sm-9">S<></dd>
}
@if (!string.IsNullOrWhiteSpace(denuncia.Comments))
{
<dt class="col-sm-3">Comentarios</dt>
<dd class="col-sm-9"><pre>@denuncia.Comments</pre></dd>
}
</dl>
@{
var camposFormulario = denuncia.GetCamposFormulario();
}
@if (camposFormulario.Count > 0)
{
<h5 class="section-heading">Formulario Original</h5>
@foreach (var grupoCampos in camposFormulario.GroupBy(field => string.IsNullOrWhiteSpace(field.Section) ? "Sin secci<63>n" : field.Section))
{
<h6 class="mt-3">@grupoCampos.Key</h6>
<dl class="row">
@foreach (var campo in grupoCampos)
{
<dt class="col-sm-4">@campo.Label</dt>
<dd class="col-sm-8">@(string.IsNullOrWhiteSpace(campo.Value) ? "<22>" : campo.Value)</dd>
}
</dl>
}
}
@if (ficherosAdjuntos.ContainsKey(denuncia.Id_Denuncia) && ficherosAdjuntos[denuncia.Id_Denuncia].Any())
{
<h5 class="section-heading">Ficheros Adjuntos</h5>
<table class="table table-striped">
<thead>
<tr>
<th class="seleccionar-col">Subir</th>
<th>Nombre</th>
<th>Fecha</th>
<th>Tama<6D>o (bytes)</th>
<th>Ver</th>
</tr>
</thead>
<tbody>
@foreach (var fichero in ficherosAdjuntos[denuncia.Id_Denuncia])
{
var isReport = IsReportFileName(fichero.NombreFichero);
<tr>
<td class="seleccionar-col">
<input class="form-check-input"
type="checkbox"
checked="@IsFileSelectedForUpload(denuncia.Id_Denuncia, fichero.NombreFichero)"
disabled="@isReport"
title='@(isReport ? "El report se sube siempre" : "Incluir este fichero en la subida")'
@onchange="args => ToggleFileSelection(denuncia.Id_Denuncia, fichero.NombreFichero, args.Value is bool selected && selected)" />
</td>
<td>
@fichero.NombreFichero
@if (isReport)
{
<span class="badge bg-primary ms-2">Obligatorio</span>
}
</td>
<td>@FormatFileDate(fichero.Fecha)</td>
<td>@fichero.Fichero.Length</td>
<td>
<a class="btn btn-primary btn-sm" href="@BuildAttachmentContentUrl(denuncia.Id_Denuncia, fichero.NombreFichero)" target="_blank" rel="noopener">
<i class="bi bi-eye"></i> Ver
</a>
</td>
</tr>
}
</tbody>
</table>
}
</div>
</div>
</div>
}
</div>
}
<script>
function createObjectUrl(base64, contentType) {
const binaryString = window.atob(base64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); }
const blob = new Blob([bytes], { type: contentType });
return URL.createObjectURL(blob);
}
function openFile(event, base64, contentType) {
event.preventDefault();
event.stopPropagation();
const objectUrl = createObjectUrl(base64, contentType);
window.open(objectUrl, '_blank');
}
</script>
@if (showModal && selectedDenuncias != null)
{
<div class="modal custom-modal fade show"
style="display:block;" tabindex="-1">
<div class="modal-dialog custom-modal-dialog">
<div class="modal-content custom-modal-content">
<div class="modal-header custom-modal-header">
<h5 class="modal-title">Enviar a Gestiona</h5>
<button type="button" class="btn-close" @onclick="CloseModal"></button>
</div>
<div class="modal-body custom-modal-body">
@if (!string.IsNullOrWhiteSpace(operationError))
{
<div class="alert alert-danger" role="alert">
@operationError
</div>
}
<h6 class="modal-section-heading">Descripci<63>n</h6>
<div class="mb-3">
<input type="text"
class="form-control"
@bind="nuevoAsunto"
placeholder="Ingrese el nombre de la denuncia" />
</div>
<h6 class="modal-section-heading">Nombre de los documentos</h6>
<div class="mb-3">
<input type="text"
class="form-control"
@bind="nombreDocumentos"
placeholder="Ej.: Gesti<74>n AN (lo ver<65>s como: Documento Adjunto 1 Gesti<74>n AN, ...)" />
<small class="text-muted">
Se aplicar<61> al subir en modo <strong>individual</strong>. El <em>report.txt</em> se subir<69> como <strong>Denuncia</strong>.
</small>
</div>
<h6 class="modal-section-heading">Modo de subida</h6>
<div class="form-check">
<input class="form-check-input"
type="radio"
name="uploadMode"
id="modoMerge"
checked='@(uploadMode == "merge")'
@onclick='() => uploadMode = "merge"' />
<label class="form-check-label" for="modoMerge">
Unir todos los ficheros en un <20>nico PDF
</label>
</div>
<div class="form-check">
<input class="form-check-input"
type="radio"
name="uploadMode"
id="modoIndividual"
checked='@(uploadMode == "individual")'
@onclick='() => uploadMode = "individual"' />
<label class="form-check-label" for="modoIndividual">
Subir ficheros de forma independiente
</label>
</div>
<h6 class="modal-section-heading">Grupo de destino</h6>
<div class="form-check">
<input class="form-check-input"
type="radio"
name="selectedGroup"
id="grupo600"
checked='@(selectedGroup == "600")'
@onclick='() => selectedGroup = "600"' />
<label class="form-check-label" for="grupo600">
600. Asuntos Jur<75>dicos y Protecci<63>n a la Persona Denunciante
</label>
</div>
@* <div class="form-check">
<input class="form-check-input"
type="radio"
name="selectedGroup"
id="grupo510"
checked='@(selectedGroup == "510")'
@onclick='() => selectedGroup = "510"' />
<label class="form-check-label" for="grupo510">
510. SDI <20> Investigaci<63>n Entradas
</label>
</div>
<div class="form-check">
<input class="form-check-input"
type="radio"
name="selectedGroup"
id="grupo700"
checked='@(selectedGroup == "700")'
@onclick='() => selectedGroup = "700"' />
<label class="form-check-label" for="grupo700">
700. RESPONSABLE DEL SERVICIO
</label>
</div> *@
<!-- DATOS DEL TERCERO -->
@{
var modalThirdParty = selectedThirdParty ?? ThirdPartyIdentityData.FromComplaint(selectedDenuncias);
}
<h6 class="modal-section-heading mt-3">Tercero (denunciante)</h6>
<div class="alert alert-light border mb-3">
Los datos del tercero se cargan autom<6F>ticamente desde la denuncia y no se pueden editar aqu<71>.
</div>
@if (modalThirdParty.IsAnonymous)
{
<div class="alert alert-warning mb-3">
Denuncia an<61>nima. Se enlazar<61> autom<6F>ticamente el tercero <strong>00000000T</strong>.
</div>
}
<div class="row g-2">
<div class="col-6 mb-2">
<label class="form-label">@GetDocumentoLabel(selectedDenuncias)</label>
<input class="form-control" value="@GetReadOnlyValue(modalThirdParty.DocumentId)" readonly />
</div>
<div class="col-6 mb-2">
<label class="form-label">Email</label>
<input class="form-control" value="@GetReadOnlyValue(modalThirdParty.Email)" readonly />
</div>
</div>
@if (!string.IsNullOrWhiteSpace(selectedDenuncias.TipoDenunciante))
{
<div class="row g-2">
<div class="col-12 mb-2">
<label class="form-label">Tipo de denunciante</label>
<input class="form-control" value="@selectedDenuncias.TipoDenunciante" readonly />
</div>
</div>
}
@if (modalThirdParty.IsLegalEntity)
{
<div class="row g-2">
<div class="col-12 mb-2">
<label class="form-label">Raz<61>n social</label>
<input class="form-control" value="@GetReadOnlyValue(selectedDenuncias.RazonSocialResuelta)" readonly />
</div>
</div>
}
else
{
<div class="row g-2">
<div class="col-4 mb-2">
<label class="form-label">Nombre</label>
<input class="form-control" value="@GetReadOnlyValue(selectedDenuncias.NombreResuelto)" readonly />
</div>
<div class="col-4 mb-2">
<label class="form-label">1<> apellido</label>
<input class="form-control" value="@GetReadOnlyValue(selectedDenuncias.PrimerApellidoResuelto)" readonly />
</div>
<div class="col-4 mb-2">
<label class="form-label">2<> apellido</label>
<input class="form-control" value="@GetReadOnlyValue(selectedDenuncias.SegundoApellidoResuelto)" readonly />
</div>
</div>
}
@if (!modalThirdParty.IsAnonymous && HasPostalAddress(selectedDenuncias))
{
<div class="row g-2">
<div class="col-12 mb-2">
<label class="form-label">Direcci<63>n postal</label>
<textarea class="form-control" rows="2" readonly>@BuildPostalAddressSummary(selectedDenuncias)</textarea>
</div>
</div>
}
<small class="text-muted">
Al confirmar, se enlazar<61> en Gestiona el tercero obtenido del formulario de la denuncia.
</small>
@if (!modalThirdParty.IsAnonymous && !string.IsNullOrWhiteSpace(modalThirdParty.DocumentId))
{
<div class="mt-2">
<button type="button"
class="btn btn-outline-secondary btn-sm"
@onclick="BuscarExpedientesTerceroAsync">
Ver expedientes de este tercero en Gestiona
</button>
</div>
}
</div>
<div class="modal-footer custom-modal-footer">
<button type="button" class="btn btn-secondary" @onclick="CloseModal">
Cancelar
</button>
<button type="button" class="btn btn-primary" disabled="@isUploading" @onclick="ConfirmarEnvio">
Confirmar
</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop fade show"></div>
}
@if (showModalRechazo && selectedDenuncias != null)
{
<div class="modal custom-modal fade show" style="display:block;" tabindex="-1">
<div class="modal-dialog custom-modal-dialog">
<div class="modal-content custom-modal-content">
<div class="modal-header custom-modal-header">
<h5 class="modal-title">Rechazar Denuncia</h5>
<button type="button" class="btn-close" @onclick="CloseRechazoModal"></button>
</div>
<div class="modal-body custom-modal-body">
<h6 class="modal-section-heading">Motivo de Rechazo</h6>
<div class="mb-3">
<input type="text" class="form-control" @bind="motivoRechazo" placeholder="Ingrese el motivo de rechazo" />
</div>
</div>
<div class="modal-footer custom-modal-footer">
<button type="button" class="btn btn-secondary" @onclick="CloseRechazoModal">Cancelar</button>
<button type="button" class="btn btn-primary" @onclick="ConfirmarRechazo">Confirmar</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop fade show"></div>
}
@if (showExpedientesModal)
{
<div class="modal custom-modal fade show expedientes-modal"
style="display:block; z-index:2100;" tabindex="-1">
<div class="modal-dialog custom-modal-dialog" style="max-width: 900px;">
<div class="modal-content custom-modal-content">
<div class="modal-header custom-modal-header">
<h5 class="modal-title">
Expedientes en Gestiona para @nifConsultaExpedientes
</h5>
<button type="button" class="btn-close" @onclick="CloseExpedientesModal"></button>
</div>
<div class="modal-body custom-modal-body">
@if (isLoadingExpedientes)
{
<div class="d-flex align-items-center">
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
<span>Cargando expedientes<65></span>
</div>
}
else if (!string.IsNullOrWhiteSpace(errorExpedientes))
{
<div class="alert alert-danger">@errorExpedientes</div>
}
else if (expedientesTercero == null || !expedientesTercero.Any())
{
<div class="alert alert-warning">
No se han encontrado expedientes asociados a este tercero.
</div>
}
else
{
<table class="table table-sm table-striped table-hover">
<thead>
<tr>
<th>Expediente</th>
<th>Asunto</th>
<th>Fecha creaci<63>n</th>
<th>Estado</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var exp in expedientesTercero)
{
<tr>
<td>@exp.CodigoExpediente</td>
<td>@exp.Asunto</td>
<td>@(exp.FechaCreacion?.ToLocalTime().ToString("dd/MM/yyyy HH:mm"))</td>
<td>@exp.Estado</td>
<td class="text-end">
@if (!string.IsNullOrWhiteSpace(exp.FileUrl))
{
}
</td>
</tr>
}
</tbody>
</table>
}
</div>
<div class="modal-footer custom-modal-footer">
<button type="button" class="btn btn-secondary" @onclick="CloseExpedientesModal">
Cerrar
</button>
</div>
</div>
</div>
</div>
}
@code {
private string nombreDocumentos = string.Empty;
private bool isUploading = false;
private string uploadMode = "merge";
private string selectedGroup = "600";
private string busqueda = "";
private List<DenunciasGestiona> pendientes = new();
private Dictionary<int, List<FicherosDenuncias>> ficherosAdjuntos = new();
private Dictionary<int, HashSet<string>> excludedUploadFiles = new();
private bool hasLoaded = false;
private string loadError = string.Empty;
private string operationError = string.Empty;
private string operationNotice = string.Empty;
private bool showModal = false;
private bool showModalRechazo = false;
private DenunciasGestiona? selectedDenuncias;
private ThirdPartyIdentityData? selectedThirdParty;
private string nuevoAsunto = string.Empty;
private string motivoRechazo = string.Empty;
private string terceroDni = "";
private bool showExpedientesModal = false;
private bool isLoadingExpedientes = false;
private string errorExpedientes = string.Empty;
private string nifConsultaExpedientes = string.Empty;
private List<ExpedienteTerceroDto> expedientesTercero = new();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await CargarDatosAsync();
}
}
private async Task CargarDatosAsync()
{
try
{
loadError = string.Empty;
var todas = await CargarDenunciasJsonAsync();
// Asegura ProcedureId/GroupId por si faltan
foreach (var d in todas.Where(x => x.ProcedureId == Guid.Empty))
{
d.ProcedureId = Guid.Parse("82722c9b-cecc-4299-8a7b-ce5abeb8170b");
d.GroupId = Guid.Parse("6dbfc433-1eb6-4b9a-a533-bfebc652c101");
}
// SOLO pendientes
pendientes = todas
.Where(d => !d.EnGestiona && !d.EnRechazada && !d.EsActualizacion)
.ToList();
// Adjuntos SOLO de las pendientes visibles
ficherosAdjuntos = await CargarFicherosPorDenunciaAsync(pendientes.Select(p => p.Id_Denuncia));
}
catch (Exception ex)
{
pendientes.Clear();
ficherosAdjuntos.Clear();
loadError = $"No se han podido cargar las denuncias pendientes: {ex.Message}";
}
hasLoaded = true;
StateHasChanged();
}
private async Task<List<DenunciasGestiona>> CargarDenunciasJsonAsync()
{
return await DenunciaStore.GetDenunciasByScopeAsync(DenunciaListScope.Pending);
}
private async Task<Dictionary<int, List<FicherosDenuncias>>> CargarFicherosPorDenunciaAsync(IEnumerable<int> denunciaIds)
{
var result = new Dictionary<int, List<FicherosDenuncias>>();
foreach (var denunciaId in denunciaIds.Where(id => id > 0).Distinct())
{
var ficheros = await DenunciaStore.GetFicherosByDenunciaAsync(denunciaId);
if (ficheros.Count > 0)
{
result[denunciaId] = ficheros;
}
}
return result;
}
private static bool IsReportFileName(string? fileName)
{
if (string.IsNullOrWhiteSpace(fileName))
{
return false;
}
var name = Path.GetFileNameWithoutExtension(fileName);
var extension = Path.GetExtension(fileName);
return name.StartsWith("report", StringComparison.OrdinalIgnoreCase) &&
(extension.Equals(".txt", StringComparison.OrdinalIgnoreCase) ||
extension.Equals(".pdf", StringComparison.OrdinalIgnoreCase));
}
private string FixFileName(string input)
{
var normalized = input.Normalize(NormalizationForm.FormD);
var sb = new StringBuilder();
foreach (var c in normalized)
{
var uc = CharUnicodeInfo.GetUnicodeCategory(c);
if (uc != UnicodeCategory.NonSpacingMark) sb.Append(c);
}
var clean = sb.ToString().Normalize(NormalizationForm.FormC);
clean = clean.Replace(' ', '_');
return new string(clean.Where(ch => ch <= 127).ToArray());
}
private async Task ConfirmarEnvio()
{
if (selectedDenuncias == null) return;
// Seguridad: no permitir enviar actualizaciones desde /Pendientes
if (selectedDenuncias.EsActualizacion)
{
CloseModal();
Navigation.NavigateTo("/Actualizaciones");
return;
}
try
{
isUploading = true;
operationError = string.Empty;
operationNotice = string.Empty;
using var busy = Busy.Show(
"Enviando a Gestiona",
"Preparando expediente, tercero y documentos de la denuncia.");
StateHasChanged();
await Task.Yield();
Busy.Update(message: "Cargando ficheros de la denuncia.", detail: "Paso 1 de 7");
var existentesF = await DenunciaStore.GetFicherosByDenunciaAsync(selectedDenuncias.Id_Denuncia);
var ficherosNoSeleccionados = GetExcludedUploadFileNames(selectedDenuncias.Id_Denuncia, existentesF);
var ficherosSeleccionados = GetSelectedUploadFiles(selectedDenuncias.Id_Denuncia, existentesF);
var todos = ficherosSeleccionados
.Select(f => (FileName: f.NombreFichero!, Content: f.Fichero!))
.ToList();
var ficherosVacios = todos
.Where(t => t.Content is null || t.Content.Length == 0)
.Select(t => string.IsNullOrWhiteSpace(t.FileName) ? "(sin nombre)" : t.FileName)
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
todos = todos
.Where(t => t.Content is { Length: > 0 })
.ToList();
if (!todos.Any())
{
operationError = ficherosVacios.Count == 0
? $"La denuncia #{selectedDenuncias.Id_Denuncia} no tiene ficheros para subir."
: $"La denuncia #{selectedDenuncias.Id_Denuncia} solo tiene ficheros vac<61>os y no se ha subido nada. Ficheros omitidos: {string.Join(", ", ficherosVacios)}.";
return;
}
string fileUrl;
if (selectedDenuncias.EnGestiona && !string.IsNullOrWhiteSpace(selectedDenuncias.Expediente_Gestiona))
{
fileUrl = selectedDenuncias.Expediente_Gestiona;
}
else
{
Busy.Update(message: "Creando expediente nuevo en Gestiona.", detail: "Paso 2 de 7");
var createdFile = await ApiDenuncias.CreateGestionaFileAsync(
selectedDenuncias.ProcedureId,
nuevoAsunto,
"RQ2ZLC - Expediente de Denuncias",
"3109963"
);
fileUrl = createdFile.FileUrl;
Busy.Update(message: "Abriendo expediente y asignando el grupo elegido.", detail: "Paso 2 de 7");
await ApiDenuncias.OpenGestionaFileAsync(
fileUrl,
createdFile.FileOpenUrl,
managementUnitGroupId: Guid.Parse("a4ad4dfb-70dc-4219-8ee3-4dcc939f0955"),
assignedGroupId: selectedGroup switch
{
"510" => Guid.Parse("6dbfc433-1eb6-4b9a-a533-bfebc652c101"),
"600" => Guid.Parse("454fa4ec-8b82-4240-9419-113f45d4b004"),
"700" => Guid.Parse("a4ad4dfb-70dc-4219-8ee3-4dcc939f0955"),
_ => throw new InvalidOperationException($"Grupo desconocido: {selectedGroup}")
},
confidential: selectedDenuncias.Confidencial,
freeTitle: nuevoAsunto,
siaCode: "3109963"
);
selectedDenuncias.Expediente_Gestiona = fileUrl;
selectedDenuncias.EnGestiona = true;
}
Busy.Update(message: "Guardando referencia local del expediente.", detail: "Paso 3 de 7");
selectedDenuncias.Expediente_Gestiona = fileUrl;
selectedDenuncias.EnGestiona = true;
var thirdParty = selectedThirdParty ?? ThirdPartyIdentityData.FromComplaint(selectedDenuncias);
Busy.Update(message: "Resolviendo tercero y enlazandolo al expediente.", detail: "Paso 4 de 7");
await ApiDenuncias.EnsureGestionaThirdAndLinkAsync(fileUrl, thirdParty);
var nombresOriginalesSubidos = new List<string>();
var nombresFinalesSubidos = new List<string>();
var ahoraUtc = DateTime.UtcNow;
string? documentoParaTramitar = null;
var report = todos.FirstOrDefault(t =>
IsReportFileName(t.FileName));
if (!string.IsNullOrWhiteSpace(report.FileName))
{
Busy.Update(message: "Preparando y subiendo el report para firma.", detail: "Paso 5 de 7");
var reportPdfBytes = PdfHelper.MergeFilesToPdf(new[]
{
(FileName: report.FileName, Content: report.Content)
});
const string reportFinalName = "Denuncia.pdf";
documentoParaTramitar = await ApiDenuncias.UploadGestionaDocumentAsync(
fileUrl,
reportPdfBytes,
FixFileName(reportFinalName));
nombresOriginalesSubidos.Add(report.FileName);
nombresFinalesSubidos.Add(FixFileName(reportFinalName));
}
var adjuntos = todos
.Where(t => !IsReportFileName(t.FileName))
.ToList();
if (adjuntos.Count > 0 && uploadMode == "merge")
{
Busy.Update(message: "Uniendo adjuntos en un unico PDF y subiendolo.", detail: "Paso 6 de 7");
var pdfBytes = PdfHelper.MergeFilesToPdf(adjuntos);
var pdfName = FixFileName($"Adjuntos {selectedDenuncias.Id_Denuncia}_{ahoraUtc:yyyyMMddHHmmss}.pdf");
var docUrl = await ApiDenuncias.UploadGestionaDocumentAsync(fileUrl, pdfBytes, pdfName);
if (string.IsNullOrWhiteSpace(documentoParaTramitar))
{
documentoParaTramitar = docUrl;
}
foreach (var adjunto in adjuntos)
{
nombresOriginalesSubidos.Add(adjunto.FileName);
}
nombresFinalesSubidos.Add(pdfName);
}
else
{
int i = 1;
string baseNombre = string.IsNullOrWhiteSpace(nombreDocumentos) ? "" : $" {nombreDocumentos}";
foreach (var (origName, content) in adjuntos)
{
Busy.Update(
message: $"Subiendo adjunto {i} de {adjuntos.Count}.",
detail: "Paso 6 de 7",
current: i,
total: adjuntos.Count);
var ext = Path.GetExtension(origName).ToLowerInvariant();
byte[] bytesParaSubir = content;
string finalName;
if (ext == ".txt")
{
bytesParaSubir = PdfHelper.MergeFilesToPdf(new[]
{
(FileName: origName, Content: content)
});
finalName = FixFileName($"Documento Adjunto {i}{baseNombre}.pdf");
}
else
{
finalName = FixFileName($"Documento Adjunto {i}{baseNombre}{ext}");
}
var docUrl = await ApiDenuncias.UploadGestionaDocumentAsync(fileUrl, bytesParaSubir, finalName);
if (string.IsNullOrWhiteSpace(documentoParaTramitar))
{
documentoParaTramitar = docUrl;
}
nombresOriginalesSubidos.Add(origName);
nombresFinalesSubidos.Add(finalName);
i++;
}
}
selectedDenuncias.ArchivoElegido = string.Join(";", nombresFinalesSubidos);
if (!string.IsNullOrWhiteSpace(documentoParaTramitar))
{
Busy.Update(message: "Enviando el report al circuito de firma.", detail: "Paso 7 de 7");
await ApiDenuncias.TramitarGestionaDocumentAsync(
documentoParaTramitar,
GetAssignedGroupLinkBySelectedGroup(),
selectedDenuncias.Id_Denuncia);
}
foreach (var origName in nombresOriginalesSubidos)
{
var f = existentesF.FirstOrDefault(x =>
x.Id_Denuncia == selectedDenuncias.Id_Denuncia &&
x.NombreFichero == origName);
if (f != null)
{
f.Subido = true;
f.FechaSubida = ahoraUtc;
}
}
Busy.Update(message: "Actualizando trazabilidad en la base de datos.", detail: "Finalizando");
await DenunciaStore.MarkFicherosAsUploadedAsync(
selectedDenuncias.Id_Denuncia,
nombresOriginalesSubidos,
ahoraUtc);
selectedDenuncias.EsActualizacion = false;
selectedDenuncias.NombreDenuncia = nuevoAsunto;
selectedDenuncias.FechaSubidaAGestiona = ahoraUtc;
await ActualizarDenunciaAsync(selectedDenuncias);
var denunciaProcesadaId = selectedDenuncias.Id_Denuncia;
pendientes.Remove(selectedDenuncias);
excludedUploadFiles.Remove(denunciaProcesadaId);
CloseModal();
var avisos = new List<string>();
if (ficherosVacios.Count > 0)
{
avisos.Add($"Se omitieron ficheros vac<61>os: {string.Join(", ", ficherosVacios)}.");
}
if (ficherosNoSeleccionados.Count > 0)
{
avisos.Add($"No se subieron por selecci<63>n del usuario: {string.Join(", ", ficherosNoSeleccionados)}.");
}
if (avisos.Count > 0)
{
operationNotice = $"Denuncia #{denunciaProcesadaId} enviada. {string.Join(" ", avisos)}";
}
StateHasChanged();
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error al confirmar env<6E>o: {ex}");
operationError = $"No se ha podido completar el env<6E>o de la denuncia #{selectedDenuncias?.Id_Denuncia}: {ex.Message}";
}
finally
{
isUploading = false;
StateHasChanged();
}
}
private string ObtenerUrlPublicaDe(string fileName)
{
return Navigation.BaseUri + $"CombinedPdfs/{Uri.EscapeDataString(fileName)}";
}
private async Task SincronizarExpedienteGestionaAsync(DenunciasGestiona denuncia, string fileUrl)
{
if (string.IsNullOrWhiteSpace(fileUrl))
{
return;
}
try
{
var expediente = await ApiDenuncias.GetGestionaExpedienteAsync(fileUrl);
if (expediente is null)
{
return;
}
denuncia.Expediente_Gestiona = expediente.FileUrl;
if (!string.IsNullOrWhiteSpace(expediente.CodigoExpediente))
{
denuncia.CodigoExpedienteGestiona = expediente.CodigoExpediente;
}
if (!string.IsNullOrWhiteSpace(expediente.FreeTitle))
{
denuncia.NombreDenuncia = expediente.FreeTitle;
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"No se ha podido sincronizar el expediente de Gestiona: {ex}");
}
}
private string GetAssignedGroupLinkBySelectedGroup()
{
return selectedGroup switch
{
"510" => "https://02.g3stiona.com/rest/groups/6dbfc433-1eb6-4b9a-a533-bfebc652c101",
"600" => "https://02.g3stiona.com/rest/groups/454fa4ec-8b82-4240-9419-113f45d4b004",
"700" => "https://02.g3stiona.com/rest/groups/a4ad4dfb-70dc-4219-8ee3-4dcc939f0955",
_ => throw new InvalidOperationException($"Grupo desconocido: {selectedGroup}")
};
}
private async Task ConfirmarRechazo()
{
if (selectedDenuncias == null)
return;
selectedDenuncias.EnRechazada = true;
selectedDenuncias.EstadoDenuncia = motivoRechazo;
selectedDenuncias.FechaSubidaAGestiona = DateTime.Now;
await ActualizarDenunciaAsync(selectedDenuncias);
pendientes.Remove(selectedDenuncias);
CloseRechazoModal();
StateHasChanged();
}
private async Task ActualizarDenunciaAsync(DenunciasGestiona d)
{
await DenunciaStore.UpsertDenunciaAsync(d);
}
private void OpenEnviarAGestionaModal(DenunciasGestiona d)
{
selectedDenuncias = d;
nuevoAsunto = $"Denuncia {d.Id_Denuncia}-CD";
selectedThirdParty = ThirdPartyIdentityData.FromComplaint(d);
terceroDni = selectedThirdParty.DocumentId;
operationError = string.Empty;
operationNotice = string.Empty;
showModal = true;
}
private void OpenRechazarModal(DenunciasGestiona d)
{
selectedDenuncias = d;
motivoRechazo = string.Empty;
showModalRechazo = true;
}
private void CloseModal()
{
showModal = false;
selectedDenuncias = null;
selectedThirdParty = null;
nuevoAsunto = string.Empty;
terceroDni = string.Empty;
operationError = string.Empty;
}
private void CloseRechazoModal() =>
(showModalRechazo, selectedDenuncias, motivoRechazo) =
(false, null, string.Empty);
private bool IsFileSelectedForUpload(int denunciaId, string? fileName)
{
if (IsReportFileName(fileName))
{
return true;
}
return string.IsNullOrWhiteSpace(fileName) ||
!excludedUploadFiles.TryGetValue(denunciaId, out var excluded) ||
!excluded.Contains(fileName);
}
private void ToggleFileSelection(int denunciaId, string? fileName, bool selected)
{
if (string.IsNullOrWhiteSpace(fileName) || IsReportFileName(fileName))
{
return;
}
if (!excludedUploadFiles.TryGetValue(denunciaId, out var excluded))
{
excluded = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
excludedUploadFiles[denunciaId] = excluded;
}
if (selected)
{
excluded.Remove(fileName);
if (excluded.Count == 0)
{
excludedUploadFiles.Remove(denunciaId);
}
}
else
{
excluded.Add(fileName);
}
}
private List<FicherosDenuncias> GetSelectedUploadFiles(int denunciaId, IEnumerable<FicherosDenuncias> files)
{
return files
.Where(file => IsReportFileName(file.NombreFichero) || IsFileSelectedForUpload(denunciaId, file.NombreFichero))
.ToList();
}
private List<string> GetExcludedUploadFileNames(int denunciaId, IEnumerable<FicherosDenuncias> files)
{
return files
.Where(file => !IsReportFileName(file.NombreFichero) && !IsFileSelectedForUpload(denunciaId, file.NombreFichero))
.Select(file => string.IsNullOrWhiteSpace(file.NombreFichero) ? "(sin nombre)" : file.NombreFichero)
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(name => name, StringComparer.OrdinalIgnoreCase)
.ToList();
}
private static string BuildAttachmentContentUrl(int denunciaId, string? fileName)
{
return $"/api/denuncias/{denunciaId}/ficheros/content?fileName={Uri.EscapeDataString(fileName ?? string.Empty)}";
}
private static string FormatFileDate(DateTime date)
=> date == DateTime.MinValue
? "-"
: date.ToLocalTime().ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture);
private string GetContentType(string fileName)
{
return Path.GetExtension(fileName).ToLowerInvariant() switch
{
".jpg" or ".jpeg" => "image/jpeg",
".png" => "image/png",
".gif" => "image/gif",
".pdf" => "application/pdf",
".txt" => "text/plain",
_ => "application/octet-stream",
};
}
private static string GetDocumentoLabel(DenunciasGestiona denuncia)
{
return string.IsNullOrWhiteSpace(denuncia.TipoDocumentoIdentificativo)
? "Documento identificativo"
: denuncia.TipoDocumentoIdentificativo;
}
private static string GetReadOnlyValue(string? value) =>
string.IsNullOrWhiteSpace(value) ? "<22>" : value;
private static bool HasPostalAddress(DenunciasGestiona denuncia)
{
return !string.IsNullOrWhiteSpace(denuncia.Direccion) ||
!string.IsNullOrWhiteSpace(denuncia.DireccionNumero) ||
!string.IsNullOrWhiteSpace(denuncia.Municipio) ||
!string.IsNullOrWhiteSpace(denuncia.Provincia) ||
!string.IsNullOrWhiteSpace(denuncia.CodigoPostal);
}
private static string BuildPostalAddressSummary(DenunciasGestiona denuncia)
{
var parts = new List<string>();
var street = string.Join(
' ',
new[]
{
denuncia.DireccionTipoVia,
denuncia.Direccion,
denuncia.DireccionNumero
}.Where(value => !string.IsNullOrWhiteSpace(value)));
if (!string.IsNullOrWhiteSpace(street))
{
parts.Add(street);
}
var extras = string.Join(
", ",
new[]
{
string.IsNullOrWhiteSpace(denuncia.DireccionBloque) ? null : $"Bloque {denuncia.DireccionBloque}",
string.IsNullOrWhiteSpace(denuncia.DireccionEscalera) ? null : $"Esc. {denuncia.DireccionEscalera}",
string.IsNullOrWhiteSpace(denuncia.DireccionPiso) ? null : $"Planta {denuncia.DireccionPiso}",
string.IsNullOrWhiteSpace(denuncia.DireccionPuerta) ? null : $"Puerta {denuncia.DireccionPuerta}",
denuncia.DireccionExtra
}.Where(value => !string.IsNullOrWhiteSpace(value)));
if (!string.IsNullOrWhiteSpace(extras))
{
parts.Add(extras);
}
var location = string.Join(
", ",
new[]
{
denuncia.CodigoPostal,
denuncia.Municipio,
denuncia.Provincia
}.Where(value => !string.IsNullOrWhiteSpace(value)));
if (!string.IsNullOrWhiteSpace(location))
{
parts.Add(location);
}
return string.Join(" | ", parts);
}
// mover a Actualizaciones
private async Task MoverAActualizaciones(DenunciasGestiona d)
{
d.EsActualizacion = true;
d.EnRechazada = false;
await ActualizarDenunciaAsync(d);
pendientes.RemoveAll(x => x.Id_Denuncia == d.Id_Denuncia);
StateHasChanged();
}
// ========= L<>GICA BUSCADOR DE EXPEDIENTES POR TERCERO =========
private void CloseExpedientesModal()
{
showExpedientesModal = false;
errorExpedientes = string.Empty;
expedientesTercero.Clear();
nifConsultaExpedientes = string.Empty;
}
private async Task BuscarExpedientesTerceroAsync()
{
errorExpedientes = string.Empty;
expedientesTercero.Clear();
var nif = (selectedThirdParty?.DocumentId ?? terceroDni ?? string.Empty).Trim().ToUpperInvariant();
if (string.IsNullOrWhiteSpace(nif) || nif == "00000000T")
{
errorExpedientes = "NIF no v<>lido para b<>squeda (an<61>nimo o vac<61>o).";
showExpedientesModal = true;
StateHasChanged();
return;
}
showExpedientesModal = true;
isLoadingExpedientes = true;
nifConsultaExpedientes = nif;
StateHasChanged();
try
{
expedientesTercero = await ApiDenuncias.GetGestionaExpedientesPorTerceroAsync(nif);
if (expedientesTercero.Count == 0)
{
errorExpedientes = "No se han encontrado expedientes asociados a ese NIF en Gestiona.";
}
}
catch (Exception ex)
{
errorExpedientes = $"Error al consultar expedientes: {ex.Message}";
}
finally
{
isLoadingExpedientes = false;
StateHasChanged();
}
}
}