Files
AdminFinanceRCA/AdminFinanceRCA/Repository.cs
2025-09-15 15:02:17 -06:00

319 lines
11 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using AdminFinanceRCA.Models;
using System.Data;
using Dapper;
using Microsoft.Data.Sqlite;
namespace AdminFinanceRCA;
public class FinanzasRepository
{
private readonly string _connectionString;
public FinanzasRepository()
{
var config = new AppConfig();
_connectionString = config.GetConnectionString();
InitializeDatabase();
}
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,
Descripcion TEXT 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)");
}
}
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, Nota)
VALUES (@Monto, @TipoMov, @DeptoTrabajo, @FechaMovimiento, @FechaRegistro, @Concepto, @Descripcion, @Nota);
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,
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
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,
Nota = @Nota
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);
}
}
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
#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()
{
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<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)
{
using (var connection = GetConnection())
{
var sql = "INSERT INTO TipoMovimiento (Nombre) VALUES (@Nombre); SELECT last_insert_rowid();";
return await connection.ExecuteScalarAsync<int>(sql, tipoMovimiento);
}
}
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
#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
}