From 166f82d0bfdc598099c088275d68dc42499694f9 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Thu, 2 Jul 2026 09:10:46 +0200 Subject: feat: tx add --from-id/--to-id to disambiguate same-name accounts (v0.3.7) ISSUES.md #2: two accounts can share a name (e.g. expense id 52 and revenue id 129 both "Nexi"), making --from/--to ambiguous and unresolvable. Add --from-id/--to-id to target an account by numeric id. Per side, exactly one of the name flag or the id flag; sides independent. The id path fetches the account (resolver.account_by_id), validating existence before writing. Name-only callers unchanged; JSON/exit unchanged, so PATCH. Co-Authored-By: Claude Opus 4.8 --- firefly_cli/__init__.py | 2 +- firefly_cli/commands/transaction.py | 21 +++++++++++++++++---- firefly_cli/resolver.py | 6 ++++++ 3 files changed, 24 insertions(+), 5 deletions(-) (limited to 'firefly_cli') diff --git a/firefly_cli/__init__.py b/firefly_cli/__init__.py index 27e214f..1ed8352 100644 --- a/firefly_cli/__init__.py +++ b/firefly_cli/__init__.py @@ -2,4 +2,4 @@ # Copyright (C) 2026 Danilo M. # Licensed under the GNU General Public License v2.0 only. -__version__ = "0.3.6" +__version__ = "0.3.7" diff --git a/firefly_cli/commands/transaction.py b/firefly_cli/commands/transaction.py index 714d2d4..3ce20f3 100644 --- a/firefly_cli/commands/transaction.py +++ b/firefly_cli/commands/transaction.py @@ -22,8 +22,12 @@ def _infer_type(src_type, dst_type): def _add_args(p): p.add_argument("amount") - p.add_argument("--from", dest="source", required=True, help="source account") - p.add_argument("--to", dest="dest", required=True, help="destination account") + p.add_argument("--from", dest="source", default=None, help="source account (name)") + p.add_argument("--to", dest="dest", default=None, help="destination account (name)") + p.add_argument("--from-id", dest="source_id", default=None, + help="source account by numeric id (disambiguates same-name accounts)") + p.add_argument("--to-id", dest="dest_id", default=None, + help="destination account by numeric id (disambiguates same-name accounts)") p.add_argument("--desc", default=None) p.add_argument("--date", default=None, help="YYYY-MM-DD (default today)") p.add_argument("--category", default=None) @@ -36,9 +40,18 @@ def _add_args(p): help="skip if a tx with same amount+date+source+destination exists") @registry.command("tx add", help="record a transaction; source/destination resolve to accounts, category/tags auto-create", args=_add_args) +def _resolve_side(ctx, name, acc_id, side): + # Exactly one of name/id per side (mutually exclusive). id path (ISSUES.md + # #2) fetches by id, validating existence; name path resolves as before. + if bool(name) == bool(acc_id): + raise FireflyError( + f"--{side}/--{side}-id: supply exactly one " + f"(got name={name!r}, id={acc_id!r})") + return ctx.resolver.account_by_id(acc_id) if acc_id else ctx.resolver.account(name) + def cmd_add(args, ctx): - src = ctx.resolver.account(args.source) - dst = ctx.resolver.account(args.dest) + src = _resolve_side(ctx, args.source, args.source_id, "from") + dst = _resolve_side(ctx, args.dest, args.dest_id, "to") ttype = args.type or _infer_type(src.get("type"), dst.get("type")) from datetime import date as _date split = { diff --git a/firefly_cli/resolver.py b/firefly_cli/resolver.py index 7673af6..2a73e79 100644 --- a/firefly_cli/resolver.py +++ b/firefly_cli/resolver.py @@ -28,6 +28,12 @@ class Resolver: def account(self, name): return self._match("account", self._list("/api/v1/accounts"), name) + def account_by_id(self, acc_id): + # Escape hatch for same-name accounts (ISSUES.md #2): GET the account + # directly; a bad id 404s and client.request surfaces a FireflyError. + item = self.client.request("GET", f"/api/v1/accounts/{acc_id}")["data"] + return {"id": item["id"], **item.get("attributes", {})} + def tag(self, name): return self._match("tag", self._list("/api/v1/tags"), name) -- cgit v1.2.3