import datetime import logging from aiogram.fsm.state import StatesGroup, State from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, FSInputFile from aiogram.utils.keyboard import InlineKeyboardBuilder from config import FILES_PATH, ROLE_MODERATOR_ID, ROLE_CURATOR_ID from core import bot from utils.bitrix import notify from utils.db import get_data, query class ModerationState(StatesGroup): confirm = State() confirm_confirm = State() revision = State() grade = State() reject = State() check_revision_comment = State() check_reject_comment = State() date = State() new_idea_text = """ {name}, пожалуйста, ознакомьтесь с новой НеоИдеей. """ new_idea_data_text = """ Автор: {author_name} Дата: {creation_date} Подразделение: {department} Категория: {category} Город: {city} Название: «{idea_name}» Содержание: {idea_content} """ choose_action_text = """ Пожалуйста, выберите одно из следующих действий: """ confirm_action_text = """ Вы согласовываете НеоИдею: «{idea_name}». Автор: {author_name} """ choose_responsible_text = """ Пожалуйста, выберите Ответственного за категорию для передачи НеоИдеи в работу. """ send_date_text = """ В календаре укажите крайние сроки выполнения: """ confirm_responsible_date_text = """ Вы передаёте НеоИдею в работу. Название: «{idea_name}». Автор: {author_name} Ответственный за категорию: {responsible_name} Крайние сроки выполнения: {date} """ confirm_action_send_text = """ Спасибо! Вы передали НеоИдею в работу. """ revision_action_text = """ Вы возвращаете на доработку НеоИдею: «{idea_name}». Автор: {author_name} Оставьте комментарий для того, чтобы отправить НеоИдею на доработку. """ send_revision_comment_text = """ Оставьте комментарий для того, чтобы отправить НеоИдею на доработку """ send_comment_text = """ Пожалуйста, оставьте свой комментарий: """ check_comment = """ Проверьте правильность введенных данных: {comment} """ revision_action_send_text = """ Вы отправили НеоИдею на доработку. """ grade_action_text = """ Вы направляете НеоИдею на оценку: «{idea_name}». Автор: {author_name} НеоИдея будет передана Куратору. """ grade_action_send_text = """ Спасибо! НеоИдея передана Куратору. """ reject_action_text = """ Вы отклоняете НеоИдею: «{idea_name}». Автор: {author_name} Пожалуйста, оставьте свой комментарий. """ reject_action_send_text = """ Спасибо! НеоИдея отклонена. """ you_rejected = """ Здравствуйте, {name}. Ваша НеоИдея "{idea_name}" была отклонена с комментарием: "{comment}" """ you_revision = """ Ваша НеоИдея возвращена на доработку, пожалуйста проработайте комментарии от генерального директора и отправьте заявку заново. НеоИдея: "{idea_name}" Комментарий: "{comment}" """ accept_notify_author_text = """ Поздравляем! Ваша НеоИдея передана к внедрению """ accept_notify_curator_text = """ Быстрая НеоИдея автора {author_name} передана к внедрению {responsible_name} """ grade_curator_text = """ Вам на оценку передана НеоИдея "{idea_name}". """ confirm_notify_curator_text = """ Быстрая НеоИдея автора {author_name} передана к ответственному за категорию {responsible_name} """ confirm_notify_author_text = """ Ваша НеоИдея передана ответственному за категорию """ def confirm_action_ikb() -> InlineKeyboardMarkup: """ -Да, продолжить ✅ -Нет, вернуться назад ❌ :return: объект клавиатуры для параметра reply_markup """ builder = InlineKeyboardBuilder() builder.add( InlineKeyboardButton( text='Да, продолжить ✅', callback_data='confirm_action_confirm' ), InlineKeyboardButton( text='Нет, вернуться назад ❌', callback_data='confirm_action_reject' ) ) builder.adjust(1) return builder.as_markup() def choose_action_ikb(idea_id: str | int, msg_id: str | int) -> InlineKeyboardMarkup: """ -Согласовать и передать в работу -Вернуть Автору на доработку -Направить на оценку -Отклонить :param idea_id: ID идеи :param msg_id: ID сообщения с клавиатурой :return: объект клавиатуры для параметра reply_markup """ builder = InlineKeyboardBuilder() builder.add( InlineKeyboardButton( text='Согласовать и передать в работу', callback_data=f'moderation_confirm_{idea_id}_{msg_id}' ), InlineKeyboardButton( text='Вернуть Автору на доработку', callback_data=f'moderation_revision_{idea_id}_{msg_id}' ), InlineKeyboardButton( text='Направить на оценку', callback_data=f'moderation_grade_{idea_id}_{msg_id}' ), InlineKeyboardButton( text='Отклонить', callback_data=f'moderation_reject_{idea_id}_{msg_id}' ) ) builder.adjust(1) return builder.as_markup() async def choose_responsible_ikb(category_id: int) -> InlineKeyboardMarkup: """ -Ответственный 1 -Ответственный 2 :param category_id: ID категории идеи :return: объект клавиатуры для параметра reply_markup """ builder = InlineKeyboardBuilder() responsible_list = await get_data( table_name='user_to_categories', query_filter={'category_id': category_id} ) for responsible in responsible_list: responsible_data = await get_data( table_name='users', query_filter={'id': responsible['user_id']} ) builder.add( InlineKeyboardButton( text=responsible_data[0]['full_name'], callback_data=f'choose_responsible_{responsible_data[0]["id"]}', ) ) builder.adjust(1) return builder.as_markup() async def send_new_idea_on_moderation( idea_id: int, user_name: str, department: str, idea_title: str, idea_content: str, relation_id: int, city_id: int, category_id: int, creation_date: datetime.datetime): """ Присылает новую идею модераторам из списка :param idea_id: Данные идеи :param user_name: Имя пользователя :param department: Отдел пользователя :param idea_title: Название идеи :param idea_content: Описание идеи :param relation_id: id отношения к идее :param city_id: id города, где работает пользователь :param category_id: id категории :param creation_date: Дата создания идеи :return: """ moderators = await get_data( table_name='user_to_roles', query_filter={'role_id': ROLE_MODERATOR_ID} ) city = await get_data( table_name='cities', query_filter={'id': city_id} ) files = await get_data( table_name='idea_to_files', query_filter={'idea_id': idea_id} ) category = await get_data( table_name='categories', query_filter={'id': category_id} ) notify_text = new_idea_data_text.format( author_name=user_name, creation_date=creation_date, department=department, idea_name=idea_title, idea_content=idea_content, city=city[0]['name'], category=category[0]['name'] ) for moderator_id in moderators: try: moderator = await get_data( table_name='users', query_filter={'id': moderator_id['user_id']} ) formatted_new_idea_text = new_idea_text.format( name=moderator[0]['full_name'], ) await bot.send_message( chat_id=moderator[0]['telegram_id'], text=formatted_new_idea_text ) await bot.send_message( chat_id=moderator[0]['telegram_id'], text=notify_text ) for file in files: file_data = await get_data( table_name='files', query_filter={'id': file['file_id']} ) await bot.send_document( chat_id=moderator[0]['telegram_id'], document=FSInputFile(FILES_PATH + file_data[0]['file']) ) last_msg = await bot.send_message( chat_id=moderator[0]['telegram_id'], text=choose_action_text, reply_markup=choose_action_ikb( idea_id=idea_id, msg_id=0 ) ) await bot.edit_message_reply_markup( message_id=last_msg.message_id, chat_id=moderator[0]['telegram_id'], reply_markup=choose_action_ikb( idea_id=idea_id, msg_id=last_msg.message_id ) ) moderator_user_data = await get_data( table_name='users', query_filter={'id': moderator_id['user_id']} ) await notify( user_id=moderator_user_data[0]['external_id'], message='Новая быстрая НеоИдея!' ) except Exception as e: logging.error(e) curators = await get_data( table_name='user_to_roles', query_filter={'role_id': ROLE_CURATOR_ID} ) for curator in curators: try: user_data = await get_data( table_name='users', query_filter={'id': curator['user_id']} ) await notify( user_id=user_data[0]['external_id'], message='Новая быстрая НеоИдея!' ) except Exception as e: logging.error(f'не могу отправить уведомление куратору о новой идее {e}') async def accept_notify(author_name: str, responsible_id: str, author_id: int) -> None: """ Уведомляет куратора и автора о принятии идеи :param responsible_id: ID кому передают идею :param author_name: Имя автора идеи :param author_id: ID автора :return: """ responsible_data = await get_data( table_name='users', query_filter={'id': responsible_id} ) notify_text = notify_curator_text.format( author_name=author_name, responsible_name=responsible_data[0]['full_name'] ) curators = await get_data( table_name='user_to_roles', query_filter={'role_id': ROLE_CURATOR_ID} ) for curator in curators: try: user_data = await get_data( table_name='users', query_filter={'id': curator['user_id']} ) await notify( user_id=user_data[0]['external_id'], message=notify_text ) await bot.send_message( chat_id=user_data[0]['telegram_id'], text=notify_text ) except Exception as e: logging.error(f'не могу отправить уведомление куратору о принятии идеи {e}') try: author_data = await get_data( table_name='users', query_filter={'id': author_id} ) await notify( user_id=author_data[0]['external_id'], message=notify_author_text ) await bot.send_message( chat_id=author_data[0]['telegram_id'], text=notify_author_text ) except Exception as e: logging.error(f'Не смог отправить уведомление автору идеи {e}') async def confirm_notify(author_name: str, responsible_id: str, author_id: int) -> None: """ Уведомляет куратора и автора о согласовании идеи :param responsible_id: ID кому передают идею :param author_name: Имя автора идеи :param author_id: ID автора :return: """ responsible_data = await get_data( table_name='users', query_filter={'id': responsible_id} ) notify_text = confirm_notify_curator_text.format( author_name=author_name, responsible_name=responsible_data[0]['full_name'] ) curators = await get_data( table_name='user_to_roles', query_filter={'role_id': ROLE_CURATOR_ID} ) for curator in curators: try: user_data = await get_data( table_name='users', query_filter={'id': curator['user_id']} ) await notify( user_id=user_data[0]['external_id'], message=notify_text ) await bot.send_message( chat_id=user_data[0]['telegram_id'], text=notify_text ) except Exception as e: logging.error(f'не могу отправить уведомление куратору о принятии идеи {e}') try: author_data = await get_data( table_name='users', query_filter={'id': author_id} ) await notify( user_id=author_data[0]['external_id'], message=notify_author_text ) await bot.send_message( chat_id=author_data[0]['telegram_id'], text=notify_author_text ) except Exception as e: logging.error(f'Не смог отправить уведомление автору идеи {e}')