From 7385fb09c0e29c637d66d88f0bfd4eb002430ba0 Mon Sep 17 00:00:00 2001 From: kolo Date: Fri, 27 Feb 2026 17:30:40 +0300 Subject: [PATCH] update --- src/dutylog/application/__main__.py | 3 +- .../database/repositories/__init__.py | 0 .../hours_transactions_repository.py | 75 +++++++++++++++++++ .../database/repositories/users_repository.py | 66 ++++++++++++++++ src/dutylog/infrastructure/ioc.py | 17 +++++ 5 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/dutylog/infrastructure/database/repositories/__init__.py create mode 100644 src/dutylog/infrastructure/database/repositories/hours_transactions_repository.py create mode 100644 src/dutylog/infrastructure/database/repositories/users_repository.py diff --git a/src/dutylog/application/__main__.py b/src/dutylog/application/__main__.py index 7039801..c767aaf 100644 --- a/src/dutylog/application/__main__.py +++ b/src/dutylog/application/__main__.py @@ -10,7 +10,7 @@ from dishka.integrations.aiogram import setup_dishka from dutylog.application.bot.user_handlers import router as user_router from dutylog.application.bot.user_dialogs import main_menu_dialog -from dutylog.infrastructure.ioc import ConfigProvider, DatabaseProvider, DAOProvider +from dutylog.infrastructure.ioc import ConfigProvider, DatabaseProvider, DAOProvider, RepositoryProvider from dutylog.infrastructure.utils.config import load_config @@ -29,6 +29,7 @@ async def main(): ConfigProvider(), DatabaseProvider(), DAOProvider(), + RepositoryProvider(), ) dp.include_router(user_router) diff --git a/src/dutylog/infrastructure/database/repositories/__init__.py b/src/dutylog/infrastructure/database/repositories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/dutylog/infrastructure/database/repositories/hours_transactions_repository.py b/src/dutylog/infrastructure/database/repositories/hours_transactions_repository.py new file mode 100644 index 0000000..79332ed --- /dev/null +++ b/src/dutylog/infrastructure/database/repositories/hours_transactions_repository.py @@ -0,0 +1,75 @@ +from dutylog.infrastructure.database.dao.hours_transactions_dao import HoursTransactionsDAO +from dutylog.infrastructure.database.dao.users_dao import UsersDAO +from dutylog.infrastructure.database.models.hours_transaction import HoursTransaction, TransactionType +from dutylog.infrastructure.database.models.user import User + + +class HoursTransactionsRepository: + def __init__( + self, + transactions_dao: HoursTransactionsDAO, + users_dao: UsersDAO, + ): + self.transactions_dao = transactions_dao + self.users_dao = users_dao + + async def add_hours( + self, + user_id: int, + amount: int, + admin_id: int | None = None, + is_active: bool = True, + ) -> tuple[HoursTransaction, User | None]: + transaction = HoursTransaction( + user_id=user_id, + transaction_type=TransactionType.INCREASE.value, + amount=amount, + admin_id=admin_id, + ) + transaction = await self.transactions_dao.create(transaction) + + user = await self.users_dao.get_by_id(user_id) + if user: + if is_active: + new_hours = user.active_hours + amount + user = await self.users_dao.update(user_id, active_hours=new_hours) + else: + new_hours = user.inactive_hours + amount + user = await self.users_dao.update(user_id, inactive_hours=new_hours) + + return transaction, user + + async def remove_hours( + self, + user_id: int, + amount: int, + admin_id: int | None = None, + is_active: bool = True, + ) -> tuple[HoursTransaction, User | None]: + transaction = HoursTransaction( + user_id=user_id, + transaction_type=TransactionType.DECREASE.value, + amount=amount, + admin_id=admin_id, + ) + transaction = await self.transactions_dao.create(transaction) + + user = await self.users_dao.get_by_id(user_id) + if user: + if is_active: + new_hours = max(0, user.active_hours - amount) + user = await self.users_dao.update(user_id, active_hours=new_hours) + else: + new_hours = max(0, user.inactive_hours - amount) + user = await self.users_dao.update(user_id, inactive_hours=new_hours) + + return transaction, user + + async def get_user_history(self, user_id: int) -> list[HoursTransaction]: + return await self.transactions_dao.get_by_user_id(user_id) + + async def get_all_transactions(self) -> list[HoursTransaction]: + return await self.transactions_dao.get_all() + + async def get_transaction_by_id(self, transaction_id: int) -> HoursTransaction | None: + return await self.transactions_dao.get_by_id(transaction_id) diff --git a/src/dutylog/infrastructure/database/repositories/users_repository.py b/src/dutylog/infrastructure/database/repositories/users_repository.py new file mode 100644 index 0000000..ff5cf6a --- /dev/null +++ b/src/dutylog/infrastructure/database/repositories/users_repository.py @@ -0,0 +1,66 @@ +from dutylog.infrastructure.database.dao.users_dao import UsersDAO +from dutylog.infrastructure.database.models.user import User + + +class UsersRepository: + def __init__(self, users_dao: UsersDAO): + self.users_dao = users_dao + + async def get_or_create_user( + self, + user_id: int, + username: str | None = None, + first_name: str | None = None, + last_name: str | None = None, + ) -> User: + user = await self.users_dao.get_by_id(user_id) + if not user: + user = User( + id=user_id, + username=username, + first_name=first_name, + last_name=last_name, + ) + user = await self.users_dao.create(user) + return user + + async def update_user_info( + self, + user_id: int, + username: str | None = None, + first_name: str | None = None, + last_name: str | None = None, + ) -> User | None: + return await self.users_dao.update( + user_id, + username=username, + first_name=first_name, + last_name=last_name, + ) + + async def set_admin_status(self, user_id: int, is_admin: bool) -> User | None: + return await self.users_dao.update(user_id, is_admin=is_admin) + + async def add_active_hours(self, user_id: int, hours: int) -> User | None: + user = await self.users_dao.get_by_id(user_id) + if user: + new_hours = user.active_hours + hours + return await self.users_dao.update(user_id, active_hours=new_hours) + return None + + async def add_inactive_hours(self, user_id: int, hours: int) -> User | None: + user = await self.users_dao.get_by_id(user_id) + if user: + new_hours = user.inactive_hours + hours + return await self.users_dao.update(user_id, inactive_hours=new_hours) + return None + + async def get_all_admins(self) -> list[User]: + all_users = await self.users_dao.get_all() + return [user for user in all_users if user.is_admin] + + async def get_user_by_id(self, user_id: int) -> User | None: + return await self.users_dao.get_by_id(user_id) + + async def get_all_users(self) -> list[User]: + return await self.users_dao.get_all() diff --git a/src/dutylog/infrastructure/ioc.py b/src/dutylog/infrastructure/ioc.py index 3bde9f7..1c24cb0 100644 --- a/src/dutylog/infrastructure/ioc.py +++ b/src/dutylog/infrastructure/ioc.py @@ -6,6 +6,8 @@ from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker from dutylog.infrastructure.database.config import create_engine, create_session_maker from dutylog.infrastructure.database.dao.users_dao import UsersDAO from dutylog.infrastructure.database.dao.hours_transactions_dao import HoursTransactionsDAO +from dutylog.infrastructure.database.repositories.users_repository import UsersRepository +from dutylog.infrastructure.database.repositories.hours_transactions_repository import HoursTransactionsRepository from dutylog.infrastructure.utils.config import Config, load_config @@ -42,3 +44,18 @@ class DAOProvider(Provider): return HoursTransactionsDAO(session) +class RepositoryProvider(Provider): + @provide(scope=Scope.REQUEST) + def get_users_repository(self, users_dao: UsersDAO) -> UsersRepository: + return UsersRepository(users_dao) + + @provide(scope=Scope.REQUEST) + def get_hours_transactions_repository( + self, + transactions_dao: HoursTransactionsDAO, + users_dao: UsersDAO, + ) -> HoursTransactionsRepository: + return HoursTransactionsRepository(transactions_dao, users_dao) + + +