407 lines
14 KiB
C#
407 lines
14 KiB
C#
using EFCDesk.Classes;
|
|
using FontAwesome.Sharp;
|
|
using Microsoft.Win32;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace EFCDesk.Forms
|
|
{
|
|
public partial class FormExpedientes : Form
|
|
{
|
|
private class Paginacion
|
|
{
|
|
public long _registro;
|
|
public long _registros;
|
|
public long _pagina;
|
|
public long _paginas;
|
|
public string? _buscarExpediente;
|
|
}
|
|
|
|
private static SQLiteHelper _sqliteHelper = new SQLiteHelper(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "historico.db"));
|
|
private long paginacion = 1000;
|
|
private bool _clickPorCodigo = false;
|
|
private Paginacion _paginacion = new Paginacion();
|
|
private string DominioEFC = Helpers.DominioExpedienteElectronico();
|
|
|
|
public FormExpedientes()
|
|
{
|
|
InitializeComponent();
|
|
dgwExpedientes.SelectionChanged += dgwExpedientes_SelectionChanged!;
|
|
dgwExpedientes.AutoGenerateColumns = true;
|
|
dgwExpedientes.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
|
|
|
|
}
|
|
|
|
private async Task CargarVistaExpedientes(long pagina, string buscarExpediente = "*")
|
|
{
|
|
// Limpiar la fuente de datos
|
|
dgwExpedientes.DataSource = null;
|
|
|
|
// 1) Trabajo pesado en segundo plano
|
|
DataTable? dt = await Task.Run(() =>
|
|
{
|
|
var listaExpedientes = _sqliteHelper.ObtenerExpedientes(pagina: pagina, tamanioPagina: paginacion, buscarExpediente: buscarExpediente);
|
|
if (listaExpedientes == null || listaExpedientes.Count == 0)
|
|
return null;
|
|
|
|
DataTable table = new DataTable();
|
|
table.Columns.Add("Expediente", typeof(string));
|
|
table.Columns.Add("Ruta", typeof(string));
|
|
table.Columns.Add("Estatus", typeof(string));
|
|
table.Columns.Add("Fecha Registro", typeof(string)); // TaskId
|
|
table.Columns.Add("TaskId", typeof(string)); // TaskId
|
|
// Columna de Acciones con botón FontAwesome
|
|
var columnaAcciones = new DataGridViewImageColumn
|
|
{
|
|
Name = "Acciones",
|
|
HeaderText = "Acciones",
|
|
Width = 50,
|
|
ImageLayout = DataGridViewImageCellLayout.Zoom
|
|
};
|
|
|
|
// Columna de acciones
|
|
//table.Columns.Add("Acciones", typeof(Image));
|
|
|
|
// Crear el icono UNA sola vez
|
|
Bitmap iconoVer = IconChar.Eye.ToBitmap(
|
|
IconFont.Auto,
|
|
16,
|
|
Color.Black
|
|
);
|
|
|
|
foreach (var exp in listaExpedientes)
|
|
{
|
|
var row = table.NewRow();
|
|
row["Expediente"] = exp.Expediente;
|
|
row["Ruta"] = exp.Ruta;
|
|
row["Estatus"] = exp.Estado;
|
|
row["Fecha Registro"] = exp.FechaCreacion;
|
|
row["TaskId"] = exp.TaskId;
|
|
//row["Acciones"] = iconoVer;
|
|
table.Rows.Add(row);
|
|
}
|
|
return table;
|
|
});
|
|
|
|
long totalPaginas = await TotalPaginas(edt_BuscarExpediente.Text);
|
|
|
|
// 2) Volver al UI thread para asignar el origen
|
|
if (dt != null)
|
|
{
|
|
// Deshabilitar el redimensionamiento de ALTOS de filas
|
|
dgwExpedientes.AllowUserToResizeRows = false;
|
|
|
|
dgwExpedientes.DataSource = dt;
|
|
dgwExpedientes.Columns["Expediente"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
|
dgwExpedientes.Columns["Expediente"].Frozen = true;
|
|
dgwExpedientes.Columns["Expediente"].Width = 100;
|
|
|
|
dgwExpedientes.Columns["Ruta"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
|
dgwExpedientes.Columns["Ruta"].Width = 300;
|
|
|
|
dgwExpedientes.Columns["Estatus"].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
|
|
dgwExpedientes.Columns["Estatus"].Width = 100;
|
|
|
|
dgwExpedientes.Columns["Fecha Registro"].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
|
|
dgwExpedientes.Columns["Fecha Registro"].Width = 180;
|
|
|
|
//dgwExpedientes.Columns["Acciones"].Width = 40;
|
|
//dgwExpedientes.Columns["Acciones"].HeaderText = "";
|
|
//((DataGridViewImageColumn)dgwExpedientes.Columns["Acciones"]).ImageLayout = DataGridViewImageCellLayout.Zoom;
|
|
|
|
_ = Task.Run(() =>
|
|
{
|
|
long total = dgwExpedientes.RowCount;
|
|
|
|
_paginacion._registro = 1;
|
|
_paginacion._registros = total;
|
|
_paginacion._pagina = pagina;
|
|
_paginacion._paginas = totalPaginas;
|
|
_paginacion._buscarExpediente = ((string.IsNullOrEmpty(buscarExpediente) || string.IsNullOrWhiteSpace(buscarExpediente))) ? "*" : buscarExpediente;
|
|
|
|
ActualizarEtiqueta();
|
|
});
|
|
|
|
}
|
|
else
|
|
{
|
|
_paginacion._registro = 0;
|
|
_paginacion._registros = 0;
|
|
_paginacion._pagina = 0;
|
|
_paginacion._paginas = 0;
|
|
_paginacion._buscarExpediente = "*";
|
|
|
|
ActualizarEtiqueta();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private async Task<string> ConsultarEstadoTareaAsync(string taskId)
|
|
{
|
|
try
|
|
{
|
|
var apiClient = Globales.ApiClient;
|
|
string url = DominioEFC + $"/api/v1/tasks/status/?task_id={taskId}";
|
|
return await apiClient.GetAsync(url);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"Error al consultar estado: {ex.Message}", "Error",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
return "";
|
|
}
|
|
}
|
|
|
|
private async Task ProcesarRespuestaTareaAsync(string responseJson, string rutaExpediente)
|
|
{
|
|
if (string.IsNullOrEmpty(responseJson)) return;
|
|
|
|
var apiClient = Globales.ApiClient;
|
|
if (!apiClient.IsJson(responseJson)) return;
|
|
|
|
var data = apiClient.TryParseJson<Dictionary<string, object>>(responseJson);
|
|
if (data == null) return;
|
|
|
|
// Extraer información
|
|
string status = data.ContainsKey("status") ? data["status"]?.ToString() ?? "" : "";
|
|
bool successful = data.ContainsKey("successful") && Convert.ToBoolean(data["successful"]);
|
|
int documentsCreated = 0;
|
|
bool tieneError = true;
|
|
|
|
if (data.ContainsKey("result") && data["result"] is JsonElement resultElement)
|
|
{
|
|
var result = JsonSerializer.Deserialize<Dictionary<string, object>>(resultElement.GetRawText());
|
|
if (result != null)
|
|
{
|
|
tieneError = result.ContainsKey("tieneError") && Convert.ToBoolean(result["tieneError"]);
|
|
documentsCreated = result.ContainsKey("documents_created") ? Convert.ToInt32(result["documents_created"]) : 0;
|
|
}
|
|
}
|
|
|
|
// Determinar nuevo estado basado en respuesta
|
|
string nuevoEstado = "Error";
|
|
string mensaje = "";
|
|
|
|
if (successful && !tieneError)
|
|
{
|
|
nuevoEstado = "Procesado";
|
|
mensaje = $"Tarea completada. Documentos creados: {documentsCreated}";
|
|
}
|
|
else if (status == "PENDING" || status == "STARTED")
|
|
{
|
|
nuevoEstado = "Procesando";
|
|
mensaje = "Tarea en proceso...";
|
|
}
|
|
else
|
|
{
|
|
mensaje = $"Error en tarea: {status}";
|
|
}
|
|
|
|
// Actualizar en SQLite
|
|
_sqliteHelper.MarcarCarpetaProcesada(rutaExpediente, nuevoEstado);
|
|
|
|
// Mostrar resultado
|
|
MessageBox.Show(mensaje, "Estado de Tarea", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
|
|
// Recargar la grilla para ver el cambio
|
|
long pagina = _paginacion._pagina; // 'long' no puede ser null, así que no se necesita el operador '??'
|
|
string buscarExpediente = _paginacion._buscarExpediente ?? "*"; // Si es null, usar "*"
|
|
if (!(pagina > 0))
|
|
{
|
|
pagina = 1; // Valor predeterminado si 'pagina' no es válido
|
|
}
|
|
|
|
// await Task.Run(() => CargarVistaExpedientes(pagina: pagina, buscarExpediente: buscarExpediente));
|
|
await CargarVistaExpedientes(pagina: pagina, buscarExpediente: buscarExpediente);
|
|
}
|
|
|
|
private async void FormExpedientes_Shown(object sender, EventArgs e)
|
|
{
|
|
edt_Pagina.Text = "1";
|
|
await CargarVistaExpedientes(pagina: 1);
|
|
}
|
|
|
|
private async void BTN_Buscar_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
string busqueda = edt_BuscarExpediente.Text.Trim();
|
|
|
|
if (string.IsNullOrEmpty(busqueda))
|
|
{
|
|
busqueda = "*";
|
|
}
|
|
|
|
int pag = int.Parse(edt_Pagina.Text);
|
|
|
|
if (_clickPorCodigo)
|
|
{
|
|
// fue llamado desde código
|
|
await CargarVistaExpedientes(buscarExpediente: busqueda, pagina: pag);
|
|
_clickPorCodigo = false; // reset
|
|
}
|
|
else
|
|
{
|
|
// fue el usuario
|
|
await CargarVistaExpedientes(buscarExpediente: busqueda, pagina: 1);
|
|
}
|
|
|
|
}
|
|
|
|
private async void btn_siguiente_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
long totalPaginas = await TotalPaginas(edt_BuscarExpediente.Text);
|
|
|
|
long pag = (int.Parse(edt_Pagina.Text) + 1);
|
|
|
|
if (pag > totalPaginas) return;
|
|
|
|
edt_Pagina.Text = pag.ToString();
|
|
_clickPorCodigo = true;
|
|
BTN_Buscar.PerformClick();
|
|
|
|
}
|
|
|
|
private void btn_anterior_Click(object sender, EventArgs e)
|
|
{
|
|
int pag = (int.Parse(edt_Pagina.Text) - 1);
|
|
if (pag <= 0)
|
|
{
|
|
return;
|
|
}
|
|
edt_Pagina.Text = pag.ToString();
|
|
_clickPorCodigo = true;
|
|
BTN_Buscar.PerformClick();
|
|
}
|
|
|
|
private void btn_inicio_Click(object sender, EventArgs e)
|
|
{
|
|
edt_Pagina.Text = "1";
|
|
_clickPorCodigo = true;
|
|
BTN_Buscar.PerformClick();
|
|
}
|
|
|
|
private async void btn_ultimo_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
long totalPaginas = await TotalPaginas(edt_BuscarExpediente.Text);
|
|
edt_Pagina.Text = totalPaginas.ToString();
|
|
_clickPorCodigo = true;
|
|
BTN_Buscar.PerformClick();
|
|
|
|
}
|
|
|
|
private async Task<long> TotalPaginas(string busqueda)
|
|
{
|
|
long total = 0;
|
|
|
|
if (string.IsNullOrEmpty(busqueda))
|
|
{
|
|
total = await _sqliteHelper.TotalExpedientes("*");
|
|
}
|
|
else if (string.IsNullOrWhiteSpace(busqueda))
|
|
{
|
|
total = await _sqliteHelper.TotalExpedientes("*");
|
|
}
|
|
else
|
|
{
|
|
total = await _sqliteHelper.TotalExpedientes(busqueda);
|
|
}
|
|
|
|
long resto = total % paginacion;
|
|
|
|
long totalPaginas = ((total - resto) / paginacion);
|
|
|
|
if (resto > 0) totalPaginas += 1;
|
|
|
|
return totalPaginas;
|
|
|
|
}
|
|
private void ActualizarEtiqueta()
|
|
{
|
|
|
|
// Si el llamado llega desde otro hilo, lo redirigimos al UI
|
|
if (lblPaginacion.InvokeRequired)
|
|
{
|
|
lblPaginacion.BeginInvoke((MethodInvoker)(() =>
|
|
lblPaginacion.Text = $"[Registro {_paginacion._registro.ToString()} de {_paginacion._registros.ToString()}][Página {_paginacion._pagina.ToString()} de {_paginacion._paginas.ToString()}]"));
|
|
return;
|
|
}
|
|
|
|
// Ya estamos en el hilo UI
|
|
lblPaginacion.Text = $"[Registro {_paginacion._registro.ToString()} de {_paginacion._registros.ToString()}][Página {_paginacion._pagina.ToString()} de {_paginacion._paginas.ToString()}]";
|
|
|
|
|
|
}
|
|
|
|
private void dgwExpedientes_SelectionChanged(object sender, EventArgs e)
|
|
{
|
|
if (dgwExpedientes.CurrentRow == null) return;
|
|
|
|
int indiceFila = dgwExpedientes.CurrentRow.Index;
|
|
|
|
_paginacion._registro = (indiceFila + 1);
|
|
|
|
ActualizarEtiqueta();
|
|
|
|
}
|
|
|
|
private void edt_BuscarExpediente_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
if (e.KeyChar == (char)Keys.Return)
|
|
{
|
|
e.Handled = true;
|
|
BTN_Buscar.PerformClick();
|
|
}
|
|
}
|
|
|
|
private async void dgwExpedientes_CellClick(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
if (e.RowIndex < 0)
|
|
return;
|
|
|
|
var column = dgwExpedientes.Columns[e.ColumnIndex];
|
|
|
|
if (column.Name == "Acciones")
|
|
{
|
|
object? cellValueExp = dgwExpedientes.Rows[e.RowIndex].Cells["Expediente"].Value;
|
|
object? cellValueTask = dgwExpedientes.Rows[e.RowIndex].Cells["TaskId"].Value;
|
|
|
|
string? expediente = cellValueExp?.ToString();
|
|
string? taskId = cellValueTask?.ToString();
|
|
|
|
if (string.IsNullOrEmpty(taskId))
|
|
return;
|
|
|
|
//// Ejecutar trabajo pesado en segundo plano
|
|
//var resultado = await Task.Run(() =>
|
|
//{
|
|
// // Simulación de proceso pesado
|
|
// Thread.Sleep(1000);
|
|
// return $"Procesado expediente {taskId}";
|
|
//});
|
|
|
|
//MessageBox.Show(resultado);
|
|
|
|
string responseJson = await ConsultarEstadoTareaAsync(taskId);
|
|
|
|
await ProcesarRespuestaTareaAsync(responseJson, expediente);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|