Source code for finalynx.budget._render

"""
This module contains the logic for displaying a table of expenses. It is only used
internally by the `Budget` class.
"""
from datetime import datetime
from typing import List
from typing import Optional

from rich import box
from rich.table import Table

from ..config import get_active_theme as TH
from .expense import Constraint
from .expense import Expense
from .expense import Period
from .expense import Status


[docs]def _render_expenses_table( expenses: List[Expense], title: str = "", caption: str = "", focus: Optional[int] = None, ) -> Table: """Generate a rich console table from a list of expenses.""" table = Table(title=title, box=box.MINIMAL, caption=caption, caption_justify="right", expand=True) table.add_column("#", justify="center", style=TH().TEXT) table.add_column("Date", justify="left", style="orange1") table.add_column("Time", justify="left", style="orange1") table.add_column("Amount", justify="right", style="red") table.add_column("Merchant", justify="left", style="cyan") table.add_column("Category", justify="left", style=TH().HINT) table.add_column("Status", justify="left", style=TH().TEXT) table.add_column("I Paid", justify="right", style="red") table.add_column("Payback", justify="left", style=TH().TEXT) table.add_column("Type", justify="left", style=TH().TEXT) table.add_column("Period", justify="left", style=TH().TEXT) table.add_column("Comment", justify="left", style=TH().HINT) for i, t in enumerate(expenses): # Format date and time ts_date = t.as_datetime() day_name_str = ts_date.strftime("%A")[:3] day_nth_str = ts_date.strftime("%d") month_str = ts_date.strftime("%B") time_str = ts_date.strftime("%H:%M") date_str = f"{day_name_str} {day_nth_str} {month_str[:3]}" # Format amount with colors amount_color = "" if t.amount < 0 else "[green]" amount_str = f"{amount_color}{t.amount:.2f} €" # Format i_paid with colors just as amount i_paid_color = "[green]" if t.i_paid is not None and t.i_paid > 0 else "" i_paid_str = f"{i_paid_color}{t.i_paid:.2f} €" if t.i_paid is not None else "" # Add a separator between months separator = False if len(expenses) > 1 and i < len(expenses) - 1: np1_month_str = datetime.utcfromtimestamp(int(expenses[i + 1].timestamp) / 1000).strftime("%B") separator = bool(month_str != np1_month_str) # If focus is set, highlight the corresponding row and dim the others if focus is not None: style = "bold" if i == focus else "dim" else: style = "dim" if "(transfer)" in t.merchant_name else "none" # Add the row to the table table.add_row( str(t.cell_number), date_str, time_str, amount_str, t.merchant_name, t.merchant_category[:30], str(t.status.value).capitalize() if t.status != Status.UNKNOWN else "", i_paid_str, t.payback, str(t.constraint.value).capitalize() if t.constraint != Constraint.UNKNOWN else "", str(t.period.value).capitalize() if t.period != Period.UNKNOWN else "", t.comment, style=style, end_section=separator, ) return table