# Copyright (C) 2026 Danilo M. GPL-2.0-only import calendar from datetime import date from firefly_cli import registry, output def _current_month(): """(first, last) ISO dates for the current calendar month.""" today = date.today() last_day = calendar.monthrange(today.year, today.month)[1] first = today.replace(day=1).isoformat() last = today.replace(day=last_day).isoformat() return first, last def _spent_scalar(budget_obj): """Sum a budget's nested `spent` array into a single number (for --human). Firefly sends spent as a per-currency list of {sum: "-12.34", ...}; we sum the sums. JSON output is untouched; this only feeds the table view.""" total = 0.0 for entry in budget_obj.get("spent") or []: try: total += float(entry.get("sum", 0)) except (TypeError, ValueError): pass return f"{total:.2f}" def _list_args(p): p.add_argument("--start", default=None, help="YYYY-MM-DD (default: 1st of this month)") p.add_argument("--end", default=None, help="YYYY-MM-DD (default: last of this month)") @registry.command("budget list", help="list budgets with spent for a period (default: current month)", args=_list_args) def cmd_list(args, ctx): first, last = _current_month() params = {"start": args.start or first, "end": args.end or last} resp = ctx.client.request("GET", "/api/v1/budgets", params=params) rows = output.unwrap(resp) if ctx.human and isinstance(rows, list): # Replace the nested spent array with a scalar so the table shows it. rows = [{**r, "spent": _spent_scalar(r)} for r in rows] output.emit(rows, human=ctx.human) return 0