375 строки
12 KiB
Python
375 строки
12 KiB
Python
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',
|
|
)
|