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, '
❗ Данное сообщение видят только администраторы бота.
",
+ 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
+
+