ultimos cambios
This commit is contained in:
58
AdminFinanceRCA/ComboMessageBox.cs
Normal file
58
AdminFinanceRCA/ComboMessageBox.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Layout;
|
||||||
|
|
||||||
|
namespace AdminFinanceRCA;
|
||||||
|
|
||||||
|
public class ComboMessageBox<T> : Window
|
||||||
|
{
|
||||||
|
private ComboBox _comboBox;
|
||||||
|
private Button _okButton;
|
||||||
|
private Button _cancelButton;
|
||||||
|
private object _result;
|
||||||
|
|
||||||
|
public ComboMessageBox(IEnumerable<T> items, string title = "Seleccione una opción")
|
||||||
|
{
|
||||||
|
Title = title;
|
||||||
|
Width = 300;
|
||||||
|
Height = 150;
|
||||||
|
|
||||||
|
var stackPanel = new StackPanel { Margin = new Thickness(10) };
|
||||||
|
|
||||||
|
_comboBox = new ComboBox
|
||||||
|
{
|
||||||
|
ItemsSource = items,
|
||||||
|
SelectedIndex = 0
|
||||||
|
};
|
||||||
|
stackPanel.Children.Add(_comboBox);
|
||||||
|
|
||||||
|
var buttonPanel = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right };
|
||||||
|
_okButton = new Button { Content = "Aceptar", Margin = new Thickness(5) };
|
||||||
|
_cancelButton = new Button { Content = "Cancelar", Margin = new Thickness(5) };
|
||||||
|
|
||||||
|
_okButton.Click += (_, __) =>
|
||||||
|
{
|
||||||
|
_result = _comboBox.SelectedItem;//?.ToString();
|
||||||
|
Close(_result);
|
||||||
|
};
|
||||||
|
|
||||||
|
_cancelButton.Click += (_, __) =>
|
||||||
|
{
|
||||||
|
Close(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
buttonPanel.Children.Add(_okButton);
|
||||||
|
buttonPanel.Children.Add(_cancelButton);
|
||||||
|
|
||||||
|
stackPanel.Children.Add(buttonPanel);
|
||||||
|
Content = stackPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<T> ShowDialog(Window parent, IEnumerable<T> items, string title = "Seleccione")
|
||||||
|
{
|
||||||
|
var msgBox = new ComboMessageBox<T>(items, title);
|
||||||
|
return await msgBox.ShowDialog<T>(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -124,3 +124,10 @@ public class MovimientoCompleto : ObservableObject
|
|||||||
|
|
||||||
public IBrush ForegroundColor => TipoMovNombre == "Egreso" ? Brushes.Red : Brushes.Black;
|
public IBrush ForegroundColor => TipoMovNombre == "Egreso" ? Brushes.Red : Brushes.Black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class MesItem
|
||||||
|
{
|
||||||
|
public int Value { get; set; } // Número del mes (1-12)
|
||||||
|
public string Nombre { get; set; } // Nombre del mes
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,6 +122,27 @@ public class FinanzasRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<IEnumerable<MovimientoCompleto>> GetMovimientoByGrupoTrabajoAsync(int idGrupoTrabajo)
|
||||||
|
{
|
||||||
|
using (var connection = GetConnection())
|
||||||
|
{
|
||||||
|
var sql = @"SELECT
|
||||||
|
m.ID, m.Monto, m.FechaMovimiento, m.FechaRegistro, m.Descripcion,
|
||||||
|
tm.ID as TipoMovID, tm.Nombre as TipoMovNombre,
|
||||||
|
dt.Id as DeptoTrabajoID, dt.Nombre as DeptoTrabajoNombre,
|
||||||
|
c.ID as ConceptoID, c.Nombre as ConceptoNombre,
|
||||||
|
m.Nota as Nota
|
||||||
|
FROM Movimientos m
|
||||||
|
INNER JOIN TipoMovimiento tm ON m.TipoMov = tm.ID
|
||||||
|
INNER JOIN DepartTrabajo dt ON m.DeptoTrabajo = dt.Id
|
||||||
|
INNER JOIN Concepto c ON m.Concepto = c.ID
|
||||||
|
WHERE DeptoTrabajo = @idGrupoTrabajo
|
||||||
|
ORDER BY m.FechaMovimiento DESC";
|
||||||
|
return await connection.QueryAsync<MovimientoCompleto>(sql, new { idGrupoTrabajo = idGrupoTrabajo });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Movimiento> GetMovimientoByIdAsync(int id)
|
public async Task<Movimiento> GetMovimientoByIdAsync(int id)
|
||||||
{
|
{
|
||||||
using (var connection = GetConnection())
|
using (var connection = GetConnection())
|
||||||
@@ -131,6 +152,64 @@ public class FinanzasRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<MovimientoCompleto>> GetMovimientosFiltradosAsync(
|
||||||
|
int? deptoTrabajo = null,
|
||||||
|
int? mes = null,
|
||||||
|
int? anio = null,
|
||||||
|
int? tipoMov = null,
|
||||||
|
int? concepto = null)
|
||||||
|
{
|
||||||
|
using (var connection = GetConnection())
|
||||||
|
{
|
||||||
|
var sql = @"SELECT
|
||||||
|
m.ID, m.Monto, m.FechaMovimiento, m.FechaRegistro, m.Descripcion,
|
||||||
|
tm.ID as TipoMovID, tm.Nombre as TipoMovNombre,
|
||||||
|
dt.Id as DeptoTrabajoID, dt.Nombre as DeptoTrabajoNombre,
|
||||||
|
c.ID as ConceptoID, c.Nombre as ConceptoNombre,
|
||||||
|
m.Nota as Nota
|
||||||
|
FROM Movimientos m
|
||||||
|
INNER JOIN TipoMovimiento tm ON m.TipoMov = tm.ID
|
||||||
|
INNER JOIN DepartTrabajo dt ON m.DeptoTrabajo = dt.Id
|
||||||
|
INNER JOIN Concepto c ON m.Concepto = c.ID
|
||||||
|
WHERE 1=1";
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (deptoTrabajo.HasValue)
|
||||||
|
{
|
||||||
|
sql += " AND DeptoTrabajo = @DeptoTrabajo";
|
||||||
|
parameters.Add("DeptoTrabajo", deptoTrabajo.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mes.HasValue)
|
||||||
|
{
|
||||||
|
sql += " AND strftime('%m', FechaMovimiento) = @Mes";
|
||||||
|
// strftime devuelve con cero adelante ("01","02"...)
|
||||||
|
parameters.Add("Mes", mes.Value.ToString("D2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anio.HasValue)
|
||||||
|
{
|
||||||
|
sql += " AND strftime('%Y', FechaMovimiento) = @Anio";
|
||||||
|
parameters.Add("Anio", anio.Value.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tipoMov.HasValue)
|
||||||
|
{
|
||||||
|
sql += " AND TipoMov = @TipoMov";
|
||||||
|
parameters.Add("TipoMov", tipoMov.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (concepto.HasValue)
|
||||||
|
{
|
||||||
|
sql += " AND Concepto = @Concepto";
|
||||||
|
parameters.Add("Concepto", concepto.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await connection.QueryAsync<MovimientoCompleto>(sql, parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<bool> UpdateMovimientoAsync(Movimiento movimiento)
|
public async Task<bool> UpdateMovimientoAsync(Movimiento movimiento)
|
||||||
{
|
{
|
||||||
using (var connection = GetConnection())
|
using (var connection = GetConnection())
|
||||||
@@ -303,7 +382,7 @@ public class FinanzasRepository
|
|||||||
// Datos
|
// Datos
|
||||||
foreach (var mov in movimientos)
|
foreach (var mov in movimientos)
|
||||||
{
|
{
|
||||||
csv.AppendLine($"{mov.ID};{mov.FechaMovimiento:yyyy-MM-dd};{mov.Monto};" +
|
csv.AppendLine($"{mov.ID};{mov.FechaMovimiento:yyyy-MM-dd};{mov.Monto.ToString().Replace('.', ',')};" +
|
||||||
$"{mov.TipoMovNombre};{mov.DeptoTrabajoNombre};{mov.ConceptoNombre};" +
|
$"{mov.TipoMovNombre};{mov.DeptoTrabajoNombre};{mov.ConceptoNombre};" +
|
||||||
$"\"{mov.Descripcion}\"");
|
$"\"{mov.Descripcion}\"");
|
||||||
}
|
}
|
||||||
@@ -314,5 +393,27 @@ public class FinanzasRepository
|
|||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<string> ExportToCsvAsync(string filePath, int departamentoTrabajo)
|
||||||
|
{
|
||||||
|
var movimientos = await GetMovimientoByGrupoTrabajoAsync(departamentoTrabajo);
|
||||||
|
var csv = new StringBuilder();
|
||||||
|
|
||||||
|
// Encabezados
|
||||||
|
csv.AppendLine("ID;FechaMovimiento;Monto;TipoMovimiento;Departamento;Concepto;Descripcion");
|
||||||
|
|
||||||
|
// Datos
|
||||||
|
foreach (var mov in movimientos)
|
||||||
|
{
|
||||||
|
csv.AppendLine($"{mov.ID};{mov.FechaMovimiento:yyyy-MM-dd};{mov.Monto.ToString().Replace('.', ',')};" +
|
||||||
|
$"\"{mov.TipoMovNombre}\";\"{mov.DeptoTrabajoNombre}\";\"{mov.ConceptoNombre}\";" +
|
||||||
|
$"\"{mov.Descripcion}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guardar archivo
|
||||||
|
await File.WriteAllTextAsync(filePath, csv.ToString(), Encoding.UTF8);
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AdminFinanceRCA.Models;
|
using AdminFinanceRCA.Models;
|
||||||
using AdminFinanceRCA.Views;
|
using AdminFinanceRCA.Views;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Media;
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
|
||||||
@@ -20,7 +20,13 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
[ObservableProperty] private ObservableCollection<DepartTrabajo> _departamentos;
|
[ObservableProperty] private ObservableCollection<DepartTrabajo> _departamentos;
|
||||||
[ObservableProperty] private ObservableCollection<TipoMovimiento> _tiposMovimiento;
|
[ObservableProperty] private ObservableCollection<TipoMovimiento> _tiposMovimiento;
|
||||||
[ObservableProperty] private MovimientoCompleto _movimientoSeleccionado;
|
[ObservableProperty] private MovimientoCompleto _movimientoSeleccionado;
|
||||||
|
[ObservableProperty] private DepartTrabajo _departamentoSeleccionado;
|
||||||
|
[ObservableProperty] private ObservableCollection<int> _anios;
|
||||||
|
[ObservableProperty] private ObservableCollection<MesItem> _meses;
|
||||||
|
[ObservableProperty] private int _anioSelect;
|
||||||
|
[ObservableProperty] private MesItem _mesSelect;
|
||||||
|
[ObservableProperty] private int _anioIndex;
|
||||||
|
[ObservableProperty] private int _mesIndex;
|
||||||
public MainWindowViewModel()
|
public MainWindowViewModel()
|
||||||
{
|
{
|
||||||
_repository = new FinanzasRepository();
|
_repository = new FinanzasRepository();
|
||||||
@@ -126,6 +132,39 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task<(string, DepartTrabajo)> ShowSaveFileDialogForGrupoTrabajoAsync(Window window, string defaultFileName = "movimientos.csv")
|
||||||
|
{
|
||||||
|
|
||||||
|
var dpt = await _repository.GetAllDepartamentosAsync();
|
||||||
|
List<DepartTrabajo> dt = dpt.ToList();
|
||||||
|
var seleccion = await ComboMessageBox<DepartTrabajo>.ShowDialog(GetCurrentWindow<MainWindow>(), dt, "Escoge una opción");
|
||||||
|
|
||||||
|
|
||||||
|
var saveFileDialog = new SaveFileDialog
|
||||||
|
{
|
||||||
|
Title = "Guardar archivo CSV",
|
||||||
|
InitialFileName = defaultFileName,
|
||||||
|
DefaultExtension = "csv",
|
||||||
|
Filters = new List<FileDialogFilter>
|
||||||
|
{
|
||||||
|
new FileDialogFilter
|
||||||
|
{
|
||||||
|
Name = "Archivos CSV",
|
||||||
|
Extensions = new List<string> { "csv" }
|
||||||
|
},
|
||||||
|
new FileDialogFilter
|
||||||
|
{
|
||||||
|
Name = "Todos los archivos",
|
||||||
|
Extensions = new List<string> { "*" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = await saveFileDialog.ShowAsync(window);
|
||||||
|
return (result, seleccion);
|
||||||
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async void CrearCsv()
|
public async void CrearCsv()
|
||||||
{
|
{
|
||||||
@@ -134,10 +173,12 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
var window = GetCurrentWindow<MainWindow>(); //WindowService?.GetActiveWindow() ?? WindowService?.GetWindowForViewModel(this);
|
var window = GetCurrentWindow<MainWindow>(); //WindowService?.GetActiveWindow() ?? WindowService?.GetWindowForViewModel(this);
|
||||||
if (window != null)
|
if (window != null)
|
||||||
{
|
{
|
||||||
string result = await ShowSaveFileDialogAsync(window);
|
//string result = await ShowSaveFileDialogAsync(window);
|
||||||
if (!string.IsNullOrEmpty(result))
|
var dt = await ShowSaveFileDialogForGrupoTrabajoAsync(window);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(dt.Item1))
|
||||||
{
|
{
|
||||||
var filePath = await _repository.ExportToCsvAsync(result);
|
var filePath = await _repository.ExportToCsvAsync(dt.Item1, dt.Item2.Id);
|
||||||
Console.WriteLine($"CSV creado en: {filePath}");
|
Console.WriteLine($"CSV creado en: {filePath}");
|
||||||
|
|
||||||
// Opcional: abrir el archivo con la aplicación predeterminada
|
// Opcional: abrir el archivo con la aplicación predeterminada
|
||||||
@@ -152,6 +193,47 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task FiltrarDatos()
|
||||||
|
{
|
||||||
|
if (DepartamentoSeleccionado != null)
|
||||||
|
{
|
||||||
|
var movFilter = _repository.GetMovimientosFiltradosAsync(DepartamentoSeleccionado.Id, MesSelect.Value, AnioSelect);
|
||||||
|
Movimientos = new ObservableCollection<MovimientoCompleto>(await movFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ObtenerAnios()
|
||||||
|
{
|
||||||
|
Anios = new ObservableCollection<int>();
|
||||||
|
int añoActual = DateTime.Now.Year;
|
||||||
|
for (int i = 0; i <= 5; i++)
|
||||||
|
{
|
||||||
|
Anios.Add(añoActual - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ObtenerMeses(int añoSeleccionado)
|
||||||
|
{
|
||||||
|
Meses = new ObservableCollection<MesItem>();
|
||||||
|
|
||||||
|
// Obtenemos el mes actual
|
||||||
|
int mesActual = DateTime.Now.Month;
|
||||||
|
|
||||||
|
// Definimos hasta qué mes llenar según el año
|
||||||
|
int mesLimite = añoSeleccionado == DateTime.Now.Year ? mesActual : 12;
|
||||||
|
|
||||||
|
for (int i = 1; i <= mesLimite; i++)
|
||||||
|
{
|
||||||
|
Meses.Add(new MesItem
|
||||||
|
{
|
||||||
|
Value = i,
|
||||||
|
Nombre = new DateTime(añoSeleccionado, i, 1).ToString("MMMM") // Nombre completo del mes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public async void CargarDatos()
|
public async void CargarDatos()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -168,6 +250,10 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
Conceptos = new ObservableCollection<Concepto>(await conceptosTask);
|
Conceptos = new ObservableCollection<Concepto>(await conceptosTask);
|
||||||
Departamentos = new ObservableCollection<DepartTrabajo>(await departamentosTask);
|
Departamentos = new ObservableCollection<DepartTrabajo>(await departamentosTask);
|
||||||
TiposMovimiento = new ObservableCollection<TipoMovimiento>(await tiposTask);
|
TiposMovimiento = new ObservableCollection<TipoMovimiento>(await tiposTask);
|
||||||
|
ObtenerAnios();
|
||||||
|
ObtenerMeses(DateTime.Now.Year);
|
||||||
|
MesIndex = 0;
|
||||||
|
AnioIndex = 0;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,7 +47,27 @@
|
|||||||
<TextBlock FontSize="24" Margin="0 15" Text="Administrador Financiero Grupos"
|
<TextBlock FontSize="24" Margin="0 15" Text="Administrador Financiero Grupos"
|
||||||
Foreground="Black" FontWeight="SemiBold"/>
|
Foreground="Black" FontWeight="SemiBold"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Spacing="10">
|
||||||
|
<Label VerticalAlignment="Center" >Grupo:</Label>
|
||||||
|
<ComboBox ItemsSource="{Binding Departamentos}" SelectedItem="{Binding DepartamentoSeleccionado}" Width="200" >
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding Nombre}"></TextBlock>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
<Label VerticalAlignment="Center">Mes:</Label>
|
||||||
|
<ComboBox ItemsSource="{Binding Meses}" SelectedIndex="{Binding MesIndex}" SelectedItem="{Binding MesSelect}" Width="150" >
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding Nombre}"></TextBlock>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
<Label VerticalAlignment="Center">Año:</Label>
|
||||||
|
<ComboBox ItemsSource="{Binding Anios}" SelectedIndex="{Binding AnioIndex}" SelectedItem="{Binding AnioSelect}" Width="100"></ComboBox>
|
||||||
|
<Button VerticalAlignment="Center" Command="{Binding FiltrarDatosCommand}">Filtrar</Button>
|
||||||
|
</StackPanel>
|
||||||
<!-- Botones flotantes estilo moderno -->
|
<!-- Botones flotantes estilo moderno -->
|
||||||
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 10 20 20">
|
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 10 20 20">
|
||||||
<Button Content="Agregar Movimiento"
|
<Button Content="Agregar Movimiento"
|
||||||
|
|||||||
Reference in New Issue
Block a user