Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## A streamlined .gitignore for modern .NET projects
## including temporary files, build results, and
## files generated by popular .NET tools. If you are
## developing with Visual Studio, the VS .gitignore
## https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
## has more thorough IDE-specific entries.
##
## Get latest from https://github.com/github/gitignore/blob/main/Dotnet.gitignore

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/

# ASP.NET Scaffolding
ScaffoldingReadMe.txt

# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg

# Others
~$*
*~
CodeCoverage/

# MSBuild Binary and Structured Log
*.binlog

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
122 changes: 64 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,72 @@
# Reto Técnico: Procesamiento de Transacciones Bancarias (CLI)
# 📊 Procesador de Transacciones Bancarias (CLI) - .NET 8

## Objetivo:
## 🧾 Introducción

Desarrolla una aplicación de línea de comandos (CLI) que procese un archivo CSV con transacciones bancarias y genere un reporte que incluya:
Este proyecto es una aplicación de línea de comandos desarrollada en **C# con .NET 8**. Su objetivo es procesar un archivo CSV con transacciones bancarias para generar un reporte que contenga:

- **Balance Final:**
Suma de los montos de las transacciones de tipo "Crédito" menos la suma de los montos de las transacciones de tipo "Débito".
- 💰 Balance Final (Créditos - Débitos)
- 🔍 Transacción de Mayor Monto
- 📊 Conteo de Transacciones por tipo ("Crédito" y "Débito")

- **Transacción de Mayor Monto:**
Identificar el ID y el monto de la transacción con el valor más alto.
---

## ▶️ Instrucciones de Ejecución

### 1. Requisitos

- Tener instalado **.NET 8 SDK**
- Verifica la instalación con: `dotnet --version`
- Descarga desde: https://dotnet.microsoft.com/download/dotnet/8.0

### 2. Crear archivo CSV de prueba

- **Conteo de Transacciones:**
Número total de transacciones para cada tipo ("Crédito" y "Débito").
Contenido sugerido para `datos.csv`:

id,tipo,monto
1,Crédito,100.00
2,Débito,50.00
3,Crédito,200.00
4,Débito,75.00
5,Crédito,150.00

### 3. Ejecutar la aplicación

Ubicado en la carpeta del proyecto:

dotnet run -- ../data.csv

---

## Instrucciones

1. **Repositorio Base:**
Clona o haz un fork del repositorio base disponible en:
`https://github.com/codeableorg/interbank-academy-25`

2. **Entrada de Datos:**
La aplicación deberá leer un archivo CSV. Ejemplo de contenido:

```
id,tipo,monto
1,Crédito,100.00
2,Débito,50.00
3,Crédito,200.00
4,Débito,75.00
5,Crédito,150.00
```

3. **Salida del Programa:**
La aplicación debe mostrar el reporte final en la terminal.
Ejemplo de salida:

```
Reporte de Transacciones
---------------------------------------------
Balance Final: 325.00
Transacción de Mayor Monto: ID 3 - 200.00
Conteo de Transacciones: Crédito: 3 Débito: 2
```

4. **Lenguaje de Programación:**
Utiliza el lenguaje de tu preferencia. Opciones recomendadas:

- Python
- Java
- C#
- JavaScript (Node.js)

5. **README del Proyecto:**
Incluye un archivo `README.md` con la siguiente estructura:

- **Introducción:** Breve descripción del reto y su propósito.
- **Instrucciones de Ejecución:** Cómo instalar dependencias y ejecutar la aplicación.
- **Enfoque y Solución:** Lógica implementada y decisiones de diseño.
- **Estructura del Proyecto:** Archivos y carpetas principales.

6. **Documentación y Calidad del Código:**
- Código bien documentado y fácil de leer.
- Comentarios explicando pasos clave y lógica del programa.
## ⚙️ Enfoque y Solución

- Se creó una clase `Transaccion` para representar los datos.
- Toda la lógica de lectura, cálculo y reporte se colocó en `ProcesadorTransacciones.cs`.
- Se usó LINQ para sumar, contar y encontrar la transacción con mayor monto.
- Se separaron las responsabilidades y se manejaron errores de entrada.

---

## 📁 Estructura del Proyecto

TransaccionesApp/
├── Program.cs
├── Models/Transaccion.cs
├── Services/ProcesadorTransacciones.cs
├── data.csv
├── TransaccionesApp.csproj
└── README.md

La estructura del proyecto sigue una organización clara y modular:
- El archivo `Program.cs` actúa como punto de entrada principal, mientras que la carpeta `Models` contiene la clase `Transaccion.cs` que representa los datos de cada transacción.
- La lógica de procesamiento y generación del reporte está encapsulada en `ProcesadorTransacciones.cs`, dentro de la carpeta `Services`, promoviendo la separación de responsabilidades y facilitando el mantenimiento del código.

---

## ✅ Resultado Esperado

