# -*- coding: utf8 -*- # Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) # Заказы from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes from bot_modules import mod_table_operate, mod_simple_message from template import bd_item_select, bd_item_view, bd_item from enum import Enum from enum import auto class OrderStatus(Enum): NEW = auto() PAY = auto() ADDRESS = auto() FINISH = auto() # --------------------------------------------------------- # БД module_name = 'orders' table_name = module_name key_name = 'orderID' user_id_field = 'userID' name_field = 'orderName' desc_field = 'orderDesc' photo_field = 'orderPhoto' photo_pay_field = 'orderPhotoPay' status_field = 'orderStatus' address_field = 'orderAddress' access_field = 'orderAccess' create_datetime_field = 'orderCreateDateTime' parent_id_field = 'catID' pay_field = bd_table.TableField(photo_pay_field, bd_table.TableFieldDestiny.PHOTO_PAY, bd_table.TableFieldType.PHOTO) table = bd_table.Table(table_name, [ bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), bd_table.TableField(user_id_field, bd_table.TableFieldDestiny.USER_ID, bd_table.TableFieldType.INT), bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR), bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO), pay_field, bd_table.TableField(status_field, bd_table.TableFieldDestiny.STATUS, bd_table.TableFieldType.ENUM, a_Enum = OrderStatus), bd_table.TableField(address_field, bd_table.TableFieldDestiny.ADDRESS, bd_table.TableFieldType.STR), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT), ]) init_access = f'{user_access.user_access_group_auth_users}=vea' # --------------------------------------------------------- # Сообщения и кнопки class ButtonNames(Enum): LIST_ALL = auto() button_names = { mod_simple_message.ButtonNames.START: "‍🛒 Заказы", mod_table_operate.ButtonNames.SHOW: "☐ Открыть заказ", mod_table_operate.ButtonNames.LIST: "📃 Список моих текущих заказов", ButtonNames.LIST_ALL: "📃 Список всех моих заказов", mod_table_operate.ButtonNames.ADD: "✅ Добавить заказ", 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.ButtonNames.DEL: "❌ Удалить мой заказ", } messages = { mod_simple_message.Messages.START: f''' {button_names[mod_simple_message.ButtonNames.START]} ''', mod_table_operate.Messages.SELECT: ''' Пожалуйста, выберите заказ: ''', mod_table_operate.Messages.ERROR_FIND: ''' ❌ Ошибка, заказ не найден ''', mod_table_operate.Messages.OPEN: f''' Номер заказа: #{key_name} Имя заказа: #{name_field} Описание и состав заказа: #{desc_field} Статус: #{status_field} Адрес доставки: #{address_field} Время создания: #{create_datetime_field} ''', mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): ''' Создание заказа. Шаг №1 Введите название заказа: ''', mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' Создание заказа. Шаг №2 Введите описание заказа: ''', mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' Создание заказа. Шаг №3 Загрузите фотографию для заказа. Фото будет отображаться в его описании. (Если фотографии нет, то нажмите "⏩ Пропустить") ''', mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Заказ успешно добавлен!''', mod_table_operate.Messages.START_EDIT: ''' Пожалуйста, выберите действие: ''', mod_table_operate.Messages.SELECT_TO_EDIT: ''' Выберите заказ, который вы хотите отредактировать. ''', mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO_PAY): ''' Загрузите чек по оплате заказа (фото): ''', mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): ''' Загрузите новую обложку для заказа (Фото): Она будет отображаться в его описании. ''', mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f''' Текущее название заказа: #{name_field} Введите новое название заказа: ''', mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' Текущее описание заказа: #{desc_field} Введите новое описание заказа: ''', mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ADDRESS): f''' Текущий адрес заказа: #{address_field} Введите новый адрес доставки заказа (укажите, кто, когда и где его сможет забрать): ''', mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' Текущий доступ к заказу: #{access_field} {user_access.user_access_readme} Введите новую строку доступа: ''', mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Заказ успешно отредактирован!''', mod_table_operate.Messages.SELECT_TO_DELETE: ''' Выберите заказ, который вы хотите удалить. Все задачи и потребности в этом заказе так же будут удалены! ''', mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Заказ успешно удалён!''', } messages_order_status = { mod_table_operate.EnumMessageForView(OrderStatus.NEW): f'''Заказ создан, ожидает модерации''', mod_table_operate.EnumMessageForView(OrderStatus.PAY): f'''Заказ ожидает оплаты''', mod_table_operate.EnumMessageForView(OrderStatus.ADDRESS): f'''Заказ ожидает указания адреса доставки''', mod_table_operate.EnumMessageForView(OrderStatus.FINISH): f'''Заказ выполнен''', } messages.update(messages_order_status) messages_subscribes = { mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Заказ создан''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Заказ отредактирован''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Заказ удалён''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Заказ отредактирован #item_id''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Заказ удалён #item_id''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT):f'''Заказ создан Номер заказа: #{key_name} Имя заказа: #{name_field} Описание и состав заказа: #{desc_field}''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT):f'''Заказ отредактирован Номер заказа: #{key_name} Имя заказа: #{name_field} Описание и состав заказа: #{desc_field}''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT):f'''Заказ удалён''', } messages.update(messages_subscribes) def GetCurItemsTemplate(a_Bot, a_TableName, a_UserIDFieldName, a_ParentIDFieldName, a_StatusFieldName): def GetBDItems(a_Message, a_UserGroups, a_ParentID): user_id = str(a_Message.from_user.id) request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_UserIDFieldName} = ? AND {a_StatusFieldName} != ?' return a_Bot.SQLRequest(request, param = ([a_ParentID, user_id, str(OrderStatus.FINISH)])) return GetBDItems def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_UserIDFieldName, a_ParentIDFieldName): def GetBDItems(a_Message, a_UserGroups, a_ParentID): user_id = str(a_Message.from_user.id) request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_UserIDFieldName} = ?' print('GetBDItemsForUserTemplate', user_id, request, a_ParentID) return a_Bot.SQLRequest(request, param = ([a_ParentID, user_id])) 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, user_id_field, self.m_ParentIDFieldName, status_field) return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName, user_id_field, self.m_ParentIDFieldName) class ModuleOrders(mod_table_operate.TableOperateModule): def __init__(self, a_Table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): super().__init__(table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) 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 AddBDItemFunc(self, a_ItemData, a_UserID): parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) a_ItemData[name_field] = '' a_ItemData[photo_field] = '' a_ItemData[user_id_field] = a_UserID a_ItemData[status_field] = str(OrderStatus.NEW) a_ItemData[address_field] = '' a_ItemData[photo_pay_field] = '0' return super().AddBDItemFunc(a_ItemData, a_UserID) def GetModuleButtons(self): buttons = super().GetModuleButtons(); add_order_button = [ keyboard.ButtonWithAccess(self.GetButton(mod_table_operate.ButtonNames.ADD), user_access.AccessMode.ADD, self.GetAccess()), ] return add_order_button + buttons def GetNameFromDesc(self, a_Desc): name = '' lines = str(a_Desc).splitlines() for l in lines: name = l.strip(); if len(name) > 0: break; return name[0:16] def GetButtonNameAndKeyValueAndAccess(self, a_Item): user_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID) key_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY) desc_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.DESC) n, k, a = super().GetButtonNameAndKeyValueAndAccess(a_Item) return str(a_Item[key_field_id]) + ":" + str(self.GetNameFromDesc(a_Item[desc_field_id])), k, a def GetAddFieldDestinys(self): return ( bd_table.TableFieldDestiny.DESC, ) def GetStartButtons(self, a_Message, a_UserGroups): pay_access = self.GetAccessForEditKeyboardButtons(pay_field) return [ [mod_table_operate.ButtonNames.ADD, user_access.AccessMode.ADD], [mod_table_operate.EditButton(pay_field.m_Destiny), pay_access], [mod_table_operate.ButtonNames.EDIT, user_access.AccessMode.EDIT], [mod_table_operate.ButtonNames.LIST, user_access.AccessMode.VIEW], [mod_table_operate.ButtonNames.DEL, user_access.AccessMode.DELETE], ] def GetStartKeyboardButtons(self, a_Message, a_UserGroups): parent_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups) cur_buttons = [ keyboard.ButtonWithAccess(self.GetButton(ButtonNames.LIST_ALL), user_access.AccessMode.VIEW, self.GetAccess()), ] return parent_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) def RegisterHandlers(self): super().RegisterHandlers() table_name = self.m_Table.GetName() key_name = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY) def GetViewItemInlineKeyboardTemplate(a_ItemID): return self.GetViewItemInlineKeyboardTemplate(a_ItemID) GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc GetAccess = self.m_GetAccessFunc default_keyboard_func = self.m_GetStartKeyboardButtonsFunc # Список всех заказов a_ButtonName = self.GetButton(ButtonNames.LIST_ALL) if a_ButtonName: a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True) a_Prefix = bd_item_select.SelectRegisterHandlers(self.m_Bot,\ self.SelectSourceForAllTemplate(a_Prefix, a_ButtonName), \ GetButtonNameAndKeyValueAndAccess,\ self.GetMessage(mod_table_operate.Messages.SELECT),\ GetAccess,\ access_mode = user_access.AccessMode.VIEW\ ) bd_item_view.ShowBDItemRegisterHandlers(self.m_Bot,\ a_Prefix,\ table_name,\ key_name,\ self.ShowMessageTemplate(self.GetMessage(mod_table_operate.Messages.OPEN),GetViewItemInlineKeyboardTemplate, a_EnablePhoto = True),\ GetAccess,\ default_keyboard_func,\ access_mode = user_access.AccessMode.VIEW\ ) class ModuleUserOrders(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 GetName(self): return module_name def GetShowItemInlineKeyboard(self, a_Message, a_UserGroups, a_ItemID): all_orders_mod = self.GetModule('all_orders') if not all_orders_mod: return None cur_buttons = [ keyboard.InlineButtonWithAccess(all_orders_mod.GetButton(mod_table_operate.ButtonNames.SHOW), all_orders_mod.GetShowPrefix(), a_ItemID, all_orders_mod.GetAccess(), user_access.AccessMode.VIEW), ] return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups)