1
0
Fork 0
forked from s3lph/matemat
matemat/matemat/db/primitives/Transaction.py
s3lph f3af4d64a7
feat: Immediately purchase a product by calling /?ean=...
chore: Replace datetime.utcnow with datetime.now(UTC)
chore: Replace sqlite3 qmark-bindings with named bindings
2024-11-23 04:35:05 +01:00

163 lines
5.4 KiB
Python

from typing import Optional
from datetime import datetime
from matemat.db.primitives import User
from matemat.util.currency_format import format_chf
class Transaction:
"""
Representation of a generic transaction involving an user and an amount of money.
:param _id: The transaction ID in the database.
:param user: The user affected by this transaction.
:param value: The monetary value of this transaction.
:param old_balance: The balance on the user's account before this transaction.
:param date: The date of this transaction.
"""
def __init__(self, _id: int, user: User, value: int, old_balance: int, date: datetime) -> None:
self.id: int = _id
self.user: User = user
self.value: int = value
self.old_balance: int = old_balance
self.date: datetime = date
@property
def receipt_date(self) -> str:
if self.date == datetime.fromtimestamp(0, UTC):
return '<unknown> '
date: str = self.date.strftime('%d.%m.%Y, %H:%M')
return date
@property
def receipt_value(self) -> str:
value: str = format_chf(self.value, with_currencysign=False, plus_sign=True).rjust(8)
return value
@property
def receipt_description(self) -> str:
return 'Unidentified transaction'
@property
def receipt_message(self) -> Optional[str]:
return None
def __eq__(self, other) -> bool:
if not isinstance(other, Transaction):
return False
return self.id == other.id and \
self.user == other.user and \
self.value == other.value and \
self.old_balance == other.old_balance and \
self.date == other.date
def __hash__(self) -> int:
return hash((self.id, self.user, self.value, self.old_balance, self.date))
class Consumption(Transaction):
"""
Representation of a consumption involving an user, a product and an amount of money.
:param _id: The transaction ID in the database.
:param user: The user affected by this transaction.
:param value: The (negative) price of the product that was bought.
:param old_balance: The balance on the user's account before this transaction.
:param date: The date of this transaction.
:param product: The name of the product that was bought.
"""
def __init__(self, _id: int, user: User, value: int, old_balance: int, date: datetime, product: str) -> None:
super().__init__(_id, user, value, old_balance, date)
self.product: str = product
@property
def receipt_description(self) -> str:
return self.product
def __eq__(self, other) -> bool:
if not isinstance(other, Consumption):
return False
return super().__eq__(other) and \
self.product == other.product
def __hash__(self) -> int:
return hash((super().__hash__(), self.product))
class Deposit(Transaction):
"""
Representation of a deposit involving an user and an amount of money.
:param _id: The transaction ID in the database.
:param user: The user affected by this transaction.
:param value: The amount of money that was deposited on the account.
:param old_balance: The balance on the user's account before this transaction.
:param date: The date of this transaction.
"""
def __init__(self, _id: int, user: User, value: int, old_balance: int, date: datetime) -> None:
super().__init__(_id, user, value, old_balance, date)
@property
def receipt_description(self) -> str:
return 'Deposit'
def __eq__(self, other) -> bool:
if not isinstance(other, Deposit):
return False
return super().__eq__(other)
def __hash__(self) -> int:
return super().__hash__()
class Modification(Transaction):
"""
Representation of a administrative account balance modification. Involves the affected user, the agent that
performed the modification and optionally a message for the reason of the modification.
:param _id: The transaction ID in the database.
:param user: The user affected by this transaction.
:param value: The amount of money that was deposited on the account.
:param old_balance: The balance on the user's account before this transaction.
:param date: The date of this transaction.
:param agent: The username of the agent performing the modification.
:param reason: The reason for this modification, as provided by the agent.
"""
def __init__(self,
_id: int,
user: User,
value: int,
old_balance: int,
date: datetime,
agent: str,
reason: Optional[str]) -> None:
super().__init__(_id, user, value, old_balance, date)
self.agent: str = agent
self.reason: Optional[str] = reason
@property
def receipt_description(self) -> str:
return f'Balance modified by {self.agent}'
@property
def receipt_message(self) -> Optional[str]:
if self.reason is None:
return None
else:
return f'Reason: «{self.reason}»'
def __eq__(self, other) -> bool:
if not isinstance(other, Modification):
return False
return super().__eq__(other) and \
self.agent == other.agent and \
self.reason == other.reason
def __hash__(self) -> int:
return hash((super().__hash__(), self.agent, self.reason))