|
|
# -*- coding: utf8 -*- |
|
|
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
|
|
|
|
|
# Заказы |
|
|
|
|
|
from bot_sys import bot_bd, keyboard, user_access, bd_table |
|
|
from bot_modules import mod_table_operate, mod_simple_message, orders, access_utils |
|
|
from bot_modules import users, user_message |
|
|
from template import bd_item_select, bd_item_view, bd_item, bd_item_edit |
|
|
|
|
|
from enum import Enum |
|
|
from enum import auto |
|
|
|
|
|
# --------------------------------------------------------- |
|
|
# БД |
|
|
module_name = 'all_orders' |
|
|
|
|
|
table = orders.table |
|
|
|
|
|
init_access = f'{user_access.user_access_group_new}=-' |
|
|
|
|
|
# --------------------------------------------------------- |
|
|
# Сообщения и кнопки |
|
|
|
|
|
class ButtonNames(Enum): |
|
|
SHOW_USER_INFO = auto() |
|
|
SEND_USER_MESSAGE = auto() |
|
|
ADD_TO_DESC = auto() |
|
|
|
|
|
button_names = {} |
|
|
button_names.update(orders.button_names) |
|
|
button_names.pop(mod_table_operate.ButtonNames.ADD) |
|
|
|
|
|
cur_button_names = { |
|
|
mod_simple_message.ButtonNames.START: "🛒 Все заказы", |
|
|
mod_table_operate.ButtonNames.SHOW: "☐ Открыть заказ", |
|
|
mod_table_operate.ButtonNames.LIST: "📃 Список текущих заказов", |
|
|
orders.ButtonNames.LIST_ALL: "📃 Список всех заказов", |
|
|
ButtonNames.SHOW_USER_INFO: "👤 Информация о пользователе", |
|
|
ButtonNames.SEND_USER_MESSAGE: "📨 Отправить сообщение пользователю", |
|
|
ButtonNames.ADD_TO_DESC: "𝌴 Добавить к описанию", |
|
|
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать заказ", |
|
|
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO_PAY): "☐ Загрузить чек по оплате заказа", |
|
|
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в заказе", |
|
|
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в заказе", |
|
|
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в заказе", |
|
|
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ADDRESS): "𝌴 Изменить адрес в заказе", |
|
|
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к заказу", |
|
|
mod_table_operate.EditButton(bd_table.TableFieldDestiny.STATUS): "𝌴 Изменить статус в заказе", |
|
|
mod_table_operate.EnumButton(orders.OrderStatus.NEW): "Заказ ожидает модерации", |
|
|
mod_table_operate.EnumButton(orders.OrderStatus.PAY): "Заказ ожидает оплаты", |
|
|
mod_table_operate.EnumButton(orders.OrderStatus.ADDRESS): "Заказ ожидает уточнения адреса", |
|
|
mod_table_operate.EnumButton(orders.OrderStatus.FINISH): "Заказ выполнен", |
|
|
mod_table_operate.ButtonNames.DEL: "❌ Удалить заказ",} |
|
|
button_names.update(cur_button_names) |
|
|
|
|
|
messages = {} |
|
|
messages.update(orders.messages) |
|
|
|
|
|
cur_messages = { |
|
|
mod_simple_message.Messages.START: f''' |
|
|
<b>{button_names[mod_simple_message.ButtonNames.START]}</b> |
|
|
|
|
|
''', |
|
|
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.STATUS): f''' |
|
|
Текущий статус заказа: |
|
|
#{orders.status_field} |
|
|
|
|
|
Введите новый статус заказа: |
|
|
''', |
|
|
mod_table_operate.Messages.OPEN: f''' |
|
|
<b>Номер заказа: #{orders.key_name} </b> |
|
|
|
|
|
<b>Заказ: #{orders.name_field}</b> |
|
|
|
|
|
<b>Описание и состав заказа:</b> #{orders.desc_field} |
|
|
|
|
|
<b>Статус:</b> #{orders.status_field} |
|
|
|
|
|
<b>Пользователь:</b> #{orders.user_id_field} |
|
|
|
|
|
<b>Адрес доставки:</b> #{orders.address_field} |
|
|
|
|
|
<b>Время создания:</b> #{orders.create_datetime_field} |
|
|
''', |
|
|
mod_table_operate.InlineMessage(ButtonNames.ADD_TO_DESC): f''' |
|
|
Текущее описание заказа: |
|
|
<code>#{orders.desc_field}</code> |
|
|
|
|
|
Введите дополение к описанию заказа: |
|
|
''', |
|
|
} |
|
|
|
|
|
messages_notification = { |
|
|
mod_table_operate.NotificationMessage(orders.OrderStatus.NEW): f'''Статус заказа "#{orders.name_field}" изменён на - ожидает модерации''', |
|
|
mod_table_operate.NotificationMessage(orders.OrderStatus.PAY): f'''Статус заказа "#{orders.name_field}" изменён на - Заказ ожидает оплаты. |
|
|
|
|
|
<b>Описание заказа:</b> |
|
|
#{orders.desc_field} |
|
|
|
|
|
Оплатите заказ и прикрепите чек об оплате к заказу. Для этого проследуйте по пути "Главное меню"->"Заказы"->"Загрузить чек по оплате моего заказа" |
|
|
Или воспользуйтесь кнопкой:''', |
|
|
mod_table_operate.NotificationMessage(orders.OrderStatus.ADDRESS): f'''Статус заказа "#{orders.name_field}" изменён на - Заказ ожидает указания адреса доставки. |
|
|
|
|
|
<b>Описание заказа:</b> |
|
|
#{orders.desc_field} |
|
|
|
|
|
Для этого проследуйте по пути "Главное меню"->"Заказы"->"Редактировать мой заказ"->"Изменить адрес в моём заказе"''', |
|
|
mod_table_operate.NotificationMessage(orders.OrderStatus.FINISH): f'''Статус заказа "#{orders.name_field}" изменён на - Заказ выполнен''', |
|
|
} |
|
|
|
|
|
messages.update(orders.messages_order_status) |
|
|
messages.update(messages_notification) |
|
|
messages.update(cur_messages) |
|
|
|
|
|
def GetCurItemsTemplate(a_Bot, a_TableName, a_StatusFieldName, a_ParentIDFieldName): |
|
|
def GetBDItems(a_Message, a_UserGroups, a_ParentID): |
|
|
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_StatusFieldName} != ?' |
|
|
return a_Bot.SQLRequest(request, param = ([a_ParentID, str(orders.OrderStatus.FINISH)])) |
|
|
return GetBDItems |
|
|
|
|
|
def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_ParentIDFieldName): |
|
|
def GetBDItems(a_Message, a_UserGroups, a_ParentID): |
|
|
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ?' |
|
|
return a_Bot.SQLRequest(request, param = ([a_ParentID])) |
|
|
return GetBDItems |
|
|
|
|
|
class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource): |
|
|
def __init__(self, a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName, a_OnlyCurrent = False): |
|
|
super().__init__(a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName) |
|
|
self.m_OnlyCurrent = a_OnlyCurrent |
|
|
|
|
|
def GetItemsFunc(self): |
|
|
if self.m_OnlyCurrent: |
|
|
return GetCurItemsTemplate(self.m_Bot, self.m_TableName, orders.status_field, self.m_ParentIDFieldName) |
|
|
return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName, self.m_ParentIDFieldName) |
|
|
|
|
|
class ModuleAllOrders(orders.ModuleOrders): |
|
|
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): |
|
|
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) |
|
|
|
|
|
def GetInitBDCommands(self): |
|
|
# уже сделано в ModuleUserOrders |
|
|
return [ |
|
|
access_utils.GetAccessForModuleRequest(self.GetName(), self.m_InitAccess, self.m_DefInitAccess), |
|
|
] |
|
|
|
|
|
def GetName(self): |
|
|
return module_name |
|
|
|
|
|
def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName): |
|
|
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) |
|
|
return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName, a_OnlyCurrent = True) |
|
|
|
|
|
def SelectSourceForAllTemplate(self, a_PrevPrefix, a_ButtonName): |
|
|
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) |
|
|
return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName) |
|
|
|
|
|
def GetButtonNameAndKeyValueAndAccess(self, a_Item): |
|
|
user_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID) |
|
|
n, k, a = super().GetButtonNameAndKeyValueAndAccess(a_Item) |
|
|
return n + "," + str(a_Item[user_field_id]), k, a |
|
|
|
|
|
def GetPayInlineKeyboardFunc(self, a_ItemID, a_Destiny): |
|
|
def PayInlineKeyboard(a_Message, a_UserGroups): |
|
|
#print('PayInlineKeyboard', a_Message, a_UserGroups, a_ItemID) |
|
|
cur_buttons = [] |
|
|
|
|
|
orders_mod = self.GetModule(orders.module_name) |
|
|
dst = a_Destiny |
|
|
if orders_mod: |
|
|
prefix = orders_mod.m_EditPrefix.get(dst, None) |
|
|
if prefix: |
|
|
access = orders_mod.GetAccessForEditKeyboardButtons(orders_mod.m_Table.GetFieldByDestiny(dst)) |
|
|
cur_buttons += [ |
|
|
keyboard.InlineButtonWithAccess(orders_mod.GetButton(mod_table_operate.EditButton(dst)), prefix, a_ItemID, orders_mod.GetAccess(), access), |
|
|
] |
|
|
|
|
|
#print('cur_buttons', cur_buttons, a_Message, a_UserGroups, a_ItemID) |
|
|
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups) |
|
|
return PayInlineKeyboard |
|
|
|
|
|
|
|
|
async def OnChangeField(self, a_Field, a_ItemID, a_ItemData, a_EditUserID): |
|
|
await super().OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID) |
|
|
if a_Field.m_Destiny == bd_table.TableFieldDestiny.STATUS: |
|
|
key_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY) |
|
|
item = bd_item.GetBDItemsTemplate(self.m_Bot, self.m_Table.GetName(), key_field)(a_ItemID) |
|
|
if len(item) < 1: |
|
|
self.m_Log.Error(f'Не удалось оповестить по заказу №{a_ItemID}.') |
|
|
return |
|
|
|
|
|
item = item[0] |
|
|
user_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID) |
|
|
parent_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID) |
|
|
status_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.STATUS) |
|
|
#print('OnChangeField', item, user_field_id, status_field_id) |
|
|
owner_id = item[user_field_id] |
|
|
new_status = item[status_field_id] |
|
|
parent_id = item[parent_field_id] |
|
|
msg = self.GetMessage(mod_table_operate.NotificationMessage(new_status)) |
|
|
parent_id_msg = None |
|
|
if msg: |
|
|
name = self.GetMessageNameWithTableFieldDestinyAndValue(mod_table_operate.NotificationMessage(new_status), bd_table.TableFieldDestiny.PARENT_ID, parent_id) |
|
|
#print('name', name, msg.GetLanguage()) |
|
|
parent_id_msg = msg.FindMessageForLang(name, msg.GetLanguage()) |
|
|
if parent_id_msg: |
|
|
msg = parent_id_msg |
|
|
if not msg: |
|
|
self.m_Log.Error(f'Не удалось оповестить по заказу №{a_ItemID}. Пустое сообщение для нового статуса {new_status}') |
|
|
return |
|
|
msg = self.UpdateMessage(msg, None, item) |
|
|
inline_keyboard = None |
|
|
#print('new_status', str(orders.OrderStatus.PAY), new_status) |
|
|
if new_status == str(orders.OrderStatus.PAY): |
|
|
inline_keyboard = self.GetPayInlineKeyboardFunc(a_ItemID, bd_table.TableFieldDestiny.PHOTO_PAY) |
|
|
elif new_status == str(orders.OrderStatus.ADDRESS): |
|
|
inline_keyboard = self.GetPayInlineKeyboardFunc(a_ItemID, bd_table.TableFieldDestiny.ADDRESS) |
|
|
|
|
|
await self.SendMessageToUser(msg, owner_id, a_GetInlineButtonsFunc = inline_keyboard) |
|
|
|
|
|
def GetStartButtons(self, a_Message, a_UserGroups): |
|
|
return [ |
|
|
[mod_table_operate.ButtonNames.LIST, user_access.AccessMode.VIEW], |
|
|
[mod_table_operate.ButtonNames.EDIT, user_access.AccessMode.EDIT], |
|
|
[mod_table_operate.ButtonNames.ADD, user_access.AccessMode.ADD], |
|
|
[mod_table_operate.ButtonNames.DEL, user_access.AccessMode.DELETE], |
|
|
] |
|
|
|
|
|
def GetViewItemInlineKeyboard(self, a_Message, a_UserGroups, a_ItemID): |
|
|
table_name = self.m_Table.GetName() |
|
|
key_name = self.GetKeyFieldName() |
|
|
cur_item = mod_table_operate.GetCurItem(self.m_Bot, table_name, key_name, a_ItemID) |
|
|
|
|
|
user_id = None |
|
|
user_id_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID) |
|
|
key_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY) |
|
|
if user_id_field_index and cur_item and cur_item[user_id_field_index]: |
|
|
user_id = cur_item[user_id_field_index] |
|
|
|
|
|
if not user_id: |
|
|
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, [], a_UserGroups) |
|
|
|
|
|
cur_buttons = [] |
|
|
|
|
|
for dst in bd_table.TableFieldDestiny.DESC, bd_table.TableFieldDestiny.STATUS: |
|
|
access = self.GetAccessForEditKeyboardButtons(self.m_Table.GetFieldByDestiny(dst)) |
|
|
btn = mod_table_operate.EditButton(dst) |
|
|
prefix = self.m_EditPrefix.get(dst, None) |
|
|
if prefix: |
|
|
cur_buttons += [ |
|
|
keyboard.InlineButtonWithAccess(self.GetButton(btn), prefix, cur_item[key_field_index], self.GetAccess(), access), |
|
|
] |
|
|
|
|
|
access = self.GetAccessForEditKeyboardButtons(self.m_Table.GetFieldByDestiny(bd_table.TableFieldDestiny.DESC)) |
|
|
a_Button = ButtonNames.ADD_TO_DESC |
|
|
prefix = self.m_EditPrefix.get(a_Button, None) |
|
|
cur_buttons += [ |
|
|
keyboard.InlineButtonWithAccess(self.GetButton(a_Button), prefix, cur_item[key_field_index], self.GetAccess(), access), |
|
|
] |
|
|
|
|
|
user_message_mod = self.GetModule(user_message.module_name) |
|
|
if user_message_mod: |
|
|
cur_buttons += [ |
|
|
keyboard.InlineButtonWithAccess(self.GetButton(ButtonNames.SEND_USER_MESSAGE), user_message_mod.GetAddPrefix(), user_id, user_message_mod.GetAccess(), user_access.AccessMode.ADD), |
|
|
] |
|
|
|
|
|
users_mod = self.GetModule(users.module_name) |
|
|
if users_mod: |
|
|
cur_buttons += [ |
|
|
keyboard.InlineButtonWithAccess(self.GetButton(ButtonNames.SHOW_USER_INFO), users_mod.GetShowPrefix(), user_id, users_mod.GetAccess(), user_access.AccessMode.VIEW), |
|
|
] |
|
|
|
|
|
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups) |
|
|
|
|
|
def RegisterAddToDesc(self): |
|
|
a_AccessMode = user_access.AccessMode.EDIT |
|
|
a_Button = ButtonNames.ADD_TO_DESC |
|
|
a_ButtonName = self.GetButton(a_Button) |
|
|
a_EditMessage = self.GetMessage(mod_table_operate.InlineMessage(a_Button)) |
|
|
a_Field = self.m_Table.GetFieldByDestiny(bd_table.TableFieldDestiny.DESC) |
|
|
a_FieldName = a_Field.m_Name |
|
|
|
|
|
a_FieldType = bd_item.FieldType.text |
|
|
if a_Field.m_Type == bd_table.TableFieldType.PHOTO: |
|
|
a_FieldType = bd_item.FieldType.photo |
|
|
|
|
|
if not a_ButtonName or not a_EditMessage: |
|
|
return |
|
|
|
|
|
async def OnChange(a_ItemID, a_ItemData, a_EditUserID): |
|
|
await self.OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID) |
|
|
return self.OnChange() |
|
|
|
|
|
table_name = self.m_Table.GetName() |
|
|
key_name = self.GetKeyFieldName() |
|
|
edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc |
|
|
GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc |
|
|
GetAccess = self.m_GetAccessFunc |
|
|
|
|
|
async def EditBDItemFunc(a_ItemData, a_UserID): |
|
|
a_KeyName = key_name |
|
|
a_TableName = table_name |
|
|
item_id = a_ItemData[a_KeyName] |
|
|
field_value = a_ItemData[a_FieldName] |
|
|
|
|
|
cur_item = mod_table_operate.GetCurItem(self.m_Bot, table_name, key_name, item_id) |
|
|
|
|
|
desc = "" |
|
|
desc_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.DESC) |
|
|
if desc_field_index and cur_item and cur_item[desc_field_index]: |
|
|
desc = cur_item[desc_field_index] |
|
|
|
|
|
new_value = desc + "\n" + field_value |
|
|
res, error = bd_item.EditBDItemInTableTemplate(self.m_Bot, a_TableName, a_KeyName, a_FieldName)(item_id, new_value) |
|
|
if error: |
|
|
self.m_Bot.GetLog().Error(f'Пользователю {a_UserID} не удалось изменить поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={field_value}. Ошибка: {error}') |
|
|
else: |
|
|
self.m_Bot.GetLog().Success(f'Пользователь {a_UserID} добавил в поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={new_value}. Старое {desc}.') |
|
|
|
|
|
await OnChange(item_id, a_ItemData, a_UserID) |
|
|
return res, error |
|
|
|
|
|
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True) |
|
|
|
|
|
a_Prefix = bd_item_edit.CustomEditBDItemRegisterHandlers(self.m_Bot, \ |
|
|
EditBDItemFunc, |
|
|
self.SelectSourceTemplate(a_Prefix, a_ButtonName), \ |
|
|
mod_table_operate.MakeFSMForAddAndEdit(self.GetName(), a_FieldName), \ |
|
|
self.GetMessage(mod_table_operate.Messages.SELECT_TO_EDIT), \ |
|
|
self.ShowMessageTemplate(a_EditMessage), \ |
|
|
self.ShowMessageTemplate(self.GetMessage(mod_table_operate.Messages.SUCCESS_EDIT)), \ |
|
|
table_name, \ |
|
|
key_name, \ |
|
|
a_FieldName, \ |
|
|
self.PostProccessingForFieldForEditTemplate(a_Field),\ |
|
|
GetButtonNameAndKeyValueAndAccess, \ |
|
|
GetAccess, \ |
|
|
self.AdditionalKeyboardForEditTemplate(a_Field),\ |
|
|
edit_keyboard_func, \ |
|
|
access_mode = a_AccessMode, \ |
|
|
field_type = a_FieldType\ |
|
|
) |
|
|
|
|
|
self.m_EditPrefix.update({a_Button: a_Prefix}) |
|
|
|
|
|
|
|
|
def RegisterHandlers(self): |
|
|
super().RegisterHandlers() |
|
|
self.RegisterAddToDesc()
|
|
|
|