Source code for babilonia.utils.cashflow

# SPDX-License-Identifier: GPL-3.0-or-later
#
# Copyright (C) 2025 The Project Authors
# See pyproject.toml for authors/maintainers.
# See LICENSE for license details.
"""
todo refactor docstring

"""

# IMPORTS
# ***********************************************************************
# import modules from other libs

# Native imports
# =======================================================================
import glob
import argparse
from pathlib import Path
# ... {develop}

# External imports
# =======================================================================
import pandas as pd
# ... {develop}

# Project-level imports
# =======================================================================
from babilonia.utils.core import *
from babilonia.accounting import CashFlow
# ... {develop}

# FUNCTIONS
# ***********************************************************************

[docs] def main(): char_w = 150 args = get_arguments() data_folder = Path(args.folder) data_type = args.type.lower() year_arg = args.year bank = get_bank(data_type) account = get_account(data_type) ls_priority = [ "Data", "Categoria", "Valor", "Descricao", ] cols_to_format = [ "Entradas", "Saidas", "Fluxo", "Entradas_Acum", "Saidas_Acum", "Fluxo_Acum", ] print("\n\n") print("=" * char_w) print(" Cashflow Analysis from Bank Statements\n".upper()) print(f" Folder : {data_folder}") print(f" Bank : {BANK_NAMES[data_type]}") print(f" Account : {ACCOUNT_NAMES[data_type]}") print(f" Year : {year_arg if year_arg is not None else 'ALL'}") print("=" * char_w) # Resolve file pattern (year wildcard handled inside helper) pattern_files = get_file_pattern(data_type, data_folder, year_arg) pattern_files = pattern_files.replace("T0.csv", "T1.csv") ls_files = glob.glob(pattern_files) if not ls_files: print(" No input files found. Nothing to process.") print("=" * char_w) return None # Group files by year (assumes year is the parent directory name) # ------------------------------------------------------------------ files_by_year = {} for f in ls_files: fpath = Path(f) try: year = fpath.parent.name except IndexError: continue files_by_year.setdefault(year, []).append(fpath) cf = PARSERS[data_type]() total_processed = 0 for year in sorted(files_by_year): print() # print("-" * char_w) print(f" Year {year}") print("-" * char_w) yearly_processed = 0 ls_dfs = [] for i, fpath in enumerate(files_by_year[year], start=1): name = fpath.stem print(f"[{i:02d}] {fpath.name}", end=" -> ") df = pd.read_csv(fpath, sep=";", dtype=str) ls_dfs.append(df.copy()) print(f"LOADED") yearly_processed += 1 print(f"\n Year completed. Output files loaded: {yearly_processed}") # Concat data # -------------------------------------------------------------------- df_full = pd.concat(ls_dfs).reset_index(drop=True) ls_cols = list(df_full.columns) ls_ordered = ls_priority + [c for c in ls_cols if c not in ls_priority] df_full = df_full[ls_ordered] name = f"CAIXA_{bank.upper()}_{account.upper()}_{year}" # Daily # -------------------------------------------------------------------- print("\n") print(f" Year {year} -- Daily Cash Flow (preview)") print("-" * char_w) df_pretty = CashFlow.format_currency_columns( df_full[ls_priority], columns=["Valor"] ) preview_df(df_pretty) print("\n") # export file_out = Path(args.folder) / f"{year}/{name}_DIARIO.csv" df_full.to_csv(file_out, sep=";", index=False) total_processed += 1 print(f" Output : {file_out}") # Run Cashflow analysis # -------------------------------------------------------------------- cf = CashFlow() cf.load_data(file_out) dc_cfa = cf.cashflow_analysis(df=cf.data, category=None) # Monthly # -------------------------------------------------------------------- print("\n") print(f" Year {year} -- Monthly Cash Flow") print("-" * char_w) df_pretty = CashFlow.format_currency_columns( dc_cfa["monthly"], columns=cols_to_format ) print(df_pretty) print("\n") # exports file_out = Path(args.folder) / f"{year}/{name}_MENSAL.csv" dc_cfa["monthly"].to_csv(file_out, sep=";", index=False) total_processed += 1 print(f" Output : {file_out}") # Yearly # -------------------------------------------------------------------- print("\n") print(f" Year {year} -- Annual Cash Flow") print("-" * char_w) df_pretty = CashFlow.format_currency_columns( dc_cfa["yearly"], columns=cols_to_format ) print(df_pretty) print("\n") file_out = Path(args.folder) / f"{year}/{name}_ANUAL.csv" dc_cfa["yearly"].to_csv(file_out, sep=";", index=False) total_processed += 1 print(f" Output : {file_out}") # Merge full system # -------------------------------------------------------------------- name = f"CAIXA_{bank.upper()}_{account.upper()}" ls_scales = ["DIARIO", "MENSAL", "ANUAL"] dc_scales = {"DIARIO": "Data", "MENSAL": "Mes", "ANUAL": "Ano"} for scale in list(dc_scales.keys()): pattern = Path(args.folder) / f"*/CAIXA*{scale}.csv" ls_files = glob.glob(str(pattern)) df = concat_dfs(ls_files) df.sort_values(by=dc_scales[scale], ascending=True, inplace=True) file_out = Path(args.folder) / f"{name}_O_{scale}.csv" df.to_csv(file_out, sep=";", index=False) total_processed += 1 # Yearly # -------------------------------------------------------------------- if scale == "ANUAL": print("\n") print(f" ANNUAL CASH FLOW") print("=" * char_w) cols_to_format = [ "Entradas", "Saidas", "Fluxo", "Entradas_Acum", "Saidas_Acum", "Fluxo_Acum", ] df_pretty = CashFlow.format_currency_columns(df, columns=cols_to_format) print(df_pretty) print("\n") print() print("=" * char_w) print(f" Completed. Output files written: {total_processed}") print("=" * char_w) print("\n\n") return None
# SCRIPT # *********************************************************************** # standalone behaviour as a script if __name__ == "__main__": main()