diff --git a/TelegramGoodsinbot/main.py b/TelegramGoodsinbot/main.py new file mode 100644 index 0000000..2a422fb --- /dev/null +++ b/TelegramGoodsinbot/main.py @@ -0,0 +1,77 @@ +# - *- coding: utf- 8 - *- +import os +import sys + +import colorama +from aiogram import executor, Dispatcher +from colorama import Fore + + +from tgbot.data.config import get_admins +from tgbot.handlers import dp +from tgbot.loader import scheduler +from tgbot.middlewares import setup_middlewares +from tgbot.services.api_session import RequestsSession +from tgbot.services.api_sqlite import create_dbx +from tgbot.services.regular import send_message_start +from tgbot.utils.misc.bot_commands import set_commands +from tgbot.utils.misc.bot_logging import bot_logger +from tgbot.utils.misc_functions import check_update, check_bot_data, on_startup_notify, update_profit_day, \ + update_profit_week + +#CHANNEL_ID = '-1001683374540' +#text = "test" + +#async def send_message(channel_id: int, text: str): +# await bot.send_message(channel_id, text) + +# Запуск шедулеров +async def scheduler_start(): + # scheduler.add_job(send_message_start, 'interval', seconds=600) + # scheduler.add_job(check_order_messages, 'interval', seconds=600) + # scheduler.add_job(update_profit_week, "cron", day_of_week="mon", hour=00, minute=1) + # scheduler.add_job(update_profit_day, "cron", hour=00) + # scheduler.add_job(check_update, "cron", hour=00) + pass + +# Выполнение функции после запуска бота +async def on_startup(dp: Dispatcher): + await dp.bot.delete_webhook() + await dp.bot.get_updates(offset=-1) + dp.bot['rSession'] = RequestsSession() + + await set_commands(dp) + await check_bot_data() + await scheduler_start() + await on_startup_notify(dp) + + bot_logger.exception("BOT WAS STARTED") + print(Fore.LIGHTYELLOW_EX + "~~~~~ Bot was started ~~~~~") + print(Fore.LIGHTBLUE_EX + "~~~~~ TG developer: @raclear ~~~~~") + print(Fore.RESET) + + if len(get_admins()) == 0: print("***** ENTER ADMIN ID IN settings.ini *****") + + +# Выполнение функции после выключения бота +async def on_shutdown(dp: Dispatcher): + rSession: RequestsSession = dp.bot['rSession'] + await rSession.close() + # + await dp.storage.close() + await dp.storage.wait_closed() + await (await dp.bot.get_session()).close() + # + if sys.platform.startswith("win"): + os.system("cls") + else: + os.system("clear") + + +if __name__ == "__main__": + create_dbx() + + scheduler.start() + setup_middlewares(dp) + + executor.start_polling(dp, on_startup=on_startup, on_shutdown=on_shutdown) diff --git a/TelegramGoodsinbot/main.sh b/TelegramGoodsinbot/main.sh new file mode 100644 index 0000000..9b88836 --- /dev/null +++ b/TelegramGoodsinbot/main.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cd autoshopDjimbo3.1&&python3.9 main.py \ No newline at end of file diff --git a/TelegramGoodsinbot/requirements.txt b/TelegramGoodsinbot/requirements.txt new file mode 100644 index 0000000..6c45e57 --- /dev/null +++ b/TelegramGoodsinbot/requirements.txt @@ -0,0 +1,12 @@ +aiogram +colorlog +requests +bs4 +beautifulsoup4 +pyQiwiP2P +aiohttp +APScheduler==3.9.1 +colorama +async_class +yoomoney +geopy \ No newline at end of file diff --git a/TelegramGoodsinbot/settings.ini b/TelegramGoodsinbot/settings.ini new file mode 100644 index 0000000..5705ec6 --- /dev/null +++ b/TelegramGoodsinbot/settings.ini @@ -0,0 +1,7 @@ +# - *- coding: utf- 8 - *- +[settings] +token= +admin_id= +admin = +shopadmin_id= + diff --git a/TelegramGoodsinbot/tgbot/__init__.py b/TelegramGoodsinbot/tgbot/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TelegramGoodsinbot/tgbot/data/__init__.py b/TelegramGoodsinbot/tgbot/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TelegramGoodsinbot/tgbot/data/config.py b/TelegramGoodsinbot/tgbot/data/config.py new file mode 100644 index 0000000..e37c60a --- /dev/null +++ b/TelegramGoodsinbot/tgbot/data/config.py @@ -0,0 +1,180 @@ +# - *- coding: utf- 8 - *- +import sqlite3 +import configparser +import json + + +read_config = configparser.ConfigParser() +read_config.read('settings.ini') + +BOT_TOKEN = read_config['settings']['token'].strip() # Токен бота +PATH_DATABASE = 'tgbot/data/database.db' # Путь к БД +PATH_LOGS = 'tgbot/data/logs.log' # Путь к Логам +BOT_VERSION = '1.0' + +# Преобразование полученного списка в словарь + + +def dict_factory(cursor, row): + save_dict = {} + + for idx, col in enumerate(cursor.description): + save_dict[col[0]] = row[idx] + + return save_dict + +# Форматирование запроса без аргументов + + +def update_format(sql, parameters: dict): + if "XXX" not in sql: + sql += " XXX " + + values = ", ".join([ + f"{item} = ?" for item in parameters + ]) + sql = sql.replace("XXX", values) + + return sql, list(parameters.values()) + + +def get_type_trade(): + get_type_trade = get_settingsx()['type_trade'] + return get_type_trade + +# Получение администраторов бота + + +def get_admins(): + read_admins = configparser.ConfigParser() + read_admins.read('settings.ini') + + admins = read_admins['settings']['admin_id'].strip() + admins = admins.replace(' ', '') + + if ',' in admins: + admins = admins.split(',') + else: + if len(admins) >= 1: + admins = [admins] + else: + admins = [] + + while '' in admins: + admins.remove('') + while ' ' in admins: + admins.remove(' ') + while '\r' in admins: + admins.remove('\r') + + admins = list(map(int, admins)) + # print(admins) + return admins + + # Получение админов магазинов + + +def get_shopadmins(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT user_id FROM storage_users WHERE user_role='ShopAdmin'" + allshopadmins = con.execute(sql).fetchall() + # print(allshopadmins) + shopadmins = [] + for admin in allshopadmins: + k = admin['user_id'] + shopadmins.append(k) + # print(shopadmins) + # print(type(shopadmins)) + + return shopadmins + + +def get_shopadmins2(): + read_shopadmins = configparser.ConfigParser() + read_shopadmins.read('settings.ini') + + shopadmins = read_shopadmins['settings']['shopadmin_id'].strip() + shopadmins = shopadmins.replace(' ', '') + + if ',' in shopadmins: + shopadmins = shopadmins.split(',') + else: + if len(shopadmins) >= 1: + shopadmins = [shopadmins] + else: + shopadmins = [] + + while '' in shopadmins: + shopadmins.remove('') + while ' ' in shopadmins: + shopadmins.remove(' ') + while '\r' in shopadmins: + shopadmins.remove('\r') + + shopadmins = list(map(int, shopadmins)) + + return shopadmins + + # Получение админов магазинов + + +def is_shopadmin(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT user_id FROM storage_users " + #sql, parameters = update_format(sql, kwargs) + # parameters.append(user_id) + shopadmin = con.execute( + sql + "WHERE user_id = ?", [user_id]).fetchone() + + return shopadmin['user_id'] + + +def check_adminproducts(): + #get_position = get_positionsx(position_user_id=message.from_user.id) + + return 1 + + +BOT_DESCRIPTION = f""" + +❗🔴 Правила использования: +- Запрещено менять данные аккаунта, при этом вы можете добавлять друзей (для того чтоб поиграть с ними) +- Запрещено использовать читы и другие виды мошенничества, играйте честно! +- Вы не можете передавать аккаунт третьему лицу. Если это произойдет, то у нас будет зафиксирован вход с другого устройства. Вы будете деавторизованы и лишены возможности зайти в аккаунт, без возврата денежных средств. +- На аккаунт может зайти наш оператор поддержки для проверки. При любых подозрениях, что аккаунтом кто-то пользуется кроме вас - сразу же сообщайте нам, мы проверим и деавторизуем любые сессии, кроме вашей. +- После истечения срока аренды вы не можете продолжать пользоваться аккаунтом и должны выйти из аккаунта или же оплатить дополнительное время аренды. + +Активация предоставляется только на один компьютер. Вы платите за 1 активацию на 1 ПК! +✅ Обязательно проверьте что ваш компьютер соответствует минимальным требованиям игры! +✅ Мы не делаем возвратов если ваш ПК не соответствует минимальным требованиям игры. +✅ Аккаунт куплен легально, является собственностью продавца и не передается вам в собственность. Менять пароль ЗАПРЕЩЕНО! Вы получаете только право использования аккаунта. +➖➖➖➖➖➖➖➖➖➖ +⚜ Часто задаваемые вопросы: +➖➖➖➖➖➖➖➖➖➖ +Как взять игру в аренду ? +В главном меню бота выбираем - "Игры в аренду" => Игру которую хотите арендовать => Выбираете срок аренды => +💰 Взять в аренду (Если на балансе недостаточно средств, пополнить баланс можно в профиле => "💰 Пополнить") + +Как я получу игру после оплаты ? +Как только Вы оплатите аренду, доступы к аккаунту Steam появятся с Вашем профиле в разделе "🎁 Мои покупки" + +Как мне начать играть ? +Вам выдаётся логин и пароль от аккаунта с игрой в Steam. +Просто заходите в аккаунт с этими данными, на аккаунте будет арендованная игра. +Срок аренды исчисляется с момента оплаты, устанавливаете и играете. + +Не могу войти в Steam, что делать? +Если возникли сложности со входом, напишите нашему администратору - "@tech_steam" +Ответ вы получите в порядке очереди обращения. + +Могу ли я разместить свои игры в аренду в вашем магазине ? +По вопросам сотрудничества пишите - @ru_adm + +➖➖➖➖➖➖➖➖➖➖ +⚜ Контакты: +Техническая поддержка : @tech_steam +Сотрудничество : @ru_adm +➖➖➖➖➖➖➖➖➖➖ +""".strip() diff --git a/TelegramGoodsinbot/tgbot/data/data_cities.db b/TelegramGoodsinbot/tgbot/data/data_cities.db new file mode 100644 index 0000000..19ca95c Binary files /dev/null and b/TelegramGoodsinbot/tgbot/data/data_cities.db differ diff --git a/TelegramGoodsinbot/tgbot/data/database.db b/TelegramGoodsinbot/tgbot/data/database.db new file mode 100644 index 0000000..3ceb054 Binary files /dev/null and b/TelegramGoodsinbot/tgbot/data/database.db differ diff --git a/TelegramGoodsinbot/tgbot/data/logs.log b/TelegramGoodsinbot/tgbot/data/logs.log new file mode 100644 index 0000000..1cf2ed6 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/data/logs.log @@ -0,0 +1,2 @@ +ERROR | 2022-12-04 16:30:14,219 | main.py:48 | BOT WAS STARTED +NoneType: None diff --git a/TelegramGoodsinbot/tgbot/handlers/__init__.py b/TelegramGoodsinbot/tgbot/handlers/__init__.py new file mode 100644 index 0000000..657a5b5 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/__init__.py @@ -0,0 +1,16 @@ +# - *- coding: utf- 8 - *- + +from .z_all_errors import dp +from .main_start import dp +from .admin_menu import dp +from .user_menu import dp +from .admin_functions import dp +from .admin_payment import dp +from .admin_products import dp +from .admin_settings import dp +from .user_transactions import dp +from .user_location import dp +from .admin_products_shop import dp +from .z_all_missed_ import dp + +__all__ = ['dp'] diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/__init__.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..cd90ddd Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/__init__.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_functions.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_functions.cpython-310.pyc new file mode 100644 index 0000000..9faff9d Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_functions.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_menu.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_menu.cpython-310.pyc new file mode 100644 index 0000000..ad1048a Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_menu.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_payment.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_payment.cpython-310.pyc new file mode 100644 index 0000000..91896b2 Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_payment.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_products.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_products.cpython-310.pyc new file mode 100644 index 0000000..6330c1d Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_products.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_products_shop.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_products_shop.cpython-310.pyc new file mode 100644 index 0000000..07e4d26 Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_products_shop.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_settings.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_settings.cpython-310.pyc new file mode 100644 index 0000000..22a71b3 Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/admin_settings.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/main_start.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/main_start.cpython-310.pyc new file mode 100644 index 0000000..7781d03 Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/main_start.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_location.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_location.cpython-310.pyc new file mode 100644 index 0000000..a7bacee Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_location.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_menu.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_menu.cpython-310.pyc new file mode 100644 index 0000000..0d4a7ad Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_menu.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_transactions.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_transactions.cpython-310.pyc new file mode 100644 index 0000000..26fe837 Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/user_transactions.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/z_all_errors.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/z_all_errors.cpython-310.pyc new file mode 100644 index 0000000..f8fe4c4 Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/z_all_errors.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/__pycache__/z_all_missed_.cpython-310.pyc b/TelegramGoodsinbot/tgbot/handlers/__pycache__/z_all_missed_.cpython-310.pyc new file mode 100644 index 0000000..a607921 Binary files /dev/null and b/TelegramGoodsinbot/tgbot/handlers/__pycache__/z_all_missed_.cpython-310.pyc differ diff --git a/TelegramGoodsinbot/tgbot/handlers/admin_functions.py b/TelegramGoodsinbot/tgbot/handlers/admin_functions.py new file mode 100644 index 0000000..706895d --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/admin_functions.py @@ -0,0 +1,405 @@ +# - *- coding: utf- 8 - *- +import asyncio + +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message +from aiogram.utils.exceptions import CantParseEntities + +from tgbot.keyboards.inline_admin import profile_search_finl, profile_search_reqs +from tgbot.keyboards.inline_z_all import ad_confirm_inl +from tgbot.loader import dp, bot +from tgbot.services.api_sqlite import * +from tgbot.utils.misc.bot_filters import IsAdmin +from tgbot.utils.misc_functions import open_profile_search, open_profile_search_req, upload_text, generate_sales_report +#from munch import Munch + + +# Рассылка +@dp.message_handler(IsAdmin(), text="📢 Рассылка", state="*") +async def functions_ad(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_ad_text") + await message.answer("📢 Введите текст для рассылки пользователям\n" + "❕ Вы можете использовать HTML разметку") + +# Поиск профиля +@dp.message_handler(IsAdmin(), text="👤 Поиск профиля 🔍", state="*") +async def functions_profile(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_profile") + await message.answer("👤 Введите логин или айди пользователя") + +# Поиск чеков +@dp.message_handler(IsAdmin(), text="🧾 Поиск чеков 🔍", state="*") +async def functions_receipt(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_receipt") + await message.answer("🧾 Отправьте номер чека") + +# Просмотр запросов продавцов +@dp.message_handler(IsAdmin(), text="🖍 Посмотреть запросы", state="*") +async def functions_seller_requests(message: Message, state: FSMContext): + await state.finish() + + #await state.set_state("check_seller_requests") + + await message.answer("🧾 Посмотрим запросы продавцов:") + + all_requests = get_all_requestx() + #print(all_requests) + if len(all_requests) >= 1: + await message.answer("Запросы на роль продавца" + str(len(all_requests)) + "шт.") + + for request in all_requests: + + await message.answer(open_profile_search_req(request['user_id']), reply_markup=profile_search_reqs(request['user_id'])) + +########################################### CALLBACKS ########################################### +# Подтверждение отправки рассылки +@dp.callback_query_handler(IsAdmin(), text_startswith="confirm_ad", state="here_ad_confirm") +async def functions_ad_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + + send_message = (await state.get_data())['here_ad_text'] + get_users = get_all_usersx() + await state.finish() + + if get_action == "yes": + await call.message.edit_text(f"📢 Рассылка началась... (0/{len(get_users)})") + asyncio.create_task(functions_ad_make(send_message, call)) + else: + await call.message.edit_text("📢 Вы отменили отправку рассылки ✅") + + +# Покупки пользователя +@dp.callback_query_handler(IsAdmin(), text_startswith="admin_user_purchases", state="*") +async def functions_profile_purchases(call: CallbackQuery, state: FSMContext): + user_id = call.data.split(":")[1] + last_purchases = last_purchasesx(user_id, 10) + + if len(last_purchases) >= 1: + await call.answer("🎁 Последние 10 покупок") + await call.message.delete() + + for purchases in last_purchases: + link_items = await upload_text(call, purchases['purchase_item']) + + await call.message.answer(f"🧾 Чек: #{purchases['purchase_receipt']}\n" + f"🎁 Товар: {purchases['purchase_position_name']} | {purchases['purchase_count']}шт | {purchases['purchase_price']}₽\n" + f"🕰 Дата покупки: {purchases['purchase_date']}\n" + f"🔗 Товары: кликабельно") + + await call.message.answer(open_profile_search(user_id), reply_markup=profile_search_finl(user_id)) + else: + await call.answer("❗ У пользователя отсутствуют покупки", True) + + +# Отправка рассылки +async def functions_ad_make(message, call: CallbackQuery): + receive_users, block_users, how_users = 0, 0, 0 + get_users = get_all_usersx() + + for user in get_users: + try: + await bot.send_message(user['user_id'], message, disable_web_page_preview=True) + receive_users += 1 + except: + block_users += 1 + + how_users += 1 + + if how_users % 10 == 0: + await call.message.edit_text(f"📢 Рассылка началась... ({how_users}/{len(get_users)})") + + await asyncio.sleep(0.05) + + await call.message.edit_text( + f"📢 Рассылка была завершена ✅\n" + f"👤 Пользователей получило сообщение: {receive_users} ✅\n" + f"👤 Пользователей не получило сообщение: {block_users} ❌" + ) + +# Подтверждение запроса продавца +@dp.callback_query_handler(IsAdmin(), text_startswith="admin_user_request_approve", state="*") +async def functions_shopadmin_request_approve(call: CallbackQuery, state: FSMContext): + #await state.update_data(here_profile=call.data.split(":")[1]) + + #await state.set_state("here_user_request_approve") + #user_id = (await state.get_data())['here_profile'] + user_id = call.data.split(":")[1] + await state.finish() + + get_user = get_userx(user_id=user_id) + update_userx(user_id, user_role="ShopAdmin") + update_requestx(user_id, state="Approved") + + await call.message.answer( + f"✅ Пользователю {get_user['user_name']} " + f"изменена роль на: {get_user['user_role']}") + + await bot.send_message(user_id, f" Вам была выдана роль Продавца магазина. ") + #await call.answer(open_profile_search(user_id), reply_markup=profile_search_finl(user_id)) + + +# Отклонение запроса продавца +@dp.callback_query_handler(IsAdmin(), text_startswith="admin_user_request_decline", state="*") +async def functions_shopadmin_request_decline(call: CallbackQuery, state: FSMContext): + #await state.update_data(here_profile=call.data.split(":")[1]) + #user_id = (await state.get_data())['here_profile'] + await state.finish() + user_id = call.data.split(":")[1] + print(user_id) + #user_id = call.data.split(":")[1] + #get_user = get_userx(user_id=user_id) + + #get_user = get_userx(user_id=user_id) + #delete_requests_userx(user_id) + delete_requests_userx(user_id) + #call.data + + await call.answer(" Запрос был успешно удален.") + + #await state.set_state("here_user_request_decline") + await bot.send_message(user_id, f"Ваш запрос был отклонен. Вы можете попробовать подать следующий запрос через 14 дней.") + + +# Выдача баланса пользователю +@dp.callback_query_handler(IsAdmin(), text_startswith="admin_user_balance_add", state="*") +async def functions_profile_balance_add(call: CallbackQuery, state: FSMContext): + await state.update_data(here_profile=call.data.split(":")[1]) + + await state.set_state("here_profile_add") + await call.message.edit_text("💰 Введите сумму для выдачи баланса") + + +# Изменение баланса пользователю +@dp.callback_query_handler(IsAdmin(), text_startswith="admin_user_balance_set", state="*") +async def functions_profile_balance_set(call: CallbackQuery, state: FSMContext): + await state.update_data(here_profile=call.data.split(":")[1]) + + await state.set_state("here_profile_set") + await call.message.edit_text("💰 Введите сумму для изменения баланса") + + +# Обновление профиля пользователя +@dp.callback_query_handler(IsAdmin(), text_startswith="admin_user_refresh", state="*") +async def functions_profile_refresh(call: CallbackQuery, state: FSMContext): + user_id = call.data.split(":")[1] + + await call.message.delete() + await call.message.answer(open_profile_search(user_id), reply_markup=profile_search_finl(user_id)) + + + +# Просмотр запросов продавцов +@dp.message_handler(IsAdmin(), text="📊 Отчет о продажах", state="*") +async def functions_seller_requests(message: Message, state: FSMContext): + await state.finish() + + #await state.set_state("check_seller_requests") + + await message.answer(generate_sales_report()) + + get_users = get_purchasesbysellers() + #print(all_requests) + if len(get_users)>= 1: + await message.answer("Топ - продавцов" + str(len(get_users)) + "шт.") + + for user in get_users: + #if user['user_id'] is None: continue + + await message.answer(open_profile_search_seller(user_id=user['user_id']), reply_markup=profile_search_finl(user['user_id'])) + +######################################## СМЕНА СТАТУСОВ ПОЛЬЗОВАТЕЛЯ ############################ + +# Принятие суммы для выдачи баланса пользователю +#@dp.message_handler(IsAdmin(), state="here_user_request_approve") +@dp.callback_query_handler(IsAdmin(), state="here_user_request_approve") +async def functions_shopadmin_request_approvep(message: Message, state: FSMContext): + user_id = (await state.get_data())['here_profile'] + await state.finish() + + get_user = get_userx(user_id=user_id) + update_userx(user_id, user_role="ShopAdmin") + + await message.answer( + f"✅ Пользователю {get_user['user_name']} " + f"изменена роль на: {get_user['user_role']}") + + await message.bot.send_message(user_id, f" Вам была выдана роль Продавца магазина ") + await message.answer(open_profile_search(user_id), reply_markup=profile_search_finl(user_id)) + + +######################################## ПРИНЯТИЕ ДАННЫХ ######################################## +# Принятие текста для рассылки +@dp.message_handler(IsAdmin(), state="here_ad_text") +async def functions_ad_get(message: Message, state: FSMContext): + await state.update_data(here_ad_text="📢 Рассылка.\n" + str(message.text)) + get_users = get_all_usersx() + + try: + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + await state.set_state("here_ad_confirm") + await message.answer( + f"📢 Отправить {len(get_users)} юзерам сообщение?\n" + f"{message.text}", + reply_markup=ad_confirm_inl, + disable_web_page_preview=True + ) + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📢 Введите текст для рассылки пользователям.\n" + "❕ Вы можете использовать HTML разметку.") + +# Принятие айди или логина для поиска профиля +@dp.message_handler(IsAdmin(), state="here_profile") +async def functions_profile_get(message: Message, state: FSMContext): + find_user = message.text + + if find_user.isdigit(): + get_user = get_userx(user_id=find_user) + else: + if find_user.startswith("@"): find_user = find_user[1:] + get_user = get_userx(user_login=find_user.lower()) + + if get_user is not None: + await state.finish() + await message.answer(open_profile_search(get_user['user_id']), + reply_markup=profile_search_finl(get_user['user_id'])) + else: + await message.answer("❌ Профиль не был найден\n" + "👤 Введите логин или айди пользователя.") + + +# Принятие суммы для выдачи баланса пользователю +@dp.message_handler(IsAdmin(), state="here_profile_add") +async def functions_profile_balance_add_get(message: Message, state: FSMContext): + if message.text.isdigit(): + if 0 <= int(message.text) <= 1000000000: + user_id = (await state.get_data())['here_profile'] + await state.finish() + + get_user = get_userx(user_id=user_id) + update_userx(user_id, user_balance=get_user['user_balance'] + int(message.text)) + + await message.answer( + f"✅ Пользователю {get_user['user_name']} " + f"выдано {message.text}₽") + + await message.bot.send_message(user_id, f"💰 Вам было выдано {message.text}₽") + await message.answer(open_profile_search(user_id), reply_markup=profile_search_finl(user_id)) + else: + await message.answer("❌ Сумма выдачи не может быть меньше 1 и больше 1 000 000 000\n" + "💰 Введите сумму для выдачи баланса") + else: + await message.answer("❌ Данные были введены неверно.\n" + "💰 Введите сумму для выдачи баланса") + + +# Принятие суммы для изменения баланса пользователя +@dp.message_handler(IsAdmin(), state="here_profile_set") +async def functions_profile_balance_set_get(message: Message, state: FSMContext): + if message.text.isdigit(): + if 0 <= int(message.text) <= 1000000000: + user_id = (await state.get_data())['here_profile'] + await state.finish() + + get_user = get_userx(user_id=user_id) + update_userx(user_id, user_balance=message.text) + + await message.answer( + f"✅ Пользователю {get_user['user_name']} " + f"изменён баланс на {message.text}₽") + + await message.answer(open_profile_search(user_id), reply_markup=profile_search_finl(user_id)) + else: + await message.answer("❌ Сумма изменения не может быть меньше 0 и больше 1 000 000 000\n" + "💰 Введите сумму для изменения баланса") + else: + await message.answer("❌ Данные были введены неверно.\n" + "💰 Введите сумму для изменения баланса") + + +# Отправка сообщения пользователю +@dp.callback_query_handler(IsAdmin(), text_startswith="admin_user_message", state="*") +async def functions_profile_user_message(call: CallbackQuery, state: FSMContext): + await state.update_data(here_profile=call.data.split(":")[1]) + + await state.set_state("here_profile_message") + await call.message.edit_text("💌 Введите сообщение для отправки\n" + "⚠ Сообщение будет сразу отправлено пользователю.") + +# Принятие сообщения для пользователя +@dp.message_handler(IsAdmin(), state="here_profile_message") +async def functions_profile_user_message_get(message: Message, state: FSMContext): + user_id = (await state.get_data())['here_profile'] + await state.finish() + + get_message = "💌 Вам сообщение:\n" + clear_html(message.text) + get_user = get_userx(user_id=user_id) + + await message.bot.send_message(user_id, get_message) + await message.answer(f"✅ Пользователю {get_user['user_name']} " + f"было отправлено сообщение:\n" + f"{get_message}") + + await message.answer(open_profile_search(user_id), reply_markup=profile_search_finl(user_id)) + + +# Принятие чека для поиска +@dp.message_handler(IsAdmin(), state="here_receipt") +async def functions_receipt_search(message: Message, state: FSMContext): + receipt = message.text[1:] + + if message.text.startswith("#"): + get_refill = get_refillx(refill_receipt=receipt) + get_purchase = get_purchasex(purchase_receipt=receipt) + + if get_refill is not None: + await state.finish() + + if get_refill['refill_way'] == "Form": + way_input = "🥝 Способ пополнения: По форме" + elif get_refill['refill_way'] == "Nickname": + way_input = "🥝 Способ пополнения: По никнейму" + elif get_refill['refill_way'] == "Number": + way_input = "🥝 Способ пополнения: По номеру" + else: + way_input = f"🥝 Способ пополнения: {get_refill['refill_way']}" + + await message.answer( + f"🧾 Чек: #{get_refill['refill_receipt']}\n" + "➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"👤 Пользователь: {get_refill['user_name']} ({get_refill['user_id']})\n" + f"💰 Сумма пополнения: {get_refill['refill_amount']}₽\n" + f"{way_input}\n" + f"🏷 Комментарий: {get_refill['refill_comment']}\n" + f"🕰 Дата пополнения: {get_refill['refill_date']}" + ) + return + elif get_purchase is not None: + await state.finish() + + link_items = await upload_text(message, get_purchase['purchase_item']) + await message.answer( + f"🧾 Чек: #{get_purchase['purchase_receipt']}\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"👤 Пользователь: {get_purchase['user_name']} ({get_purchase['user_id']})\n" + f"🏷 Название товара: {get_purchase['purchase_position_name']}\n" + f"📦 Куплено товаров: {get_purchase['purchase_count']}шт\n" + f"💰 Цена 1-го товара: {get_purchase['purchase_price_one']}₽\n" + f"💸 Сумма покупки: {get_purchase['purchase_price']}₽\n" + f"🔗 Товары: кликабельно\n" + f"🔻 Баланс до покупки: {get_purchase['balance_before']}₽\n" + f"🔺 Баланс после покупки: {get_purchase['balance_after']}₽\n" + f"🕰 Дата покупки: {get_purchase['purchase_date']}" + ) + return + + await message.answer("❌ Чек не был найден.\n" + "🧾 Отправьте номер чека") diff --git a/TelegramGoodsinbot/tgbot/handlers/admin_menu.py b/TelegramGoodsinbot/tgbot/handlers/admin_menu.py new file mode 100644 index 0000000..77b11cb --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/admin_menu.py @@ -0,0 +1,88 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher import FSMContext +from aiogram.types import Message + +from tgbot.data.config import BOT_VERSION, PATH_LOGS, PATH_DATABASE +from tgbot.keyboards.reply_z_all import payments_frep, settings_frep, functions_frep, items_frep, seller_requests_frep +from tgbot.loader import dp +from tgbot.utils.const_functions import get_date +from tgbot.utils.misc.bot_filters import IsAdmin +from tgbot.utils.misc_functions import get_statisctics + + +# Платежные системы +@dp.message_handler(IsAdmin(), text="🔑 Платежные системы", state="*") +async def admin_payment(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🔑 Настройка платежных систем.", reply_markup=payments_frep()) + + +# Настройки бота +@dp.message_handler(IsAdmin(), text="⚙ Настройки", state="*") +async def admin_settings(message: Message, state: FSMContext): + await state.finish() + + await message.answer("⚙ Основные настройки бота.", reply_markup=settings_frep()) + + +# Запросы продавцов +@dp.message_handler(IsAdmin(), text="Запросы продавцов", state="*") +async def admin_requests(message: Message, state: FSMContext): + await state.finish() + + await message.answer("⚙ Запросы продавцов.", reply_markup=seller_requests_frep()) + + +# Общие функции +@dp.message_handler(IsAdmin(), text="🔆 Общие функции", state="*") +async def admin_functions(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🔆 Выберите нужную функцию.", reply_markup=functions_frep(message.from_user.id)) + + +# Управление товарами +@dp.message_handler(IsAdmin(), text="🎁 Управление товарами 🖍", state="*") +async def admin_products(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🎁 Редактирование товаров.", reply_markup=items_frep()) + + +# Cтатистики бота +@dp.message_handler(IsAdmin(), text="📊 Статистика", state="*") +async def admin_statistics(message: Message, state: FSMContext): + await state.finish() + + await message.answer(get_statisctics()) + + +# Получение БД +@dp.message_handler(IsAdmin(), commands=['db', 'database'], state="*") +async def admin_database(message: Message, state: FSMContext): + await state.finish() + + with open(PATH_DATABASE, "rb") as document: + await message.answer_document(document, + caption=f"📦 BACKUP\n" + f"🕰 {get_date()}") + + +# Получение Логов +@dp.message_handler(IsAdmin(), commands=['log', 'logs'], state="*") +async def admin_log(message: Message, state: FSMContext): + await state.finish() + + with open(PATH_LOGS, "rb") as document: + await message.answer_document(document, + caption=f"🖨 LOGS\n" + f"🕰 {get_date()}") + + +# Получение версии бота +@dp.message_handler(commands=['version', 'log'], state="*") +async def admin_version(message: Message, state: FSMContext): + await state.finish() + + await message.answer(f"❇ Текущая версия бота: {BOT_VERSION}") diff --git a/TelegramGoodsinbot/tgbot/handlers/admin_payment.py b/TelegramGoodsinbot/tgbot/handlers/admin_payment.py new file mode 100644 index 0000000..3176e86 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/admin_payment.py @@ -0,0 +1,219 @@ +# - *- coding: utf- 8 - *- +import asyncio + +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message + +from tgbot.keyboards.inline_admin import payment_choice_finl +from tgbot.loader import dp +from tgbot.services.api_qiwi import QiwiAPI +from tgbot.services.api_yoo import YooAPI +from tgbot.services.api_sqlite import update_paymentx, get_paymentx +from tgbot.utils.misc.bot_filters import IsAdmin + + +################################################################################### +############################# ВЫБОР СПОСОБА ПОПОЛНЕНИЯ ############################ +# Открытие способов пополнения +@dp.message_handler(IsAdmin(), text="🖲 Способы пополнения", state="*") +async def payment_systems(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🖲 Выберите способ пополнения", reply_markup=payment_choice_finl()) + + +# Включение/выключение самих способов пополнения +@dp.callback_query_handler(IsAdmin(), text_startswith="change_payment:") +async def payment_systems_edit(call: CallbackQuery): + way_pay = call.data.split(":")[1] + way_status = call.data.split(":")[2] + print(call.message.from_user.id) + get_payment = get_paymentx() + + if get_payment['qiwi_login'] != "None" and get_payment['qiwi_token'] != "None" or way_status == "False": + if way_pay == "Form": + if get_payment['qiwi_secret'] != "None" or way_status == "False": + update_paymentx(way_form=way_status) + else: + await call.answer( + "❗ Приватный ключ отсутствует. Измените киви и добавьте приватный ключ для включения оплаты по Форме", + True) + elif way_pay == "ForYm": + if get_payment['yoo_client_id'] != "None" or way_status == "False": + update_paymentx(way_formy=way_status) + else: + await call.answer( + "❗ Приватный ключ отсутствует. Измените киви и добавьте приватный ключ для включения оплаты по Форме", + True) + elif way_pay == "Number": + update_paymentx(way_number=way_status) + elif way_pay == "Nickname": + status, response = await (await QiwiAPI(call)).get_nickname() + if status: + update_paymentx(way_nickname=way_status, qiwi_nickname=response) + else: + await call.answer(response, True) + else: + await call.answer("❗ Добавьте киви кошелёк перед включением Способов пополнений.", True) + + try: + await call.message.edit_text("🖲 Выберите способ пополнения", reply_markup=payment_choice_finl()) + except: + pass + + +################################################################################### +####################################### QIWI ###################################### +# Изменение QIWI кошелька +@dp.message_handler(IsAdmin(), text="🥝 Изменить QIWI 🖍", state="*") +async def payment_qiwi_edit(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_qiwi_login") + await message.answer("🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Проверка работоспособности QIWI +@dp.message_handler(IsAdmin(), text="🥝 Проверить QIWI ♻", state="*") +async def payment_qiwi_check(message: Message, state: FSMContext): + print("||| Проверка КИВИ админом площадки. |||") + await state.finish() + + await (await QiwiAPI(message, check_pass=True)).pre_checker() + + +# Баланс QIWI +@dp.message_handler(IsAdmin(), text="🥝 Баланс QIWI 👁", state="*") +async def payment_qiwi_balance(message: Message, state: FSMContext): + await state.finish() + + await (await QiwiAPI(message)).get_balance() + +######################################## YooMoney ################################ +# Изменение реквизитов Yoo +@dp.message_handler(IsAdmin(), text="💳 Изменить Yoo 🖍", state="*") +async def payment_qiwi_edit(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_yoo_acc_number") + await message.answer("💳 Введите номер счета Yoo аккаунта 🖍") + + + + +######################################## ПРИНЯТИЕ QIWI ######################################## +# Принятие логина для QIWI +@dp.message_handler(IsAdmin(), state="here_qiwi_login") +async def payment_qiwi_edit_login(message: Message, state: FSMContext): + if message.text.startswith("+"): + await state.update_data(here_qiwi_login=message.text) + + await state.set_state("here_qiwi_token") + await message.answer( + "🥝 Введите токен API QIWI кошелька 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ При получении токена, ставьте только первые 3 галочки.", + disable_web_page_preview=True + ) + else: + await message.answer("❌ Номер должен начинаться с + (+7..., +380...)\n" + "🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Принятие acc_number для Yoo +@dp.message_handler(IsAdmin(), state="here_yoo_acc_number") +async def payment_qiwi_edit_login(message: Message, state: FSMContext): + #if message.text.startswith("+"): + await state.update_data(here_yoo_acc_number=message.text) + + await state.set_state("here_yoo_token") + await message.answer( + "🥝 Введите токен API Yoo кошелька 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ При получении токена, ставьте только первые 3 галочки.", + disable_web_page_preview=True + ) + #else: + #await message.answer("❌ Номер должен начинаться с + (+7..., +380...)\n" + # "🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Принятие токена для QIWI +@dp.message_handler(IsAdmin(), state="here_qiwi_token") +async def payment_qiwi_edit_token(message: Message, state: FSMContext): + await state.update_data(here_qiwi_token=message.text) + + await state.set_state("here_qiwi_secret") + await message.answer( + "🥝 Введите Секретный ключ 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ Вы можете пропустить добавление оплаты по Форме, отправив: 0", + disable_web_page_preview=True + ) + +# Принятие токена для Yoo +@dp.message_handler(IsAdmin(), state="here_yoo_token") +async def payment_qiwi_edit_token(message: Message, state: FSMContext): + await state.update_data(here_yoo_token=message.text) + + await state.set_state("here_yoo_client_id") + await message.answer( + "🥝 Введите Клиентский ID 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ Вы можете пропустить добавление оплаты по Форме, отправив: 0", + disable_web_page_preview=True + ) + +# Принятие клиентского ID для Yoo +@dp.message_handler(IsAdmin(), state="here_yoo_client_id") +async def payment_qiwi_edit_token(message: Message, state: FSMContext): + await state.update_data(here_yoo_client_id=message.text) + + await state.set_state("here_yoo_redirect_url") + await message.answer( + "🥝 Введите Redirect URL 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ Вы можете пропустить добавление оплаты по Форме, отправив: 0", + disable_web_page_preview=True + ) + + +# Принятие приватного ключа для QIWI +@dp.message_handler(IsAdmin(), state="here_qiwi_secret") +async def payment_qiwi_edit_secret(message: Message, state: FSMContext): + async with state.proxy() as data: + qiwi_login = data['here_qiwi_login'] + qiwi_token = data['here_qiwi_token'] + if message.text == "0": qiwi_secret = "None" + if message.text != "0": qiwi_secret = message.text + + await state.finish() + + cache_message = await message.answer("🥝 Проверка введённых QIWI данных... 🔄") + await asyncio.sleep(0.5) + + await (await QiwiAPI(cache_message, qiwi_login, qiwi_token, qiwi_secret, True)).pre_checker() + + +# Принятие приватного ключа для Yoo +@dp.message_handler(IsAdmin(), state="here_yoo_redirect_url") +async def payment_qiwi_edit_secret(message: Message, state: FSMContext): + async with state.proxy() as data: + acc_number = data['here_yoo_acc_number'] + token = data['here_yoo_token'] + client_id = data['here_yoo_client_id'] + if message.text == "0": redirect_url = "None" + if message.text != "0": redirect_url = message.text + + await state.finish() + + cache_message = await message.answer("🥝 Проверка введённых Yoo данных... 🔄") + await asyncio.sleep(0.5) + #await update_paymentx() + await (await YooAPI(acc_number, token, client_id, redirect_url)).update_yoo() + await message.answer( + "Данные yoomoney успешно обновлены!\n" + "❕ Вы можете пропустить добавление оплаты по Форме, отправив: 0", + disable_web_page_preview=True + ) + diff --git a/TelegramGoodsinbot/tgbot/handlers/admin_products.py b/TelegramGoodsinbot/tgbot/handlers/admin_products.py new file mode 100644 index 0000000..b2c1b21 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/admin_products.py @@ -0,0 +1,1068 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message +from aiogram.utils.exceptions import CantParseEntities + +from tgbot.keyboards.inline_admin import category_edit_open_finl, position_edit_open_finl, category_edit_delete_finl, \ + position_edit_clear_finl, position_edit_delete_finl +from tgbot.keyboards.inline_z_all import category_remove_confirm_inl, position_remove_confirm_inl, \ + item_remove_confirm_inl, close_inl +from tgbot.keyboards.inline_z_page import * +from tgbot.keyboards.reply_z_all import finish_load_rep, items_frep, items_sh_frep +from tgbot.loader import dp +from tgbot.middlewares.throttling import rate_limit +from tgbot.services.api_sqlite import * +from tgbot.utils.const_functions import clear_list +from tgbot.utils.misc.bot_filters import IsAdmin, IsShopAdmin, IsAdminorShopAdmin +from tgbot.utils.misc_functions import get_position_admin, upload_text +# Добавлено +from tgbot.keyboards.location_keyboards import geo_1_kb +from tgbot.services.location_function import update_position_city, get_city_info + + +# Создание новой категории +@dp.message_handler(IsAdmin(), text="🗃 Создать категорию ➕", state="*") +async def product_category_create(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_category_name") + await message.answer("🗃 Введите название для категории 🏷") + + +# Открытие страниц выбора категорий для редактирования +@dp.message_handler(IsAdmin(), text="🗃 Изменить категорию 🖍", state="*") +async def product_category_edit(message: Message, state: FSMContext): + await state.finish() + + if len(get_all_categoriesx()) >= 1: + await message.answer("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_open_fp(0)) + else: + await message.answer("🗃 Категории отсутствуют 🖍") + + +# Окно с уточнением удалить все категории (позиции и товары включительно) +@dp.message_handler(IsAdmin(), text="🗃 Удалить все категории ❌", state="*") +async def product_category_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🗃 Вы действительно хотите удалить все категории? ❌\n" + "❗ Так же будут удалены все позиции и товары", + reply_markup=category_remove_confirm_inl) + +# Начальные категории для изменения позиции + + +# !!!!!!! Изменить позицию +@dp.message_handler(IsAdmin(), text="📁 Изменить позицию 🖍", state="*") +async def product_position_edit(message: Message, state: FSMContext): + print(f'📁 Изменить позицию 🖍 admin_products.py 73') + await state.finish() + + await message.answer("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_open_fp(0)) + +# Подтверждение удаления всех позиций + + +@dp.message_handler(IsAdmin(), text="📁 Удалить все позиции ❌", state="*") +async def product_position_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("📁 Вы действительно хотите удалить все позиции? ❌\n" + "❗ Так же будут удалены все товары", + reply_markup=position_remove_confirm_inl) + +# Начальные категории для добавления товаров + + +@dp.message_handler(IsAdminorShopAdmin(), text="🎁 Добавить товары ➕", state="*") +async def product_item_create(message: Message, state: FSMContext): + print(f'🎁 Добавить товары ➕ admin_products_shop.py 93') + await state.finish() + + if len(get_all_positionsx()) >= 1: + await message.answer("🎁 Выберите категорию с нужной позицией", + reply_markup=products_add_category_open_fp(0)) + else: + await message.answer("❌ Отсутствуют позиции для добавления товара.") + + +# Удаление определённых товаров +@dp.message_handler(IsAdmin(), text="🎁 Удалить товары 🖍", state="*") +async def product_item_delete(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_items_delete") + await message.answer("🖍 Вводите айди товаров, которые нужно удалить\n" + "❕ Получить айди товаров можно при изменении позиции\n" + "❕ Если хотите удалить несколько товаров, отправьте ID товаров через запятую или пробел. Пример:\n" + "▶ 123456,123456,123456\n" + "▶ 123456 123456 123456") + + +# ------------------------------------------------------------------------------------------------------------------- +# Кнопки с подтверждением удаления всех категорий +@dp.message_handler(IsAdmin(), text="🎁 Удалить все товары ❌", state="*") +async def product_item_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🎁 Вы действительно хотите удалить все товары? ❌\n", + reply_markup=item_remove_confirm_inl) + + +################################################################################################ +####################################### СОЗДАНИЕ КАТЕГОРИЙ ##################################### +# Принятие названия категории для её создания +@dp.message_handler(IsAdmin(), state="here_category_name") +async def product_category_create_name(message: Message, state: FSMContext): + if len(message.text) <= 100: + add_categoryx(clear_html(message.text)) + + await state.finish() + await message.answer("🗃 Категория была успешно создана ✅") + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "🗃 Введите название для категории 🏷") + + +################################################################################################ +####################################### ИЗМЕНЕНИЕ КАТЕГОРИЙ #################################### +# Следующая страница выбора категорий для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="catategory_edit_nextp:", state="*") +async def product_category_edit_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_next_page_fp(remover)) + + +# Предыдущая страница выбора категорий для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="catategory_edit_backp:", state="*") +async def product_category_edit_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.delete() + await call.message.answer("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_back_page_fp(remover)) + + +# Выбор текущей категории для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_here:", state="*") +async def product_category_edit_open(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + get_fat_count = len(get_positionsx(category_id=category_id)) + get_category = get_categoryx(category_id=category_id) + + await call.message.edit_text(f"🗃 Категория: {get_category['category_name']}\n" + "➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"📁 Кол-во позиций: {get_fat_count}шт", + reply_markup=category_edit_open_finl(category_id, remover)) + + +# Возвращение к списку выбора категорий для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_return:", state="*") +async def product_category_edit_return(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_open_fp(remover)) + + +######################################## САМО ИЗМЕНЕНИЕ КАТЕГОРИИ ######################################## +# Изменение названия категории +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_name:", state="*") +async def product_category_edit_name(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_category_remover=remover) + + await state.set_state("here_change_category_name") + await call.message.delete() + await call.message.answer("🗃 Введите новое название для категории 🏷") + + +# Принятие нового имени для категории +@dp.message_handler(IsAdmin(), state="here_change_category_name") +async def product_category_edit_name_get(message: Message, state: FSMContext): + if len(message.text) <= 100: + async with state.proxy() as data: + category_id = data['here_cache_category_id'] + remover = data['here_cache_category_remover'] + await state.finish() + + update_categoryx(category_id, category_name=clear_html(message.text)) + + get_fat_count = len(get_positionsx(category_id=category_id)) + get_category = get_categoryx(category_id=category_id) + + await message.answer(f"🗃 Категория: {get_category['category_name']}\n" + "➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"📁 Кол-во позиций: {get_fat_count}шт", + reply_markup=category_edit_open_finl(category_id, remover)) + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "🗃 Введите новое название для категории 🏷") + + +# Окно с уточнением удалить категорию +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_delete:", state="*") +async def product_category_edit_delete(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + await call.message.edit_text("❗ Вы действительно хотите удалить категорию и все её данные?", + reply_markup=category_edit_delete_finl(category_id, remover)) + + +# Отмена удаления категории +@dp.callback_query_handler(IsAdmin(), text_startswith="category_delete:", state="*") +async def product_category_edit_delete_confirm(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + get_action = call.data.split(":")[2] + remover = int(call.data.split(":")[3]) + + if get_action == "yes": + remove_categoryx(category_id=category_id) + remove_positionx(category_id=category_id) + remove_itemx(category_id=category_id) + + await call.answer("🗃 Категория и все её данные были успешно удалены ✅") + if len(get_all_categoriesx()) >= 1: + await call.message.edit_text("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_open_fp(remover)) + else: + await call.message.delete() + else: + get_fat_count = len(get_positionsx(category_id=category_id)) + get_category = get_categoryx(category_id=category_id) + + await call.message.edit_text(f"🗃 Категория: {get_category['category_name']}\n" + "➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"📁 Кол-во позиций: {get_fat_count}шт", + reply_markup=category_edit_open_finl(category_id, remover)) + + +################################################################################################ +#################################### УДАЛЕНИЕ ВСЕХ КАТЕГОРИЙ ################################### +# Подтверждение на удаление всех категорий (позиций и товаров включительно) +@dp.callback_query_handler(IsAdmin(), text_startswith="confirm_remove_category:", state="*") +async def product_category_remove_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + + if get_action == "yes": + get_categories = len(get_all_categoriesx()) + get_positions = len(get_all_positionsx()) + get_items = len(get_all_itemsx()) + + clear_categoryx() + clear_positionx() + clear_itemx() + + await call.message.edit_text( + f"🗃 Вы удалили все категории({get_categories}шт), " + f"позиции({get_positions}шт) и товары({get_items}шт)") + else: + await call.message.edit_text("🗃 Вы отменили удаление всех категорий ✅") + + +################################################################################################ +####################################### ДОБАВЛЕНИЕ ПОЗИЦИЙ ##################################### +# Следующая страница выбора категорий для создания позиций +@dp.callback_query_handler(IsAdmin(), text_startswith="position_create_nextp:", state="*") +async def product_position_create_next(call: CallbackQuery, state: FSMContext): + print(f'выбора категорий для создания позиций admin_products_shop.py 300') + remover = int(call.data.split(":")[1]) + print(remover) + + await call.message.edit_text("📁 Выберите категорию для позиции ➕", + reply_markup=position_create_next_page_fp(remover)) + + +# Предыдущая страница выбора категорий для создания позиций +@dp.callback_query_handler(IsAdmin(), text_startswith="position_create_backp:", state="*") +async def product_position_create_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию для позиции ➕", + reply_markup=position_create_back_page_fp(remover)) + + +@dp.callback_query_handler(IsAdmin(), text_startswith="position_shop_create_here:", state="*") +async def product_position_create(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + await state.update_data(here_cache_change_shop_id=category_id) + + if len(get_all_categoriesx()) >= 1: + await call.message.answer("📁 Выберите категорию для позиции", + reply_markup=position_create_open_fp(0)) + else: + await call.message.answer("❌ Отсутствуют категории для создания позиции.") + + +# Выбор категории для создания позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_create_here:", state="*") +async def product_position_create_select_category(call: CallbackQuery, state: FSMContext): + print('position_create_here - admin_products') + category_id = int(call.data.split(":")[1]) + print(category_id) + + await state.update_data(here_cache_change_category_id=category_id) + + await state.set_state("here_position_name") + await call.message.edit_text("📁 Введите название для позиции 🏷") + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Заготовка под принятие города магазином +# Принятие города для создания позиции +# @dp.message_handler(IsAdmin(), state="here_position_city") +# async def product_position_create_name(message: Message, state: FSMContext): +# print(f'Принятие города для создания позиции admin_products_shop.py 344') +# city_user = get_city_user(message.from_user.id) + +# Принятие имени для создания позиции + + +@dp.message_handler(IsAdmin(), state="here_position_name") +async def product_position_create_name(message: Message, state: FSMContext): + print(f'Принятие имени для создания позиции admin_products.py 355') + if len(message.text) <= 100: + await state.update_data(here_position_name=clear_html(message.text), here_position_city=get_city_user(message.from_user.id)[0], position_city_id=get_city_user(message.from_user.id)[0]) + + await state.set_state("here_position_price") + await message.answer("📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "📁 Введите название для позиции 🏷") + + +# Принятие цены позиции для её создания +@dp.message_handler(IsAdmin(), state="here_position_price") +async def product_position_create_price(message: Message, state: FSMContext): + print(f'Принятие цены позиции admin_products.py 366') + if message.text.isdigit(): + if 0 <= int(message.text) <= 10000000: + await state.update_data(here_position_price=message.text) + + await state.set_state("here_position_description") + await message.answer("📁 Введите описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + else: + await message.answer("❌ Цена не может быть меньше 0 или больше 10 000 000.\n" + "📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Данные были введены неверно.\n" + "📁 Введите цену для позиции 💰") + + +# Принятие описания позиции для её создания +@dp.message_handler(IsAdmin(), state="here_position_description") +async def product_position_create_description(message: Message, state: FSMContext): + print(f'Принятие описания позиции admin_products.py 386') + + try: + if len(message.text) <= 600: + if message.text != "0": + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + await state.update_data(here_position_description=message.text) + + await state.set_state("here_position_photo") + await message.answer("📁 Отправьте изображение для позиции 📸\n" + "❕ Отправьте 0 чтобы пропустить.") + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📁 Введите описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие изображения позиции для её создания +@dp.message_handler(IsAdmin(), content_types="photo", state="here_position_photo") +@dp.message_handler(IsAdmin(), text="0", state="here_position_photo") +async def product_position_create_photo(message: Message, state: FSMContext): + print(f'Принятие изображения позиции admin_products.py 418') + async with state.proxy() as data: + position_user_id = message.from_user.id + position_city = data['here_position_city'] + position_city_id = data['position_city_id'] + position_name = clear_html(data['here_position_name']) + position_price = data['here_position_price'] + catategory_id = data['here_cache_change_category_id'] + position_description = data['here_position_description'] + await state.finish() + + if "text" in message: + position_photo = "" + else: + position_photo = message.photo[-1].file_id + + add_positionx(position_city, position_city_id, position_name, position_price, + position_description, position_photo, catategory_id, position_user_id) + + await message.answer("📁 Позиция была успешно создана ✅") + + +################################################################################################ +####################################### ИЗМЕНЕНИЕ ПОЗИЦИЙ ##################################### +# Возвращение к начальным категориям для редактирования позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_category_return", state="*") +async def product_position_edit_return(call: CallbackQuery, state: FSMContext): + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_open_fp(0)) + + +# Следующая страница категорий для редактирования позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_category_nextp:", state="*") +async def product_position_edit_category_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_next_page_fp(remover)) + + +# Предыдущая страница категорий для редактирования позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_category_backp:", state="*") +async def product_position_edit_category_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_back_page_fp(remover)) + + +# Выбор категории с нужной позицией +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_category:", state="*") +async def product_position_edit_category_open(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.edit_text("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(0, category_id)) + else: + await call.answer("📁 Позиции в данной категории отсутствуют") + + +# Следующая страница позиций для их изменения +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_nextp:", state="*") +async def product_position_edit_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_next_page_fp(remover, category_id)) + + +# Предыдущая страница позиций для их изменения +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_backp:", state="*") +async def product_position_edit_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_back_page_fp(remover, category_id)) + + +# Выбор позиции для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit:", state="*") +async def product_position_edit_open(call: CallbackQuery, state: FSMContext): + print(f'Выбор позиции для редактирования api_sqlite.py 496') + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Возвращение к выбору позиции для изменения +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_return", state="*") +async def product_position_edit_return(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.delete() + await call.message.answer("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(remover, category_id)) + else: + await call.answer("❗ Позиции в данной категории отсутствуют") + + +######################################## САМО ИЗМЕНЕНИЕ ПОЗИЦИИ ######################################## +# Изменение имени позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_name", state="*") +async def product_position_edit_name(call: CallbackQuery, state: FSMContext): + print(f'Изменение имени позиции api_sqlite.py 529') + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_name") + await call.message.delete() + await call.message.answer("📁 Введите новое название для позиции 🏷") + + +# Принятие имени позиции для её изменения +@dp.message_handler(IsAdmin(), state="here_change_position_name") +async def product_position_edit_name_get(message: Message, state: FSMContext): + if len(message.text) <= 100: + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + update_positionx(position_id, position_name=clear_html(message.text)) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "📁 Введите новое название для позиции 🏷") + + +# Изменение цены позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_price", state="*") +async def product_position_edit_price(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_price") + await call.message.delete() + await call.message.answer("📁 Введите новую цену для позиции 💰") + + +# Принятие цены позиции для её изменения +@dp.message_handler(IsAdmin(), state="here_change_position_price") +async def product_position_edit_price_get(message: Message, state: FSMContext): + if message.text.isdigit(): + if 0 <= int(message.text) <= 10000000: + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + update_positionx(position_id, position_price=message.text) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Цена не может быть меньше 0 или больше 10 000 000.\n" + "📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Данные были введены неверно.\n" + "📁 Введите цену для позиции 💰") + + +# Изменение описания позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_description", state="*") +async def product_position_edit_description(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_description") + await call.message.delete() + await call.message.answer("📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие описания позиции для её изменения +@dp.message_handler(IsAdmin(), state="here_change_position_description") +async def product_position_edit_description_get(message: Message, state: FSMContext): + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + + try: + if len(message.text) <= 600: + await state.finish() + + if message.text != "0": + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + update_positionx(position_id, position_description=message.text) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Изменение изображения позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_photo", state="*") +async def product_position_edit_photo(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_photo") + await call.message.delete() + await call.message.answer("📁 Отправьте новое изображение для позиции 📸\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие нового фото для позиции +@dp.message_handler(IsAdmin(), content_types="photo", state="here_change_position_photo") +@dp.message_handler(IsAdmin(), text="0", state="here_change_position_photo") +async def product_position_edit_photo_get(message: Message, state: FSMContext): + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + if "text" in message: + position_photo = "" + else: + position_photo = message.photo[-1].file_id + + update_positionx(position_id, position_photo=position_photo) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# --------------------------- Добавлено 12.08.22 ------------------------------------------ + +# Изменение города продукта +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_city", state="*") +async def product_position_edit_description(call: CallbackQuery, state: FSMContext): + print(f'Изменение города продукта admin_products.py 715') + print(call.data) + category_id = int(call.data.split(":")[2]) + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[3]) + + current_city = get_city_user(call.from_user.id)[0] + + # await state.update_data(here_cache_category_id=category_id) + # await state.update_data(here_cache_position_id=position_id) + # await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_city") + await state.update_data({'position_id': position_id, 'category_id': category_id, 'remover': remover}) + await call.message.delete() + await call.message.answer("📁 Выбирите другой город 🏙\n" + "❕ Вы можете использовать геолокацию или выбрать город из списка\n" + f"❕ Город товара: {current_city}", reply_markup=geo_1_kb()) + + +# принятие новой геопозиции для позиции +@dp.callback_query_handler(text_startswith='geo_chosen_cities', state='here_change_city') +async def geo_5(cb: CallbackQuery, state: FSMContext): + info = int(str(cb.data).split('#')[1]) + if info == 0: + async with state.proxy() as data: + city = data['city'] + position_id = int(data['position_id']) + category_id = data['category_id'] + remover = data['remover'] + city_id = data['city_id'] + + else: + async with state.proxy() as data: + position_id = int(data['position_id']) + category_id = data['category_id'] + remover = data['remover'] + + city_id = info + city = get_city_info(info) + + await state.finish() + update_position_city(city[0], city_id, position_id) + + # update_positionx(position_id) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await cb.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await cb.message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Выгрузка товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_items", state="*") +async def product_position_edit_items(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + save_items = ['АйдиТовара - Данные товара', + "================================"] + + if len(get_items) >= 1: + for item in get_items: + save_items.append(f"{item['item_id']} - {item['item_data']}") + save_items = "\n".join(save_items) + + save_items = await upload_text(call, save_items) + await call.message.answer(f"📥 Все товары позиции: {get_position['position_name']}\n" + f"🔗 Ссылка: кликабельно", + reply_markup=close_inl) + await call.answer() + else: + await call.answer("❕ В данной позиции отсутствуют товары", True) + + +# Удаление позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_delete", state="*") +async def product_position_edit_delete(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await call.message.delete() + await call.message.answer("📁 Вы действительно хотите удалить позицию? ❌", + reply_markup=position_edit_delete_finl(position_id, category_id, remover)) + + +# Подтверждение удаления позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_delete", state="*") +async def product_position_edit_delete_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + remover = int(call.data.split(":")[4]) + + if get_action == "yes": + remove_itemx(position_id=position_id) + remove_positionx(position_id=position_id) + + await call.answer("📁 Вы успешно удалили позицию и её товары ✅") + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.edit_text("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(remover, category_id)) + else: + await call.message.delete() + else: + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Очистка позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_clear", state="*") +async def product_position_edit_clear(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await call.message.delete() + await call.message.answer("📁 Вы хотите удалить все товары позиции?", + reply_markup=position_edit_clear_finl(position_id, category_id, remover)) + + +# Согласие очистики позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_clear", state="*") +async def product_position_edit_clear_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + remover = int(call.data.split(":")[4]) + + if get_action == "yes": + remove_itemx(position_id=position_id) + await call.answer("📁 Вы успешно удалили все товары позиции ✅") + + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +################################################################################################ +###################################### УДАЛЕНИЕ ВСЕХ ПОЗИЦИЙ ################################### +# Согласие на удаление всех позиций и товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="confirm_remove_position:", state="*") +async def product_position_remove(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + + if get_action == "yes": + get_positions = len(get_all_positionsx()) + get_items = len(get_all_itemsx()) + + clear_positionx() + clear_itemx() + + await call.message.edit_text( + f"📁 Вы удалили все позиции({get_positions}шт) и товары({get_items}шт)") + else: + await call.message.edit_text("📁 Вы отменили удаление всех позиций ✅") + + +################################################################################################ +####################################### ДОБАВЛЕНИЕ ТОВАРОВ ##################################### +# Возвращение к начальным категориям для добавления товаров +@dp.callback_query_handler(IsAdminorShopAdmin(), text_startswith="back_add_products_to_category", state="*") +async def product_item_create(call: CallbackQuery, state: FSMContext): + await call.message.edit_text("🎁 Выберите категорию с нужной позицией", + reply_markup=products_add_category_open_fp(0)) + + +# Следующая страница выбора категории с позицией для добавления товаров +@dp.callback_query_handler(IsAdminorShopAdmin(), text_startswith="products_add_category_nextp", state="*") +async def product_item_load_category_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.delete() + await call.message.answer("🎁 Выберите категорию с нужной позицией", + reply_markup=products_add_category_next_page_fp(remover)) + + +# Предыдущая страница выбора категории с позицией для добавления товаров +@dp.callback_query_handler(IsAdminorShopAdmin(), text_startswith="products_add_category_backp", state="*") +async def product_item_load_category_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.delete() + await call.message.answer("🎁 Выберите категорию с нужной позицией", + reply_markup=products_add_category_back_page_fp(remover)) + + +# Выбор категории с нужной позицией +@dp.callback_query_handler(IsAdminorShopAdmin(), text_startswith="products_add_category", state="*") +async def product_item_load_category_open(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.delete() + await call.message.answer("🎁 Выберите нужную вам позицию", + reply_markup=products_add_position_open_fp(0, category_id)) + else: + await call.answer("🎁 Позиции в данной категории отсутствуют") + + +# Следующая страница позиций для добавления товаров +@dp.callback_query_handler(IsAdminorShopAdmin(), text_startswith="products_add_position_nextp", state="*") +async def product_item_load_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("🎁 Выберите нужную вам позицию", + reply_markup=products_add_position_next_page_fp(remover, category_id)) + + +# Предыдущая страница позиций для добавления товаров +@dp.callback_query_handler(IsAdminorShopAdmin(), text_startswith="products_add_position_backp", state="*") +async def product_item_load_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("🎁 Выберите нужную вам позицию", + reply_markup=products_add_position_back_page_fp(remover, category_id)) + + +# Выбор позиции для добавления товаров +@rate_limit(0) +@dp.callback_query_handler(IsAdminorShopAdmin(), text_startswith="products_add_position:", state="*") +async def product_item_load_open(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await state.update_data(here_cache_add_item_category_id=category_id) + await state.update_data(here_cache_add_item_position_id=position_id) + await state.update_data(here_count_add_items=0) + + await state.set_state("here_add_items") + await call.message.delete() + await call.message.answer("📤 Отправьте данные товаров (доступы для входа).\n" + "❗ Товары разделяются одной пустой строчкой. Пример:\n" + "Логин:... Пароль...\n\n" + "Логин:... Пароль...\n\n" + "Логин:... Пароль...", + reply_markup=finish_load_rep) + + +# Завершение загрузки товаров +@rate_limit(0) +@dp.message_handler(IsAdminorShopAdmin(), text="📥 Закончить загрузку товаров", state="*") +async def product_item_load_finish(message: Message, state: FSMContext): + get_all_items = 0 + try: + async with state.proxy() as data: + get_all_items = data['here_count_add_items'] + except: + pass + + await state.finish() + user_id = message.from_user.id + ur = get_userx(user_id=user_id)['user_role'] + if ur == 'ShopAdmin': + await message.answer("📥 Загрузка товаров была успешно завершена ✅\n" + f"▶ Загружено товаров: {get_all_items}шт", + reply_markup=items_sh_frep()) + else: + await message.answer("📥 Загрузка товаров была успешно завершена ✅\n" + f"▶ Загружено товаров: {get_all_items}шт", + reply_markup=items_frep()) + + + +# Принятие данных товара +@rate_limit(0) +@dp.message_handler(IsAdminorShopAdmin(), state="here_add_items") +async def product_item_load_get(message: Message, state: FSMContext): + cache_msg = await message.answer("⌛ Ждите, товары добавляются...") + + count_add = 0 + get_all_items = clear_list(message.text.split("\n\n")) + + for check_item in get_all_items: + if not check_item.isspace() and check_item != "": + count_add += 1 + + async with state.proxy() as data: + category_id = data['here_cache_add_item_category_id'] + position_id = data['here_cache_add_item_position_id'] + data['here_count_add_items'] += count_add + + get_user = get_userx(user_id=message.from_user.id) + add_itemx(category_id, position_id, get_all_items, + get_user['user_id'], get_user['user_name']) + + await cache_msg.edit_text(f"📥 Товары в кол-ве {count_add}шт были успешно добавлены ✅") + + +################################################################################################ +####################################### УДАЛЕНИЕ ТОВАРОВ ###################################### +# Принятие айди товаров для их удаления +@dp.message_handler(IsAdmin(), state="here_items_delete") +async def product_item_delete_get(message: Message, state: FSMContext): + await state.finish() + + remove_ids, cancel_ids = [], [] # Айди удалённых и ненайденных товаров + get_item_ids_one, get_item_ids_two = [], [[]] + save_ids = [] + + if "," in message.text: + get_item_ids_one = clear_list(message.text.split(",")) + else: + get_item_ids_one = clear_list([message.text]) + + for item in get_item_ids_one: + if " " in item: + get_item_ids_two.append(item.split(" ")) + + if len(get_item_ids_two) == 1: + get_item_ids_two.append(get_item_ids_one) + + for check_item in get_item_ids_two: + for item in clear_list(check_item): + save_ids.append(item) + + save_ids = clear_list(save_ids) + + for item_id in save_ids: + check_item = get_itemx(item_id=item_id) + if check_item is not None: + remove_itemx(item_id=item_id) + remove_ids.append(item_id) + else: + cancel_ids.append(item_id) + + remove_ids = ", ".join(remove_ids) + cancel_ids = ", ".join(cancel_ids) + + await message.answer(f"✅ Успешно удалённые товары:\n" + f"▶ {remove_ids}\n" + f"➖➖➖➖➖➖➖➖➖➖\n" + f"❌ Ненайденные товары:\n" + f"▶ {cancel_ids}") + + +################################################################################################ +##################################### УДАЛЕНИЕ ВСЕХ ТОВАРОВ #################################### +# Согласие на удаление всех товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="confirm_remove_item:", state="*") +async def product_item_remove(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + + if get_action == "yes": + get_items = len(get_all_itemsx()) + clear_itemx() + + await call.message.edit_text(f"🎁 Вы удалили все товары({get_items}шт)") + else: + await call.message.edit_text("🎁 Вы отменили удаление всех товаров ✅") diff --git a/TelegramGoodsinbot/tgbot/handlers/admin_products_shop.py b/TelegramGoodsinbot/tgbot/handlers/admin_products_shop.py new file mode 100644 index 0000000..125606f --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/admin_products_shop.py @@ -0,0 +1,298 @@ +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message +from aiogram.utils.exceptions import CantParseEntities + +from tgbot.keyboards.inline_admin import category_edit_open_finl, position_edit_open_finl, category_edit_delete_finl, \ + position_edit_clear_finl, position_edit_delete_finl +from tgbot.keyboards.inline_z_all import category_remove_confirm_inl, position_remove_confirm_inl, \ + item_remove_confirm_inl, close_inl +from tgbot.keyboards.shop_keyboards import * +from tgbot.keyboards.reply_z_all import finish_load_rep, items_frep +from tgbot.keyboards.inline_z_page import position_create_open_fp +from tgbot.loader import dp +from tgbot.middlewares.throttling import rate_limit +from tgbot.services.api_sqlite_shop import * +from tgbot.services.api_sqlite import get_city_user, check_user_shop_exist +from tgbot.utils.const_functions import clear_list +from tgbot.utils.misc.bot_filters import IsAdmin, IsShopAdmin, IsAdminorShopAdmin +from tgbot.utils.misc_functions import get_position_admin, upload_text + + + +# -------------------------------------------------------------------------------------------------------- +# Создание нового магазина +@dp.message_handler(IsShopAdmin(), text="🏪 Создать магазин ➕", state="*") +async def product_category_create(message: Message, state: FSMContext): + await state.finish() + print("admin_products_shop - создание магазина") + user_id=message.from_user.id + if check_user_shop_exist(user_id): + await message.answer("🏪 Магазин уже существует 🏷", parse_mode='HTML') + else: + await state.set_state("here_shop_name") + await message.answer("🏪 Введите название для магазина 🏷", parse_mode='HTML') + + +# принятие названия магазина, запрос описания +@dp.message_handler(IsAdmin(), state="here_shop_name") +async def product_category_create_name(message: Message, state: FSMContext): + if len(message.text) <= 100: + + print("admin_products_shop - создание магазина") + await state.update_data(data={'name': message.text}) + await state.set_state('here_shop_description') + await message.answer("🏪 Введите описание для магазина 📜\n" + "❕ Отправьте 0 чтобы пропустить.", parse_mode='HTML') + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "🏪 Введите название для магазина 🏷", parse_mode='HTML') + + +# принятие описания магазина, запрос адреса +@dp.message_handler(IsAdmin(), state="here_shop_description") +async def product_category_create_name(message: Message, state: FSMContext): + if len(message.text) <= 600: + if message.text == '0': + await state.update_data(data={'description': 'None'}) + else: + await state.update_data(data={'description': message.text}) + await state.set_state('here_shop_adress') + await message.answer("🏪 Отправьте адресс магазина 📍\n" + "❕ Отправьте 0 чтобы пропустить.", parse_mode='HTML') + + + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "🏪 Введите новое описание для магазина 📜\n" + "❕ Отправьте 0 чтобы пропустить.", parse_mode='HTML') + + +# принятие адреса магазина, запрос номера +@dp.message_handler(IsAdmin(), state="here_shop_adress") +async def product_category_create_name(message: Message, state: FSMContext): + if message.text == '0': + await state.update_data(data={'address': 'None'}) + else: + await state.update_data(data={'address': message.text}) + await state.set_state('here_shop_phone') + await message.answer("🏪 Отправьте телефон магазина ☎️\n" + "❕ Отправьте 0 чтобы пропустить.", parse_mode='HTML') + + +# принятие номера магазина, запрос лого +@dp.message_handler(IsAdmin(), state="here_shop_phone") +async def product_category_create_name(message: Message, state: FSMContext): + if message.text == '0': + await state.update_data(data={'phone': 'None'}) + else: + await state.update_data(data={'phone': message.text}) + await state.set_state('here_shop_logo') + await message.answer("🏪 Отправьте лого магазина 📷\n" + "❕ Отправьте 0 чтобы пропустить.", parse_mode='HTML') + + +# принятие лого магазина, запрос лого +@dp.message_handler(IsAdmin(), content_types=['photo','text'], state="here_shop_logo") +async def product_category_create_name(message: Message, state: FSMContext): + if message.content_type == 'photo': + logo = message.photo[0].file_id + else: + logo = None + + async with state.proxy() as data: + print(data) + name = data['name'] + description = data['description'] + address = data['address'] + phone = data['phone'] + + await state.finish() + + city = get_city_user(message.from_user.id) + add_shopx(name, description, address, phone, message.from_user.id, logo, city[0], city[1], city[2]) + await message.answer("🏪 Магазин был успешно создан ✅", parse_mode='HTML') + +################################################################################################ +####################################### СОЗДАНИЕ МАГАЗИНА ##################################### +# Принятие названия магазина для её создания +@dp.message_handler(IsAdmin(), state="here_shop_name") +async def product_category_create_name(message: Message, state: FSMContext): + if len(message.text) <= 100: + add_shopx(clear_html(message.text)) + + await state.finish() + await message.answer("🏪 Магазин был успешно создан ✅") + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "🏪 Введите название для магазина 🏷") + + +# ----------------------------------------------------------------------------------------------------------- +# Открытие страниц выбора магазина для редактирования +@dp.message_handler(IsAdmin(), text="🏪 Изменить магазин 🖍", state="*") +async def product_category_edit(message: Message, state: FSMContext): + await state.finish() + + shops = get_all_shopx() + print(f'shops {shops}') + + if len(shops) >= 1: + await message.answer("🏪 Выберите магазин для изменения 🖍", + reply_markup=shop_edit_open_fp(0, shops)) + else: + await message.answer("🏪 Магазины отсутствуют 🖍") + + +# ----------------------------------------------------------------------------------------------------------- +# Открытие страниц выбора магазина для редактирования +@dp.message_handler(IsShopAdmin(), text="🏪 Изменить магазин 🖍", state="*") +async def product_category_edit(message: Message, state: FSMContext): + await state.finish() + user_id=message.from_user.id + #if get_my_shopx(user_id): + #shops = get_all_shopx() + print(f'shops {shops}') + shops = get_my_shopx(user_id) + print(shops) + + if len(shops) >= 1: + await message.answer("🏪 Выберите магазин для изменения 🖍", + reply_markup=shop_edit_open_fp(0, shops)) + else: + await message.answer("🏪 Магазины отсутствуют 🖍") + + +# Смена страницы выбора магазина +@dp.message_handler(IsAdmin(), text_startswith="change_shop_edit_pg:", state="*") +async def product_category_edit(call: CallbackQuery, state: FSMContext): + await state.finish() + page = int(str(call.data).split(':')[1]) + shops = get_all_shopx() + + + if len(shops) >= 1: + await call.message.answer("🏪 Выберите магазин для изменения 🖍", + reply_markup=shop_edit_open_fp(page, shops)) + else: + await call.message.answer("🏪 Магазины отсутствуют 🖍") + + + +# Выбор магазина для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="shop_edit_here:", state="*") +async def product_category_edit_open(call: CallbackQuery, state: FSMContext): + shop_id = int(call.data.split(":")[1]) + shop = get_the_shop(shop_id) + + text = f"🎁 Редактировать магазин:\n➖➖➖➖➖➖➖➖➖➖➖➖➖\n🏷 Название: {shop[1]}\n" \ + f"🏙 Город: {shop[7]}\n🗃 Адрес: {shop[4]}\n" \ + f"💰 Телефон: {shop[5]}₽\n{shop[3]}" + + if shop[6] is None: + await call.message.answer(text, parse_mode='HTML') + + else: + await call.message.answer_photo(text, parse_mode='HTML') + + + +################################ Добавление магазина при создании позиции ######################## + +# Создание новой позиции +@dp.message_handler(IsAdminorShopAdmin(), text="📁 Создать позицию ➕", state="*") +async def product_position_create(message: Message, state: FSMContext): + await state.finish() + print("APS 182") + + #if len(get_all_shopx()) >= 1: + await message.answer("📁 Выберите категорию для позиции", + reply_markup=position_create_open_fp(0)) + #else: + #await message.answer("❌ Отсутствуют магазины для создания позиции.") + + +######################################## САМО ИЗМЕНЕНИЕ МАГАЗИНОВ ######################################## +# Изменение названия магазина +@dp.callback_query_handler(IsAdmin(), text_startswith="shop_edit_name:", state="*") +async def product_category_edit_name(call: CallbackQuery, state: FSMContext): + shop_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + await state.update_data(here_cache_shop_id=shop_id) + await state.update_data(here_cache_shop_remover=remover) + + await state.set_state("here_change_shop_name") + await call.message.delete() + await call.message.answer("🗃 Введите новое название для магазина 🏷") + + +# Принятие нового имени для магазина +@dp.message_handler(IsAdmin(), state="here_change_shop_name") +async def product_shop_edit_name_get(message: Message, state: FSMContext): + if len(message.text) <= 100: + async with state.proxy() as data: + shop_id = data['here_cache_shop_id'] + remover = data['here_cache_shop_remover'] + await state.finish() + + update_shopx(shop_id, shop_name=clear_html(message.text)) + + get_fat_count = len(get_positionsx(shop_id=shop_id)) + get_shop = get_shopx(shop_id=shop_id) + + await message.answer(f"🗃 Категория: {get_shop['category_name']}\n" + "➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"📁 Кол-во позиций: {get_fat_count}шт", + reply_markup=shop_edit_open_finl(shop_id, remover)) + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "🗃 Введите новое название для магазина 🏷") + + + +# ------------------------------------------------------------------------------------------------------------- +# Окно с уточнением удалить все магазины (позиции и товары включительно) +@dp.message_handler(IsAdmin(), text="🏪 Удалить все магазины ❌", state="*") +async def product_category_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🗃 Вы действительно хотите удалить все магазины? ❌\n" + "❗ Так же будут удалены все позиции и товары", + reply_markup=category_remove_confirm_inl) + + + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +################################################################################################ +####################################### ИЗМЕНЕНИЕ МАГАЗИНА #################################### +# Следующая страница выбора магазина для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="catategory_edit_nextp:", state="*") +async def product_category_edit_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_next_page_fp(remover)) + + +# Предыдущая страница выбора категорий для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="catategory_edit_backp:", state="*") +async def product_category_edit_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.delete() + await call.message.answer("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_back_page_fp(remover)) + + + + +# Возвращение к списку выбора категорий для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_return:", state="*") +async def product_category_edit_return(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_open_fp(remover)) + + diff --git a/TelegramGoodsinbot/tgbot/handlers/admin_settings.py b/TelegramGoodsinbot/tgbot/handlers/admin_settings.py new file mode 100644 index 0000000..d1079b3 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/admin_settings.py @@ -0,0 +1,169 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message +from aiogram.utils.exceptions import CantParseEntities + +from tgbot.keyboards.inline_admin import turn_open_finl, settings_open_finl +from tgbot.loader import dp +from tgbot.services.api_sqlite import * +from tgbot.utils.misc.bot_filters import IsAdmin +from tgbot.utils.misc_functions import send_admins, get_faq + + +# Изменение данных +@dp.message_handler(IsAdmin(), text="🖍 Изменить данные", state="*") +async def settings_data_edit(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🖍 Изменение настроек бота.", reply_markup=settings_open_finl()) + + +# Выключатели бота +@dp.message_handler(IsAdmin(), text="🕹 Выключатели", state="*") +async def settings_turn_edit(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🕹 Включение и выключение основных функций", reply_markup=turn_open_finl()) + + +######################################## ВЫКЛЮЧАТЕЛИ ######################################## +# Включение/выключение тех работ +@dp.callback_query_handler(IsAdmin(), text_startswith="turn_twork", state="*") +async def settings_turn_twork(call: CallbackQuery, state: FSMContext): + get_status = call.data.split(":")[1] + + get_user = get_userx(user_id=call.from_user.id) + update_settingsx(status_work=get_status) + + if get_status == "True": + send_text = "🔴 Отправил бота на технические работы." + else: + send_text = "🟢 Вывел бота из технических работ." + + await send_admins( + f"👤 Администратор {get_user['user_name']}\n" + f"{send_text}", not_me=get_user['user_id']) + + await call.message.edit_reply_markup(reply_markup=turn_open_finl()) + + +# Включение/выключение покупок +@dp.callback_query_handler(IsAdmin(), text_startswith="turn_buy", state="*") +async def settings_turn_buy(call: CallbackQuery, state: FSMContext): + get_status = call.data.split(":")[1] + + get_user = get_userx(user_id=call.from_user.id) + update_settingsx(status_buy=get_status) + + if get_status == "True": + send_text = "🟢 Включил покупки в боте." + else: + send_text = "🔴 Выключил покупки в боте." + + await send_admins( + f"👤 Администратор {get_user['user_name']}\n" + f"{send_text}", not_me=get_user['user_id']) + + await call.message.edit_reply_markup(reply_markup=turn_open_finl()) + + +# Включение/выключение пополнений +@dp.callback_query_handler(IsAdmin(), text_startswith="turn_pay", state="*") +async def settings_turn_pay(call: CallbackQuery, state: FSMContext): + get_status = call.data.split(":")[1] + + get_user = get_userx(user_id=call.from_user.id) + update_settingsx(status_refill=get_status) + + if get_status == "True": + send_text = "🟢 Включил пополнения в боте." + else: + send_text = "🔴 Выключил пополнения в боте." + + await send_admins( + f"👤 Администратор {get_user['user_name']}\n" + f"{send_text}", not_me=get_user['user_id']) + + await call.message.edit_reply_markup(reply_markup=turn_open_finl()) + + +######################################## ИЗМЕНЕНИЕ ДАННЫХ ######################################## +# Изменение поддержки +@dp.callback_query_handler(IsAdmin(), text_startswith="settings_edit_support", state="*") +async def settings_support_edit(call: CallbackQuery, state: FSMContext): + await state.set_state("here_settings_support") + await call.message.edit_text("☎ Отправьте ID пользователя.\n" + "❕ Вводимый ID должен быть пользователем бота.") + +# Изменение типа площадки +@dp.callback_query_handler(IsAdmin(), text_startswith="settings_edit_type_trade", state="*") +async def settings_type_trade_edit(call: CallbackQuery, state: FSMContext): + await state.set_state("here_settings_trade_type") + await call.message.edit_text("ℹ Выберите тип площадки: real | digital | hybrid\n") + +# Изменение FAQ +@dp.callback_query_handler(IsAdmin(), text_startswith="settings_edit_faq", state="*") +async def settings_faq_edit(call: CallbackQuery, state: FSMContext): + await state.set_state("here_settings_faq") + await call.message.edit_text("ℹ Введите новый текст для FAQ\n" + "❕ Вы можете использовать заготовленный синтаксис и HTML разметку:\n" + "▶ {username} - логин пользоваля\n" + "▶ {user_id} - айди пользователя\n" + "▶ {firstname} - имя пользователя") + +# Принятие нового типа площдки +@dp.message_handler(IsAdmin(), state="here_settings_trade_type") +async def settings_tt_edit(message: Message, state: FSMContext): + get_message = get_faq(message.from_user.id, message.text) + + try: + cache_msg = await message.answer(get_message) + await state.finish() + update_settingsx(type_trade=message.text) + + await cache_msg.edit_text("ℹ Тип площадки был успешно обновлен ✅") + await message.answer("🖍 Изменение настроек бота.", reply_markup=settings_open_finl()) + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "ℹ Введите новый тип real | digital | hybrid.") + + +# Принятие нового текста для FAQ +@dp.message_handler(IsAdmin(), state="here_settings_faq") +async def settings_faq_get(message: Message, state: FSMContext): + get_message = get_faq(message.from_user.id, message.text) + + try: + cache_msg = await message.answer(get_message) + await state.finish() + update_settingsx(misc_faq=message.text) + + await cache_msg.edit_text("ℹ FAQ было успешно обновлено ✅") + await message.answer("🖍 Изменение настроек бота.", reply_markup=settings_open_finl()) + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "ℹ Введите новый текст для FAQ") + + +# Принятие нового айди для поддержки +@dp.message_handler(IsAdmin(), state="here_settings_support") +async def settings_support_get(message: Message, state: FSMContext): + if message.text.isdigit(): + get_user = get_userx(user_id=message.text) + + if get_user is not None: + if len(get_user['user_login']) >= 1: + await state.finish() + update_settingsx(misc_support=get_user['user_id']) + + await message.answer("☎ Поддержка была успешно обновлена ✅") + await message.answer("🖍 Изменение настроек бота.", reply_markup=settings_open_finl()) + else: + await message.answer("❌ У пользоваля отсутствует юзернейм.\n" + "☎ Отправьте ID пользователя.") + else: + await message.answer("❌ Пользователь не был найден.\n" + "☎ Отправьте ID пользователя.") + else: + await message.answer("❌ Данные были введены неверно.\n" + "☎ Отправьте ID пользователя.") diff --git a/TelegramGoodsinbot/tgbot/handlers/main_start.py b/TelegramGoodsinbot/tgbot/handlers/main_start.py new file mode 100644 index 0000000..3e90c54 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/main_start.py @@ -0,0 +1,127 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher import FSMContext +from aiogram.types import Message, CallbackQuery + +from tgbot.keyboards.inline_user import user_support_finl +from tgbot.keyboards.reply_z_all import menu_frep +from tgbot.loader import dp +from tgbot.services.api_sqlite import get_settingsx, get_userx +from tgbot.utils.misc.bot_filters import IsBuy, IsRefill, IsWork +from tgbot.utils.misc_functions import get_position_of_day +from tgbot.services.location_function import is_location +from tgbot.services.location_stat import geo_choice +from tgbot.keyboards.location_keyboards import geo_11_kb + +#from tgbot.services.user_seller_function import is_seller +#from tgbot.keyboards.user_seller_keyboards import geo_1_kb + +# Игнор-колбэки покупок +prohibit_buy = ['buy_category_open', 'buy_category_return', 'buy_category_nextp', 'buy_category_backp', + 'buy_position_open', 'buy_position_return', 'buy_position_nextp', 'buy_position_backp', + 'buy_purchase_select', 'here_purchase_count', 'xpurchase_item', 'add_item_cart', 'user_cart', + 'enter_address_manualy', 'enter_address_manualy_fin', 'checkout_finally', + 'here_itemsadd_cart', 'xaddcart_item', 'geo_first_letter', 'cart_checkout_start', + 'enter_message_manualy', 'conf_order_addr_saved'] +#'add_item_cart', 'enter_address_manualy', 'enter_address_manualy_fin', +# Игнор-колбэки пополнений +prohibit_refill = ['user_refill', 'refill_choice', 'Pay:', + 'Pay:Form', 'Pay:ForYm', 'Pay:Number', 'Pay:Nickname'] + + +#################################################################################################### +######################################## ТЕХНИЧЕСКИЕ РАБОТЫ ######################################## +# Фильтр на технические работы - сообщение +@dp.message_handler(IsWork(), state="*") +async def filter_work_message(message: Message, state: FSMContext): + await state.finish() + + user_support = get_settingsx()['misc_support'] + if str(user_support).isdigit(): + get_user = get_userx(user_id=user_support) + + if len(get_user['user_login']) >= 1: + await message.answer("⛔ Бот находится на технических работах.", + reply_markup=user_support_finl(get_user['user_login'])) + return + + await message.answer("⛔ Бот находится на технических работах.") + + +# Фильтр на технические работы - колбэк +@dp.callback_query_handler(IsWork(), state="*") +async def filter_work_callback(call: CallbackQuery, state: FSMContext): + await state.finish() + + await call.answer("⛔ Бот находится на технических работах.", True) + + +#################################################################################################### +########################################### СТАТУС ПОКУПОК ######################################### +# Фильтр на доступность покупок - сообщение +@dp.message_handler(IsBuy(), text="🎁 Купить", state="*") +@dp.message_handler(IsBuy(), state="here_purchase_count") +async def filter_buy_message(message: Message, state: FSMContext): + await state.finish() + + await message.answer("⛔ Покупки временно отключены.") + +# Фильтр на доступность покупок - колбэк + + +@dp.callback_query_handler(IsBuy(), text_startswith=prohibit_buy, state="*") +async def filter_buy_callback(call: CallbackQuery, state: FSMContext): + await state.finish() + + await call.answer("⛔ Покупки временно отключены.", True) + + +#################################################################################################### +######################################### СТАТУС ПОПОЛНЕНИЙ ######################################## +# Фильтр на доступность пополнения - сообщение +@dp.message_handler(IsRefill(), state="here_pay_amount") +async def filter_refill_message(message: Message, state: FSMContext): + await state.finish() + + await message.answer("⛔ Пополнение временно отключено.") + + +# Фильтр на доступность пополнения - колбэк +@dp.callback_query_handler(IsRefill(), text_startswith=prohibit_refill, state="*") +async def filter_refill_callback(call: CallbackQuery, state: FSMContext): + await state.finish() + + await call.answer("⛔ Пополнение временно отключено.", True) + + +#################################################################################################### +############################################## ПРОЧЕЕ ############################################## +# Открытие главного меню +@dp.message_handler(text=['⬅ Главное меню', '/start', '⬆️ Вперёд'], state="*") +async def main_start(message: Message, state: FSMContext): + await state.finish() + get_settings = get_settingsx() + type_trade = get_settings['type_trade'] + + if type_trade == 'hybrid': + if message.text == '⬆️ Вперёд': + await message.answer("🔸 Покупай, продавай, арендуй игры из Steam по самой низкой цене.\n" + "🔸 Если не появились вспомогательные кнопки\n" + "▶ Введите /start", + reply_markup=menu_frep(message.from_user.id)) + + else: + if is_location(message.from_user.id) == True: + + await message.answer("🔸 Покупай, продавай, арендуй игры из Steam по самой низкой цене.\n" + "🔸 Если не появились вспомогательные кнопки\n" + "▶ Введите /start", + reply_markup=menu_frep(message.from_user.id)) + else: + await geo_choice.location.set() + await message.answer('Покупай,арендуй и продавай игры по самой низкой цене.', reply_markup=geo_11_kb()) + + elif type_trade == 'digital' or type_trade == 'real': + await message.answer("🔸 Покупай, продавай, арендуй игры из Steam по самой низкой цене.\n" + "🔸 Если не появились вспомогательные кнопки\n" + "▶ Введите /start", + reply_markup=menu_frep(message.from_user.id)) diff --git a/TelegramGoodsinbot/tgbot/handlers/shopadmin_payment.py b/TelegramGoodsinbot/tgbot/handlers/shopadmin_payment.py new file mode 100644 index 0000000..0c518fb --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/shopadmin_payment.py @@ -0,0 +1,131 @@ +# - *- coding: utf- 8 - *- +import asyncio + +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message + +from tgbot.keyboards.inline_admin import payment_choice_finl +from tgbot.loader import dp +from tgbot.services.api_qiwi import QiwiAPI +from tgbot.services.api_sqlite import update_paymentx, get_upaymentx +from tgbot.utils.misc.bot_filters import IsShopAdmin + + +################################################################################### +############################# ВЫБОР СПОСОБА ПОПОЛНЕНИЯ ############################ +# Открытие способов пополнения +@dp.message_handler(IsShopAdmin(), text="🖲 Способы пополнения", state="*") +async def payment_systems(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🖲 Выберите способ пополнения", reply_markup=payment_choice_finl()) + + +# Включение/выключение самих способов пополнения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="change_payment:") +async def payment_systems_edit(call: CallbackQuery): + way_pay = call.data.split(":")[1] + way_status = call.data.split(":")[2] + + get_payment = get_upaymentx(user_id=call.from_user.id) + + if get_payment['qiwi_login'] != "None" and get_payment['qiwi_token'] != "None" or way_status == "False": + if way_pay == "Form": + if get_payment['qiwi_secret'] != "None" or way_status == "False": + update_paymentx(way_form=way_status) + else: + await call.answer( + "❗ Приватный ключ отсутствует. Измените киви и добавьте приватный ключ для включения оплаты по Форме", + True) + elif way_pay == "Number": + update_paymentx(way_number=way_status) + elif way_pay == "Nickname": + status, response = await (await QiwiAPI(call)).get_nickname() + if status: + update_paymentx(way_nickname=way_status, qiwi_nickname=response) + else: + await call.answer(response, True) + else: + await call.answer("❗ Добавьте киви кошелёк перед включением Способов пополнений.", True) + + try: + await call.message.edit_text("🖲 Выберите способ пополнения", reply_markup=payment_choice_finl()) + except: + pass + + +################################################################################### +####################################### QIWI ###################################### +# Изменение QIWI кошелька +@dp.message_handler(IsShopAdmin(), text="🥝 Изменить QIWI 🖍", state="*") +async def payment_qiwi_edit(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_qiwi_login") + await message.answer("🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Проверка работоспособности QIWI +@dp.message_handler(IsShopAdmin(), text="🥝 Проверить QIWI ♻", state="*") +async def payment_qiwi_check(message: Message, state: FSMContext): + await state.finish() + + await (await QiwiAPI(message, check_pass=True)).pre_checker() + + +# Баланс QIWI +@dp.message_handler(IsShopAdmin(), text="🥝 Баланс QIWI 👁", state="*") +async def payment_qiwi_balance(message: Message, state: FSMContext): + await state.finish() + + await (await QiwiAPI(message)).get_balance() + + +######################################## ПРИНЯТИЕ QIWI ######################################## +# Принятие логина для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_login") +async def payment_qiwi_edit_login(message: Message, state: FSMContext): + if message.text.startswith("+"): + await state.update_data(here_qiwi_login=message.text) + + await state.set_state("here_qiwi_token") + await message.answer( + "🥝 Введите токен API QIWI кошелька 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ При получении токена, ставьте только первые 3 галочки.", + disable_web_page_preview=True + ) + else: + await message.answer("❌ Номер должен начинаться с + (+7..., +380...)\n" + "🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Принятие токена для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_token") +async def payment_qiwi_edit_token(message: Message, state: FSMContext): + await state.update_data(here_qiwi_token=message.text) + + await state.set_state("here_qiwi_secret") + await message.answer( + "🥝 Введите Секретный ключ 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ Вы можете пропустить добавление оплаты по Форме, отправив: 0", + disable_web_page_preview=True + ) + + +# Принятие приватного ключа для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_secret") +async def payment_qiwi_edit_secret(message: Message, state: FSMContext): + async with state.proxy() as data: + qiwi_login = data['here_qiwi_login'] + qiwi_token = data['here_qiwi_token'] + if message.text == "0": qiwi_secret = "None" + if message.text != "0": qiwi_secret = message.text + + await state.finish() + + cache_message = await message.answer("🥝 Проверка введённых QIWI данных... 🔄") + await asyncio.sleep(0.5) + + await (await QiwiAPI(cache_message, qiwi_login, qiwi_token, qiwi_secret, True)).pre_checker() diff --git a/TelegramGoodsinbot/tgbot/handlers/shopadmin_products.py b/TelegramGoodsinbot/tgbot/handlers/shopadmin_products.py new file mode 100644 index 0000000..44dfbd4 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/shopadmin_products.py @@ -0,0 +1,1066 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message +from aiogram.utils.exceptions import CantParseEntities + +from tgbot.keyboards.inline_admin import category_edit_open_finl, position_edit_open_finl, category_edit_delete_finl, \ + position_edit_clear_finl, position_edit_delete_finl +from tgbot.keyboards.inline_z_all import category_remove_confirm_inl, position_remove_confirm_inl, \ + item_remove_confirm_inl, close_inl +from tgbot.keyboards.inline_z_page import * +from tgbot.keyboards.reply_z_all import finish_load_rep, items_frep +from tgbot.loader import dp +from tgbot.middlewares.throttling import rate_limit +from tgbot.services.api_sqlite import * +from tgbot.utils.const_functions import clear_list +from tgbot.utils.misc.bot_filters import IsShopAdmin +from tgbot.utils.misc_functions import get_position_admin, upload_text +# Добавлено +from tgbot.keyboards.location_keyboards import geo_1_kb +from tgbot.services.location_function import update_position_city, get_city_info + + +# Создание новой категории +@dp.message_handler(IsShopAdmin(), text="🗃 Создать категорию ➕", state="*") +async def product_category_create(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_category_name") + await message.answer("🗃 Введите название для категории 🏷") + + +# Открытие страниц выбора категорий для редактирования +@dp.message_handler(IsShopAdmin(), text="🗃 Изменить категорию 🖍", state="*") +async def product_category_edit(message: Message, state: FSMContext): + await state.finish() + + if len(get_all_categoriesx()) >= 1: + await message.answer("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_open_fp(0)) + else: + await message.answer("🗃 Категории отсутствуют 🖍") + + +# Окно с уточнением удалить все категории (позиции и товары включительно) +@dp.message_handler(IsAdmin(), text="🗃 Удалить все категории ❌", state="*") +async def product_category_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🗃 Вы действительно хотите удалить все категории? ❌\n" + "❗ Так же будут удалены все позиции и товары", + reply_markup=category_remove_confirm_inl) + + +# Начальные категории для изменения позиции +# !!!!!!! Изменить позицию +@dp.message_handler(IsShopAdmin(), text="📁 Изменить позицию 🖍", state="*") +async def product_position_edit(message: Message, state: FSMContext): + print(f'📁 Изменить позицию 🖍 shop_admin_products.py 73') + await state.finish() + + await message.answer("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_open_fp(0)) + + +# Подтверждение удаления всех позиций +@dp.message_handler(IsShopAdmin(), text="📁 Удалить все позиции ❌", state="*") +async def product_position_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("📁 Вы действительно хотите удалить все позиции? ❌\n" + "❗ Так же будут удалены все товары", + reply_markup=position_remove_confirm_inl) + + +# Начальные категории для добавления товаров +@dp.message_handler(IsShopAdmin(), text="🎁 Добавить товары ➕", state="*") +async def product_item_create(message: Message, state: FSMContext): + print(f'🎁 Добавить товары ➕ admin_products_shop.py 93') + await state.finish() + + if len(get_all_positionsx()) >= 1: + await message.answer("🎁 Выберите категорию с нужной позицией", + reply_markup=products_add_category_open_fp(0)) + else: + await message.answer("❌ Отсутствуют позиции для добавления товара.") + + +# Удаление определённых товаров +@dp.message_handler(IsShopAdmin(), text="🎁 Удалить товары 🖍", state="*") +async def product_item_delete(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_items_delete") + await message.answer("🖍 Вводите айди товаров, которые нужно удалить\n" + "❕ Получить айди товаров можно при изменении позиции\n" + "❕ Если хотите удалить несколько товаров, отправьте ID товаров через запятую или пробел. Пример:\n" + "▶ 123456,123456,123456\n" + "▶ 123456 123456 123456") + + +# ------------------------------------------------------------------------------------------------------------------- +# Кнопки с подтверждением удаления всех категорий +@dp.message_handler(IsAdmin(), text="🎁 Удалить все товары ❌", state="*") +async def product_item_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🎁 Вы действительно хотите удалить все товары? ❌\n", + reply_markup=item_remove_confirm_inl) + + +# Кнопки с подтверждением удаления всех категорий +@dp.message_handler(IsAdmin(), text="🎁 Удалить все товары ❌", state="*") +async def product_item_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🎁 Вы действительно хотите удалить все товары? ❌\n", + reply_markup=item_remove_confirm_inl) + + +################################################################################################ +####################################### СОЗДАНИЕ КАТЕГОРИЙ ##################################### +# Принятие названия категории для её создания +@dp.message_handler(IsAdmin(), state="here_category_name") +async def product_category_create_name(message: Message, state: FSMContext): + if len(message.text) <= 100: + add_categoryx(clear_html(message.text)) + + await state.finish() + await message.answer("🗃 Категория была успешно создана ✅") + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "🗃 Введите название для категории 🏷") + + +################################################################################################ +####################################### ИЗМЕНЕНИЕ КАТЕГОРИЙ #################################### +# Следующая страница выбора категорий для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="catategory_edit_nextp:", state="*") +async def product_category_edit_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_next_page_fp(remover)) + + +# Предыдущая страница выбора категорий для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="catategory_edit_backp:", state="*") +async def product_category_edit_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.delete() + await call.message.answer("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_back_page_fp(remover)) + + +# Выбор текущей категории для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_here:", state="*") +async def product_category_edit_open(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + get_fat_count = len(get_positionsx(category_id=category_id)) + get_category = get_categoryx(category_id=category_id) + + await call.message.edit_text(f"🗃 Категория: {get_category['category_name']}\n" + "➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"📁 Кол-во позиций: {get_fat_count}шт", + reply_markup=category_edit_open_finl(category_id, remover)) + + +# Возвращение к списку выбора категорий для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_return:", state="*") +async def product_category_edit_return(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_open_fp(remover)) + + +######################################## САМО ИЗМЕНЕНИЕ КАТЕГОРИИ ######################################## +# Изменение названия категории +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_name:", state="*") +async def product_category_edit_name(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_category_remover=remover) + + await state.set_state("here_change_category_name") + await call.message.delete() + await call.message.answer("🗃 Введите новое название для категории 🏷") + + +# Принятие нового имени для категории +@dp.message_handler(IsAdmin(), state="here_change_category_name") +async def product_category_edit_name_get(message: Message, state: FSMContext): + if len(message.text) <= 100: + async with state.proxy() as data: + category_id = data['here_cache_category_id'] + remover = data['here_cache_category_remover'] + await state.finish() + + update_categoryx(category_id, category_name=clear_html(message.text)) + + get_fat_count = len(get_positionsx(category_id=category_id)) + get_category = get_categoryx(category_id=category_id) + + await message.answer(f"🗃 Категория: {get_category['category_name']}\n" + "➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"📁 Кол-во позиций: {get_fat_count}шт", + reply_markup=category_edit_open_finl(category_id, remover)) + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "🗃 Введите новое название для категории 🏷") + + +# Окно с уточнением удалить категорию +@dp.callback_query_handler(IsAdmin(), text_startswith="category_edit_delete:", state="*") +async def product_category_edit_delete(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + await call.message.edit_text("❗ Вы действительно хотите удалить категорию и все её данные?", + reply_markup=category_edit_delete_finl(category_id, remover)) + + +# Отмена удаления категории +@dp.callback_query_handler(IsAdmin(), text_startswith="category_delete:", state="*") +async def product_category_edit_delete_confirm(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + get_action = call.data.split(":")[2] + remover = int(call.data.split(":")[3]) + + if get_action == "yes": + remove_categoryx(category_id=category_id) + remove_positionx(category_id=category_id) + remove_itemx(category_id=category_id) + + await call.answer("🗃 Категория и все её данные были успешно удалены ✅") + if len(get_all_categoriesx()) >= 1: + await call.message.edit_text("🗃 Выберите категорию для изменения 🖍", + reply_markup=category_edit_open_fp(remover)) + else: + await call.message.delete() + else: + get_fat_count = len(get_positionsx(category_id=category_id)) + get_category = get_categoryx(category_id=category_id) + + await call.message.edit_text(f"🗃 Категория: {get_category['category_name']}\n" + "➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"📁 Кол-во позиций: {get_fat_count}шт", + reply_markup=category_edit_open_finl(category_id, remover)) + + +################################################################################################ +#################################### УДАЛЕНИЕ ВСЕХ КАТЕГОРИЙ ################################### +# Подтверждение на удаление всех категорий (позиций и товаров включительно) +@dp.callback_query_handler(IsAdmin(), text_startswith="confirm_remove_category:", state="*") +async def product_category_remove_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + + if get_action == "yes": + get_categories = len(get_all_categoriesx()) + get_positions = len(get_all_positionsx()) + get_items = len(get_all_itemsx()) + + clear_categoryx() + clear_positionx() + clear_itemx() + + await call.message.edit_text( + f"🗃 Вы удалили все категории({get_categories}шт), " + f"позиции({get_positions}шт) и товары({get_items}шт)") + else: + await call.message.edit_text("🗃 Вы отменили удаление всех категорий ✅") + + +################################################################################################ +####################################### ДОБАВЛЕНИЕ ПОЗИЦИЙ ##################################### +# Следующая страница выбора категорий для создания позиций +@dp.callback_query_handler(IsProductsShopAdmin(), text_startswith="position_create_nextp:", state="*") +async def product_position_create_next(call: CallbackQuery, state: FSMContext): + print(f'выбора категорий для создания позиций shopadmin_products.py 300') + remover = int(call.data.split(":")[1]) + print(remover) + + await call.message.edit_text("📁 Выберите категорию для позиции ➕", + reply_markup=position_create_next_page_fp(remover)) + +# Предыдущая страница выбора категорий для создания позиций + + +@dp.callback_query_handler(IsProductsShopAdmin(), text_startswith="position_create_backp:", state="*") +async def product_position_create_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию для позиции ➕", + reply_markup=position_create_back_page_fp(remover)) + + +@dp.callback_query_handler(IsProductsShopAdmin(), text_startswith="position_create_here:", state="*") +async def product_position_create(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + await state.update_data(here_cache_change_shop_id=category_id) + + if len(get_all_categoriesx()) >= 1: + await call.message.answer("📁 Выберите категорию для позиции", + reply_markup=position_create_open_fp(0)) + else: + await call.message.answer("❌ Отсутствуют категории для создания позиции.") + + +# Выбор категории для создания позиции +@dp.callback_query_handler(IsProductsShopAdmin(), text_startswith="position_create_here:", state="*") +async def product_position_create_select_category(call: CallbackQuery, state: FSMContext): + print('position_create_here') + category_id = int(call.data.split(":")[1]) + + await state.update_data(here_cache_change_category_id=category_id) + + await state.set_state("here_position_name") + await call.message.edit_text("📁 Введите название для позиции 🏷") + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Заготовка под принятие города магазином +# Принятие города для создания позиции +# @dp.message_handler(IsAdmin(), state="here_position_city") +# async def product_position_create_name(message: Message, state: FSMContext): +# print(f'Принятие города для создания позиции admin_products_shop.py 344') +# city_user = get_city_user(message.from_user.id) + +# Принятие имени для создания позиции + + +@dp.message_handler(IsProductsShopAdmin(), state="here_position_name") +async def product_position_create_name(message: Message, state: FSMContext): + print(f'Принятие имени для создания позиции shopadmin_products.py 337') + if len(message.text) <= 100: + await state.update_data(here_position_name=clear_html(message.text), here_position_city=get_city_user(message.from_user.id)[0], position_city_id=get_city_user(message.from_user.id)[2]) + + await state.set_state("here_position_price") + await message.answer("📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "📁 Введите название для позиции 🏷") + + +# Принятие цены позиции для её создания +@dp.message_handler(IsProductsShopAdmin(), state="here_position_price") +async def product_position_create_price(message: Message, state: FSMContext): + print(f'Принятие цены позиции shopadmin_products.py 366') + if message.text.isdigit(): + if 0 <= int(message.text) <= 10000000: + await state.update_data(here_position_price=message.text) + + await state.set_state("here_position_description") + await message.answer("📁 Введите описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + else: + await message.answer("❌ Цена не может быть меньше 0 или больше 10 000 000.\n" + "📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Данные были введены неверно.\n" + "📁 Введите цену для позиции 💰") + + +# Принятие описания позиции для её создания +@dp.message_handler(IsProductsShopAdmin(), state="here_position_description") +async def product_position_create_description(message: Message, state: FSMContext): + print(f'Принятие описания позиции shopadmin_products.py 386') + + try: + if len(message.text) <= 600: + if message.text != "0": + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + await state.update_data(here_position_description=message.text) + + await state.set_state("here_position_photo") + await message.answer("📁 Отправьте изображение для позиции 📸\n" + "❕ Отправьте 0 чтобы пропустить.") + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📁 Введите описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие изображения позиции для её создания +@dp.message_handler(IsProductsShopAdmin(), content_types="photo", state="here_position_photo") +@dp.message_handler(IsProductsShopAdmin(), text="0", state="here_position_photo") +async def product_position_create_photo(message: Message, state: FSMContext): + print(f'Принятие изображения позиции shopadmin_products.py 418') + async with state.proxy() as data: + position_user_id = message.from_user.id + position_city = data['here_position_city'] + position_city_id = data['position_city_id'] + position_name = clear_html(data['here_position_name']) + position_price = data['here_position_price'] + catategory_id = data['here_cache_change_category_id'] + position_description = data['here_position_description'] + await state.finish() + + if "text" in message: + position_photo = "" + else: + position_photo = message.photo[-1].file_id + + add_positionx(position_city, position_city_id, position_name, position_price, + position_description, position_photo, catategory_id, position_user_id) + + await message.answer("📁 Позиция была успешно создана ✅") + + +################################################################################################ +####################################### ИЗМЕНЕНИЕ ПОЗИЦИЙ ##################################### +# Возвращение к начальным категориям для редактирования позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_category_return", state="*") +async def product_position_edit_return(call: CallbackQuery, state: FSMContext): + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_open_fp(0)) + + +# Следующая страница категорий для редактирования позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_category_nextp:", state="*") +async def product_position_edit_category_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_next_page_fp(remover)) + + +# Предыдущая страница категорий для редактирования позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_category_backp:", state="*") +async def product_position_edit_category_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_back_page_fp(remover)) + + +# Выбор категории с нужной позицией +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_category:", state="*") +async def product_position_edit_category_open(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.edit_text("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(0, category_id)) + else: + await call.answer("📁 Позиции в данной категории отсутствуют") + + +# Следующая страница позиций для их изменения +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_nextp:", state="*") +async def product_position_edit_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_next_page_fp(remover, category_id)) + + +# Предыдущая страница позиций для их изменения +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_backp:", state="*") +async def product_position_edit_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_back_page_fp(remover, category_id)) + + +# Выбор позиции для редактирования +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit:", state="*") +async def product_position_edit_open(call: CallbackQuery, state: FSMContext): + print(f'Выбор позиции для редактирования api_sqlite.py 496') + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Возвращение к выбору позиции для изменения +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_return", state="*") +async def product_position_edit_return(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.delete() + await call.message.answer("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(remover, category_id)) + else: + await call.answer("❗ Позиции в данной категории отсутствуют") + + +######################################## САМО ИЗМЕНЕНИЕ ПОЗИЦИИ ######################################## +# Изменение имени позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_name", state="*") +async def product_position_edit_name(call: CallbackQuery, state: FSMContext): + print(f'Изменение имени позиции api_sqlite.py 529') + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_name") + await call.message.delete() + await call.message.answer("📁 Введите новое название для позиции 🏷") + + +# Принятие имени позиции для её изменения +@dp.message_handler(IsAdmin(), state="here_change_position_name") +async def product_position_edit_name_get(message: Message, state: FSMContext): + if len(message.text) <= 100: + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + update_positionx(position_id, position_name=clear_html(message.text)) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "📁 Введите новое название для позиции 🏷") + + +# Изменение цены позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_price", state="*") +async def product_position_edit_price(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_price") + await call.message.delete() + await call.message.answer("📁 Введите новую цену для позиции 💰") + + +# Принятие цены позиции для её изменения +@dp.message_handler(IsAdmin(), state="here_change_position_price") +async def product_position_edit_price_get(message: Message, state: FSMContext): + if message.text.isdigit(): + if 0 <= int(message.text) <= 10000000: + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + update_positionx(position_id, position_price=message.text) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Цена не может быть меньше 0 или больше 10 000 000.\n" + "📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Данные были введены неверно.\n" + "📁 Введите цену для позиции 💰") + + +# Изменение описания позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_description", state="*") +async def product_position_edit_description(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_description") + await call.message.delete() + await call.message.answer("📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие описания позиции для её изменения +@dp.message_handler(IsAdmin(), state="here_change_position_description") +async def product_position_edit_description_get(message: Message, state: FSMContext): + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + + try: + if len(message.text) <= 600: + await state.finish() + + if message.text != "0": + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + update_positionx(position_id, position_description=message.text) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Изменение изображения позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_photo", state="*") +async def product_position_edit_photo(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_photo") + await call.message.delete() + await call.message.answer("📁 Отправьте новое изображение для позиции 📸\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие нового фото для позиции +@dp.message_handler(IsAdmin(), content_types="photo", state="here_change_position_photo") +@dp.message_handler(IsAdmin(), text="0", state="here_change_position_photo") +async def product_position_edit_photo_get(message: Message, state: FSMContext): + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + if "text" in message: + position_photo = "" + else: + position_photo = message.photo[-1].file_id + + update_positionx(position_id, position_photo=position_photo) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# --------------------------- Добавлено 12.08.22 ------------------------------------------ + +# Изменение города продукта +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_city", state="*") +async def product_position_edit_description(call: CallbackQuery, state: FSMContext): + print(f'Изменение города продукта admin_products.py 715') + print(call.data) + category_id = int(call.data.split(":")[2]) + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[3]) + + current_city = get_city_user(call.from_user.id)[0] + + # await state.update_data(here_cache_category_id=category_id) + # await state.update_data(here_cache_position_id=position_id) + # await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_city") + await state.update_data({'position_id': position_id, 'category_id': category_id, 'remover': remover}) + await call.message.delete() + await call.message.answer("📁 Выбирите другой город 🏙\n" + "❕ Вы можете использовать геолокацию или выбрать город из списка\n" + f"❕ Город товара: {current_city}", reply_markup=geo_1_kb()) + + +# принятие новой геопозиции для позиции +@dp.callback_query_handler(text_startswith='geo_chosen_cities', state='here_change_city') +async def geo_5(cb: CallbackQuery, state: FSMContext): + info = int(str(cb.data).split('#')[1]) + if info == 0: + async with state.proxy() as data: + city = data['city'] + position_id = int(data['position_id']) + category_id = data['category_id'] + remover = data['remover'] + city_id = data['city_id'] + + else: + async with state.proxy() as data: + position_id = int(data['position_id']) + category_id = data['category_id'] + remover = data['remover'] + + city_id = info + city = get_city_info(info) + + await state.finish() + update_position_city(city[0], city_id, position_id) + + # update_positionx(position_id) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await cb.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await cb.message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Выгрузка товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_items", state="*") +async def product_position_edit_items(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + save_items = ['АйдиТовара - Данные товара', + "================================"] + + if len(get_items) >= 1: + for item in get_items: + save_items.append(f"{item['item_id']} - {item['item_data']}") + save_items = "\n".join(save_items) + + save_items = await upload_text(call, save_items) + await call.message.answer(f"📥 Все товары позиции: {get_position['position_name']}\n" + f"🔗 Ссылка: кликабельно", + reply_markup=close_inl) + await call.answer() + else: + await call.answer("❕ В данной позиции отсутствуют товары", True) + + +# Удаление позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_delete", state="*") +async def product_position_edit_delete(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await call.message.delete() + await call.message.answer("📁 Вы действительно хотите удалить позицию? ❌", + reply_markup=position_edit_delete_finl(position_id, category_id, remover)) + + +# Подтверждение удаления позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_delete", state="*") +async def product_position_edit_delete_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + remover = int(call.data.split(":")[4]) + + if get_action == "yes": + remove_itemx(position_id=position_id) + remove_positionx(position_id=position_id) + + await call.answer("📁 Вы успешно удалили позицию и её товары ✅") + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.edit_text("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(remover, category_id)) + else: + await call.message.delete() + else: + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Очистка позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_edit_clear", state="*") +async def product_position_edit_clear(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await call.message.delete() + await call.message.answer("📁 Вы хотите удалить все товары позиции?", + reply_markup=position_edit_clear_finl(position_id, category_id, remover)) + + +# Согласие очистики позиции +@dp.callback_query_handler(IsAdmin(), text_startswith="position_clear", state="*") +async def product_position_edit_clear_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + remover = int(call.data.split(":")[4]) + + if get_action == "yes": + remove_itemx(position_id=position_id) + await call.answer("📁 Вы успешно удалили все товары позиции ✅") + + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +################################################################################################ +###################################### УДАЛЕНИЕ ВСЕХ ПОЗИЦИЙ ################################### +# Согласие на удаление всех позиций и товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="confirm_remove_position:", state="*") +async def product_position_remove(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + + if get_action == "yes": + get_positions = len(get_all_positionsx()) + get_items = len(get_all_itemsx()) + + clear_positionx() + clear_itemx() + + await call.message.edit_text( + f"📁 Вы удалили все позиции({get_positions}шт) и товары({get_items}шт)") + else: + await call.message.edit_text("📁 Вы отменили удаление всех позиций ✅") + + +################################################################################################ +####################################### ДОБАВЛЕНИЕ ТОВАРОВ ##################################### +# Возвращение к начальным категориям для добавления товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="back_add_products_to_category", state="*") +async def product_item_create(call: CallbackQuery, state: FSMContext): + await call.message.edit_text("🎁 Выберите категорию с нужной позицией", + reply_markup=products_add_category_open_fp(0)) + + +# Следующая страница выбора категории с позицией для добавления товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="products_add_category_nextp", state="*") +async def product_item_load_category_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.delete() + await call.message.answer("🎁 Выберите категорию с нужной позицией", + reply_markup=products_add_category_next_page_fp(remover)) + + +# Предыдущая страница выбора категории с позицией для добавления товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="products_add_category_backp", state="*") +async def product_item_load_category_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.delete() + await call.message.answer("🎁 Выберите категорию с нужной позицией", + reply_markup=products_add_category_back_page_fp(remover)) + + +# Выбор категории с нужной позицией +@dp.callback_query_handler(IsAdmin(), text_startswith="products_add_category", state="*") +async def product_item_load_category_open(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.delete() + await call.message.answer("🎁 Выберите нужную вам позицию", + reply_markup=products_add_position_open_fp(0, category_id)) + else: + await call.answer("🎁 Позиции в данной категории отсутствуют") + + +# Следующая страница позиций для добавления товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="products_add_position_nextp", state="*") +async def product_item_load_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("🎁 Выберите нужную вам позицию", + reply_markup=products_add_position_next_page_fp(remover, category_id)) + + +# Предыдущая страница позиций для добавления товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="products_add_position_backp", state="*") +async def product_item_load_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("🎁 Выберите нужную вам позицию", + reply_markup=products_add_position_back_page_fp(remover, category_id)) + + +# Выбор позиции для добавления товаров +@rate_limit(0) +@dp.callback_query_handler(IsAdmin(), text_startswith="products_add_position:", state="*") +async def product_item_load_open(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await state.update_data(here_cache_add_item_category_id=category_id) + await state.update_data(here_cache_add_item_position_id=position_id) + await state.update_data(here_count_add_items=0) + + await state.set_state("here_add_items") + await call.message.delete() + await call.message.answer("📤 Отправьте данные товаров (доступы для входа).\n" + "❗ Товары разделяются одной пустой строчкой. Пример:\n" + "Логин:... Пароль...\n\n" + "Логин:... Пароль...\n\n" + "Логин:... Пароль...", + reply_markup=finish_load_rep) + + +# Завершение загрузки товаров +@rate_limit(0) +@dp.message_handler(IsAdmin(), text="📥 Закончить загрузку товаров", state="*") +async def product_item_load_finish(message: Message, state: FSMContext): + get_all_items = 0 + try: + async with state.proxy() as data: + get_all_items = data['here_count_add_items'] + except: + pass + + await state.finish() + await message.answer("📥 Загрузка товаров была успешно завершена ✅\n" + f"▶ Загружено товаров: {get_all_items}шт", + reply_markup=items_frep()) + + +# Принятие данных товара +@rate_limit(0) +@dp.message_handler(IsAdmin(), state="here_add_items") +async def product_item_load_get(message: Message, state: FSMContext): + cache_msg = await message.answer("⌛ Ждите, товары добавляются...") + + count_add = 0 + get_all_items = clear_list(message.text.split("\n\n")) + + for check_item in get_all_items: + if not check_item.isspace() and check_item != "": + count_add += 1 + + async with state.proxy() as data: + category_id = data['here_cache_add_item_category_id'] + position_id = data['here_cache_add_item_position_id'] + data['here_count_add_items'] += count_add + + get_user = get_userx(user_id=message.from_user.id) + add_itemx(category_id, position_id, get_all_items, + get_user['user_id'], get_user['user_name']) + + await cache_msg.edit_text(f"📥 Товары в кол-ве {count_add}шт были успешно добавлены ✅") + + +################################################################################################ +####################################### УДАЛЕНИЕ ТОВАРОВ ###################################### +# Принятие айди товаров для их удаления +@dp.message_handler(IsAdmin(), state="here_items_delete") +async def product_item_delete_get(message: Message, state: FSMContext): + await state.finish() + + remove_ids, cancel_ids = [], [] # Айди удалённых и ненайденных товаров + get_item_ids_one, get_item_ids_two = [], [[]] + save_ids = [] + + if "," in message.text: + get_item_ids_one = clear_list(message.text.split(",")) + else: + get_item_ids_one = clear_list([message.text]) + + for item in get_item_ids_one: + if " " in item: + get_item_ids_two.append(item.split(" ")) + + if len(get_item_ids_two) == 1: + get_item_ids_two.append(get_item_ids_one) + + for check_item in get_item_ids_two: + for item in clear_list(check_item): + save_ids.append(item) + + save_ids = clear_list(save_ids) + + for item_id in save_ids: + check_item = get_itemx(item_id=item_id) + if check_item is not None: + remove_itemx(item_id=item_id) + remove_ids.append(item_id) + else: + cancel_ids.append(item_id) + + remove_ids = ", ".join(remove_ids) + cancel_ids = ", ".join(cancel_ids) + + await message.answer(f"✅ Успешно удалённые товары:\n" + f"▶ {remove_ids}\n" + f"➖➖➖➖➖➖➖➖➖➖\n" + f"❌ Ненайденные товары:\n" + f"▶ {cancel_ids}") + + +################################################################################################ +##################################### УДАЛЕНИЕ ВСЕХ ТОВАРОВ #################################### +# Согласие на удаление всех товаров +@dp.callback_query_handler(IsAdmin(), text_startswith="confirm_remove_item:", state="*") +async def product_item_remove(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + + if get_action == "yes": + get_items = len(get_all_itemsx()) + clear_itemx() + + await call.message.edit_text(f"🎁 Вы удалили все товары({get_items}шт)") + else: + await call.message.edit_text("🎁 Вы отменили удаление всех товаров ✅") diff --git a/TelegramGoodsinbot/tgbot/handlers/user_location-l.py b/TelegramGoodsinbot/tgbot/handlers/user_location-l.py new file mode 100644 index 0000000..db8b29e --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/user_location-l.py @@ -0,0 +1,96 @@ +from aiogram import types +from aiogram.dispatcher import Dispatcher, FSMContext + +from tgbot.loader import dp + + +from tgbot.services.location_stat import geo_choice +from tgbot.keyboards.location_keyboards import * +from tgbot.services.location_function import search_city, add_geocode, add_city, get_city, update_position_city + +from tgbot.keyboards.reply_z_all import menu_frep + + +@dp.callback_query_handler(lambda cb: cb.data == 'edit_locatoin', state='*') +async def geo_1(cb: types.CallbackQuery, state: FSMContext): + await state.finish() + await geo_choice.location.set() + await cb.message.answer('Отправте локациюили выбирите город из списка', reply_markup=geo_11_kb()) + +# приём локации + + +@dp.message_handler(content_types=['location'], state=geo_choice.location) +async def geo_2(msg: types.Message, state: FSMContext): + await msg.delete() + lat = msg.location.latitude + long = msg.location.longitude + city = search_city(lat, long)[0] + add_geocode(lat, long, msg.from_user.id) + if city == False: + await msg.answer('Ваш город не определён. Выберите город из списка', reply_markup=geo_3_kb()) + else: + await msg.answer(f'Ваш город: {city}?', reply_markup=geo_2_kb(city)) + + +@dp.message_handler(lambda msg: msg.text == '📋 Выбрать из списка', state=geo_choice.location) +async def geo_3(msg: types.Message, state: FSMContext): + await msg.answer('Первая буква названия вашего города', reply_markup=geo_3_kb()) + + +@dp.callback_query_handler(lambda cb: cb.data[:16] == 'geo_first_letter', state=geo_choice.location) +async def geo_4(cb: types.CallbackQuery): + info = str(cb.data).split('#')[1] + await cb.message.edit_text('Выберите город', reply_markup=geo_4_kb(info)) + + +@dp.callback_query_handler(lambda cb: cb.data[:17] == 'geo_chosen_cities', state=geo_choice.location) +async def geo_5(cb: types.CallbackQuery, state: FSMContext): + await state.finish() + info = str(cb.data).split('#')[1] + if len(info) < 4: + id = info + info = get_city(id, cb.from_user.id) + add_city(info[0], cb.from_user.id, info[3]) + await cb.message.answer("🔸 Покупай, продавай, арендуй игры из Steam по самой низкой цене.\n" + "🔸 Если не появились вспомогательные кнопки\n" + "▶ Введите /start", + reply_markup=menu_frep(cb.from_user.id)) + + +# ============================================================================================================== +# ================================ Локация для позицци (для магазина в будующем) ============================= + + +# приём локации +@dp.message_handler(content_types=['location'], state='here_change_city') +async def geo_position_1(msg: types.Message, state: FSMContext): + await msg.delete() + lat = msg.location.latitude + long = msg.location.longitude + city = search_city(lat, long) + if city == False: + await msg.answer('Город не определён. Выберите город из списка', reply_markup=geo_3_kb()) + else: + await state.update_data({'city': city[0], 'city_id': city[1]}) + await msg.answer(f'Ваш город: {city[0]}?', reply_markup=geo_2_kb(0)) + +# выбор буквы города при нажатии кнопки + + +@dp.message_handler(lambda msg: msg.text == '📋 Выбрать из списка', state='here_change_city') +async def geo_3(msg: types.Message, state: FSMContext): + await msg.answer('Первая буква названия вашего города', reply_markup=geo_3_kb()) + + +# выбор буквы города при ошибке геокода +@dp.callback_query_handler(text_startswith='choice_city_list', state='here_change_city') +async def geo_position_2(cb: types.CallbackQuery, state: FSMContext): + await cb.message.answer('Первая буква названия вашего города', reply_markup=geo_3_kb()) + + +# выбор города по букве +@dp.callback_query_handler(text_startswith='geo_first_letter', state='here_change_city') +async def geo_4(cb: types.CallbackQuery): + info = str(cb.data).split('#')[1] + await cb.message.edit_text('Выберите город', reply_markup=geo_4_kb(info)) diff --git a/TelegramGoodsinbot/tgbot/handlers/user_location.py b/TelegramGoodsinbot/tgbot/handlers/user_location.py new file mode 100644 index 0000000..eadbb96 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/user_location.py @@ -0,0 +1,96 @@ +from aiogram import types +from aiogram.dispatcher import Dispatcher, FSMContext + +from tgbot.loader import dp + +from tgbot.services.location_stat import geo_choice +from tgbot.keyboards.location_keyboards import * +from tgbot.services.location_function import search_address, add_address, search_city, add_geocode, add_city, get_city, update_position_city + +from tgbot.keyboards.reply_z_all import menu_frep + + +@dp.callback_query_handler(lambda cb: cb.data == 'edit_locatoin', state='*') +async def geo_1(cb: types.CallbackQuery, state: FSMContext): + await state.finish() + await geo_choice.location.set() + await cb.message.answer('Отправьте локацию или выберите город из списка', reply_markup=geo_11_kb()) + +# приём локации + + +@dp.message_handler(content_types=['location'], state=geo_choice.location) +async def geo_2(msg: types.Message, state: FSMContext): + await msg.delete() + lat = msg.location.latitude + long = msg.location.longitude + city = search_city(lat, long) + address = search_address(lat, long) + add_geocode(lat, long, msg.from_user.id) + add_address(address, msg.from_user.id) + + if city == False: + await msg.answer('Ваш город не определён. Выберите город из списка', reply_markup=geo_3_kb()) + else: + await msg.answer(f'Ваш город: {city[0]}?', reply_markup=geo_2_kb(city[1])) + + +@dp.message_handler(lambda msg: msg.text == '📋 Выбрать из списка', state=geo_choice.location) +async def geo_3(msg: types.Message, state: FSMContext): + await msg.answer('Первая буква названия вашего города', reply_markup=geo_3_kb()) + + +@dp.callback_query_handler(lambda cb: cb.data[:16] == 'geo_first_letter', state=geo_choice.location) +async def geo_4(cb: types.CallbackQuery): + info = str(cb.data).split('#')[1] + await cb.message.edit_text('Выберите город', reply_markup=geo_4_kb(info)) + + +@dp.callback_query_handler(lambda cb: cb.data[:17] == 'geo_chosen_cities', state=geo_choice.location) +async def geo_5(cb: types.CallbackQuery, state: FSMContext): + await state.finish() + info = str(cb.data).split('#')[1] + city_info = get_city(info, cb.from_user.id) + add_city(city_info[0], cb.from_user.id, city_info[3]) + await cb.message.answer("🔸 Покупай, продавай, арендуй игры из Steam по самой низкой цене.\n" + "🔸 Если не появились вспомогательные кнопки\n" + "▶ Введите /start", + reply_markup=menu_frep(cb.from_user.id)) + + +# ============================================================================================================== +# ================================ Локация для позицци (для магазина в будующем) ============================= + + +# приём локации +@dp.message_handler(content_types=['location'], state='here_change_city') +async def geo_position_1(msg: types.Message, state: FSMContext): + await msg.delete() + lat = msg.location.latitude + long = msg.location.longitude + city = search_city(lat, long) + if city == False: + await msg.answer('Город не определён. Выберите город из списка', reply_markup=geo_3_kb()) + else: + await state.update_data({'city': city[0], 'city_id': city[1]}) + await msg.answer(f'Ваш город: {city[0]}?', reply_markup=geo_2_kb(0)) + +# выбор буквы города при нажатии кнопки + + +@dp.message_handler(lambda msg: msg.text == '📋 Выбрать из списка', state='here_change_city') +async def geo_3(msg: types.Message, state: FSMContext): + await msg.answer('Первая буква названия вашего города', reply_markup=geo_3_kb()) + + +# выбор буквы города при ошибке геокода +@dp.callback_query_handler(text_startswith='choice_city_list', state='here_change_city') +async def geo_position_2(cb: types.CallbackQuery, state: FSMContext): + await cb.message.answer('Первая буква названия вашего города', reply_markup=geo_3_kb()) + + +# выбор города по букве +@dp.callback_query_handler(text_startswith='geo_first_letter', state='here_change_city') +async def geo_4(cb: types.CallbackQuery): + info = str(cb.data).split('#')[1] + await cb.message.edit_text('Выберите город', reply_markup=geo_4_kb(info)) diff --git a/TelegramGoodsinbot/tgbot/handlers/user_menu copy.py b/TelegramGoodsinbot/tgbot/handlers/user_menu copy.py new file mode 100644 index 0000000..d9d938a --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/user_menu copy.py @@ -0,0 +1,1143 @@ +# - *- coding: utf- 8 - *- +import asyncio + +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message + +from tgbot.data.config import BOT_DESCRIPTION +from tgbot.keyboards.inline_user import user_support_finl, products_open_finl, products_confirm_finl, payment_as_choice_finl +from tgbot.keyboards.inline_z_all import profile_open_inl +from tgbot.keyboards.inline_z_page import * +from tgbot.keyboards.reply_z_all import menu_frep, items_sh_frep +from tgbot.keyboards.inline_admin import category_edit_open_finl, position_edit_open_finl, category_edit_delete_finl, \ + position_edit_clear_finl, position_edit_delete_finl, payment_choice_finl +from tgbot.keyboards.inline_z_all import category_remove_confirm_inl, position_remove_confirm_inl, \ + item_remove_confirm_inl, close_inl +from tgbot.keyboards.inline_z_page import * +from tgbot.keyboards.reply_z_all import finish_load_rep +from tgbot.utils.misc.bot_filters import IsShopAdmin +from tgbot.utils.misc_functions import get_position_admin, upload_text +from tgbot.loader import dp +from tgbot.services.api_qiwi import QiwiAPI +from tgbot.services.api_sqlite import * +from tgbot.utils.const_functions import get_date, split_messages, get_unix +from tgbot.utils.misc_functions import open_profile_my, upload_text, get_faq, send_admins + +################################################################################################ +# Заявка на продавца магазина +# Открытие товаров + + +@dp.message_handler(text="Хочу продавать", state="*") +async def user_seller_request(message: Message, state: FSMContext): + await state.finish() + + await message.answer("Подтвердите заявку:", + reply_markup=request_seller_role(message.from_user.id)) + +# Управление товарами + + +@dp.message_handler(IsShopAdmin(), text="🎁 Управление товарами дмаг.🖍", state="*") +async def shopadmin_products(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🎁 Редактирование товаров дмаг.", reply_markup=items_sh_frep()) + + +@dp.message_handler(text="🗃 Создать категорию ➕", state="*") +async def product_category_create(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_category_name") + await message.answer("🗃 Введите название для категории 🏷") + +# Начальные категории для изменения позиции + + +# !!!!!!! Изменить позицию +@dp.message_handler(IsShopAdmin(), text="📁 Изменить позицию 🖍", state="*") +async def product_position_edit(message: Message, state: FSMContext): + print(f'📁 Изменить позицию 🖍 user_menu.py 73') + await state.finish() + + await message.answer("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_open_fp(0)) + +# Открытие товаров + + +@dp.message_handler(text="🎁 Игры в аренду", state="*") +async def user_shop(message: Message, state: FSMContext): + print(f'Открытие категорий товаров user_menu.py 39') + await state.finish() + + city_id = get_city_user(message.from_user.id)[2] + # get_categories = get_category_in_city(city_id) + + if len(get_category_in_city(city_id)) >= 1: + await message.answer("🎁 Выберите нужный вам товар:", + reply_markup=products_item_category_open_fp(0, city_id)) + else: + await message.answer("🎁 В вашем городе товаров нет,выбирите другой город\n\n" + "🏙 Изменить город вы можете в личном кабинете") + + +# Открытие профиля +@dp.message_handler(text="👤 Профиль", state="*") +async def user_profile(message: Message, state: FSMContext): + await state.finish() + + await message.answer(open_profile_my(message.from_user.id), reply_markup=profile_open_inl) + + +# Открытие FAQ +@dp.message_handler(text=["ℹ FAQ", "/faq"], state="*") +async def user_faq(message: Message, state: FSMContext): + await state.finish() + + send_message = get_settingsx()['misc_faq'] + if send_message == "None": + send_message = f"ℹ Информация. Измените её в настройках бота.\n➖➖➖➖➖➖➖➖➖➖➖➖➖\n{BOT_DESCRIPTION}" + + await message.answer(get_faq(message.from_user.id, send_message), disable_web_page_preview=True) + + +# Открытие сообщения с ссылкой на поддержку +@dp.message_handler(text=["☎ Поддержка/FAQ", "/support"], state="*") +async def user_support(message: Message, state: FSMContext): + await state.finish() + + user_support = get_settingsx()['misc_support'] + if str(user_support).isdigit(): + get_user = get_userx(user_id=user_support) + + if len(get_user['user_login']) >= 1: + await message.answer("☎ Нажмите кнопку ниже для связи с Администратором.", + reply_markup=user_support_finl(get_user['user_login'])) + return + else: + update_settingsx(misc_support="None") + + await message.answer(f"☎ Поддержка/FAQ.\n➖➖➖➖➖➖➖➖➖➖➖➖➖\n{BOT_DESCRIPTION}", + disable_web_page_preview=True) + + +# Просмотр истории покупок +@dp.callback_query_handler(text="create_seller_request", state="*") +async def user_seller(call: CallbackQuery, state: FSMContext): + seller_request = create_seller_request(call.from_user.id) + await call.answer("🎁 Запрос успешно создан") + await send_admins(f"Поступил новый запрос продавца!", markup='check_seller_requests') + # await bot.send_message(get_admins(), "ntcnnnnnn") + +# Удаление позиции + + +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_delete", state="*") +async def product_position_edit_delete(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await call.message.delete() + await call.message.answer("📁 Вы действительно хотите удалить позицию? ❌", + reply_markup=position_edit_delete_finl(position_id, category_id, remover)) + + +# Подтверждение удаления позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_delete", state="*") +async def product_position_edit_delete_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + remover = int(call.data.split(":")[4]) + + if get_action == "yes": + remove_itemx(position_id=position_id) + remove_positionx(position_id=position_id) + + await call.answer("📁 Вы успешно удалили позицию и её товары ✅") + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.edit_text("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(remover, category_id)) + else: + await call.message.delete() + else: + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Согласие очистики позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_clear", state="*") +async def product_position_edit_clear_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + remover = int(call.data.split(":")[4]) + + if get_action == "yes": + remove_itemx(position_id=position_id) + await call.answer("📁 Вы успешно удалили все товары позиции ✅") + + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Открытие способов пополнения +@dp.message_handler(IsShopAdmin(), text="🖲 Способы пополнения", state="*") +async def payment_systems(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🖲 Выберите способ пополнения", reply_markup=payment_as_choice_finl()) + + +# Включение/выключение самих способов пополнения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="change_payment:") +async def payment_systems_edit(call: CallbackQuery): + way_pay = call.data.split(":")[1] + way_status = call.data.split(":")[2] + print("Админ магазина") + # print(call.data.split(":")[0]) + print(call.message.from_user.id) + get_payment = get_paymentx() + + if get_payment['qiwi_login'] != "None" and get_payment['qiwi_token'] != "None" or way_status == "False": + if way_pay == "Form": + if get_payment['qiwi_secret'] != "None" or way_status == "False": + update_upaymentx(way_form=way_status) + else: + await call.answer( + "❗ Приватный ключ отсутствует. Измените киви и добавьте приватный ключ для включения оплаты по Форме", + True) + elif way_pay == "Number": + update_upaymentx(way_number=way_status) + elif way_pay == "Nickname": + status, response = await (await QiwiAPI(call)).get_nickname() + if status: + update_upaymentx(way_nickname=way_status, + qiwi_nickname=response) + else: + await call.answer(response, True) + else: + await call.answer("❗ Добавьте киви кошелёк перед включением Способов пополнений.", True) + + try: + await call.message.edit_text("🖲 Выберите способ пополнения", reply_markup=payment_as_choice_finl()) + except: + pass + + +####################################### QIWI ###################################### +# Изменение QIWI кошелька +@dp.message_handler(IsShopAdmin(), text="🥝 Изменить QIWI 🖍", state="*") +async def payment_qiwi_edit(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_qiwi_login") + await message.answer("🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Проверка работоспособности QIWI +@dp.message_handler(IsShopAdmin(), text="🥝 Проверить QIWI ♻", state="*") +async def payment_qiwi_check(message: Message, state: FSMContext): + print("Проверка КИВИ админом магазина") + await state.finish() + + await (await QiwiAPI(message, check_pass=True)).pre_checker() + + +# Баланс QIWI +@dp.message_handler(IsShopAdmin(), text="🥝 Баланс QIWI 👁", state="*") +async def payment_qiwi_balance(message: Message, state: FSMContext): + await state.finish() + + await (await QiwiAPI(message)).get_balance() + + +######################################## ПРИНЯТИЕ QIWI ######################################## +# Принятие логина для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_login") +async def payment_qiwi_edit_login(message: Message, state: FSMContext): + if message.text.startswith("+"): + await state.update_data(here_qiwi_login=message.text) + + await state.set_state("here_qiwi_token") + await message.answer( + "🥝 Введите токен API QIWI кошелька 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ При получении токена, ставьте только первые 3 галочки.", + disable_web_page_preview=True + ) + else: + await message.answer("❌ Номер должен начинаться с + (+7..., +380...)\n" + "🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Принятие токена для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_token") +async def payment_qiwi_edit_token(message: Message, state: FSMContext): + await state.update_data(here_qiwi_token=message.text) + + await state.set_state("here_qiwi_secret") + await message.answer( + "🥝 Введите Секретный ключ 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ Вы можете пропустить добавление оплаты по Форме, отправив: 0", + disable_web_page_preview=True + ) + + +# Принятие приватного ключа для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_secret") +async def payment_qiwi_edit_secret(message: Message, state: FSMContext): + async with state.proxy() as data: + qiwi_login = data['here_qiwi_login'] + qiwi_token = data['here_qiwi_token'] + if message.text == "0": + qiwi_secret = "None" + if message.text != "0": + qiwi_secret = message.text + + await state.finish() + + cache_message = await message.answer("🥝 Проверка введённых QIWI данных... 🔄") + await asyncio.sleep(0.5) + + await (await QiwiAPI(cache_message, qiwi_login, qiwi_token, qiwi_secret, True)).pre_checker() + +################################################################################################ +###################################### УДАЛЕНИЕ ВСЕХ ПОЗИЦИЙ ################################### +# Согласие на удаление всех позиций и товаров + + +@dp.callback_query_handler(IsShopAdmin(), text_startswith="confirm_remove_position:", state="*") +async def product_position_remove(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + + if get_action == "yes": + get_positions = len(get_all_positionsx()) + get_items = len(get_all_my_itemsx()) + + clear_positionx() + clear_itemx() + + await call.message.edit_text( + f"📁 Вы удалили все позиции({get_positions}шт) и товары({get_items}шт)") + else: + await call.message.edit_text("📁 Вы отменили удаление всех позиций ✅") + + +############################################################################################### +################################################################################################ +####################################### ДОБАВЛЕНИЕ ПОЗИЦИЙ ##################################### +# Следующая страница выбора категорий для создания позиций +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_create_nextp:", state="*") +async def product_position_create_next(call: CallbackQuery, state: FSMContext): + print(f'выбора категорий для создания позиций user_menu.py 126') + remover = int(call.data.split(":")[1]) + print(remover) + + await call.message.edit_text("📁 Выберите категорию для позиции ➕", + reply_markup=position_create_next_page_fp(remover)) + + +# Предыдущая страница выбора категорий для создания позиций +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_create_backp:", state="*") +async def product_position_create_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию для позиции ➕", + reply_markup=position_create_back_page_fp(remover)) + + +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_shop_create_here:", state="*") +async def product_position_create(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + await state.update_data(here_cache_change_shop_id=category_id) + + if len(get_all_categoriesx()) >= 1: + await call.message.answer("📁 Выберите категорию для позиции", + reply_markup=position_create_open_fp(0)) + else: + await call.message.answer("❌ Отсутствуют категории для создания позиции.") + + +# Выбор категории для создания позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_create_here:", state="*") +async def product_position_create_select_category(call: CallbackQuery, state: FSMContext): + print('position_create_here - user_menu 160') + category_id = int(call.data.split(":")[1]) + + await state.update_data(here_cache_change_category_id=category_id) + + await state.set_state("here_position_name") + await call.message.edit_text("📁 Введите название для позиции 🏷") + + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Заготовка под принятие города магазином +# Принятие города для создания позиции +# @dp.message_handler(IsShopAdmin(), state="here_position_city") +# async def product_position_create_name(message: Message, state: FSMContext): +# print(f'Принятие города для создания позиции admin_products_shop.py 344') +# city_user = get_city_user(message.from_user.id) +# Принятие имени для создания позиции +@dp.message_handler(IsShopAdmin(), state="here_position_name") +async def product_position_create_name(message: Message, state: FSMContext): + print(f'Принятие имени для создания позиции admin_products.py 355') + if len(message.text) <= 100: + await state.update_data(here_position_name=clear_html(message.text), here_position_city=get_city_user(message.from_user.id)[0], position_city_id=get_city_user(message.from_user.id)[2]) + + await state.set_state("here_position_price") + await message.answer("📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "📁 Введите название для позиции 🏷") + + +# Принятие цены позиции для её создания +@dp.message_handler(IsShopAdmin(), state="here_position_price") +async def product_position_create_price(message: Message, state: FSMContext): + print(f'Принятие цены позиции admin_products.py 366') + if message.text.isdigit(): + if 0 <= int(message.text) <= 10000000: + await state.update_data(here_position_price=message.text) + + await state.set_state("here_position_description") + await message.answer("📁 Введите описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + else: + await message.answer("❌ Цена не может быть меньше 0 или больше 10 000 000.\n" + "📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Данные были введены неверно.\n" + "📁 Введите цену для позиции 💰") + + +# Принятие описания позиции для её создания +@dp.message_handler(IsShopAdmin(), state="here_position_description") +async def product_position_create_description(message: Message, state: FSMContext): + print(f'Принятие описания позиции admin_products.py 386') + + try: + if len(message.text) <= 600: + if message.text != "0": + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + await state.update_data(here_position_description=message.text) + + await state.set_state("here_position_photo") + await message.answer("📁 Отправьте изображение для позиции 📸\n" + "❕ Отправьте 0 чтобы пропустить.") + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📁 Введите описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие изображения позиции для её создания +@dp.message_handler(IsShopAdmin(), content_types="photo", state="here_position_photo") +@dp.message_handler(IsShopAdmin(), text="0", state="here_position_photo") +async def product_position_create_photo(message: Message, state: FSMContext): + print(f'Принятие изображения позиции admin_products.py 418') + async with state.proxy() as data: + position_user_id = message.from_user.id + position_city = data['here_position_city'] + position_city_id = data['position_city_id'] + position_name = clear_html(data['here_position_name']) + position_price = data['here_position_price'] + catategory_id = data['here_cache_change_category_id'] + position_description = data['here_position_description'] + await state.finish() + + if "text" in message: + position_photo = "" + else: + position_photo = message.photo[-1].file_id + + add_positionx(position_city, position_city_id, position_name, position_price, + position_description, position_photo, catategory_id, position_user_id) + + await message.answer("📁 Позиция была успешно создана ✅") + + +################################################################################################ +####################################### ИЗМЕНЕНИЕ ПОЗИЦИЙ ##################################### +# Возвращение к начальным категориям для редактирования позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_category_return", state="*") +async def product_position_edit_return(call: CallbackQuery, state: FSMContext): + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_open_fp(0)) + + +# Следующая страница категорий для редактирования позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_category_nextp:", state="*") +async def product_position_edit_category_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_next_page_fp(remover)) + + +# Предыдущая страница категорий для редактирования позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_category_backp:", state="*") +async def product_position_edit_category_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_back_page_fp(remover)) + + +# Выбор категории с нужной позицией +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_category:", state="*") +async def product_position_edit_category_open(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.edit_text("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(0, category_id)) + else: + await call.answer("📁 Позиции в данной категории отсутствуют") + + +# Следующая страница позиций для их изменения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_nextp:", state="*") +async def product_position_edit_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_next_page_fp(remover, category_id)) + + +# Предыдущая страница позиций для их изменения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_backp:", state="*") +async def product_position_edit_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_back_page_fp(remover, category_id)) + + +# Выбор позиции для редактирования +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit:", state="*") +async def product_position_edit_open(call: CallbackQuery, state: FSMContext): + print(f'Выбор позиции для редактирования api_sqlite.py 496') + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + user_id = call.from_user.id + + # IsProductShopAdmin() + adminspos = check_position_owner(user_id, position_id) + if adminspos is True: + + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.answer("❗ У Вас нет прав редактировать данную позицию.") + + +# Возвращение к выбору позиции для изменения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_return", state="*") +async def product_position_edit_return(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.delete() + await call.message.answer("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(remover, category_id)) + else: + await call.answer("❗ Позиции в данной категории отсутствуют") + + +######################################## САМО ИЗМЕНЕНИЕ ПОЗИЦИИ ######################################## +# Изменение имени позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_name", state="*") +async def product_position_edit_name(call: CallbackQuery, state: FSMContext): + print(f'Изменение имени позиции api_sqlite.py 529') + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_name") + await call.message.delete() + await call.message.answer("📁 Введите новое название для позиции 🏷") + + +# Принятие имени позиции для её изменения +@dp.message_handler(IsShopAdmin(), state="here_change_position_name") +async def product_position_edit_name_get(message: Message, state: FSMContext): + if len(message.text) <= 100: + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + update_positionx(position_id, position_name=clear_html(message.text)) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "📁 Введите новое название для позиции 🏷") + + +# Изменение цены позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_price", state="*") +async def product_position_edit_price(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_price") + await call.message.delete() + await call.message.answer("📁 Введите новую цену для позиции 💰") + + +# Принятие цены позиции для её изменения +@dp.message_handler(IsShopAdmin(), state="here_change_position_price") +async def product_position_edit_price_get(message: Message, state: FSMContext): + if message.text.isdigit(): + if 0 <= int(message.text) <= 10000000: + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + update_positionx(position_id, position_price=message.text) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Цена не может быть меньше 0 или больше 10 000 000.\n" + "📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Данные были введены неверно.\n" + "📁 Введите цену для позиции 💰") + + +# Изменение описания позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_description", state="*") +async def product_position_edit_description(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_description") + await call.message.delete() + await call.message.answer("📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие описания позиции для её изменения +@dp.message_handler(IsShopAdmin(), state="here_change_position_description") +async def product_position_edit_description_get(message: Message, state: FSMContext): + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + + try: + if len(message.text) <= 600: + await state.finish() + + if message.text != "0": + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + update_positionx(position_id, position_description=message.text) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Изменение изображения позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_photo", state="*") +async def product_position_edit_photo(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_photo") + await call.message.delete() + await call.message.answer("📁 Отправьте новое изображение для позиции 📸\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие нового фото для позиции +@dp.message_handler(IsShopAdmin(), content_types="photo", state="here_change_position_photo") +@dp.message_handler(IsShopAdmin(), text="0", state="here_change_position_photo") +async def product_position_edit_photo_get(message: Message, state: FSMContext): + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + if "text" in message: + position_photo = "" + else: + position_photo = message.photo[-1].file_id + + update_positionx(position_id, position_photo=position_photo) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# --------------------------- Добавлено 12.08.22 ------------------------------------------ + +# Изменение города продукта +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_city", state="*") +async def product_position_edit_description(call: CallbackQuery, state: FSMContext): + print(f'Изменение города продукта admin_products.py 715') + print(call.data) + category_id = int(call.data.split(":")[2]) + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[3]) + + current_city = get_city_user(call.from_user.id)[0] + + # await state.update_data(here_cache_category_id=category_id) + # await state.update_data(here_cache_position_id=position_id) + # await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_city") + await state.update_data({'position_id': position_id, 'category_id': category_id, 'remover': remover}) + await call.message.delete() + await call.message.answer("📁 Выбирите другой город 🏙\n" + "❕ Вы можете использовать геолокацию или выбрать город из списка\n" + f"❕ Город товара: {current_city}", reply_markup=geo_1_kb()) + + +# принятие новой геопозиции для позиции +@dp.callback_query_handler(text_startswith='geo_chosen_cities', state='here_change_city') +async def geo_5(cb: CallbackQuery, state: FSMContext): + info = int(str(cb.data).split('#')[1]) + if info == 0: + async with state.proxy() as data: + city = data['city'] + position_id = int(data['position_id']) + category_id = data['category_id'] + remover = data['remover'] + city_id = data['city_id'] + + else: + async with state.proxy() as data: + position_id = int(data['position_id']) + category_id = data['category_id'] + remover = data['remover'] + + city_id = info + city = get_city_info(info) + + await state.finish() + update_position_city(city[0], city_id, position_id) + + # update_positionx(position_id) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await cb.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await cb.message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +################################################################################################ +# Просмотр истории покупок +@dp.callback_query_handler(text="user_history", state="*") +async def user_history(call: CallbackQuery, state: FSMContext): + last_purchases = last_purchasesx(call.from_user.id, 5) + + if len(last_purchases) >= 1: + await call.answer("🎁 Последние 5 покупок") + await call.message.delete() + + for purchases in last_purchases: + link_items = await upload_text(call, purchases['purchase_item']) + + await call.message.answer(f"🧾 Чек: #{purchases['purchase_receipt']}\n" + f"🎁 Аренда: {purchases['purchase_position_name']} | {purchases['purchase_count']}шт | {purchases['purchase_price']}₽\n" + f"🕰 Дата покупки: {purchases['purchase_date']}\n" + f"🔗 Товары: кликабельно") + + await call.message.answer(open_profile_my(call.from_user.id), reply_markup=profile_open_inl) + else: + await call.answer("❗ У вас отсутствуют покупки", True) + + +# Возвращение к профилю +@dp.callback_query_handler(text="user_profile", state="*") +async def user_profile_return(call: CallbackQuery, state: FSMContext): + await call.message.edit_text(open_profile_my(call.from_user.id), reply_markup=profile_open_inl) + + +################################################################################################ +######################################### ПОКУПКА ТОВАРА ####################################### +########################################### КАТЕГОРИИ ########################################## +# Открытие категорий для покупки +@dp.callback_query_handler(text_startswith="buy_category_open", state="*") +async def user_purchase_category_open(call: CallbackQuery, state: FSMContext): + print(f'Открытие категорий для покупки user_menu.py 133') + category_id = int(call.data.split(":")[1]) + + get_category = get_categoryx(category_id=category_id) + city = get_city_user(call.from_user.id) + # get_positionsx(category_id=category_id) + get_positions = get_position_on_city(category_id, city[2]) + + if len(get_positions) >= 1: + await call.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_position_open_fp(0, category_id, city[2])) + else: + await call.answer(f"❕ Товары в категории {get_category['category_name']} отсутствуют") + + +# Вернуться к категориям для покупки +@dp.callback_query_handler(text_startswith="buy_category_return", state="*") +async def user_purchase_category_return(call: CallbackQuery, state: FSMContext): + get_categories = get_all_categoriesx() + + city = get_city_user(call.from_user.id) + + if len(get_categories) >= 1: + await call.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_category_open_fp(0, city[2])) + else: + await call.message.edit_text("🎁 Товары в данное время отсутствуют.") + await call.answer("❗ Категории были изменены или удалены") + + +# Следующая страница категорий для покупки +@dp.callback_query_handler(text_startswith="buy_category_nextp", state="*") +async def user_purchase_category_next_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_category_next_page_fp(remover)) + + +# Предыдущая страница категорий для покупки +@dp.callback_query_handler(text_startswith="buy_category_backp", state="*") +async def user_purchase_category_prev_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_category_back_page_fp(remover)) + + +########################################### ПОЗИЦИИ ########################################## +# Открытие позиции для покупки +@dp.callback_query_handler(text_startswith="buy_position_open", state="*") +async def user_purchase_position_open(call: CallbackQuery, state: FSMContext): + print(f'🎁 Покупка товара: user_menu.py 152') + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + + get_position = get_positionx(position_id=position_id) + get_category = get_categoryx(category_id=category_id) + get_items = get_itemsx(position_id=position_id) + + if get_position['position_description'] == "0": + text_description = "" + else: + text_description = f"\n📜 Описание:\n" \ + f"{get_position['position_description']}" + + send_msg = f"🎁 Покупка товара:\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🏷 Название: {get_position['position_name']}\n" \ + f"🏙 Город: {get_position['position_city']}\n" \ + f"🗃 Категория: {get_category['category_name']}\n" \ + f"💰 Стоимость: {get_position['position_price']}₽\n" \ + f"📦 Количество: {len(get_items)}шт" \ + f"{text_description}" + + if len(get_position['position_photo']) >= 5: + await call.message.delete() + await call.message.answer_photo(get_position['position_photo'], + send_msg, reply_markup=products_open_finl(position_id, remover, category_id)) + else: + await call.message.edit_text(send_msg, + reply_markup=products_open_finl(position_id, remover, category_id)) + + +# Вернуться к позициям для покупки +@dp.callback_query_handler(text_startswith="buy_position_return", state="*") +async def user_purchase_position_return(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + get_positions = get_all_positionsx() + city = get_city_user(call.from_user.id) + + if len(get_positions) >= 1: + await call.message.delete() + await call.message.answer("🎁 Выберите нужный вам товар:", + reply_markup=products_item_position_open_fp(remover, category_id, city[2])) + else: + await call.message.edit_text("🎁 Товары в данное время отсутствуют.") + await call.answer("❗ Позиции были изменены или удалены") + + +# Следующая страница позиций для покупки +@dp.callback_query_handler(text_startswith="buy_position_nextp", state="*") +async def user_purchase_position_next_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_position_next_page_fp(remover, category_id)) + + +# Предыдущая страница позиций для покупки +@dp.callback_query_handler(text_startswith="buy_position_backp", state="*") +async def user_purchase_position_prev_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=buy_position_return_page_fp(remover, category_id)) + + +########################################### ПОКУПКА ########################################## +# Выбор количества товаров для покупки +@dp.callback_query_handler(text_startswith="buy_item_select", state="*") +async def user_purchase_select(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + get_user = get_userx(user_id=call.from_user.id) + + if get_position['position_price'] != 0: + get_count = int(get_user['user_balance'] / + get_position['position_price']) + if get_count > len(get_items): + get_count = len(get_items) + else: + get_count = len(get_items) + + if int(get_user['user_balance']) >= int(get_position['position_price']): + if get_count == 1: + await state.update_data(here_cache_position_id=position_id) + await state.finish() + + await call.message.delete() + await call.message.answer(f"🎁 Вы действительно хотите купить товар(ы)?\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Срок аренды: {get_position['position_name']}\n" + f"📦 Количество: 1шт\n" + f"💰 Сумма к покупке: {get_position['position_price']}₽", + reply_markup=products_confirm_finl(position_id, 1)) + elif get_count >= 1: + await state.update_data(here_cache_position_id=position_id) + await state.set_state("here_item_count") + + await call.message.delete() + await call.message.answer(f"🎁 Введите количество аккаунтов которое хотите купить\n" + f"▶ От 1 до {get_count}\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Аренда: {get_position['position_name']} - {get_position['position_price']}₽\n" + f"💰 Ваш баланс: {get_user['user_balance']}₽") + else: + await call.answer("🎁 Товаров нет в наличии") + else: + await call.answer("❗ У вас недостаточно средств. Пополните баланс", True) + + +# Принятие количества товаров для покупки +@dp.message_handler(state="here_item_count") +async def user_purchase_select_count(message: Message, state: FSMContext): + position_id = (await state.get_data())['here_cache_position_id'] + + get_position = get_positionx(position_id=position_id) + get_user = get_userx(user_id=message.from_user.id) + get_items = get_itemsx(position_id=position_id) + + if get_position['position_price'] != 0: + get_count = int(get_user['user_balance'] / + get_position['position_price']) + if get_count > len(get_items): + get_count = len(get_items) + else: + get_count = len(get_items) + + send_message = f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🎁 Введите количество аккаунтов которое хотите купить\n" \ + f"▶ От 1 до {get_count}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🎁 Товар: {get_position['position_name']} - {get_position['position_price']}₽\n" \ + f"💰 Ваш баланс: {get_user['user_balance']}₽" + + if message.text.isdigit(): + get_count = int(message.text) + amount_pay = int(get_position['position_price']) * get_count + + if len(get_items) >= 1: + if 1 <= get_count <= len(get_items): + if int(get_user['user_balance']) >= amount_pay: + await state.finish() + await message.answer(f"🎁 Вы действительно хотите купить товар(ы)?\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Срок аренды: {get_position['position_name']}\n" + f"📦 Количество: {get_count}шт\n" + f"💰 Сумма к покупке: {amount_pay}₽", + reply_markup=products_confirm_finl(position_id, get_count)) + else: + await message.answer(f"❌ Недостаточно средств на счете.\n" + send_message) + else: + await message.answer(f"❌ Неверное количество товаров.\n" + send_message) + else: + await state.finish() + await message.answer("🎁 Товар который вы хотели купить, закончился") + else: + await message.answer(f"❌ Данные были введены неверно.\n" + send_message) + + +# Подтверждение покупки товара +@dp.callback_query_handler(text_startswith="xbuy_item", state="*") +async def user_purchase_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + get_count = int(call.data.split(":")[3]) + + if get_action == "yes": + await call.message.edit_text("🔄 Ждите, товары подготавливаются") + + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + get_user = get_userx(user_id=call.from_user.id) + + amount_pay = int(get_position['position_price'] * get_count) + + if 1 <= int(get_count) <= len(get_items): + if int(get_user['user_balance']) >= amount_pay: + save_items, send_count, split_len = buy_itemx( + get_items, get_count) + + if get_count != send_count: + amount_pay = int( + get_position['position_price'] * send_count) + get_count = send_count + + receipt = get_unix() + buy_time = get_date() + + await call.message.delete() + if split_len == 0: + await call.message.answer("\n\n".join(save_items), parse_mode="None") + else: + for item in split_messages(save_items, split_len): + await call.message.answer("\n\n".join(item), parse_mode="None") + await asyncio.sleep(0.3) + + update_userx( + get_user['user_id'], user_balance=get_user['user_balance'] - amount_pay) + add_purchasex(get_user['user_id'], get_user['user_login'], get_user['user_name'], receipt, get_count, + amount_pay, get_position['position_price'], get_position['position_id'], + get_position['position_name'], "\n".join( + save_items), buy_time, receipt, + get_user['user_balance'], int(get_user['user_balance'] - amount_pay)) + + await call.message.answer(f"✅ Вы успешно купили товар(ы)\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🧾 Чек: #{receipt}\n" + f"🎁 Товар: {get_position['position_name']} | {get_count}шт | {amount_pay}₽\n" + f"🕰 Дата покупки: {buy_time}", + reply_markup=menu_frep(call.from_user.id)) + else: + await call.message.answer("❗ На вашем счёте недостаточно средств") + else: + await call.message.answer("🎁 Товар который вы хотели купить закончился или изменился.", + reply_markup=menu_frep(call.from_user.id)) + else: + if len(get_all_categoriesx()) >= 1: + await call.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_category_open_fp(0)) + else: + await call.message.edit_text("✅ Вы отменили покупку товаров.") diff --git a/TelegramGoodsinbot/tgbot/handlers/user_menu.py b/TelegramGoodsinbot/tgbot/handlers/user_menu.py new file mode 100644 index 0000000..519fc59 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/user_menu.py @@ -0,0 +1,2012 @@ +# - *- coding: utf- 8 - *- +import asyncio +import json +from aiogram.dispatcher import FSMContext +#from aiogram import Bot +from aiogram import Dispatcher + +from aiogram.types import CallbackQuery, Message, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove + +from tgbot.data.config import BOT_DESCRIPTION +from tgbot.keyboards.inline_admin import category_edit_open_finl, position_edit_open_finl, category_edit_delete_finl, \ + position_edit_clear_finl, position_edit_delete_finl, payment_choice_finl +from tgbot.keyboards.inline_user import user_support_finl, products_open_finl, products_confirm_finl, \ + products_addcart_confirm_finl, payment_as_choice_finl, accept_saved_adr, accept_saved_phone, \ + cart_enter_message_finl, give_number_inl, reply_order_message_finl, refill_choice_finl, charge_button_add, products_open_cart_finl +from tgbot.keyboards.inline_z_all import category_remove_confirm_inl, position_remove_confirm_inl, \ + item_remove_confirm_inl, close_inl, confirm_delete_user_cart_inl +from tgbot.keyboards.inline_z_all import refill_open_inl, profile_open_inl, cart_open_created_inl, cart_open_delivery_inl, checkout_step2_accept, order_user_refill +from tgbot.keyboards.inline_z_page import * +from tgbot.keyboards.reply_z_all import finish_load_rep +from tgbot.keyboards.reply_z_all import menu_frep, items_sh_frep +from tgbot.loader import dp +from tgbot.loader import bot +from tgbot.services.api_qiwi import QiwiAPI +from tgbot.services.api_sqlite import * +from tgbot.utils.const_functions import get_date, split_messages, get_unix, clear_list +from tgbot.utils.misc.bot_filters import IsShopAdmin, IsAdminorShopAdmin +from tgbot.utils.misc_functions import user_refill_my, calc_cart_summ, open_cart_my, open_profile_my, upload_text, get_faq, send_admins +from tgbot.utils.misc_functions import get_position_admin, upload_text + + +async def notify(dp: Dispatcher, msg): + print('Уведомление!') + await send_admins(msg, markup="default") +################################################################################################ +# Заявка на продавца магазина +# Открытие товаров + + +@dp.message_handler(text="Хочу продавать", state="*") +async def user_seller_request(message: Message, state: FSMContext): + # await state.finish() + await state.set_state("here_seller_request_direction") + await message.answer("📁 Введите вид товаров или услуг, которые Вы предлагаете:") + +# Управление товарами + + +@dp.message_handler(IsShopAdmin(), text="🎁 Управление товарами дмаг.🖍", state="*") +async def shopadmin_products(message: Message, state: FSMContext): + await state.finish() + await message.answer("🎁 Редактирование товаров дмаг.", reply_markup=items_sh_frep()) + + +@dp.message_handler(text="🗃 Создать категорию ➕", state="*") +async def product_category_create(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_category_name") + await message.answer("🗃 Введите название для категории 🏷") + + +# Начальные категории для изменения позиции +# !!!!!!! Изменить позицию +@dp.message_handler(IsShopAdmin(), text="📁 Изменить позицию 🖍", state="*") +async def product_position_edit(message: Message, state: FSMContext): + print(f'📁 Изменить позицию 🖍 user_menu.py 56') + await state.finish() + + await message.answer("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_open_fp(0)) + + +# Открытие товаров +@dp.message_handler(text="🎁 Игры в аренду", state="*") +async def user_shop(message: Message, state: FSMContext): + print(f'Открытие категорий товаров user_menu.py 65') + await state.finish() + + get_settings = get_settingsx() + if(get_settings['type_trade'] != 'digital'): + city_id = get_city_user(message.from_user.id)[0] + #get_categories = get_category_in_city(city_id) + if len(get_category_in_city(city_id)) >= 1: + await message.answer("🎁 Выберите нужную игру:", + reply_markup=products_item_category_open_fp(0, city_id)) + else: + await message.answer("🎁 Игр доступных пока нет\n\n") + else: # if len(get_all_categoriesx()) >= 1 + await message.answer("🎁 Выберите нужную игру:", + reply_markup=products_item_category_open_fp(0, None)) + +# Открытие пополнения счета + + +@dp.message_handler(text="💰 Пополнить", state="*") +async def user_refill_b(message: Message, state: FSMContext): + await state.finish() + await message.answer(user_refill_my(message.from_user.id), reply_markup=refill_open_inl) + +# refiil_way(message.from_user.id) + +# Открытие профиля + + +@dp.message_handler(text="👤 Профиль", state="*") +async def user_profile(message: Message, state: FSMContext): + await state.finish() + await message.answer(open_profile_my(message.from_user.id), reply_markup=profile_open_inl) + +# Открытие корзины + + +@dp.message_handler(text="🧮 Корзина", state="*") +async def user_cart(message: Message, state: FSMContext): + await state.finish() + user_id = message.from_user.id + orderdata = get_params_orderx(user_id=user_id) + print(orderdata) + for order in orderdata: + print(order['order_state']) + if order['order_state'] == 'delivery': + await message.answer(open_cart_my(message.from_user.id), reply_markup=cart_open_delivery_inl) + if order['order_state'] == 'created': + await message.answer(open_cart_my(message.from_user.id), reply_markup=cart_open_created_inl) + if order['order_state'] == 'submited': + await message.answer(f"Активных заказов нет.\n") + +# Открытие FAQ + + +@dp.message_handler(text=["ℹ FAQ", "/faq"], state="*") +async def user_faq(message: Message, state: FSMContext): + await state.finish() + + send_message = get_settingsx()['misc_faq'] + if send_message == "None": + send_message = f"ℹ Информация. Измените её в настройках бота.\n➖➖➖➖➖➖➖➖➖➖➖➖➖\n{BOT_DESCRIPTION}" + + await message.answer(get_faq(message.from_user.id, send_message), disable_web_page_preview=True) + + +# ----------------------------------------------------------------------------------------------------------- +# Открытие страниц выбора магазина для редактирования +@dp.message_handler(IsShopAdmin(), text="🏪 Изменить магазин 🖍", state="*") +async def product_category_edit(message: Message, state: FSMContext): + await state.finish() + user_id = message.from_user.id + + shops = get_my_shopx(user_id) + print(f'shops {shops}') + + if len(shops) >= 1: + await message.answer("🏪 Выберите магазин для изменения 🖍", + reply_markup=shop_edit_open_fp(0, shops)) + else: + await message.answer("🏪 Магазины отсутствуют 🖍") + + +# Открытие сообщения с ссылкой на поддержку +@dp.message_handler(text=["☎ Поддержка/FAQ", "/support"], state="*") +async def user_support(message: Message, state: FSMContext): + await state.finish() + + user_support = get_settingsx()['misc_support'] + if str(user_support).isdigit(): + get_user = get_userx(user_id=user_support) + + if len(get_user['user_login']) >= 1: + await message.answer("☎ Нажмите кнопку ниже для связи с Администратором.", + reply_markup=user_support_finl(get_user['user_login'])) + return + else: + update_settingsx(misc_support="None") + + await message.answer(f"☎ Поддержка/FAQ.\n➖➖➖➖➖➖➖➖➖➖➖➖➖\n{BOT_DESCRIPTION}", + disable_web_page_preview=True) + + +# Создание запроса на продавца +@dp.message_handler(state="here_seller_request_direction") +async def user_seller(message: Message, state: FSMContext): + await state.finish() + # message.answer(message.text) + seller_request = create_seller_request(message.from_user.id, message.text) + await message.answer("👌 Ваш запрос успешно отправлен.") + +# Просмотр истории покупок + + +@dp.callback_query_handler(text="create_seller_request5", state="*") +async def user_seller(call: CallbackQuery, state: FSMContext): + seller_request = create_seller_request(call.from_user.id) + await call.answer("🎁 Запрос успешно создан") + await notify(dp, f"Поступил новый запрос продавца!") + # await bot.send_message(get_admins(), "ntcnnnnnn") + +# Подтверждение удаления всех позиций + + +@dp.message_handler(IsShopAdmin(), text="📁 Удалить все позиции ❌", state="*") +async def product_position_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("📁 Вы действительно хотите удалить все позиции? ❌\n" + "❗ Так же будут удалены все товары", + reply_markup=position_remove_confirm_inl) + +# Удаление позиции + + +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_delete", state="*") +async def product_position_edit_delete(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await call.message.delete() + await call.message.answer("📁 Вы действительно хотите удалить позицию? ❌", + reply_markup=position_edit_delete_finl(position_id, category_id, remover)) + + +# Подтверждение удаления позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_delete", state="*") +async def product_position_edit_delete_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + remover = int(call.data.split(":")[4]) + + if get_action == "yes": + remove_itemx(position_id=position_id) + remove_positionx(position_id=position_id) + + await call.answer("📁 Вы успешно удалили позицию и её товары ✅") + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.edit_text("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(remover, category_id)) + else: + await call.message.delete() + else: + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Согласие очистики позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_clear", state="*") +async def product_position_edit_clear_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + remover = int(call.data.split(":")[4]) + + if get_action == "yes": + remove_itemx(position_id=position_id) + await call.answer("📁 Вы успешно удалили все товары позиции ✅") + + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# Открытие способов пополнения +@dp.message_handler(IsShopAdmin(), text="🖲 Способы пополнения", state="*") +async def payment_systems(message: Message, state: FSMContext): + await state.finish() + user_id = message.from_user.id + + await message.answer("🖲 Выберите способ пополнения", reply_markup=payment_as_choice_finl(user_id)) + + +# Включение/выключение самих способов пополнения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="change_payment:") +async def payment_systems_edit(call: CallbackQuery): + way_pay = call.data.split(":")[1] + way_status = call.data.split(":")[2] + user_id = call.data.split(":")[3] + print("Админ магазина") + # print(call.data.split(":")[0]) + print(call.from_user.id) + get_payment = get_upaymentx(user_id) + + if get_payment['qiwi_login'] != "None" and get_payment['qiwi_token'] != "None" or way_status == "False": + if way_pay == "Form": + if get_payment['qiwi_secret'] != "None" or way_status == "False": + update_upaymentx(user_id, way_form=way_status) + else: + await call.answer( + "❗ Приватный ключ отсутствует. Измените киви и добавьте приватный ключ для включения оплаты по Форме", + True) + elif way_pay == "ForYm": + if get_payment['yoo_token'] != "None" or way_status == "False": + update_upaymentx(user_id, way_formy=way_status) + else: + await call.answer( + "❗ Номер счета отсутствует. Измените YooMoney и добавьте токен для включения оплаты по Форме YooMoney", + True) + elif way_pay == "Number": + update_paymentx(way_number=way_status) + elif way_pay == "Nickname": + status, response = await (await QiwiAPI(call)).get_nickname() + if status: + update_upaymentx( + user_id, way_nickname=way_status, qiwi_nickname=response) + else: + await call.answer(response, True) + else: + await call.answer("❗ Добавьте киви кошелёк перед включением Способов пополнений.", True) + + try: + await call.message.edit_text("🖲 Выберите способ пополнения", reply_markup=payment_as_choice_finl()) + except: + pass + + +####################################### QIWI ###################################### +# Изменение QIWI кошелька +@dp.message_handler(IsShopAdmin(), text="🥝 Изменить QIWI 🖍", state="*") +async def payment_qiwi_edit(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_qiwi_login") + await message.answer("🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Проверка работоспособности QIWI +@dp.message_handler(IsShopAdmin(), text="🥝 Проверить QIWI ♻", state="*") +async def payment_qiwi_check(message: Message, state: FSMContext): + print("Проверка КИВИ админом магазина") + await state.finish() + + await (await QiwiAPI(message, check_pass=True)).pre_checker() + + +# Баланс QIWI +@dp.message_handler(IsShopAdmin(), text="🥝 Баланс QIWI 👁", state="*") +async def payment_qiwi_balance(message: Message, state: FSMContext): + await state.finish() + + await (await QiwiAPI(message)).get_balance() + + +######################################## ПРИНЯТИЕ QIWI ######################################## +# Принятие логина для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_login") +async def payment_qiwi_edit_login(message: Message, state: FSMContext): + if message.text.startswith("+"): + await state.update_data(here_qiwi_login=message.text) + + await state.set_state("here_qiwi_token") + await message.answer( + "🥝 Введите токен API QIWI кошелька 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ При получении токена, ставьте только первые 3 галочки.", + disable_web_page_preview=True + ) + else: + await message.answer("❌ Номер должен начинаться с + (+7..., +380...)\n" + "🥝 Введите номер (через +7, +380) QIWI кошелька 🖍") + + +# Принятие токена для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_token") +async def payment_qiwi_edit_token(message: Message, state: FSMContext): + await state.update_data(here_qiwi_token=message.text) + + await state.set_state("here_qiwi_secret") + await message.answer( + "🥝 Введите Секретный ключ 🖍\n" + "❕ Получить можно тут 👉 Нажми на меня\n" + "❕ Вы можете пропустить добавление оплаты по Форме, отправив: 0", + disable_web_page_preview=True + ) + + +# Принятие приватного ключа для QIWI +@dp.message_handler(IsShopAdmin(), state="here_qiwi_secret") +async def payment_qiwi_edit_secret(message: Message, state: FSMContext): + async with state.proxy() as data: + qiwi_login = data['here_qiwi_login'] + qiwi_token = data['here_qiwi_token'] + if message.text == "0": + qiwi_secret = "None" + if message.text != "0": + qiwi_secret = message.text + + await state.finish() + + cache_message = await message.answer("🥝 Проверка введённых QIWI данных... 🔄") + await asyncio.sleep(0.5) + + await (await QiwiAPI(cache_message, qiwi_login, qiwi_token, qiwi_secret, True)).pre_checker() + + +################################################################################################ +###################################### УДАЛЕНИЕ ВСЕХ ПОЗИЦИЙ ################################### +# Согласие на удаление всех позиций и товаров +@dp.callback_query_handler(IsShopAdmin(), text_startswith="confirm_remove_position:", state="*") +async def product_position_remove(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + print("SA DEL POSITIONS") + user_id = call.from_user.id + print(user_id) + + if get_action == "yes": + + get_positions = len(get_all_my_positionsnx(position_user_id=user_id)) + print(get_positions) + get_items = len(get_all_my_itemsnx(creator_id=user_id)) + print(get_items) + + remove_positionx(position_user_id=user_id) + remove_itemx(creator_id=user_id) + + await call.message.edit_text( + f"📁 Вы удалили все позиции({get_positions}шт) и товары({get_items}шт)") + else: + await call.message.edit_text("📁 Вы отменили удаление всех позиций ✅") + +#################### УДАЛЕНИЕ ТОВАРОВ ################### +# Кнопки с подтверждением удаления всех категорий + + +@dp.message_handler(IsShopAdmin(), text="🎁 Удалить все товары ❌", state="*") +async def product_item_remove(message: Message, state: FSMContext): + await state.finish() + + await message.answer("🎁 Вы действительно хотите удалить все товары? ❌\n", + reply_markup=item_remove_confirm_inl) + +##################################### УДАЛЕНИЕ ВСЕХ ТОВАРОВ #################################### +# Согласие на удаление всех товаров + + +@dp.callback_query_handler(IsShopAdmin(), text_startswith="confirm_remove_item:", state="*") +async def product_item_remove(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + user_id = call.from_user.id + + if get_action == "yes": + get_items = len(get_all_my_itemsnx(creator_id=user_id)) + remove_itemx(creator_id=user_id) + + await call.message.edit_text(f"🎁 Вы удалили все товары({get_items}шт)") + else: + await call.message.edit_text("🎁 Вы отменили удаление всех товаров ✅") + + +# Удаление определённых товаров +@dp.message_handler(IsShopAdmin(), text="🎁 Удалить товары 🖍", state="*") +async def product_item_delete(message: Message, state: FSMContext): + await state.finish() + + await state.set_state("here_items_delete") + await message.answer("🖍 Вводите айди товаров, которые нужно удалить\n" + "❕ Получить айди товаров можно при изменении позиции\n" + "❕ Если хотите удалить несколько товаров, отправьте ID товаров через запятую или пробел. Пример:\n" + "▶ 123456,123456,123456\n" + "▶ 123456 123456 123456") + +################################################################################################ +####################################### УДАЛЕНИЕ ТОВАРОВ ###################################### +# Принятие айди товаров для их удаления + + +@dp.message_handler(IsShopAdmin(), state="here_items_delete") +async def product_item_delete_get(message: Message, state: FSMContext): + await state.finish() + user_id = message.from_user.id + + remove_ids, cancel_ids = [], [] # Айди удалённых и ненайденных товаров + get_item_ids_one, get_item_ids_two = [], [[]] + save_ids = [] + + if "," in message.text: + get_item_ids_one = clear_list(message.text.split(",")) + else: + get_item_ids_one = clear_list([message.text]) + + for item in get_item_ids_one: + if " " in item: + get_item_ids_two.append(item.split(" ")) + + if len(get_item_ids_two) == 1: + get_item_ids_two.append(get_item_ids_one) + + for check_item in get_item_ids_two: + for item in clear_list(check_item): + save_ids.append(item) + + save_ids = clear_list(save_ids) + + for item_id in save_ids: + #check_item = get_itemx(item_id=item_id) + check_item = get_itemx(item_id=item_id, creator_id=user_id) + if check_item is not None: + remove_itemx(item_id=item_id) + remove_ids.append(item_id) + else: + cancel_ids.append(item_id) + + remove_ids = ", ".join(remove_ids) + cancel_ids = ", ".join(cancel_ids) + + await message.answer(f"✅ Успешно удалённые товары:\n" + f"▶ {remove_ids}\n" + f"➖➖➖➖➖➖➖➖➖➖\n" + f"❌ Ненайденные товары:\n" + f"▶ {cancel_ids}") +############################################################################################### +################################################################################################ +####################################### ДОБАВЛЕНИЕ ПОЗИЦИЙ ##################################### +# Следующая страница выбора категорий для создания позиций + + +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_create_nextp:", state="*") +async def product_position_create_next(call: CallbackQuery, state: FSMContext): + print(f'выбора категорий для создания позиций user_menu.py 126') + remover = int(call.data.split(":")[1]) + print(remover) + + await call.message.edit_text("📁 Выберите категорию для позиции ➕", + reply_markup=position_create_next_page_fp(remover)) + + +# Предыдущая страница выбора категорий для создания позиций +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_create_backp:", state="*") +async def product_position_create_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию для позиции ➕", + reply_markup=position_create_back_page_fp(remover)) + + +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_shop_create_here:", state="*") +async def product_position_create(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + await state.update_data(here_cache_change_shop_id=category_id) + + if len(get_all_categoriesx()) >= 1: + await call.message.answer("📁 Выберите категорию для позиции", + reply_markup=position_create_open_fp(0)) + else: + await call.message.answer("❌ Отсутствуют категории для создания позиции.") + + +# Выбор категории для создания позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_create_here:", state="*") +async def product_position_create_select_category(call: CallbackQuery, state: FSMContext): + print('position_create_here - user_menu 160') + category_id = int(call.data.split(":")[1]) + + await state.update_data(here_cache_change_category_id=category_id) + + await state.set_state("here_position_name") + await call.message.edit_text("📁 Введите название для позиции 🏷") + + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Заготовка под принятие города магазином +# Принятие города для создания позиции +# @dp.message_handler(IsShopAdmin(), state="here_position_city") +# async def product_position_create_name(message: Message, state: FSMContext): +# print(f'Принятие города для создания позиции admin_products_shop.py 344') +# city_user = get_city_user(message.from_user.id) +# Принятие имени для создания позиции +@dp.message_handler(IsShopAdmin(), state="here_position_name") +async def product_position_create_name(message: Message, state: FSMContext): + print(f'Принятие имени для создания позиции user_menu.py 355') + if len(message.text) <= 100: + await state.update_data(here_position_name=clear_html(message.text), + here_position_city=get_citytext_user(message.from_user.id)[0], position_city_id=get_city_user(message.from_user.id)[0]) + + await state.set_state("here_position_price") + await message.answer("📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "📁 Введите название для позиции 🏷") + + +# Принятие цены позиции для её создания +@dp.message_handler(IsShopAdmin(), state="here_position_price") +async def product_position_create_price(message: Message, state: FSMContext): + print(f'Принятие цены позиции admin_products.py 366') + if message.text.isdigit(): + if 0 <= int(message.text) <= 10000000: + await state.update_data(here_position_price=message.text) + + await state.set_state("here_position_description") + await message.answer("📁 Введите описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + else: + await message.answer("❌ Цена не может быть меньше 0 или больше 10 000 000.\n" + "📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Данные были введены неверно.\n" + "📁 Введите цену для позиции 💰") + + +# Принятие описания позиции для её создания +@dp.message_handler(IsShopAdmin(), state="here_position_description") +async def product_position_create_description(message: Message, state: FSMContext): + print(f'Принятие описания позиции admin_products.py 386') + + try: + if len(message.text) <= 600: + if message.text != "0": + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + await state.update_data(here_position_description=message.text) + + await state.set_state("here_position_photo") + await message.answer("📁 Отправьте изображение для позиции 📸\n" + "❕ Отправьте 0 чтобы пропустить.") + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📁 Введите описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие изображения позиции для её создания +@dp.message_handler(IsShopAdmin(), content_types="photo", state="here_position_photo") +@dp.message_handler(IsShopAdmin(), text="0", state="here_position_photo") +async def product_position_create_photo(message: Message, state: FSMContext): + print(f'Принятие изображения позиции admin_products.py 418') + async with state.proxy() as data: + position_user_id = message.from_user.id + position_city = data['here_position_city'] + position_city_id = data['position_city_id'] + position_name = clear_html(data['here_position_name']) + position_price = data['here_position_price'] + catategory_id = data['here_cache_change_category_id'] + position_description = data['here_position_description'] + await state.finish() + + if "text" in message: + position_photo = "" + else: + position_photo = message.photo[-1].file_id + + add_positionx(position_city, position_city_id, position_name, position_price, position_description, position_photo, + catategory_id, position_user_id) + + # async def on_notify(dp: Dispatcher, msg, markup): + # await send_admins(msg, markup="default") + await notify(dp, f"Создана позиция: {position_name}, пользователем ID: {position_user_id}") + + await message.answer("📁 Позиция была успешно создана ✅") + + +################################################################################################ +####################################### ИЗМЕНЕНИЕ ПОЗИЦИЙ ##################################### +# Возвращение к начальным категориям для редактирования позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_category_return", state="*") +async def product_position_edit_return(call: CallbackQuery, state: FSMContext): + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_open_fp(0)) + + +# Следующая страница категорий для редактирования позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_category_nextp:", state="*") +async def product_position_edit_category_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_next_page_fp(remover)) + + +# Предыдущая страница категорий для редактирования позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_category_backp:", state="*") +async def product_position_edit_category_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_category_back_page_fp(remover)) + + +# Выбор категории с нужной позицией +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_category:", state="*") +async def product_position_edit_category_open(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.edit_text("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(0, category_id)) + else: + await call.answer("📁 Позиции в данной категории отсутствуют") + + +# Следующая страница позиций для их изменения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_nextp:", state="*") +async def product_position_edit_next(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_next_page_fp(remover, category_id)) + + +# Предыдущая страница позиций для их изменения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_backp:", state="*") +async def product_position_edit_back(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("📁 Выберите категорию с нужной позицией 🖍", + reply_markup=position_edit_back_page_fp(remover, category_id)) + + +# Выбор позиции для редактирования +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit:", state="*") +async def product_position_edit_open(call: CallbackQuery, state: FSMContext): + print(f'Выбор позиции для редактирования api_sqlite.py 496') + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + user_id = call.from_user.id + + # IsProductShopAdmin() + adminspos = check_position_owner(user_id, position_id) + if adminspos is True: + + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await call.message.delete() + await call.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.message.edit_text(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await call.answer("❗ У Вас нет прав редактировать данную позицию.") + + +# Возвращение к выбору позиции для изменения +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_return", state="*") +async def product_position_edit_return(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + + if len(get_positionsx(category_id=category_id)) >= 1: + await call.message.delete() + await call.message.answer("📁 Выберите нужную вам позицию 🖍", + reply_markup=position_edit_open_fp(remover, category_id)) + else: + await call.answer("❗ Позиции в данной категории отсутствуют") + + +######################################## САМО ИЗМЕНЕНИЕ ПОЗИЦИИ ######################################## +# Изменение имени позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_name", state="*") +async def product_position_edit_name(call: CallbackQuery, state: FSMContext): + print(f'Изменение имени позиции api_sqlite.py 529') + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_name") + await call.message.delete() + await call.message.answer("📁 Введите новое название для позиции 🏷") + + +# Принятие имени позиции для её изменения +@dp.message_handler(IsShopAdmin(), state="here_change_position_name") +async def product_position_edit_name_get(message: Message, state: FSMContext): + if len(message.text) <= 100: + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + update_positionx(position_id, position_name=clear_html(message.text)) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Название не может превышать 100 символов.\n" + "📁 Введите новое название для позиции 🏷") + + +# Изменение цены позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_price", state="*") +async def product_position_edit_price(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_price") + await call.message.delete() + await call.message.answer("📁 Введите новую цену для позиции 💰") + + +# Принятие цены позиции для её изменения +@dp.message_handler(IsShopAdmin(), state="here_change_position_price") +async def product_position_edit_price_get(message: Message, state: FSMContext): + if message.text.isdigit(): + if 0 <= int(message.text) <= 10000000: + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + update_positionx(position_id, position_price=message.text) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Цена не может быть меньше 0 или больше 10 000 000.\n" + "📁 Введите цену для позиции 💰") + else: + await message.answer("❌ Данные были введены неверно.\n" + "📁 Введите цену для позиции 💰") + + +# Изменение описания позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_description", state="*") +async def product_position_edit_description(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_description") + await call.message.delete() + await call.message.answer("📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие описания позиции для её изменения +@dp.message_handler(IsShopAdmin(), state="here_change_position_description") +async def product_position_edit_description_get(message: Message, state: FSMContext): + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + + try: + if len(message.text) <= 600: + await state.finish() + + if message.text != "0": + cache_msg = await message.answer(message.text) + await cache_msg.delete() + + update_positionx(position_id, position_description=message.text) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer("❌ Описание не может превышать 600 символов.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + except CantParseEntities: + await message.answer("❌ Ошибка синтаксиса HTML.\n" + "📁 Введите новое описание для позиции 📜\n" + "❕ Вы можете использовать HTML разметку\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Изменение изображения позиции +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_photo", state="*") +async def product_position_edit_photo(call: CallbackQuery, state: FSMContext): + category_id = int(call.data.split(":")[1]) + position_id = int(call.data.split(":")[2]) + remover = int(call.data.split(":")[3]) + + await state.update_data(here_cache_category_id=category_id) + await state.update_data(here_cache_position_id=position_id) + await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_position_photo") + await call.message.delete() + await call.message.answer("📁 Отправьте новое изображение для позиции 📸\n" + "❕ Отправьте 0 чтобы пропустить.") + + +# Принятие нового фото для позиции +@dp.message_handler(IsShopAdmin(), content_types="photo", state="here_change_position_photo") +@dp.message_handler(IsShopAdmin(), text="0", state="here_change_position_photo") +async def product_position_edit_photo_get(message: Message, state: FSMContext): + async with state.proxy() as data: + position_id = data['here_cache_category_id'] + category_id = data['here_cache_position_id'] + remover = data['here_cache_position_remover'] + await state.finish() + + position = get_positionx(position_id=position_id) + print(position['position_name']) + + if "text" in message: + position_photo = "" + else: + position_photo = message.photo[-1].file_id + + update_positionx(position_id, position_photo=position_photo) + get_message, get_photo = get_position_admin(position_id) + await notify(dp, f"Была отредактирована позиция: {position['position_name']}") + + if get_photo is not None: + await message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await message.answer(get_message, reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +# --------------------------- Добавлено 12.08.22 ------------------------------------------ + +# Изменение города продукта +@dp.callback_query_handler(IsShopAdmin(), text_startswith="position_edit_city", state="*") +async def product_position_edit_description(call: CallbackQuery, state: FSMContext): + print(f'Изменение города продукта admin_products.py 715') + print(call.data) + category_id = int(call.data.split(":")[2]) + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[3]) + + current_city = get_city_user(call.from_user.id)[0] + + # await state.update_data(here_cache_category_id=category_id) + # await state.update_data(here_cache_position_id=position_id) + # await state.update_data(here_cache_position_remover=remover) + + await state.set_state("here_change_city") + await state.update_data({'position_id': position_id, 'category_id': category_id, 'remover': remover}) + await call.message.delete() + await call.message.answer("📁 Выберите другой город 🏙\n" + "❕ Вы можете использовать геолокацию или выбрать город из списка\n" + f"❕ Город товара: {current_city}", reply_markup=geo_1_kb()) + + +# принятие новой геопозиции для позиции +@dp.callback_query_handler(text_startswith='geo_chosen_cities', state='here_change_city') +async def geo_5(cb: CallbackQuery, state: FSMContext): + info = int(str(cb.data).split('#')[1]) + if info == 0: + async with state.proxy() as data: + city = data['city'] + position_id = int(data['position_id']) + category_id = data['category_id'] + remover = data['remover'] + city_id = data['city_id'] + + else: + async with state.proxy() as data: + position_id = int(data['position_id']) + category_id = data['category_id'] + remover = data['remover'] + + city_id = info + city = get_city_info(info) + + await state.finish() + update_position_city(city[0], city_id, position_id) + + # update_positionx(position_id) + get_message, get_photo = get_position_admin(position_id) + + if get_photo is not None: + await cb.message.answer_photo(get_photo, get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + else: + await cb.message.answer(get_message, + reply_markup=position_edit_open_finl(position_id, category_id, remover)) + + +################################################################################################ +# Просмотр истории покупок +@dp.callback_query_handler(text="user_history", state="*") +async def user_history(call: CallbackQuery, state: FSMContext): + last_purchases = last_purchasesx(call.from_user.id, 5) + + if len(last_purchases) >= 1: + await call.answer("🎁 Последние 5 покупок") + await call.message.delete() + + for purchases in last_purchases: + link_items = await upload_text(call, purchases['purchase_item']) + + await call.message.answer(f"🧾 Чек: #{purchases['purchase_receipt']}\n" + f"🎁 Товар: {purchases['purchase_position_name']} | {purchases['purchase_count']}шт | {purchases['purchase_price']}₽\n" + f"🕰 Дата покупки: {purchases['purchase_date']}\n" + f"🔗 Товары: кликабельно") + + await call.message.answer(open_profile_my(call.from_user.id), reply_markup=profile_open_inl) + else: + await call.answer("❗ У вас отсутствуют покупки", True) + + +# Возвращение к профилю +@dp.callback_query_handler(text="user_profile", state="*") +async def user_profile_return(call: CallbackQuery, state: FSMContext): + await call.message.edit_text(open_profile_my(call.from_user.id), reply_markup=profile_open_inl) + + +# Возвращение к корзине +@dp.callback_query_handler(text="user_cart", state="*") +async def user_cart_return(call: CallbackQuery, state: FSMContext): + user_id = call.from_user.id + orderdata = get_params_orderx(user_id=user_id) + #cart_state = orderdata['order_state'] + for order in orderdata: + # await call.message.edit_text(open_cart_my(call.from_user.id), reply_markup=cart_open_+{'cart_state'}+_inl) + if order['order_state'] == 'created': + await call.message.answer(open_cart_my(user_id), reply_markup=cart_open_created_inl) + if order['order_state'] == 'delivery': + await call.message.answer(open_cart_my(user_id), reply_markup=cart_open_delivery_inl) + if order['order_state'] == 'submited': + await call.message.answer(f"🎁 Активных заказов нет.\n") + +################################################################################################ +######################################### ПОКУПКА ТОВАРА ####################################### +########################################### КАТЕГОРИИ ########################################## +# Открытие категорий для покупки + + +@dp.callback_query_handler(text_startswith="buy_category_open", state="*") +async def user_purchase_category_open(call: CallbackQuery, state: FSMContext): + print(f'Открытие категорий для покупки user_menu.py 133') + category_id = int(call.data.split(":")[1]) + + get_category = get_categoryx(category_id=category_id) + city = get_city_user(call.from_user.id)[0] + # get_positionsx(category_id=category_id) + get_positions = get_position_on_city(category_id, city) + + if len(get_positions) >= 1: + await call.message.edit_text("🎁 Выберите нужную игру:", + reply_markup=products_item_position_open_fp(0, category_id, city)) + else: + await call.answer(f"❕ Товары в категории {get_category['category_name']} отсутствуют") + + +# Вернуться к категориям для покупки +@dp.callback_query_handler(text_startswith="buy_category_return", state="*") +async def user_purchase_category_return(call: CallbackQuery, state: FSMContext): + get_categories = get_all_categoriesx() + get_settings = get_settingsx() + city = None + if get_settings['type_trade'] != 'digital': + city = get_city_user(call.from_user.id)[0] + + if len(get_categories) >= 1: + await call.message.edit_text("🎁 Выберите нужную игру:", + reply_markup=products_item_category_open_fp(0, city)) + else: + await call.message.edit_text("🎁 Товары в данное время отсутствуют.") + await call.answer("❗ Категории были изменены или удалены") + + +# Следующая страница категорий для покупки +@dp.callback_query_handler(text_startswith="buy_category_nextp", state="*") +async def user_purchase_category_next_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🎁 Выберите нужную игру:", + reply_markup=products_item_category_next_page_fp(remover)) + + +# Предыдущая страница категорий для покупки +@dp.callback_query_handler(text_startswith="buy_category_backp", state="*") +async def user_purchase_category_prev_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🎁 Выберите нужную игру:", + reply_markup=products_item_category_back_page_fp(remover)) + +########################################### ПОЗИЦИИ ########################################## +# Открытие позиции для покупки + + +@dp.callback_query_handler(text_startswith="buy_position_open", state="*") +async def user_purchase_position_open(call: CallbackQuery, state: FSMContext): + print(f'Карточка товара: user_menu.py 152') + position_id = int(call.data.split(":")[1]) + remover = int(call.data.split(":")[2]) + category_id = int(call.data.split(":")[3]) + + get_position = get_positionx(position_id=position_id) + get_category = get_categoryx(category_id=category_id) + get_items = get_itemsx(position_id=position_id) + get_settings = get_settingsx() + + if get_position['position_description'] == "0": + text_description = "" + else: + text_description = f"\n📜 Описание:\n" \ + f"{get_position['position_description']}" + + send_msg = f"Карточка товара:\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🗃 Игра: {get_category['category_name']}\n" \ + f"🏷 Срок аренды: {get_position['position_name']}\n" \ + f"💰 Стоимость: {get_position['position_price']}₽\n" \ + f"{text_description}" + # f"🏙 Город: {get_position['position_city']}\n" \ + + +# f"📦 Остаток: {len(get_items)}шт" \ + print(get_settings['type_trade']) + tt = get_settings['type_trade'] + + if tt != "digital": + # product_markup = products_open_finl(position_id, remover, category_id) + # product_markup = products_open_cart_finl(position_id, remover, category_id) + if len(get_position['position_photo']) >= 5: + await call.message.delete() + await call.message.answer_photo(get_position['position_photo'], + send_msg, reply_markup=products_open_cart_finl(position_id, remover, category_id)) + else: + await call.message.edit_text(send_msg, + reply_markup=products_open_cart_finl(position_id, remover, category_id)) + elif tt == "digital": + if len(get_position['position_photo']) >= 5: + await call.message.delete() + await call.message.answer_photo(get_position['position_photo'], + send_msg, reply_markup=products_open_finl(position_id, remover, category_id)) + else: + await call.message.edit_text(send_msg, + reply_markup=products_open_finl(position_id, remover, category_id)) + + +# Вернуться к позициям для покупки +@dp.callback_query_handler(text_startswith="buy_position_return", state="*") +async def user_purchase_position_return(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + get_positions = get_all_positionsx() + city = get_city_user(call.from_user.id)[0] + + if len(get_positions) >= 1: + await call.message.delete() + await call.message.answer("🎁 Выберите нужную игру:", + reply_markup=products_item_position_open_fp(remover, category_id, city)) + else: + await call.message.edit_text("🎁 Товары в данное время отсутствуют.") + await call.answer("❗ Позиции были изменены или удалены") + + +# Переключение страниц категорий для покупки +@dp.callback_query_handler(text_startswith="buy_category_swipe:", state="*") +async def user_purchase_category_next_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + + await call.message.edit_text("🎁 Выберите нужную игру:", + reply_markup=products_item_category_swipe_fp(remover)) + +# Следующая страница позиций для покупки + + +@dp.callback_query_handler(text_startswith="buy_position_nextp", state="*") +async def user_purchase_position_next_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("🎁 Выберите нужную игру:", + reply_markup=products_item_position_next_page_fp(remover, category_id)) + +# Предыдущая страница позиций для покупки + + +@dp.callback_query_handler(text_startswith="buy_position_backp", state="*") +async def user_purchase_position_prev_page(call: CallbackQuery, state: FSMContext): + remover = int(call.data.split(":")[1]) + category_id = int(call.data.split(":")[2]) + + await call.message.edit_text("🎁 Выберите нужную игру:", + reply_markup=buy_position_return_page_fp(remover, category_id)) + + +########################################### ПОКУПКА ########################################## +# Выбор количества товаров в корзине +@dp.callback_query_handler(text_startswith="add_item_cart", state="*") +async def user_purchase_addcart(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + print("Добавление в корзину") + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + get_user = get_userx(user_id=call.from_user.id) + get_count = len(get_items) + + if get_count == 1: + await state.update_data(here_cache_position_id=position_id) + await state.finish() + + await call.message.delete() + await call.message.answer(f"1 шт. в наличии. Добавить товар(ы) в корзину?\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Товар: {get_position['position_name']}\n" + f"📦 Остаток: 1шт\n" + f"💰 Сумма к покупке: {get_position['position_price']}₽", + reply_markup=products_addcart_confirm_finl(position_id, 1)) + elif get_count >= 1: + await state.update_data(here_cache_position_id=position_id) + await state.set_state("here_itemsadd_cart") + + await call.message.delete() + await call.message.answer(f"🎁 Введите количество товаров для покупки\n" + f"▶ От 1 до {get_count}\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Аренда: {get_position['position_name']} - {get_position['position_price']}₽\n" + f"💰 Ваш баланс: {get_user['user_balance']}₽") + else: + await call.answer("🎁 Товара нет в наличии") + + +# Принятие количества товаров в корзине +@dp.message_handler(state="here_itemsadd_cart") +async def user_purchase_select_count(message: Message, state: FSMContext): + position_id = (await state.get_data())['here_cache_position_id'] + get_position = get_positionx(position_id=position_id) + get_user = get_userx(user_id=message.from_user.id) + get_items = get_itemsx(position_id=position_id) + + if get_position['position_price'] != 0: + get_count = int(get_user['user_balance'] / + get_position['position_price']) + if get_count > len(get_items): + get_count = len(get_items) + else: + get_count = len(get_items) + + send_message = f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🎁 Введите количество аккаунтов которое хотите купить\n" \ + f"▶ От 1 до {get_count}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🎁 Аренда: {get_position['position_name']} - {get_position['position_price']}₽\n" \ + f"💰 Ваш баланс: {get_user['user_balance']}₽" + print("test") + if message.text: # .isdigit() + get_count = int(message.text) + amount_pay = int(get_position['position_price']) * get_count + + if len(get_items) >= 1: + if 1 <= get_count <= len(get_items): + # if int(get_user['user_balance']) >= amount_pay: + await state.finish() + await message.answer(f"🎁 Вы действительно хотите добавить в корзину товар(ы)?\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Аренда: {get_position['position_name']}\n" + f"📦 Остаток: {get_count}шт\n" + f"💰 Сумма добавляемых товаров: {amount_pay}₽", + reply_markup=products_addcart_confirm_finl(position_id, get_count)) + # else: + needed_to_refill = amount_pay - int(get_user['user_balance']) + await state.finish() + await message.answer(f"🎁 Вы действительно хотите добавить в корзину товар(ы)?\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Аренда: {get_position['position_name']}\n" + f"📦 Остаток: {get_count}шт\n" + f"💰 Сумма добавляемых товаров: {amount_pay}₽", + f"💰 Сумма к пополнению: {needed_to_refill}₽", + reply_markup=products_addcart_confirm_finl(position_id, get_count)) + + else: + await message.answer(f"❌ Неверное количество товаров.\n" + send_message) + else: + await state.finish() + await message.answer("🎁 Товар который вы хотели купить, закончился") + else: + await message.answer(f"❌ Данные были введены неверно.\n" + send_message) + + +# Подтверждение добавления товара в корзину +@dp.callback_query_handler(text_startswith="xaddcart_item", state="*") +async def user_addcart_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + get_count = int(call.data.split(":")[3]) + + if get_action == "yes": + await call.message.edit_text("🔄 Ждите, товары подготавливаются") + + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + get_user = get_userx(user_id=call.from_user.id) + + amount_pay = int(get_position['position_price'] * get_count) + + if 1 <= int(get_count) <= len(get_items): + save_items, send_count, split_len = buy_itemx(get_items, get_count) + + # уточнение цены за количество в наличии + if get_count != send_count: + amount_pay = int(get_position['position_price'] * send_count) + get_count = send_count + + receipt = get_unix() + add_time = get_date() + print(add_time) + + await call.message.delete() + + # if split_len == 0: + # await call.message.answer("\n\n".join(save_items), parse_mode="None") + # else: + # for item in split_messages(save_items, split_len): + # await call.message.answer("\n\n".join(item), parse_mode="None") + # await asyncio.sleep(0.3) + await asyncio.sleep(0.3) + # update_userx(get_user['user_id'], user_balance=get_user['user_balance'] - amount_pay) + i = 0 + #users_order = get_user_orderx(get_user['user_id']) + users_order = get_params_orderx(user_id=get_user['user_id'], order_state='created') + print(users_order) + alength = len(users_order) + for i in range(alength): + print(users_order[i]['order_id']) + + print('test2') + #print(users_order['order_id']) + + if not users_order: + create_orderx(call.from_user.id, get_user['user_login'], get_user['user_name'], 'created', str(add_time), + receipt) + users_order = get_params_orderx(user_id=get_user['user_id'], order_state='created') + #print(users_order['order_id']) + print('test3') + for i in range(alength): + print(users_order[i]['order_id']) + order_id = users_order[i]['order_id'] + # price = int(get_position['position_price']) + add_order_itemx(order_id, position_id, get_count, get_position['position_price'], receipt, get_position['position_user_id']) + # add_order_itemx(1, 1, 1, 1, 1) + + await call.message.answer(f"✅ Вы успешно добавили товар(ы) в корзину\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🧾 Чек: #{receipt}\n" + f"🎁 Товар: {get_position['position_name']} | {get_count}шт | {amount_pay}₽\n" + f"🕰 Дата покупки: {add_time}", + reply_markup=menu_frep(call.from_user.id)) + else: + await call.message.answer("🎁 Товар который вы хотели купить закончился или изменился.", + reply_markup=menu_frep(call.from_user.id)) + else: + if len(get_all_categoriesx()) >= 1: + await call.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_category_open_fp(0)) + else: + await call.message.edit_text("✅ Вы отменили покупку товаров.") + + +# Удаление корзины +@dp.callback_query_handler(text_startswith="del_user_cart", state="*") +async def del_user_cart(call: CallbackQuery, state: FSMContext): + await state.finish() + await call.message.edit_text(" Удалить корзину и ее позиции?", + reply_markup=confirm_delete_user_cart_inl) + +# Подтверждение удаления корзины + + +@dp.callback_query_handler(text_startswith="confirm_del_user_cart", state="*") +async def confirm_del_user_cart(call: CallbackQuery, state: FSMContext): + + user_id = call.from_user.id + print(user_id) + order = get_orderx(user_id=user_id) + print(order) + order_id = order['order_id'] + print(order_id) + remove_ordersx(order_id=order_id) + remove_orders_itemx(order_id=order_id) + print("|||| - - ||||") + await call.message.edit_text("✅ Вы удалили корзину.") + + +####################################################################################### +# ************************** CHECK OUT CART ****************************************** +####################################################################################### + +# Оформление заказа по корзине - Адрес +@dp.callback_query_handler(text="checkout_start", state="*") +async def checkout_start(call: CallbackQuery, state: FSMContext): + # user_id = int(call.data.split(":")[2]) + user_id = call.from_user.id + get_user = get_userx(user_id=user_id) + ub = get_user['user_balance'] + cart_sum = calc_cart_summ(user_id=user_id) + delivery = 200 + order_total = cart_sum + delivery + adr = geo = phone = 0 + users_order = get_user_orderx(user_id) + order_id = users_order['order_id'] + touser_id = get_cart_sellersx(order_id) + + print(user_id) + + if get_user['user_address'] != "": + print("Адрес есть") + adr = 1 + if get_user['user_geocode'] != "": + print("Геокод есть") + geo = 1 + if get_user['user_phone'] != "": + print("Телефон есть") + phone = 1 + + await call.message.answer(f" Начинаем оформление заказа.\n") + + if phone == 0: + await state.set_state("enter_phone_auto") + # await call.message.delete() + # await call.message.answer(f" Введите пожалуйста адрес доставки.\n") + + if adr == 0: + await state.set_state("enter_address_manualy") + + if ub < order_total: + await state.set_state("user_balance_lower_than_cart") + await call.message.delete() + await call.message.answer(f"Суммы на Вашем балансе не достаточно для оформления заказа.\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f" Баланс: {ub}\n" + f" Сумма заказа: {order_total}\n", + reply_markup=order_user_refill) + else: + await state.set_state("checkout_finish") + await call.message.answer(f"Продолхить оформление заказа:.\n", + reply_markup=checkout_step2_accept) + + # await state.finish() + + +# Принятие адреса для доставки +# @dp.message_handler(state="checkout_finish") +# async def checkout_finish(message: Message, state: FSMContext): +@dp.callback_query_handler(text="checkout_finish", state="*") +async def checkout_finish(call: CallbackQuery, state: FSMContext): + print('checkout_finish') +# проверка - есть вопросы без ответов + touser_id = call.from_user.id + cm = get_user_messagesx(to_uid=touser_id, state='created') + if len(cm) > 0: + print("Messages present:" + str(touser_id)) +# статус заказа - delivery + order_data = get_orderx(user_id=touser_id) + order_id = order_data['order_id'] + os = update_orderx(order_id=order_id, order_state='delivery') + await call.message.answer(f"Начинаем доставку товара Вашей корзины.") + print('Сумма заказа на холде') +# холд суммы заказа + validity = 5 + state = 'created' + cart_sum = calc_cart_summ(user_id=touser_id) + delivery = 200 + amount = cart_sum + delivery + #amount = order_data['order_total'] + buyer = touser_id + order_sellers = get_order_sellers(order_id) + print(order_sellers) + if(len(order_sellers) > 1): + print("продавцов более 1") + # for seller in order_sellers: + print(type(order_sellers)) + order_sellers = order_sellers.strip('[[') + order_sellers = order_sellers.strip(']]') + # seller=list(order_sellers) + h = create_holdx(int(order_id), int(buyer), int( + str(order_sellers)), int(amount), int(validity), state) + i = update_userx(user_id=buyer, user_hold=amount) + await call.message.answer(f"Денежные средства в размере {amount}р. успешно заблокированы до \n" + f"подтверждения получения покупателем товара.") + + +# Оформление заказа по корзине - Адрес +@dp.callback_query_handler(text="submit_order", state="*") +async def submit_order(call: CallbackQuery, state: FSMContext): + # buyer + user_id = call.from_user.id + buyer_data = get_userx(user_id=user_id) + print(buyer_data) + order_data = get_orderx(user_id=user_id) + order_id = order_data['order_id'] + print(order_id) + order_sellers = get_order_sellers(order_id) + print(order_sellers) + if(len(order_sellers) > 1): + print("продавцов более 1") + # for seller in order_sellers: + print(type(order_sellers)) + order_sellers = order_sellers.strip('[[') + order_sellers = order_sellers.strip(']]') + print(order_sellers) + hold_data = get_orders_holdsx(order_id) + #hold_data = hold_data.strip('[') + #hold_data = hold_data.strip(']') + print(hold_data[0]['seller']) + # seller + seller_data = get_userx(user_id=hold_data[0]['seller']) + print(seller_data) + # hold_data['seller'] +# изменение статуса заказа submitted + os = update_orderx(order_id=order_id, order_state='submitted', active=0) +# снятие холда с суммы заказа + a = update_holdx(order_id=order_id, state='released') +# транзакция + seller_rest = int(seller_data['user_balance'])+int(hold_data[0]['amount']) + buyer_rest = int(buyer_data['user_balance'])-int(hold_data[0]['amount']) + # списание у покупателя + b = update_userx(user_id, user_balance=buyer_rest) + # пополнение у продавца + c = update_userx(order_sellers, user_balance=seller_rest) + + receipt = get_unix() + buy_time = get_date() + + await call.message.answer(f"Покупка завершена, возвращайтесь!\n") + + +@dp.callback_query_handler(text="reply_toorder_message", state="*") +async def reply_toorder_message(call: CallbackQuery, state: FSMContext): + print('reply_toorder_message') + # order_id = int(call.data.split(":")[1]) + # user_id = int(call.data.split(":")[1]) + user_id = call.from_user.id + print(user_id) + get_user = get_userx(user_id=user_id) + + # get_user = get_userx(user_id=call.from_user.id) + await state.set_state("reply_toorder_message_fin") + + # await call.message.delete() + await call.message.answer(f"Пожалуйста, введите сообщение для покупателя:\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n") + + +# Принятие адреса для доставки +@dp.message_handler(state="reply_toorder_message_fin") +async def reply_toorder_message_fin(message: Message, state: FSMContext): + print('reply_toorder_message_fin') + # user_id = int(call.data.split(":")[1]) + # order_id = int(message.data.split(":")[1]) + user_id = message.from_user.id + get_user = get_userx(user_id=user_id) + users_order = get_user_orderx(user_id) + order_id = users_order['order_id'] + # get_user = get_userx(user_id=message.from_user.id) + await state.finish() + + if message.text: + messagetxt = str(message.text) + print(str(user_id) + str(messagetxt)) + touser_id = get_cart_sellersx(order_id) + print(touser_id) + + add_messagex(from_id=user_id, to_id=touser_id, order_id=order_id, + txtmessage=messagetxt, photo='', state='responded') + + await message.delete() + await message.answer(f"✅ Было отправлено следующее сообщение покупателю:\n" + + messagetxt, reply_markup=cart_enter_message_finl(user_id)) + + cm = get_user_messagesx(to_uid=touser_id, state='responded') + if len(cm) > 0: + print("Messages present:" + str(touser_id)) + + await dp.bot.send_message(chat_id=touser_id, text=f"Сообщение/вопрос по заказу от продавца:"+messagetxt, reply_markup=reply_order_message_finl(order_id)) + + +@dp.callback_query_handler(text="enter_message_manualy", state="*") +async def enter_message_manualy(call: CallbackQuery, state: FSMContext): + print('enter_message_manualy') + # order_id = int(call.data.split(":")[1]) + # user_id = int(call.data.split(":")[1]) + user_id = call.from_user.id + print(user_id) + get_user = get_userx(user_id=user_id) + + # get_user = get_userx(user_id=call.from_user.id) + await state.set_state("enter_message_manualy_fin") + + # await call.message.delete() + await call.message.answer(f"Пожалуйста, введите сообщение для продавца:\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n") + + +# Принятие адреса для доставки +@dp.message_handler(state="enter_message_manualy_fin") +async def enter_message_manualy_fin(message: Message, state: FSMContext): + print('enter_message_manualy_fin') + # user_id = int(call.data.split(":")[1]) + # order_id = int(message.data.split(":")[1]) + user_id = message.from_user.id + get_user = get_userx(user_id=user_id) + users_order = get_user_orderx(user_id) + order_id = users_order['order_id'] + # get_user = get_userx(user_id=message.from_user.id) + await state.finish() + + if message.text: + messagetxt = str(message.text) + print(str(user_id) + str(messagetxt)) + touser_id = get_cart_sellersx(order_id) + print(touser_id) + + add_messagex(from_id=user_id, to_id=touser_id, order_id=order_id, + txtmessage=messagetxt, photo='', state='created') + + await message.delete() + await message.answer(f"✅ Было отправлено следующее сообщение продавцу:\n" + + messagetxt, reply_markup=cart_enter_message_finl(user_id)) + + cm = get_user_messagesx(to_uid=touser_id, state='created') + if len(cm) > 0: + print("Messages present:" + str(touser_id)) + + await dp.bot.send_message(chat_id=touser_id, text=f"Сообщение/вопрос по заказу от покупателя:"+messagetxt, reply_markup=reply_order_message_finl(order_id)) + + +@dp.callback_query_handler(text_startswith="enter_phone_auto", state="*") +async def enter_phone_man(call: CallbackQuery, state: FSMContext): + print('enter_phone_auto') + # user_id = int(call.data.split(":")[1]) + user_id = call.from_user.id + get_user = get_userx(user_id=call.from_user.id) + + await state.set_state("enter_phone_auto_fin") + + button_phone = KeyboardButton(text="Делись!", request_contact=True) + keyboard = ReplyKeyboardMarkup( + row_width=1, resize_keyboard=True, one_time_keyboard=True) + keyboard.add(button_phone) + await call.message.answer(f"✅ Вы можете поделиться своим номером телефона.", reply_markup=menu_frep(message.from_user.id)) + + # get_user = get_userx(user_id=call.from_user.id) + + # await state.finish() + + # await Person.contact.set() + + '''await call.message.delete() + await call.message.answer(f"🎁 Введите Ваш номер телефона:\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n")''' + + +# content_types=ContentType.CONTACT, +@dp.message_handler(content_types=['contact'], state="enter_phone_auto_fin") +async def contacts(message: Message, state: FSMContext): + phone = message.contact.phone_number + + print(phone) + phone = str(message.text) + phone = message.contact.phone_number + update_userx(message.from_user.id, user_phone=phone) + + await message.answer(f"Ваш номер сохранен в Вашем личном кабинете: {message.contact.phone_number}", + reply_markup=ReplyKeyboardRemove()) # , reply_markup=types.ReplyKeyboardRemove() + await state.finish() + + await message.answer(f"✅ Номер телефон был успешно изменен на следующий:\n" + + str(phone), reply_markup=accept_saved_phone(message.from_user.id)) + + +''' + await message.answer("🔸 Мы снова с Вами!.\n" + "🔸 Если не появились вспомогательные кнопки\n" + "▶ Введите /start", + reply_markup=menu_frep(message.from_user.id)) ''' + + +# Принятие адреса для доставки +@dp.message_handler(state="enter_phone_auto_fin2") +async def user_get_phone(message: Message, state: FSMContext): + print('enter_phone_auto_fin') + # user_id = int(call.data.split(":")[1]) + phone = message.contact.phone_number + # phone = int(message.data.split(":")[1]) + get_user = get_userx(user_id=message.from_user.id) + # get_user = get_userx(user_id=message.from_user.id) + await state.finish() + + print(phone) + + # if message.text: + # phone = str(message.text) + # update_userx(message.from_user.id, user_phone=phone) + + await message.delete() + await message.answer(f"✅ Номер телефон был успешно изменен на следующий:\n" + + phone, reply_markup=accept_saved_phone(message.from_user.id)) + + +@dp.callback_query_handler(text_startswith="enter_phone_manualy", state="*") +async def enter_phone_man(call: CallbackQuery, state: FSMContext): + print('enter_phone_manualy') + # user_id = int(call.data.split(":")[1]) + user_id = call.from_user.id + get_user = get_userx(user_id=call.from_user.id) + + # get_user = get_userx(user_id=call.from_user.id) + + await state.set_state("enter_phone_manualy_fin") + + await call.message.delete() + await call.message.answer(f"🎁 Введите Ваш номер телефона:\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n") + + +# Принятие адреса для доставки +@dp.message_handler(state="enter_phone_manualy_fin") +async def user_enter_phone(message: Message, state: FSMContext): + print('enter_phone_manualy_fin') + # user_id = int(call.data.split(":")[1]) + get_user = get_userx(user_id=message.from_user.id) + # get_user = get_userx(user_id=message.from_user.id) + await state.finish() + + if message.text: + phone = str(message.text) + update_userx(message.from_user.id, user_phone=phone) + + await message.delete() + await message.answer(f"✅ Номер телефон был успешно изменен на следующий:\n" + + phone, reply_markup=accept_saved_phone(message.from_user.id)) + + +@dp.callback_query_handler(text_startswith="enter_address_manualy", state="*") +async def enter_address_man(call: CallbackQuery, state: FSMContext): + print('enter_address_manualy') + # user_id = int(call.data.split(":")[1]) + # user_id = call.from_user.id + get_user = get_userx(user_id=call.from_user.id) + + # get_user = get_userx(user_id=call.from_user.id) + + await state.set_state("enter_address_manualy_fin") + + await call.message.delete() + await call.message.answer(f"🎁 Введите Ваш адрес:\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n") + + +# Принятие адреса для доставки +@dp.message_handler(state="enter_address_manualy_fin") +async def user_enter_addr(message: Message, state: FSMContext): + print('enter_address_manualy_fin') + #user_id = int(message.split(":")[1]) + user_id = message.from_user.id + get_user = get_userx(user_id=user_id) + # get_user = get_userx(user_id=message.from_user.id) + await state.finish() + + if message.text: + address = str(message.text) + update_userx(message.from_user.id, user_address=address) + + await message.delete() + await message.answer(f"✅ Адрес доставки был успешно изменен на следующий:\n" + + address, reply_markup=accept_saved_adr(message.from_user.id)) + + +# Выбор количества товаров для покупки +@dp.callback_query_handler(text_startswith="buy_item_select", state="*") +async def buy_item_select(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + get_user = get_userx(user_id=call.from_user.id) + + if get_position['position_price'] != 0: + get_count = int(get_user['user_balance'] / + get_position['position_price']) + if get_count > len(get_items): + get_count = len(get_items) + else: + get_count = len(get_items) + + if int(get_user['user_balance']) >= int(get_position['position_price']): + if get_count == 1: + await state.update_data(here_cache_position_id=position_id) + await state.finish() + + await call.message.delete() + await call.message.answer(f"🎁 Вы действительно хотите купить товар(ы)?\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Срок аренды: {get_position['position_name']}\n" + f"📦 Количество: 1шт\n" + f"💰 Сумма к покупке: {get_position['position_price']}₽", + reply_markup=products_confirm_finl(position_id, 1)) + elif get_count >= 1: + await state.update_data(here_cache_position_id=position_id) + await state.set_state("here_item_count") + + await call.message.delete() + await call.message.answer(f"🎁 Введите количество аккаунтов которое хотите купить\n" + f"▶ От 1 до {get_count}\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Аренда: {get_position['position_name']} - {get_position['position_price']}₽\n" + f"💰 Ваш баланс: {get_user['user_balance']}₽") + else: + await call.answer("🎁 Товаров нет в наличии") + else: + # await call.answer("❗ У вас недостаточно средств. Пополните баланс", True) + # await call.message.delete() + await call.message.answer(f"❗ У вас недостаточно средств. Пополните баланс", reply_markup=charge_button_add(0)) + + +# ------------------------------------------------------------------------------------- +# Выбор количества товаров для покупки +@dp.callback_query_handler(text_startswith="buy_item_select", state="*") +async def user_purchase_select(call: CallbackQuery, state: FSMContext): + position_id = int(call.data.split(":")[1]) + + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + get_user = get_userx(user_id=call.from_user.id) + + if get_position['position_price'] != 0: + get_count = int(get_user['user_balance'] / + get_position['position_price']) + if get_count > len(get_items): + get_count = len(get_items) + else: + get_count = len(get_items) + + if int(get_user['user_balance']) >= int(get_position['position_price']): + if get_count == 1: + await state.update_data(here_cache_position_id=position_id) + await state.finish() + + await call.message.delete() + await call.message.answer(f"🎁 Вы действительно хотите купить товар(ы)?\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Срок аренды: {get_position['position_name']}\n" + f"📦 Количество: 1шт\n" + f"💰 Сумма к покупке: {get_position['position_price']}₽", + reply_markup=products_confirm_finl(position_id, 1)) + elif get_count >= 1: + await state.update_data(here_cache_position_id=position_id) + await state.set_state("here_item_count") + + await call.message.delete() + await call.message.answer(f"🎁 Введите количество аккаунтов которое хотите купить\n" + f"▶ От 1 до {get_count}\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Аренда: {get_position['position_name']} - {get_position['position_price']}₽\n" + f"💰 Ваш баланс: {get_user['user_balance']}₽") + else: + await call.answer("🎁 Товаров нет в наличии") + else: + # await call.answer("❗ У вас недостаточно средств. Пополните баланс", True) + # await call.message.delete() + await call.message.answer(f"❗ У вас недостаточно средств. Пополните баланс", reply_markup=charge_button_add(0)) + + +# Принятие количества товаров для покупки +@dp.message_handler(state="here_item_count") +async def user_purchase_select_count(message: Message, state: FSMContext): + position_id = (await state.get_data())['here_cache_position_id'] + + get_position = get_positionx(position_id=position_id) + get_user = get_userx(user_id=message.from_user.id) + get_items = get_itemsx(position_id=position_id) + + if get_position['position_price'] != 0: + get_count = int(get_user['user_balance'] / + get_position['position_price']) + if get_count > len(get_items): + get_count = len(get_items) + else: + get_count = len(get_items) + + send_message = f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🎁 Введите количество аккаунтов которое хотите купить\n" \ + f"▶ От 1 до {get_count}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🎁 Срок аренды: {get_position['position_name']} - {get_position['position_price']}₽\n" \ + f"💰 Ваш баланс: {get_user['user_balance']}₽" + + if message.text.isdigit(): + get_count = int(message.text) + amount_pay = int(get_position['position_price']) * get_count + + if len(get_items) >= 1: + if 1 <= get_count <= len(get_items): + if int(get_user['user_balance']) >= amount_pay: + await state.finish() + await message.answer(f"🎁 Вы действительно хотите купить товар(ы)?\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🎁 Срок аренды: {get_position['position_name']}\n" + f"📦 Количество: {get_count}шт\n" + f"💰 Сумма к покупке: {amount_pay}₽", + reply_markup=products_confirm_finl(position_id, get_count)) + else: + await message.answer(f"❌ Недостаточно средств на счете.\n" + send_message) + else: + await message.answer(f"❌ Неверное количество товаров.\n" + send_message) + else: + await state.finish() + await message.answer("🎁 Товар который вы хотели купить, закончился") + else: + await message.answer(f"❌ Данные были введены неверно.\n" + send_message) + + +# Подтверждение покупки товара +@dp.callback_query_handler(text_startswith="xbuy_item", state="*") +async def user_purchase_confirm(call: CallbackQuery, state: FSMContext): + get_action = call.data.split(":")[1] + position_id = int(call.data.split(":")[2]) + get_count = int(call.data.split(":")[3]) + + if get_action == "yes": + await call.message.edit_text("🔄 Ждите, товары подготавливаются") + + get_position = get_positionx(position_id=position_id) + get_items = get_itemsx(position_id=position_id) + get_user = get_userx(user_id=call.from_user.id) + + amount_pay = int(get_position['position_price'] * get_count) + + if 1 <= int(get_count) <= len(get_items): + if int(get_user['user_balance']) >= amount_pay: + save_items, send_count, split_len = buy_itemx( + get_items, get_count) + + if get_count != send_count: + amount_pay = int( + get_position['position_price'] * send_count) + get_count = send_count + + receipt = get_unix() + buy_time = get_date() + + await call.message.delete() + if split_len == 0: + await call.message.answer("\n\n".join(save_items), parse_mode="None") + else: + for item in split_messages(save_items, split_len): + await call.message.answer("\n\n".join(item), parse_mode="None") + await asyncio.sleep(0.3) + + update_userx( + get_user['user_id'], user_balance=get_user['user_balance'] - amount_pay) + add_purchasex(get_user['user_id'], get_user['user_login'], get_user['user_name'], receipt, get_count, + amount_pay, get_position['position_price'], get_position['position_id'], + get_position['position_name'], "\n".join( + save_items), buy_time, receipt, + get_user['user_balance'], int(get_user['user_balance'] - amount_pay)) + + await notify(dp, f"Продана позиция: {get_position['position_name']}") + await call.message.answer(f"✅ Вы успешно купили товар(ы)\n" + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" + f"🧾 Чек: #{receipt}\n" + f"🎁 Товар: {get_position['position_name']} | {get_count}шт | {amount_pay}₽\n" + f"🕰 Дата покупки: {buy_time}", + reply_markup=menu_frep(call.from_user.id)) + else: + await call.message.answer("❗ На вашем счёте недостаточно средств") + else: + await call.message.answer("🎁 Товар который вы хотели купить закончился или изменился.", + reply_markup=menu_frep(call.from_user.id)) + else: + + if len(get_all_categoriesx()) >= 1: + await call.message.edit_text("🎁 Выберите нужную игру:", + reply_markup=products_item_category_open_fp(0,None)) + else: + await call.message.edit_text("✅ Вы отменили покупку товаров.") diff --git a/TelegramGoodsinbot/tgbot/handlers/user_transactions.py b/TelegramGoodsinbot/tgbot/handlers/user_transactions.py new file mode 100644 index 0000000..1bd448a --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/user_transactions.py @@ -0,0 +1,173 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message + +from tgbot.keyboards.inline_user import refill_bill_finl, refill_choice_finl +from tgbot.loader import dp +from tgbot.services.api_qiwi import QiwiAPI +from tgbot.services.api_yoo import YooAPI +#from yoomoney import Client as ClientYoo +from tgbot.services.api_sqlite import update_userx, get_refillx, add_refillx, get_userx +from tgbot.utils.const_functions import get_date, get_unix +from tgbot.utils.misc_functions import send_admins + +min_input_qiwi = 5 # Минимальная сумма пополнения в рублях +min_input_yoo = 5 + +# Выбор способа пополнения +@dp.callback_query_handler(text="user_refill", state="*") +async def refill_way(call: CallbackQuery, state: FSMContext): + get_kb = refill_choice_finl() + + if get_kb is not None: + await call.message.edit_text("💰 Выберите способ пополнения", reply_markup=get_kb) + else: + await call.answer("⛔ Пополнение временно недоступно", True) + +# Выбор способа пополнения +@dp.callback_query_handler(text_startswith="refill_choice", state="*") +async def refill_way_choice(call: CallbackQuery, state: FSMContext): + get_way = call.data.split(":")[1] + + await state.update_data(here_pay_way=get_way) + + await state.set_state("here_pay_amount") + await call.message.edit_text("💰 Введите сумму пополнения") + + +################################################################################### +#################################### ВВОД СУММЫ ################################### +# Принятие суммы для пополнения средств через QIWI +@dp.message_handler(state="here_pay_amount") +async def refill_get(message: Message, state: FSMContext): + if message.text.isdigit(): + cache_message = await message.answer("♻ Подождите, платёж генерируется...") + pay_amount = int(message.text) + #pay_user_id = int(message.from_user.id) + + if min_input_qiwi <= pay_amount <= 300000: + get_way = (await state.get_data())['here_pay_way'] + + await state.finish() + if get_way == 'Form': + get_message, get_link, receipt = await ( + await QiwiAPI(cache_message, user_bill_pass=True) + ).bill_pay(pay_amount, get_way) + elif get_way == 'ForYm': + print("test") + get_message, get_link, receipt = await ( + await YooAPI(cache_message) #, acc_number=410011512189686 + ).bill_pay(pay_amount, get_way) + + if get_message: + await cache_message.edit_text(get_message, reply_markup=refill_bill_finl(get_link, receipt, get_way)) + else: + await cache_message.edit_text(f"❌ Неверная сумма пополнения\n" + f"▶ Cумма не должна быть меньше {min_input_qiwi}₽ и больше 300 000₽\n" + f"💰 Введите сумму для пополнения средств") + else: + await message.answer("❌ Данные были введены неверно.\n" + "💰 Введите сумму для пополнения средств") + + + +################################################################################### +################################ ПРОВЕРКА ПЛАТЕЖЕЙ ################################ +# Проверка оплаты через форму QIWI +@dp.callback_query_handler(text_contains="Pay:Form") +async def refill_check_form(call: CallbackQuery): + receipt = call.data.split(":")[2] + + pay_status, pay_amount = await ( + await QiwiAPI(call, user_check_pass=True) + ).check_form(receipt) + + if pay_status == "PAID": + get_refill = get_refillx(refill_receipt=receipt) + if get_refill is None: + await refill_success(call, receipt, pay_amount, "Form") + else: + await call.answer("❗ Ваше пополнение уже было зачислено.", True) + elif pay_status == "EXPIRED": + await call.message.edit_text("❌ Время оплаты вышло. Платёж был удалён.") + elif pay_status == "WAITING": + await call.answer("❗ Платёж не был найден.\n" + "⌛ Попробуйте чуть позже.", True, cache_time=5) + elif pay_status == "REJECTED": + await call.message.edit_text("❌ Счёт был отклонён.") + + +# Проверка оплаты через форму Yoo +@dp.callback_query_handler(text_contains="Pay:ForYm") +async def refill_check_formy(call: CallbackQuery): + receipt = call.data.split(":")[2] + print(call.data) + #print(receipt) + + pay_status, pay_amount = await ( + await YooAPI() + ).check_formy(receipt) + + #print(pay_status, pay_amount) + + if pay_status == "success": + get_refill = get_refillx(refill_receipt=receipt) + if get_refill is None: + await refill_success(call, receipt, pay_amount, "ForYm") + else: + await call.answer("❗ Ваше пополнение уже было зачислено.", True) + elif pay_status == "EXPIRED": + await call.message.edit_text("❌ Время оплаты вышло. Платёж был удалён.") + elif pay_status == "WAITING": + await call.answer("❗ Платёж не был найден.\n" + "⌛ Попробуйте чуть позже.", True, cache_time=5) + elif pay_status == "REJECTED": + await call.message.edit_text("❌ Счёт был отклонён.") + + +# Проверка оплаты по переводу (по нику или номеру) +@dp.callback_query_handler(text_startswith=['Pay:Number', 'Pay:Nickname']) +async def refill_check_send(call: CallbackQuery): + way_pay = call.data.split(":")[1] + receipt = call.data.split(":")[2] + + pay_status, pay_amount = await ( + await QiwiAPI(call, user_check_pass=True) + ).check_send(receipt) + + if pay_status == 1: + await call.answer("❗ Оплата была произведена не в рублях.", True, cache_time=5) + elif pay_status == 2: + await call.answer("❗ Платёж не был найден.\n" + "⌛ Попробуйте чуть позже.", True, cache_time=5) + elif pay_status == 4: + pass + else: + get_refill = get_refillx(refill_receipt=receipt) + if get_refill is None: + await refill_success(call, receipt, pay_amount, way_pay) + else: + await call.answer("❗ Ваше пополнение уже зачислено.", True, cache_time=60) + + +########################################################################################## +######################################### ПРОЧЕЕ ######################################### +# Зачисление средств +async def refill_success(call: CallbackQuery, receipt, amount, get_way): + get_user = get_userx(user_id=call.from_user.id) + + add_refillx(get_user['user_id'], get_user['user_login'], get_user['user_name'], receipt, + amount, receipt, get_way, get_date(), get_unix()) + + update_userx(call.from_user.id, + user_balance=get_user['user_balance'] + amount, + user_refill=get_user['user_refill'] + amount) + + await call.message.edit_text(f"💰 Вы пополнили баланс на сумму {amount}₽. Удачи ❤\n" + f"🧾 Чек: #{receipt}") + + await send_admins( + f"👤 Пользователь: @{get_user['user_login']} | {get_user['user_name']} | {get_user['user_id']}\n" + f"💰 Сумма пополнения: {amount}₽\n" + f"🧾 Чек: #{receipt}" + ) diff --git a/TelegramGoodsinbot/tgbot/handlers/user_transactions2.py b/TelegramGoodsinbot/tgbot/handlers/user_transactions2.py new file mode 100644 index 0000000..298af19 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/user_transactions2.py @@ -0,0 +1,136 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message + +from tgbot.keyboards.inline_user import refill_bill_finl, refill_choice_finl +from tgbot.loader import dp +from tgbot.services.api_qiwi import QiwiAPI +from tgbot.services.api_sqlite import update_userx, get_refillx, add_refillx, get_userx +from tgbot.utils.const_functions import get_date, get_unix +from tgbot.utils.misc_functions import send_admins + +min_input_qiwi = 5 # Минимальная сумма пополнения в рублях + + +# Выбор способа пополнения +@dp.callback_query_handler(text="user_refill", state="*") +async def refill_way(call: CallbackQuery, state: FSMContext): + get_kb = refill_choice_finl(user_id=call.from_user.id) + + if get_kb is not None: + await call.message.edit_text("💰 Выберите способ пополнения", reply_markup=get_kb) + else: + await call.answer("⛔ Пополнение временно недоступно", True) + + +# Выбор способа пополнения +@dp.callback_query_handler(text_startswith="refill_choice", state="*") +async def refill_way_choice(call: CallbackQuery, state: FSMContext): + get_way = call.data.split(":")[1] + + await state.update_data(here_pay_way=get_way) + + await state.set_state("here_pay_amount") + await call.message.edit_text("💰 Введите сумму пополнения") + + +################################################################################### +#################################### ВВОД СУММЫ ################################### +# Принятие суммы для пополнения средств через QIWI +@dp.message_handler(state="here_pay_amount") +async def refill_get(message: Message, state: FSMContext): + if message.text.isdigit(): + cache_message = await message.answer("♻ Подождите, платёж генерируется...") + pay_amount = int(message.text) + + if min_input_qiwi <= pay_amount <= 300000: + get_way = (await state.get_data())['here_pay_way'] + await state.finish() + + get_message, get_link, receipt = await ( + await QiwiAPI(cache_message, user_bill_pass=True) + ).bill_pay(pay_amount, get_way) + + if get_message: + await cache_message.edit_text(get_message, reply_markup=refill_bill_finl(get_link, receipt, get_way)) + else: + await cache_message.edit_text(f"❌ Неверная сумма пополнения\n" + f"▶ Cумма не должна быть меньше {min_input_qiwi}₽ и больше 300 000₽\n" + f"💰 Введите сумму для пополнения средств") + else: + await message.answer("❌ Данные были введены неверно.\n" + "💰 Введите сумму для пополнения средств") + + +################################################################################### +################################ ПРОВЕРКА ПЛАТЕЖЕЙ ################################ +# Проверка оплаты через форму +@dp.callback_query_handler(text_startswith="Pay:Form") +async def refill_check_form(call: CallbackQuery): + receipt = call.data.split(":")[2] + + pay_status, pay_amount = await ( + await QiwiAPI(call, user_check_pass=True) + ).check_form(receipt) + + if pay_status == "PAID": + get_refill = get_refillx(refill_receipt=receipt) + if get_refill is None: + await refill_success(call, receipt, pay_amount, "Form") + else: + await call.answer("❗ Ваше пополнение уже было зачислено.", True) + elif pay_status == "EXPIRED": + await call.message.edit_text("❌ Время оплаты вышло. Платёж был удалён.") + elif pay_status == "WAITING": + await call.answer("❗ Платёж не был найден.\n" + "⌛ Попробуйте чуть позже.", True, cache_time=5) + elif pay_status == "REJECTED": + await call.message.edit_text("❌ Счёт был отклонён.") + + +# Проверка оплаты по переводу (по нику или номеру) +@dp.callback_query_handler(text_startswith=['Pay:Number', 'Pay:Nickname']) +async def refill_check_send(call: CallbackQuery): + way_pay = call.data.split(":")[1] + receipt = call.data.split(":")[2] + + pay_status, pay_amount = await ( + await QiwiAPI(call, user_check_pass=True) + ).check_send(receipt) + + if pay_status == 1: + await call.answer("❗ Оплата была произведена не в рублях.", True, cache_time=5) + elif pay_status == 2: + await call.answer("❗ Платёж не был найден.\n" + "⌛ Попробуйте чуть позже.", True, cache_time=5) + elif pay_status == 4: + pass + else: + get_refill = get_refillx(refill_receipt=receipt) + if get_refill is None: + await refill_success(call, receipt, pay_amount, way_pay) + else: + await call.answer("❗ Ваше пополнение уже зачислено.", True, cache_time=60) + + +########################################################################################## +######################################### ПРОЧЕЕ ######################################### +# Зачисление средств +async def refill_success(call: CallbackQuery, receipt, amount, get_way): + get_user = get_userx(user_id=call.from_user.id) + + add_refillx(get_user['user_id'], get_user['user_login'], get_user['user_name'], receipt, + amount, receipt, get_way, get_date(), get_unix()) + + update_userx(call.from_user.id, + user_balance=get_user['user_balance'] + amount, + user_refill=get_user['user_refill'] + amount) + + await call.message.edit_text(f"💰 Вы пополнили баланс на сумму {amount}₽. Удачи ❤\n" + f"🧾 Чек: #{receipt}") + + await send_admins( + f"👤 Пользователь: @{get_user['user_login']} | {get_user['user_name']} | {get_user['user_id']}\n" + f"💰 Сумма пополнения: {amount}₽\n" + f"🧾 Чек: #{receipt}" + ) diff --git a/TelegramGoodsinbot/tgbot/handlers/z_all_errors.py b/TelegramGoodsinbot/tgbot/handlers/z_all_errors.py new file mode 100644 index 0000000..5b82fb6 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/z_all_errors.py @@ -0,0 +1,67 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import Update + +from tgbot.keyboards.inline_z_page import products_item_category_open_fp, products_item_position_open_fp +from tgbot.loader import dp +from tgbot.services.api_sqlite import get_categoryx, get_all_categoriesx, get_positionx, get_positionsx +from tgbot.utils.misc.bot_logging import bot_logger + + +# Обработка телеграм ошибок +@dp.errors_handler() +async def all_errors(update: Update, exception): + get_data = None + + if "'NoneType' object is not subscriptable" in str(exception): + if "callback_query" in update: + get_data = update.callback_query.data + + if get_data is not None: + split_data = get_data.split(":") + + if split_data[0] in ['buy_category_open']: + get_category = get_categoryx(category_id=split_data[1]) + + if get_category is None: + get_categories = get_all_categoriesx() + + if len(get_categories) >= 1: + await update.callback_query.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_category_open_fp(0)) + await update.callback_query.answer("❗ Категория была изменена или удалена") + else: + await update.callback_query.message.edit_text("🎁 Товары в данное время отсутствуют.") + await update.callback_query.answer("❗ Категория была изменена или удалена") + elif split_data[0] in ['buy_position_open']: + get_position = get_positionx(position_id=split_data[1]) + + if get_position is None: + get_positions = get_positionsx(category_id=split_data[3]) + + if len(get_positions) >= 1: + await update.callback_query.message.edit_text("🎁 Выберите нужный вам товар:", + reply_markup=products_item_position_open_fp( + split_data[2], split_data[3])) + await update.callback_query.answer("❗ Позиция была изменена или удалена") + else: + await update.callback_query.message.edit_text("🎁 Товары в данное время отсутствуют.") + await update.callback_query.answer("❗ Позиция была изменена или удалена") + elif split_data[0] in ['buy_item_select']: + get_position = get_positionx(position_id=split_data[1]) + + if get_position is None: + await update.callback_query.message.edit_text("🎁 Товары в данное время отсутствуют.") + await update.callback_query.answer("❗ Позиция была изменена или удалена") + else: + pass + + # Логгирование ошибок в ЛС бота + # await send_admins(f"❌ Ошибка\n\n" + # f"Exception: {exception}\n\n" + # f"Update: {update}") + + print(f"-Exception | {exception}") + bot_logger.exception( + f"Exception: {exception}\n" + f"Update: {update}" + ) diff --git a/TelegramGoodsinbot/tgbot/handlers/z_all_missed_.py b/TelegramGoodsinbot/tgbot/handlers/z_all_missed_.py new file mode 100644 index 0000000..6230cee --- /dev/null +++ b/TelegramGoodsinbot/tgbot/handlers/z_all_missed_.py @@ -0,0 +1,37 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher import FSMContext +from aiogram.types import CallbackQuery, Message + +from tgbot.keyboards.reply_z_all import menu_frep +from tgbot.loader import dp + + +# Колбэк с удалением сообщения +@dp.callback_query_handler(text="close_this", state="*") +async def missed_callback_close(call: CallbackQuery, state: FSMContext): + await call.message.delete() + + +# Колбэк с обработкой кнопки +@dp.callback_query_handler(text="...", state="*") +async def missed_callback_answer(call: CallbackQuery, state: FSMContext): + await call.answer(cache_time=60) + + +# Обработка всех колбэков которые потеряли стейты после перезапуска скрипта +@dp.callback_query_handler(state="*") +async def missed_callback(call: CallbackQuery, state: FSMContext): + try: + await call.message.delete() + except: + pass + + await call.message.answer("❌ Данные не были найдены из-за перезапуска скрипта.\n" + "♻ Выполните действие заново.", + reply_markup=menu_frep(call.from_user.id)) + +# Обработка всех неизвестных команд +@dp.message_handler() +async def missed_message(message: Message): + await message.answer("♦ Неизвестная команда.\n" + "▶ Введите /start") diff --git a/TelegramGoodsinbot/tgbot/keyboards/__init__.py b/TelegramGoodsinbot/tgbot/keyboards/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TelegramGoodsinbot/tgbot/keyboards/inline_admin.py b/TelegramGoodsinbot/tgbot/keyboards/inline_admin.py new file mode 100644 index 0000000..dbf4940 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/inline_admin.py @@ -0,0 +1,232 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton as ikb, InlineKeyboardButton + +from tgbot.services.api_sqlite import get_paymentx, get_settingsx, get_userx, update_settingsx + + +# Поиск профиля +def profile_search_finl(user_id): + keyboard = InlineKeyboardMarkup( + ).add( + ikb("💰 Изменить баланс", + callback_data=f"admin_user_balance_set:{user_id}"), + ikb("💰 Выдать баланс", + callback_data=f"admin_user_balance_add:{user_id}") + ).add( + ikb("🎁 Покупки", callback_data=f"admin_user_purchases:{user_id}"), + ikb("💌 Отправить СМС", callback_data=f"admin_user_message:{user_id}") + ).add( + ikb("🔄 Обновить", callback_data=f"admin_user_refresh:{user_id}") + ) + + return keyboard + + +# Поиск профиля с запросом на продавца +def profile_search_reqs(user_id): + keyboard = InlineKeyboardMarkup( + ).add( + ikb(" Подтвердить запрос", + callback_data=f"admin_user_request_approve:{user_id}"), + ikb(" Отклонить запрос", + callback_data=f"admin_user_request_decline:{user_id}"), + ikb(" Удалить запрос", + callback_data=f"admin_user_request_delete:{user_id}") + ) + + return keyboard + + +# Способы пополнения +def payment_choice_finl(): + keyboard = InlineKeyboardMarkup() + get_payments = get_paymentx() + + status_form_kb = ikb("✅", callback_data="change_payment:Form:False") + status_number_kb = ikb("✅", callback_data="change_payment:Number:False") + status_nickname_kb = ikb( + "✅", callback_data="change_payment:Nickname:False") + status_formy_kb = ikb("✅", callback_data="change_payment:ForYm:False") + + if get_payments['way_form'] == "False": + status_form_kb = ikb("❌", callback_data="change_payment:Form:True") + if get_payments['way_number'] == "False": + status_number_kb = ikb("❌", callback_data="change_payment:Number:True") + if get_payments['way_nickname'] == "False": + status_nickname_kb = ikb( + "❌", callback_data="change_payment:Nickname:True") + if get_payments['way_formy'] == "False": + status_formy_kb = ikb("❌", callback_data="change_payment:ForYm:True") + + keyboard.add(InlineKeyboardButton( + "📋 По форме", url="https://vk.cc/bYjKGM"), status_form_kb) + keyboard.add(InlineKeyboardButton( + "📞 По номеру", url="https://vk.cc/bYjKEy"), status_number_kb) + keyboard.add(InlineKeyboardButton("Ⓜ По никнейму", + url="https://vk.cc/c8s66X"), status_nickname_kb) + keyboard.add(InlineKeyboardButton( + "📋 По Yoo", url="https://vk.cc/bYjKGM"), status_formy_kb) + + return keyboard + + +# Кнопки с настройками +def settings_open_finl(): + keyboard = InlineKeyboardMarkup() + get_settings = get_settingsx() + + if get_settings['misc_support'].isdigit(): + get_user = get_userx(user_id=get_settings['misc_support']) + + if get_user is not None: + support_kb = ikb( + f"@{get_user['user_login']} ✅", callback_data="settings_edit_support") + else: + support_kb = ikb("Не установлены ❌", + callback_data="settings_edit_support") + update_settingsx(misc_support="None") + else: + support_kb = ikb("Не установлены ❌", + callback_data="settings_edit_support") + + if "None" == get_settings['misc_faq']: + faq_kb = ikb("Не установлено ❌", callback_data="settings_edit_faq") + else: + faq_kb = ikb("Установлено ✅", callback_data="settings_edit_faq") + + if get_settings['type_trade'] is None: + trade_type_kb = ikb( + "Тип не задан ❌", callback_data="settings_edit_trade_type") + else: + trade_type_kb = ikb( + f"Тип плоащдки утановлен: {get_settings['type_trade']} ✅", callback_data="settings_edit_type_trade") + + keyboard.add( + ikb("ℹ FAQ", callback_data="..."), faq_kb + ).add( + ikb("☎ Поддержка/FAQ", callback_data="..."), support_kb + ).add( + ikb("☎ Тип площадки", callback_data="..."), trade_type_kb + ) + + return keyboard + + +# Выключатели +def turn_open_finl(): + keyboard = InlineKeyboardMarkup() + get_settings = get_settingsx() + + if get_settings['status_buy'] == "True": + status_buy_kb = ikb("Включены ✅", callback_data="turn_buy:False") + elif get_settings['status_buy'] == "False": + status_buy_kb = ikb("Выключены ❌", callback_data="turn_buy:True") + + if get_settings['status_work'] == "True": + status_twork_kb = ikb("Включены ✅", callback_data="turn_twork:False") + elif get_settings['status_work'] == "False": + status_twork_kb = ikb("Выключены ❌", callback_data="turn_twork:True") + + if get_settings['status_refill'] == "True": + status_pay_kb = ikb("Включены ✅", callback_data="turn_pay:False") + else: + status_pay_kb = ikb("Выключены ❌", callback_data="turn_pay:True") + + keyboard.row(ikb("⛔ Тех. работы", callback_data="..."), status_twork_kb) + keyboard.row(ikb("💰 Пополнения", callback_data="..."), status_pay_kb) + keyboard.row(ikb("🎁 Покупки", callback_data="..."), status_buy_kb) + + return keyboard + + +######################################## ТОВАРЫ ######################################## +# Изменение категории +def category_edit_open_finl(category_id, remover): + keyboard = InlineKeyboardMarkup( + ).add( + ikb("🏷 Изм. название", + callback_data=f"category_edit_name:{category_id}:{remover}"), + ikb("❌ Удалить", + callback_data=f"category_edit_delete:{category_id}:{remover}") + ).add( + ikb("⬅ Вернуться ↩", callback_data=f"category_edit_return:{remover}") + ) + + return keyboard + + +# Кнопки с удалением категории +def category_edit_delete_finl(category_id, remover): + keyboard = InlineKeyboardMarkup( + ).add( + ikb("❌ Да, удалить", + callback_data=f"category_delete:{category_id}:yes:{remover}"), + ikb("✅ Нет, отменить", + callback_data=f"category_delete:{category_id}:not:{remover}") + ) + + return keyboard + + +# Кнопки при открытии позиции для изменения +def position_edit_open_finl(position_id, category_id, remover): + keyboard = InlineKeyboardMarkup( + ).add( + ikb("🏷 Изм. название", + callback_data=f"position_edit_name:{position_id}:{category_id}:{remover}"), + ikb("💰 Изм. цену", + callback_data=f"position_edit_price:{position_id}:{category_id}:{remover}"), + ).add( + ikb("📜 Изм. описание", + callback_data=f"position_edit_description:{position_id}:{category_id}:{remover}"), + ikb("📸 Изм. фото", + callback_data=f"position_edit_photo:{position_id}:{category_id}:{remover}"), + # добавил 12.08.22 ----------------------------------------------------------- + ).add( + ikb("🏙 Изм. город", + callback_data=f"position_edit_city:{position_id}:{category_id}:{remover}"), + ikb("Для симметрии", + callback_data=f"position____edit_photo:{position_id}:{category_id}:{remover}"), + # ------------------------------------------------------------------------- + ).add( + ikb("🗑 Очистить", + callback_data=f"position_edit_clear:{position_id}:{category_id}:{remover}"), + ikb("🎁 Добавить товары", + callback_data=f"products_add_position:{position_id}:{category_id}"), + ).add( + ikb("📥 Товары", + callback_data=f"position_edit_items:{position_id}:{category_id}:{remover}"), + ikb("❌ Удалить", + callback_data=f"position_edit_delete:{position_id}:{category_id}:{remover}"), + ).add( + ikb("⬅ Вернуться ↩", + callback_data=f"position_edit_return:{category_id}:{remover}"), + ) + + return keyboard + + +# Подтверждение удаления позиции +def position_edit_delete_finl(position_id, category_id, remover): + keyboard = InlineKeyboardMarkup( + ).add( + ikb("❌ Да, удалить", + callback_data=f"position_delete:yes:{position_id}:{category_id}:{remover}"), + ikb("✅ Нет, отменить", + callback_data=f"position_delete:not:{position_id}:{category_id}:{remover}") + ) + + return keyboard + + +# Подтверждение очистики позиции +def position_edit_clear_finl(position_id, category_id, remover): + keyboard = InlineKeyboardMarkup( + ).add( + ikb("❌ Да, очистить", + callback_data=f"position_clear:yes:{position_id}:{category_id}:{remover}"), + ikb("✅ Нет, отменить", + callback_data=f"position_clear:not:{position_id}:{category_id}:{remover}") + ) + + return keyboard diff --git a/TelegramGoodsinbot/tgbot/keyboards/inline_user copy.py b/TelegramGoodsinbot/tgbot/keyboards/inline_user copy.py new file mode 100644 index 0000000..3e935c9 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/inline_user copy.py @@ -0,0 +1,127 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton + +from tgbot.services.api_sqlite import get_paymentx + + +# Выбор способов пополнения +def refill_choice_finl(): + keyboard = InlineKeyboardMarkup() + + get_payments = get_paymentx() + active_kb = [] + + if get_payments['way_form'] == "True": + active_kb.append(InlineKeyboardButton( + "📋 QIWI форма", callback_data="refill_choice:Form")) + if get_payments['way_number'] == "True": + active_kb.append(InlineKeyboardButton( + "📞 QIWI номер", callback_data="refill_choice:Number")) + if get_payments['way_nickname'] == "True": + active_kb.append(InlineKeyboardButton( + "Ⓜ QIWI никнейм", callback_data="refill_choice:Nickname")) + + if len(active_kb) == 3: + keyboard.add(active_kb[0], active_kb[1]) + keyboard.add(active_kb[2]) + elif len(active_kb) == 2: + keyboard.add(active_kb[0], active_kb[1]) + elif len(active_kb) == 1: + keyboard.add(active_kb[0]) + else: + keyboard = None + + if len(active_kb) >= 1: + keyboard.add(InlineKeyboardButton( + "⬅ Вернуться ↩", callback_data="user_profile")) + + return keyboard + +# Проверка киви платежа + + +def refill_bill_finl(send_requests, get_receipt, get_way): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("🌀 Перейти к оплате", url=send_requests) + ).add( + InlineKeyboardButton("🔄 Проверить оплату", + callback_data=f"Pay:{get_way}:{get_receipt}") + ) + + return keyboard + + +# Кнопки при открытии самого товара +def products_open_finl(position_id, remover, category_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton( + "💰 Купить товар", callback_data=f"buy_item_select:{position_id}") + ).add( + InlineKeyboardButton( + "⬅ Вернуться ↩", callback_data=f"buy_position_return:{remover}:{category_id}") + ) + + return keyboard + +# Способы пополнения + + +def payment_as_choice_finl(): + keyboard = InlineKeyboardMarkup() + get_payments = get_paymentx() + + if get_payments['way_form'] == "True": + status_form_kb = InlineKeyboardButton( + "✅", callback_data="change_payment:Form:False") + else: + status_form_kb = InlineKeyboardButton( + "❌", callback_data="change_payment:Form:True") + + if get_payments['way_number'] == "True": + status_number_kb = InlineKeyboardButton( + "✅", callback_data="change_payment:Number:False") + else: + status_number_kb = InlineKeyboardButton( + "❌", callback_data="change_payment:Number:True") + + if get_payments['way_nickname'] == "True": + status_nickname_kb = InlineKeyboardButton( + "✅", callback_data="change_payment:Nickname:False") + else: + status_nickname_kb = InlineKeyboardButton( + "❌", callback_data="change_payment:Nickname:True") + + keyboard.add(InlineKeyboardButton( + "📋 По форме", url="https://vk.cc/bYjKGM"), status_form_kb) + keyboard.add(InlineKeyboardButton( + "📞 По номеру", url="https://vk.cc/bYjKEy"), status_number_kb) + keyboard.add(InlineKeyboardButton("Ⓜ По никнейму", + url="https://vk.cc/c8s66X"), status_nickname_kb) + + return keyboard + + +# Подтверждение покупки товара +def products_confirm_finl(position_id, get_count): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton( + "✅ Подтвердить", callback_data=f"xbuy_item:yes:{position_id}:{get_count}"), + InlineKeyboardButton( + "❌ Отменить", callback_data=f"xbuy_item:not:{position_id}:{get_count}") + ) + + return keyboard + + +# Ссылка на поддержку +def user_support_finl(user_name): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("💌 Написать в поддержку", + url=f"https://t.me/{user_name}"), + ) + + return keyboard diff --git a/TelegramGoodsinbot/tgbot/keyboards/inline_user.py b/TelegramGoodsinbot/tgbot/keyboards/inline_user.py new file mode 100644 index 0000000..5493671 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/inline_user.py @@ -0,0 +1,296 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton + +from tgbot.services.api_sqlite import get_paymentx, get_upaymentx + + +# Выбор способов пополнения +def refill_choice_finl(): + keyboard = InlineKeyboardMarkup() + + get_payments = get_paymentx() + active_kb = [] + + if get_payments['way_form'] == "True": + active_kb.append(InlineKeyboardButton( + "📋 QIWI форма", callback_data="refill_choice:Form")) + if get_payments['way_number'] == "True": + active_kb.append(InlineKeyboardButton( + "📞 QIWI номер", callback_data="refill_choice:Number")) + if get_payments['way_nickname'] == "True": + active_kb.append(InlineKeyboardButton( + "Ⓜ QIWI никнейм", callback_data="refill_choice:Nickname")) + if get_payments['way_formy'] == "True": + active_kb.append(InlineKeyboardButton( + "📋 Yoo форма", callback_data="refill_choice:ForYm")) + + if len(active_kb) == 4: + keyboard.add(active_kb[0], active_kb[1]) + keyboard.add(active_kb[2], active_kb[3]) + elif len(active_kb) == 3: + keyboard.add(active_kb[0], active_kb[1]) + keyboard.add(active_kb[2]) + elif len(active_kb) == 2: + keyboard.add(active_kb[0], active_kb[1]) + elif len(active_kb) == 1: + keyboard.add(active_kb[0]) + else: + keyboard = None + + if len(active_kb) >= 1: + keyboard.add(InlineKeyboardButton( + "⬅ Вернуться в профиль ↩", callback_data="user_profile")) + keyboard.add(InlineKeyboardButton( + "⬅ Вернуться в корзину ↩", callback_data="user_cart")) + + return keyboard + +# Проверка киви платежа + + +def refill_bill_finl(send_requests, get_receipt, get_way): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("🌀 Перейти к оплате", url=send_requests) + ).add( + InlineKeyboardButton("🔄 Проверить оплату", + callback_data=f"Pay:{get_way}:{get_receipt}") + ) + + return keyboard + +# Поделиться телефоном + + +def give_number_inl(): + keyboard = InlineKeyboardMarkup( + ).add( + #InlineKeyboardButton("Поделиться номером", callback_data="enter_phone_auto") + InlineKeyboardButton("Поделиться номером", request_contact=True) + ) + + return keyboard + +# Кнопки при открытии самого товара + + +def products_open_finl(position_id, remover, category_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton( + "💰 Купить товар", callback_data=f"buy_item_select:{position_id}") + ).add( + InlineKeyboardButton( + "⬅ Вернуться ↩", callback_data=f"buy_position_return:{remover}:{category_id}") + ) + + return keyboard + +# Кнопки при открытии самого товара c корзиной + + +def products_open_cart_finl(position_id, remover, category_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("🛒 Добавить в корзину", + callback_data=f"add_item_cart:{position_id}") + ).add( + InlineKeyboardButton( + "⬅ Вернуться ↩", callback_data=f"buy_position_return:{remover}:{category_id}") + ) + + return keyboard + +# ).add( +#InlineKeyboardButton("💰 Купить товар", callback_data=f"buy_item_select:{position_id}") + + +def charge_button_add(anull): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("💰 Пополнить", callback_data="user_refill") + ) + + return keyboard + +# Способы пополнения + + +def payment_as_choice_finl(user_id): + keyboard = InlineKeyboardMarkup() + #get_payments = get_paymentx() + print(user_id) + print("inline_user") + get_payments = get_upaymentx(user_id) + + if get_payments['way_form'] == "True": + status_form_kb = InlineKeyboardButton( + "✅", callback_data="change_payment:Form:False:user_id") + else: + status_form_kb = InlineKeyboardButton( + "❌", callback_data="change_payment:Form:True:user_id") + + if get_payments['way_number'] == "True": + status_number_kb = InlineKeyboardButton( + "✅", callback_data="change_payment:Number:False:user_id") + else: + status_number_kb = InlineKeyboardButton( + "❌", callback_data="change_payment:Number:True:user_id") + + if get_payments['way_nickname'] == "True": + status_nickname_kb = InlineKeyboardButton( + "✅", callback_data="change_payment:Nickname:False:user_id") + else: + status_nickname_kb = InlineKeyboardButton( + "❌", callback_data="change_payment:Nickname:True:user_id") + + if get_payments['way_formy'] == "True": + status_formy_kb = InlineKeyboardButton( + "✅", callback_data="change_payment:ForYm:False:user_id") + else: + status_formy_kb = InlineKeyboardButton( + "❌", callback_data="change_payment:ForYm:True:user_id") + + keyboard.add(InlineKeyboardButton( + "📋 По форме", url="https://vk.cc/bYjKGM"), status_form_kb) + keyboard.add(InlineKeyboardButton( + "📞 По номеру", url="https://vk.cc/bYjKEy"), status_number_kb) + keyboard.add(InlineKeyboardButton("Ⓜ По никнейму", + url="https://vk.cc/c8s66X"), status_nickname_kb) + keyboard.add(InlineKeyboardButton("📋 По форме Yoo", + url="https://vk.cc/bYjKGM"), status_formy_kb) + + return keyboard + +# Удаление корзины + + +def confirm_user_cart(user_id, ): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton( + "✅ Подтвердить", callback_data=f"xaddcart_item:yes:{position_id}:{get_count}"), + InlineKeyboardButton( + "❌ Отменить", callback_data=f"xaddcart_item:not:{position_id}:{get_count}") + ) + + return keyboard + +# Подтверждение покупки товара + + +def products_addcart_confirm_finl(position_id, get_count): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton( + "✅ Подтвердить", callback_data=f"xaddcart_item:yes:{position_id}:{get_count}"), + InlineKeyboardButton( + "❌ Отменить", callback_data=f"xaddcart_item:not:{position_id}:{get_count}") + ) + + return keyboard + + +# Подтверждение покупки товара +def products_confirm_finl(position_id, get_count): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton( + "✅ Подтвердить", callback_data=f"xbuy_item:yes:{position_id}:{get_count}"), + InlineKeyboardButton( + "❌ Отменить", callback_data=f"xbuy_item:not:{position_id}:{get_count}") + ) + + return keyboard + + +# Подтверждение сохранения адреса доставки +def accept_saved_adr(user_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("✅ Да, оставить текущий адрес", + callback_data=f"user_cart"), + InlineKeyboardButton("❌ Ввести новый адрес", + callback_data=f"enter_address_manualy:{user_id}") + ) + + return keyboard + + +def accept_saved_phone(user_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("✅ Да, оставить текущий номер", + callback_data=f"user_cart"), + InlineKeyboardButton("❌ Ввести новый номер", + callback_data=f"enter_phone_manualy:{user_id}") + ) + + return keyboard + +# Подтверждение отправки сообщения продавцом + + +def order_reply_message_finl(user_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("✅ Вернуться в Корзину", + callback_data=f"user_cart"), + InlineKeyboardButton("❌ Ввести новое сообщение", + callback_data=f"reply_toorder_message") + ) + + return keyboard + +# Подтверждение отправки сообщения покупателем + + +def cart_enter_message_finl(user_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("✅ Ответить на сообщение продавца", + callback_data=f"enter_message_manualy"), + # InlineKeyboardButton("❌ Остановить сделку", + # callback_data=f"stop_sale_process") + ) + + return keyboard + +# Ответ на сообщение продавца + + +def enter_cart_message_finl(user_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("✅ Вернуться в Корзину", + callback_data=f"user_cart"), + InlineKeyboardButton("❌ Ввести новое сообщение", + callback_data=f"enter_message_manualy") + ) + + return keyboard + + +# Ответ на сообщение покупателя +def reply_order_message_finl(user_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("✅ Ответить на сообщение покупателя", + callback_data=f"reply_toorder_message"), + # InlineKeyboardButton("❌ Остановить сделку", + # callback_data=f"stop_sale_process") + ) + + return keyboard + +# Ссылка на поддержку + + +def user_support_finl(user_name): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("💌 Написать в поддержку", + url=f"https://t.me/{user_name}"), + ) + + return keyboard diff --git a/TelegramGoodsinbot/tgbot/keyboards/inline_user2.py b/TelegramGoodsinbot/tgbot/keyboards/inline_user2.py new file mode 100644 index 0000000..4a4d974 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/inline_user2.py @@ -0,0 +1,90 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton + +from tgbot.services.api_sqlite import get_upaymentx + + +# Выбор способов пополнения +def refill_choice_finl(user_id): + keyboard = InlineKeyboardMarkup() + + get_payments = get_upaymentx(user_id) + active_kb = [] + + if get_payments['way_form'] == "True": + active_kb.append(InlineKeyboardButton( + "📋 QIWI форма", callback_data="refill_choice:Form")) + if get_payments['way_number'] == "True": + active_kb.append(InlineKeyboardButton( + "📞 QIWI номер", callback_data="refill_choice:Number")) + if get_payments['way_nickname'] == "True": + active_kb.append(InlineKeyboardButton( + "Ⓜ QIWI никнейм", callback_data="refill_choice:Nickname")) + + if len(active_kb) == 3: + keyboard.add(active_kb[0], active_kb[1]) + keyboard.add(active_kb[2]) + elif len(active_kb) == 2: + keyboard.add(active_kb[0], active_kb[1]) + elif len(active_kb) == 1: + keyboard.add(active_kb[0]) + else: + keyboard = None + + if len(active_kb) >= 1: + keyboard.add(InlineKeyboardButton( + "⬅ Вернуться ↩", callback_data="user_profile")) + + return keyboard + +# Проверка киви платежа + + +def refill_bill_finl(send_requests, get_receipt, get_way): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("🌀 Перейти к оплате", url=send_requests) + ).add( + InlineKeyboardButton("🔄 Проверить оплату", + callback_data=f"Pay:{get_way}:{get_receipt}") + ) + + return keyboard + + +# Кнопки при открытии самого товара +def products_open_finl(position_id, remover, category_id): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton( + "💰 Купить товар", callback_data=f"buy_item_select:{position_id}") + ).add( + InlineKeyboardButton( + "⬅ Вернуться ↩", callback_data=f"buy_position_return:{remover}:{category_id}") + ) + + return keyboard + + +# Подтверждение покупки товара +def products_confirm_finl(position_id, get_count): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton( + "✅ Подтвердить", callback_data=f"xbuy_item:yes:{position_id}:{get_count}"), + InlineKeyboardButton( + "❌ Отменить", callback_data=f"xbuy_item:not:{position_id}:{get_count}") + ) + + return keyboard + + +# Ссылка на поддержку +def user_support_finl(user_name): + keyboard = InlineKeyboardMarkup( + ).add( + InlineKeyboardButton("💌 Написать в поддержку", + url=f"https://t.me/{user_name}"), + ) + + return keyboard diff --git a/TelegramGoodsinbot/tgbot/keyboards/inline_z_all.py b/TelegramGoodsinbot/tgbot/keyboards/inline_z_all.py new file mode 100644 index 0000000..b199867 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/inline_z_all.py @@ -0,0 +1,130 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton +from tgbot.services.api_sqlite import get_settingsx + +settings = get_settingsx() +type_trade = settings['type_trade'] +print(type_trade) + +# Рассылка +ad_confirm_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("✅ Отправить", callback_data="confirm_ad:yes"), + InlineKeyboardButton("❌ Отменить", callback_data="confirm_ad:not") +) + +# Кнопки при поиске профиля через админ-меню +refill_open_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("💰 Пополнить", callback_data="user_refill") +) + +# Кнопки при поиске профиля через админ-меню +profile_open_inl = InlineKeyboardMarkup(row_width=2 + ).add( + InlineKeyboardButton("💰 Пополнить", callback_data="user_refill"), + InlineKeyboardButton("🎁 Мои покупки", callback_data="user_history") +) +if(type_trade != 'digital'): + profile_open_inl = InlineKeyboardMarkup(row_width=2).add( + InlineKeyboardButton("💰 Пополнить", callback_data="user_refill"), + InlineKeyboardButton("🎁 Мои покупки", callback_data="user_history"), + #InlineKeyboardButton("📡 Изменить город", callback_data="edit_locatoin") + ) + +give_number_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("Поделиться номером", + callback_data="enter_phone_auto_fin") + #InlineKeyboardButton("Поделиться номером", request_contact=True) +) + +# Удаление сообщения +close_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("❌ Закрыть", callback_data="close_this"), +) + +# Открытие корзины +cart_open_created_inl = InlineKeyboardMarkup( +).add( + # InlineKeyboardButton( + # "🏢 Ввести адрес", callback_data=f"enter_address_manualy"), + # InlineKeyboardButton("📱 Ввести телефон", + # callback_data=f"enter_phone_manualy"), + InlineKeyboardButton(" ! Оформить заказ", + callback_data=f"checkout_start"), +).add( + # InlineKeyboardButton("📱 Поделиться номером", + # callback_data=f"enter_phone_auto"), + InlineKeyboardButton("💰 Пополнить счет", callback_data=f"user_refill"), + InlineKeyboardButton("❓ Спросить продавца", + callback_data=f"enter_message_manualy"), +).add( + InlineKeyboardButton(" Удалить корзину", + callback_data=f"del_user_cart"), +) + + +cart_open_delivery_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("📱 Подтвердить получение", + callback_data=f"submit_order"), +).add( + # InlineKeyboardButton("📱 Открыть спор", callback_data=f"open_debate"), + InlineKeyboardButton("❓ Задать вопрос продавцу", + callback_data=f"enter_message_manualy"), +) + +# Удаление корзина +confirm_delete_user_cart_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("❌ Да, удалить корзину", + callback_data="confirm_del_user_cart"), + InlineKeyboardButton("✅ Нет, вернуться в корзину", + callback_data="user_cart") +) + +######################################## ТОВАРЫ ######################################## +# Удаление категорий +category_remove_confirm_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("❌ Да, удалить все", + callback_data="confirm_remove_category:yes"), + InlineKeyboardButton( + "✅ Нет, отменить", callback_data="confirm_remove_category:not") +) + +# Подтверждение полполнения счета +checkout_step2_accept = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("✅ Да, оформить", callback_data="checkout_finish"), + InlineKeyboardButton("❌ Вернуться в Корзину", callback_data="user_cart") +) + +# Подтверждение полполнения счета +order_user_refill = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("✅ Да, пополнить баланс", + callback_data="user_refill"), + InlineKeyboardButton("❌ Вернуться в Корзину", + callback_data="user_cart") +) + +# Удаление позиций +position_remove_confirm_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("❌ Да, удалить все", + callback_data="confirm_remove_position:yes"), + InlineKeyboardButton( + "✅ Нет, отменить", callback_data="confirm_remove_position:not") +) + +# Удаление товаров +item_remove_confirm_inl = InlineKeyboardMarkup( +).add( + InlineKeyboardButton("❌ Да, удалить все", + callback_data="confirm_remove_item:yes"), + InlineKeyboardButton( + "✅ Нет, отменить", callback_data="confirm_remove_item:not") +) diff --git a/TelegramGoodsinbot/tgbot/keyboards/inline_z_page.py b/TelegramGoodsinbot/tgbot/keyboards/inline_z_page.py new file mode 100644 index 0000000..a64ac32 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/inline_z_page.py @@ -0,0 +1,849 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton as ikb + +from tgbot.services.api_sqlite import get_all_categoriesx, get_itemsx, get_positionsx, get_all_shopx, get_city_user\ + , get_position_on_city, get_category_in_city + +cpage = 10 + + +# fp - flip page +# cpage - count page + +################################################################################################ +################################# СТРАНИЦЫ ИЗМЕНЕНИЯ КАТЕГОРИЙ ################################# +# Стартовые страницы выбора категории для изменения +def category_edit_open_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"category_edit_here:{get_categories[a]['category_id']}:{remover}")) + count += 1 + + if len(get_categories) <= 10: + pass + elif len(get_categories) > cpage and remover < 10: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"catategory_edit_nextp:{remover + cpage}") + ) + elif remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"catategory_edit_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"catategory_edit_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"catategory_edit_nextp:{remover + cpage}"), + ) + + return keyboard + + +# Следующая страница выбора категории для изменения +def category_edit_next_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"category_edit_here:{get_categories[a]['category_id']}:{remover}")) + count += 1 + if remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"catategory_edit_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"catategory_edit_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"catategory_edit_nextp:{remover + cpage}"), + ) + + return keyboard + + +# Предыдующая страница выбора категории для изменения +def category_edit_back_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"category_edit_here:{get_categories[a]['category_id']}:{remover}")) + count += 1 + + if remover <= 0: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"catategory_edit_nextp:{remover + cpage}") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"catategory_edit_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"catategory_edit_nextp:{remover + cpage}"), + ) + + return keyboard + + +################################################################################################ +################################### СТРАНИЦЫ СОЗДАНИЯ ПОЗИЦИЙ ################################## +# Стартовые страницы выбора категории для добавления позиции +def position_create_open_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"position_create_here:{get_categories[a]['category_id']}")) + count += 1 + + if len(get_categories) <= 10: + pass + elif len(get_categories) > cpage: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_create_nextp:{remover + cpage}") + ) + + return keyboard + + +# Следующая страница выбора категории для добавления позиции +def position_create_next_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"position_create_here:{get_categories[a]['category_id']}")) + count += 1 + + if remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_create_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_create_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_create_nextp:{remover + cpage}"), + ) + + return keyboard + +# Предыдующая страница выбора категории для добавления позиции +def position_create_back_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"position_create_here:{get_categories[a]['category_id']}")) + count += 1 + + if remover <= 0: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_create_nextp:{remover + cpage}") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_create_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_create_nextp:{remover + cpage}") + ) + + return keyboard + + +################################################################################################ +################################## СТРАНИЦЫ ИЗМЕНЕНИЯ ПОЗИЦИЙ ################################## +########################################### Категории ########################################## +# Стартовые страницы категорий при изменении позиции +def position_edit_category_open_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"position_edit_category:{get_categories[a]['category_id']}")) + count += 1 + + if len(get_categories) <= 10: + pass + elif len(get_categories) > cpage and remover < 10: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_category_nextp:{remover + cpage}") + ) + elif remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +# Следующая страница категорий при изменении позиции +def position_edit_category_next_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"position_edit_category:{get_categories[a]['category_id']}")) + count += 1 + + if remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +# Предыдующая страница категорий при изменении позиции +def position_edit_category_back_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"position_edit_category:{get_categories[a]['category_id']}")) + count += 1 + + if remover <= 0: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_category_nextp:{remover + cpage}") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +########################################### ПОЗИЦИИ ########################################## +# Стартовые страницы позиций для их изменения +def position_edit_open_fp(remover, category_id): + get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_positions)): + if count < cpage: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add(ikb( + f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽ | {len(get_items)} шт", + callback_data=f"position_edit:{get_positions[a]['position_id']}:{remover}:{category_id}")) + count += 1 + + if len(get_positions) <= 10: + pass + elif len(get_positions) > cpage and remover < 10: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_nextp:{remover + cpage}:{category_id}") + ) + elif remover + cpage >= len(get_positions): + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_nextp:{remover + cpage}:{category_id}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data="position_edit_category_return")) + + return keyboard + + +# Следующая страница позиций для их изменения +def position_edit_next_page_fp(remover, category_id): + get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_positions)): + if count < cpage: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add(ikb( + f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽ | {len(get_items)} шт", + callback_data=f"position_edit:{get_positions[a]['position_id']}:{remover}:{category_id}")) + count += 1 + + if remover + cpage >= len(get_positions): + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_nextp:{remover + cpage}:{category_id}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data="position_edit_category_return")) + + return keyboard + + +# Предыдующая страница позиций для их изменения +def position_edit_back_page_fp(remover, category_id): + get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_positions)): + if count < cpage: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add(ikb( + f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽ | {len(get_items)} шт", + callback_data=f"position_edit:{get_positions[a]['position_id']}:{remover}:{category_id}")) + count += 1 + + if remover <= 0: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_nextp:{remover + cpage}:{category_id}") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"position_edit_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_edit_nextp:{remover + cpage}:{category_id}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data="position_edit_category_return")) + + return keyboard + + +################################################################################################ +################################## СТРАНИЦЫ ДОБАВЛЕНИЯ ТОВАРОВ ################################# +# Стартовые страницы категорий при добавлении товара +def products_add_category_open_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"products_add_category:{get_categories[a]['category_id']}")) + count += 1 + + if len(get_categories) <= 10: + pass + elif len(get_categories) > cpage and remover < 10: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_category_nextp:{remover + cpage}") + ) + elif remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +# Следующая страница категорий при добавлении товара +def products_add_category_next_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"products_add_category:{get_categories[a]['category_id']}")) + count += 1 + + if remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +# Предыдующая страница категорий при добавлении товара +def products_add_category_back_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"products_add_category:{get_categories[a]['category_id']}")) + count += 1 + + if remover <= 0: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_category_nextp:{remover + cpage}") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +########################################### ПОЗИЦИИ ########################################## +# Стартовые страницы позиций для добавления товаров +def products_add_position_open_fp(remover, category_id): + get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_positions)): + if count < cpage: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add(ikb( + f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽ | {len(get_items)} шт", + callback_data=f"products_add_position:{get_positions[a]['position_id']}:{category_id}")) + count += 1 + + if len(get_positions) <= 10: + pass + elif len(get_positions) > cpage and remover < 10: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_position_nextp:{remover + cpage}:{category_id}") + ) + elif remover + cpage >= len(get_positions): + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_position_nextp:{remover + cpage}:{category_id}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data="back_add_products_to_category")) + + return keyboard + + +# Следующая страница позиций для добавления товаров +def products_add_position_next_page_fp(remover, category_id): + get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_positions)): + if count < cpage: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add(ikb( + f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽ | {len(get_items)} шт", + callback_data=f"products_add_position:{get_positions[a]['position_id']}:{category_id}")) + count += 1 + + if remover + cpage >= len(get_positions): + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_position_nextp:{remover + cpage}:{category_id}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data="back_add_products_to_category")) + + return keyboard + + +# Предыдующая страница позиций для добавления товаров +def products_add_position_back_page_fp(remover, category_id): + get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_positions)): + if count < cpage: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add(ikb( + f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽ | {len(get_items)} шт", + callback_data=f"products_add_position:{get_positions[a]['position_id']}:{category_id}")) + count += 1 + + if remover <= 0: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_position_nextp:{remover + cpage}:{category_id}") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"products_add_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"products_add_position_nextp:{remover + cpage}:{category_id}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data="back_add_products_to_category")) + + return keyboard + +################################################################################ +##################### Страница подтверждения запроса на продавца ############### +################################################################################ + +def request_seller_role(user_id): + keyboard = InlineKeyboardMarkup() + keyboard.add( + ikb("🔸 Запросить права продавца 🔸", callback_data="create_seller_request")) + + return keyboard + + +################################################################################################ +################################## СТРАНИЦЫ ПОКУПКИ ТОВАРОВ ################################# +# Стартовые страницы категорий при покупке товара +def products_item_category_open_fp(remover, city_id): + # get_categories = get_all_categoriesx() + if city_id == 0: + get_categories = get_all_categoriesx() + else: + get_categories = get_category_in_city(city_id) + print(len(get_categories)) + keyboard = InlineKeyboardMarkup() + count = 0 + + for category in get_categories[remover: len(get_categories)]: + if count < cpage: + keyboard.add(ikb(f"{category[1]}", + callback_data=f"buy_category_open:{category[0]}")) + count += 1 + + if len(get_categories) <= 10: + pass + elif len(get_categories) > cpage and remover < 10: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_category_nextp:{remover + cpage}") + ) + elif remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +# Следующая страница категорий при покупке товара +def products_item_category_next_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"buy_category_open:{get_categories[a]['category_id']}")) + count += 1 + + if remover + cpage >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +# Предыдующая страница категорий при покупке товара +def products_item_category_back_page_fp(remover): + get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_categories)): + if count < cpage: + keyboard.add(ikb(f"{get_categories[a]['category_name']}", + callback_data=f"buy_category_open:{get_categories[a]['category_id']}")) + count += 1 + + if remover <= 0: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_category_nextp:{remover + cpage}") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_category_backp:{remover - cpage}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_category_nextp:{remover + cpage}"), + ) + + return keyboard + + +########################################### ПОЗИЦИИ ########################################## +# Стартовые страницы позиций для покупки товаров +def products_item_position_open_fp(remover, category_id, city): + # get_positions = get_positionsx(category_id=category_id) + get_positions = get_position_on_city(category_id, city) + print(f'get_position {get_positions}') + keyboard = InlineKeyboardMarkup() + count = 0 + + # for a in range(remover, len(get_positions)): + # for a in get_positions[(remover): len(get_positions)]: + # if count < cpage: + # print(f'a {a}') + # get_items = get_itemsx(position_id=get_positions[a]['position_id']) + # keyboard.add(ikb( + # f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽ | {len(get_items)} шт", + # callback_data=f"buy_position_open:{get_positions[a]['position_id']}:{remover}:{category_id}")) + # count += 1 + for position in get_positions[(remover): len(get_positions)]: + if count < cpage: + print(f'position {position}') + get_items = get_itemsx(position_id=position[1]) + keyboard.add(ikb( + f"{position[2]} | {position[3]}₽", # | {len(get_items)} шт", + callback_data=f"buy_position_open:{position[1]}:{remover}:{category_id}:{city}")) + count += 1 + + if len(get_positions) <= 10: + pass + elif len(get_positions) > cpage and remover < 10: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_position_nextp:{remover + cpage}:{category_id}") + ) + elif remover + cpage >= len(get_positions): + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_position_nextp:{remover + cpage}:{category_id}"), + + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data=f"buy_category_return")) + + return keyboard + + +# Следующая страница позиций для покупки товаров +def products_item_position_next_page_fp(remover, category_id, city_id): + get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_positions)): + if count < cpage: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add(ikb( + f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽", # | {len(get_items)} шт", + callback_data=f"buy_position_open:{get_positions[a]['position_id']}:{remover}:{category_id}")) + count += 1 + + if remover + cpage >= len(get_positions): + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="...") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_position_nextp:{remover + cpage}:{category_id}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data=f"buy_category_return")) + + return keyboard + + +# Предыдующая страница позиций для покупки товаров +def buy_position_return_page_fp(remover, category_id): + get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_positions)): + if count < cpage: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add( + ikb(f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽", # | {len(get_items)} шт", + callback_data=f"buy_position_open:{get_positions[a]['position_id']}:{remover}:{category_id}")) + count += 1 + + if remover <= 0: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_position_nextp:{remover + cpage}:{category_id}") + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_position_backp:{remover - cpage}:{category_id}"), + ikb(f"🔸 {str(remover + cpage)[:-1]} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_position_nextp:{remover + cpage}:{category_id}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data=f"buy_category_return")) + + return keyboard + +############################################################################################# +####################################### ПОКУПКИ ТОВАРОВ ##################################### +# Страницы категорий при покупке товара +def products_item_category_swipe_fp(remover, city_id): + get_categories = get_category_in_city(city_id) + print(len(get_categories)) + #keyboard = InlineKeyboardMarkup() + count = 0 + + #get_categories = get_all_categoriesx() + keyboard = InlineKeyboardMarkup() + + if remover >= len(get_categories): remover -= 10 + + for count, a in enumerate(range(remover, len(get_categories))): + if count < 10: + keyboard.add(ikb(get_categories[a]['category_name'], + callback_data=f"buy_category_open:{get_categories[a]['category_id']}:{city_id}")) + + if len(get_categories) <= 10: + pass + elif len(get_categories) > 10 and remover < 10: + keyboard.add( + ikb(f"🔸 1/{math.ceil(len(get_categories) / 10)} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_category_swipe:{remover + 10}"), + ) + elif remover + 10 >= len(get_categories): + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_category_swipe:{remover - 10}"), + ikb(f"🔸 {str(remover + 10)[:-1]}/{math.ceil(len(get_categories) / 10)} 🔸", callback_data="..."), + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_category_swipe:{remover - 10}"), + ikb(f"🔸 {str(remover + 10)[:-1]}/{math.ceil(len(get_categories) / 10)} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_category_swipe:{remover + 10}"), + ) + + return keyboard + + +# Страницы позиций для покупки товаров +def products_item_position_swipe_fp(remover, category_id, city): + get_positions = get_position_on_city(category_id, city) + #get_positions = get_positionsx(category_id=category_id) + keyboard = InlineKeyboardMarkup() + + if remover >= len(get_positions): remover -= 10 + + for count, a in enumerate(range(remover, len(get_positions))): + if count < 10: + get_items = get_itemsx(position_id=get_positions[a]['position_id']) + keyboard.add(ikb( + f"{get_positions[a]['position_name']} | {get_positions[a]['position_price']}₽ | {len(get_items)} шт", + callback_data=f"buy_position_open:{get_positions[a]['position_id']}:{category_id}:{remover}")) + + if len(get_positions) <= 10: + pass + elif len(get_positions) > 10 and remover < 10: + keyboard.add( + ikb(f"🔸 1/{math.ceil(len(get_positions) / 10)} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_position_swipe:{category_id}:{remover + 10}"), + ) + elif remover + 10 >= len(get_positions): + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_position_swipe:{category_id}:{remover - 10}"), + ikb(f"🔸 {str(remover + 10)[:-1]}/{math.ceil(len(get_positions) / 10)} 🔸", callback_data="..."), + ) + else: + keyboard.add( + ikb("⬅ Назад", callback_data=f"buy_position_swipe:{category_id}:{remover - 10}"), + ikb(f"🔸 {str(remover + 10)[:-1]}/{math.ceil(len(get_positions) / 10)} 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"buy_position_swipe:{category_id}:{remover + 10}"), + ) + keyboard.add(ikb("⬅ Вернуться ↩", callback_data=f"buy_category_swipe:0")) + + return keyboard diff --git a/TelegramGoodsinbot/tgbot/keyboards/location_keyboards.py b/TelegramGoodsinbot/tgbot/keyboards/location_keyboards.py new file mode 100644 index 0000000..1cfb635 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/location_keyboards.py @@ -0,0 +1,59 @@ +from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, KeyboardButton + +import sqlite3 + + +def geo_11_kb(): + markup = ReplyKeyboardMarkup( + resize_keyboard=True, one_time_keyboard=True, row_width=1) + # bt1 = KeyboardButton('📡 Отправить своё местоположение', request_location=True) + #bt2 = KeyboardButton('📋 Выбрать из списка') + bt3 = KeyboardButton('⬆️ Вперёд') + markup.add(bt3) + return markup + + +def geo_1_kb(): + markup = ReplyKeyboardMarkup( + resize_keyboard=True, one_time_keyboard=True, row_width=1) + bt1 = KeyboardButton('📡 Отправить своё местоположение', + request_location=True) + bt2 = KeyboardButton('📋 Выбрать из списка') + markup.add(bt1, bt2) + return markup + + +def geo_2_kb(city): + markup = InlineKeyboardMarkup(row_width=1) + bt1 = InlineKeyboardButton( + 'Подтвердить', callback_data=f'geo_chosen_cities#{city}') + bt2 = InlineKeyboardButton( + 'Выбрать из списка', callback_data='choice_city_list') + markup.add(bt1, bt2) + return markup + + +def geo_3_kb(): + markup = InlineKeyboardMarkup(row_width=6) + letters_list = ['А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ж', 'З', 'И', 'Й', 'К', 'Л', + 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Х', 'Ч', 'Ш', 'Щ', 'Э', 'Ю', 'Я'] + for letter in letters_list: + button = InlineKeyboardButton( + letter, callback_data=f'geo_first_letter#{letter}') + markup.insert(button) + return markup + + +def geo_4_kb(info): + conn = sqlite3.connect('tgbot/data/data_cities.db') + cur = conn.cursor() + query = f'''select id, city FROM cities where temp = ? ''' + cur.execute(query, (info,)) + cities = cur.fetchall() + conn.commit() + markup = InlineKeyboardMarkup(row_width=1) + for city in cities: + button = InlineKeyboardButton( + str(city[1]), callback_data=f'geo_chosen_cities#{city[0]}') + markup.add(button) + return markup diff --git a/TelegramGoodsinbot/tgbot/keyboards/reply_z_all.py b/TelegramGoodsinbot/tgbot/keyboards/reply_z_all.py new file mode 100644 index 0000000..016e808 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/reply_z_all.py @@ -0,0 +1,126 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import ReplyKeyboardMarkup + +from tgbot.data.config import get_admins, get_shopadmins +from tgbot.services.api_sqlite import get_userx, check_user_shop_exist + +# Кнопки главного меню + + +def menu_frep(user_id): + user_role = get_userx(user_id=user_id) + if user_role is None: + user_role = "User" + else: + user_role = user_role['user_role'] + print(user_role) + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.row("🎁 Игры в аренду", "👤 Профиль", "🧮 Корзина") + + if user_role is None: + keyboard.row("☎ Поддержка/FAQ", "Хочу продавать") + #keyboard.row("☎ Поддержка/FAQ", "Хочу продавать", "💰 Пополнить") + if user_id in get_admins(): + keyboard.row("🎁 Управление товарами 🖍", "📊 Статистика") + keyboard.row("⚙ Настройки", "🔆 Общие функции", "🔑 Платежные системы") + keyboard.row("Запросы продавцов", "📊 Отчет о продажах") + + if user_id in get_shopadmins(): + #print(f'вывод меню reply_z_all.py 19') + keyboard.row("☎ Поддержка/FAQ") + #keyboard.row("☎ Поддержка/FAQ", "💰 Пополнить") + # , "🧮 Корзина") #, "🔑 Платежные системы") #, "📊 Статистика") + keyboard.row("🎁 Управление товарами дмаг.🖍") + #keyboard.row("⚙ Настройки", "🔆 Общие функции", "🔑 Платежные системы") + #keyboard.row("Запросы продавцов", "Управление магазинами") + + return keyboard + + +# Кнопки продавца +def shop_admin_frep(): + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.row("Отправить заявку") + keyboard.row("⬅ Главное меню") + + return keyboard + +# Кнопки платежных систем + + +def payments_frep(): + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.row("🥝 Изменить QIWI 🖍", "🥝 Проверить QIWI ♻", "🥝 Баланс QIWI 👁") + keyboard.row("⬅ Главное меню", "💳 Изменить Yoo 🖍", "🖲 Способы пополнения") + + return keyboard + + +# Кнопки общих функций +def functions_frep(user_id): + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.row("👤 Поиск профиля 🔍", "📢 Рассылка", "🧾 Поиск чеков 🔍") + keyboard.row("⬅ Главное меню") + + return keyboard + + +# Кнопки запросов в продавцы +def seller_requests_frep(): + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.row("🖍 Посмотреть запросы") + keyboard.row("⬅ Главное меню") + + return keyboard + +# Кнопки настроек + + +def settings_frep(): + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.row("🖍 Изменить данные", "🕹 Выключатели") + keyboard.row("⬅ Главное меню") + + return keyboard + +# Кнопки изменения товаров + + +def items_frep(): + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.row("🎁 Добавить товары ➕", "🎁 Удалить товары 🖍", + "🎁 Удалить все товары ❌") + keyboard.row("📁 Создать позицию ➕", "📁 Изменить позицию 🖍", + "📁 Удалить все позиции ❌") + keyboard.row("🗃 Создать категорию ➕", "🗃 Изменить категорию 🖍", + "🗃 Удалить все категории ❌") + keyboard.row("🏪 Создать магазин ➕", "🏪 Изменить магазин 🖍", + "🏪 Удалить все магазины ❌") + keyboard.row("⬅ Главное меню") + + return keyboard + +# Кнопки изменения товаров + + +def items_sh_frep(): + keyboard = ReplyKeyboardMarkup(resize_keyboard=True) + keyboard.row("🎁 Добавить товары ➕", "🎁 Удалить товары 🖍", + "🎁 Удалить все товары ❌") + keyboard.row("📁 Создать позицию ➕", "📁 Изменить позицию 🖍", + "📁 Удалить все позиции ❌") + # keyboard.row("🗃 Создать категорию ➕", "🗃 Изменить категорию 🖍") #, "🗃 Удалить все категории ❌") + #user_id = message.from_user.id + # if check_user_shop_exist(message.from_user.id) == 'True': + # keyboard.row("🏪 Изменить магазин 🖍") #, "🏪 Удалить все магазины ❌") + # if check_user_shop_exist(message.from_user.id) == 'False': + # , "🏪 Удалить все магазины ❌") + keyboard.row("🏪 Создать магазин ➕", "🏪 Изменить магазин 🖍") + keyboard.row("⬅ Главное меню") + + return keyboard + + +# Завершение загрузки товаров +finish_load_rep = ReplyKeyboardMarkup(resize_keyboard=True) +finish_load_rep.row("📥 Закончить загрузку товаров") diff --git a/TelegramGoodsinbot/tgbot/keyboards/shop_keyboards.py b/TelegramGoodsinbot/tgbot/keyboards/shop_keyboards.py new file mode 100644 index 0000000..2e591d8 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/keyboards/shop_keyboards.py @@ -0,0 +1,67 @@ +# - *- coding: utf- 8 - *- +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton as ikb + +from tgbot.services.api_sqlite_shop import get_all_shopx + +cpage = 10 + + +# fp - flip page +# cpage - count page + + +################################################################################################ +################################# СТРАНИЦЫ ИЗМЕНЕНИЯ МАГАЗИНА ################################# +# Стартовые страницы выбора магазина для изменения +def shop_edit_open_fp(remover, shops): + kb = InlineKeyboardMarkup() + count = 0 + if len(shops) < 10: + for shop in shops: + kb.add(ikb(f"{shop[1]}", + callback_data=f"shop_edit_here:{shop[0]}:{remover}")) + + + + else: + pg_cnt = len(shops) // 10 + print(f'pg_cnt {pg_cnt}') + print(f'page {remover}') + + if remover > 0: + bt3 = ikb('Предыдущая страница', callback_data=f'change_shop_edit_pg:{remover - 1}') + kb.add(bt3) + + pg_end = (int(remover) + 1) * 10 + print(f'pg_end {pg_end}') + for shop in shops[pg_end - 10:pg_end]: + bt2 = ikb(f'+{shop[1]}', callback_data=f'shop_edit_here:{shop[0]}') + kb.add(bt2) + + if remover < pg_cnt: + bt4 = ikb('Следующая страница', callback_data=f'change_shop_edit_pg:{remover + 1}') + kb.add(bt4) + return kb + + +# Стартовые страницы выбора категории для добавления позиции +def position_create_shop_fp(remover): + get_shops = get_all_shopx() + keyboard = InlineKeyboardMarkup() + count = 0 + + for a in range(remover, len(get_shops)): + if count < cpage: + keyboard.add(ikb(f"{get_shops[a]['shop_name']}", + callback_data=f"position_shop_create_here:{get_shops[a]['shop_id']}")) + count += 1 + + if len(get_shops) <= 10: + pass + elif len(get_shops) > cpage: + keyboard.add( + ikb("🔸 1 🔸", callback_data="..."), + ikb("Далее ➡", callback_data=f"position_shop_create_nextp:{remover + cpage}") + ) + + return keyboard diff --git a/TelegramGoodsinbot/tgbot/loader.py b/TelegramGoodsinbot/tgbot/loader.py new file mode 100644 index 0000000..ffabdc6 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/loader.py @@ -0,0 +1,11 @@ +# - *- coding: utf- 8 - *- +from aiogram import Bot, Dispatcher +from aiogram.contrib.fsm_storage.memory import MemoryStorage +from aiogram.types import ParseMode +from apscheduler.schedulers.asyncio import AsyncIOScheduler + +from tgbot.data.config import BOT_TOKEN + +bot = Bot(token=BOT_TOKEN, parse_mode=ParseMode.HTML) +dp = Dispatcher(bot, storage=MemoryStorage()) +scheduler = AsyncIOScheduler() diff --git a/TelegramGoodsinbot/tgbot/middlewares/__init__.py b/TelegramGoodsinbot/tgbot/middlewares/__init__.py new file mode 100644 index 0000000..2c26548 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/middlewares/__init__.py @@ -0,0 +1,11 @@ +# - *- coding: utf- 8 - *- +from aiogram import Dispatcher + +from tgbot.middlewares.exists_user import ExistsUserMiddleware +from tgbot.middlewares.throttling import ThrottlingMiddleware + + +# Подключение милдварей +def setup_middlewares(dp: Dispatcher): + dp.middleware.setup(ExistsUserMiddleware()) + dp.middleware.setup(ThrottlingMiddleware()) diff --git a/TelegramGoodsinbot/tgbot/middlewares/exists_user.py b/TelegramGoodsinbot/tgbot/middlewares/exists_user.py new file mode 100644 index 0000000..538d804 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/middlewares/exists_user.py @@ -0,0 +1,48 @@ +# - *- coding: utf- 8 - *- +from aiogram.dispatcher.middlewares import BaseMiddleware +from aiogram.types import Update + +from tgbot.data.config import get_admins +from tgbot.services.api_sqlite import get_userx, add_userx, update_userx, get_settingsx +from tgbot.utils.const_functions import clear_html + + +# Проверка юзеров в БД и его добавление +class ExistsUserMiddleware(BaseMiddleware): + def __init__(self): + self.prefix = "key_prefix" + super(ExistsUserMiddleware, self).__init__() + + async def on_process_update(self, update: Update, data: dict): + if "message" in update: + this_user = update.message.from_user + elif "callback_query" in update: + this_user = update.callback_query.from_user + else: + this_user = None + + if this_user is not None: + get_settings = get_settingsx() + get_prefix = self.prefix + + if get_settings['status_work'] == "False" or this_user.id in get_admins(): + if not this_user.is_bot: + get_user = get_userx(user_id=this_user.id) + + user_id = this_user.id + user_login = this_user.username + user_name = clear_html(this_user.first_name) + + if user_login is None: user_login = "" + + if get_user is None: + add_userx(user_id, user_login.lower(), user_name) + else: + if user_name != get_user['user_name']: + update_userx(get_user['user_id'], user_name=user_name) + + if len(user_login) >= 1: + if user_login.lower() != get_user['user_login']: + update_userx(get_user['user_id'], user_login=user_login.lower()) + else: + update_userx(get_user['user_id'], user_login="") diff --git a/TelegramGoodsinbot/tgbot/middlewares/throttling.py b/TelegramGoodsinbot/tgbot/middlewares/throttling.py new file mode 100644 index 0000000..024dd0c --- /dev/null +++ b/TelegramGoodsinbot/tgbot/middlewares/throttling.py @@ -0,0 +1,50 @@ +# - *- coding: utf- 8 - *- +from aiogram import types, Dispatcher +from aiogram.dispatcher.handler import CancelHandler, current_handler +from aiogram.dispatcher.middlewares import BaseMiddleware +from aiogram.types import Message +from aiogram.utils.exceptions import Throttled + +from tgbot.data.config import get_admins + + +# Мидлварь для антиспама +class ThrottlingMiddleware(BaseMiddleware): + def __init__(self, limit=0.5, key_prefix='antiflood_'): + self.rate_limit = limit + self.prefix = key_prefix + super(ThrottlingMiddleware, self).__init__() + + async def on_process_message(self, message: Message, data: dict): + handler = current_handler.get() + dispatcher = Dispatcher.get_current() + + if handler: + limit = getattr(handler, "throttling_rate_limit", self.rate_limit) + key = getattr(handler, "throttling_key", f"{self.prefix}_{handler.__name__}") + else: + limit = self.rate_limit + key = f"{self.prefix}_message" + + if message.from_user.id not in get_admins(): + try: + await dispatcher.throttle(key, rate=limit) + except Throttled as t: + await self.message_throttled(message, t) + raise CancelHandler() + + @staticmethod + async def message_throttled(message: types.Message, throttled: Throttled): + if throttled.exceeded_count <= 2: + await message.reply("❗ Пожалуйста, не спамьте.") + + +# Изменение лимитов отправки сообщения у декораторов +def rate_limit(limit: int, key=None): + def decorator(func): + setattr(func, "throttling_rate_limit", limit) + if key: + setattr(func, "throttling_key", key) + return func + + return decorator diff --git a/TelegramGoodsinbot/tgbot/services/__init__.py b/TelegramGoodsinbot/tgbot/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TelegramGoodsinbot/tgbot/services/api_qiwi-orig.py b/TelegramGoodsinbot/tgbot/services/api_qiwi-orig.py new file mode 100644 index 0000000..a17273c --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/api_qiwi-orig.py @@ -0,0 +1,320 @@ +# - *- coding: utf- 8 - *- +import asyncio +import json +import time + +from aiohttp import ClientConnectorCertificateError +from async_class import AsyncClass +from pyqiwip2p import QiwiP2P + +from tgbot.services.api_session import RequestsSession +from tgbot.services.api_sqlite import update_paymentx, get_paymentx +from tgbot.utils.misc_functions import send_admins + + +# Апи работы с QIWI +class QiwiAPI(AsyncClass): + async def __ainit__(self, dp, login=None, token=None, secret=None, add_pass=False, + check_pass=False, user_bill_pass=False, user_check_pass=False): + if login is not None: + self.login = login + self.token = token + self.secret = secret + else: + self.login = get_paymentx()['qiwi_login'] + self.token = get_paymentx()['qiwi_token'] + self.secret = get_paymentx()['qiwi_secret'] + + self.base_url = "https://edge.qiwi.com/{}/{}/persons/{}/{}" + self.headers = {"authorization": f"Bearer {self.token}"} + self.nickname = get_paymentx()['qiwi_nickname'] + self.user_check_pass = user_check_pass + self.user_bill_pass = user_bill_pass + self.check_pass = check_pass + self.add_pass = add_pass + self.dp = dp + + # Рассылка админам о нерабочем киви + @staticmethod + async def error_wallet(): + await send_admins("🥝 Qiwi кошелёк недоступен ❌\n" + "❗ Как можно быстрее его замените ❗") + + # Обязательная проверка перед каждым запросом + async def pre_checker(self): + if self.login != "None": + if self.add_pass: + status, response = await self.check_account() + else: + status, response, code = await self.check_logpass() + await asyncio.sleep(0.5) + + if self.add_pass: + await self.dp.edit_text(response) + if status: + update_paymentx(qiwi_login=self.login, qiwi_token=self.token, qiwi_secret=self.secret) + else: + return False + elif self.check_pass: + if status: + if self.secret == "None": + text_secret = "Отсутствует" + else: + text_secret = self.secret + + await self.dp.answer(f"🥝 Qiwi кошелёк полностью функционирует ✅\n" + f"◾ Номер: {self.login}\n" + f"◾ Токен: {self.token}\n" + f"◾ Приватный ключ: {text_secret}") + else: + await self.error_wallet() + return False + elif self.user_bill_pass: + if not status: + await self.dp.edit_text( + "❗ Извиняемся за доставленные неудобства, пополнение временно недоступно.\n" + "⌛ Попробуйте чуть позже.") + await self.error_wallet() + return False + elif self.user_check_pass: + if not status: + await self.dp.answer( + "❗ Извиняемся за доставленные неудобства, проверка временно недоступна.\n" + "⌛ Попробуйте чуть позже.", True) + await self.error_wallet() + return False + elif not status: + if not self.add_pass: + await self.error_wallet() + return False + + return True + else: + if self.user_bill_pass: + await self.dp.edit_text( + "❗ Извиняемся за доставленные неудобства, пополнение временно недоступно.\n" + "⌛ Попробуйте чуть позже.") + await self.error_wallet() + return False + + # Проверка баланса + async def get_balance(self): + response = await self.pre_checker() + if response: + status, response, code = await self._request( + "funding-sources", + "v2", + "accounts", + ) + + save_balance = [] + for balance in response['accounts']: + if "qw_wallet_usd" == balance['alias']: + save_balance.append(f"🇺🇸 Долларов: {balance['balance']['amount']}$") + + if "qw_wallet_rub" == balance['alias']: + save_balance.append(f"🇷🇺 Рублей: {balance['balance']['amount']}₽") + + if "qw_wallet_eur" == balance['alias']: + save_balance.append(f"🇪🇺 Евро: {balance['balance']['amount']}€") + + if "qw_wallet_kzt" == balance['alias']: + save_balance.append(f"🇰🇿 Тенге: {balance['balance']['amount']}₸") + + save_balance = "\n".join(save_balance) + await self.dp.answer(f"🥝 Баланс кошелька {self.login} составляет:\n" + f"{save_balance}") + + # Получение никнейма аккаунта + async def get_nickname(self): + response = await self.pre_checker() + if response: + status, response, code = await self._request( + "qw-nicknames", + "v1", + "nickname", + ) + + if response['nickname'] is None: + return False, "❗ На аккаунте отсутствует QIWI Никнейм. Установите его в настройках своего кошелька." + else: + return True, response['nickname'] + + return False, "" + + # Проверка аккаунта (логпаса и п2п) + async def check_account(self): + status_history, response_history, code_history = await self.check_logpass() + status_balance, response_balance, code_balance = await self._request( + "funding-sources", + "v2", + "accounts" + ) + + if status_history and status_balance: + if self.secret != "None": + status_secret = await self.check_secret() + if status_secret: + return True, "🥝 QIWI кошелёк был успешно изменён ✅" + else: + return_message = "🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + "▶ Код ошибки: Неверный приватный ключ\n" \ + "❕ Указывайте ПРИВАТНЫЙ КЛЮЧ, а не публичный. " \ + "Приватный ключ заканчивается на =" + else: + return True, "🥝 QIWI кошелёк был успешно изменён ✅" + else: + if 400 in [code_history, code_balance]: + return_message = f"🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Код ошибки: Номер телефона указан в неверном формате" + elif 401 in [code_history, code_balance]: + return_message = f"🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Код ошибки: Неверный токен или истек срок действия токена API" + elif 403 in [code_history, code_balance]: + return_message = f"🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Ошибка: Нет прав на данный запрос (недостаточно разрешений у токена API)" + elif "CERTIFICATE_VERIFY_FAILED" == code_history: + return_message = "🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Код ошибки: CERTIFICATE_VERIFY_FAILED certificate verify failed: self signed certificate in certificate chain\n" \ + f"❗ Ваш сервер/дедик/устройство блокирует запросы к QIWI. Отключите антивирус или другие блокирующие ПО." + else: + return_message = "🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Код ошибки: {code_history}/{code_balance}" + + return False, return_message + + # Проверка логпаса киви + async def check_logpass(self): + status, response, code = await self._request( + "payment-history", + "v2", + "payments", + {"rows": 1, "operation": "IN"}, + ) + + if status: + if "data" in response: + return True, response, code + else: + return False, None, code + else: + return False, None, code + + # Проверка п2п ключа + async def check_secret(self): + try: + qiwi_p2p = QiwiP2P(self.secret) + bill = qiwi_p2p.bill(amount=1, lifetime=1) + qiwi_p2p.reject(bill_id=bill.bill_id) + return True + except: + return False + + # Создание платежа + async def bill_pay(self, get_amount, get_way): + response = await self.pre_checker() + if response: + receipt = str(int(time.time() * 100)) + + if get_way == "Form": + qiwi = QiwiP2P(self.secret) + bill = qiwi.bill(bill_id=receipt, amount=get_amount, comment=receipt) + send_requests = bill.pay_url + + return_message = f"🆙 Пополнение баланса\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🥝 Для пополнения баланса, нажмите на кнопку ниже \n" \ + f"Перейти к оплате и оплатите выставленный вам счёт\n" \ + f"❗ У вас имеется 30 минут на оплату счета.\n" \ + f"💰 Сумма пополнения: {get_amount}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔄 После оплаты, нажмите на Проверить оплату" + elif get_way == "Number": + send_requests = f"https://qiwi.com/payment/form/99?extra%5B%27account%27%5D={self.login}&amountInteger=" \ + f"{get_amount}&amountFraction=0&extra%5B%27comment%27%5D={receipt}¤cy=" \ + f"643&blocked%5B0%5D=sum&blocked%5B1%5D=comment&blocked%5B2%5D=account" + + return_message = f"🆙 Пополнение баланса\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🥝 Для пополнения баланса, нажмите на кнопку ниже \n" \ + f"Перейти к оплате и оплатите выставленный вам счёт\n" \ + f"📞 QIWI кошелёк: {self.login}\n" \ + f"🏷 Комментарий: {receipt}\n" \ + f"💰 Сумма пополнения: {get_amount}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔄 После оплаты, нажмите на Проверить оплату" + elif get_way == "Nickname": + send_requests = f"https://qiwi.com/payment/form/99999?amountInteger={get_amount}&amountFraction=0¤cy=643" \ + f"&extra%5B%27comment%27%5D={receipt}&extra%5B%27account%27%5D={self.nickname}&blocked%5B0%5D=" \ + f"comment&blocked%5B1%5D=account&blocked%5B2%5D=sum&0%5Bextra%5B%27accountType%27%5D%5D=nickname" + + return_message = f"🆙 Пополнение баланса\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🥝 Для пополнения баланса, нажмите на кнопку ниже \n" \ + f"Перейти к оплате и оплатите выставленный вам счёт\n" \ + f"❗ Не забудьте указать КОММЕНТАРИЙ к платежу\n" \ + f"Ⓜ QIWI Никнейм: {self.nickname}\n" \ + f"🏷 Комментарий: {receipt}\n" \ + f"💰 Сумма пополнения: {get_amount}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔄 После оплаты, нажмите на Проверить оплату" + + return return_message, send_requests, receipt + return False, False, False + + # Проверка платежа по форме + async def check_form(self, receipt): + qiwi_p2p = QiwiP2P(self.secret) + get_pay = qiwi_p2p.check(bill_id=receipt) + + pay_status = get_pay.status # Получение статуса платежа + pay_amount = int(float(get_pay.amount)) # Получение суммы платежа в рублях + + return pay_status, pay_amount + + # Проверка платежа по переводу + async def check_send(self, receipt): + response = await self.pre_checker() + if response: + status, response, code = await self._request( + "payment-history", + "v2", + "payments", + {"rows": 30, "operation": "IN"}, + ) + + pay_status = False + pay_amount = 0 + + for check_pay in response['data']: + if str(receipt) == str(check_pay['comment']): + if "643" == str(check_pay['sum']['currency']): + pay_status = True + pay_amount = int(float(check_pay['sum']['amount'])) + else: + return_message = 1 + break + + if pay_status: + return_message = 3 + else: + return_message = 2 + + return return_message, pay_amount + + return 4, False + + # Запросы + async def _request(self, action, version, get_way, params=None): + url = self.base_url.format(action, version, self.login, get_way) + + rSession: RequestsSession = self.dp.bot['rSession'] + session = await rSession.get_session() + + try: + response = await session.get(url, params=params, headers=self.headers, ssl=False) + return True, json.loads((await response.read()).decode()), response.status + except ClientConnectorCertificateError: + return False, None, "CERTIFICATE_VERIFY_FAILED" + except: + return False, None, response.status diff --git a/TelegramGoodsinbot/tgbot/services/api_qiwi.py b/TelegramGoodsinbot/tgbot/services/api_qiwi.py new file mode 100644 index 0000000..71ae839 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/api_qiwi.py @@ -0,0 +1,325 @@ +# - *- coding: utf- 8 - *- +import asyncio +import json +import time + +from aiohttp import ClientConnectorCertificateError +from async_class import AsyncClass +from pyqiwip2p import QiwiP2P + +from tgbot.services.api_session import RequestsSession +from tgbot.services.api_sqlite import update_paymentx, get_upaymentx, get_paymentx +from tgbot.utils.misc_functions import send_admins + + +# Апи работы с QIWI +class QiwiAPI(AsyncClass): + async def __ainit__(self, dp, login=None, token=None, secret=None, add_pass=False, + check_pass=False, user_bill_pass=False, user_check_pass=False): + #self.user_id = user_id + if login is not None: + self.login = login + self.token = token + self.secret = secret + else: + #self.login = get_upaymentx(self.user_id)['qiwi_login'] + #self.token = get_upaymentx(self.user_id)['qiwi_token'] + #self.secret = get_upaymentx(self.user_id)['qiwi_secret'] + self.login = get_paymentx()['qiwi_login'] + self.token = get_paymentx()['qiwi_token'] + self.secret = get_paymentx()['qiwi_secret'] + + self.base_url = "https://edge.qiwi.com/{}/{}/persons/{}/{}" + self.headers = {"authorization": f"Bearer {self.token}"} + self.nickname = get_paymentx()['qiwi_nickname'] + self.user_check_pass = user_check_pass + self.user_bill_pass = user_bill_pass + self.check_pass = check_pass + self.add_pass = add_pass + self.dp = dp + + + # Рассылка админам о нерабочем киви + @staticmethod + async def error_wallet(): + await send_admins("🥝 Qiwi кошелёк недоступен ❌\n" + "❗ Как можно быстрее его замените ❗") + + # Обязательная проверка перед каждым запросом + async def pre_checker(self): + if self.login != "None": + if self.add_pass: + status, response = await self.check_account() + else: + status, response, code = await self.check_logpass() + await asyncio.sleep(0.5) + + if self.add_pass: + await self.dp.edit_text(response) + if status: + update_paymentx(qiwi_login=self.login, qiwi_token=self.token, qiwi_secret=self.secret) + else: + return False + elif self.check_pass: + if status: + if self.secret == "None": + text_secret = "Отсутствует" + else: + text_secret = self.secret + + await self.dp.answer(f"🥝 Qiwi кошелёк полностью функционирует ✅\n" + f"◾ Номер: {self.login}\n" + f"◾ Токен: {self.token}\n" + f"◾ Приватный ключ: {text_secret}") + else: + await self.error_wallet() + return False + elif self.user_bill_pass: + if not status: + await self.dp.edit_text( + "❗ Извиняемся за доставленные неудобства, пополнение временно недоступно.\n" + "⌛ Попробуйте чуть позже.") + await self.error_wallet() + return False + elif self.user_check_pass: + if not status: + await self.dp.answer( + "❗ Извиняемся за доставленные неудобства, проверка временно недоступна.\n" + "⌛ Попробуйте чуть позже.", True) + await self.error_wallet() + return False + elif not status: + if not self.add_pass: + await self.error_wallet() + return False + + return True + else: + if self.user_bill_pass: + await self.dp.edit_text( + "❗ Извиняемся за доставленные неудобства, пополнение временно недоступно.\n" + "⌛ Попробуйте чуть позже.") + await self.error_wallet() + return False + + # Проверка баланса + async def get_balance(self): + response = await self.pre_checker() + if response: + status, response, code = await self._request( + "funding-sources", + "v2", + "accounts", + ) + + save_balance = [] + for balance in response['accounts']: + if "qw_wallet_usd" == balance['alias']: + save_balance.append(f"🇺🇸 Долларов: {balance['balance']['amount']}$") + + if "qw_wallet_rub" == balance['alias']: + save_balance.append(f"🇷🇺 Рублей: {balance['balance']['amount']}₽") + + if "qw_wallet_eur" == balance['alias']: + save_balance.append(f"🇪🇺 Евро: {balance['balance']['amount']}€") + + if "qw_wallet_kzt" == balance['alias']: + save_balance.append(f"🇰🇿 Тенге: {balance['balance']['amount']}₸") + + save_balance = "\n".join(save_balance) + await self.dp.answer(f"🥝 Баланс кошелька {self.login} составляет:\n" + f"{save_balance}") + + # Получение никнейма аккаунта + async def get_nickname(self): + response = await self.pre_checker() + if response: + status, response, code = await self._request( + "qw-nicknames", + "v1", + "nickname", + ) + + if response['nickname'] is None: + return False, "❗ На аккаунте отсутствует QIWI Никнейм. Установите его в настройках своего кошелька." + else: + return True, response['nickname'] + + return False, "" + + # Проверка аккаунта (логпаса и п2п) + async def check_account(self): + status_history, response_history, code_history = await self.check_logpass() + status_balance, response_balance, code_balance = await self._request( + "funding-sources", + "v2", + "accounts" + ) + + if status_history and status_balance: + if self.secret != "None": + status_secret = await self.check_secret() + if status_secret: + return True, "🥝 QIWI кошелёк был успешно изменён ✅" + else: + return_message = "🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + "▶ Код ошибки: Неверный приватный ключ\n" \ + "❕ Указывайте ПРИВАТНЫЙ КЛЮЧ, а не публичный. " \ + "Приватный ключ заканчивается на =" + else: + return True, "🥝 QIWI кошелёк был успешно изменён ✅" + else: + if 400 in [code_history, code_balance]: + return_message = f"🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Код ошибки: Номер телефона указан в неверном формате" + elif 401 in [code_history, code_balance]: + return_message = f"🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Код ошибки: Неверный токен или истек срок действия токена API" + elif 403 in [code_history, code_balance]: + return_message = f"🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Ошибка: Нет прав на данный запрос (недостаточно разрешений у токена API)" + elif "CERTIFICATE_VERIFY_FAILED" == code_history: + return_message = "🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Код ошибки: CERTIFICATE_VERIFY_FAILED certificate verify failed: self signed certificate in certificate chain\n" \ + f"❗ Ваш сервер/дедик/устройство блокирует запросы к QIWI. Отключите антивирус или другие блокирующие ПО." + else: + return_message = "🥝 Введённые QIWI данные не прошли проверку ❌\n" \ + f"▶ Код ошибки: {code_history}/{code_balance}" + + return False, return_message + + # Проверка логпаса киви + async def check_logpass(self): + status, response, code = await self._request( + "payment-history", + "v2", + "payments", + {"rows": 1, "operation": "IN"}, + ) + + if status: + if "data" in response: + return True, response, code + else: + return False, None, code + else: + return False, None, code + + # Проверка п2п ключа + async def check_secret(self): + try: + qiwi_p2p = QiwiP2P(self.secret) + bill = qiwi_p2p.bill(amount=1, lifetime=1) + qiwi_p2p.reject(bill_id=bill.bill_id) + return True + except: + return False + + # Создание платежа + async def bill_pay(self, get_amount, get_way): + response = await self.pre_checker() + if response: + receipt = str(int(time.time() * 100)) + + if get_way == "Form": + qiwi = QiwiP2P(self.secret) + bill = qiwi.bill(bill_id=receipt, amount=get_amount, comment=receipt) + send_requests = bill.pay_url + + return_message = f"🆙 Пополнение баланса\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🥝 Для пополнения баланса, нажмите на кнопку ниже \n" \ + f"Перейти к оплате и оплатите выставленный вам счёт\n" \ + f"❗ У вас имеется 30 минут на оплату счета.\n" \ + f"💰 Сумма пополнения: {get_amount}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔄 После оплаты, нажмите на Проверить оплату" + elif get_way == "Number": + send_requests = f"https://qiwi.com/payment/form/99?extra%5B%27account%27%5D={self.login}&amountInteger=" \ + f"{get_amount}&amountFraction=0&extra%5B%27comment%27%5D={receipt}¤cy=" \ + f"643&blocked%5B0%5D=sum&blocked%5B1%5D=comment&blocked%5B2%5D=account" + + return_message = f"🆙 Пополнение баланса\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🥝 Для пополнения баланса, нажмите на кнопку ниже \n" \ + f"Перейти к оплате и оплатите выставленный вам счёт\n" \ + f"📞 QIWI кошелёк: {self.login}\n" \ + f"🏷 Комментарий: {receipt}\n" \ + f"💰 Сумма пополнения: {get_amount}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔄 После оплаты, нажмите на Проверить оплату" + elif get_way == "Nickname": + send_requests = f"https://qiwi.com/payment/form/99999?amountInteger={get_amount}&amountFraction=0¤cy=643" \ + f"&extra%5B%27comment%27%5D={receipt}&extra%5B%27account%27%5D={self.nickname}&blocked%5B0%5D=" \ + f"comment&blocked%5B1%5D=account&blocked%5B2%5D=sum&0%5Bextra%5B%27accountType%27%5D%5D=nickname" + + return_message = f"🆙 Пополнение баланса\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🥝 Для пополнения баланса, нажмите на кнопку ниже \n" \ + f"Перейти к оплате и оплатите выставленный вам счёт\n" \ + f"❗ Не забудьте указать КОММЕНТАРИЙ к платежу\n" \ + f"Ⓜ QIWI Никнейм: {self.nickname}\n" \ + f"🏷 Комментарий: {receipt}\n" \ + f"💰 Сумма пополнения: {get_amount}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔄 После оплаты, нажмите на Проверить оплату" + + return return_message, send_requests, receipt + return False, False, False + + # Проверка платежа по форме + async def check_form(self, receipt): + qiwi_p2p = QiwiP2P(self.secret) + get_pay = qiwi_p2p.check(bill_id=receipt) + + pay_status = get_pay.status # Получение статуса платежа + pay_amount = int(float(get_pay.amount)) # Получение суммы платежа в рублях + + return pay_status, pay_amount + + # Проверка платежа по переводу + async def check_send(self, receipt): + response = await self.pre_checker() + if response: + status, response, code = await self._request( + "payment-history", + "v2", + "payments", + {"rows": 30, "operation": "IN"}, + ) + + pay_status = False + pay_amount = 0 + + for check_pay in response['data']: + if str(receipt) == str(check_pay['comment']): + if "643" == str(check_pay['sum']['currency']): + pay_status = True + pay_amount = int(float(check_pay['sum']['amount'])) + else: + return_message = 1 + break + + if pay_status: + return_message = 3 + else: + return_message = 2 + + return return_message, pay_amount + + return 4, False + + # Запросы + async def _request(self, action, version, get_way, params=None): + url = self.base_url.format(action, version, self.login, get_way) + + rSession: RequestsSession = self.dp.bot['rSession'] + session = await rSession.get_session() + + try: + response = await session.get(url, params=params, headers=self.headers, ssl=False) + return True, json.loads((await response.read()).decode()), response.status + except ClientConnectorCertificateError: + return False, None, "CERTIFICATE_VERIFY_FAILED" + except: + return False, None, response.status diff --git a/TelegramGoodsinbot/tgbot/services/api_session.py b/TelegramGoodsinbot/tgbot/services/api_session.py new file mode 100644 index 0000000..f31e19c --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/api_session.py @@ -0,0 +1,45 @@ +# - *- coding: utf- 8 - *- +from typing import Optional + +import aiohttp + + +# Асинхронная сессия для запросов +class AsyncSession: + def __init__(self) -> None: + self._session: Optional[aiohttp.ClientSession] = None + + # Вызов сессии + async def get_session(self) -> aiohttp.ClientSession: + if self._session is None: + new_session = aiohttp.ClientSession() + self._session = new_session + + return self._session + + # Закрытие сессии + async def close(self) -> None: + if self._session is None: + return None + + await self._session.close() + +# Асинхронная сессия для запросов +class RequestsSession: + def __init__(self) -> None: + self._session: Optional[aiohttp.ClientSession] = None + + # Вызов сессии + async def get_session(self) -> aiohttp.ClientSession: + if self._session is None: + new_session = aiohttp.ClientSession() + self._session = new_session + + return self._session + + # Закрытие сессии + async def close(self) -> None: + if self._session is None: + return None + + await self._session.close() \ No newline at end of file diff --git a/TelegramGoodsinbot/tgbot/services/api_sqlite.py b/TelegramGoodsinbot/tgbot/services/api_sqlite.py new file mode 100644 index 0000000..99eec12 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/api_sqlite.py @@ -0,0 +1,1376 @@ +# - *- coding: utf- 8 - *- +import math +import random +import sqlite3 +import json +import datetime + +from tgbot.data.config import PATH_DATABASE +from tgbot.utils.const_functions import get_unix, get_date, clear_html + + +# Преобразование полученного списка в словарь +def dict_factory(cursor, row): + save_dict = {} + + for idx, col in enumerate(cursor.description): + save_dict[col[0]] = row[idx] + + return save_dict + +#################################################################################################### +##################################### ФОРМАТИРОВАНИЕ ЗАПРОСА ####################################### +# Форматирование запроса без аргументов +def update_format(sql, parameters: dict): + if "XXX" not in sql: sql += " XXX " + + values = ", ".join([ + f"{item} = ?" for item in parameters + ]) + sql = sql.replace("XXX", values) + + return sql, list(parameters.values()) + + +# Форматирование запроса с аргументами +def update_format_args(sql, parameters: dict): + sql = f"{sql} WHERE " + + sql += " AND ".join([ + f"{item} = ?" for item in parameters + ]) + + return sql, list(parameters.values()) + + +########################################### ЗАПРОСЫ НА ПРОДАВЦА ######################## +######################################################################################## +def create_seller_request(user_id, requesttxt): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_requests " + "(requester, datetime, state, requesttxt) " + "VALUES (?, ?, ?, ?)", + [user_id, get_unix(), 'created', requesttxt]) + con.commit() + +# Получение всех запросов продавцов +def get_all_randtgaccounts(): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = "SELECT * FROM storage_tgaccounts" + return con.execute(sql).fetchall() + +#Проыерка на дубли username +def check_dbfor_invited_username(username): + print(f'Проверка на существование записи username api_sqlite.py 67') + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = f"SELECT count(*) FROM storage_tgparse " + #sql, parameters = update_format_args(sql, kwargs) + #return con.execute(sql, parameters).fetchone() + #sql, parameters = update_format(sql, kwargs) + #parameters.append(user_id) + dbrow = [] + #count = 0 + dbrow = con.execute(sql + "WHERE state='invited' AND username = ?", [username]).fetchone()[0] + #print(len(dbrow)) + print(dbrow) + #count = len(dbrow) + #print(str(dbrow['username'])) + #dbrow=dbrow.strip("(") + #dbrow=dbrow.strip(")") + #dbrow=dbrow.strip(",") + #con.commit() + print(f'Проверяем {username} в БД') + if(dbrow>=1): + return True + else: + return False + +# Удаление корзины +def remove_ordersx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_orders" + sql, parameters = update_format_args(sql, kwargs) + con.execute(sql, parameters) + con.commit() + +# Удаление позиций корзины +def remove_orders_itemx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_orders_items" + sql, parameters = update_format_args(sql, kwargs) + con.execute(sql, parameters) + con.commit() + +#Проыерка на дубли username +def check_dbfor_username(username): + print(f'Проверка на существование записи username api_sqlite.py 67') + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = f"SELECT count(*) FROM storage_tgparse " + #sql, parameters = update_format_args(sql, kwargs) + #return con.execute(sql, parameters).fetchone() + #sql, parameters = update_format(sql, kwargs) + #parameters.append(user_id) + dbrow = [] + #count = 0 + dbrow = con.execute(sql + "WHERE username = ?", [username]).fetchone()[0] + #print(len(dbrow)) + print(dbrow) + #count = len(dbrow) + #print(str(dbrow['username'])) + #dbrow=dbrow.strip("(") + #dbrow=dbrow.strip(")") + #dbrow=dbrow.strip(",") + #con.commit() + print(f'Проверяем {username} в БД') + if(dbrow>=1): + return True + else: + return False + +# Удаление аккаунта ТГ +def remove_accountx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_tgaccounts" + sql, parameters = update_format_args(sql, kwargs) + con.execute(sql, parameters) + con.commit() + +#Пользователи по статусам +def get_all_tgaccounts_states(): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = "SELECT source, groupname, state, count(username) FROM storage_tgparse GROUP BY source, groupname, state" + return con.execute(sql).fetchall() + + +# Получение всех запросов продавцов +def get_all_avtgaccounts(): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = "SELECT * FROM storage_tgaccounts WHERE state='available'" + return con.execute(sql).fetchall() + +# Получение номеров по статусам +def get_all_tgaccounts_time(): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = "SELECT * FROM storage_tgaccounts ORDER BY date(waitfor24) ASC" + return con.execute(sql).fetchall() + +# Получение номеров по статусам +def get_all_tgaccounts(): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = "SELECT * FROM storage_tgaccounts" + return con.execute(sql).fetchall() + +# Получение всех запросов продавцов +def get_tgaccount_statecounts(account_id): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + #sql = "SELECT state, invited24, last FROM storage_tgaccounts " + sql = "SELECT invited24 FROM storage_tgaccounts " + return con.execute(sql + "WHERE account_id = ?", [account_id]).fetchone() + +# Добавление аккаунта ТГ в БД +def add_tgacc_todb(username, user_id, access_hash, name, source, groupname, group_id, tag, state='created'): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_tgparse " + "(username, user_id, access_hash, name, source, groupname, group_id, tag, state) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", + [username, user_id, access_hash, name, source, groupname, group_id, tag, state]) + print("addok") + con.commit() + +#есть ли магазин у пользователя +def check_user_shop_exist(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT admin FROM storage_shop " + shopadmin = con.execute(sql + "WHERE admin = ?", [user_id]).fetchone() + + return shopadmin['admin'] + +# Добавление аккаунта ТГ в БД +def add_account_todb(xid, xhash, xphone, invited24, state='created'): + with sqlite3.connect(PATH_DATABASE) as con: + datenow = datetime.datetime.now() + con.row_factory = dict_factory + con.execute("INSERT INTO storage_tgaccounts " + "(tg_api_id, tg_api_hash, phone, invited24, date, state) " + "VALUES (?, ?, ?, ?, ?, ?)", + [xid, xhash, xphone, invited24, datenow, state]) + con.commit() + #print(con.lastrowid) + +# Получение всех запросов продавцов +def get_lasttgaccount(): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + #sql = "SELECT state, invited24, last FROM storage_tgaccounts " + sql = "SELECT MAX(account_id) as acc FROM storage_tgaccounts GROUP BY account_id" + return con.execute(sql).fetchone()[0] + +# Группы в ТГ +def groups_telegram(): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = f"SELECT distinct group_id, groupname FROM storage_tgparse WHERE groupname != '' AND source = 'groups' ORDER BY group_id ASC" # LIMIT {start},{count} + return con.execute(sql).fetchall() + +# Пользователи группы для инвайта +def first_grouptoinvite(groupname, start, count): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = f"SELECT * FROM storage_tgparse WHERE state = 'created' AND source = 'groups' AND groupname=? ORDER BY acc_id ASC LIMIT {start},{count}" + return con.execute(sql, [groupname]).fetchall() + +# Последние 10 покупок +def first_toinvite(state, start, count): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = f"SELECT * FROM storage_tgparse WHERE state = ? AND source = 'groups' ORDER BY acc_id ASC LIMIT {start},{count}" + return con.execute(sql, [state]).fetchall() + +def firstgeo_toinvite(state, start, count): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = f"SELECT * FROM storage_tgparse WHERE state = ? AND source = 'geoparse' ORDER BY acc_id ASC LIMIT {start},{count}" + return con.execute(sql, [state]).fetchall() + #return con.execute(sql).fetchall() + +# Редактирование запроса +def update_tgparsex(acc_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_tgparse SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(acc_id) + con.execute(sql + "WHERE acc_id = ?", parameters) + con.commit() + +# Редактирование запроса +def update_tgaccounts(account_id, pole): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + inc = "" + if pole == 'invited24': inc = " invited24 = invited24 + 1, last = datetime('now') " + if pole == 'waitfor24': inc = " state = 'wait', waitfor24 = datetime('now', '+1 day') " + if pole == 'banned': inc = " state = 'banned' " + if pole == 'available': inc = " state = 'available', invited24 = 0 " + sql = f"UPDATE storage_tgaccounts SET " + inc + #sql, parameters = update_format(sql, kwargs) + #parameters.append(account_id) + con.execute(sql + "WHERE account_id = ?", [account_id]) + con.commit() + +#удаление аккаунта +def delete_tgacc(acc_id): + print(f"Удаляем аккаунт{acc_id}") + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_tgaccounts " + #sql, parameters = update_format_args(sql, kwargs) + #sql, user_id = update_format(sql, user_id) + con.execute(sql + "WHERE account_id = ?", [acc_id]) + con.commit() + +# Получение всех запросов продавцов +def get_all_requestx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT DISTINCT requester as user_id FROM storage_requests ORDER BY datetime ASC" + return con.execute(sql).fetchall() + +# Удаление запроса +def delete_requests_userx(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_requests " + #sql, parameters = update_format_args(sql, kwargs) + #sql, user_id = update_format(sql, user_id) + con.execute(sql + "WHERE requester = ?", [user_id]) + con.commit() + +# Редактирование запроса +def update_requestx(user_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_requests SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(user_id) + con.execute(sql + "WHERE user_id = ?", parameters) + con.commit() + + +# Проверка принадлежности позиции в каталоге +def check_position_owner(user_id, position_id): + print(f'Проверка принадлежности позиции api_sqlite.py 86') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT position_user_id FROM storage_position " + #sql, parameters = update_format_args(sql, kwargs) + #return con.execute(sql, parameters).fetchone() + + #sql, parameters = update_format(sql, kwargs) + #parameters.append(user_id) + dbuser_id = con.execute(sql + "WHERE position_id = ?", [position_id]).fetchone() + #con.commit() + print(f'Лот пользователя {dbuser_id} проверяем для {user_id} 97') + if(user_id==dbuser_id['position_user_id'] or user_id==919148970): #['position_user_id'] + return True + else: + return False + +#create_seller_request('919148970') +#################################################################################################### +########################################### ЗАПРОСЫ К БД ########################################### + +# Добавление пользователя +def add_userx(user_id, user_login, user_name): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_users " + "(user_id, user_login, user_name, user_balance, user_refill, user_date, user_unix) " + "VALUES (?, ?, ?, ?, ?, ?, ?)", + [user_id, user_login, user_name, 0, 0, get_date(), get_unix()]) + con.commit() + +# Получение пользователя +def get_userx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_users" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchone() + +# Получение админов магазинов +def get_shopadmins(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_users WHERE user_role='ShopAdmin" + return con.execute(sql).fetchall() + +# Получение пользователей +def get_usersx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_users" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + + +# Получение всех пользователей +def get_all_usersx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_users" + return con.execute(sql).fetchall() + +# Получение всех пользователей +def get_top_sellersx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_users WHERE user_role='ShopAdmin' AND user_balance >0 ORDER BY user_balance DESC LIMIT 0,15" + return con.execute(sql).fetchall() + + + +# Редактирование пользователя +def update_userx(user_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_users SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(user_id) + con.execute(sql + "WHERE user_id = ?", parameters) + con.commit() + +# Редактирование пользователя +def update_holdx(order_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_money_holds SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(order_id) + con.execute(sql + "WHERE order_id = ?", parameters) + con.commit() + +# Удаление пользователя +def delete_userx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_users" + sql, parameters = update_format_args(sql, kwargs) + con.execute(sql, parameters) + con.commit() + +# Получение платежных реквизитов продавца +def get_upaymentx(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + #print("|||uyo|||") + return con.execute("SELECT * FROM storage_payment WHERE user_id = ?", [user_id]).fetchone() + +def get_upaycount(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + return con.execute("SELECT COUNT(*) as paycount FROM storage_payment WHERE user_id = ?", [user_id]).fetchone() + + +def create_upayments_row(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_payment " + "(qiwi_login, qiwi_token, qiwi_secret, qiwi_nickname, way_form, way_number, way_nickname, user_id, yoo_token, yoo_client_id, yoo_redirect_url, yoo_acc_number, way_formy)" + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + ['', '', '', '', 'False', 'False', 'False', user_id, '', 0, '', 0, 'False']) + con.commit() + +# Получение платежных систем +def get_paymentx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_payment WHERE user_id=919148970" + return con.execute(sql).fetchone() + + +# Редактирование платежных систем +def update_paymentx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "UPDATE storage_payment SET" + sql, parameters = update_format(sql, kwargs) + con.execute(sql, parameters) + con.commit() + +# Редактирование платежных систем +def update_upaymentx(user_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "UPDATE storage_payment SET " + sql, parameters = update_format(sql, kwargs) + parameters.append(user_id) + con.execute(sql + " WHERE user_id = ?", parameters) + con.commit() + +# Получение настроек +def get_settingsx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_settings" + return con.execute(sql).fetchone() + + +# Редактирование настроек +def update_settingsx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "UPDATE storage_settings SET" + sql, parameters = update_format(sql, kwargs) + con.execute(sql, parameters) + con.commit() + + +# Добавление пополнения +def add_refillx(user_id, user_login, user_name, refill_comment, refill_amount, refill_receipt, + refill_way, refill_date, refill_unix): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_refill " + "(user_id, user_login, user_name, refill_comment, refill_amount, refill_receipt, refill_way, refill_date, refill_unix) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", + [user_id, user_login, user_name, refill_comment, refill_amount, refill_receipt, refill_way, + refill_date, refill_unix]) + con.commit() + + +# Получение пополнения +def get_refillx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_refill" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchone() + + +# Получение пополнений +def get_refillsx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_refill" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + + +# Получение всех пополнений +def get_all_refillx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_refill" + return con.execute(sql).fetchall() + + +# Добавление категории +def add_categoryx(category_name): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_category (category_id, category_name) VALUES (?, ?)", + [random.randint(1000000000, 9999999999), category_name]) + con.commit() + + +# Изменение категории +def update_categoryx(category_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_category SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(category_id) + con.execute(sql + "WHERE category_id = ?", parameters) + con.commit() + + +# Получение категории +def get_categoryx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_category" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchone() + + +# Получение категорий +def get_categoriesx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_category" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + + +# Получение всех категорий +def get_all_shopx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_shop" + return con.execute(sql).fetchall() + +# Получение платежных реквизитов продавца +def get_my_shopx(admin): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_shop " + #sql, parameters = update_format(sql, kwargs) + return con.execute(sql, "WHERE admin = ?", [admin]).fetchone() + +# Получение всех категорий +def get_all_categoriesx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_category" + return con.execute(sql).fetchall() + + +# Удаление всех категорий +def clear_categoryx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_category" + con.execute(sql) + con.commit() + + +# Удаление категории +def remove_categoryx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_category" + sql, parameters = update_format_args(sql, kwargs) + con.execute(sql, parameters) + con.commit() + + +# Добавление категории ? позиции +def add_positionx(position_city, position_city_id, position_name, position_price, position_description, position_photo, category_id, position_user_id): + print(f'Добавление позиции api_sqlite_shop.py 294') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_position " + "(position_id, position_name, position_price, position_description, position_photo, position_date, category_id, position_city, position_city_id, position_user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + [random.randint(1000000000, 9999999999), position_name, position_price, position_description, + position_photo, get_date(), category_id, position_city, position_city_id, position_user_id]) + con.commit() + + +# Изменение позиции +def update_positionx(position_id, **kwargs): + print('Изменение позиции api_sqlite.py 306') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_position SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(position_id) + con.execute(sql + "WHERE position_id = ?", parameters) + con.commit() + +# Получение магазина +def get_shopx(**kwargs): + print(f'Получение магазина api_sqlite.py 318') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_shop" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchone() + +# Получение позиции +def get_positionx(**kwargs): + print(f'Получение позиции api_sqlite.py 318') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_position" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchone() + +# Получение сообщений для пользователя +def get_user_messagesx(**kwargs): + print(f'Получение сообющений для пользователя api_sqlite.py 367') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_messages" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + +# Обмновление статуса сообщения +def update_orderx(order_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_messages SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(order_id) + con.execute(sql + "WHERE order_id = ?", parameters) + con.commit() + +# Изменение корзины +def update_orderx(order_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_orders SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(order_id) + con.execute(sql + "WHERE order_id = ?", parameters) + con.commit() + +# Изменение холда +def update_holdsx(order_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_money_holds SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(order_id) + con.execute(sql + "WHERE order_id = ?", parameters) + con.commit() + +# Получение продавцов корзины +def get_cart_sellersx(order_id): + print(f'Получение продавцов корзины api_sqlite.py 777') + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sellers = con.execute(f"SELECT DISTINCT owner_uid FROM storage_orders_items WHERE order_id = ?", [order_id]).fetchall() + print(len(sellers)) + slss='' + slsss = ''.join(str(slss) for slss in sellers) + print(slsss) + slsss1 = slsss.replace('(', '') + slsss2 = slsss1.replace(')', '') + touser_id = slsss2.replace(',', '') + return touser_id + + +# Получение позиций корзины +def get_cart_positionsx(order_id): + print(f'Получение позиций корзины api_sqlite.py 568') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + positions = con.execute(f"SELECT * FROM storage_orders_items LEFT JOIN storage_position USING(position_id) WHERE order_id = ?", [order_id]).fetchall() + return positions + +# Получение позиций корзины +def get_order_sellers(order_id): + print(f'Получение позиций корзины api_sqlite.py 568') + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + positions = con.execute(f"SELECT DISTINCT owner_uid as owner_id FROM storage_orders_items WHERE order_id = ?", [order_id]).fetchall() + return json.dumps(positions) + #return positions + + +# Получение данных холдов заказа +def get_orders_holdsx(order_id): + print(f'Получение холдов заказа {order_id} 626') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + holds = con.execute(f"SELECT * FROM storage_money_holds WHERE order_id = ?", [order_id]).fetchall() + #return json.dumps(holds) + return holds + +# Получение позиций +def get_positionsx(**kwargs): + print(f'Получение позиции (дубль) api_sqlite.py 328') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_position" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + +# Получение всех категорий +def get_all_positionsidx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT position_id FROM storage_position" + return con.execute(sql).fetchall() + +# Получение всех категорий +def get_all_positionsx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_position" + return con.execute(sql).fetchall() + + +# Удаление всех позиций +def clear_positionx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_position" + con.execute(sql) + con.commit() + + +# Удаление позиции +def remove_positionx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_position" + sql, parameters = update_format_args(sql, kwargs) + con.execute(sql, parameters) + con.commit() + + +# Добавление товара +def add_itemx(category_id, position_id, get_all_items, user_id, user_name): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + + for item_data in get_all_items: + if not item_data.isspace() and item_data != "": + con.execute("INSERT INTO storage_item " + "(item_id, item_data, position_id, category_id, creator_id, creator_name, add_date) " + "VALUES (?, ?, ?, ?, ?, ?, ?)", + [random.randint(1000000000, 9999999999), clear_html(item_data.strip()), position_id, category_id, + user_id, user_name, get_date()]) + con.commit() + + +# Изменение товара +def update_itemx(item_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_item SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(item_id) + con.execute(sql + "WHERE item_id = ?", parameters) + con.commit() + +# Получение продавца заказа +def get_ordersellerx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_item" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchone() + + +# Получение товара +def get_itemx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_item" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchone() + + +# Получение товаров +def get_itemsx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_item" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + +# Получение всех товаров +def get_all_itemsx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_item" + return con.execute(sql).fetchall() + +# Получение всех моих позиций +def get_all_my_positionsx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_position" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql + "WHERE position_user_id = ?", [user_id]).fetchall() + +# Получение всех моих позиций +def get_all_my_positionsnx(position_user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_position" + #sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql + " WHERE position_user_id = ?", [position_user_id]).fetchall() + +# Получение всех моих товаров +def get_all_my_itemsnx(creator_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_item" + #sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql + " WHERE creator_id = ?", [creator_id]).fetchall() + +# Получение всех моих товаров +def get_all_my_itemsx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_item" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql + "WHERE creator_id = ?", [user_id]).fetchall() + + +# Очистка товаров +def clear_itemx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_item" + con.execute(sql) + con.commit() + + +# Удаление товаров +def remove_itemx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "DELETE FROM storage_item" + sql, parameters = update_format_args(sql, kwargs) + con.execute(sql, parameters) + con.commit() + + +# Покупка товаров +def buy_itemx(get_items, get_count): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + split_len, send_count, save_items = 0, 0, [] + + for select_send_item in get_items: + if send_count != get_count: + send_count += 1 + if get_count >= 2: + select_data = f"{send_count}. {select_send_item['item_data']}" + else: + select_data = select_send_item['item_data'] + + save_items.append(select_data) + sql, parameters = update_format_args("DELETE FROM storage_item", + {"item_id": select_send_item['item_id']}) + con.execute(sql, parameters) + + if len(select_data) >= split_len: split_len = len(select_data) + else: + break + con.commit() + + split_len += 1 + get_len = math.ceil(3500 / split_len) + + return save_items, send_count, get_len + +# Проверка существования заказа +def get_orderx(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + orders = con.execute(f"SELECT * FROM storage_orders WHERE user_id = ?", [user_id]).fetchone() + return orders + +# Последние 10 покупок +def get_params_orderx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_orders" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + +# Проверка существования заказа +def get_userc_orderx(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + #con.row_factory = dict_factory + sql = "SELECT order_state FROM storage_orders WHERE order_state='created' AND user_id = ?" + order = con.execute(sql, [user_id]).fetchone() + order=json.dumps(order) + print(order) + return order + +# Проверка существования заказа +def get_user_orderx(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + order = con.execute(f"SELECT * FROM storage_orders WHERE user_id = ?", [user_id]).fetchone() + return order + + +# Создание заказа +def create_orderx(user_id, user_login, user_name, order_state, order_date, order_unix): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_orders " + "(user_id, user_login, user_name, order_state, order_date, order_unix) " + "VALUES (?, ?, ?, ?, ?, ?)", + [user_id, user_login, user_name, order_state, order_date, order_unix]) + con.commit() + +# Создание холда +def create_holdx(order_id, buyer, seller, amount, validity, state): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_money_holds " + "(order_id, buyer, seller, amount, validity, state) " + "VALUES (?, ?, ?, ?, ?, ?)", + [order_id, buyer, seller, amount, validity, state]) + con.commit() + +# Добавление товара в заказ +def add_order_itemx(order_id, position_id, count, price, receipt, owner_uid): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_orders_items " + "(order_id, position_id, count, price, receipt, owner_uid) " + "VALUES (?, ?, ?, ?, ?, ?)", + [order_id, position_id, count, price, receipt, owner_uid]) + con.commit() + + +# Добавление сообщения +def add_messagex(from_id, to_id, order_id, txtmessage, photo, state): + print(f'Добавление позиции api_sqlite_shop.py 294') + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_messages " + "(message_id, from_uid, to_uid, order_id, message, photo, state) VALUES (?, ?, ?, ?, ?, ?, ?)", + [random.randint(1000000000, 9999999999), from_id, to_id, order_id, txtmessage, photo, state]) + con.commit() + +def get_params_messagesx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_messages" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + +# Добавление покупки +def add_purchasex(user_id, user_login, user_name, purchase_receipt, purchase_count, purchase_price, purchase_price_one, + purchase_position_id, purchase_position_name, purchase_item, purchase_date, purchase_unix, + balance_before, balance_after): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_purchases " + "(user_id, user_login, user_name, purchase_receipt, purchase_count, purchase_price, purchase_price_one, purchase_position_id, " + "purchase_position_name, purchase_item, purchase_date, purchase_unix, balance_before, balance_after) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + [user_id, user_login, user_name, purchase_receipt, purchase_count, purchase_price, + purchase_price_one, purchase_position_id, purchase_position_name, purchase_item, purchase_date, + purchase_unix, balance_before, balance_after]) + con.commit() + + + +# Получение покупок +def get_purchasesbysellers(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT DISTINCT c.user_id FROM storage_purchases a LEFT JOIN storage_position b ON(a.purchase_position_id=b.position_id) LEFT JOIN storage_users c ON(c.user_id=b.position_user_id) WHERE c.user_id NOT NULL GROUP BY a.user_id, a.purchase_position_name" + #sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql).fetchall() + + +# Получение покупок +def get_purchasesxx2(user_id): + #with sqlite3.connect(PATH_DATABASE) as con: + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query= f"SELECT c.user_id, a.purchase_position_name, SUM(a.purchase_count) as counts, SUM(a.purchase_price) as price FROM storage_purchases a LEFT JOIN storage_position b ON(a.purchase_position_id=b.position_id) LEFT JOIN storage_users c ON(c.user_id=b.position_user_id) WHERE c.user_id=? GROUP BY a.user_id, a.purchase_position_name" + #result = cur.execute(query, (user_id,)).fetchall() + result = cur.execute(query, [user_id]).fetchall() + cur.close() + return result + +def get_purchasesx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_purchases" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + + # Получение покупок +def get_purchasesxx3(user_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + #cur = conn.cursor() + sql= f"SELECT c.user_id, a.purchase_position_name, SUM(a.purchase_count) as counts, SUM(a.purchase_price) as price FROM storage_purchases a LEFT JOIN storage_position b ON(a.purchase_position_id=b.position_id) LEFT JOIN storage_users c ON(c.user_id=b.position_user_id) WHERE c.user_id=? GROUP BY a.user_id, a.purchase_position_name" + sql, parameters = update_format_args(sql, [user_id]) + return con.execute(sql, parameters).fetchall() + + +def get_purchasesxx(user_id): + print(f'возвращает город пользователя и координаты api_sqlite.py 675') + conn = sqlite3.connect(PATH_DATABASE) + #cur = conn.cursor() + query = '''SELECT c.user_id, a.purchase_position_name, SUM(a.purchase_count) as counts, SUM(a.purchase_price) as price FROM storage_purchases a LEFT JOIN storage_position b ON(a.purchase_position_id=b.position_id) LEFT JOIN storage_users c ON(c.user_id=b.position_user_id) WHERE c.user_id=? GROUP BY a.user_id, a.purchase_position_name''' + result = conn.execute(query, (user_id,)).fetchall() + #cur.close() + return result + +# Получение запросов +def get_requestx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_requests" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() + +# Получение всех покупок +def get_all_purchasesx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_purchases" + return con.execute(sql).fetchall() + +# Получение всех покупок +def getpurchasesbysellersx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = "SELECT * FROM storage_purchases LEFT JOIN storage_position USING(user_id)" + return con.execute(sql).fetchall() + + +# Последние 10 покупок +def last_purchasesx(user_id, count): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_purchases WHERE user_id = ? ORDER BY increment DESC LIMIT {count}" + return con.execute(sql, [user_id]).fetchall() + + +# Создание всех таблиц для БД +def create_dbx(): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + + # Создание БД с хранением данных пользователей + if len(con.execute("PRAGMA table_info(storage_users)").fetchall()) == 12: + print("DB was found(1/12)") + else: + con.execute("CREATE TABLE IF NOT EXISTS storage_users(" + "increment INTEGER PRIMARY KEY AUTOINCREMENT," + "user_id INTEGER," + "user_login TEXT," + "user_name TEXT," + "user_address TEXT," + "user_phone TEXT," + "user_balance INTEGER," + "user_refill INTEGER," + "user_date TIMESTAMP," + "user_unix INTEGER," + "user_city TEXT," + "user_geocode TEXT," + "user_role TEXT," + "user_city_id INTEGER)") # Добавил город + print("DB was not found(1/12) | Creating...") + + # Создание БД с хранением данных платежных систем + if len(con.execute("PRAGMA table_info(storage_payment)").fetchall()) == 13: + print("DB was found(2/12)") + else: + con.execute("CREATE TABLE storage_payment(" + "qiwi_login TEXT," + "qiwi_token TEXT," + "qiwi_secret TEXT," + "qiwi_nickname TEXT," + "way_form TEXT," + "way_number TEXT," + "way_nickname TEXT," + "way_formy TEXT," + "user_id INTEGER," + "yoo_token TEXT," + "yoo_client_id TEXT," + "yoo_redirect_url TEXT," + "yoo_acc_number INTEGER)") + + con.execute("INSERT INTO storage_payment(" + "qiwi_login, qiwi_token, qiwi_secret, qiwi_nickname, way_form, way_number, way_nickname, way_formy, yoo_token, yoo_client_id, yoo_redirect_url, yoo_acc_number) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + ['None', 'None', 'None', 'None', 'False', 'False', 'False', 'False', 'None', 'None', 'None', 'None']) + print("DB was not found(2/12) | Creating...") + + # Создание БД с хранением настроек + if len(con.execute("PRAGMA table_info(storage_settings)").fetchall()) == 10: + print("DB was found(3/12)") + else: + con.execute("CREATE TABLE storage_settings(" + "status_work TEXT," + "status_refill TEXT," + "status_buy TEXT," + "misc_faq TEXT," + "misc_support TEXT," + "misc_bot TEXT," + "misc_update TEXT," + "misc_profit_day INTEGER," + "misc_profit_week INTEGER," + "type_trade TEXT)") + + con.execute("INSERT INTO storage_settings(" + "status_work, status_refill, status_buy, misc_faq, misc_support, misc_bot, misc_update, misc_profit_day, misc_profit_week)" + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", + ["True", "False", "False", "None", "None", "None", "False", get_unix(), get_unix()]) + print("DB was not found(3/12) | Creating...") + + # Создание БД с хранением пополнений пользователей + if len(con.execute("PRAGMA table_info(storage_refill)").fetchall()) == 10: + print("DB was found(4/12)") + else: + con.execute("CREATE TABLE storage_refill(" + "increment INTEGER PRIMARY KEY AUTOINCREMENT," + "user_id INTEGER," + "user_login TEXT," + "user_name TEXT," + "refill_comment TEXT," + "refill_amount INTEGER," + "refill_receipt TEXT," + "refill_way TEXT," + "refill_date TIMESTAMP," + "refill_unix INTEGER)") + print("DB was not found(4/12) | Creating...") + + # Создание БД с хранением категорий + if len(con.execute("PRAGMA table_info(storage_category)").fetchall()) == 3: + print("DB was found(5/8)") + else: + con.execute("CREATE TABLE storage_category(" + "increment INTEGER PRIMARY KEY AUTOINCREMENT," + "category_id INTEGER," + "category_name TEXT)") + print("DB was not found(5/12) | Creating...") + + + + # Создание БД с хранением позиций + if len(con.execute("PRAGMA table_info(storage_position)").fetchall()) == 11: + print("DB was found(6/12)") + else: + con.execute("CREATE TABLE IF NOT EXISTS storage_position(" + "increment INTEGER PRIMARY KEY AUTOINCREMENT," + "position_id INTEGER," + "position_name TEXT," + "position_price INTEGER," + "position_description TEXT," + "position_photo TEXT," + "position_date TIMESTAMP," + "category_id INTEGER," + "store_id INTEGER," + "position_city TEXT," + "position_city_id INTEGER)") + print("DB was not found(6/12) | Creating...") + + # Создание БД с хранением товаров + if len(con.execute("PRAGMA table_info(storage_item)").fetchall()) == 9: + print("DB was found(7/12)") + else: + con.execute("CREATE TABLE IF NOT EXISTS storage_item(" + "increment INTEGER PRIMARY KEY AUTOINCREMENT," + "item_id INTEGER," + "item_data TEXT," + "position_id INTEGER," + "category_id INTEGER," + "shop_id INTEGER," + "creator_id INTEGER," + "creator_name TEXT," + "add_date TIMESTAMP)") + print("DB was not found(7/12) | Creating...") + + # # Создание БД с хранением покупок + if len(con.execute("PRAGMA table_info(storage_purchases)").fetchall()) == 15: + print("DB was found(8/12)") + else: + con.execute("CREATE TABLE IF NOT EXISTS storage_purchases(" + "increment INTEGER PRIMARY KEY AUTOINCREMENT," + "user_id INTEGER," + "user_login TEXT," + "user_name TEXT," + "purchase_receipt TEXT," + "purchase_count INTEGER," + "purchase_price INTEGER," + "purchase_price_one INTEGER," + "purchase_position_id INTEGER," + "purchase_position_name TEXT," + "purchase_item TEXT," + "purchase_date TIMESTAMP," + "purchase_unix INTEGER," + "balance_before INTEGER," + "balance_after INTEGER)") + print("DB was not found(8/12) | Creating...") + + if len(con.execute("PRAGMA table_info(storage_shop)").fetchall()) == 3: + print("DB was not found(9/12) | Creating...") + else: + # Создание БД с хранением магазинов + con.execute("CREATE TABLE IF NOT EXISTS storage_shop(" + "increment INTEGER PRIMARY KEY AUTOINCREMENT," + "shop_id INTEGER," + "shop_name TEXT)") + + # # Создание БД с хранением покупок + if len(con.execute("PRAGMA table_info(storage_purchases)").fetchall()) == 15: + print("DB was found(10/12)") + else: + con.execute("CREATE TABLE IF NOT EXISTS storage_purchases(" + "increment INTEGER PRIMARY KEY AUTOINCREMENT," + "user_id INTEGER," + "user_login TEXT," + "user_name TEXT," + "purchase_receipt TEXT," + "purchase_count INTEGER," + "purchase_price INTEGER," + "purchase_price_one INTEGER," + "purchase_position_id INTEGER," + "purchase_position_name TEXT," + "purchase_item TEXT," + "purchase_date TIMESTAMP," + "purchase_unix INTEGER," + "balance_before INTEGER," + "balance_after INTEGER)") + print("DB was not found(10/12) | Creating...") + + if len(con.execute("PRAGMA table_info(storage_orders)").fetchall()) == 15: + print("DB was found(11/12)") + else: + con.execute("CREATE TABLE IF NOT EXISTS storage_orders(" + "order_id INTEGER PRIMARY KEY AUTOINCREMENT," + "user_id INTEGER," + "user_login TEXT," + "user_name TEXT," + "order_date TEXT," + "order_state INTEGER," + "order_unix INTEGER," + "phone TEXT," + "address TEXT)") + + print("DB was not found(11/12) | Creating...") + + if len(con.execute("PRAGMA table_info(storage_orders_items)").fetchall()) == 7: + print("DB was found(12/12)") + else: + con.execute("CREATE TABLE IF NOT EXISTS storage_orders_items(" + "order_item_id INTEGER PRIMARY KEY AUTOINCREMENT," + "order_id INTEGER," + "position_id INTEGER," + "user_name TEXT," + "count INTEGER," + "price INTEGER," + "receipt INTEGER)") + + print("DB was not found(12/12) | Creating...") + + + con.commit() + + +# ================================================================================================================ +# ========== Новые функции 11.08.22 ================================== + +# возвращает город пользователя и координаты +def get_city_user(user_id): + print(f'возвращает город пользователя и координаты api_sqlite.py 675') + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select user_city_id from storage_users where user_id = ?''' + result = cur.execute(query, (user_id,)).fetchone() + cur.close() + return result + +# возвращает город пользователя и координаты +def get_city_user2(user_id): + print(f'возвращает город пользователя и координаты api_sqlite.py 675') + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select user_city, user_geocode, user_city_id from storage_users where user_id = ?''' + result = cur.execute(query, (user_id,)).fetchone() + cur.close() + return result + + +# возвращает город пользователя и координаты +def get_citytext_user(user_id): + print(f'возвращает город пользователя и координаты api_sqlite.py 675') + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select user_city from storage_users where user_id = ?''' + result = cur.execute(query, (user_id,)).fetchone() + cur.close() + return result + +# позиции по городу и категории +def get_position_on_city(category_id, city): + print(f'позиции по городу и категории api_sqlite.py 686') + if city is None: + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select * from storage_position where category_id = ?''' + result = cur.execute(query, (category_id,)).fetchall() + cur.close() + return result + else: + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select * from storage_position where category_id = ? and position_city_id = ?''' + items = [category_id, city] + result = cur.execute(query, items).fetchall() + cur.close() + return result + + +# категории в городе +def get_category_in_city(city_id): + if city_id is None: + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select distinct c.category_id, c.category_name + from storage_category c join storage_position p on c.category_id=p.category_id order by c.category_name asc''' + result = cur.execute(query).fetchall() + return result + + else: + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select distinct c.category_id, c.category_name + from storage_category c join storage_position p on c.category_id=p.category_id where position_city_id = ? order by c.category_name asc''' + result = cur.execute(query, (city_id,)).fetchall() + return result + diff --git a/TelegramGoodsinbot/tgbot/services/api_sqlite_shop.py b/TelegramGoodsinbot/tgbot/services/api_sqlite_shop.py new file mode 100644 index 0000000..aa6de65 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/api_sqlite_shop.py @@ -0,0 +1,97 @@ +# - *- coding: utf- 8 - *- +import math +import random +import sqlite3 + +from tgbot.data.config import PATH_DATABASE +from tgbot.utils.const_functions import get_unix, get_date, clear_html + +# Преобразование полученного списка в словарь +def dict_factory(cursor, row): + save_dict = {} + + for idx, col in enumerate(cursor.description): + save_dict[col[0]] = row[idx] + + return save_dict + + +#################################################################################################### +##################################### ФОРМАТИРОВАНИЕ ЗАПРОСА ####################################### +# Форматирование запроса без аргументов +def update_format(sql, parameters: dict): + if "XXX" not in sql: sql += " XXX " + + values = ", ".join([ + f"{item} = ?" for item in parameters + ]) + sql = sql.replace("XXX", values) + + return sql, list(parameters.values()) + + +# Форматирование запроса с аргументами +def update_format_args(sql, parameters: dict): + sql = f"{sql} WHERE " + + sql += " AND ".join([ + f"{item} = ?" for item in parameters + ]) + + return sql, list(parameters.values()) + + + +# Получение всех магазинов +def get_all_shopx(): + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select shop_id, name, description, address, phone, admin, logo, city, geocode, city_id from storage_shop''' + result = cur.execute(query).fetchall() + cur.close() + return result + +# Получение одного магазина +def get_the_shop(shop_id): + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select shop_id, name, description, address, phone, admin, logo, city, geocode, city_id from storage_shop where shop_id = &''' + result = cur.execute(query, (shop_id,)).fetchall() + cur.close() + return result + + +# Добавление магазина +def add_shopx(name, description, adreess, phone, admin, logo, city, geocode, city_id): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + con.execute("INSERT INTO storage_shop (shop_id, name, description, address, phone, admin, logo, city, geocode, city_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + [random.randint(1000000000, 9999999999), name, description, adreess, phone, admin, logo, city, geocode, city_id]) + con.commit() + + +# Изменение магазина +def update_shopx(category_id, **kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"UPDATE storage_shop SET" + sql, parameters = update_format(sql, kwargs) + parameters.append(category_id) + con.execute(sql + "WHERE shop_id = ?", parameters) + con.commit() + +# Получение категории +def get_shopx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_shop" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchone() + +# Получение категорий +def get_positionsx(**kwargs): + with sqlite3.connect(PATH_DATABASE) as con: + con.row_factory = dict_factory + sql = f"SELECT * FROM storage_position" + sql, parameters = update_format_args(sql, kwargs) + return con.execute(sql, parameters).fetchall() diff --git a/TelegramGoodsinbot/tgbot/services/api_yoo.py b/TelegramGoodsinbot/tgbot/services/api_yoo.py new file mode 100644 index 0000000..1aee6ab --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/api_yoo.py @@ -0,0 +1,265 @@ +# - *- coding: utf- 8 - *- +import asyncio +import json +import time + +from aiohttp import ClientConnectorCertificateError +from async_class import AsyncClass +from yoomoney import Client +from yoomoney import Quickpay + + +from tgbot.services.api_session import RequestsSession +from tgbot.services.api_sqlite import update_paymentx, get_upaymentx, get_paymentx +from tgbot.utils.misc_functions import send_admins + + +# Апи работы с YooMoney +class YooAPI(AsyncClass): + async def __ainit__(self, acc_number=None, token=None, client_id=None, redirect_url=None): + #self.user_id = user_id + #check_pass=False, user_bill_pass=False, user_check_pass=False + if token is not None: + self.token = token + self.client_id = client_id + self.acc_number = acc_number + self.redirect_url = redirect_url + else: + #self.login = get_upaymentx(self.user_id)['qiwi_login'] + #self.token = get_upaymentx(self.user_id)['qiwi_token'] + #self.secret = get_upaymentx(self.user_id)['qiwi_secret'] + #self.login = get_paymentx()['qiwi_login'] + self.token = get_paymentx()['yoo_token'] + self.client_id = get_paymentx()['yoo_client_id'] + self.acc_number = get_paymentx()['yoo_acc_number'] + self.redirect_url = get_paymentx()['yoo_redirect_url'] + + #self.base_url = "https://yoomoney.ru/api/" + #self.headers = {"authorization": f"Bearer {self.token}"} + #self.client_id = get_paymentx()['yoo_client_id'] + #self.user_check_pass = user_check_pass + #self.user_bill_pass = user_bill_pass + #self.check_pass = check_pass + #self.add_pass = add_pass + #self.dp = dp + + + # Рассылка админам о нерабочем киви + @staticmethod + async def error_wallet(): + await send_admins(" Yoo кошелёк недоступен ❌\n" + "❗ Как можно быстрее его замените ❗") + + + #Обновление данных + async def update_yoo(self): + update_paymentx(yoo_acc_number=self.acc_number, yoo_token=self.token, yoo_client_id=self.client_id, yoo_redirect_url=self.redirect_url) + + + # Обязательная проверка перед каждым запросом + async def pre_checker(self): + if self.acc_number != "None": + if self.add_pass: + status, response = await self.check_account() + else: + status, response, code = await self.check_logpass() + await asyncio.sleep(0.5) + + if self.add_pass: + await self.dp.edit_text(response) + if status: + update_paymentx(qiwi_login=self.login, qiwi_token=self.token, qiwi_secret=self.secret) + else: + return False + elif self.check_pass: + if status: + if self.secret == "None": + text_secret = "Отсутствует" + else: + text_secret = self.secret + + await self.dp.answer(f"🥝 Qiwi кошелёк полностью функционирует ✅\n" + f"◾ Номер: {self.login}\n" + f"◾ Токен: {self.token}\n" + f"◾ Приватный ключ: {text_secret}") + else: + await self.error_wallet() + return False + elif self.user_bill_pass: + if not status: + await self.dp.edit_text( + "❗ Извиняемся за доставленные неудобства, пополнение временно недоступно.\n" + "⌛ Попробуйте чуть позже.") + await self.error_wallet() + return False + elif self.user_check_pass: + if not status: + await self.dp.answer( + "❗ Извиняемся за доставленные неудобства, проверка временно недоступна.\n" + "⌛ Попробуйте чуть позже.", True) + await self.error_wallet() + return False + elif not status: + if not self.add_pass: + await self.error_wallet() + return False + + return True + else: + if self.user_bill_pass: + await self.dp.edit_text( + "❗ Извиняемся за доставленные неудобства, пополнение временно недоступно.\n" + "⌛ Попробуйте чуть позже.") + await self.error_wallet() + return False + + # Проверка баланса + async def get_balance(self): + response = await self.pre_checker() + if response: + status, response, code = await self._request( + "funding-sources", + "v2", + "accounts", + ) + + save_balance = [] + for balance in response['accounts']: + if "qw_wallet_usd" == balance['alias']: + save_balance.append(f"🇺🇸 Долларов: {balance['balance']['amount']}$") + + if "qw_wallet_rub" == balance['alias']: + save_balance.append(f"🇷🇺 Рублей: {balance['balance']['amount']}₽") + + if "qw_wallet_eur" == balance['alias']: + save_balance.append(f"🇪🇺 Евро: {balance['balance']['amount']}€") + + if "qw_wallet_kzt" == balance['alias']: + save_balance.append(f"🇰🇿 Тенге: {balance['balance']['amount']}₸") + + save_balance = "\n".join(save_balance) + await self.dp.answer(f"🥝 Баланс кошелька {self.login} составляет:\n" + f"{save_balance}") + + # Проверка п2п ключа + async def check_secret(self): + try: + qiwi_p2p = QiwiP2P(self.secret) + bill = qiwi_p2p.bill(amount=1, lifetime=1) + qiwi_p2p.reject(bill_id=bill.bill_id) + return True + except: + return False + + # Создание платежа + async def bill_pay(self, get_amount, get_way): + #response = await self.pre_checker() + #if response: + receipt = str(int(time.time() * 100)) + + #print(get_way) + + if get_way == "ForYm": + #yoo = yooAPI() + #bill = qiwi.bill(bill_id=receipt, amount=get_amount, comment=receipt) + #send_requests = bill.pay_url + + quickpay = Quickpay( + receiver=self.acc_number, #'410011512189686', + quickpay_form="shop", + targets="Pay for goods in bot", + paymentType="SB", + sum=get_amount, + label=receipt, + ) + + print(quickpay.base_url) + + send_requests = quickpay.base_url + + print(quickpay.redirected_url) + + return_message = f"🆙 Пополнение баланса Yoomoney\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🥝 Для пополнения баланса, нажмите на кнопку ниже \n" \ + f"Перейти к оплате и оплатите выставленный вам счёт\n" \ + f"❗ У вас имеется 30 минут на оплату счета.\n" \ + f"💰 Сумма пополнения: {get_amount}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔄 После оплаты, нажмите на Проверить оплату" + + + return return_message, send_requests, receipt + return False, False, False + #send_requests, + + # Проверка платежа по форме + async def check_formy(self, receipt): + #yoo = YooAPI() + print(self.token) + #token = "410011512189686.0C1440CB73FD1452BC25E2B8FF48A4C8EA46FCF44A5A8E432F9B5F65E16AD45A5B07CAA9E8684E384ADD321358C4B4EDF10662A2AB8F9685CC27D6F6EF60B4DE851917851F2EB51FAD265BAA0AEDDA7E27D919C179C1491C140133FE01817816B6A1D4BA839E472C7CE1468E37470D312B8FB516242D1420D25802E2E66C2588" + client = Client(self.token) + history = client.operation_history(label=receipt) + #print(history.operations) + for operation in history.operations: + #r = list(get_pay) + #get_pay = qiwi_p2p.check(bill_id=receipt) + #print(r) + #print(get_pay) + #for pay in r: + # print(pay) + + #pay_status = 'success' # Получение статуса платежа + #pay_amount = '4' + + pay_status = operation.status # Получение статуса платежа + pay_amount = int(float(operation.amount)) # Получение суммы платежа в рублях + + return pay_status, pay_amount + + # Проверка платежа по переводу + async def check_send(self, receipt): + response = await self.pre_checker() + if response: + status, response, code = await self._request( + "payment-history", + "v2", + "payments", + {"rows": 30, "operation": "IN"}, + ) + + pay_status = False + pay_amount = 0 + + for check_pay in response['data']: + if str(receipt) == str(check_pay['comment']): + if "643" == str(check_pay['sum']['currency']): + pay_status = True + pay_amount = int(float(check_pay['sum']['amount'])) + else: + return_message = 1 + break + + if pay_status: + return_message = 3 + else: + return_message = 2 + + return return_message, pay_amount + + return 4, False + + # Запросы +''' async def _request(self, action, version, get_way, params=None): + url = self.base_url.format(action, version, self.login, get_way) + + rSession: RequestsSession = self.dp.bot['rSession'] + session = await rSession.get_session() + + try: + response = await session.get(url, params=params, headers=self.headers, ssl=False) + return True, json.loads((await response.read()).decode()), response.status + except ClientConnectorCertificateError: + return False, None, "CERTIFICATE_VERIFY_FAILED" + except: + return False, None, response.status''' diff --git a/TelegramGoodsinbot/tgbot/services/location_function.py b/TelegramGoodsinbot/tgbot/services/location_function.py new file mode 100644 index 0000000..cf9c6dc --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/location_function.py @@ -0,0 +1,113 @@ +import sqlite3 + +from geopy.geocoders import Nominatim +from tgbot.data.config import PATH_DATABASE + + +# проверка записи локации +def is_location(user_id): + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = '''select user_city from storage_users where user_id = ?''' + result = cur.execute(query, (user_id,)).fetchone() + if result[0] == None: + return False + else: + return True + +# Nominatim geo 2 address +def search_address(lat, long): + geolocator = Nominatim(user_agent="TGGoodsinbot") + location = geolocator.reverse(f'{lat}, {long}') + return location.address + +def add_address(address, user_id): + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = 'update storage_users set user_address = ? where user_id = ?' + #row = f'{lat}, {long}' + items = [address, user_id] + cur.execute(query, items) + conn.commit() + + +# поиск города в радиусе 0.5' вокруг пользователя +def search_city(lat, long): + conn = sqlite3.connect('tgbot/data/data_cities.db') + cur = conn.cursor() + lat_min = lat - 0.5 + lat_max = lat + 0.5 + long_min = long - 0.5 + long_max = long + 0.5 + query = f'''select city, id FROM cities where co_1 > ? and co_1 < ? and co_2 > ? and co_2 < ?''' + items = [lat_min, lat_max, long_min, long_max] + cur.execute(query, items) + result = cur.fetchone() + conn.commit() + if result == None: + return False + else: + return result + +# добавляет геокод в бд +def add_geocode(lat, long, user_id): + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = 'update storage_users set user_geocode = ? where user_id = ?' + row = f'{lat}, {long}' + items = [row, user_id] + cur.execute(query, items) + conn.commit() + +# добавляет город в бд +def add_city(city, user_id, city_id): + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = 'update storage_users set user_city = ?, user_city_id = ? where user_id = ?' + items = [city, city_id, user_id] + cur.execute(query, items) + conn.commit() + +# город по айди и записывет координаты города в профиль пользователя +def get_city(id, user_id): + conn = sqlite3.connect('tgbot/data/data_cities.db') + cur = conn.cursor() + query = 'select city, co_1, co_2, id from cities where id = ?' + result = cur.execute(query, (id,)).fetchone() + conn.commit() + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + row = f'{result[1]}, {result[2]}' + items = [row, user_id] + query = 'update storage_users set user_geocode = ? where user_id = ?' + cur.execute(query, items) + conn.commit() + return result + +# ============================================================================================================== +# ========================= функции для локации позиции (магазина) ========================================= + +# добавляет город в позиции +def update_position_city(city, city_id, user_id): + conn = sqlite3.connect(PATH_DATABASE) + cur = conn.cursor() + query = 'update storage_position set position_city = ?, position_city_id = ? where position_id = ?' + items = [city, city_id, user_id] + cur.execute(query, items) + conn.commit() + +# город по айди +def get_city_info(id): + conn = sqlite3.connect('tgbot/data/data_cities.db') + cur = conn.cursor() + query = 'select city, co_1, co_2 from cities where id = ?' + result = cur.execute(query, (id,)).fetchone() + return result + + +# город пользователя по айди +# def get_user_city(user_id): +# conn = sqlite3.connect(PATH_DATABASE) +# cur = conn.cursor() +# query = '''select user_city from storage_users where user_id = ?''' +# result = cur.execute(query, (user_id,)).fetchone() \ No newline at end of file diff --git a/TelegramGoodsinbot/tgbot/services/location_stat.py b/TelegramGoodsinbot/tgbot/services/location_stat.py new file mode 100644 index 0000000..416cb4f --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/location_stat.py @@ -0,0 +1,5 @@ +from aiogram.dispatcher.filters.state import State, StatesGroup + + +class geo_choice(StatesGroup): + location= State() \ No newline at end of file diff --git a/TelegramGoodsinbot/tgbot/services/mes.py b/TelegramGoodsinbot/tgbot/services/mes.py new file mode 100644 index 0000000..6f5769d --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/mes.py @@ -0,0 +1,20 @@ +import asyncio + +from aiogram import Bot, types + +API_TOKEN = '5361635126:AAF9sQ8__qoITGGlUVBhsev-nz15NJj_QN0' +CHANNEL_ID = -1001683374540 + +bot = Bot(token=API_TOKEN, parse_mode=types.ParseMode.HTML) + + +async def send_message(channel_id: int, text: str): + await bot.send_message(channel_id, text) + + +async def main(): + await send_message(CHANNEL_ID, 'Hello!') + + +if __name__ == '__main__': + asyncio.run(main()) diff --git a/TelegramGoodsinbot/tgbot/services/regular.py b/TelegramGoodsinbot/tgbot/services/regular.py new file mode 100644 index 0000000..02273b7 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/regular.py @@ -0,0 +1,74 @@ +# - *- coding: utf- 8 - *- +import asyncio +import os +from datetime import datetime +#import requests + +from apscheduler.schedulers.asyncio import AsyncIOScheduler +from aiogram import Bot, types + + +from tgbot.utils.misc_functions import get_position_of_day + +API_TOKEN = '5402212470:AAGFv7hY2bYGeaCOi_77cZJlOd31crtXK9k' +#API_TOKEN = '5337905343:AAFnZEexDdOAhn16AEw1zofEzVrPPEag89Q' +#API_TOKEN = '5337905343:AAFnZEexDdOAhn16AEw1zofEzVrPPEag89Q' +#CHANNEL_ID = -1001683374540 +CHANNEL_ID = 919148970 + + +bot = Bot(token=API_TOKEN, parse_mode=types.ParseMode.HTML) + +def tick(): + print('Tick! The time is: %s' % datetime.now()) +#get_message, get_image = get_position_of_day() + + + +def send_photo_telegram(file_id): + files = {'photo': open({file_id}, 'rb')} + token = "5337905343:AAFnZEexDdOAhn16AEw1zofEzVrPPEag89Q" + chat_id = "-1001683374540" # если у вас группа то будет так chat_id = "-1009999999" + r = requests.post("https://api.telegram.org/bot"+token+"/sendPhoto?chat_id=" + chat_id, files=files) + if r.status_code != 200: + raise Exception("post_text error") + + + + +async def send_message_start(): + position, image = get_position_of_day() + #await send_message(CHANNEL_ID, 'tttt') + #get_position = get_positionx(position_id=4875164059) + print(image) + #await send_photo_telegram(image) + #await send_photo(CHANNEL_ID, photo='file_id_' + image) + #await send_photo(CHANNEL_ID, image, position) + await send_message(CHANNEL_ID, position) + #await send_photo(chat_id=CHANNEL_ID, photo=image, caption=position, parse_mode=ParseMode.MARKDOWN) + #if len(image) >= 5: + # photo = types.InputMediaPhoto(image) + # await send_photo(CHANNEL_ID, photo, position) + #else: + + + #await send_message(CHANNEL_ID, position) + #await send_message(CHANNEL_ID, '
|||
') + + +async def send_message(channel_id: int, text: str): + await bot.send_message(channel_id, text) + +if __name__ == '__main__': + scheduler = AsyncIOScheduler() + scheduler.add_job(tick, 'interval', seconds=3) + scheduler.add_job(send_message_start, 'interval', seconds=5) + #scheduler.add_job(send_message_start, 'interval', next_run_time=datetime.now()) + + scheduler.start() + print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C')) + # Execution will block here until Ctrl+C (Ctrl+Break on Windows) is pressed. + try: + asyncio.get_event_loop().run_forever() + except (KeyboardInterrupt, SystemExit): + pass \ No newline at end of file diff --git a/TelegramGoodsinbot/tgbot/services/tick.py b/TelegramGoodsinbot/tgbot/services/tick.py new file mode 100644 index 0000000..75d17cb --- /dev/null +++ b/TelegramGoodsinbot/tgbot/services/tick.py @@ -0,0 +1,20 @@ +# - *- coding: utf- 8 - *- +import asyncio +import os +from datetime import datetime + +from apscheduler.schedulers.asyncio import AsyncIOScheduler + +def tick(): + print('Tick! The time is: %s' % datetime.now()) + +if __name__ == '__main__': + scheduler = AsyncIOScheduler() + scheduler.add_job(tick, 'interval', seconds=3) + scheduler.start() + print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C')) + # Execution will block here until Ctrl+C (Ctrl+Break on Windows) is pressed. + try: + asyncio.get_event_loop().run_forever() + except (KeyboardInterrupt, SystemExit): + pass \ No newline at end of file diff --git a/TelegramGoodsinbot/tgbot/utils/__init__.py b/TelegramGoodsinbot/tgbot/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TelegramGoodsinbot/tgbot/utils/const_functions.py b/TelegramGoodsinbot/tgbot/utils/const_functions.py new file mode 100644 index 0000000..c2af0b3 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/utils/const_functions.py @@ -0,0 +1,61 @@ +# - *- coding: utf- 8 - *- +import time +from datetime import datetime + + +# Очистка текста от HTML тэгов +def clear_html(get_text): + if "<" in get_text: get_text = get_text.replace("<", "*") + if ">" in get_text: get_text = get_text.replace(">", "*") + + return get_text + + +# Получение текущего unix времени +def get_unix(): + return int(time.time()) + + +# Получение текущей даты +def get_date(): + this_date = datetime.today().replace(microsecond=0) + this_date = this_date.strftime("%d.%m.%Y %H:%M:%S") + + return this_date + + +# Разбив списка по количеству переданных значений +def split_messages(get_list, count): + return [get_list[i:i + count] for i in range(0, len(get_list), count)] + + +# Очистка мусорных символов из списка +def clear_list(get_list: list): + while "" in get_list: + get_list.remove("") + + while " " in get_list: + get_list.remove(" ") + + while "," in get_list: + get_list.remove(",") + + while "\r" in get_list: + get_list.remove("\r") + + return get_list + + +# Конвертация дней +def convert_day(day): + day = int(day) + days = ['день', 'дня', 'дней'] + + if day % 10 == 1 and day % 100 != 11: + count = 0 + elif 2 <= day % 10 <= 4 and (day % 100 < 10 or day % 100 >= 20): + count = 1 + else: + count = 2 + + return f"{day} {days[count]}" diff --git a/TelegramGoodsinbot/tgbot/utils/misc/__init__.py b/TelegramGoodsinbot/tgbot/utils/misc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TelegramGoodsinbot/tgbot/utils/misc/bot_commands.py b/TelegramGoodsinbot/tgbot/utils/misc/bot_commands.py new file mode 100644 index 0000000..b5738a5 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/utils/misc/bot_commands.py @@ -0,0 +1,34 @@ +# - *- coding: utf- 8 - *- +from aiogram import Dispatcher +from aiogram.types import BotCommand, BotCommandScopeChat, BotCommandScopeDefault + +from tgbot.data.config import get_admins + +# Команды для юзеров +user_commands = [ + BotCommand("start", "♻ Перезапустить бота"), + BotCommand("support", "☎ Поддержка/FAQ"), + #BotCommand("user_seller_request", "Хочу продавать"), + BotCommand("faq", "ℹ FAQ"), +] + +# Команды для админов +admin_commands = [ + BotCommand("start", "♻ Перезапустить бота"), + BotCommand("support", "☎ Поддержка/FAQ"), + BotCommand("faq", "ℹ FAQ"), + #BotCommand("check_seller_requests", "Заявки в продавцы"), + BotCommand("db", "📦 Получить Базу Данных"), + BotCommand("log", "🖨 Получить логи"), +] + + +# Установка команд +async def set_commands(dp: Dispatcher): + await dp.bot.set_my_commands(user_commands, scope=BotCommandScopeDefault()) + + for admin in get_admins(): + try: + await dp.bot.set_my_commands(admin_commands, scope=BotCommandScopeChat(chat_id=admin)) + except: + pass diff --git a/TelegramGoodsinbot/tgbot/utils/misc/bot_filters.py b/TelegramGoodsinbot/tgbot/utils/misc/bot_filters.py new file mode 100644 index 0000000..dbd2686 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/utils/misc/bot_filters.py @@ -0,0 +1,83 @@ +# - *- coding: utf- 8 - *- +from aiogram import types +from aiogram.dispatcher.filters import BoundFilter + +from tgbot.data.config import get_admins, get_shopadmins, is_shopadmin +from tgbot.services.api_sqlite import get_settingsx + + +# Проверка на админа +class IsAdmin(BoundFilter): + async def check(self, message: types.Message): + if message.from_user.id in get_admins(): + return True + else: + return False + #return True + + +# Проверка на админа +class IsShopAdmin(BoundFilter): + async def check(self, message: types.Message): + if message.from_user.id in get_shopadmins(): #== is_shopadmin(message.from_user.id): + #if message.from_user.id == is_shopadmin(message.from_user.id): + return True + else: + return False + +#Проверка на любого админа +class IsAdminorShopAdmin(BoundFilter): + async def check(self, message: types.Message): + if message.from_user.id in get_admins() or message.from_user.id in get_shopadmins(): + return True + else: + return False + +# Проверка на принадлежность товара для админа магазина +class IsProductShopAdmin(BoundFilter): + async def check(self, message: types.Message): + #print message.from_user.id + # if message.from_user.id in get_admins(): + # return True + # else: + # return False + return True + +# Проверка на возможность покупки товара +class IsBuy(BoundFilter): + async def check(self, message: types.Message): + get_settings = get_settingsx() + + if get_settings['status_buy'] == "True" or message.from_user.id in get_admins(): + return False + else: + return True + + +# Проверка на возможность пополнения +class IsRefill(BoundFilter): + async def check(self, message: types.Message): + get_settings = get_settingsx() + + if get_settings['status_refill'] == "True" or message.from_user.id in get_admins(): + return False + else: + return True + + +# Проверка на технические работы +class IsWork(BoundFilter): + async def check(self, message: types.Message): + get_settings = get_settingsx() + + if get_settings['status_work'] == "False" or message.from_user.id in get_admins(): + return False + else: + return True + +class IsShopExist(BoundFilter): + async def check(self, message: types.Message): + if check_user_shop_exist(message.from_user.id) == 'True': + return True + else: + return False diff --git a/TelegramGoodsinbot/tgbot/utils/misc/bot_logging.py b/TelegramGoodsinbot/tgbot/utils/misc/bot_logging.py new file mode 100644 index 0000000..b9074b4 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/utils/misc/bot_logging.py @@ -0,0 +1,32 @@ +# - *- coding: utf- 8 - *- +import logging as bot_logger + +import colorlog + +from tgbot.data.config import PATH_LOGS + +# Формат логгирования +log_formatter_file = bot_logger.Formatter("%(levelname)s | %(asctime)s | %(filename)s:%(lineno)d | %(message)s") +log_formatter_console = colorlog.ColoredFormatter( + "%(purple)s%(levelname)s %(blue)s|%(purple)s %(asctime)s %(blue)s|%(purple)s %(filename)s:%(lineno)d %(blue)s|%(purple)s %(message)s%(red)s", + datefmt="%d-%m-%Y %H:%M:%S", +) + +# Логгирование в файл tgbot/data/logs.log +file_handler = bot_logger.FileHandler(PATH_LOGS, "w", "utf-8") +file_handler.setFormatter(log_formatter_file) +file_handler.setLevel(bot_logger.INFO) + +# Логгирование в консоль +console_handler = bot_logger.StreamHandler() +console_handler.setFormatter(log_formatter_console) +console_handler.setLevel(bot_logger.CRITICAL) + +# Подключение настроек логгирования +bot_logger.basicConfig( + format="%(levelname)s | %(asctime)s | %(filename)s:%(lineno)d | %(message)s", + handlers=[ + file_handler, + console_handler + ] +) diff --git a/TelegramGoodsinbot/tgbot/utils/misc_functions.py b/TelegramGoodsinbot/tgbot/utils/misc_functions.py new file mode 100644 index 0000000..da51b03 --- /dev/null +++ b/TelegramGoodsinbot/tgbot/utils/misc_functions.py @@ -0,0 +1,691 @@ +# - *- coding: utf- 8 - *- +import asyncio +import json +import random + +import requests +from aiogram import Dispatcher +from bs4 import BeautifulSoup + +from tgbot.data.config import get_admins, BOT_VERSION, BOT_DESCRIPTION +from tgbot.keyboards.reply_z_all import menu_frep +from tgbot.services.api_session import AsyncSession +from tgbot.loader import bot +from tgbot.services.api_sqlite import get_settingsx, update_settingsx, get_userx, get_all_positionsx, \ + update_positionx, get_all_categoriesx, get_all_purchasesx, get_all_refillx, get_all_usersx, get_all_itemsx, \ + get_itemsx, get_positionx, get_categoryx, get_all_positionsidx, get_requestx, get_user_orderx, get_cart_positionsx, get_orderx, get_purchasesx, get_purchasesxx +from tgbot.utils.const_functions import get_unix, convert_day + + +# Уведомление и проверка обновления при запуске бота +async def on_startup_notify(dp: Dispatcher): + if len(get_admins()) >= 1: + await send_admins(f"✅ Бот был успешно запущен\n" + f"➖➖➖➖➖➖➖➖➖➖\n" + f"{BOT_DESCRIPTION}\n" + f"➖➖➖➖➖➖➖➖➖➖\n" + f"❗ Данное сообщение видят только администраторы бота.", + markup="default") + await check_update() + +# Рассылка сообщения всем администраторам + + +async def send_admins(message, markup=None, not_me=0): + for admin in get_admins(): + if markup == "default": + markup = menu_frep(admin) + + try: + if str(admin) != str(not_me): + await bot.send_message(admin, message, reply_markup=markup, disable_web_page_preview=True) + except: + pass + +# Автоматическая очистка ежедневной статистики после 00:00 + + +async def update_profit_day(): + await send_admins(get_statisctics()) + + update_settingsx(misc_profit_day=get_unix()) + + +# Автоматическая очистка еженедельной статистики в понедельник 00:01 +async def update_profit_week(): + update_settingsx(misc_profit_week=get_unix()) + + +# Автоматическая проверка обновления каждые 24 часа +async def check_update(): + update_link = "" +''' + +# Автоматическая проверка обновления каждые 24 часа +async def check_update(aSession: AsyncSession): + session = await aSession.get_session() + + try: + response = await session.get("https://sites.google.com/view/check-update-autoshop/main-page", ssl=False) + soup_parse = BeautifulSoup(await response.read(), "html.parser") + get_bot_update = soup_parse.select("p[class$='CDt4Ke zfr3Q']")[0].text.split("^^^^^") + + if float(get_bot_update[0]) > float(BOT_VERSION): + if "*****" in get_bot_update[2]: + get_bot_update[2] = get_bot_update[2].replace("*****", "\n") + + await send_admins(f"❇ Вышло обновление: Скачать\n" + f"➖➖➖➖➖➖➖➖➖➖\n" + f"{get_bot_update[2]}\n" + f"➖➖➖➖➖➖➖➖➖➖\n" + f"❗ Данное сообщение видят только администраторы бота.") + except Exception as ex: + print(f"Error check update: {ex}") +''' + +# Получение faq + + +def get_faq(user_id, send_message): + get_user = get_userx(user_id=user_id) + + if "{user_id}" in send_message: + send_message = send_message.replace( + "{user_id}", f"{get_user['user_id']}") + if "{username}" in send_message: + send_message = send_message.replace( + "{username}", f"{get_user['user_login']}") + if "{firstname}" in send_message: + send_message = send_message.replace( + "{firstname}", f"{get_user['user_name']}") + + return send_message + + +# Загрузка текста на текстовый хостинг +async def upload_text(dp, get_text): + session = await (dp.bot['rSession']).get_session() + + spare_pass = False + await asyncio.sleep(0.5) + + try: + response = await session.post("http://pastie.org/pastes/create", + data={"language": "plaintext", "content": get_text}) + + get_link = response.url + if "create" in str(get_link): + spare_pass = True + except: + spare_pass = True + + if spare_pass: + response = await session.post("https://www.friendpaste.com", + json={"language": "text", "title": "", "snippet": get_text}) + + get_link = json.loads((await response.read()).decode())['url'] + + return get_link + + +# Проверка на перенесение БД из старого бота, в нового или указание токена нового бота +async def check_bot_data(): + get_login = get_settingsx()['misc_bot'] + get_bot = await bot.get_me() + + if get_login not in [get_bot.username, "None"]: + get_positions = get_all_positionsx() + + for position in get_positions: + update_positionx(position['position_id'], position_photo="") + + update_settingsx(misc_bot=get_bot.username) + + +# Получить информацию о позиции для админа +def get_position_of_day(): + print('Получить информацию о случайной позиции для админа misc_functions.py 127') + print(len(get_all_positionsx())) + pos_id = random.choice(get_all_positionsidx()) + print(pos_id['position_id']) + # pos_id=random.choice(get_all_positionsidx()) + get_items = get_itemsx(position_id=pos_id['position_id']) + get_position = get_positionx(position_id=pos_id['position_id']) + get_category = get_categoryx(category_id=get_position['category_id']) + + text_description = "Отсутствует ❌" + photo_text = "Отсутствует ❌" + get_photo = None + + if len(get_position['position_photo']) >= 5: + photo_text = "Присутствует ✅" + get_photo = get_position['position_photo'] + + if get_position['position_description'] != "0": + text_description = f"\n{get_position['position_description']}" + + get_message = f"📁 Позиция: {get_position['position_name']}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🏙 Город: {get_position['position_city']}\n" \ + f"🗃 Категория: {get_category['category_name']}\n" \ + f"💰 Стоимость: {get_position['position_price']}₽\n" \ + f"📦 Остаток: {len(get_items)}шт\n" \ + f"📸 Изображение: {photo_text}\n" \ + f"📜 Описание: {text_description}" + + return get_message, get_photo + + +# Получить информацию о позиции для админа +def get_position_admin(position_id): + print('Получить информацию о позиции для админа misc_functions.py 127') + get_items = get_itemsx(position_id=position_id) + get_position = get_positionx(position_id=position_id) + get_category = get_categoryx(category_id=get_position['category_id']) + + text_description = "Отсутствует ❌" + photo_text = "Отсутствует ❌" + get_photo = None + + if len(get_position['position_photo']) >= 5: + photo_text = "Присутствует ✅" + get_photo = get_position['position_photo'] + + if get_position['position_description'] != "0": + text_description = f"\n{get_position['position_description']}" + + get_message = f"📁 Позиция: {get_position['position_name']}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🏙 Город: {get_position['position_city']}\n" \ + f"🗃 Категория: {get_category['category_name']}\n" \ + f"💰 Стоимость: {get_position['position_price']}₽\n" \ + f"📦 Остаток: {len(get_items)}шт\n" \ + f"📸 Изображение: {photo_text}\n" \ + f"📜 Описание: {text_description}" + + return get_message, get_photo + + +def user_refill_my(user_id): + return f"Нажмите пожалуйста кнопку:\n" + +# Открытие своего профиля + + +def open_profile_my(user_id): + get_purchases = get_purchasesxx(user_id=user_id) + get_user = get_userx(user_id=user_id) + count_items = 0 + how_days = get_unix() - get_user['user_unix'] // 60 // 60 // 24 + + if len(get_purchases) >= 1: + for items in get_purchases: + count_items += int(items['purchase_count']) + + get_settings = get_settingsx() + profile_my = f"👤 Ваш профиль:\n" \ + f"➖➖➖➖➖➖➖➖➖➖\n" \ + f"🆔 ID: {get_user['user_id']}\n" \ + f"💰 Баланс: {get_user['user_balance']}₽\n" \ + f"🎁 Куплено товаров: {count_items}шт\n" \ + f"🕰 Регистрация: {get_user['user_date'].split(' ')[0]} ({convert_day(how_days)})\n" + + # if get_settings['type_trade'] != "digital": + # profile_my = f"{profile_my} 🏙 Город: {get_user['user_city']}" + + return profile_my + +#f"📡 Координаты: {get_user['user_geocode']}" + + +def calc_cart_summ(user_id): + order = get_user_orderx(user_id=user_id) + get_positions = [] + totalm = 0 + get_positions = get_cart_positionsx(order_id=order['order_id']) + for position in get_positions: + poscost = position['count'] * position['position_price'] + totalm += poscost + return totalm + +# Открытие своей корзины + + +def open_cart_my(user_id): + order = get_user_orderx(user_id=user_id) + orderdata = get_orderx(user_id=user_id) + get_user = get_userx(user_id=user_id) + ub = get_user['user_balance'] + get_positions = [] + get_positions = get_cart_positionsx(order_id=order['order_id']) + this_items = [] + this_itemst = this_itemst2 = this_itemst3 = '' + delivery = 200 + totalm = 0 + print("|||") + this_items.append(f"| Наименование | Цена | Количество | Стоимость |") + + for position in get_positions: + poscost = position['count'] * position['position_price'] + totalm += poscost # собираем стоимость корзины + this_items.append( + f"{position['position_name']} | {position['position_price']}₽ | {position['count']}шт. | {poscost}₽") + + this_itemst += f"{position['position_name']} | {position['position_price']}₽ | {position['count']}шт. | {poscost}₽ \n" + + print( + f"{position['position_name']} | {position['position_price']}₽ | {position['count']}шт.| {poscost}₽") + + this_itemst3 += "Всего по всем позициям: " + str(totalm) + "\n" + #this_itemst += this_itemst2 + totalm2 = totalm + delivery + + if ub >= totalm2: + this_itemst2 = "Заказ возможно оплатить с баланса целиком." + elif ub < totalm2: + torefill = totalm2 - get_user['user_balance'] + this_itemst2 = "Для оформления заказа потребуется пополнение в размере:" + \ + str(torefill) + "₽" + + this_address = get_user['user_address'] + if this_address is None: + this_address = "Ваш адрес доставки не указан." + # else: this_itemst += this_address + + this_phone = get_user['user_phone'] + if this_phone is None: + this_phone = "Ваш контактный номер не указан." + # else: this_itemst += this_phone + + return f"👤 Ваша Корзина:\n" \ + f"➖➖➖➖➖➖➖➖➖➖\n" \ + f"🆔 Telegram ID: {get_user['user_id']}\n" \ + f"💳 Баланс: {get_user['user_balance']}₽\n" \ + f"🗃 Всего товаров: {totalm}\n" \ + f" {this_itemst}\n" \ + f"🏙 Итого корзина: {totalm2}₽\n" \ + f"🏙 Примечание: {this_itemst2}\n" + # f"🆔 Telegram ID: {get_user['user_id']}\n" \ + # f"ID: {orderdata['order_id']} Статус корзины: {orderdata['order_state']}\n" \ + # f"🏙 Доставка: {delivery}₽\n" \ + + # f"🕰 Адрес: {this_address}\n" \ + # f"📞 Телефон: {this_phone}\n" \ + + +# f"📡 Координаты: {get_user['user_geocode']}\n" \ + +# Открытие профиля при поиске + + +def open_profile_search(user_id): + get_purchases = get_purchasesx(user_id=user_id) + get_user = get_userx(user_id=user_id) + count_items = 0 + + how_days = int(get_unix() - get_user['user_unix']) // 60 // 60 // 24 + + if len(get_purchases) >= 1: + for items in get_purchases: + count_items += items['purchase_count'] + + return f"👤 Профиль пользователя: {get_user['user_name']}\n" \ + f"➖➖➖➖➖➖➖➖➖➖\n" \ + f"🆔 ID: {get_user['user_id']}\n" \ + f"👤 Логин: @{get_user['user_login']}\n" \ + f"Ⓜ Имя: {get_user['user_name']}\n" \ + f"🕰 Регистрация: {get_user['user_date']} ({convert_day(how_days)})\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"💰 Баланс: {get_user['user_balance']}₽\n" \ + f"💰 Всего пополнено: {get_user['user_refill']}₽\n" \ + f"🎁 Куплено товаров: {count_items}шт" + +# Открытие профиля при поиске + + +def open_profile_search_req(user_id): + get_requests = get_requestx(requester=user_id) + get_purchases = get_purchasesx(user_id=user_id) + get_user = get_userx(user_id=user_id) + count_items = 0 + total_items = '' + + how_days = int(get_unix() - get_user['user_unix']) // 60 // 60 // 24 + + if len(get_purchases) >= 1: + for items in get_purchases: + count_items += items['purchase_count'] + + if len(get_requests) >= 1: + for items in get_requests: + total_items += "|" + str(items['requesttxt']) + + return f"👤 Запрос от пользователя: {get_user['user_name']}\n" \ + f"➖➖➖➖➖➖➖➖➖➖\n" \ + f"Группа товаров: {total_items}\n" \ + f" requestID: {items['increment']}\n" \ + f"🆔 userID: {get_user['user_id']}\n" \ + f"👤 Логин: @{get_user['user_login']}\n" \ + f"👤 Роль: {get_user['user_role']}\n" \ + f"Ⓜ Имя: {get_user['user_name']}\n" \ + f"🕰 Регистрация: {get_user['user_date']} ({convert_day(how_days)})\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"💰 Баланс: {get_user['user_balance']}₽\n" \ + f"💰 Всего пополнено: {get_user['user_refill']}₽\n" \ + f"🎁 Куплено товаров: {count_items}шт" + + +# Статистика бота +def get_statisctics(): + show_profit_all, show_profit_day, show_profit_week = 0, 0, 0 + show_refill_all, show_refill_day, show_refill_week = 0, 0, 0 + show_money_users, show_buy_items = 0, 0 + + get_categories = get_all_categoriesx() + get_positions = get_all_positionsx() + get_purchases = get_all_purchasesx() + get_refill = get_all_refillx() + get_settings = get_settingsx() + get_items = get_all_itemsx() + get_users = get_all_usersx() + + for purchase in get_purchases: + show_profit_all += purchase['purchase_price'] + show_buy_items += purchase['purchase_count'] + if purchase['purchase_unix'] - get_settings['misc_profit_day'] >= 0: + show_profit_day += purchase['purchase_price'] + if purchase['purchase_unix'] - get_settings['misc_profit_week'] >= 0: + show_profit_week += purchase['purchase_price'] + + for refill in get_refill: + show_refill_all += refill['refill_amount'] + if refill['refill_unix'] - get_settings['misc_profit_day'] >= 0: + show_refill_day += refill['refill_amount'] + if refill['refill_unix'] - get_settings['misc_profit_week'] >= 0: + show_refill_week += refill['refill_amount'] + + for user in get_users: + show_money_users += user['user_balance'] + + message = "📊 Статистика бота\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Пользователи: 🔶\n" \ + f"👤 Пользователей: {len(get_users)}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Средства 🔶\n" \ + f"💸 Продаж за 24 часа: {show_profit_day}₽\n" \ + f"💸 Продаж за неделю: {show_profit_week}₽\n" \ + f"💸 Продаж за всё время: {show_profit_all}₽\n" \ + f"💳 Средств в системе: {show_money_users}₽\n" \ + f"💰 Пополнений за 24 часа: {show_refill_day}₽\n" \ + f"💰 Пополнений за неделю: {show_refill_week}₽\n" \ + f"💰 Пополнений за всё время: {show_refill_all}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Прочее 🔶\n" \ + f"🎁 Товаров: {len(get_items)}шт\n" \ + f"📁 Позиций: {len(get_positions)}шт\n" \ + f"🗃 Категорий: {len(get_categories)}шт\n" \ + f"🎁 Продано товаров: {show_buy_items}шт\n" + + return message + +# Открытие профиля при поиске +def open_profile_search_seller(user_id, price): + get_purchases = get_purchasesx(user_id=user_id) + get_user = get_userx(user_id=user_id) + count_items = 0 + + how_days = int(get_unix() - get_user['user_unix']) // 60 // 60 // 24 + + if len(get_purchases) >= 1: + for items in get_purchases: + count_items += items['purchase_count'] + + + return f"👤 Профиль пользователя: {get_user['user_name']}\n" \ + f"➖➖➖➖➖➖➖➖➖➖\n" \ + f"🆔 ID: {get_user['user_id']}\n" \ + f"👤 Логин: @{get_user['user_login']}\n" \ + f"Ⓜ Имя: {get_user['user_name']}\n" \ + f"🕰 Регистрация: {get_user['user_date']} ({convert_day(how_days)})\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"💰 Продано: {price}₽\n" \ + f"💰 Баланс: {get_user['user_balance']}₽\n" \ + f"💰 Всего пополнено: {get_user['user_refill']}₽\n" \ + f"🎁 Куплено товаров: {count_items}шт" + + +# Открытие профиля при поиске +def open_profile_search_seller(user_id): + get_purchases = get_purchasesx(user_id=user_id) + get_user = get_userx(user_id=user_id) + count_items = 0 + seller_items = '' + totals = 0 + + print(user_id) + + get_purchasessel = get_purchasesxx(user_id) + print(get_purchasessel) + + how_days = int(get_unix() - get_user['user_unix']) // 60 // 60 // 24 + + if len(get_purchasessel) >= 1: + for items in get_purchasessel: + name_item = items[1] + count_items = items[2] + name_price = items[3] + seller_items += f"{name_item} {count_items}шт. {name_price}₽\n" + totals += items[3] + + + if len(get_purchases) >= 1: + for items in get_purchases: + count_items += items['purchase_count'] + + + return f"👤 Профиль пользователя: {get_user['user_name']}\n" \ + f"➖➖➖➖➖➖➖➖➖➖\n" \ + f"🆔 ID: {get_user['user_id']}\n" \ + f"👤 Логин: @{get_user['user_login']}\n" \ + f"Ⓜ Имя: {get_user['user_name']}\n" \ + f"🕰 Регистрация: {get_user['user_date']} ({convert_day(how_days)})\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"➖➖➖➖{seller_items}➖➖➖\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"Всего продано: {totals}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"💰 Баланс: {get_user['user_balance']}₽\n" \ + f"💰 Всего пополнено: {get_user['user_refill']}₽\n" \ + f"🎁 Куплено товаров: {count_items}шт" + +# Статистика бота +def generate_dales_report(): + show_profit_all, show_profit_day, show_profit_week = 0, 0, 0 + show_refill_all, show_refill_day, show_refill_week = 0, 0, 0 + show_money_users, show_buy_items = 0, 0 + + get_categories = get_all_categoriesx() + get_positions = get_all_positionsx() + get_purchases = get_all_purchasesx() + get_refill = get_all_refillx() + get_settings = get_settingsx() + get_items = get_all_itemsx() + get_users = get_all_usersx() + + for purchase in get_purchases: + show_profit_all += purchase['purchase_price'] + show_buy_items += purchase['purchase_count'] + if purchase['purchase_unix'] - get_settings['misc_profit_day'] >= 0: + show_profit_day += purchase['purchase_price'] + if purchase['purchase_unix'] - get_settings['misc_profit_week'] >= 0: + show_profit_week += purchase['purchase_price'] + + for refill in get_refill: + show_refill_all += refill['refill_amount'] + if refill['refill_unix'] - get_settings['misc_profit_day'] >= 0: + show_refill_day += refill['refill_amount'] + if refill['refill_unix'] - get_settings['misc_profit_week'] >= 0: + show_refill_week += refill['refill_amount'] + + for user in get_users: + show_money_users += user['user_balance'] + + message = "📊 Статистика бота\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Пользователи: 🔶\n" \ + f"👤 Пользователей: {len(get_users)}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Средства 🔶\n" \ + f"💸 Продаж за 24 часа: {show_profit_day}₽\n" \ + f"💸 Продаж за неделю: {show_profit_week}₽\n" \ + f"💸 Продаж за всё время: {show_profit_all}₽\n" \ + f"💳 Средств в системе: {show_money_users}₽\n" \ + f"💰 Пополнений за 24 часа: {show_refill_day}₽\n" \ + f"💰 Пополнений за неделю: {show_refill_week}₽\n" \ + f"💰 Пополнений за всё время: {show_refill_all}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Прочее 🔶\n" \ + f"🎁 Товаров: {len(get_items)}шт\n" \ + f"📁 Позиций: {len(get_positions)}шт\n" \ + f"🗃 Категорий: {len(get_categories)}шт\n" \ + f"🎁 Продано товаров: {show_buy_items}шт\n" + + return message + + + +# Статистика бота +def get_statisctics(): + show_profit_all, show_profit_day, show_profit_week = 0, 0, 0 + show_refill_all, show_refill_day, show_refill_week = 0, 0, 0 + show_money_users, show_buy_items = 0, 0 + + get_categories = get_all_categoriesx() + get_positions = get_all_positionsx() + get_purchases = get_all_purchasesx() + get_refill = get_all_refillx() + get_settings = get_settingsx() + get_items = get_all_itemsx() + get_users = get_all_usersx() + + for purchase in get_purchases: + show_profit_all += purchase['purchase_price'] + show_buy_items += purchase['purchase_count'] + if purchase['purchase_unix'] - get_settings['misc_profit_day'] >= 0: + show_profit_day += purchase['purchase_price'] + if purchase['purchase_unix'] - get_settings['misc_profit_week'] >= 0: + show_profit_week += purchase['purchase_price'] + + for refill in get_refill: + show_refill_all += refill['refill_amount'] + if refill['refill_unix'] - get_settings['misc_profit_day'] >= 0: + show_refill_day += refill['refill_amount'] + if refill['refill_unix'] - get_settings['misc_profit_week'] >= 0: + show_refill_week += refill['refill_amount'] + + for user in get_users: + show_money_users += user['user_balance'] + + message = "📊 Статистика бота\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Пользователи: 🔶\n" \ + f"👤 Пользователей: {len(get_users)}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Средства 🔶\n" \ + f"💸 Продаж за 24 часа: {show_profit_day}₽\n" \ + f"💸 Продаж за неделю: {show_profit_week}₽\n" \ + f"💸 Продаж за всё время: {show_profit_all}₽\n" \ + f"💳 Средств в системе: {show_money_users}₽\n" \ + f"💰 Пополнений за 24 часа: {show_refill_day}₽\n" \ + f"💰 Пополнений за неделю: {show_refill_week}₽\n" \ + f"💰 Пополнений за всё время: {show_refill_all}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Прочее 🔶\n" \ + f"🎁 Товаров: {len(get_items)}шт\n" \ + f"📁 Позиций: {len(get_positions)}шт\n" \ + f"🗃 Категорий: {len(get_categories)}шт\n" \ + f"🎁 Продано товаров: {show_buy_items}шт\n" + + return message + + +# Статистика бота +def generate_sales_report(): + show_profit_all, show_profit_day, show_profit_week = 0, 0, 0 + show_refill_all, show_refill_day, show_refill_week = 0, 0, 0 + show_money_users, show_money_sellers, show_buy_items = 0, 0, 0 + + + get_categories = get_all_categoriesx() + get_positions = get_all_positionsx() + get_purchases = get_all_purchasesx() + #get_purchasesbysellers = get_purchasesbysellers() + get_refill = get_all_refillx() + get_settings = get_settingsx() + get_items = get_all_itemsx() + get_users = get_all_usersx() + top_sellers = [] + top_sellersp = [] + #keyboard = InlineKeyboardMarkup() + + for purchase in get_purchases: + show_profit_all += purchase['purchase_price'] + show_buy_items += purchase['purchase_count'] + if purchase['purchase_unix'] - get_settings['misc_profit_day'] >= 0: + show_profit_day += purchase['purchase_price'] + if purchase['purchase_unix'] - get_settings['misc_profit_week'] >= 0: + show_profit_week += purchase['purchase_price'] + + for refill in get_refill: + show_refill_all += refill['refill_amount'] + if refill['refill_unix'] - get_settings['misc_profit_day'] >= 0: + show_refill_day += refill['refill_amount'] + if refill['refill_unix'] - get_settings['misc_profit_week'] >= 0: + show_refill_week += refill['refill_amount'] + + for user in get_users: + print(user) + if user['user_role'] == "ShopAdmin": + show_money_sellers += user['user_balance'] + elif user['user_role'] is None: + show_money_users += user['user_balance'] + if user['user_role'] == "ShopAdmin" and user['user_balance'] >= 0: + top_sellers += user['user_name'] + str(user['user_balance']) + "\n" + + #for seller in get_purchasesbysellers: + # top_sellersp += user['user_login'] + str(user['price']) + "\n" + + #keyboard.add(ikb( + # f"{user['user_login']} | {user['user_balance']}₽", # | {len(get_items)} шт", + # callback_data=f"open_profile_search({user['increment']})")) + + #for position in get_positions[(remover): len(get_positions)]: + #print(f'position {position}') + #get_items = get_itemsx(position_id=position[1]) + + + message = "📊 Отчет о продажах\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Пользователи: 🔶\n" \ + f"👤 Пользователей: {len(get_users)}\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Средства 🔶\n" \ + f"💸 Продаж за 24 часа: {show_profit_day}₽\n" \ + f"💸 Продаж за неделю: {show_profit_week}₽\n" \ + f"💸 Продаж за всё время: {show_profit_all}₽\n" \ + f"💳 Средств на балансах пользователей: {show_money_users}₽\n" \ + f"💳 Средств на балансах продавцов: {show_money_sellers}₽\n" \ + f"💰 Пополнений за 24 часа: {show_refill_day}₽\n" \ + f"💰 Пополнений за неделю: {show_refill_week}₽\n" \ + f"💰 Пополнений за всё время: {show_refill_all}₽\n" \ + f"➖➖➖➖➖➖➖➖➖➖➖➖➖\n" \ + f"🔶 Прочее 🔶\n" \ + f"🎁 Товаров: {len(get_items)}шт\n" \ + f"📁 Позиций: {len(get_positions)}шт\n" \ + f"🗃 Категорий: {len(get_categories)}шт\n" \ + f"🎁 Продано товаров: {show_buy_items}шт\n" + + return message + +