=== Procesador de Transacciones ===
Reporte de Transacciones
---------------------------------------------
Balance Final: 325.00
Transacción de Mayor Monto: ID 3 - 200.00
Conteo de Transacciones: Crédito: 3 Débito: 2
11 changes: 11 additions & 0 deletions TransaccionesApp/Models/Transaccion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace TransaccionesApp;

/// <summary>
/// Representa una transacción bancaria con ID, tipo y monto.
/// </summary>
public class Transaccion
{
public int Id { get; set; } // ID único de la transacción
public required string Tipo { get; set; } // Tipo de transacción: "Crédito" o "Débito"
public decimal Monto { get; set; } // Monto de la transacción
}
15 changes: 15 additions & 0 deletions TransaccionesApp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// See https://aka.ms/new-console-template for more information
using TransaccionesApp;

Console.WriteLine("=== Procesador de Transacciones ===");
Console.WriteLine();

// Validación de argumentos: se espera que se pase un solo argumento (la ruta del archivo CSV)
if (args.Length != 1)
{
Console.WriteLine("Uso: dotnet run <ruta_del_archivo_csv>");
return;
}

ProcesadorTransacciones.ProcesarArchivo(args[0]);
Console.WriteLine();
87 changes: 87 additions & 0 deletions TransaccionesApp/Services/ProcesadorTransacciones.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System.Globalization;

namespace TransaccionesApp;

/// <summary>
/// Clase que contiene la lógica para procesar transacciones desde un archivo CSV.
/// </summary>
public static class ProcesadorTransacciones
{
public static void ProcesarArchivo(string rutaArchivo)
{
// Validar si el archivo existe en la ruta especificada
if (!File.Exists(rutaArchivo))
{
Console.WriteLine("El archivo no existe: " + rutaArchivo);
return;
}

var transacciones = new List<Transaccion>(); // Lista donde se almacenarán todas las transacciones

try
{
// Leer todas las líneas del archivo, ignorando la primera (encabezados)
var lineas = File.ReadAllLines(rutaArchivo).Skip(1);

// Procesar cada línea del archivo CSV
foreach (var linea in lineas)
{
var partes = linea.Split(',');

// Validar que la línea tenga exactamente 3 partes: id, tipo, monto
if (partes.Length != 3)
continue;

// Crear un objeto Transaccion a partir de la línea
transacciones.Add(new Transaccion
{
Id = int.Parse(partes[0]),
Tipo = partes[1].Trim(),
Monto = decimal.Parse(partes[2], CultureInfo.InvariantCulture)
});
}

// Calcular el total de montos para transacciones de tipo "Crédito"
var totalCredito = transacciones
.Where(t => t.Tipo.Equals("Crédito", StringComparison.OrdinalIgnoreCase))
.Sum(t => t.Monto);

// Calcular el total de montos para transacciones de tipo "Débito"
var totalDebito = transacciones
.Where(t => t.Tipo.Equals("Débito", StringComparison.OrdinalIgnoreCase))
.Sum(t => t.Monto);

// Calcular el balance final: créditos - débitos
var balanceFinal = totalCredito - totalDebito;

// Encontrar la transacción con el monto más alto
var transaccionMayor = transacciones
.OrderByDescending(t => t.Monto)
.First();

// Contar la cantidad de transacciones de tipo "Crédito"
var conteoCredito = transacciones
.Count(t => t.Tipo.Equals("Crédito", StringComparison.OrdinalIgnoreCase));

// Contar la cantidad de transacciones de tipo "Débito"
var conteoDebito = transacciones
.Count(t => t.Tipo.Equals("Débito", StringComparison.OrdinalIgnoreCase));

// Mostrar el reporte en la terminal
Console.WriteLine("Reporte de Transacciones");
Console.WriteLine("---------------------------------------------");
Console.WriteLine($"Balance Final: {balanceFinal:F2}");
Console.WriteLine($"Transacción de Mayor Monto: ID {transaccionMayor.Id} - {transaccionMayor.Monto:F2}");
Console.WriteLine($"Conteo de Transacciones: Crédito: {conteoCredito} Débito: {conteoDebito}");
}
catch (Exception ex)
{
Console.WriteLine("Error procesando el archivo: " + ex.Message);
}
finally
{
Console.WriteLine();
Console.WriteLine(" - Proceso de lectura de transacciones finalizado.");
}
}
}
10 changes: 10 additions & 0 deletions TransaccionesApp/TransaccionesApp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
24 changes: 24 additions & 0 deletions interbank-academy-25.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransaccionesApp", "TransaccionesApp\TransaccionesApp.csproj", "{33BC2708-774C-2881-CEE1-7F7F98EDB2B3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{33BC2708-774C-2881-CEE1-7F7F98EDB2B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33BC2708-774C-2881-CEE1-7F7F98EDB2B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33BC2708-774C-2881-CEE1-7F7F98EDB2B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33BC2708-774C-2881-CEE1-7F7F98EDB2B3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {137CE233-29AA-4688-BEE1-2D17EAA89DA4}
EndGlobalSection
EndGlobal