diff --git a/bot.py b/bot.py
index 282539b..b33fe4f 100644
--- a/bot.py
+++ b/bot.py
@@ -56,8 +56,9 @@ logger = logging.getLogger(__name__)
SELECT_FORMAT,
SELECT_TEMPLATE,
DOWNLOAD_DOCUMENT,
- BATCH_INPUT
-) = range(11)
+ BATCH_INPUT,
+ BATCH_FORMAT_CHOICE
+) = range(12)
# Менеджер пользователей
user_manager = UserManager()
@@ -1307,8 +1308,7 @@ async def batch_generation_prompt(
"Примеры:\n"
" 4926,4927,4928\n"
" 00001,00002,00003\n\n"
- "⚠️ Все отгрузки будут объединены в один XML файл "
- "(EnterpriseData 1.20).",
+ "Максимум 50 отгрузок за раз.",
parse_mode='HTML',
reply_markup=ReplyKeyboardMarkup(
[["⬅️ Назад"]],
@@ -1319,11 +1319,11 @@ async def batch_generation_prompt(
return BATCH_INPUT
-async def batch_generation_process(
+async def batch_format_choice(
update: Update,
context: ContextTypes.DEFAULT_TYPE
):
- """Обработка массовой генерации"""
+ """Выбор формата генерации: один файл или множество"""
user_id = update.effective_user.id
text = update.message.text.strip()
@@ -1354,9 +1354,72 @@ async def batch_generation_process(
)
return BATCH_INPUT
+ # Сохраняем номера в контекст
+ context.user_data['batch_order_numbers'] = order_numbers
+
+ # Предлагаем выбор формата
+ keyboard = [
+ ["📄 Один файл (все документы)"],
+ ["📑 Отдельные файлы (каждый документ)"],
+ ["⬅️ Назад"]
+ ]
+
+ await update.message.reply_text(
+ f"✅ Будет обработано отгрузок: {len(order_numbers)}\n\n"
+ "Выберите формат генерации:",
+ parse_mode='HTML',
+ reply_markup=ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
+ )
+
+ return BATCH_FORMAT_CHOICE
+
+
+async def batch_generation_process(
+ update: Update,
+ context: ContextTypes.DEFAULT_TYPE
+):
+ """Обработка массовой генерации"""
+ user_id = update.effective_user.id
+ text = update.message.text.strip()
+
+ # Проверка на отмену
+ if text == "⬅️ Назад":
+ await update.message.reply_text(
+ "Массовая генерация отменена.",
+ reply_markup=get_main_keyboard()
+ )
+ return MAIN_MENU
+
+ # Определяем режим генерации
+ if text == "📄 Один файл (все документы)":
+ batch_mode = True
+ elif text == "📑 Отдельные файлы (каждый документ)":
+ batch_mode = False
+ else:
+ await update.message.reply_text(
+ "❌ Неверный выбор. Попробуйте ещё раз:",
+ parse_mode='HTML'
+ )
+ return BATCH_FORMAT_CHOICE
+
+ # Получаем сохранённые номера
+ order_numbers = context.user_data.get('batch_order_numbers', [])
+ if not order_numbers:
+ await update.message.reply_text(
+ "❌ Ошибка: номера отгрузок не найдены. "
+ "Начните заново.",
+ reply_markup=get_main_keyboard()
+ )
+ return MAIN_MENU
+
# Уведомление о начале обработки
+ mode_text = (
+ "один общий файл" if batch_mode
+ else f"{len(order_numbers)} отдельных файлов"
+ )
progress_msg = await update.message.reply_text(
f"⏳ Обработка {len(order_numbers)} отгрузок...\n"
+ f"Режим: {mode_text}\n\n"
f"Это может занять некоторое время."
)
@@ -1372,7 +1435,8 @@ async def batch_generation_process(
try:
# Обновляем прогресс
await progress_msg.edit_text(
- f"⏳ Обработка отгрузки {idx}/{len(order_numbers)}: {order_num}"
+ f"⏳ Обработка отгрузки {idx}/{len(order_numbers)}: "
+ f"{order_num}"
)
# Поиск отгрузки
@@ -1399,7 +1463,9 @@ async def batch_generation_process(
# Проверка результатов
if not orders_data:
- error_text = "❌ Не удалось обработать ни одной отгрузки\n\n"
+ error_text = (
+ "❌ Не удалось обработать ни одной отгрузки\n\n"
+ )
if not_found:
error_text += f"Не найдено: {', '.join(not_found)}\n"
if errors:
@@ -1428,39 +1494,89 @@ async def batch_generation_process(
output_dir = Path("temp_documents")
output_dir.mkdir(exist_ok=True)
- # Генерируем пакетный XML
- xml_filename = f"batch_{len(orders_data)}_orders.xml"
- xml_path = str(output_dir / xml_filename)
- xml_gen.generate_batch_realization(orders_data, xml_path)
-
- # Формируем отчёт
- order_names = [
- od['order'].get('name', 'N/A')
- for od in orders_data
- ]
-
- caption = (
- f"✅ Пакетный XML создан!\n\n"
- f"📦 Документов: {len(orders_data)}\n"
- f"📋 Отгрузки: {', '.join(order_names)}\n\n"
- )
-
- if not_found:
- caption += f"⚠️ Не найдено: {', '.join(not_found)}\n"
- if errors:
- caption += f"⚠️ Ошибок: {len(errors)}\n"
-
- caption += "\n📄 Формат: 1С EnterpriseData 1.20"
-
- # Отправляем файл
- await update.message.reply_document(
- document=open(xml_path, 'rb'),
- caption=caption,
- parse_mode='HTML'
- )
-
- # Удаляем временный файл
- os.remove(xml_path)
+ if batch_mode:
+ # ОДИН ФАЙЛ - все документы в одном XML
+ xml_filename = f"batch_{len(orders_data)}_orders.xml"
+ xml_path = str(output_dir / xml_filename)
+ xml_gen.generate_batch_realization(orders_data, xml_path)
+
+ # Формируем отчёт
+ order_names = [
+ od['order'].get('name', 'N/A')
+ for od in orders_data
+ ]
+
+ caption = (
+ f"✅ Пакетный XML создан!\n\n"
+ f"📦 Документов: {len(orders_data)}\n"
+ f"📋 Отгрузки: {', '.join(order_names)}\n\n"
+ )
+
+ if not_found:
+ caption += f"⚠️ Не найдено: {', '.join(not_found)}\n"
+ if errors:
+ caption += f"⚠️ Ошибок: {len(errors)}\n"
+
+ caption += "\n📄 Формат: 1С EnterpriseData 1.20"
+
+ # Отправляем файл
+ await update.message.reply_document(
+ document=open(xml_path, 'rb'),
+ caption=caption,
+ parse_mode='HTML'
+ )
+
+ # Удаляем временный файл
+ os.remove(xml_path)
+
+ else:
+ # МНОЖЕСТВО ФАЙЛОВ - каждый документ отдельно
+ generated_files = []
+
+ for idx, order_data in enumerate(orders_data, 1):
+ order_name = order_data['order'].get('name', f'order_{idx}')
+ xml_filename = f"order_{order_name}.xml"
+ xml_path = str(output_dir / xml_filename)
+
+ # Генерируем отдельный XML
+ xml_gen.generate_realization(order_data, xml_path)
+ generated_files.append((xml_path, order_name))
+
+ # Отправляем все файлы
+ await progress_msg.edit_text(
+ f"✅ Сгенерировано {len(generated_files)} файлов\n"
+ f"⏳ Отправка..."
+ )
+
+ for xml_path, order_name in generated_files:
+ caption = (
+ f"📄 Отгрузка {order_name}\n"
+ f"Формат: 1С EnterpriseData 1.20"
+ )
+
+ await update.message.reply_document(
+ document=open(xml_path, 'rb'),
+ caption=caption,
+ parse_mode='HTML'
+ )
+
+ # Удаляем временный файл
+ os.remove(xml_path)
+
+ # Итоговая статистика
+ summary = (
+ f"✅ Массовая генерация завершена!\n\n"
+ f"📦 Отправлено файлов: {len(generated_files)}\n"
+ )
+ if not_found:
+ summary += f"⚠️ Не найдено: {', '.join(not_found)}\n"
+ if errors:
+ summary += f"⚠️ Ошибок: {len(errors)}\n"
+
+ await update.message.reply_text(
+ summary,
+ parse_mode='HTML'
+ )
# Показываем главное меню
await update.message.reply_text(
@@ -1470,6 +1586,9 @@ async def batch_generation_process(
await progress_msg.delete()
+ # Очищаем контекст
+ context.user_data.pop('batch_order_numbers', None)
+
return MAIN_MENU
except Exception as e:
@@ -1580,6 +1699,12 @@ def main():
MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text),
],
BATCH_INPUT: [
+ MessageHandler(
+ filters.TEXT & ~filters.COMMAND,
+ batch_format_choice
+ ),
+ ],
+ BATCH_FORMAT_CHOICE: [
MessageHandler(
filters.TEXT & ~filters.COMMAND,
batch_generation_process