Compare commits

...

13 Commits

Author SHA1 Message Date
652400e50f fix order module
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-26 23:01:02 +03:00
95195c2749 fix order module
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-26 22:54:46 +03:00
9979937113 fix drone file
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-26 22:44:54 +03:00
be80c4044b new inline button for order ,message "finish_work_on_order"
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone Build is passing
2025-09-26 22:34:45 +03:00
6549c3d70b fix state value
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-26 22:21:47 +03:00
cc520caef5 Merge branch 'master' into dev
Some checks reported errors
continuous-integration/drone/push Build was killed
# Conflicts:
#	drone.yaml
2025-09-26 21:29:27 +03:00
51eebcc165 fix env
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-26 21:20:31 +03:00
ffe5e2e938 update orders list message sending 2025-09-26 21:20:29 +03:00
77a00d7623 clear and fix database modul 2025-09-26 21:19:30 +03:00
369bd7a6e1 Revert "clear database_engine imports"
Some checks reported errors
continuous-integration/drone/push Build was killed
This reverts commit de9c0e6724.
2025-09-26 20:53:36 +03:00
8604774741 fix imports
Some checks failed
continuous-integration/drone/push Build is failing
update search_by_item and show_order
2025-09-26 20:43:02 +03:00
5f2a00ba4a fix env
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
2025-09-26 20:26:48 +03:00
355f81520c fix imports
Some checks failed
continuous-integration/drone/push Build is failing
change sending list of orders
2025-09-26 19:49:03 +03:00
6 changed files with 54 additions and 56 deletions

View File

@@ -4,6 +4,7 @@ from aiogram.fsm.state import State, StatesGroup
class SearchForm(StatesGroup):
search_option = State()
data_to_search = State()
sent_messages = State()
search_result = State()

View File

@@ -1,8 +1,8 @@
import os
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine, session
DATABASE_URL = (f"postgresql+asyncpg://{os.getenv('DB_USER')}:{os.getenv('DB_PASSWORD')}@"
f"{os.getenv('DB_HOST')}/{os.getenv('DATABASE')}")
engine = create_async_engine(DATABASE_URL, echo=True)
async_session_ = async_sessionmaker(bind=engine, expire_on_commit=False)

View File

