defmodule Ledger.FileHandler do @moduledoc """ Módulo para manejo de archivos y salida de datos en el sistema Ledger. Proporciona funciones para mostrar información de entidades, balances y errores. """ alias Ledger.Moneda @doc """ Muestra el balance proporcionado en el archivo especificado o en la salida estándar. ## Parámetros - `balance`: Mapa con las monedas y sus respectivos montos. - `archivo`: Archivo donde se mostrará el balance o "stdout" para mostrar por salida estándar. ## Retorno - `:ok` después de mostrar el balance. """ def mostrar_balance(balance, archivo) do msg_balance = "✦ . ⁺ . ✦ BALANCE ✦ . ⁺ . ✦" cond do archivo == "stdout" -> IO.puts(msg_balance) true -> File.write!(archivo, msg_balance <> "\n", [:append]) end Enum.each(balance, fn {moneda, monto} -> mostrar_linea_balance(moneda, monto, archivo) end) end @doc """ Muestra la información de un usuario. ## Parámetros - `usuario`: Estructura del usuario. - `archivo`: Archivo donde se mostrará la información o "stdout" para mostrar por salida estándar. ## Retorno - `informacion` mostrada. """ def mostrar_usuario(usuario, archivo) do informacion = """ ✦ . ⁺ . ✦ USUARIO #{usuario.id} ✦ . ⁺ . ✦ Nombre: #{usuario.nombre} Fecha de Nacimiento: #{Date.to_iso8601(usuario.fecha_nacimiento)} Creado: #{NaiveDateTime.to_iso8601(usuario.inserted_at)} Modificado: #{NaiveDateTime.to_iso8601(usuario.updated_at)} """ cond do archivo == "stdout" -> IO.puts(informacion) true -> File.write!(archivo, informacion <> "\n", [:append]) end informacion end @doc """ Muestra la información de una moneda. ## Parámetros - `moneda`: Estructura de la moneda. - `archivo`: Archivo donde se mostrará la información o "stdout" para mostrar por salida estándar. ## Retorno - `informacion` mostrada. """ def mostrar_moneda(moneda, archivo) do informacion = """ ✦ . ⁺ . ✦ MONEDA #{moneda.id} ✦ . ⁺ . ✦ Nombre: #{moneda.nombre} Precio: #{moneda.precio_usd} Creado: #{NaiveDateTime.to_iso8601(moneda.inserted_at)} Modificado: #{NaiveDateTime.to_iso8601(moneda.updated_at)} """ cond do archivo == "stdout" -> IO.puts(informacion) true -> File.write!(archivo, informacion <> "\n", [:append]) end informacion end @doc """ Muestra la información de una transacción. ## Parámetros - `transaccion`: Estructura de la transacción. - `archivo`: Archivo donde se mostrará la información o "stdout" para mostrar por salida estándar. ## Retorno - `informacion` mostrada. """ def mostrar_transaccion(transaccion, archivo) do lineas = [ "✦ . ⁺ . ✦ TRANSACCIÓN #{transaccion.id} ✦ . ⁺ . ✦", "Tipo: #{transaccion.tipo}", "Cuenta Origen: #{transaccion.cuenta_origen_id}", if(transaccion.cuenta_destino_id, do: "Cuenta Destino: #{transaccion.cuenta_destino_id}"), "Moneda Origen: #{transaccion.moneda_origen_id}", if(transaccion.moneda_destino_id, do: "Moneda Destino: #{transaccion.moneda_destino_id}"), "Monto: #{:io_lib.format("~.6f", [transaccion.monto]) |> to_string()}", "Creado: #{NaiveDateTime.to_iso8601(transaccion.inserted_at)}", "Modificado: #{NaiveDateTime.to_iso8601(transaccion.updated_at)}\n" ] informacion = lineas |> Enum.filter(& &1) |> Enum.join("\n") cond do archivo == "stdout" -> IO.puts(informacion) true -> File.write!(archivo, informacion <> "\n", [:append]) end informacion end @doc """ Muestra un error en la salida estándar. ## Parámetros - `razon`: Razón del error. """ def mostrar_error(razon) do IO.puts("{:error, " <> razon <> "}") end @doc """ Extrae un mensaje de error de un changeset de Ecto. ## Parámetros - `changeset`: Changeset de Ecto. ## Retorno - `mensaje_error`: Mensaje de error extraído. """ def extraer_error(changeset) do mensaje_error = case changeset.errors do [error | _] -> {_campo, {mensaje, _}} = error "#{mensaje}" [] -> case changeset.constraints do [%{type: :unique, constraint: "usuarios_nombre_index"} | _] -> "El nombre ya está en uso" [%{type: :unique, constraint: "monedas_nombre_index"} | _] -> "El nombre ya está en uso" _ -> "Error desconocido" end end mensaje_error end defp mostrar_linea_balance(moneda, monto, archivo) do nombre_moneda = Moneda.obtener_nombre(moneda) monto_decimales = :io_lib.format("~.6f", [monto]) |> to_string() monto_str = "#{nombre_moneda}=#{monto_decimales}" cond do archivo == "stdout" -> IO.puts(monto_str) true -> File.write!(archivo, monto_str <> "\n", [:append]) end end end