Adds business logic for split transaction

Moves split member to be part of parent class and removes it from the
init.
This commit is contained in:
Luís Murta 2023-01-23 20:11:58 +00:00
parent ace5195164
commit 5235fcdfc3
Signed by: satprog
GPG Key ID: 169EF1BBD7049F94
4 changed files with 72 additions and 5 deletions

View File

@ -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 ###

View File

@ -28,6 +28,7 @@ class Operation(Enum):
TagRuleModify = auto()
Forge = auto()
Dismantle = auto()
Split = auto()
BankAdd = auto()
BankMod = auto()
BankDel = auto()

View File

@ -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?

View File

@ -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"}