add AccountingService
This commit is contained in:
parent
8b87d78d5d
commit
02134f61f5
@ -3,12 +3,14 @@ from datetime import datetime
|
||||
|
||||
from from_root import from_root
|
||||
|
||||
from src.ez_lan_manager.services.AccountingService import AccountingService
|
||||
from src.ez_lan_manager.services.ConfigurationService import ConfigurationService
|
||||
from src.ez_lan_manager.services.DatabaseService import DatabaseService
|
||||
|
||||
from random import randint
|
||||
|
||||
from src.ez_lan_manager.services.UserService import UserService
|
||||
from src.ez_lan_manager.types.Transaction import Transaction
|
||||
from src.ez_lan_manager.types.User import User
|
||||
|
||||
logger = logging.getLogger(__name__.split(".")[-1])
|
||||
@ -19,7 +21,16 @@ if __name__ == "__main__":
|
||||
db_config = configuration_service.get_database_configuration()
|
||||
db_service = DatabaseService(db_config)
|
||||
user_service = UserService(db_service)
|
||||
user_service.create_user("Mamfred", "Peter@peterson.com", "MamaHalloDoo")
|
||||
accounting_service = AccountingService(db_service, user_service)
|
||||
#user_service.create_user("Mamfred", "Peter@peterson.com", "MamaHalloDoo")
|
||||
# db_service.add_transaction(Transaction(
|
||||
# user_id=19,
|
||||
# value=50,
|
||||
# is_debit=True,
|
||||
# reference="Ein teures Bier",
|
||||
# transaction_date=datetime.now()
|
||||
# ))
|
||||
#print(accounting_service.remove_balance(19, 150, "EinsFuffzig"))
|
||||
# print(db_service.create_user(f"TestUser{randint(0, 9999)}", f"TestMail{randint(0, 9999)}", "pw123"))
|
||||
# print(db_service.update_user(
|
||||
# User(user_id=19, user_name='TestUser838', user_mail='TestMail3142', user_password='pw123', user_first_name=None, user_last_name=None,
|
||||
|
||||
72
src/ez_lan_manager/services/AccountingService.py
Normal file
72
src/ez_lan_manager/services/AccountingService.py
Normal file
@ -0,0 +1,72 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from src.ez_lan_manager.services.DatabaseService import DatabaseService
|
||||
from src.ez_lan_manager.services.UserService import UserService
|
||||
from src.ez_lan_manager.types.Transaction import Transaction
|
||||
|
||||
logger = logging.getLogger(__name__.split(".")[-1])
|
||||
|
||||
class InsufficientFundsError(Exception):
|
||||
pass
|
||||
|
||||
class AccountingService:
|
||||
def __init__(self, db_service: DatabaseService, user_service: UserService) -> None:
|
||||
self._db_service = db_service
|
||||
self._user_service = user_service
|
||||
|
||||
def add_balance(self, user_id: int, balance_to_add: int, reference: str) -> int:
|
||||
self._db_service.add_transaction(Transaction(
|
||||
user_id=user_id,
|
||||
value=balance_to_add,
|
||||
is_debit=False,
|
||||
reference=reference,
|
||||
transaction_date=datetime.now()
|
||||
))
|
||||
logger.debug(f"Added balance of {self.make_euro_string_from_int(balance_to_add)} to user with ID {user_id}")
|
||||
return self.get_balance(user_id)
|
||||
|
||||
def remove_balance(self, user_id: int, balance_to_remove: int, reference: str) -> int:
|
||||
current_balance = self.get_balance(user_id)
|
||||
if (current_balance - balance_to_remove) < 0:
|
||||
raise InsufficientFundsError
|
||||
self._db_service.add_transaction(Transaction(
|
||||
user_id=user_id,
|
||||
value=balance_to_remove,
|
||||
is_debit=True,
|
||||
reference=reference,
|
||||
transaction_date=datetime.now()
|
||||
))
|
||||
logger.debug(f"Removed balance of {self.make_euro_string_from_int(balance_to_remove)} to user with ID {user_id}")
|
||||
return self.get_balance(user_id)
|
||||
|
||||
def get_balance(self, user_id: int) -> int:
|
||||
balance_buffer = 0
|
||||
for transaction in self._db_service.get_all_transactions_for_user(user_id):
|
||||
if transaction.is_debit:
|
||||
balance_buffer -= transaction.value
|
||||
else:
|
||||
balance_buffer += transaction.value
|
||||
return balance_buffer
|
||||
|
||||
@staticmethod
|
||||
def make_euro_string_from_int(cent_int: int) -> str:
|
||||
""" Internally, all money values are cents as ints. Only when showing them to the user we generate a string. Prevents float inaccuracy. """
|
||||
as_str = str(cent_int)
|
||||
if as_str[0] == "-":
|
||||
is_negative = True
|
||||
as_str = as_str[1:]
|
||||
else:
|
||||
is_negative = False
|
||||
|
||||
if len(as_str) == 1:
|
||||
result = f"0.0{as_str} €"
|
||||
elif len(as_str) == 2:
|
||||
result = f"0.{as_str} €"
|
||||
else:
|
||||
result = f"{as_str[:-2]}.{as_str[-2:]} €"
|
||||
|
||||
if is_negative:
|
||||
result = f"-{result}"
|
||||
|
||||
return result
|
||||
@ -6,6 +6,7 @@ import mariadb
|
||||
from mariadb import Cursor
|
||||
|
||||
from src.ez_lan_manager.types.ConfigurationTypes import DatabaseConfiguration
|
||||
from src.ez_lan_manager.types.Transaction import Transaction
|
||||
from src.ez_lan_manager.types.User import User
|
||||
|
||||
logger = logging.getLogger(__name__.split(".")[-1])
|
||||
@ -49,8 +50,7 @@ class DatabaseService:
|
||||
is_team_member=bool(data[8]),
|
||||
is_admin=bool(data[9]),
|
||||
created_at=data[10],
|
||||
last_updated_at=data[11],
|
||||
balance=int(data[12])
|
||||
last_updated_at=data[11]
|
||||
)
|
||||
|
||||
def get_user_by_name(self, user_name: str) -> Optional[User]:
|
||||
@ -96,13 +96,49 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute(
|
||||
"UPDATE users SET user_name=?, user_mail=?, user_password=?, user_first_name=?, user_last_name=?, user_birth_date=?, "
|
||||
"is_active=?, is_team_member=?, is_admin=?, balance=? WHERE (user_id=?)", (user.user_name, user.user_mail.lower(), user.user_password,
|
||||
"is_active=?, is_team_member=?, is_admin=? WHERE (user_id=?)", (user.user_name, user.user_mail.lower(), user.user_password,
|
||||
user.user_first_name, user.user_last_name, user.user_birth_day,
|
||||
user.is_active, user.is_team_member, user.is_admin,
|
||||
user.balance, user.user_id)
|
||||
user.user_id)
|
||||
)
|
||||
self._connection.commit()
|
||||
except mariadb.IntegrityError as e:
|
||||
logger.warning(f"Aborted duplication entry: {e}")
|
||||
raise DuplicationError
|
||||
return user
|
||||
|
||||
def add_transaction(self, transaction: Transaction) -> Optional[Transaction]:
|
||||
cursor = self._get_cursor()
|
||||
try:
|
||||
cursor.execute(
|
||||
"INSERT INTO transactions (user_id, value, is_debit, transaction_date, transaction_reference) "
|
||||
"VALUES (?, ?, ?, ?, ?)",
|
||||
(transaction.user_id, transaction.value, transaction.is_debit, transaction.transaction_date, transaction.reference)
|
||||
)
|
||||
self._connection.commit()
|
||||
except Exception as e:
|
||||
logger.warning(f"Error adding Transaction: {e}")
|
||||
return
|
||||
|
||||
return transaction
|
||||
|
||||
def get_all_transactions_for_user(self, user_id: int) -> list[Transaction]:
|
||||
transactions = []
|
||||
|
||||
cursor = self._get_cursor()
|
||||
try:
|
||||
cursor.execute("SELECT * FROM transactions WHERE user_id=?", (user_id,))
|
||||
result = cursor.fetchall()
|
||||
except mariadb.Error as e:
|
||||
logger.error(f"Error getting all transactions for user: {e}")
|
||||
return []
|
||||
|
||||
for transaction_raw in result:
|
||||
transactions.append(Transaction(
|
||||
user_id=user_id,
|
||||
value=int(transaction_raw[2]),
|
||||
is_debit=bool(transaction_raw[3]),
|
||||
transaction_date=transaction_raw[4],
|
||||
reference=transaction_raw[5]
|
||||
))
|
||||
return transactions
|
||||
|
||||
11
src/ez_lan_manager/types/Transaction.py
Normal file
11
src/ez_lan_manager/types/Transaction.py
Normal file
@ -0,0 +1,11 @@
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Transaction:
|
||||
user_id: int
|
||||
value: int
|
||||
is_debit: bool
|
||||
reference: str
|
||||
transaction_date: datetime
|
||||
@ -17,4 +17,3 @@ class User:
|
||||
is_admin: bool
|
||||
created_at: datetime
|
||||
last_updated_at: datetime
|
||||
balance: int
|
||||
|
||||
Loading…
Reference in New Issue
Block a user