Primer comit
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
10
.idea/.idea.AdminFinanceRCA/.idea/.gitignore
generated
vendored
Normal file
10
.idea/.idea.AdminFinanceRCA/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/projectSettingsUpdater.xml
|
||||
/.idea.AdminFinanceRCA.iml
|
||||
/contentModel.xml
|
||||
/modules.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
13
.idea/.idea.AdminFinanceRCA/.idea/avalonia.xml
generated
Normal file
13
.idea/.idea.AdminFinanceRCA/.idea/avalonia.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AvaloniaProject">
|
||||
<option name="projectPerEditor">
|
||||
<map>
|
||||
<entry key="AdminFinanceRCA/App.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
|
||||
<entry key="AdminFinanceRCA/Views/MainWindow.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
|
||||
<entry key="AdminFinanceRCA/Views/Mantenimiento_DepartTrabajo.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
|
||||
<entry key="AdminFinanceRCA/Views/MovimientoWindow.axaml" value="AdminFinanceRCA/AdminFinanceRCA.csproj" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
4
.idea/.idea.AdminFinanceRCA/.idea/encodings.xml
generated
Normal file
4
.idea/.idea.AdminFinanceRCA/.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
||||
8
.idea/.idea.AdminFinanceRCA/.idea/indexLayout.xml
generated
Normal file
8
.idea/.idea.AdminFinanceRCA/.idea/indexLayout.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/.idea.AdminFinanceRCA/.idea/vcs.xml
generated
Normal file
6
.idea/.idea.AdminFinanceRCA/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
16
AdminFinanceRCA.sln
Normal file
16
AdminFinanceRCA.sln
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdminFinanceRCA", "AdminFinanceRCA\AdminFinanceRCA.csproj", "{1917BD06-B762-42E3-BD49-67C08B3848BD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1917BD06-B762-42E3-BD49-67C08B3848BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1917BD06-B762-42E3-BD49-67C08B3848BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1917BD06-B762-42E3-BD49-67C08B3848BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1917BD06-B762-42E3-BD49-67C08B3848BD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
6
AdminFinanceRCA.sln.DotSettings.user
Normal file
6
AdminFinanceRCA.sln.DotSettings.user
Normal file
@@ -0,0 +1,6 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<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_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_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_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>
|
||||
42
AdminFinanceRCA/AdminFinanceRCA.csproj
Normal file
42
AdminFinanceRCA/AdminFinanceRCA.csproj
Normal file
@@ -0,0 +1,42 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.3.0" />
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.0" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.3.0" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.0" />
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.0" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.0">
|
||||
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
||||
<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="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.Abstractions" Version="10.0.0-preview.7.25380.108" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0-preview.7.25380.108" />
|
||||
<PackageReference Include="System.Data.SQLite" Version="2.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
17
AdminFinanceRCA/App.axaml
Normal file
17
AdminFinanceRCA/App.axaml
Normal file
@@ -0,0 +1,17 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="AdminFinanceRCA.App"
|
||||
xmlns:local="using:AdminFinanceRCA"
|
||||
RequestedThemeVariant="Default"
|
||||
xmlns:themes="clr-namespace:Material.Styles.Themes;assembly=Material.Styles"
|
||||
>
|
||||
<Application.DataTemplates>
|
||||
<local:ViewLocator/>
|
||||
</Application.DataTemplates>
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
<themes:MaterialTheme BaseTheme="Dark" PrimaryColor="Purple" SecondaryColor="Lime" />
|
||||
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
47
AdminFinanceRCA/App.axaml.cs
Normal file
47
AdminFinanceRCA/App.axaml.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Data.Core;
|
||||
using Avalonia.Data.Core.Plugins;
|
||||
using System.Linq;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using AdminFinanceRCA.ViewModels;
|
||||
using AdminFinanceRCA.Views;
|
||||
|
||||
namespace AdminFinanceRCA;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
|
||||
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
|
||||
DisableAvaloniaDataAnnotationValidation();
|
||||
desktop.MainWindow = new MainWindow
|
||||
{
|
||||
DataContext = new MainWindowViewModel(),
|
||||
};
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
|
||||
private void DisableAvaloniaDataAnnotationValidation()
|
||||
{
|
||||
// Get an array of plugins to remove
|
||||
var dataValidationPluginsToRemove =
|
||||
BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();
|
||||
|
||||
// remove each entry found
|
||||
foreach (var plugin in dataValidationPluginsToRemove)
|
||||
{
|
||||
BindingPlugins.DataValidators.Remove(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
AdminFinanceRCA/AppConfig.cs
Normal file
24
AdminFinanceRCA/AppConfig.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace AdminFinanceRCA;
|
||||
|
||||
public class AppConfig
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public AppConfig()
|
||||
{
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
|
||||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
|
||||
|
||||
_configuration = builder.Build();
|
||||
}
|
||||
|
||||
public string GetConnectionString(string name = "DefaultConnection")
|
||||
{
|
||||
return _configuration.GetConnectionString(name);
|
||||
}
|
||||
}
|
||||
BIN
AdminFinanceRCA/Assets/avalonia-logo.ico
Normal file
BIN
AdminFinanceRCA/Assets/avalonia-logo.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
107
AdminFinanceRCA/Models/Entidades.cs
Normal file
107
AdminFinanceRCA/Models/Entidades.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace AdminFinanceRCA.Models;
|
||||
|
||||
// Clase para la tabla Concepto
|
||||
public class Concepto
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
public Concepto() { }
|
||||
|
||||
public Concepto(string nombre)
|
||||
{
|
||||
Nombre = nombre;
|
||||
}
|
||||
}
|
||||
|
||||
// Clase para la tabla DepartTrabajo
|
||||
public class DepartTrabajo : ObservableObject
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
public string Descripcion { get; set; } = string.Empty;
|
||||
|
||||
|
||||
public DepartTrabajo() { }
|
||||
|
||||
public DepartTrabajo(string nombre)
|
||||
{
|
||||
Nombre = nombre;
|
||||
}
|
||||
public DepartTrabajo(string nombre, string descripcion)
|
||||
{
|
||||
Nombre = nombre;
|
||||
Descripcion = descripcion;
|
||||
}
|
||||
}
|
||||
|
||||
// Clase para la tabla TipoMovimiento
|
||||
public class TipoMovimiento : ObservableObject
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
public TipoMovimiento() { }
|
||||
|
||||
public TipoMovimiento(string nombre)
|
||||
{
|
||||
Nombre = nombre;
|
||||
}
|
||||
}
|
||||
|
||||
// Clase principal para la tabla Movimientos con relaciones
|
||||
public class Movimiento : ObservableObject
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public decimal Monto { get; set; }
|
||||
public int TipoMov { get; set; }
|
||||
public int DeptoTrabajo { get; set; }
|
||||
public DateTime FechaMovimiento { get; set; }
|
||||
public DateTime FechaRegistro { get; set; }
|
||||
public int Concepto { get; set; }
|
||||
public string Descripcion { get; set; } = string.Empty;
|
||||
|
||||
// Propiedades de navegación para las relaciones (opcionales pero útiles)
|
||||
public TipoMovimiento TipoMovimientoNav { get; set; } = new TipoMovimiento();
|
||||
public DepartTrabajo DepartTrabajoNav { get; set; } = new DepartTrabajo();
|
||||
public Concepto ConceptoNav { get; set; } = new Concepto();
|
||||
|
||||
public Movimiento() { }
|
||||
|
||||
public Movimiento(decimal monto, int tipoMov, int deptoTrabajo,
|
||||
DateTime fechaMovimiento, int concepto, string descripcion = "")
|
||||
{
|
||||
Monto = monto;
|
||||
TipoMov = tipoMov;
|
||||
DeptoTrabajo = deptoTrabajo;
|
||||
FechaMovimiento = fechaMovimiento;
|
||||
FechaRegistro = DateTime.Now;
|
||||
Concepto = concepto;
|
||||
Descripcion = descripcion;
|
||||
}
|
||||
}
|
||||
|
||||
// Clase para resultados de consultas JOIN
|
||||
public class MovimientoCompleto : ObservableObject
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public decimal Monto { get; set; }
|
||||
public DateTime FechaMovimiento { get; set; }
|
||||
public DateTime FechaRegistro { get; set; }
|
||||
public string Descripcion { get; set; } = string.Empty;
|
||||
|
||||
// Datos de TipoMovimiento
|
||||
public int TipoMovID { get; set; }
|
||||
public string TipoMovNombre { get; set; } = string.Empty;
|
||||
|
||||
// Datos de DepartTrabajo
|
||||
public int DeptoTrabajoID { get; set; }
|
||||
public string DeptoTrabajoNombre { get; set; } = string.Empty;
|
||||
|
||||
// Datos de Concepto
|
||||
public int ConceptoID { get; set; }
|
||||
public string ConceptoNombre { get; set; } = string.Empty;
|
||||
}
|
||||
21
AdminFinanceRCA/Program.cs
Normal file
21
AdminFinanceRCA/Program.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Avalonia;
|
||||
using System;
|
||||
|
||||
namespace AdminFinanceRCA;
|
||||
|
||||
sealed class Program
|
||||
{
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
[STAThread]
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.WithInterFont()
|
||||
.LogToTrace();
|
||||
}
|
||||
302
AdminFinanceRCA/Repository.cs
Normal file
302
AdminFinanceRCA/Repository.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AdminFinanceRCA.Models;
|
||||
|
||||
namespace AdminFinanceRCA;
|
||||
|
||||
using System.Data;
|
||||
using Dapper;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
public class FinanzasRepository
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
|
||||
public FinanzasRepository()
|
||||
{
|
||||
var config = new AppConfig();
|
||||
_connectionString = config.GetConnectionString();
|
||||
InitializeDatabase();
|
||||
}
|
||||
// Constructor alternativo para testing
|
||||
public FinanzasRepository(string connectionString)
|
||||
{
|
||||
_connectionString = connectionString;
|
||||
InitializeDatabase();
|
||||
}
|
||||
private void InitializeDatabase()
|
||||
{
|
||||
using (var connection = new SqliteConnection(_connectionString))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
// Crear tablas si no existen
|
||||
connection.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS Concepto (
|
||||
ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
Nombre TEXT NOT NULL
|
||||
)");
|
||||
|
||||
connection.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS DepartTrabajo (
|
||||
Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
Nombre TEXT NOT NULL
|
||||
)");
|
||||
|
||||
connection.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS TipoMovimiento (
|
||||
ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
Nombre TEXT NOT NULL
|
||||
)");
|
||||
|
||||
connection.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS Movimientos (
|
||||
ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
Monto REAL NOT NULL,
|
||||
TipoMov INTEGER NOT NULL,
|
||||
DeptoTrabajo INTEGER NOT NULL,
|
||||
FechaMovimiento TEXT NOT NULL,
|
||||
FechaRegistro TEXT NOT NULL,
|
||||
Concepto INTEGER NOT NULL,
|
||||
Descripcion TEXT,
|
||||
FOREIGN KEY(TipoMov) REFERENCES TipoMovimiento(ID),
|
||||
FOREIGN KEY(DeptoTrabajo) REFERENCES DepartTrabajo(Id),
|
||||
FOREIGN KEY(Concepto) REFERENCES Concepto(ID)
|
||||
)");
|
||||
|
||||
// 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')");
|
||||
}
|
||||
}
|
||||
|
||||
public IDbConnection GetConnection()
|
||||
{
|
||||
return new SqliteConnection(_connectionString);
|
||||
}
|
||||
|
||||
#region Operaciones para Movimientos
|
||||
|
||||
public async Task<int> CreateMovimientoAsync(Movimiento movimiento)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = @"INSERT INTO Movimientos
|
||||
(Monto, TipoMov, DeptoTrabajo, FechaMovimiento, FechaRegistro, Concepto, Descripcion)
|
||||
VALUES (@Monto, @TipoMov, @DeptoTrabajo, @FechaMovimiento, @FechaRegistro, @Concepto, @Descripcion);
|
||||
SELECT last_insert_rowid();";
|
||||
|
||||
var id = await connection.ExecuteScalarAsync<int>(sql, movimiento);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Movimiento>> GetAllMovimientosAsync()
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "SELECT * FROM Movimientos ORDER BY FechaMovimiento DESC";
|
||||
return await connection.QueryAsync<Movimiento>(sql);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MovimientoCompleto>> GetAllMovimientosCompletosAsync()
|
||||
{
|
||||
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
|
||||
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
|
||||
ORDER BY m.FechaMovimiento DESC";
|
||||
|
||||
return await connection.QueryAsync<MovimientoCompleto>(sql);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Movimiento> GetMovimientoByIdAsync(int id)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "SELECT * FROM Movimientos WHERE ID = @Id";
|
||||
return await connection.QueryFirstOrDefaultAsync<Movimiento>(sql, new { Id = id });
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateMovimientoAsync(Movimiento movimiento)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = @"UPDATE Movimientos SET
|
||||
Monto = @Monto,
|
||||
TipoMov = @TipoMov,
|
||||
DeptoTrabajo = @DeptoTrabajo,
|
||||
FechaMovimiento = @FechaMovimiento,
|
||||
Concepto = @Concepto,
|
||||
Descripcion = @Descripcion
|
||||
WHERE ID = @ID";
|
||||
|
||||
var affectedRows = await connection.ExecuteAsync(sql, movimiento);
|
||||
return affectedRows > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteMovimientoAsync(int id)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "DELETE FROM Movimientos WHERE ID = @Id";
|
||||
var affectedRows = await connection.ExecuteAsync(sql, new { Id = id });
|
||||
return affectedRows > 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operaciones para Concepto
|
||||
|
||||
public async Task<IEnumerable<Concepto>> GetAllConceptosAsync()
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "SELECT * FROM Concepto ORDER BY Nombre";
|
||||
return await connection.QueryAsync<Concepto>(sql);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<int> CreateConceptoAsync(Concepto concepto)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "INSERT INTO Concepto (Nombre) VALUES (@Nombre); SELECT last_insert_rowid();";
|
||||
return await connection.ExecuteScalarAsync<int>(sql, concepto);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operaciones para DepartTrabajo
|
||||
|
||||
public async Task<IEnumerable<DepartTrabajo>> GetAllDepartamentosAsync()
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "SELECT * FROM DepartTrabajo ORDER BY Nombre";
|
||||
return await connection.QueryAsync<DepartTrabajo>(sql);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<int> CreateDepartamentoAsync(DepartTrabajo departamento)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "INSERT INTO DepartTrabajo (Nombre, Descripcion) VALUES (@Nombre, @Descripcion); SELECT last_insert_rowid();";
|
||||
return await connection.ExecuteScalarAsync<int>(sql, departamento);
|
||||
}
|
||||
}
|
||||
public async Task<bool> UpdateDepartamentoAsync(DepartTrabajo departamento)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = @"UPDATE DepartTrabajo
|
||||
SET Nombre = @Nombre,
|
||||
Descripcion = @Descripcion
|
||||
WHERE Id = @Id;";
|
||||
|
||||
var rowsAffected = await connection.ExecuteAsync(sql, departamento);
|
||||
return rowsAffected > 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operaciones para TipoMovimiento
|
||||
|
||||
public async Task<IEnumerable<TipoMovimiento>> GetAllTiposMovimientoAsync()
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "SELECT * FROM TipoMovimiento ORDER BY Nombre";
|
||||
return await connection.QueryAsync<TipoMovimiento>(sql);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<int> CreateTipoMovimientoAsync(TipoMovimiento tipoMovimiento)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
var sql = "INSERT INTO TipoMovimiento (Nombre) VALUES (@Nombre); SELECT last_insert_rowid();";
|
||||
return await connection.ExecuteScalarAsync<int>(sql, tipoMovimiento);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Métodos de exportación
|
||||
|
||||
public async Task<string> ExportToCsvAsync(string filePath)
|
||||
{
|
||||
var movimientos = await GetAllMovimientosCompletosAsync();
|
||||
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};" +
|
||||
$"{mov.TipoMovNombre};{mov.DeptoTrabajoNombre};{mov.ConceptoNombre};" +
|
||||
$"\"{mov.Descripcion}\"");
|
||||
}
|
||||
|
||||
// Guardar archivo
|
||||
await File.WriteAllTextAsync(filePath, csv.ToString(), Encoding.UTF8);
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
42
AdminFinanceRCA/Ventanas.cs
Normal file
42
AdminFinanceRCA/Ventanas.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Linq;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
|
||||
namespace AdminFinanceRCA;
|
||||
|
||||
// Interface
|
||||
public interface IWindowService
|
||||
{
|
||||
Window? GetWindowForViewModel(object viewModel);
|
||||
Window? GetActiveWindow();
|
||||
Window? GetMainWindow();
|
||||
}
|
||||
|
||||
// Implementación
|
||||
public class WindowService : IWindowService
|
||||
{
|
||||
public Window? GetWindowForViewModel(object viewModel)
|
||||
{
|
||||
if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
|
||||
return null;
|
||||
|
||||
return desktop.Windows.FirstOrDefault(window => ReferenceEquals(window.DataContext, viewModel));
|
||||
}
|
||||
|
||||
public Window? GetActiveWindow()
|
||||
{
|
||||
if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
|
||||
return null;
|
||||
|
||||
return desktop.Windows.FirstOrDefault(w => w.IsActive);
|
||||
}
|
||||
|
||||
public Window? GetMainWindow()
|
||||
{
|
||||
if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
|
||||
return null;
|
||||
|
||||
return desktop.MainWindow;
|
||||
}
|
||||
}
|
||||
30
AdminFinanceRCA/ViewLocator.cs
Normal file
30
AdminFinanceRCA/ViewLocator.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using AdminFinanceRCA.ViewModels;
|
||||
|
||||
namespace AdminFinanceRCA;
|
||||
|
||||
public class ViewLocator : IDataTemplate
|
||||
{
|
||||
public Control? Build(object? param)
|
||||
{
|
||||
if (param is null)
|
||||
return null;
|
||||
|
||||
var name = param.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal);
|
||||
var type = Type.GetType(name);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
return (Control)Activator.CreateInstance(type)!;
|
||||
}
|
||||
|
||||
return new TextBlock { Text = "Not Found: " + name };
|
||||
}
|
||||
|
||||
public bool Match(object? data)
|
||||
{
|
||||
return data is ViewModelBase;
|
||||
}
|
||||
}
|
||||
133
AdminFinanceRCA/ViewModels/MainWindowViewModel.cs
Normal file
133
AdminFinanceRCA/ViewModels/MainWindowViewModel.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
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;
|
||||
|
||||
namespace AdminFinanceRCA.ViewModels;
|
||||
|
||||
public partial class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
private readonly FinanzasRepository _repository;
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<MovimientoCompleto> _movimientos;
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<Concepto> _conceptos;
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<DepartTrabajo> _departamentos;
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<TipoMovimiento> _tiposMovimiento;
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
_repository = new FinanzasRepository();
|
||||
CargarDatos();
|
||||
}
|
||||
[RelayCommand]
|
||||
public void AgregarDepartamento()
|
||||
{
|
||||
Mantenimiento_DepartTrabajoViewModel mantenimientoDepart = new Mantenimiento_DepartTrabajoViewModel();
|
||||
Mantenimiento_DepartTrabajo departTrabajo = new Mantenimiento_DepartTrabajo()
|
||||
{
|
||||
DataContext = mantenimientoDepart
|
||||
};
|
||||
departTrabajo.ShowDialog(GetCurrentWindow<MainWindow>());
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void AgregarMovimiento()
|
||||
{
|
||||
MovimientoWindowViewModel mwvm = new MovimientoWindowViewModel();
|
||||
|
||||
MovimientoWindow mw = new MovimientoWindow();
|
||||
mw.DataContext = mwvm;
|
||||
mw.ShowDialog(GetCurrentWindow<MainWindow>());
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void Salir()
|
||||
{
|
||||
GetCurrentWindow<MainWindow>().Close();
|
||||
}
|
||||
private async Task<string> ShowSaveFileDialogAsync(Window window, string defaultFileName = "movimientos.csv")
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public async void CrearCsv()
|
||||
{
|
||||
try
|
||||
{
|
||||
var window = GetCurrentWindow<MainWindow>(); //WindowService?.GetActiveWindow() ?? WindowService?.GetWindowForViewModel(this);
|
||||
if (window != null)
|
||||
{
|
||||
string result = await ShowSaveFileDialogAsync(window);
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
var filePath = await _repository.ExportToCsvAsync(result);
|
||||
Console.WriteLine($"CSV creado en: {filePath}");
|
||||
|
||||
// Opcional: abrir el archivo con la aplicación predeterminada
|
||||
Process.Start(new ProcessStartInfo(filePath) { UseShellExecute = true });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error al crear CSV: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async void CargarDatos()
|
||||
{
|
||||
try
|
||||
{
|
||||
var movimientosTask = _repository.GetAllMovimientosCompletosAsync();
|
||||
var conceptosTask = _repository.GetAllConceptosAsync();
|
||||
var departamentosTask = _repository.GetAllDepartamentosAsync();
|
||||
var tiposTask = _repository.GetAllTiposMovimientoAsync();
|
||||
|
||||
await Task.WhenAll(movimientosTask, conceptosTask, departamentosTask, tiposTask);
|
||||
|
||||
// Actualizar collections
|
||||
Movimientos = new ObservableCollection<MovimientoCompleto>(await movimientosTask);
|
||||
Conceptos = new ObservableCollection<Concepto>(await conceptosTask);
|
||||
Departamentos = new ObservableCollection<DepartTrabajo>(await departamentosTask);
|
||||
TiposMovimiento = new ObservableCollection<TipoMovimiento>(await tiposTask);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error al cargar datos: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using AdminFinanceRCA.Models;
|
||||
using AdminFinanceRCA.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Material.Dialog.Views;
|
||||
|
||||
namespace AdminFinanceRCA.ViewModels;
|
||||
|
||||
public partial class Mantenimiento_DepartTrabajoViewModel : ViewModelBase
|
||||
{
|
||||
private readonly FinanzasRepository _departTrabajoService;
|
||||
|
||||
[ObservableProperty] private ObservableCollection<DepartTrabajo> _gruposTrabajo;
|
||||
[ObservableProperty] private DepartTrabajo _grupoSeleccionado;
|
||||
[ObservableProperty] private DepartTrabajo _grupoEditando;
|
||||
[ObservableProperty] private bool _estaEditando;
|
||||
[ObservableProperty] private string _nombre;
|
||||
[ObservableProperty] private string _descripcion;
|
||||
|
||||
public Mantenimiento_DepartTrabajoViewModel()
|
||||
{
|
||||
_departTrabajoService = new FinanzasRepository();
|
||||
_ = CargarDatosAsync();
|
||||
}
|
||||
|
||||
async Task CargarDatosAsync()
|
||||
{
|
||||
var dt = await _departTrabajoService.GetAllDepartamentosAsync();
|
||||
GruposTrabajo = new ObservableCollection<DepartTrabajo>(dt);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void NuevoDepartTrabajo()
|
||||
{
|
||||
Nombre = string.Empty;
|
||||
Descripcion = string.Empty;
|
||||
EstaEditando = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task GuardarRegistros()
|
||||
{
|
||||
|
||||
if (EstaEditando)
|
||||
{
|
||||
GrupoSeleccionado.Nombre = Nombre;
|
||||
GrupoSeleccionado.Descripcion = Descripcion;
|
||||
_departTrabajoService.UpdateDepartamentoAsync(GrupoSeleccionado);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(string.IsNullOrEmpty(Nombre))
|
||||
return;
|
||||
|
||||
DepartTrabajo depart = new DepartTrabajo(Nombre, Descripcion);
|
||||
await _departTrabajoService.CreateDepartamentoAsync(depart);
|
||||
Nombre = string.Empty;
|
||||
Descripcion = string.Empty;
|
||||
AlertDialog ad = new AlertDialog();
|
||||
ad.Title = "Exito";
|
||||
ad.Content = "Registro agregado con exito";
|
||||
ad.Show(GetCurrentWindow<Mantenimiento_DepartTrabajo>());
|
||||
}
|
||||
}
|
||||
}
|
||||
57
AdminFinanceRCA/ViewModels/MovimientoWindowViewModel.cs
Normal file
57
AdminFinanceRCA/ViewModels/MovimientoWindowViewModel.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using AdminFinanceRCA.Models;
|
||||
using AdminFinanceRCA.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace AdminFinanceRCA.ViewModels;
|
||||
|
||||
public partial class MovimientoWindowViewModel : ViewModelBase
|
||||
{
|
||||
private readonly FinanzasRepository _finanzasRepository;
|
||||
|
||||
[ObservableProperty] private ObservableCollection<DepartTrabajo> _departTrabajos;
|
||||
[ObservableProperty] private ObservableCollection<TipoMovimiento> _tipoMovimientos;
|
||||
[ObservableProperty] private ObservableCollection<Concepto> _conceptos;
|
||||
[ObservableProperty] private DateTime _fechaMov;
|
||||
[ObservableProperty] private decimal _montoDecimal;
|
||||
[ObservableProperty] private string _descripcion;
|
||||
[ObservableProperty] private TipoMovimiento _tipoMovimientoSelecionado;
|
||||
[ObservableProperty] private DepartTrabajo _departaDepartTrabajoSeleccionado;
|
||||
[ObservableProperty] private Concepto _conceptoSeleccionado;
|
||||
|
||||
public MovimientoWindowViewModel()
|
||||
{
|
||||
_fechaMov = DateTime.Now;
|
||||
_finanzasRepository = new FinanzasRepository();
|
||||
_ = CargarDatosAsync();
|
||||
}
|
||||
|
||||
private async Task CargarDatosAsync()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public async void GuardarDatosAsync()
|
||||
{
|
||||
Movimiento mv = new Movimiento(MontoDecimal, TipoMovimientoSelecionado.ID, DepartaDepartTrabajoSeleccionado.Id,
|
||||
FechaMov, ConceptoSeleccionado.ID, Descripcion);
|
||||
await _finanzasRepository.CreateMovimientoAsync(mv);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void Salir()
|
||||
{
|
||||
GetCurrentWindow<MovimientoWindow>().Close();
|
||||
}
|
||||
}
|
||||
28
AdminFinanceRCA/ViewModels/ViewModelBase.cs
Normal file
28
AdminFinanceRCA/ViewModels/ViewModelBase.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Linq;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace AdminFinanceRCA.ViewModels;
|
||||
|
||||
public class ViewModelBase : ObservableObject
|
||||
{
|
||||
protected IWindowService? WindowService { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Obtiene la ventana asociada al ViewModel actual.
|
||||
/// </summary>
|
||||
/// <typeparam name="TWindow">El tipo de ventana a obtener (por ejemplo, MainWindow, LoginWindow).</typeparam>
|
||||
/// <returns>La ventana asociada al ViewModel, o null si no se encuentra.</returns>
|
||||
public TWindow? GetCurrentWindow<TWindow>() where TWindow : Window
|
||||
{
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
//return desktop.Windows.OfType<TWindow>().FirstOrDefault(w => w.DataContext == this);
|
||||
return desktop.Windows.OfType<TWindow>().FirstOrDefault(w => w.DataContext == this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
113
AdminFinanceRCA/Views/MainWindow.axaml
Normal file
113
AdminFinanceRCA/Views/MainWindow.axaml
Normal file
@@ -0,0 +1,113 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:AdminFinanceRCA.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="950" d:DesignHeight="500"
|
||||
x:Class="AdminFinanceRCA.Views.MainWindow"
|
||||
x:DataType="vm:MainWindowViewModel"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
Title="AdminFinanceRCA"
|
||||
WindowState="Maximized"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
FontFamily="Segoe UI">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:MainWindowViewModel/>
|
||||
</Design.DataContext>
|
||||
|
||||
<DockPanel LastChildFill="True" Background="#F5F5F5">
|
||||
|
||||
<!-- Menú superior estilo moderno -->
|
||||
<Menu DockPanel.Dock="Top" Background="#2C3E50" Foreground="White" Height="35" VerticalAlignment="Top">
|
||||
<!-- Menú Archivo -->
|
||||
<MenuItem Header="Archivo">
|
||||
<MenuItem Header="Exportar CSV" Command="{Binding CrearCsvCommand}"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Salir" Command="{Binding SalirCommand}" />
|
||||
</MenuItem>
|
||||
|
||||
<!-- Menú Herramientas -->
|
||||
<MenuItem Header="Herramientas">
|
||||
<MenuItem Header="Departamentos" Command="{Binding AgregarDepartamentoCommand}" />
|
||||
<MenuItem Header="Tipos de Movimiento" />
|
||||
<MenuItem Header="Conceptos"/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<!-- Título con estilo moderno -->
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Center" >
|
||||
<TextBlock FontSize="24" Margin="0 15" Text="Administrador Financiero Grupos"
|
||||
Foreground="Black" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Botones flotantes estilo moderno -->
|
||||
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 10 20 20">
|
||||
<Button Content="Agregar Movimiento"
|
||||
Background="#27AE60" Foreground="White" FontWeight="Bold"
|
||||
Padding="15 8" CornerRadius="5" Margin="0 0 10 0" Command="{Binding AgregarMovimientoCommand}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- DataGrid con estilo moderno -->
|
||||
<DataGrid Margin="15" HorizontalAlignment="Stretch" BorderThickness="1" CornerRadius="3" ItemsSource="{Binding Movimientos}">
|
||||
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ID" Width="80">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding ID}" Foreground="Black" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="Fecha Mov" Width="120">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding FechaMovimiento}" Foreground="Black" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="Grupo de Trabajo" Width="150">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding DeptoTrabajoNombre}" Foreground="Black" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="Monto" Width="120">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Monto}" Foreground="Black" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="Tipo Movimiento" Width="150">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding TipoMovNombre}" Foreground="Black" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="Concepto" Width="150">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding ConceptoNombre}" Foreground="Black" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="Descripcion" Width="250">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Descripcion}" Foreground="Black" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</DockPanel>
|
||||
</Window>
|
||||
11
AdminFinanceRCA/Views/MainWindow.axaml.cs
Normal file
11
AdminFinanceRCA/Views/MainWindow.axaml.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace AdminFinanceRCA.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
64
AdminFinanceRCA/Views/Mantenimiento_DepartTrabajo.axaml
Normal file
64
AdminFinanceRCA/Views/Mantenimiento_DepartTrabajo.axaml
Normal file
@@ -0,0 +1,64 @@
|
||||
<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_DepartTrabajoViewModel"
|
||||
x:Class="AdminFinanceRCA.Views.Mantenimiento_DepartTrabajo"
|
||||
Title="Mantenimiento Departamentos de Trabajo">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:Mantenimiento_DepartTrabajoViewModel/>
|
||||
</Design.DataContext>
|
||||
|
||||
<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" />
|
||||
</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="Grupos de Trabajo" FontWeight="Bold" Margin="0,0,0,5"/>
|
||||
<ListBox ItemsSource="{Binding GruposTrabajo}" DoubleTapped="OnListBoxDoubleTapped"
|
||||
Height="200">
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Margin="5">
|
||||
<TextBlock FontWeight="Bold"/>
|
||||
<TextBlock Foreground="Gray" Text="{Binding Nombre}"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
<TextBlock />
|
||||
</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 Grupo" FontSize="16" FontWeight="Bold"/>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="Nombre *" Margin="0,0,0,2"/>
|
||||
<TextBox Watermark="Ingrese el nombre" Text="{Binding Nombre}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="Descripción" Margin="0,0,0,2"/>
|
||||
<TextBox AcceptsReturn="True"
|
||||
Watermark="Ingrese la descripción" Height="60" Text="{Binding Descripcion}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</Window>
|
||||
29
AdminFinanceRCA/Views/Mantenimiento_DepartTrabajo.axaml.cs
Normal file
29
AdminFinanceRCA/Views/Mantenimiento_DepartTrabajo.axaml.cs
Normal 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_DepartTrabajo : Window
|
||||
{
|
||||
public Mantenimiento_DepartTrabajo()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnListBoxDoubleTapped(object sender, TappedEventArgs e)
|
||||
{
|
||||
if (DataContext is Mantenimiento_DepartTrabajoViewModel viewModel &&
|
||||
sender is ListBox listBox &&
|
||||
listBox.SelectedItem is DepartTrabajo selected)
|
||||
{
|
||||
viewModel.GrupoSeleccionado = selected;
|
||||
viewModel.Nombre = selected.Nombre;
|
||||
viewModel.Descripcion = selected.Descripcion;
|
||||
viewModel.EstaEditando = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
93
AdminFinanceRCA/Views/MovimientoWindow.axaml
Normal file
93
AdminFinanceRCA/Views/MovimientoWindow.axaml
Normal file
@@ -0,0 +1,93 @@
|
||||
<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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="500" Width="600" Height="500"
|
||||
CanResize="False"
|
||||
x:Class="AdminFinanceRCA.Views.MovimientoWindow"
|
||||
xmlns:vm="using:AdminFinanceRCA.ViewModels"
|
||||
x:DataType="vm:MovimientoWindowViewModel"
|
||||
Title="Agregar Movimiento"
|
||||
FontFamily="Segoe UI"
|
||||
FontSize="12"
|
||||
SizeToContent="WidthAndHeight"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:MovimientoWindowViewModel/>
|
||||
</Design.DataContext>
|
||||
|
||||
<Grid Margin="20" Width="500">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Título -->
|
||||
<TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="Nuevo Movimiento"
|
||||
FontSize="20" FontWeight="Bold" Margin="0 0 0 20"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<!-- 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.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Nombre}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<!-- 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.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Nombre}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<!-- 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.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Nombre}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</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 -->
|
||||
<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"/>
|
||||
|
||||
<!-- Descripción -->
|
||||
<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}"/>
|
||||
|
||||
<!-- Botones -->
|
||||
<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}"/>
|
||||
<Button Content="Guardar" Width="100" Height="35"
|
||||
Background="#27AE60" Foreground="White" FontWeight="Bold" Command="{Binding GuardarDatosAsyncCommand}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
13
AdminFinanceRCA/Views/MovimientoWindow.axaml.cs
Normal file
13
AdminFinanceRCA/Views/MovimientoWindow.axaml.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace AdminFinanceRCA.Views;
|
||||
|
||||
public partial class MovimientoWindow : Window
|
||||
{
|
||||
public MovimientoWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
18
AdminFinanceRCA/app.manifest
Normal file
18
AdminFinanceRCA/app.manifest
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<!-- This manifest is used on Windows only.
|
||||
Don't remove it as it might cause problems with window transparency and embedded controls.
|
||||
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
|
||||
<assemblyIdentity version="1.0.0.0" name="AdminFinanceRCA.Desktop"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
12
AdminFinanceRCA/appsettings.json
Normal file
12
AdminFinanceRCA/appsettings.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Data Source=/home/adalberto/Documentos/RocaFinanceGrupos.db"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user