5 Commits
main ... Stable

Author SHA1 Message Date
8d8bd859c4 ultimos cambios 2025-09-20 18:19:49 -06:00
1fde928d5e agregar cambios importantes 2025-09-15 15:02:17 -06:00
6ff17cf9aa Agregar mantenimiento de Concepto y TipoMovimiento 2025-09-13 21:10:34 -06:00
985351f6a8 Mejoras 2025-09-13 20:34:08 -06:00
598b2c2936 Nueva rama 2025-09-13 18:25:57 -06:00
20 changed files with 1026 additions and 135 deletions

View File

@@ -5,7 +5,9 @@
<map> <map>
<entry key="AdminFinanceRCA/App.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" /> <entry key="AdminFinanceRCA/App.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
<entry key="AdminFinanceRCA/Views/MainWindow.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" /> <entry key="AdminFinanceRCA/Views/MainWindow.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
<entry key="AdminFinanceRCA/Views/Mantenimiento_Concepto.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
<entry key="AdminFinanceRCA/Views/Mantenimiento_DepartTrabajo.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" /> <entry key="AdminFinanceRCA/Views/Mantenimiento_DepartTrabajo.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
<entry key="AdminFinanceRCA/Views/Mantenimiento_TipoMovimiento.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
<entry key="AdminFinanceRCA/Views/MovimientoWindow.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" /> <entry key="AdminFinanceRCA/Views/MovimientoWindow.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
</map> </map>
</option> </option>

View File

@@ -2,6 +2,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAdminFinanceRCA_002EViewModels_002EMantenimiento_005FDepartTrabajoViewModel_002Eg_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fef78e682e56c19e39b0e3efe9d5c77fc453833_003FAdminFinanceRCA_002EViewModels_002EMantenimiento_005FDepartTrabajoViewModel_002Eg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAdminFinanceRCA_002EViewModels_002EMantenimiento_005FDepartTrabajoViewModel_002Eg_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fef78e682e56c19e39b0e3efe9d5c77fc453833_003FAdminFinanceRCA_002EViewModels_002EMantenimiento_005FDepartTrabajoViewModel_002Eg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AApplication_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F9a5cc8ddf36e8c8f422071f068cc8edb16e814991aa851aa131f3fa14425ed_003FApplication_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AApplication_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F9a5cc8ddf36e8c8f422071f068cc8edb16e814991aa851aa131f3fa14425ed_003FApplication_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fbf9021a960b74107a7e141aa06bc9d8a0a53c929178c2fb95b1597be8af8dc_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fbf9021a960b74107a7e141aa06bc9d8a0a53c929178c2fb95b1597be8af8dc_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInteractive_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fb23cb847f33b753542a42b3f20ac9361fcabd14fd166ec471fe468e3597a9b_003FInteractive_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARelayCommand_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F20c0f49b8854743afaecc2f359655fdbfc6c5264f49e9eb333686e85a87bf_003FRelayCommand_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARelayCommand_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F20c0f49b8854743afaecc2f359655fdbfc6c5264f49e9eb333686e85a87bf_003FRelayCommand_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASqliteException_002Ecs_002Fl_003AC_0021_003FUsers_003FBonifacia_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F154220569126135ad5d7314bf2bc694d3cf7c95840d481d44f0336f4f1f8e9c_003FSqliteException_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASqliteException_002Ecs_002Fl_003AC_0021_003FUsers_003FBonifacia_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F154220569126135ad5d7314bf2bc694d3cf7c95840d481d44f0336f4f1f8e9c_003FSqliteException_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fb90d6b47d6330753e855af18818b97d4207f32c6ee4b793faffc029f069f4_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fb90d6b47d6330753e855af18818b97d4207f32c6ee4b793faffc029f069f4_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

View File

@@ -25,8 +25,6 @@
</PackageReference> </PackageReference>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<PackageReference Include="Dapper" Version="2.1.66" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Material.Avalonia" Version="3.13.0" />
<PackageReference Include="Material.Avalonia.Dialogs" Version="3.13.0" />
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" /> <PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.8" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0-preview.7.25380.108" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0-preview.7.25380.108" />
@@ -40,4 +38,15 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Update="Views\Mantenimiento_Concepto.axaml.cs">
<DependentUpon>Mantenimiento_Concepto.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\Mantenimiento_TipoMovimiento.axaml.cs">
<DependentUpon>Mantenimiento_TipoMovimiento.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
</Project> </Project>

View File

@@ -2,16 +2,14 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AdminFinanceRCA.App" x:Class="AdminFinanceRCA.App"
xmlns:local="using:AdminFinanceRCA" xmlns:local="using:AdminFinanceRCA"
RequestedThemeVariant="Default" RequestedThemeVariant="Default">
xmlns:themes="clr-namespace:Material.Styles.Themes;assembly=Material.Styles"
>
<Application.DataTemplates> <Application.DataTemplates>
<local:ViewLocator/> <local:ViewLocator/>
</Application.DataTemplates> </Application.DataTemplates>
<Application.Styles> <Application.Styles>
<FluentTheme /> <FluentTheme />
<themes:MaterialTheme BaseTheme="Dark" PrimaryColor="Purple" SecondaryColor="Lime" /> <!-- <themes:MaterialTheme BaseTheme="Dark" PrimaryColor="Purple" SecondaryColor="Lime" /> -->
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/> <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

View 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);
}
}

View File

