Mejoras
This commit is contained in:
@@ -3,13 +3,12 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AdminFinanceRCA.Models;
|
||||
|
||||
namespace AdminFinanceRCA;
|
||||
|
||||
using System.Data;
|
||||
using Dapper;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
namespace AdminFinanceRCA;
|
||||
|
||||
public class FinanzasRepository
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
@@ -20,7 +19,6 @@ public class FinanzasRepository
|
||||
_connectionString = config.GetConnectionString();
|
||||
InitializeDatabase();
|
||||
}
|
||||
// Constructor alternativo para testing
|
||||
public FinanzasRepository(string connectionString)
|
||||
{
|
||||
_connectionString = connectionString;
|
||||
@@ -42,7 +40,8 @@ public class FinanzasRepository
|
||||
connection.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS DepartTrabajo (
|
||||
Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
Nombre TEXT NOT NULL
|
||||
Nombre TEXT NOT NULL,
|
||||
Descripcion TEXT NULL
|
||||
)");
|
||||
|
||||
connection.Execute(@"
|
||||
@@ -69,40 +68,6 @@ public class FinanzasRepository
|
||||
// Crear índice
|
||||
connection.Execute(@"
|
||||
CREATE INDEX IF NOT EXISTS Mov ON Movimientos (Concepto ASC, TipoMov ASC)");
|
||||
|
||||
// Insertar datos básicos si las tablas están vacías
|
||||
InsertarDatosBasicos(connection);
|
||||
}
|
||||
}
|
||||
|
||||
private void InsertarDatosBasicos(SqliteConnection connection)
|
||||
{
|
||||
// Verificar si TipoMovimiento está vacío
|
||||
var countTipos = connection.ExecuteScalar<int>("SELECT COUNT(*) FROM TipoMovimiento");
|
||||
if (countTipos == 0)
|
||||
{
|
||||
connection.Execute("INSERT INTO TipoMovimiento (Nombre) VALUES ('Ingreso')");
|
||||
connection.Execute("INSERT INTO TipoMovimiento (Nombre) VALUES ('Egreso')");
|
||||
}
|
||||
|
||||
// Verificar si Concepto está vacío
|
||||
var countConceptos = connection.ExecuteScalar<int>("SELECT COUNT(*) FROM Concepto");
|
||||
if (countConceptos == 0)
|
||||
{
|
||||
connection.Execute("INSERT INTO Concepto (Nombre) VALUES ('Ventas')");
|
||||
connection.Execute("INSERT INTO Concepto (Nombre) VALUES ('Compras')");
|
||||
connection.Execute("INSERT INTO Concepto (Nombre) VALUES ('Nómina')");
|
||||
connection.Execute("INSERT INTO Concepto (Nombre) VALUES ('Servicios')");
|
||||
}
|
||||
|
||||
// Verificar si DepartTrabajo está vacío
|
||||
var countDeptos = connection.ExecuteScalar<int>("SELECT COUNT(*) FROM DepartTrabajo");
|
||||
if (countDeptos == 0)
|
||||
{
|
||||
connection.Execute("INSERT INTO DepartTrabajo (Nombre) VALUES ('Administración')");
|
||||
connection.Execute("INSERT INTO DepartTrabajo (Nombre) VALUES ('Ventas')");
|
||||
connection.Execute("INSERT INTO DepartTrabajo (Nombre) VALUES ('Producción')");
|
||||
connection.Execute("INSERT INTO DepartTrabajo (Nombre) VALUES ('Logística')");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +183,6 @@ public class FinanzasRepository
|
||||
#endregion
|
||||
|
||||
#region Operaciones para DepartTrabajo
|
||||
|
||||
public async Task<IEnumerable<DepartTrabajo>> GetAllDepartamentosAsync()
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
@@ -249,7 +213,6 @@ public class FinanzasRepository
|
||||
return rowsAffected > 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operaciones para TipoMovimiento
|
||||
|
||||
@@ -5,9 +5,7 @@ using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using AdminFinanceRCA.Models;
|
||||
using AdminFinanceRCA.Views;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
@@ -45,12 +43,22 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
public void AgregarMovimiento()
|
||||
{
|
||||
MovimientoWindowViewModel mwvm = new MovimientoWindowViewModel();
|
||||
|
||||
MovimientoWindow mw = new MovimientoWindow();
|
||||
mwvm.ReloadEvent+= MwvmOnReloadEvent;
|
||||
MovimientoWindow mw = new MovimientoWindow()
|
||||
{
|
||||
Width = 600,
|
||||
Height = 400,
|
||||
};
|
||||
mw.DataContext = mwvm;
|
||||
mw.ShowDialog(GetCurrentWindow<MainWindow>());
|
||||
}
|
||||
|
||||
private async void MwvmOnReloadEvent(object? sender, EventArgs e)
|
||||
{
|
||||
var movimientosTask = _repository.GetAllMovimientosCompletosAsync();
|
||||
Movimientos = new ObservableCollection<MovimientoCompleto>(await movimientosTask);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void Salir()
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using AdminFinanceRCA.Models;
|
||||
@@ -12,7 +13,7 @@ namespace AdminFinanceRCA.ViewModels;
|
||||
public partial class Mantenimiento_DepartTrabajoViewModel : ViewModelBase
|
||||
{
|
||||
private readonly FinanzasRepository _departTrabajoService;
|
||||
|
||||
public event EventHandler? ReloadEvent;
|
||||
[ObservableProperty] private ObservableCollection<DepartTrabajo> _gruposTrabajo;
|
||||
[ObservableProperty] private DepartTrabajo _grupoSeleccionado;
|
||||
[ObservableProperty] private DepartTrabajo _grupoEditando;
|
||||
@@ -43,24 +44,54 @@ public partial class Mantenimiento_DepartTrabajoViewModel : ViewModelBase
|
||||
[RelayCommand]
|
||||
private async Task GuardarRegistros()
|
||||
{
|
||||
|
||||
string[] mensaje = {"", string.Empty};
|
||||
if (EstaEditando)
|
||||
{
|
||||
GrupoSeleccionado.Nombre = Nombre;
|
||||
GrupoSeleccionado.Descripcion = Descripcion;
|
||||
_departTrabajoService.UpdateDepartamentoAsync(GrupoSeleccionado);
|
||||
try
|
||||
{
|
||||
GrupoSeleccionado.Nombre = Nombre;
|
||||
GrupoSeleccionado.Descripcion = Descripcion;
|
||||
_departTrabajoService.UpdateDepartamentoAsync(GrupoSeleccionado);
|
||||
mensaje = new[] { "Exito", "Registro actualizado con exito" };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
mensaje = new[] { "Error", ex.Message };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(string.IsNullOrEmpty(Nombre))
|
||||
return;
|
||||
try
|
||||
{
|
||||
if(string.IsNullOrEmpty(Nombre))
|
||||
return;
|
||||
|
||||
DepartTrabajo depart = new DepartTrabajo(Nombre, Descripcion);
|
||||
await _departTrabajoService.CreateDepartamentoAsync(depart);
|
||||
Nombre = string.Empty;
|
||||
Descripcion = string.Empty;
|
||||
var dt = MessageBoxManager.GetMessageBoxStandard("Exito", "Registro agregado con exito", ButtonEnum.Ok);
|
||||
await dt.ShowAsPopupAsync(GetCurrentWindow<Mantenimiento_DepartTrabajo>());
|
||||
DepartTrabajo depart = new DepartTrabajo(Nombre, Descripcion);
|
||||
await _departTrabajoService.CreateDepartamentoAsync(depart);
|
||||
Nombre = string.Empty;
|
||||
Descripcion = string.Empty;
|
||||
|
||||
mensaje = new[] { "Exito", "Registro agregado con exito" };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
mensaje = new[] { "Error", ex.Message };
|
||||
}
|
||||
}
|
||||
var dt = MessageBoxManager.GetMessageBoxStandard(mensaje[0], mensaje[1], ButtonEnum.Ok);
|
||||
await dt.ShowAsPopupAsync(GetCurrentWindow<Mantenimiento_DepartTrabajo>());
|
||||
OnReloadEvent();
|
||||
await CargarDatosAsync();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void Cancelar()
|
||||
{
|
||||
this.GetCurrentWindow<Mantenimiento_DepartTrabajo>().Close();
|
||||
}
|
||||
|
||||
protected virtual void OnReloadEvent()
|
||||
{
|
||||
ReloadEvent?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using AdminFinanceRCA.Models;
|
||||
@@ -13,11 +14,11 @@ namespace AdminFinanceRCA.ViewModels;
|
||||
public partial class MovimientoWindowViewModel : ViewModelBase
|
||||
{
|
||||
private readonly FinanzasRepository _finanzasRepository;
|
||||
|
||||
public event EventHandler? ReloadEvent;
|
||||
[ObservableProperty] private ObservableCollection<DepartTrabajo> _departTrabajos;
|
||||
[ObservableProperty] private ObservableCollection<TipoMovimiento> _tipoMovimientos;
|
||||
[ObservableProperty] private ObservableCollection<Concepto> _conceptos;
|
||||
[ObservableProperty] private DateTime _fechaMov;
|
||||
[ObservableProperty] private DateTimeOffset _fechaMov;
|
||||
[ObservableProperty] private decimal _montoDecimal;
|
||||
[ObservableProperty] private string _descripcion;
|
||||
[ObservableProperty] private TipoMovimiento _tipoMovimientoSelecionado;
|
||||
@@ -26,7 +27,7 @@ public partial class MovimientoWindowViewModel : ViewModelBase
|
||||
|
||||
public MovimientoWindowViewModel()
|
||||
{
|
||||
_fechaMov = DateTime.Now;
|
||||
_fechaMov = DateTimeOffset.Now;
|
||||
_finanzasRepository = new FinanzasRepository();
|
||||
_ = CargarDatosAsync();
|
||||
}
|
||||
@@ -35,22 +36,90 @@ public partial class MovimientoWindowViewModel : ViewModelBase
|
||||
{
|
||||
var dt = await _finanzasRepository.GetAllDepartamentosAsync();
|
||||
DepartTrabajos = new ObservableCollection<DepartTrabajo>(dt);
|
||||
|
||||
var tm = await _finanzasRepository.GetAllTiposMovimientoAsync();
|
||||
TipoMovimientos = new ObservableCollection<TipoMovimiento>(tm);
|
||||
|
||||
var cpt = await _finanzasRepository.GetAllConceptosAsync();
|
||||
Conceptos = new ObservableCollection<Concepto>(cpt);
|
||||
DepartaDepartTrabajoSeleccionado = DepartTrabajos[0];
|
||||
TipoMovimientoSelecionado = TipoMovimientos[0];
|
||||
ConceptoSeleccionado = Conceptos[0];
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public async void GuardarDatosAsync()
|
||||
{
|
||||
Movimiento mv = new Movimiento(MontoDecimal, TipoMovimientoSelecionado.ID, DepartaDepartTrabajoSeleccionado.Id,
|
||||
FechaMov, ConceptoSeleccionado.ID, Descripcion);
|
||||
await _finanzasRepository.CreateMovimientoAsync(mv);
|
||||
var dt = MessageBoxManager.GetMessageBoxStandard("", "Se guardo con exito", ButtonEnum.Ok);
|
||||
await dt.ShowAsPopupAsync(GetCurrentWindow<MovimientoWindow>());
|
||||
try
|
||||
{
|
||||
// Validar campos obligatorios
|
||||
if (!ValidarCamposObligatorios())
|
||||
{
|
||||
return; // Detener ejecución si hay campos inválidos
|
||||
}
|
||||
Movimiento mv = new Movimiento(MontoDecimal, TipoMovimientoSelecionado.ID, DepartaDepartTrabajoSeleccionado.Id,
|
||||
DateTime.Parse(FechaMov.ToString("yyyy-MM-dd")), ConceptoSeleccionado.ID, Descripcion);
|
||||
await _finanzasRepository.CreateMovimientoAsync(mv);
|
||||
var dt = MessageBoxManager.GetMessageBoxStandard("", "Se guardo con exito", ButtonEnum.Ok);
|
||||
await dt.ShowAsPopupAsync(GetCurrentWindow<MovimientoWindow>());
|
||||
|
||||
MontoDecimal = 0;
|
||||
Descripcion = "";
|
||||
OnReloadEvent();
|
||||
}catch(Exception ex){
|
||||
var errorMsg = MessageBoxManager.GetMessageBoxStandard("Error", $"Ocurrió un error: {ex.Message}", ButtonEnum.Ok);
|
||||
await errorMsg.ShowAsPopupAsync(GetCurrentWindow<MovimientoWindow>());
|
||||
}
|
||||
}
|
||||
private bool ValidarCamposObligatorios()
|
||||
{
|
||||
var mensajesError = new List<string>();
|
||||
|
||||
// Validar MontoDecimal
|
||||
if (MontoDecimal <= 0)
|
||||
{
|
||||
mensajesError.Add("• Debe agregar un monto válido (mayor a 0)");
|
||||
}
|
||||
|
||||
// Validar TipoMovimientoSelecionado
|
||||
if (TipoMovimientoSelecionado == null || TipoMovimientoSelecionado.ID <= 0)
|
||||
{
|
||||
mensajesError.Add("• Debe seleccionar un tipo de movimiento");
|
||||
}
|
||||
|
||||
// Validar DepartaDepartTrabajoSeleccionado
|
||||
if (DepartaDepartTrabajoSeleccionado == null || DepartaDepartTrabajoSeleccionado.Id <= 0)
|
||||
{
|
||||
mensajesError.Add("• Debe seleccionar un departamento/trabajo");
|
||||
}
|
||||
|
||||
// Validar FechaMov
|
||||
if (FechaMov == default(DateTime) || FechaMov > DateTime.Now)
|
||||
{
|
||||
mensajesError.Add("• Debe seleccionar una fecha válida (no puede ser futura)");
|
||||
}
|
||||
|
||||
// Validar ConceptoSeleccionado
|
||||
if (ConceptoSeleccionado == null || ConceptoSeleccionado.ID <= 0)
|
||||
{
|
||||
mensajesError.Add("• Debe seleccionar un concepto");
|
||||
}
|
||||
|
||||
// Si hay errores, mostrar mensaje
|
||||
if (mensajesError.Count > 0)
|
||||
{
|
||||
var mensajeCompleto = "Por favor, complete los siguientes campos:\n\n" + string.Join("\n", mensajesError);
|
||||
|
||||
var errorMsg = MessageBoxManager.GetMessageBoxStandard("Campos requeridos", mensajeCompleto, ButtonEnum.Ok);
|
||||
errorMsg.ShowAsPopupAsync(GetCurrentWindow<MovimientoWindow>());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void OnReloadEvent()
|
||||
{
|
||||
ReloadEvent?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<DockPanel Margin="10">
|
||||
<!-- Barra de herramientas -->
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,10" Spacing="5">
|
||||
<Button Content="Nuevo" Width="90" Command="{Binding NuevoDepartTrabajoCommand}" />
|
||||
<Button Content="Guardar" Width="90" Command="{Binding GuardarRegistrosCommand}"/>
|
||||
<Button Content="Cancelar" Width="90" />
|
||||
<Button Content="Nuevo" Background="DarkBlue" Foreground="White" HorizontalContentAlignment="Center" Width="90" Command="{Binding NuevoDepartTrabajoCommand}" />
|
||||
<Button Content="Guardar" Background="DarkGreen" Foreground="White" HorizontalContentAlignment="Center" Width="90" Command="{Binding GuardarRegistrosCommand}"/>
|
||||
<Button Content="Cancelar" Background="DarkRed" Foreground="White" HorizontalContentAlignment="Center" Width="90" Command="{Binding CancelarCommand}" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid ColumnDefinitions="*,2*" Margin="0,10,0,0" ShowGridLines="False">
|
||||
@@ -27,15 +27,12 @@
|
||||
<StackPanel Grid.Column="0" Margin="0,0,10,0">
|
||||
<TextBlock Text="Grupos de Trabajo" FontWeight="Bold" Margin="0,0,0,5"/>
|
||||
<ListBox ItemsSource="{Binding GruposTrabajo}" DoubleTapped="OnListBoxDoubleTapped"
|
||||
Height="200">
|
||||
Height="250">
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Margin="5">
|
||||
<TextBlock FontWeight="Bold"/>
|
||||
<TextBlock Foreground="Gray" Text="{Binding Nombre}"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
<TextBlock />
|
||||
<TextBlock Text="{Binding Nombre}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<!-- Departamento de Trabajo -->
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Departamento:" VerticalAlignment="Center" Margin="0 5"/>
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding DepartTrabajos}" SelectedItem="{Binding DepartaDepartTrabajoSeleccionado}">
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" Width="250" ItemsSource="{Binding DepartTrabajos}" SelectedItem="{Binding DepartaDepartTrabajoSeleccionado}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Nombre}" />
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
<!-- Tipo de Movimiento -->
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Tipo Movimiento:" VerticalAlignment="Center" Margin="0 5"/>
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" Margin="0 5" ItemsSource="{Binding TipoMovimientos}" SelectedItem="{Binding TipoMovimientoSelecionado}">
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" Width="250" Margin="0 5" ItemsSource="{Binding TipoMovimientos}" SelectedItem="{Binding TipoMovimientoSelecionado}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Nombre}" />
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
<!-- Concepto -->
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="Concepto:" VerticalAlignment="Center" Margin="0 5"/>
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" Margin="0 0" ItemsSource="{Binding Conceptos}" SelectedItem="{Binding ConceptoSeleccionado}">
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" Width="250" Margin="0 0" ItemsSource="{Binding Conceptos}" SelectedItem="{Binding ConceptoSeleccionado}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Nombre}" />
|
||||
@@ -71,11 +71,11 @@
|
||||
|
||||
<!-- Monto -->
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Text="Monto:" VerticalAlignment="Center" Margin="0 5" FontSize="14"/>
|
||||
<TextBox Grid.Row="4" Grid.Column="1" Margin="0 5" Height="35" Watermark="Ingrese el monto" Text="{Binding MontoDecimal, StringFormat='{}{0:0.00}'}" FontSize="14"/>
|
||||
<TextBox Grid.Row="4" Grid.Column="1" Margin="0 5" Width="70" HorizontalAlignment="Left" Height="35" Watermark="Ingrese el monto" Text="{Binding MontoDecimal, StringFormat='{}{0:0.00}'}" FontSize="14"/>
|
||||
|
||||
<!-- Fecha de Movimiento -->
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Text="Fecha Movimiento:" VerticalAlignment="Center" Margin="0 5"/>
|
||||
<DatePicker Grid.Row="5" Grid.Column="1" Margin="0 5" Height="35" SelectedDate="{Binding FechaMov}" DayFormat="dd/MM/yyyy"/>
|
||||
<DatePicker Grid.Row="5" Grid.Column="1" Margin="0 5" Height="35" SelectedDate="{Binding FechaMov}"/>
|
||||
|
||||
<!-- Descripción -->
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Text="Descripción:" VerticalAlignment="Top" Margin="0 10 0 5"/>
|
||||
@@ -85,9 +85,9 @@
|
||||
<StackPanel Grid.Row="7" Grid.ColumnSpan="2" Orientation="Horizontal"
|
||||
HorizontalAlignment="Right" Margin="0 20 0 0">
|
||||
<Button Content="Cancelar" Width="100" Height="35" Margin="0 0 10 0"
|
||||
Background="#E74C3C" Foreground="White" Command="{Binding SalirCommand}"/>
|
||||
Background="#E74C3C" Foreground="White" Command="{Binding SalirCommand}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
|
||||
<Button Content="Guardar" Width="100" Height="35"
|
||||
Background="#27AE60" Foreground="White" FontWeight="Bold" Command="{Binding GuardarDatosAsyncCommand}"/>
|
||||
Background="#27AE60" Foreground="White" FontWeight="Bold" Command="{Binding GuardarDatosAsyncCommand}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
Reference in New Issue
Block a user