""" Thanks Service — система благодарностей пользователей """ import logging from datetime import datetime from typing import Dict, List, Optional from sqlalchemy import select, func from sqlalchemy.ext.asyncio import AsyncSession logger = logging.getLogger(__name__) class ThanksService: """Сервис благодарностей""" def __init__(self, session: AsyncSession): self.session = session async def give_thank(self, from_user_id: int, to_user_id: int, message: str = None) -> bool: """ Отправить благодарность Returns: True если успешно """ from database.models import Thank # Нельзя поблагодарить самого себя if from_user_id == to_user_id: return False # Создаём благодарность thank = Thank( from_user_id=from_user_id, to_user_id=to_user_id, message=message ) self.session.add(thank) await self.session.commit() logger.info(f"Благодарность от {from_user_id} к {to_user_id}") return True async def get_user_thanks(self, user_id: int) -> Dict: """ Получить статистику благодарностей пользователя Returns: dict со статистикой """ from database.models import Thank # Полученные благодарности stmt_received = ( select(func.count(Thank.id)) .where(Thank.to_user_id == user_id) ) result = await self.session.execute(stmt_received) received_count = result.scalar() or 0 # Отправленные благодарности stmt_given = ( select(func.count(Thank.id)) .where(Thank.from_user_id == user_id) ) result = await self.session.execute(stmt_given) given_count = result.scalar() or 0 # Последние полученные stmt_last = ( select(Thank) .where(Thank.to_user_id == user_id) .order_by(Thank.created_at.desc()) .limit(5) ) result = await self.session.execute(stmt_last) last_received = list(result.scalars().all()) return { 'received': received_count, 'given': given_count, 'last_received': [ { 'from': t.from_user_id, 'message': t.message, 'created_at': t.created_at.isoformat() } for t in last_received ] } async def get_leaderboard(self, limit: int = 10) -> List[Dict]: """ Получить топ пользователей по благодарностям Returns: список пользователей с количеством благодарностей """ from database.models import Thank, User stmt = ( select( User.user_id, User.full_name, User.apartment, func.count(Thank.id).label('thanks_count') ) .join(Thank, User.user_id == Thank.to_user_id, isouter=True) .group_by(User.user_id) .order_by(func.count(Thank.id).desc()) .limit(limit) ) result = await self.session.execute(stmt) rows = list(result.all()) return [ { 'user_id': row.user_id, 'name': row.full_name or f'user{row.user_id}', 'apartment': row.apartment or '?', 'thanks': row.thanks_count } for row in rows ] async def get_thanks_history(self, user_id: int, limit: int = 20) -> List[Dict]: """ Получить историю благодарностей пользователя Returns: список благодарностей """ from database.models import Thank stmt = ( select(Thank) .where((Thank.from_user_id == user_id) | (Thank.to_user_id == user_id)) .order_by(Thank.created_at.desc()) .limit(limit) ) result = await self.session.execute(stmt) thanks = list(result.scalars().all()) return [ { 'from': t.from_user_id, 'to': t.to_user_id, 'message': t.message, 'created_at': t.created_at.isoformat(), 'is_received': t.to_user_id == user_id } for t in thanks ] async def has_thanked_today(self, from_user_id: int, to_user_id: int) -> bool: """ Проверить, благодарил ли уже пользователь сегодня Returns: True если уже благодарил """ from database.models import Thank from datetime import timedelta today = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) stmt = ( select(func.count(Thank.id)) .where(Thank.from_user_id == from_user_id) .where(Thank.to_user_id == to_user_id) .where(Thank.created_at >= today) ) result = await self.session.execute(stmt) count = result.scalar() or 0 return count > 0