Primer comit

This commit is contained in:
2025-09-13 17:08:14 -06:00
commit be8111c2b8
30 changed files with 1339 additions and 0 deletions

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