From 5235fcdfc347b96838072f3c8820fdff180c691c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Murta?= Date: Mon, 23 Jan 2023 20:11:58 +0000 Subject: [PATCH] Adds business logic for split transaction Moves split member to be part of parent class and removes it from the init. --- ...11d9ff_split_member_of_base_transaction.py | 40 +++++++++++++++++++ pfbudget/common/types.py | 1 + pfbudget/core/manager.py | 30 +++++++++++++- pfbudget/db/model.py | 6 +-- 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 alembic/versions/18572111d9ff_split_member_of_base_transaction.py diff --git a/alembic/versions/18572111d9ff_split_member_of_base_transaction.py b/alembic/versions/18572111d9ff_split_member_of_base_transaction.py new file mode 100644 index 0000000..a5847b2 --- /dev/null +++ b/alembic/versions/18572111d9ff_split_member_of_base_transaction.py @@ -0,0 +1,40 @@ +"""Split member of base transaction + +Revision ID: 18572111d9ff +Revises: 28556ab17c56 +Create Date: 2023-01-23 20:09:37.892997+00:00 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "18572111d9ff" +down_revision = "28556ab17c56" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column( + "transactions", + "split", + existing_type=sa.BOOLEAN(), + nullable=False, + schema="transactions", + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column( + "transactions", + "split", + existing_type=sa.BOOLEAN(), + nullable=True, + schema="transactions", + ) + # ### end Alembic commands ### diff --git a/pfbudget/common/types.py b/pfbudget/common/types.py index 0ce7d54..0fe3efe 100644 --- a/pfbudget/common/types.py +++ b/pfbudget/common/types.py @@ -28,6 +28,7 @@ class Operation(Enum): TagRuleModify = auto() Forge = auto() Dismantle = auto() + Split = auto() BankAdd = auto() BankMod = auto() BankDel = auto() diff --git a/pfbudget/core/manager.py b/pfbudget/core/manager.py index ccae418..333b07d 100644 --- a/pfbudget/core/manager.py +++ b/pfbudget/core/manager.py @@ -17,6 +17,7 @@ from pfbudget.db.model import ( MoneyTransaction, Nordigen, Rule, + SplitTransaction, Tag, TagRule, Transaction, @@ -180,6 +181,32 @@ class Manager: links = [link.link for link in params] session.remove_links(original, links) + case Operation.Split: + if len(params) < 1 and not all( + isinstance(p, Transaction) for p in params + ): + raise TypeError(f"{params} are not transactions") + + # t -> t1, t2, t3; t.value == Σti.value + original: Transaction = params[0] + if not original.amount == sum(t.amount for t in params[1:]): + raise ValueError( + f"{original.amount}€ != {sum(v for v, _ in params[1:])}€" + ) + + with self.db.session() as session: + originals = session.get(Transaction, Transaction.id, [original.id]) + assert len(originals) == 1, ">1 transactions matched {original.id}!" + + originals[0].split = True + transactions = [ + SplitTransaction( + originals[0].date, t.description, t.amount, originals[0].id + ) + for t in params[1:] + ] + session.add(transactions) + case Operation.Export: with self.db.session() as session: self.dump(params[0], sorted(session.get(Transaction))) @@ -194,12 +221,11 @@ class Manager: row["description"], row["amount"], row["bank"], - False, ) case "money": transaction = MoneyTransaction( - row["date"], row["description"], row["amount"], False + row["date"], row["description"], row["amount"] ) # TODO case "split" how to match to original transaction?? also save ids? diff --git a/pfbudget/db/model.py b/pfbudget/db/model.py index 4c5ff55..2be6a07 100644 --- a/pfbudget/db/model.py +++ b/pfbudget/db/model.py @@ -91,6 +91,8 @@ class Transaction(Base, Export): description: Mapped[Optional[str]] amount: Mapped[money] + split: Mapped[bool] = mapped_column(init=False) + type: Mapped[str] = mapped_column(init=False) category: Mapped[Optional[TransactionCategory]] = relationship(init=False) @@ -105,6 +107,7 @@ class Transaction(Base, Export): date=self.date, description=self.description, amount=self.amount, + split=self.split, type=self.type, category=self.category.format if self.category else None, # TODO note @@ -122,7 +125,6 @@ idfk = Annotated[ class BankTransaction(Transaction): bank: Mapped[bankfk] = mapped_column(nullable=True) - split: Mapped[bool] = mapped_column(use_existing_column=True, nullable=True) __mapper_args__ = {"polymorphic_identity": "bank", "polymorphic_load": "inline"} @@ -132,8 +134,6 @@ class BankTransaction(Transaction): class MoneyTransaction(Transaction): - split: Mapped[bool] = mapped_column(use_existing_column=True, nullable=True) - __mapper_args__ = {"polymorphic_identity": "money"}