# -*- 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 ( )