part of new tg logic

This commit is contained in:
Kseninia Mikhaylova 2024-07-17 16:49:30 +03:00
parent 2ba26c942b
commit 25237f11ed
3 changed files with 178 additions and 98 deletions

View File

@ -1,6 +1,6 @@
from django.contrib import admin from django.contrib import admin
from .models import TgItem, Element from .models import TgItem, TmcElement
# Register your models here. # Register your models here.
admin.site.register(TgItem) admin.site.register(TgItem)
admin.site.register(Element) admin.site.register(TmcElement)

View File

@ -1,7 +1,7 @@
import uuid import uuid
from django.db import models from django.db import models
from tmc.models import CustomTable from tmc.models import CustomTable, BaseCustomField
import logging import logging
@ -15,15 +15,11 @@ def group_based_upload_to(instance, filename):
) )
class Element(models.Model): class TmcElement(models.Model):
tmc = models.ForeignKey(CustomTable, models.RESTRICT) tmc = models.ForeignKey(CustomTable, models.RESTRICT)
name = models.CharField() name = models.CharField(null=True, blank=True)
photoid = models.CharField() element = models.ManyToManyField(BaseCustomField)
# photo = models.ImageField(null=True, upload_to=group_based_upload_to)
text = models.TextField(blank=True, null=True)
def __str__(self):
return f"Element {self.tmc} {self.name}"
class TgItem(models.Model): class TgItem(models.Model):
id = models.UUIDField( id = models.UUIDField(
@ -35,10 +31,9 @@ class TgItem(models.Model):
) )
user_id = models.BigIntegerField() user_id = models.BigIntegerField()
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
# created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
# updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
tmc = models.ManyToManyField(CustomTable) tmc = models.ManyToManyField(TmcElement)
element = models.ManyToManyField(Element)
def __str__(self): def __str__(self):
return f"Tg item {self.id}" return f"Tg item {self.id}"

View File

@ -11,6 +11,8 @@ from telegram import (
ReplyKeyboardMarkup, ReplyKeyboardMarkup,
ReplyKeyboardRemove, ReplyKeyboardRemove,
KeyboardButton, KeyboardButton,
InlineKeyboardMarkup,
InlineKeyboardButton,
) )
from telegram.ext import ( from telegram.ext import (
ApplicationBuilder, ApplicationBuilder,
@ -26,8 +28,8 @@ from telegram.constants import ParseMode
from django.conf import settings from django.conf import settings
from .apps import TgBotUpdater from .apps import TgBotUpdater
from .models import Element, TgItem from .models import TmcElement, TgItem
from tmc.models import CustomTable from tmc.models import CustomTable, BaseCustomField
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -39,7 +41,7 @@ def chunk(n, l):
class TgBot: class TgBot:
_app = None _app = None
def __init__(self) -> None: def __init__(self) -> None:
self.token = settings.TGBOT["TOKEN"] self.token = settings.TGBOT["TOKEN"]
self.baseurl = settings.TGBOT["BASE_URL"] self.baseurl = settings.TGBOT["BASE_URL"]
@ -58,17 +60,24 @@ class TgBot:
async def start_app(self): async def start_app(self):
await TgBot.app.initialize() await TgBot.app.initialize()
async def admin_action(self, name, queryset): async def admin_action(self, name, queryset):
pass pass
async def set_handlers(self): async def set_handlers(self):
TgBot.app.add_handler(CommandHandler("start", self.start, filters.ChatType.PRIVATE)) TgBot.app.add_handler(
CommandHandler("start", self.start, filters.ChatType.PRIVATE)
)
TgBot.app.add_handler(CommandHandler("my", self.my, filters.ChatType.PRIVATE)) TgBot.app.add_handler(CommandHandler("my", self.my, filters.ChatType.PRIVATE))
TgBot.app.add_handler(CommandHandler("inv", self.inv, filters.ChatType.PRIVATE)) TgBot.app.add_handler(CommandHandler("inv", self.inv, filters.ChatType.PRIVATE))
TgBot.app.add_handler(MessageHandler(filters.ChatType.PRIVATE, self.inv)) TgBot.app.add_handler(MessageHandler(filters.ChatType.PRIVATE, self.inv))
TgBot.app.add_handler(CallbackQueryHandler(self.get_inv, r"get_inv@(.*?)"))
TgBot.app.add_handler(CallbackQueryHandler(self.add_tmc, r"add_tmc@(.*?)"))
TgBot.app.add_handler(
CallbackQueryHandler(self.add_element, r"add_element@(.*?)")
)
TgBot.app.add_error_handler(self.error_handler) TgBot.app.add_error_handler(self.error_handler)
async def start(self, update: Update, context: CallbackContext): async def start(self, update: Update, context: CallbackContext):
await update.message.reply_markdown_v2( await update.message.reply_markdown_v2(
( (
@ -87,122 +96,198 @@ class TgBot:
inv = [] inv = []
async for e in TgItem.objects.filter(user_id=user.id): async for e in TgItem.objects.filter(user_id=user.id):
inv.append(e.name) inv.append({"name": e.name, "id": str(e.id)})
keys = chunk(1, inv) keys = chunk(1, inv)
if len(inv) > 0:
await update.message.reply_markdown_v2(
("Ваши инвентаризации"),
reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
i["name"],
callback_data=f'get_inv@{i["id"]}',
)
for i in arr
]
for arr in keys
]
),
reply_parameters=ReplyParameters(message_id=update.message.message_id),
)
else:
await update.message.reply_markdown_v2(
"У вас нет доступных для редактирования инвентаризаций"
)
await update.message.reply_markdown_v2( async def get_inv(self, update: Update, context: CallbackContext):
("Ваши инвентаризации"), query = update.callback_query
reply_markup=ReplyKeyboardMarkup( await update.effective_message.edit_reply_markup(InlineKeyboardMarkup([]))
[[KeyboardButton(i) for i in arr] for arr in keys] await query.answer()
),
reply_parameters=ReplyParameters(message_id=update.message.message_id), inv_id = query.data.split("@")[-1]
) inv = await TgItem.objects.aget(id=inv_id)
if len(inv):
context.chat_data["step"] = "get_inv" context.chat_data["inv"] = inv.id
context.chat_data["step"] = "name"
await self.inv(update, context)
async def add_tmc(self, update: Update, context: CallbackContext):
query = update.callback_query
await update.effective_message.edit_reply_markup(InlineKeyboardMarkup([]))
await query.answer()
tmc_id = query.data.split("@")[-1]
tmc = await CustomTable.objects.aget(id=tmc_id)
inv = await TgItem.objects.aget(id=context.chat_data["inv"])
await inv.tmc.aadd(tmc)
context.chat_data["tmc"] = tmc.id
context.chat_data["step"] = "add_tmc"
await self.inv(update, context)
async def add_element(self, update: Update, context: CallbackContext):
query = update.callback_query
await update.effective_message.edit_reply_markup(InlineKeyboardMarkup([]))
await query.answer()
inv = await TgItem.objects.aget(id=context.chat_data["inv"])
tmc = await CustomTable.objects.aget(id=context.chat_data["tmc"])
field_id = query.data.split("@")[-1]
name = await BaseCustomField.objects.aget(id=field_id)
element = await TmcElement.objects.acreate(name=name, tmc=tmc)
await inv.element.aadd(element)
context.chat_data["element"] = element.id
context.chat_data["step"] = "add_element"
await self.inv(update, context)
async def inv(self, update: Update, context: CallbackContext): async def inv(self, update: Update, context: CallbackContext):
user = update.effective_user user = update.effective_user
current_step = context.chat_data.get("step", None) current_step = context.chat_data.get("step", None)
if not update.message:
return True
logger.info(update.message)
logger.info(f"Step {current_step} from user {user.full_name}")
if current_step == "get_inv": logger.info(
inv = await TgItem.objects.aget(name=update.message.text) f"Step {current_step} from user {user.full_name} in {update.message}"
context.chat_data["inv"] = inv.id )
context.chat_data["step"] = "name"
current_step = context.chat_data["step"]
if not current_step and update.message.text == "/inv": if not current_step and update.message.text == "/inv":
inv = await TgItem.objects.acreate(user_id=user.id) context.chat_data["step"] = "name"
await update.message.reply_markdown_v2( await update.effective_message.reply_markdown_v2(
( (
f"Специалист {user.name or user.full_name}, ID {user.id}\n" f"Специалист {user.name or user.full_name}, ID {user.id}\n"
f"Начинаем инвентаризацию `#{inv.id}`\n"
f"Введите название объекта" f"Введите название объекта"
), ),
reply_parameters=ReplyParameters(message_id=update.message.message_id), reply_parameters=ReplyParameters(
message_id=update.effective_message.message_id
),
) )
context.chat_data["inv"] = inv.id
context.chat_data["step"] = "name"
elif current_step == "name": elif current_step == "name":
inv = await TgItem.objects.aget(id=context.chat_data["inv"]) if not context.chat_data.get("inv", None):
inv.name = update.message.text inv = await TgItem.objects.acreate(user_id=user.id)
await inv.asave() inv.name = update.message.text
await inv.asave()
else:
inv = await TgItem.objects.aget(id=context.chat_data["inv"])
tmc = [] tmc = []
async for e in CustomTable.objects.all(): async for e in CustomTable.objects.all():
tmc.append(e.name) tmc.append({"name": e.name, "id": e.id})
keys = chunk(3, tmc) keys = chunk(2, tmc)
await update.message.reply_markdown_v2( context.chat_data["inv"] = inv.id
(
f"Инвентаризация `#{inv.id}`\n"
f"Название объекта `{inv.name}`\n"
f"Количество ТМЦ {await inv.tmc.acount()}"
),
reply_parameters=ReplyParameters(message_id=update.message.message_id),
reply_markup=ReplyKeyboardMarkup(
[[KeyboardButton(i) for i in arr] for arr in keys]
),
)
logger.info(tmc)
context.chat_data["step"] = "add_tmc" context.chat_data["step"] = "add_tmc"
elif current_step == "add_tmc": await update.effective_message.reply_markdown_v2(
tmc_name = update.message.text (
tmc = await CustomTable.objects.aget(name=tmc_name) f"Инвентаризация `{inv.name}` от `{inv.created_at.strftime('%x')}`\n"
f"Количество ТМЦ {await inv.tmc.acount()}\n\n"
"Выберите, какую ТМЦ вы осматриваете:"
),
reply_parameters=ReplyParameters(
message_id=update.effective_message.message_id
),
reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
i["name"],
callback_data=f'{context.chat_data["step"]}@{i["id"]}',
)
for i in arr
]
for arr in keys
]
),
)
elif current_step == "add_tmc":
inv = await TgItem.objects.aget(id=context.chat_data["inv"]) inv = await TgItem.objects.aget(id=context.chat_data["inv"])
tmc = await CustomTable.objects.aget(id=context.chat_data["tmc"])
await inv.tmc.aadd(tmc) await inv.tmc.aadd(tmc)
fields = [] fields = []
async for e in tmc.fields.all(): async for e in tmc.fields.all():
fields.append(e.name) fields.append({"name": e.name, "id": e.id})
keys = chunk(1, fields) keys = chunk(1, fields)
await update.message.reply_markdown_v2( context.chat_data["tmc"] = tmc.id
context.chat_data["step"] = "add_element"
await update.effective_message.reply_markdown_v2(
( (
f"Инвентаризация `#{inv.id}`\n" f"Инвентаризация `{inv.name}` от `{inv.created_at.strftime('%x')}`\n"
f"Название объекта `{inv.name}`\n" f"Количество ТМЦ {await inv.tmc.acount()}\n\n"
f"Название ТМЦ `{tmc.name}`\n" f"Название ТМЦ `{tmc.name}`\n"
f"Что вы загружаете?" f"Что вы загружаете?"
), ),
reply_parameters=ReplyParameters(message_id=update.message.message_id), reply_parameters=ReplyParameters(
reply_markup=ReplyKeyboardMarkup( message_id=update.effective_message.message_id
[[KeyboardButton(i) for i in arr] for arr in keys] ),
reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
i["name"],
callback_data=f'{context.chat_data["step"]}@{i["id"]}',
)
for i in arr
]
for arr in keys
]
), ),
) )
context.chat_data["tmc"] = tmc.id
context.chat_data["step"] = "add_field"
elif current_step == "add_field":
tmc = await CustomTable.objects.aget(id=context.chat_data["tmc"])
element_name = update.message.text
element = await Element.objects.acreate(name=element_name, tmc=tmc)
elif current_step == "add_element":
inv = await TgItem.objects.aget(id=context.chat_data["inv"]) inv = await TgItem.objects.aget(id=context.chat_data["inv"])
await inv.element.aadd(element) tmc = inv.tmc.aget(id=context.chat_data["tmc"])
element = inv.element.aget(id=context.chat_data["element"])
await update.message.reply_markdown_v2( context.chat_data["step"] = "add_element_data"
await update.effective_message.reply_markdown_v2(
( (
f"Инвентаризация `#{inv.id}`\n" f"Инвентаризация `{inv.name}` от `{inv.created_at.strftime('%x')}`\n"
f"Название объекта `{inv.name}`\n" f"Количество ТМЦ {await inv.tmc.acount()}\n\n"
f"Название ТМЦ `{tmc.name}`\n" f"Название ТМЦ `{tmc.name}`\n"
f"Название элемента `{element.name}`\n" f"Элемент `{element.name}`\n"
f"Загрузите фото или пришлите текст" f"Загрузите фото или пришлите текст"
), ),
reply_parameters=ReplyParameters(message_id=update.message.message_id), reply_parameters=ReplyParameters(
message_id=update.effective_message.message_id
),
reply_markup=ReplyKeyboardRemove(), reply_markup=ReplyKeyboardRemove(),
) )
context.chat_data["element"] = element.id elif current_step == "add_element_data":
context.chat_data["step"] = "add_field_data"
elif current_step == "add_field_data":
inv = await TgItem.objects.aget(id=context.chat_data["inv"]) inv = await TgItem.objects.aget(id=context.chat_data["inv"])
tmc = await CustomTable.objects.aget(id=inv.tmc) tmc = inv.tmc.aget(id=context.chat_data["tmc"])
element = await Element.objects.aget(id=inv.element) element = inv.element.aget(id=context.chat_data["element"])
if update.message.photo: if update.message.photo:
element.photoid = update.message.photo[-1].file_id element.photoid = update.message.photo[-1].file_id
@ -213,17 +298,17 @@ class TgBot:
await update.message.reply_markdown_v2( await update.message.reply_markdown_v2(
( (
f"Инвентаризация `#{inv.id}`\n" f"Инвентаризация `{inv.name}` от `{inv.created_at.strftime('%x')}`\n"
f"Название объекта `{inv.name}`\n" f"Количество ТМЦ {await inv.tmc.acount()}\n\n"
f"Название ТМЦ `{tmc.name}`\n" f"Название ТМЦ `{tmc.name}`\n"
f"Название элемента `{element.name}`\n" f"Элемент `{element.name}`\n"
f"Данные загружены" f"Данные загружены"
), ),
reply_parameters=ReplyParameters(message_id=update.message.message_id), reply_parameters=ReplyParameters(message_id=update.message.message_id),
reply_markup=ReplyKeyboardRemove(), reply_markup=ReplyKeyboardRemove(),
) )
context.chat_data["element"] = element.id context.chat_data["element"] = element.id
context.chat_data["step"] = "add_field_data" context.chat_data["step"] = "add_element_data"
else: else:
logger.info(update.message.entities) logger.info(update.message.entities)
logger.info(f"no step for update {update}") logger.info(f"no step for update {update}")