diff --git a/pfbudget/__main__.py b/pfbudget/__main__.py index 3785629..1348ca9 100644 --- a/pfbudget/__main__.py +++ b/pfbudget/__main__.py @@ -69,6 +69,27 @@ if __name__ == "__main__": assert args.keys() >= {"id"}, "argparser ill defined" params = args["id"] + case pfbudget.Operation.RuleModify: + assert args.keys() >= { + "id", + "category", + "date", + "description", + "bank", + "min", + "max", + "remove", + }, "argparser ill defined" + + nargs_1 = ["category", "date", "description", "regex", "bank", "min", "max"] + params = [] + for id in args["id"]: + param = {"id": id} + param |= {k: v[0] for k, v in args.items() if k in nargs_1 and args[k]} + param |= {k: None for k in args["remove"] if k in nargs_1} + + params.append(param) + case pfbudget.Operation.GroupAdd: assert "group" in args, "argparser ill defined" params = [pfbudget.types.CategoryGroup(group) for group in args["group"]] diff --git a/pfbudget/cli/runnable.py b/pfbudget/cli/runnable.py index ebe2504..3a44494 100644 --- a/pfbudget/cli/runnable.py +++ b/pfbudget/cli/runnable.py @@ -377,6 +377,18 @@ def category_rule(parser: argparse.ArgumentParser, universal: argparse.ArgumentP remove.set_defaults(op=Operation.RuleRemove) remove.add_argument("id", nargs="+", type=int) + modify = commands.add_parser("modify", parents=[universal]) + modify.set_defaults(op=Operation.RuleModify) + modify.add_argument("id", nargs="+", type=int) + modify.add_argument("--category", nargs=1, type=str) + modify.add_argument("--date", nargs=1, type=dt.date.fromisoformat) + modify.add_argument("--description", nargs=1, type=str) + modify.add_argument("--regex", nargs=1, type=str) + modify.add_argument("--bank", nargs=1, type=str) + modify.add_argument("--min", nargs=1, type=decimal.Decimal) + modify.add_argument("--max", nargs=1, type=decimal.Decimal) + modify.add_argument("--remove", nargs="*", default=[], type=str) + def run(): args = vars(argparser().parse_args()) diff --git a/pfbudget/common/types.py b/pfbudget/common/types.py index b090bbb..c8f39d4 100644 --- a/pfbudget/common/types.py +++ b/pfbudget/common/types.py @@ -19,6 +19,7 @@ class Operation(Enum): CategorySchedule = auto() RuleAdd = auto() RuleRemove = auto() + RuleModify = auto() GroupAdd = auto() GroupRemove = auto() diff --git a/pfbudget/core/manager.py b/pfbudget/core/manager.py index b4e6344..2597ea1 100644 --- a/pfbudget/core/manager.py +++ b/pfbudget/core/manager.py @@ -74,6 +74,11 @@ class Manager: with self.db.session() as session: session.removerules(params) + case Operation.RuleModify: + assert all(isinstance(param, dict) for param in params) + with self.db.session() as session: + session.updaterules(params) + case Operation.GroupAdd: with self.db.session() as session: session.addgroups(CategoryGroup(params)) diff --git a/pfbudget/db/client.py b/pfbudget/db/client.py index 67dbd19..175fa67 100644 --- a/pfbudget/db/client.py +++ b/pfbudget/db/client.py @@ -117,11 +117,12 @@ class DbClient: self.__session.add_all(rules) def removerules(self, ids: list[int]): - stmt = delete(CategoryRule).where( - CategoryRule.id.in_(ids) - ) + stmt = delete(CategoryRule).where(CategoryRule.id.in_(ids)) self.__session.execute(stmt) + def updaterules(self, rules: list[dict]): + self.__session.execute(update(CategoryRule), rules) + def addgroups(self, groups: list[CategoryGroup]): self.__session.add_all(groups) diff --git a/pfbudget/db/model.py b/pfbudget/db/model.py index 0a76846..4384cd6 100644 --- a/pfbudget/db/model.py +++ b/pfbudget/db/model.py @@ -114,7 +114,7 @@ class Category(Base): ) rules: Mapped[Optional[set[CategoryRule]]] = relationship( - cascade="all, delete-orphan", passive_deletes=True, default=None + cascade="all, delete-orphan", passive_deletes=True, default_factory=set ) schedule: Mapped[CategorySchedule] = relationship( back_populates="category", default=None