Игорь Надеин 6fb2cdcea0 feat: enhance Employee model and integrate Telegram/WhatsApp bot
- Add birth_date, created_at/updated_at to Employee; remove username field
- Introduce EmployeeAction for tracking HR events and is_actually_active/status properties
- Create BotSubscriber model (OneToOne relation) for TG/WA binding
- Implement Aiogram-based Telegram bot:
  • request contact to bind by phone or @username
  • department selection keyboard from DEPARTMENTS dict
  • async ORM via sync_to_async, custom filters for bound & active employees
- Update profile view & template:
  • show “Bind Telegram/WhatsApp” button only when not already bound
  • preview avatar on upload
- Remove registration tokens in favor of contact-based auth
- Clean up templates, forms and add avatar validation mixin
2025-07-30 08:15:53 +03:00

178 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# # import os
# # from dotenv import load_dotenv
# # from asgiref.sync import async_to_sync
# # from aiogram import Bot
# # from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
# # from .models import Document
# # from django.contrib.auth import get_user_model
# # from bots.models import BotSubscriber
# # import logging
# # logger = logging.getLogger(__name__)
# # load_dotenv()
# # BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
# # User = get_user_model()
# # telegram_bot = Bot(token=BOT_TOKEN)
# # def send_document_to_recipients(document_id: int):
# # """
# # Уведомляем в Telegram о появлении нового документа:
# # — всем активным, если sent_to_all=True,
# # — или тем, кто в recipients.
# # """
# # try:
# # doc = Document.objects.get(pk=document_id)
# # except Document.DoesNotExist:
# # return
# # # собираем подписчиков
# # if doc.sent_to_all:
# # subs = BotSubscriber.objects.filter(
# # telegram_id__isnull=False,
# # user__is_active=True
# # )
# # else:
# # subs = BotSubscriber.objects.filter(
# # telegram_id__isnull=False,
# # user__in=doc.recipients.filter(is_active=True)
# # )
# # if not subs.exists():
# # return
# # # клавиатура: ведёт пользователя в бот, в раздел «Документы»
# # kb = InlineKeyboardMarkup(inline_keyboard=[[
# # InlineKeyboardButton(text="📄 Открыть документы",
# # callback_data="menu_docs")
# # ]])
# # text = (
# # f"🆕 *Новый документ*: {doc.title}\n\n"
# # f"{doc.description or ''}\n\n"
# # f"Зайдите в раздел «Документы» в боте, чтобы скачать файл."
# # )
# # # шлём всем подписчикам
# # for sub in subs:
# # try:
# # async_to_sync(telegram_bot.send_message)(
# # chat_id=sub.telegram_id,
# # text=text,
# # parse_mode="Markdown",
# # disable_web_page_preview=True,
# # reply_markup=kb,
# # )
# # except Exception as e:
# # # Записываем в лог, на каком именно подписчике и с каким текстом упало
# # logger.error(
# # f"[Telegram] Ошибка при отправке документу={doc.pk} "
# # f"пользователю={sub.user.pk} tg_id={sub.telegram_id}: {e}",
# # exc_info=True
# # )
# # else:
# # logger.info(
# # f"[Telegram] Уведомление по документу={doc.pk} "
# # f"успешно отправлено пользователю={sub.user.pk}"
# # )
# # documents/tasks.py
# import os
# from dotenv import load_dotenv
# from celery import shared_task
# from django.conf import settings
# from django.urls import reverse
# from django.utils import timezone
# from telegram import Bot as TgBot, InlineKeyboardButton, InlineKeyboardMarkup
# from .models import Document
# from django.contrib.auth import get_user_model
# from bots.models import BotSubscriber
# import logging
# logger = logging.getLogger(__name__)
# load_dotenv()
# TG_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN') or settings.TELEGRAM_BOT_TOKEN
# User = get_user_model()
# # @shared_task(bind=True, name="documents.send_document_to_recipients")
# def send_document_to_recipients(document_id):
# try:
# doc = Document.objects.get(pk=document_id)
# except Document.DoesNotExist:
# return
# # Собираем подписчиков
# if doc.sent_to_all:
# subs = BotSubscriber.objects.filter(
# telegram_id__isnull=False,
# user__is_active=True,
# )
# else:
# subs = BotSubscriber.objects.filter(
# telegram_id__isnull=False,
# user__in=doc.recipients.filter(is_active=True),
# )
# if not subs.exists():
# return
# # Синхронный телеграм-бот
# bot = TgBot(token=TG_TOKEN)
# # Кнопка «Открыть документы»
# kb = InlineKeyboardMarkup(
# [[ InlineKeyboardButton("📄 Открыть документы", callback_data="menu_docs") ]]
# )
# # Текст уведомления
# text = (
# f"🆕 *Новый документ*: {doc.title}\n\n"
# f"{doc.description or ''}\n\n"
# f"Дата публикации: {doc.uploaded_at.strftime('%d.%m.%Y %H:%M')}"
# )
# # for sub in subs:
# # try:
# # bot.send_message(
# # chat_id=sub.telegram_id,
# # text=text,
# # parse_mode="Markdown",
# # reply_markup=kb,
# # disable_web_page_preview=True
# # )
# # except Exception as e:
# # print(e)
# # логируем, чтобы понимать, кому не дошло
# # self.retry(exc=e, countdown=60, max_retries=3)
# for sub in subs:
# try:
# bot.send_message(
# chat_id=sub.telegram_id,
# text=text,
# parse_mode="Markdown",
# disable_web_page_preview=True,
# reply_markup=kb,
# )
# except Exception as e:
# # Записываем в лог, на каком именно подписчике и с каким текстом упало
# logger.error(
# f"[Telegram] Ошибка при отправке документу={doc.pk} "
# f"пользователю={sub.user.pk} tg_id={sub.telegram_id}: {e}",
# exc_info=True
# )
# else:
# logger.info(
# f"[Telegram] Уведомление по документу={doc.pk} "
# f"успешно отправлено пользователю={sub.user.pk}"
# )