@@ -1,4 +1,5 @@
using System; using System;
using Avalonia.Media;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
namespace AdminFinanceRCA.Models; namespace AdminFinanceRCA.Models;
@@ -63,6 +64,7 @@ public class Movimiento : ObservableObject
public DateTime FechaRegistro { get; set; } public DateTime FechaRegistro { get; set; }
public int Concepto { get; set; } public int Concepto { get; set; }
public string Descripcion { get; set; } = string.Empty; public string Descripcion { get; set; } = string.Empty;
public string Nota { get; set; } = string.Empty;
// Propiedades de navegación para las relaciones (opcionales pero útiles) // Propiedades de navegación para las relaciones (opcionales pero útiles)
public TipoMovimiento TipoMovimientoNav { get; set; } = new TipoMovimiento(); public TipoMovimiento TipoMovimientoNav { get; set; } = new TipoMovimiento();
@@ -72,7 +74,7 @@ public class Movimiento : ObservableObject
public Movimiento() { } public Movimiento() { }
public Movimiento(decimal monto, int tipoMov, int deptoTrabajo, public Movimiento(decimal monto, int tipoMov, int deptoTrabajo,
DateTime fechaMovimiento, int concepto, string descripcion = "") DateTime fechaMovimiento, int concepto, string descripcion = "", string nota ="")
{ {
Monto = monto; Monto = monto;
TipoMov = tipoMov; TipoMov = tipoMov;
@@ -81,6 +83,20 @@ public class Movimiento : ObservableObject
FechaRegistro = DateTime.Now; FechaRegistro = DateTime.Now;
Concepto = concepto; Concepto = concepto;
Descripcion = descripcion; Descripcion = descripcion;
Nota = nota;
}
public Movimiento(int id, decimal monto, int tipoMov, int deptoTrabajo,
DateTime fechaMovimiento, int concepto, string descripcion = "", string nota = "")
{
ID = id;
Monto = monto;
TipoMov = tipoMov;
DeptoTrabajo = deptoTrabajo;
FechaMovimiento = fechaMovimiento;
FechaRegistro = DateTime.Now;
Concepto = concepto;
Descripcion = descripcion;
Nota = nota;
} }
} }
@@ -104,4 +120,14 @@ public class MovimientoCompleto : ObservableObject
// Datos de Concepto // Datos de Concepto
public int ConceptoID { get; set; } public int ConceptoID { get; set; }
public string ConceptoNombre { get; set; } = string.Empty; public string ConceptoNombre { get; set; } = string.Empty;
public string Nota { get; set; } = string.Empty;
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
} }

View File

@@ -3,13 +3,12 @@ using System.IO;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using AdminFinanceRCA.Models; using AdminFinanceRCA.Models;
namespace AdminFinanceRCA;
using System.Data; using System.Data;
using Dapper; using Dapper;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
namespace AdminFinanceRCA;
public class FinanzasRepository public class FinanzasRepository
{ {
private readonly string _connectionString; private readonly string _connectionString;
@@ -20,7 +19,6 @@ public class FinanzasRepository
_connectionString = config.GetConnectionString(); _connectionString = config.GetConnectionString();
InitializeDatabase(); InitializeDatabase();
} }
// Constructor alternativo para testing
public FinanzasRepository(string connectionString) public FinanzasRepository(string connectionString)
{ {
_connectionString = connectionString; _connectionString = connectionString;
@@ -42,7 +40,8 @@ public class FinanzasRepository
connection.Execute(@" connection.Execute(@"
CREATE TABLE IF NOT EXISTS DepartTrabajo ( CREATE TABLE IF NOT EXISTS DepartTrabajo (
Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
Nombre TEXT NOT NULL Nombre TEXT NOT NULL,
Descripcion TEXT NULL
)"); )");
connection.Execute(@" connection.Execute(@"
@@ -69,40 +68,6 @@ public class FinanzasRepository
// Crear índice // Crear índice
connection.Execute(@" connection.Execute(@"
CREATE INDEX IF NOT EXISTS Mov ON Movimientos (Concepto ASC, TipoMov ASC)"); 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')");
} }
} }
@@ -118,8 +83,8 @@ public class FinanzasRepository
using (var connection = GetConnection()) using (var connection = GetConnection())
{ {
var sql = @"INSERT INTO Movimientos var sql = @"INSERT INTO Movimientos
(Monto, TipoMov, DeptoTrabajo, FechaMovimiento, FechaRegistro, Concepto, Descripcion) (Monto, TipoMov, DeptoTrabajo, FechaMovimiento, FechaRegistro, Concepto, Descripcion, Nota)
VALUES (@Monto, @TipoMov, @DeptoTrabajo, @FechaMovimiento, @FechaRegistro, @Concepto, @Descripcion); VALUES (@Monto, @TipoMov, @DeptoTrabajo, @FechaMovimiento, @FechaRegistro, @Concepto, @Descripcion, @Nota);
SELECT last_insert_rowid();"; SELECT last_insert_rowid();";
var id = await connection.ExecuteScalarAsync<int>(sql, movimiento); var id = await connection.ExecuteScalarAsync<int>(sql, movimiento);
@@ -145,7 +110,8 @@ public class FinanzasRepository
m.ID, m.Monto, m.FechaMovimiento, m.FechaRegistro, m.Descripcion, m.ID, m.Monto, m.FechaMovimiento, m.FechaRegistro, m.Descripcion,
tm.ID as TipoMovID, tm.Nombre as TipoMovNombre, tm.ID as TipoMovID, tm.Nombre as TipoMovNombre,
dt.Id as DeptoTrabajoID, dt.Nombre as DeptoTrabajoNombre, dt.Id as DeptoTrabajoID, dt.Nombre as DeptoTrabajoNombre,
c.ID as ConceptoID, c.Nombre as ConceptoNombre c.ID as ConceptoID, c.Nombre as ConceptoNombre,
m.Nota as Nota
FROM Movimientos m FROM Movimientos m
INNER JOIN TipoMovimiento tm ON m.TipoMov = tm.ID INNER JOIN TipoMovimiento tm ON m.TipoMov = tm.ID
INNER JOIN DepartTrabajo dt ON m.DeptoTrabajo = dt.Id INNER JOIN DepartTrabajo dt ON m.DeptoTrabajo = dt.Id
@@ -156,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())
@@ -165,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())
@@ -175,7 +220,8 @@ public class FinanzasRepository
DeptoTrabajo = @DeptoTrabajo, DeptoTrabajo = @DeptoTrabajo,
FechaMovimiento = @FechaMovimiento, FechaMovimiento = @FechaMovimiento,
Concepto = @Concepto, Concepto = @Concepto,
Descripcion = @Descripcion Descripcion = @Descripcion,
Nota = @Nota
WHERE ID = @ID"; WHERE ID = @ID";
var affectedRows = await connection.ExecuteAsync(sql, movimiento); var affectedRows = await connection.ExecuteAsync(sql, movimiento);
@@ -215,10 +261,40 @@ public class FinanzasRepository
} }
} }
public async Task<bool> UpdateConceptoAsync(Concepto concepto)
{
using (var connection = GetConnection())
{
var sql = @"UPDATE Concepto
SET Nombre = @Nombre
WHERE Id = @Id;";
var rowsAffected = await connection.ExecuteAsync(sql, concepto);
return rowsAffected > 0;
}
}
public async Task<Concepto?> GetConceptoByIdAsync(int id)
{
using (var connection = GetConnection())
{
var sql = "SELECT * FROM Concepto WHERE ID = @Id";
return await connection.QueryFirstOrDefaultAsync<Concepto>(sql, new { Id = id });
}
}
#endregion #endregion
#region Operaciones para DepartTrabajo #region Operaciones para DepartTrabajo
public async Task<DepartTrabajo?> GetDepartamentoTrabajoByIdAsync(int id)
{
using (var connection = GetConnection())
{
var sql = "SELECT * FROM DepartTrabajo WHERE ID = @Id";
return await connection.QueryFirstOrDefaultAsync<DepartTrabajo>(sql, new { Id = id });
}
}
public async Task<IEnumerable<DepartTrabajo>> GetAllDepartamentosAsync() public async Task<IEnumerable<DepartTrabajo>> GetAllDepartamentosAsync()
{ {
using (var connection = GetConnection()) using (var connection = GetConnection())
@@ -249,7 +325,6 @@ public class FinanzasRepository
return rowsAffected > 0; return rowsAffected > 0;
} }
} }
#endregion #endregion
#region Operaciones para TipoMovimiento #region Operaciones para TipoMovimiento
@@ -262,6 +337,18 @@ public class FinanzasRepository
return await connection.QueryAsync<TipoMovimiento>(sql); return await connection.QueryAsync<TipoMovimiento>(sql);
} }
} }
public async Task<bool> UpdateTipoMovimientoAsync(TipoMovimiento tipomov)
{
using (var connection = GetConnection())
{
var sql = @"UPDATE Concepto
SET Nombre = @Nombre
WHERE Id = @Id;";
var rowsAffected = await connection.ExecuteAsync(sql, tipomov);
return rowsAffected > 0;
}
}
public async Task<int> CreateTipoMovimientoAsync(TipoMovimiento tipoMovimiento) public async Task<int> CreateTipoMovimientoAsync(TipoMovimiento tipoMovimiento)
{ {
@@ -272,6 +359,14 @@ public class FinanzasRepository
} }
} }
public async Task<TipoMovimiento?> GetTipoMovimientoByIdAsync(int id)
{
using (var connection = GetConnection())
{
var sql = "SELECT * FROM TipoMovimiento WHERE ID = @Id";
return await connection.QueryFirstOrDefaultAsync<TipoMovimiento>(sql, new { Id = id });
}
}
#endregion #endregion
#region Métodos de exportación #region Métodos de exportación
@@ -287,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}\"");
} }
@@ -298,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
} }

