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}')