Verified Commit 6846a1bc authored by Jakob Moser's avatar Jakob Moser
Browse files

Introduce CashFlowAnalysis class

parent 44e09e99
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
from pathlib import Path
from dataclasses import dataclass
from typing import Self
from decimal import Decimal
import sys
import json

from tabulate import tabulate

from ..budget_plan.BudgetPlan import BudgetPlan
from ..payment_order.PaymentOrder import PaymentOrder

from ..budget_plan.BudgetPlanLoader import load_pdf
from ..payment_order.PaymentOrderCollection import PaymentOrderCollection


def _format_as_euro_de(amount: Decimal) -> str:
    return f"{amount}".replace(".", ",")


@dataclass(eq=False, frozen=True)
class CashFlowAnalysis:
    budget_plan: BudgetPlan
    payment_orders: PaymentOrderCollection

    @property
    def balances(self) -> str:
        sums = self.payment_orders.sums_by_budgetary_item_id

        output_rows = [
            (
                item.id,
                item.name,
                spent := sums.get(item.id, Decimal("0.00")),
                remaining := item.amount - spent,
                item.amount,
            )
            for item in self.budget_plan.items
        ]

        formatted_output_rows = [
            (
                id,
                name,
                _format_as_euro_de(spent),
                _format_as_euro_de(remaining),
                _format_as_euro_de(total),
            )
            for (id, name, spent, remaining, total) in output_rows
        ]

        return tabulate(
            formatted_output_rows,
            headers=["Budgetposten", "Name", "Ausgegeben", "Verbleibend", "Geplant"],
            colalign=("right", "left", "right", "right", "right"),
        )

    @classmethod
    def from_files(cls, payment_orders_path: Path, budget_plan_path: Path) -> Self:
        budget_plan = load_pdf(budget_plan_path)
        return cls(budget_plan, PaymentOrderCollection(payment_orders_path))
+0 −52
Original line number Diff line number Diff line
from pathlib import Path
from decimal import Decimal
import sys
import json

from tabulate import tabulate

from ..payment_order.PaymentOrderCollection import PaymentOrderCollection
from ..budget_plan.BudgetPlanLoader import load_pdf


def _format_as_euro_de(amount: Decimal) -> str:
    return f"{amount}".replace(".", ",")


def tabulate_balances(payment_orders_path: Path, budget_plan_path: Path) -> None:
    sums = PaymentOrderCollection(payment_orders_path).sums_by_budgetary_item_id
    # print(sums)
    budget_plan = load_pdf(budget_plan_path)

    with open("instance/budget_plan.json", "w") as f:
        json.dump(budget_plan.as_dict, f, indent=4, ensure_ascii=False)

    output_rows = [
        (
            item.id,
            item.name,
            spent := sums.get(item.id, Decimal("0.00")),
            remaining := item.amount - spent,
            item.amount,
        )
        for item in budget_plan.items
    ]

    formatted_output_rows = [
        (
            id,
            name,
            _format_as_euro_de(spent),
            _format_as_euro_de(remaining),
            _format_as_euro_de(total),
        )
        for (id, name, spent, remaining, total) in output_rows
    ]

    print(
        tabulate(
            formatted_output_rows,
            headers=["Budgetposten", "Name", "Ausgegeben", "Verbleibend", "Geplant"],
            colalign=("right", "left", "right", "right", "right"),
        )
    )
+5 −2
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ from termcolor import cprint, colored
from pathlib import Path
import questionary

from ..analysis.cash_accounting import tabulate_balances
from ..analysis.CashFlowAnalysis import CashFlowAnalysis
from ..integrations.schwalbe.studienfachschaften import (
    get_studienfachschaften,
    Studienfachschaft,
@@ -12,6 +12,9 @@ from ..integrations.schwalbe.studienfachschaften import (
def _start_auto_mode() -> None:
    studienfachschaft = _ask_for_studienfachschaft()

    # TODO Ask for year, get budget plan, parse budget plan
    # TODO Somehow ask for payment orders


def _start_manual_mode() -> None:
    budget_plan_path_str = questionary.path("Pfad zum Budgetplan (*.pdf):").ask()
@@ -43,7 +46,7 @@ def _start_manual_mode() -> None:
        exit(210)

    print()
    tabulate_balances(payment_orders_path, budget_plan_path)
    print(CashFlowAnalysis.from_files(payment_orders_path, budget_plan_path).balances)


def _ask_for_studienfachschaft() -> Studienfachschaft: