Разработан чат-бот
This commit is contained in:
374
handlers/handlers.py
Normal file
374
handlers/handlers.py
Normal file
@ -0,0 +1,374 @@
|
||||
import api
|
||||
import database
|
||||
import models
|
||||
from errors import Error
|
||||
import logging
|
||||
import messages
|
||||
from models import Message, FSMContext
|
||||
import psycopg
|
||||
import re
|
||||
|
||||
|
||||
async def start(message: Message, state: FSMContext):
|
||||
if message.text == 'Записаться':
|
||||
return await messages.select_category(message, state)
|
||||
if message.text == 'Мои обращения':
|
||||
return await messages.select_order(message, state)
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def select_category(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.start(message, state)
|
||||
try:
|
||||
category = tuple(
|
||||
category
|
||||
for category in await database.read_categories()
|
||||
if category.name == message.text
|
||||
)[0]
|
||||
await state.update_data({
|
||||
'category': category,
|
||||
})
|
||||
await messages.select_subcategory(message, state)
|
||||
except IndexError:
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def select_subcategory(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.select_category(message, state)
|
||||
try:
|
||||
data = await state.get_data()
|
||||
subcategory = tuple(
|
||||
subcategory
|
||||
for subcategory in await database.read_subcategories(data['category'])
|
||||
if subcategory.name == message.text
|
||||
)[0]
|
||||
try:
|
||||
free_to_order = await database.read_free_to_order(subcategory)
|
||||
await state.update_data({
|
||||
'subcategory': subcategory,
|
||||
'free_to_order': free_to_order,
|
||||
})
|
||||
await messages.select_date(message, state)
|
||||
except psycopg.errors.RaiseException as error:
|
||||
if error.diag.message_primary == '0x00000005':
|
||||
logging.error('\n\tКатегория: %s\n\tПодкатегория: %s\n\n\tСредняя длительность выполнения заказа указанной подкатегории (таблица statistics) дольше, чем все временные промежутки (таблица time_ranges).' % (
|
||||
subcategory.category.name,
|
||||
subcategory.name,
|
||||
))
|
||||
return await message.answer(
|
||||
text=Error(0x00000005),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
raise
|
||||
except IndexError:
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def select_date(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.select_subcategory(message, state)
|
||||
try:
|
||||
data = await state.get_data()
|
||||
free_to_order = tuple(
|
||||
item
|
||||
for item in data['free_to_order']
|
||||
if item.date.strftime('%d.%m') == message.text
|
||||
)[0]
|
||||
await state.update_data({
|
||||
'date': free_to_order.date,
|
||||
})
|
||||
await messages.select_time_range(message, state)
|
||||
except IndexError:
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def select_time_range(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.select_date(message, state)
|
||||
try:
|
||||
data = await state.get_data()
|
||||
free_to_order = tuple(
|
||||
item
|
||||
for item in data['free_to_order']
|
||||
if '%s - %s' % (
|
||||
item.time_range.start_time.strftime('%H:%M'),
|
||||
item.time_range.end_time.strftime('%H:%M'),
|
||||
) == message.text
|
||||
)[0]
|
||||
await state.update_data({
|
||||
'time_range': free_to_order.time_range,
|
||||
})
|
||||
await messages.input_email_address(message, state)
|
||||
except IndexError:
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def input_email_address(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.select_time_range(message, state)
|
||||
match = re.match(models.email_address, message.text.strip())
|
||||
if match is None:
|
||||
return await message.answer(
|
||||
text=Error(0x00000003),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
await state.update_data({
|
||||
'email_address': match.string,
|
||||
})
|
||||
await messages.input_phone_number(message, state)
|
||||
|
||||
|
||||
async def input_phone_number(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.input_email_address(message, state)
|
||||
phone_number = re.sub(models.phone_number, '', message.text)
|
||||
if len(phone_number) not in range(8, 16):
|
||||
return await message.answer(
|
||||
text=Error(0x00000004),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
await state.update_data({
|
||||
'phone_number': '+%s' % phone_number,
|
||||
})
|
||||
await messages.input_comment(message, state)
|
||||
|
||||
|
||||
async def input_comment(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.input_phone_number(message, state)
|
||||
comment = message.text
|
||||
if len(comment) > models.max_comment_length:
|
||||
return await message.answer(
|
||||
text=Error(0x00000002),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
await state.update_data({
|
||||
'comment': comment,
|
||||
})
|
||||
await messages.confirm_order(message, state)
|
||||
|
||||
|
||||
async def confirm_order(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.input_comment(message, state)
|
||||
if message.text == 'Подтвердить':
|
||||
data = await state.get_data()
|
||||
# executor = sorted(
|
||||
# tuple(
|
||||
# item
|
||||
# for item in data['free_to_order']
|
||||
# if item.date == data['date'] and item.time_range == data['time_range']
|
||||
# ),
|
||||
# key=lambda x: x.busy_interval,
|
||||
# )[0].executor
|
||||
# order_id = await database.create_order(
|
||||
# subcategory=data['subcategory'],
|
||||
# date=data['date'],
|
||||
# time_range=data['time_range'],
|
||||
# executor=executor,
|
||||
# telegram_id=message.from_user.id,
|
||||
# email_address=data['email_address'],
|
||||
# phone_number=data['phone_number'],
|
||||
# comment=data['comment'],
|
||||
# )
|
||||
# orders = await database.read_orders(message.from_user.id)
|
||||
issue = await api.create_issue(
|
||||
subcategory=data['subcategory'],
|
||||
_date=data['date'],
|
||||
time_range=data['time_range'],
|
||||
email_address=data['email_address'],
|
||||
phone_number=data['phone_number'],
|
||||
comment=data['comment'],
|
||||
firstname=message.from_user.first_name,
|
||||
)
|
||||
await state.update_data({
|
||||
# 'executor': executor,
|
||||
'issue_key': issue.key,
|
||||
})
|
||||
await database.create_issue(
|
||||
issue=models.Issue(
|
||||
id=issue.id,
|
||||
key=issue.key,
|
||||
status='new',
|
||||
telegram_id=message.from_user.id,
|
||||
),
|
||||
)
|
||||
return await messages.success_sign_up(message, state)
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def success_sign_up(message: Message, state: FSMContext):
|
||||
if message.text == 'Главное меню':
|
||||
return await messages.start(message, state)
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def select_order(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.start(message, state)
|
||||
try:
|
||||
issue = tuple(
|
||||
issue
|
||||
for issue in await database.read_issues(message.from_user.id)
|
||||
if issue.key == message.text
|
||||
)[0]
|
||||
await state.update_data({
|
||||
'issue': issue,
|
||||
})
|
||||
await messages.select_operation(message, state)
|
||||
except IndexError:
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def no_orders(message: Message, state: FSMContext):
|
||||
if message.text == 'Главное меню':
|
||||
return await messages.start(message, state)
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def select_operation(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.select_order(message, state)
|
||||
if message.text == 'Перенести':
|
||||
data = await state.get_data()
|
||||
free_to_order = await database.read_free_to_order(data['order'].subcategory)
|
||||
await state.update_data({
|
||||
'free_to_order': free_to_order,
|
||||
})
|
||||
return await messages.reschedule_order_select_date(message, state)
|
||||
if message.text == 'Отменить':
|
||||
return await messages.cancel_order(message, state)
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def reschedule_order_select_date(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.select_operation(message, state)
|
||||
try:
|
||||
data = await state.get_data()
|
||||
free_to_order = tuple(
|
||||
item
|
||||
for item in data['free_to_order']
|
||||
if item.date.strftime('%d.%m') == message.text
|
||||
)[0]
|
||||
await state.update_data({
|
||||
'date': free_to_order.date,
|
||||
})
|
||||
await messages.reschedule_order_select_time_range(message, state)
|
||||
except IndexError:
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def reschedule_order_select_time_range(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.reschedule_order_select_date(message, state)
|
||||
try:
|
||||
data = await state.get_data()
|
||||
free_to_order = tuple(
|
||||
item
|
||||
for item in data['free_to_order']
|
||||
if '%s - %s' % (
|
||||
item.time_range.start_time.strftime('%H:%M'),
|
||||
item.time_range.end_time.strftime('%H:%M'),
|
||||
) == message.text
|
||||
)[0]
|
||||
executor = sorted(
|
||||
tuple(
|
||||
item
|
||||
for item in data['free_to_order']
|
||||
if item.date == data['date'] and item.time_range == free_to_order.time_range
|
||||
),
|
||||
key=lambda x: x.busy_interval,
|
||||
)[0].executor
|
||||
await state.update_data({
|
||||
'executor': executor,
|
||||
})
|
||||
await database.update_order(
|
||||
order_id=data['order'].id,
|
||||
date=data['date'],
|
||||
time_range=free_to_order.time_range,
|
||||
executor=executor,
|
||||
)
|
||||
await messages.success_reschedule_order(message, state)
|
||||
except IndexError:
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def success_reschedule_order(message: Message, state: FSMContext):
|
||||
if message.text == 'Мои обращения':
|
||||
await state.reset_data()
|
||||
return await messages.select_order(message, state)
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def cancel_order(message: Message, state: FSMContext):
|
||||
if message.text == 'Назад':
|
||||
return await messages.select_operation(message, state)
|
||||
if message.text == 'Отменить заказ':
|
||||
data = await state.get_data()
|
||||
issue = await api.read_issue(
|
||||
issue_id=data['issue'].id,
|
||||
)
|
||||
issue.delete()
|
||||
await database.delete_issue(
|
||||
issue=issue,
|
||||
)
|
||||
# await database.delete_order(
|
||||
# order_id=data['issue'].id,
|
||||
# )
|
||||
return await messages.success_cancel_order(message, state)
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
||||
|
||||
|
||||
async def success_cancel_order(message: Message, state: FSMContext):
|
||||
if message.text == 'Мои обращения':
|
||||
await state.reset_data()
|
||||
return await messages.select_order(message, state)
|
||||
await message.answer(
|
||||
text=Error(0x00000001),
|
||||
parse_mode='HTML',
|
||||
)
|
Reference in New Issue
Block a user