diff --git a/README.md b/README.md index 668a6a2..e56112b 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,65 @@ -# Reto Técnico: Procesamiento de Transacciones Bancarias (CLI) +# 📊 Procesador de Transacciones Bancarias (CLI) -## 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: +Aplicación de línea de comandos (CLI) que procesa un archivo CSV con transacciones bancarias. Genera un reporte en la terminal con: -- **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 (ID y valor) +- 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. - -- **Conteo de Transacciones:** - Número total de transacciones para cada tipo ("Crédito" y "Débito"). +Este proyecto forma parte del reto técnico propuesto por Interbank Academy 25. --- -## 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. +## 🛠️ Instrucciones de Ejecución + +1. Asegúrate de tener Node.js instalado. Puedes descargarlo desde: https://nodejs.org +2. Abre tu terminal de comando, luego clona el repositorio, navega al directorio y ejecuta el script: + +````bash +git clone https://github.com/accel33/interbank-academy-25 +cd interbank-academy-25 +node src/index.js +```` +## 🧠 Enfoque y Solución + +- Se usó Node.js sin librerías externas para mantener el proyecto simple y portable. +- Se leyó el archivo CSV utilizando el módulo nativo fs +- Se crea un arreglo mediante el uso del metodo de cadena split(',') +- Se convierte cada línea del archivo en un objeto con sus campos: ID, tipo y monto. +- Se separaron las transacciones en “Crédito” y “Débito” para calcular: + - El balance total, sumando los créditos y restando los débitos. + - El conteo por tipo usando un contador simple. + - La transacción de mayor monto comparando cada entrada. +- El código se organizó en funciones pequeñas y claras (parseCSV, calcularBalance, etc.) para facilitar la lectura y el mantenimiento. +- El resultado se imprime en consola con formato legible, usando líneas y etiquetas para que el reporte sea fácil de entender a simple vista. + +## 📁 Estructura del proyecto + +``` +├── data/ +│ └── transactions.csv # Archivo de entrada +├── src/ +│ └── index.js # Lógica principal +├── .gitignore +├── package.json +└── README.md +``` + + +## 🧪 Ejemplo de Salida +````bash +================= REPORTE DE TRANSACCIONES ================= + +Balance Final: S/ 1,250.00 + +Transacción de mayor monto: +ID: TX8921 - Monto: S/ 980.00 + +Conteo de transacciones: +Crédito: 5 +Débito: 3 + +============================================================ +```` \ No newline at end of file diff --git a/data.csv b/data/transactions.csv similarity index 99% rename from data.csv rename to data/transactions.csv index 11cbd58..0bc7f14 100644 --- a/data.csv +++ b/data/transactions.csv @@ -2,7 +2,7 @@ id,tipo,monto 1,Débito,235.81 2,Débito,227.59 3,Crédito,34.28 -4,Crédito,309.36 +4,Crédito,abcdf 5,Crédito,418.59 6,Crédito,335.24 7,Débito,449.74 diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..52507e4 --- /dev/null +++ b/src/index.js @@ -0,0 +1,76 @@ +const { throws } = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const csvPath = path.join(__dirname, "../data/transactions.csv"); + +// Leer archivo CSV +const content = fs.readFileSync(csvPath, "utf-8"); +const lines = content.trim().split("\n"); +const [header, ...rows] = lines; + +// Parsear transacciones +const rawTransactions = rows.map((line, index) => { + try { + const [id, tipo, monto] = line.split(","); + + const parsedId = Number(id); + const parsedMonto = parseFloat(monto); + + if (isNaN(parsedId)) { + throw new Error(`Línea ${index + 2}: El ID no es numérico → "${id}"`); + } + + if (isNaN(parsedMonto)) { + throw new Error( + `Línea ${index + 2}: El monto no es numérico → "${monto}"`, + ); + } + + return { + id: parsedId, + tipo: tipo.trim(), + monto: parsedMonto, + }; + } catch (e) { + console.error("Error al procesar línea:", e.message); + return null; // así podemos filtrar luego + } +}); +const transactions = rawTransactions.filter(Boolean); + +let creditTotal = 0; +let debitTotal = 0; +let maxTransaction = { id: null, monto: 0 }; + +const count = { + Crédito: 0, + Débito: 0, +}; + +transactions.forEach((tx) => { + if (tx.tipo === "Crédito") { + creditTotal += tx.monto; + count.Crédito++; + } else if (tx.tipo === "Débito") { + debitTotal += tx.monto; + count.Débito++; + } + + if (tx.monto > maxTransaction.monto) { + maxTransaction = { id: tx.id, monto: tx.monto }; + } +}); + +const finalBalance = creditTotal - debitTotal; + +// Mostrar reporte +console.log("Reporte de Transacciones"); +console.log("---------------------------------------------"); +console.log(`Balance Final: ${finalBalance.toFixed(2)}`); +console.log( + `Transacción de Mayor Monto: ID ${maxTransaction.id} - ${maxTransaction.monto.toFixed(2)}`, +); +console.log( + `Conteo de Transacciones: Crédito: ${count.Crédito} Débito: ${count.Débito}`, +);