Commit 4a6400f6 authored by Jakob Moser's avatar Jakob Moser
Browse files

Implement pay() and settle() methods

parent b9652481
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
from typing import Protocol


class IntLike(Protocol):
    """
    Any object implementing the __int__ magic method that allows converting its instances to ints.
    """

    def __int__(self) -> int:
        pass
+55 −1
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ from babel.numbers import format_currency
from sqlalchemy.orm import Mapped, mapped_column

from poolpay.model.Base import Base
from poolpay.model.IntLike import IntLike


class Person(Base):
@@ -28,9 +29,62 @@ class Person(Base):
    @property
    def balance_str(self) -> str:
        """
        :return: the balance formatted as a string, e.g. "2,50 €" or "-4,40 €".
        Return the balance formatted as string:

        >>> p = Person(name="Max", cl_account_name="mustermann", balance_cents=-250)
        >>> p.balance_str
        -2,50 
        >>> p.balance_cents = 1000
        >>> p.balance_str
        10,00 
        """
        return format_currency(self.balance_cents / 100, "EUR", locale="de_DE")

    def settle(self) -> None:
        """
        Settle all debts this person has, by ...

        a) ... setting the balance to 0 if it previously was negative.
        b) ... leaving the balance unchanged if it was non-negative.

        Example a):

        >>> p_with_credit = Person(name="Max", cl_account_name="mustermann", balance_cents=1000)
        >>> p.settle()
        >>> p_with_credit.balance_cents
        1000

        Example b):

        >>> p_with_debt = Person(name="Max", cl_account_name="mustermann", balance_cents=-1000)
        >>> p.settle()
        >>> p_with_debt.balance_cents
        0
        """
        self.balance_cents = max(0, self.balance_cents)

    def pay(self, to_be_paid: int | IntLike) -> None:
        """
        Pay something, deducing its value (in cents) from the current balance.

        >>> p = Person(name="Max", cl_account_name="mustermann")
        >>> p.balance_cents
        0
        >>> p.pay(100)
        >>> p.balance_cents
        -100

        :param to_be_paid: Either a direct monetary amount in cents, or an object that can be converted to it using int(...)
        """
        amount_cents = int(to_be_paid)
        self.balance_cents -= amount_cents

    def __str__(self) -> str:
        """
        Convert the person to a human-readable string representation:

        >>> p = Person(name="Max", cl_account_name="mustermann", balance_cents=-250)
        >>> str(p)
        Max (mustermann@cl): -2,50 
        """
        return f"{self.name} ({self.cl_account_name}@cl): {self.balance_str}"