View File

@@ -2,12 +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;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
@@ -16,20 +15,24 @@ namespace AdminFinanceRCA.ViewModels;
public partial class MainWindowViewModel : ViewModelBase public partial class MainWindowViewModel : ViewModelBase
{ {
private readonly FinanzasRepository _repository; private readonly FinanzasRepository _repository;
[ObservableProperty] [ObservableProperty] private ObservableCollection<MovimientoCompleto> _movimientos;
private ObservableCollection<MovimientoCompleto> _movimientos; [ObservableProperty] private ObservableCollection<Concepto> _conceptos;
[ObservableProperty] [ObservableProperty] private ObservableCollection<DepartTrabajo> _departamentos;
private ObservableCollection<Concepto> _conceptos; [ObservableProperty] private ObservableCollection<TipoMovimiento> _tiposMovimiento;
[ObservableProperty] [ObservableProperty] private MovimientoCompleto _movimientoSeleccionado;
private ObservableCollection<DepartTrabajo> _departamentos; [ObservableProperty] private DepartTrabajo _departamentoSeleccionado;
[ObservableProperty] [ObservableProperty] private ObservableCollection<int> _anios;
private ObservableCollection<TipoMovimiento> _tiposMovimiento; [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();
CargarDatos(); CargarDatos();
} }
[RelayCommand] [RelayCommand]
public void AgregarDepartamento() public void AgregarDepartamento()
{ {
@@ -41,16 +44,63 @@ public partial class MainWindowViewModel : ViewModelBase
departTrabajo.ShowDialog(GetCurrentWindow<MainWindow>()); departTrabajo.ShowDialog(GetCurrentWindow<MainWindow>());
} }
[RelayCommand]
public void AgregarConcepto()
{
Mantenimiento_ConceptoViewModel mantenimiento = new Mantenimiento_ConceptoViewModel();
Mantenimiento_Concepto conceptoWindow = new Mantenimiento_Concepto()
{
DataContext = mantenimiento
};
conceptoWindow.ShowDialog(GetCurrentWindow<MainWindow>());
}
[RelayCommand]
public void AgregarTipoMovimiento()
{
Mantenimiento_TipoMovViewModel mantenimiento = new Mantenimiento_TipoMovViewModel();
Mantenimiento_TipoMovimiento conceptoWindow = new Mantenimiento_TipoMovimiento()
{
DataContext = mantenimiento
};
conceptoWindow.ShowDialog(GetCurrentWindow<MainWindow>());
}
[RelayCommand]
public async Task UpdateMovimiento(MovimientoCompleto _mvMovimientoCompleto)
{
MovimientoWindowViewModel mwvm = new MovimientoWindowViewModel();
mwvm.ReloadEvent+= MwvmOnReloadEvent;
MovimientoWindow mw = new MovimientoWindow()
{
Width = 600,
Height = 500,
};
mw.DataContext = mwvm;
mw.ShowDialog(GetCurrentWindow<MainWindow>());
mw.Loaded += async (sender, args) => { await mwvm.ActualizarMovimientoAsync(_mvMovimientoCompleto); };
}
[RelayCommand] [RelayCommand]
public void AgregarMovimiento() public void AgregarMovimiento()
{ {
MovimientoWindowViewModel mwvm = new MovimientoWindowViewModel(); MovimientoWindowViewModel mwvm = new MovimientoWindowViewModel();
mwvm.ReloadEvent+= MwvmOnReloadEvent;
MovimientoWindow mw = new MovimientoWindow(); MovimientoWindow mw = new MovimientoWindow()
{
Width = 600,
Height = 500,
};
mw.DataContext = mwvm; mw.DataContext = mwvm;
mw.ShowDialog(GetCurrentWindow<MainWindow>()); mw.ShowDialog(GetCurrentWindow<MainWindow>());
} }
private async void MwvmOnReloadEvent(object? sender, EventArgs e)
{
var movimientosTask = _repository.GetAllMovimientosCompletosAsync();
Movimientos = new ObservableCollection<MovimientoCompleto>(await movimientosTask);
}
[RelayCommand] [RelayCommand]
public void Salir() public void Salir()
{ {
@@ -82,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()
{ {
@@ -90,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
@@ -108,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
@@ -124,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)
{ {

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using AdminFinanceRCA.Models;
using AdminFinanceRCA.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
namespace AdminFinanceRCA.ViewModels;
public partial class Mantenimiento_ConceptoViewModel : ViewModelBase
{
private readonly FinanzasRepository _conceptoService;
public event EventHandler? ReloadEvent;
[ObservableProperty] private ObservableCollection<Concepto> _conceptos;
[ObservableProperty] private Concepto _conceptoSeleccionado;
[ObservableProperty] private Concepto _conceptoEditando;
[ObservableProperty] private bool _estaEditando;
[ObservableProperty] private string _nombre;
// [ObservableProperty] private string _descripcion;
public Mantenimiento_ConceptoViewModel()
{
_conceptoService = new FinanzasRepository();
_ = CargarDatosAsync();
}
async Task CargarDatosAsync()
{
var dt = await _conceptoService.GetAllConceptosAsync();
Conceptos = new ObservableCollection<Concepto>(dt);
}
[RelayCommand]
private void NuevoConcepto()
{
Nombre = string.Empty;
// Descripcion = string.Empty;
EstaEditando = false;
}
[RelayCommand]
private async Task GuardarRegistros()
{
string[] mensaje = {"", string.Empty};
if (EstaEditando)
{
try
{
ConceptoSeleccionado.Nombre = Nombre;
// GrupoSeleccionado.Descripcion = Descripcion;
await _conceptoService.UpdateConceptoAsync(ConceptoSeleccionado);
mensaje = new[] { "Exito", "Registro actualizado con exito" };
}
catch (Exception ex)
{
mensaje = new[] { "Error", ex.Message };
}
}
else
{
try
{
if(string.IsNullOrEmpty(Nombre))
return;
Concepto concept = new Concepto(Nombre);
await _conceptoService.CreateConceptoAsync(concept);
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_Concepto>());
OnReloadEvent();
await CargarDatosAsync();
}
[RelayCommand]
private void Cancelar()
{
this.GetCurrentWindow<Mantenimiento_Concepto>().Close();
}
protected virtual void OnReloadEvent()
{
ReloadEvent?.Invoke(this, EventArgs.Empty);
}
}

View File

@@ -1,18 +1,19 @@
using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Threading.Tasks; using System.Threading.Tasks;
using AdminFinanceRCA.Models; using AdminFinanceRCA.Models;
using AdminFinanceRCA.Views; using AdminFinanceRCA.Views;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Material.Dialog.Views; using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
namespace AdminFinanceRCA.ViewModels; namespace AdminFinanceRCA.ViewModels;
public partial class Mantenimiento_DepartTrabajoViewModel : ViewModelBase public partial class Mantenimiento_DepartTrabajoViewModel : ViewModelBase
{ {
private readonly FinanzasRepository _departTrabajoService; private readonly FinanzasRepository _departTrabajoService;
public event EventHandler? ReloadEvent;
[ObservableProperty] private ObservableCollection<DepartTrabajo> _gruposTrabajo; [ObservableProperty] private ObservableCollection<DepartTrabajo> _gruposTrabajo;
[ObservableProperty] private DepartTrabajo _grupoSeleccionado; [ObservableProperty] private DepartTrabajo _grupoSeleccionado;
[ObservableProperty] private DepartTrabajo _grupoEditando; [ObservableProperty] private DepartTrabajo _grupoEditando;
@@ -43,14 +44,24 @@ public partial class Mantenimiento_DepartTrabajoViewModel : ViewModelBase
[RelayCommand] [RelayCommand]
private async Task GuardarRegistros() private async Task GuardarRegistros()
{ {
string[] mensaje = {"", string.Empty};
if (EstaEditando) if (EstaEditando)
{
try
{ {
GrupoSeleccionado.Nombre = Nombre; GrupoSeleccionado.Nombre = Nombre;
GrupoSeleccionado.Descripcion = Descripcion; GrupoSeleccionado.Descripcion = Descripcion;
_departTrabajoService.UpdateDepartamentoAsync(GrupoSeleccionado); _departTrabajoService.UpdateDepartamentoAsync(GrupoSeleccionado);
mensaje = new[] { "Exito", "Registro actualizado con exito" };
}
catch (Exception ex)
{
mensaje = new[] { "Error", ex.Message };
}
} }
else else
{
try
{ {
if(string.IsNullOrEmpty(Nombre)) if(string.IsNullOrEmpty(Nombre))
return; return;
@@ -59,10 +70,28 @@ public partial class Mantenimiento_DepartTrabajoViewModel : ViewModelBase
await _departTrabajoService.CreateDepartamentoAsync(depart); await _departTrabajoService.CreateDepartamentoAsync(depart);
Nombre = string.Empty; Nombre = string.Empty;
Descripcion = string.Empty; Descripcion = string.Empty;
AlertDialog ad = new AlertDialog();
ad.Title = "Exito"; mensaje = new[] { "Exito", "Registro agregado con exito" };
ad.Content = "Registro agregado con exito"; }
ad.Show(GetCurrentWindow<Mantenimiento_DepartTrabajo>()); 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);
}
} }

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using AdminFinanceRCA.Models;
using AdminFinanceRCA.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
namespace AdminFinanceRCA.ViewModels;
public partial class Mantenimiento_TipoMovViewModel : ViewModelBase
{
private readonly FinanzasRepository _repositoryService;
public event EventHandler? ReloadEvent;
[ObservableProperty] private ObservableCollection<TipoMovimiento> _tipoMovimientos;
[ObservableProperty] private TipoMovimiento _tipoMovSeleccionado;
[ObservableProperty] private TipoMovimiento _tipoMovEditando;
[ObservableProperty] private bool _estaEditando;
[ObservableProperty] private string _nombre;
// [ObservableProperty] private string _descripcion;
public Mantenimiento_TipoMovViewModel()
{
_repositoryService = new FinanzasRepository();
_ = CargarDatosAsync();
}
async Task CargarDatosAsync()
{
var dt = await _repositoryService.GetAllTiposMovimientoAsync();
TipoMovimientos = new ObservableCollection<TipoMovimiento>(dt);
}
[RelayCommand]
private void NuevoTipoMov()
{
Nombre = string.Empty;
// Descripcion = string.Empty;
EstaEditando = false;
}
[RelayCommand]
private async Task GuardarRegistros()
{
string[] mensaje = {"", string.Empty};
if (EstaEditando)
{
try
{
TipoMovSeleccionado.Nombre = Nombre;
// GrupoSeleccionado.Descripcion = Descripcion;
await _repositoryService.UpdateTipoMovimientoAsync(TipoMovSeleccionado);
mensaje = new[] { "Exito", "Registro actualizado con exito" };
}
catch (Exception ex)
{
mensaje = new[] { "Error", ex.Message };
}
}
else
{
try
{
if(string.IsNullOrEmpty(Nombre))
return;
TipoMovimiento tipomov = new TipoMovimiento(Nombre);
await _repositoryService.CreateTipoMovimientoAsync(tipomov);
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_TipoMovimiento>());
OnReloadEvent();
await CargarDatosAsync();
}
[RelayCommand]
private void Cancelar()
{
this.GetCurrentWindow<Mantenimiento_TipoMovimiento>().Close();
}
protected virtual void OnReloadEvent()
{
ReloadEvent?.Invoke(this, EventArgs.Empty);
}
}

View File

@@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AdminFinanceRCA.Models; using AdminFinanceRCA.Models;
using AdminFinanceRCA.Views; using AdminFinanceRCA.Views;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Material.Dialog.Views;
using MsBox.Avalonia; using MsBox.Avalonia;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;
@@ -14,20 +15,23 @@ namespace AdminFinanceRCA.ViewModels;
public partial class MovimientoWindowViewModel : ViewModelBase public partial class MovimientoWindowViewModel : ViewModelBase
{ {
private readonly FinanzasRepository _finanzasRepository; private readonly FinanzasRepository _finanzasRepository;
public event EventHandler? ReloadEvent;
[ObservableProperty] private ObservableCollection<DepartTrabajo> _departTrabajos; [ObservableProperty] private ObservableCollection<DepartTrabajo> _departTrabajos;
[ObservableProperty] private ObservableCollection<TipoMovimiento> _tipoMovimientos; [ObservableProperty] private ObservableCollection<TipoMovimiento> _tipoMovimientos;
[ObservableProperty] private ObservableCollection<Concepto> _conceptos; [ObservableProperty] private ObservableCollection<Concepto> _conceptos;
[ObservableProperty] private DateTime _fechaMov; [ObservableProperty] private DateTimeOffset _fechaMov;
[ObservableProperty] private decimal _montoDecimal; [ObservableProperty] private decimal _montoDecimal;
[ObservableProperty] private string _descripcion; [ObservableProperty] private string _descripcion;
[ObservableProperty] private TipoMovimiento _tipoMovimientoSelecionado; [ObservableProperty] private TipoMovimiento _tipoMovimientoSelecionado;
[ObservableProperty] private DepartTrabajo _departaDepartTrabajoSeleccionado; [ObservableProperty] private DepartTrabajo _departaDepartTrabajoSeleccionado;
[ObservableProperty] private Concepto _conceptoSeleccionado; [ObservableProperty] private Concepto _conceptoSeleccionado;
[ObservableProperty] private string _nota;
private int IdMovimiento { get; set; }
private bool modificando = false;
public MovimientoWindowViewModel() public MovimientoWindowViewModel()
{ {
_fechaMov = DateTime.Now; _fechaMov = DateTimeOffset.Now;
_finanzasRepository = new FinanzasRepository(); _finanzasRepository = new FinanzasRepository();
_ = CargarDatosAsync(); _ = CargarDatosAsync();
} }
@@ -36,22 +40,125 @@ public partial class MovimientoWindowViewModel : ViewModelBase
{ {
var dt = await _finanzasRepository.GetAllDepartamentosAsync(); var dt = await _finanzasRepository.GetAllDepartamentosAsync();
DepartTrabajos = new ObservableCollection<DepartTrabajo>(dt); DepartTrabajos = new ObservableCollection<DepartTrabajo>(dt);
var tm = await _finanzasRepository.GetAllTiposMovimientoAsync(); var tm = await _finanzasRepository.GetAllTiposMovimientoAsync();
TipoMovimientos = new ObservableCollection<TipoMovimiento>(tm); TipoMovimientos = new ObservableCollection<TipoMovimiento>(tm);
var cpt = await _finanzasRepository.GetAllConceptosAsync(); var cpt = await _finanzasRepository.GetAllConceptosAsync();
Conceptos = new ObservableCollection<Concepto>(cpt); Conceptos = new ObservableCollection<Concepto>(cpt);
DepartaDepartTrabajoSeleccionado = DepartTrabajos[0];
TipoMovimientoSelecionado = TipoMovimientos[0];
ConceptoSeleccionado = Conceptos[0];
}
public async Task ActualizarMovimientoAsync(MovimientoCompleto mc)
{
try
{
IdMovimiento = mc.ID;
FechaMov = mc.FechaMovimiento;
MontoDecimal = mc.Monto;
TipoMovimientoSelecionado = TipoMovimientos.Where(e => e.ID == mc.TipoMovID).FirstOrDefault(); //await _finanzasRepository.GetTipoMovimientoByIdAsync(mc.TipoMovID) ?? new TipoMovimiento();
ConceptoSeleccionado = Conceptos.Where(e => e.ID == mc.ConceptoID).FirstOrDefault(); // await _finanzasRepository.GetConceptoByIdAsync(mc.ConceptoID) ?? new Concepto();
DepartaDepartTrabajoSeleccionado = DepartTrabajos.Where(e => e.Id == mc.DeptoTrabajoID).FirstOrDefault(); //await _finanzasRepository.GetDepartamentoTrabajoByIdAsync(mc.DeptoTrabajoID) ?? new DepartTrabajo();
Descripcion = mc.Descripcion;
Nota = mc.Nota;
modificando = true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
} }
[RelayCommand] [RelayCommand]
public async void GuardarDatosAsync() public async void GuardarDatosAsync()
{
try
{
// Validar campos obligatorios
if (!ValidarCamposObligatorios())
{
return; // Detener ejecución si hay campos inválidos
}
if (!modificando)
{ {
Movimiento mv = new Movimiento(MontoDecimal, TipoMovimientoSelecionado.ID, DepartaDepartTrabajoSeleccionado.Id, Movimiento mv = new Movimiento(MontoDecimal, TipoMovimientoSelecionado.ID, DepartaDepartTrabajoSeleccionado.Id,
FechaMov, ConceptoSeleccionado.ID, Descripcion); DateTime.Parse(FechaMov.ToString("yyyy-MM-dd")), ConceptoSeleccionado.ID, Descripcion, Nota);
await _finanzasRepository.CreateMovimientoAsync(mv); await _finanzasRepository.CreateMovimientoAsync(mv);
var dt = MessageBoxManager.GetMessageBoxStandard("", "Se guardo con exito", ButtonEnum.Ok); var dt = MessageBoxManager.GetMessageBoxStandard("", "Se guardo con exito", ButtonEnum.Ok);
await dt.ShowAsPopupAsync(GetCurrentWindow<MovimientoWindow>()); await dt.ShowAsPopupAsync(GetCurrentWindow<MovimientoWindow>());
MontoDecimal = 0;
Descripcion = "";
OnReloadEvent();
}else
{
Movimiento mv = new Movimiento(IdMovimiento, MontoDecimal, TipoMovimientoSelecionado.ID, DepartaDepartTrabajoSeleccionado.Id,
DateTime.Parse(FechaMov.ToString("yyyy-MM-dd")), ConceptoSeleccionado.ID, Descripcion, Nota);
await _finanzasRepository.UpdateMovimientoAsync(mv);
var dt = MessageBoxManager.GetMessageBoxStandard("", "Se actualizo 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] [RelayCommand]

View File

@@ -16,6 +16,13 @@
<vm:MainWindowViewModel/> <vm:MainWindowViewModel/>
</Design.DataContext> </Design.DataContext>
<Window.Styles>
<Style Selector="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</Window.Styles>
<DockPanel LastChildFill="True" Background="#F5F5F5"> <DockPanel LastChildFill="True" Background="#F5F5F5">
<!-- Menú superior estilo moderno --> <!-- Menú superior estilo moderno -->
@@ -30,8 +37,8 @@
<!-- Menú Herramientas --> <!-- Menú Herramientas -->
<MenuItem Header="Herramientas"> <MenuItem Header="Herramientas">
<MenuItem Header="Departamentos" Command="{Binding AgregarDepartamentoCommand}" /> <MenuItem Header="Departamentos" Command="{Binding AgregarDepartamentoCommand}" />
<MenuItem Header="Tipos de Movimiento" /> <MenuItem Header="Tipos de Movimiento" Command="{Binding AgregarTipoMovimientoCommand}" />
<MenuItem Header="Conceptos"/> <MenuItem Header="Conceptos" Command="{Binding AgregarConceptoCommand}"/>
</MenuItem> </MenuItem>
</Menu> </Menu>
@@ -40,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"
@@ -49,13 +76,14 @@
</StackPanel> </StackPanel>
<!-- DataGrid con estilo moderno --> <!-- DataGrid con estilo moderno -->
<DataGrid Margin="15" HorizontalAlignment="Stretch" BorderThickness="1" CornerRadius="3" ItemsSource="{Binding Movimientos}"> <DataGrid Margin="15" HorizontalAlignment="Stretch" BorderThickness="1" CornerRadius="3" ItemsSource="{Binding Movimientos}" DoubleTapped="InputElement_OnDoubleTapped" >
<!-- Estilo para los encabezados -->
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTemplateColumn Header="ID" Width="80"> <DataGridTemplateColumn Header="ID" Width="80" IsVisible="False">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding ID}" Foreground="Black" /> <TextBlock Text="{Binding ID}" Foreground="{Binding ForegroundColor}" />
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
@@ -63,15 +91,15 @@
<DataGridTemplateColumn Header="Fecha Mov" Width="120"> <DataGridTemplateColumn Header="Fecha Mov" Width="120">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding FechaMovimiento}" Foreground="Black" /> <TextBlock Text="{Binding FechaMovimiento, StringFormat='{}{0:dd/MM/yyyy}'}" Foreground="{Binding ForegroundColor}" />
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
<DataGridTemplateColumn Header="Grupo de Trabajo" Width="150"> <DataGridTemplateColumn Header="Grupo de Trabajo" Width="250">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding DeptoTrabajoNombre}" Foreground="Black" /> <TextBlock Text="{Binding DeptoTrabajoNombre}" Foreground="{Binding ForegroundColor}" />
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
@@ -79,7 +107,7 @@
<DataGridTemplateColumn Header="Monto" Width="120"> <DataGridTemplateColumn Header="Monto" Width="120">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding Monto}" Foreground="Black" /> <TextBlock Text="{Binding Monto, StringFormat='{}{0:C}'}" Margin="0 0 25 0" TextAlignment="Right" Foreground="{Binding ForegroundColor}" />
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
@@ -87,23 +115,31 @@
<DataGridTemplateColumn Header="Tipo Movimiento" Width="150"> <DataGridTemplateColumn Header="Tipo Movimiento" Width="150">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding TipoMovNombre}" Foreground="Black" /> <TextBlock Text="{Binding TipoMovNombre}" Foreground="{Binding ForegroundColor}" Margin="20 0 0 0" />
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
<DataGridTemplateColumn Header="Concepto" Width="150"> <DataGridTemplateColumn Header="Concepto" Width="225">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding ConceptoNombre}" Foreground="Black" /> <TextBlock Text="{Binding ConceptoNombre}" Foreground="{Binding ForegroundColor}" />
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
<DataGridTemplateColumn Header="Descripcion" Width="250"> <DataGridTemplateColumn Header="Descripcion" Width="300">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding Descripcion}" Foreground="Black" /> <TextBlock Text="{Binding Descripcion}" Foreground="{Binding ForegroundColor}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Notas" Width="300">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Nota}" Foreground="{Binding ForegroundColor}" />
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>

View File

@@ -1,4 +1,7 @@
using AdminFinanceRCA.Models;
using AdminFinanceRCA.ViewModels;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
namespace AdminFinanceRCA.Views; namespace AdminFinanceRCA.Views;
@@ -8,4 +11,16 @@ public partial class MainWindow : Window
{ {
InitializeComponent(); InitializeComponent();
} }
private void InputElement_OnDoubleTapped(object? sender, TappedEventArgs e)
{
if (DataContext is MainWindowViewModel vm)
{
if (((DataGrid)sender).SelectedItem is MovimientoCompleto)
{
var row = ((DataGrid)sender).SelectedItem as MovimientoCompleto;
vm.UpdateMovimientoCommand.Execute(row);
}
}
}
} }

View File

@@ -0,0 +1,55 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="using:AdminFinanceRCA.ViewModels"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="350" CanResize="False"
Width="800" Height="350"
WindowStartupLocation="CenterScreen"
x:DataType="vm:Mantenimiento_ConceptoViewModel"
x:Class="AdminFinanceRCA.Views.Mantenimiento_Concepto"
Title="Mantenimiento de Concepto">
<Design.DataContext>
<vm:Mantenimiento_ConceptoViewModel/>
</Design.DataContext>
<DockPanel Margin="10">
<!-- Barra de herramientas -->
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,10" Spacing="5">
<Button Content="Nuevo" Background="DarkBlue" Foreground="White" HorizontalContentAlignment="Center" Width="90" Command="{Binding NuevoConceptoCommand}" />
<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">
<!-- Lista de grupos -->
<StackPanel Grid.Column="0" Margin="0,0,10,0">
<TextBlock Text="Conceptos" FontWeight="Bold" Margin="0,0,0,5"/>
<ListBox ItemsSource="{Binding Conceptos}" DoubleTapped="OnListBoxDoubleTapped"
Height="250">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="5">
<TextBlock Text="{Binding Nombre}" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<!-- Formulario de edición -->
<Border Grid.Column="1" Margin="0 0 0 0" BorderBrush="LightGray" BorderThickness="3" Padding="10" Height="250" Width="500">
<StackPanel Spacing="10">
<TextBlock Text="Editar Concepto" FontSize="16" FontWeight="Bold"/>
<StackPanel>
<TextBlock Text="Nombre *" Margin="0,0,0,2"/>
<TextBox Watermark="Ingrese el nombre" Text="{Binding Nombre}"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</DockPanel>
</Window>

View File

@@ -0,0 +1,29 @@
using AdminFinanceRCA.Models;
using AdminFinanceRCA.ViewModels;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
namespace AdminFinanceRCA.Views;
public partial class Mantenimiento_Concepto : Window
{
public Mantenimiento_Concepto()
{
InitializeComponent();
}
private void OnListBoxDoubleTapped(object sender, TappedEventArgs e)
{
if (DataContext is Mantenimiento_ConceptoViewModel viewModel &&
sender is ListBox listBox &&
listBox.SelectedItem is Concepto selected)
{
viewModel.ConceptoSeleccionado = selected;
viewModel.Nombre = selected.Nombre;
// viewModel.Descripcion = selected.Descripcion;
viewModel.EstaEditando = true;
}
}
}

View File

@@ -17,9 +17,9 @@
<DockPanel Margin="10"> <DockPanel Margin="10">
<!-- Barra de herramientas --> <!-- Barra de herramientas -->
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,10" Spacing="5"> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,10" Spacing="5">
<Button Content="Nuevo" Width="90" Command="{Binding NuevoDepartTrabajoCommand}" /> <Button Content="Nuevo" Background="DarkBlue" Foreground="White" HorizontalContentAlignment="Center" Width="90" Command="{Binding NuevoDepartTrabajoCommand}" />
<Button Content="Guardar" Width="90" Command="{Binding GuardarRegistrosCommand}"/> <Button Content="Guardar" Background="DarkGreen" Foreground="White" HorizontalContentAlignment="Center" Width="90" Command="{Binding GuardarRegistrosCommand}"/>
<Button Content="Cancelar" Width="90" /> <Button Content="Cancelar" Background="DarkRed" Foreground="White" HorizontalContentAlignment="Center" Width="90" Command="{Binding CancelarCommand}" />
</StackPanel> </StackPanel>
<Grid ColumnDefinitions="*,2*" Margin="0,10,0,0" ShowGridLines="False"> <Grid ColumnDefinitions="*,2*" Margin="0,10,0,0" ShowGridLines="False">
@@ -27,15 +27,12 @@
<StackPanel Grid.Column="0" Margin="0,0,10,0"> <StackPanel Grid.Column="0" Margin="0,0,10,0">
<TextBlock Text="Grupos de Trabajo" FontWeight="Bold" Margin="0,0,0,5"/> <TextBlock Text="Grupos de Trabajo" FontWeight="Bold" Margin="0,0,0,5"/>
<ListBox ItemsSource="{Binding GruposTrabajo}" DoubleTapped="OnListBoxDoubleTapped" <ListBox ItemsSource="{Binding GruposTrabajo}" DoubleTapped="OnListBoxDoubleTapped"
Height="200"> Height="250">
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Vertical" Margin="5"> <StackPanel Orientation="Vertical" Margin="5">
<TextBlock FontWeight="Bold"/> <TextBlock Text="{Binding Nombre}" VerticalAlignment="Center" />
<TextBlock Foreground="Gray" Text="{Binding Nombre}"
TextTrimming="CharacterEllipsis"/>
<TextBlock />
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>

View File

@@ -0,0 +1,55 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="using:AdminFinanceRCA.ViewModels"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="350" CanResize="False"
Width="800" Height="350"
WindowStartupLocation="CenterScreen"
x:DataType="vm:Mantenimiento_TipoMovViewModel"
x:Class="AdminFinanceRCA.Views.Mantenimiento_TipoMovimiento"
Title="Mantenimiento de Tipo de Movimiento">
<Design.DataContext>
<vm:Mantenimiento_TipoMovViewModel/>
</Design.DataContext>
<DockPanel Margin="10">
<!-- Barra de herramientas -->
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,10" Spacing="5">
<Button Content="Nuevo" Background="DarkBlue" Foreground="White" HorizontalContentAlignment="Center" Width="90" Command="{Binding NuevoTipoMovCommand}" />
<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">
<!-- Lista de grupos -->
<StackPanel Grid.Column="0" Margin="0,0,10,0">
<TextBlock Text="Tipo de Movimientos" FontWeight="Bold" Margin="0,0,0,5"/>
<ListBox ItemsSource="{Binding TipoMovimientos}" DoubleTapped="OnListBoxDoubleTapped"
Height="250">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="5">
<TextBlock Text="{Binding Nombre}" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<!-- Formulario de edición -->
<Border Grid.Column="1" Margin="0 0 0 0" BorderBrush="LightGray" BorderThickness="3" Padding="10" Height="250" Width="500">
<StackPanel Spacing="10">
<TextBlock Text="Editar Tipo de Movimiento" FontSize="16" FontWeight="Bold"/>
<StackPanel>
<TextBlock Text="Nombre *" Margin="0,0,0,2"/>
<TextBox Watermark="Ingrese el nombre" Text="{Binding Nombre}"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</DockPanel>
</Window>

View File

@@ -0,0 +1,27 @@
using AdminFinanceRCA.Models;
using AdminFinanceRCA.ViewModels;
using Avalonia.Controls;
using Avalonia.Input;
namespace AdminFinanceRCA.Views;
public partial class Mantenimiento_TipoMovimiento : Window
{
public Mantenimiento_TipoMovimiento()
{
InitializeComponent();
}
private void OnListBoxDoubleTapped(object sender, TappedEventArgs e)
{
if (DataContext is Mantenimiento_TipoMovViewModel viewModel &&
sender is ListBox listBox &&
listBox.SelectedItem is TipoMovimiento selected)
{
viewModel.TipoMovSeleccionado = selected;
viewModel.Nombre = selected.Nombre;
// viewModel.Descripcion = selected.Descripcion;
viewModel.EstaEditando = true;
}
}
}

View File

@@ -2,7 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="500" Width="600" Height="500" mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="500" Width="600" Height="520"
CanResize="False" CanResize="False"
x:Class="AdminFinanceRCA.Views.MovimientoWindow" x:Class="AdminFinanceRCA.Views.MovimientoWindow"
xmlns:vm="using:AdminFinanceRCA.ViewModels" xmlns:vm="using:AdminFinanceRCA.ViewModels"
@@ -28,6 +28,7 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/> <ColumnDefinition Width="150"/>
@@ -41,7 +42,7 @@
<!-- Departamento de Trabajo --> <!-- Departamento de Trabajo -->
<TextBlock Grid.Row="1" Grid.Column="0" Text="Departamento:" VerticalAlignment="Center" Margin="0 5"/> <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> <ComboBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding Nombre}" /> <TextBlock Text="{Binding Nombre}" />
@@ -51,7 +52,7 @@
<!-- Tipo de Movimiento --> <!-- Tipo de Movimiento -->
<TextBlock Grid.Row="2" Grid.Column="0" Text="Tipo Movimiento:" VerticalAlignment="Center" Margin="0 5"/> <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> <ComboBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding Nombre}" /> <TextBlock Text="{Binding Nombre}" />
@@ -61,7 +62,7 @@
<!-- Concepto --> <!-- Concepto -->
<TextBlock Grid.Row="3" Grid.Column="0" Text="Concepto:" VerticalAlignment="Center" Margin="0 5"/> <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> <ComboBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding Nombre}" /> <TextBlock Text="{Binding Nombre}" />
@@ -69,25 +70,30 @@
</ComboBox.ItemTemplate> </ComboBox.ItemTemplate>
</ComboBox> </ComboBox>
<!-- 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"/>
<!-- Fecha de Movimiento --> <!-- Fecha de Movimiento -->
<TextBlock Grid.Row="5" Grid.Column="0" Text="Fecha Movimiento:" VerticalAlignment="Center" Margin="0 5"/> <TextBlock Grid.Row="4" 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="4" Grid.Column="1" Margin="0 5" Height="35" SelectedDate="{Binding FechaMov}"/>
<!-- Monto -->
<TextBlock Grid.Row="5" Grid.Column="0" Text="Monto:" VerticalAlignment="Center" Margin="0 5" FontSize="14"/>
<TextBox Grid.Row="5" 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"/>
<!-- Descripción --> <!-- Descripción -->
<TextBlock Grid.Row="6" Grid.Column="0" Text="Descripción:" VerticalAlignment="Top" Margin="0 10 0 5"/> <TextBlock Grid.Row="6" Grid.Column="0" Text="Descripción:" VerticalAlignment="Top" Margin="0 10 0 5"/>
<TextBox Grid.Row="6" Grid.Column="1" Margin="0 5" Height="80" AcceptsReturn="True" TextWrapping="Wrap" Watermark="Ingrese una descripción opcional" Text="{Binding Descripcion}"/> <TextBox Grid.Row="6" Grid.Column="1" Margin="0 5" Height="40" AcceptsReturn="True" TextWrapping="Wrap" Watermark="Ingrese una descripción opcional" Text="{Binding Descripcion}"/>
<!-- Nota -->
<TextBlock Grid.Row="7" Grid.Column="0" Text="Nota:" VerticalAlignment="Top" Margin="0 10 0 5"/>
<TextBox Grid.Row="7" Grid.Column="1" Margin="0 5" Height="80" AcceptsReturn="True" TextWrapping="Wrap" Watermark="Ingrese una nota opcional" Text="{Binding Nota}"/>
<!-- Botones --> <!-- Botones -->
<StackPanel Grid.Row="7" Grid.ColumnSpan="2" Orientation="Horizontal" <StackPanel Grid.Row="8" Grid.ColumnSpan="2" Orientation="Horizontal"
HorizontalAlignment="Right" Margin="0 20 0 0"> HorizontalAlignment="Right" Margin="0 20 0 0">
<Button Content="Cancelar" Width="100" Height="35" Margin="0 0 10 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" <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> </StackPanel>
</Grid> </Grid>
</Window> </Window>