@@ -1,33 +1,28 @@
import asyncio
import os
from pathlib import Path
import re
from pathlib import Path
from aiogram import Router, Bot, F
from aiogram.filters import CommandStart, Command
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery, FSInputFile, InputMediaPhoto, InputMediaVideo, ReplyKeyboardRemove
from aiogram.exceptions import AiogramError
from aiogram.fsm.state import State, StatesGroup
from aiogram.fsm.context import FSMContext
from sqlalchemy import select, insert
from sqlalchemy import select
from loguru import logger
from filters import IsAdmin
from keyboards import create_inline_kb, commands, button_create
from keyboards import create_inline_kb, button_create
from database import async_session_, Order, Worker
from FSM import SearchForm, OrderForm
orders_router = Router()
# orders_router.message.filter()
order_operation_base = {"add_order_photo": "Добавить фото",
"get_order_photo": "Получить фото",
"get_order_components": "Получить список комплектующих",
"get_order_documentation": "Получить документацию"
"get_order_documentation": "Получить документацию",
"finish_work_on_order": "❌ Закрыть"
}
order_operation_update = {"add_order_documentation": "Добавить документацию"}
order_main = {"find_orders": "Найти заказ"}
order_main = {"find_orders": "Найти заказ", "create_order": "Создать заказ"}
order_main_update = {"create_order": "Создать заказ"}
find_order_params = {"search_by_name": "Поиск по названию", "search_by_description": "Поиск по описанию ",
@@ -36,9 +31,9 @@ find_order_params = {"search_by_name": "Поиск по названию", "sear
@orders_router.message(Command(commands="orders"))
async def orders_menu(message: Message):
order_main_upd = order_main_update if await IsAdmin()(message) else {}
await message.answer(text="Доступные действия с заказами:",
reply_markup=create_inline_kb(width=1, **order_main, **order_main_upd))
reply_markup=create_inline_kb(width=1, **order_main))
await message.delete()
@orders_router.callback_query(lambda x: x.data.startswith("create_order"))
@@ -69,10 +64,6 @@ async def get_order_customer(callback: CallbackQuery, state: FSMContext):
await state.set_state(OrderForm.customer)
# @orders_router.callback_query(OrderForm.counterparty)
# async def get_order_customer(message: Message, state: FSMContext):
#
@orders_router.message(OrderForm.customer)
async def order_description(message: Message, state: FSMContext):
await message.answer("Введите описание заказа в виде ключевых слов (АВР, ПСС, НКУ и т.д.) )")
@@ -119,33 +110,30 @@ async def search_by_item(message: Message, state: FSMContext):
selected_orders = result.scalars().all()
if selected_orders:
await message.answer(text="Список найденных заказов: ",
reply_markup=create_inline_kb(width=1, **dict(
(f"show_order_{order.id}", f"Описание: {order.description or "Отсутствует"}"
f"Заказ: {order.id}\n"
f"Заказчик: {order.customer}\n"
) for order in
selected_orders)))
await state.update_data(search_result=selected_orders)
await message.answer(text="Список найденных заказов: ")
sent_messages = []
for order in selected_orders:
sent_messages.append(await message.answer(text=f"Номер заказа: {order.id}\n"
f"Заказчик: {order.customer}\n"
f"Статус: {order.status_id}\n"
f"Дата отгрузки: {order.end_work}\n"
f"Дата создания: {order.created_at}\n"
f"Описание: {order.description}",
reply_markup=create_inline_kb(width=1, **{
f"show_order_{order.id}": f"Заказ: №{order.id}"})))
await state.update_data(sent_messages=sent_messages)
await state.set_state(SearchForm.search_result)
await state.update_data(search_result=selected_orders)
else:
await message.answer(text="Заказов по вашему запросу не найдено")
await state.clear()
@orders_router.callback_query(SearchForm.search_result)
async def show_order(callback: CallbackQuery, state: FSMContext):
@orders_router.callback_query(SearchForm.search_result and (lambda x: "show_order_" in x.data))
async def show_order(callback: CallbackQuery, state: FSMContext, bot: Bot):
order_id = int(re.search(r"(\d+)", callback.data).group())
try:
async with async_session_() as local_session:
result = await local_session.execute(select(Order).filter(Order.id == order_id))
order = result.scalars().first()
except Exception as err:
logger.warning(err)
order_operation_upd = order_operation_update if await IsAdmin()(callback) else {}
orders = await state.get_value("search_result")
order = next(filter(lambda item: order_id == item.id, orders), None)
if order:
await callback.message.answer(text=f"Номер заказа: {order.id}\n"
@@ -155,21 +143,22 @@ async def show_order(callback: CallbackQuery, state: FSMContext):
f"Дата отгрузки: {order.end_work}\n"
f"Дата создания: {order.created_at}\n"
f"Описание: {order.description}",
reply_markup=create_inline_kb(width=2, **dict(
reply_markup=create_inline_kb(width=1, **dict(
(f"{clbk}_{order.id}", text) for clbk, text in order_operation_base.items()))
)
await callback.message.delete()
await state.clear()
for message in await state.get_value("sent_messages"):
await bot.delete_message(chat_id=callback.message.chat.id, message_id=message.message_id)
await state.clear()
@orders_router.callback_query(lambda x: x.data.startswith("get_order_photo"))
async def send_order_photos(callback: CallbackQuery, bot: Bot):
order_id = callback.data.split("_")[-1]
media_item: Path
media_group = []
os.makedirs(Path(f"./photos/{order_id}/"), exist_ok=True)
media_path = Path(f"./photos/{order_id}/").iterdir()
order_photos_path = Path(f"/app/photos/{order_id}/")
os.makedirs(order_photos_path, exist_ok=True)
media_path = order_photos_path.iterdir()
if not (media_item := next(media_path, None)):
text = f"Фото по заказу \"{order_id}\" отсутствуют "
else:
@@ -177,7 +166,7 @@ async def send_order_photos(callback: CallbackQuery, bot: Bot):
f"")
await bot.send_message(chat_id=callback.from_user.id, text=text)
while media_item or media_group:
if len(media_group) == 10 or (media_group and not media_item):
if len(media_group) == 10 or not media_item:
await bot.send_media_group(chat_id=callback.from_user.id, media=media_group)
media_group.clear()
if media_item:
@@ -188,8 +177,10 @@ async def send_order_photos(callback: CallbackQuery, bot: Bot):
logger.error(f"Ошибка при обработке {media_path}: {err}")
media_item = next(media_path, None)
await asyncio.sleep(600)
await callback.message.delete()
try:
pass
except:
pass
@orders_router.callback_query(lambda x: x.data.startswith("add_order_photo"))
@@ -204,7 +195,7 @@ async def reply_for_photo(callback: CallbackQuery, bot: Bot):
F.reply_to_message)
async def add_order_photo(message: Message, bot: Bot):
order_id = re.search(r"(\d+)", message.reply_to_message.text).group()
order_photos_path = f"/app/photos/{order_id}/"
order_photos_path = Path(f"/app/photos/{order_id}/")
os.makedirs(order_photos_path, exist_ok=True)
item = message.video or message.photo[-1]
@@ -224,3 +215,8 @@ async def add_order_photo(message: Message, bot: Bot):
await bot.delete_message(chat_id=message.chat.id, message_id=message.reply_to_message.message_id)
except:
pass
@orders_router.callback_query(F.data.startswith("finish_work_on_order"))
async def finish_work_on_order(callback: CallbackQuery):
await callback.message.delete()

View File

@@ -20,7 +20,7 @@ user_info_template = ("Новый пользователь ждет регист
"Юзернейм: @{}\n"
"ID: @msg_{}\n")
admins_ids = list(map(int, os.getenv("BOT_ADMINS").split(",")))
@registration_router.message(CommandStart())
@@ -33,7 +33,7 @@ async def start_command(message: Message, bot: Bot):
dict_for_inline = {f'reg_@{user.id}': 'Allow', f'del_@{user.id}': 'Reject'}
user_info = user_info_template.format(user.first_name, user.last_name if user.last_name else 'Не указана',
user.username if user.username else 'Не указан', user.id)
for admin in admins_ids:
for admin in list(map(int, os.getenv("BOT_ADMINS").split(","))):
try:
await bot.send_message(chat_id=admin, text=user_info)
await bot.send_message(chat_id=admin, text='Зарегистрировать пользователя',

View File

@@ -1,12 +1,14 @@
import os
import asyncio
from dotenv import load_dotenv
load_dotenv(".env")
from aiogram import Dispatcher, Bot
from handlers import *
from keyboards import set_main_menu
from middlewares import SessionMiddleware
load_dotenv(".env")
bot = Bot(token=os.getenv("TOKEN"))

View File

@@ -17,7 +17,7 @@ steps:
- name: dockersock
path: /var/run/docker.sock
commands:
- docker build -t myapp:${DRONE_COMMIT_BRANCH} .
- docker build -t myapp:${DRONE_COMMIT_SHA} .
- name: deploy
image: docker
@@ -40,10 +40,9 @@ steps:
DB_PASSWORD:
from_secret: DB_PASSWORD
commands:
- echo "$ENV_CONTENT" > .env
- docker stop myapp || true
- docker rm myapp || true
- docker run --name=myapp --network=prod_net -v /srv/prod/telegram_bot/photos:/app/photos/ -v /srv/prod/telegram_bot/.env:/app/.env:ro myapp:${DRONE_COMMIT_BRANCH}
- docker run --name=myapp -d --network=prod_net -v /srv/prod/telegram_bot/photos:/app/photos/ -v /srv/prod/telegram_bot/.env:/app/.env:ro myapp:${DRONE_COMMIT_SHA}
volumes: