diff --git a/src/dutylog/application/bot/user_dialogs/user_menu/main_menu.py b/src/dutylog/application/bot/user_dialogs/user_menu/main_menu.py index b4c60ee..9f6cf6a 100644 --- a/src/dutylog/application/bot/user_dialogs/user_menu/main_menu.py +++ b/src/dutylog/application/bot/user_dialogs/user_menu/main_menu.py @@ -69,11 +69,42 @@ async def get_main_menu_data( room = await rooms_repository.get_room_by_id(resident.room) room_number = room.number if room else "???" - room_residents = await residents_repository.get_residents_by_room(resident.room) - room_active = sum(r.active_hours for r in room_residents) - room_inactive = sum(r.inactive_hours for r in room_residents) + all_residents = await residents_repository.get_all_residents() + residents_with_hours = [ + r for r in all_residents + if (r.inactive_hours + r.active_hours) > 0 + ] - content = f"{greeting}\n\n📊 Статус отработки:\n\n👤 Ваши часы:\n
✅ Выполнено: {resident.inactive_hours} ч.\n⏳ Осталось: {resident.active_hours} ч.\n\n🚪 Часы комнаты:\n
✅ Выполнено: {room_inactive} ч.\n⏳ Осталось: {room_active} ч.\n\n
made by kolo"
+ sorted_residents = sorted(
+ residents_with_hours,
+ key=lambda r: r.inactive_hours + r.active_hours,
+ reverse=True
+ )
+
+ user_total_hours = resident.inactive_hours + resident.active_hours
+ user_position = next(
+ (i + 1 for i, r in enumerate(sorted_residents) if r.id == resident.id),
+ len(sorted_residents)
+ )
+
+ if residents_with_hours:
+ avg_hours = sum(r.inactive_hours + r.active_hours for r in residents_with_hours) / len(residents_with_hours)
+ if avg_hours > 0:
+ diff_percent = ((user_total_hours - avg_hours) / avg_hours) * 100
+ if diff_percent > 0:
+ comparison = f"📈 На {diff_percent:.1f}% выше среднего"
+ elif diff_percent < 0:
+ comparison = f"📉 На {abs(diff_percent):.1f}% ниже среднего"
+ else:
+ comparison = "📊 Средний показатель"
+ else:
+ comparison = ""
+ else:
+ comparison = ""
+
+ position_emoji = "🥇" if user_position == 1 else "🥈" if user_position == 2 else "🥉" if user_position == 3 else "📍"
+
+ content = f"{greeting}\n\n📊 Статус отработки:\n\n✅ Выполнено: {resident.inactive_hours} ч\n⏳ Осталось: {resident.active_hours} ч\n\n{position_emoji} Место в рейтинге:
{user_position} из {len(sorted_residents)}\n{comparison}\n\nmade by kolo"
has_resident = True
else:
content = f"{greeting}\n\n📋 Панель управления\n\nДобро пожаловать в систему учета дежурств!" diff --git a/src/dutylog/infrastructure/database/repositories/hours_transactions_repository.py b/src/dutylog/infrastructure/database/repositories/hours_transactions_repository.py index e9ed92b..10664eb 100644 --- a/src/dutylog/infrastructure/database/repositories/hours_transactions_repository.py +++ b/src/dutylog/infrastructure/database/repositories/hours_transactions_repository.py @@ -2,6 +2,7 @@ from dutylog.infrastructure.database.dao.hours_transactions_dao import ( HoursTransactionsDAO, ) from dutylog.infrastructure.database.dao.residents_dao import ResidentsDAO +from dutylog.infrastructure.database.dao.users_dao import UsersDAO from dutylog.infrastructure.database.models.hours_transaction import ( HoursTransaction, TransactionType, @@ -14,9 +15,11 @@ class HoursTransactionsRepository: self, transactions_dao: HoursTransactionsDAO, residents_dao: ResidentsDAO, + users_dao: UsersDAO, ): self.transactions_dao = transactions_dao self.residents_dao = residents_dao + self.users_dao = users_dao async def add_hours( self, @@ -143,6 +146,11 @@ class HoursTransactionsRepository: results = [] for resident in residents: + if resident.is_busy and resident.user_entity: + user = await self.users_dao.get_by_id(resident.user_entity) + if user and user.is_admin: + continue + result = await self.add_hours( resident_id=resident.id, amount=amount, diff --git a/src/dutylog/infrastructure/ioc.py b/src/dutylog/infrastructure/ioc.py index 902d888..8c6661f 100644 --- a/src/dutylog/infrastructure/ioc.py +++ b/src/dutylog/infrastructure/ioc.py @@ -97,8 +97,9 @@ class RepositoryProvider(Provider): self, transactions_dao: HoursTransactionsDAO, residents_dao: ResidentsDAO, + users_dao: UsersDAO, ) -> HoursTransactionsRepository: - return HoursTransactionsRepository(transactions_dao, residents_dao) + return HoursTransactionsRepository(transactions_dao, residents_dao, users_dao) @provide(scope=Scope.REQUEST) def get_rooms_repository(self, rooms_dao: RoomsDAO) -> RoomsRepository: