aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-03 17:58:00 +0200
committerDanilo M. <danix@danix.xyz>2026-07-03 17:58:00 +0200
commit34ede2c7d38849282e46298538a14a7162cc9a37 (patch)
treea97478fcf797f5e9633fbea182e5d47194661425
parent203363fe96aabe2366985a769a7e10dabac69d04 (diff)
downloadfirefly-cli-34ede2c7d38849282e46298538a14a7162cc9a37.tar.gz
firefly-cli-34ede2c7d38849282e46298538a14a7162cc9a37.zip
feat(tx): tx add --budget assigns a budget by name or id
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--firefly_cli/commands/transaction.py5
-rw-r--r--tests/unit/test_commands_transaction.py23
2 files changed, 28 insertions, 0 deletions
diff --git a/firefly_cli/commands/transaction.py b/firefly_cli/commands/transaction.py
index 60af6f4..9f8e130 100644
--- a/firefly_cli/commands/transaction.py
+++ b/firefly_cli/commands/transaction.py
@@ -32,6 +32,8 @@ def _add_args(p):
p.add_argument("--date", default=None, help="YYYY-MM-DD (default today)")
p.add_argument("--category", default=None)
p.add_argument("--tags", default=None, help="comma-separated")
+ p.add_argument("--budget", default=None,
+ help="budget name or id to assign (must already exist)")
p.add_argument("--type", default=None,
help="withdrawal|deposit|transfer (overrides inference)")
p.add_argument("--dry-run", dest="dry_run", action="store_true",
@@ -67,6 +69,9 @@ def cmd_add(args, ctx):
split["category_name"] = args.category
if args.tags:
split["tags"] = [t.strip() for t in args.tags.split(",") if t.strip()]
+ if args.budget:
+ # Budgets must pre-exist; resolve name/id -> id (hard error on miss).
+ split["budget_id"] = ctx.resolver.budget(args.budget)["id"]
if ttype == "transfer":
# Transfer direction is easy to reverse silently (ISSUES.md #5); echo it
# to stderr so the user/agent can catch a swapped --from/--to. stdout
diff --git a/tests/unit/test_commands_transaction.py b/tests/unit/test_commands_transaction.py
index 61a09ab..7366b5c 100644
--- a/tests/unit/test_commands_transaction.py
+++ b/tests/unit/test_commands_transaction.py
@@ -430,3 +430,26 @@ class TestTxList(unittest.TestCase):
rc = tx.cmd_list(args, ctx)
self.assertEqual(rc, 0)
self.assertEqual(client.request.call_count, 2)
+
+class TestTxAddBudget(unittest.TestCase):
+ def test_budget_ref_sets_budget_id_on_split(self):
+ from types import SimpleNamespace
+ from unittest.mock import MagicMock
+ import firefly_cli.commands.transaction as tx
+
+ client = MagicMock()
+ client.request.return_value = {"data": {"id": "1", "attributes": {}}}
+ resolver = MagicMock()
+ resolver.account.side_effect = lambda n: {"id": "1", "name": n, "type": "asset"}
+ resolver.budget.return_value = {"id": "12", "name": "Groceries"}
+ ctx = SimpleNamespace(client=client, resolver=resolver, human=False)
+
+ args = SimpleNamespace(
+ amount="10", source="Checking", dest="Shop",
+ source_id=None, dest_id=None, desc=None, date="2026-07-03",
+ category=None, tags=None, type="withdrawal",
+ dry_run=False, skip_dupes=False, budget="Groceries")
+ rc = tx.cmd_add(args, ctx)
+ self.assertEqual(rc, 0)
+ body = client.request.call_args[1]["body"]
+ self.assertEqual(body["transactions"][0]["budget_id"], "12")