diff --git a/bot.py b/bot.py
index b33fe4f..c4875ce 100644
--- a/bot.py
+++ b/bot.py
@@ -11,6 +11,7 @@ import os
import sys
import logging
from pathlib import Path
+from datetime import datetime
from telegram import (
Update,
@@ -1426,10 +1427,14 @@ async def batch_generation_process(
try:
moysklad_client = get_moysklad_client(user_id)
- # Сбор данных по всем отгрузкам
+ # Сбор данных по всем отгрузкам с валидацией
+ from modules.validator import OrderValidator, ValidationLevel
+ validator = OrderValidator()
+
orders_data = []
not_found = []
errors = []
+ validation_errors = {} # Словарь {order_num: [список ошибок]}
for idx, order_num in enumerate(order_numbers, 1):
try:
@@ -1455,13 +1460,141 @@ async def batch_generation_process(
# Получаем полные данные
order_data = moysklad_client.get_full_order_data(order_id)
- orders_data.append(order_data)
+
+ # ВАЛИДАЦИЯ заказа
+ validation_results = validator.validate_order(order_data)
+
+ # Проверяем наличие критических ошибок
+ critical_errors = [
+ r for r in validation_results
+ if r.level == ValidationLevel.CRITICAL
+ ]
+
+ if critical_errors:
+ # Сохраняем ошибки для отчета
+ validation_errors[order_num] = [
+ f"{r.field}: {r.message}"
+ for r in critical_errors
+ ]
+ logger.warning(
+ f"Отгрузка {order_num} не прошла валидацию: "
+ f"{len(critical_errors)} критических ошибок"
+ )
+ else:
+ # Валидация пройдена - добавляем к обработке
+ orders_data.append(order_data)
except Exception as e:
logger.error(f"Ошибка обработки {order_num}: {e}")
errors.append(f"{order_num}: {str(e)[:50]}")
- # Проверка результатов
+ # Если есть ошибки валидации, отправляем текстовый отчет
+ if validation_errors:
+ # Создаём текстовый файл с ошибками
+ report_lines = [
+ "ОТЧЕТ О ВАЛИДАЦИИ ОТГРУЗОК",
+ "=" * 50,
+ f"Дата: {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}",
+ f"Всего обработано: {len(order_numbers)}",
+ f"С ошибками валидации: {len(validation_errors)}",
+ "",
+ "КРИТИЧЕСКИЕ ОШИБКИ ВАЛИДАЦИИ:",
+ ""
+ ]
+
+ for order_num, err_list in validation_errors.items():
+ report_lines.append(f"Отгрузка: {order_num}")
+ report_lines.append("-" * 40)
+ for err in err_list:
+ report_lines.append(f" • {err}")
+ report_lines.append("")
+
+ # Добавляем информацию о не найденных
+ if not_found:
+ report_lines.append("")
+ report_lines.append("НЕ НАЙДЕНЫ:")
+ report_lines.append("-" * 40)
+ for order_num in not_found:
+ report_lines.append(f" • {order_num}")
+ report_lines.append("")
+
+ # Добавляем прочие ошибки
+ if errors:
+ report_lines.append("")
+ report_lines.append("ОШИБКИ ОБРАБОТКИ:")
+ report_lines.append("-" * 40)
+ for err in errors:
+ report_lines.append(f" • {err}")
+ report_lines.append("")
+
+ # Статистика успешных
+ if orders_data:
+ report_lines.append("")
+ report_lines.append(
+ f"Успешно прошли валидацию: {len(orders_data)}"
+ )
+ report_lines.append("-" * 40)
+ for order_data in orders_data:
+ order_name = order_data['order'].get('name', 'N/A')
+ report_lines.append(f" ✓ {order_name}")
+
+ # Сохраняем в файл
+ output_dir = Path("temp_documents")
+ output_dir.mkdir(exist_ok=True)
+ timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
+ report_filename = f"validation_errors_{timestamp}.txt"
+ report_path = output_dir / report_filename
+
+ with open(report_path, 'w', encoding='utf-8') as f:
+ f.write('\n'.join(report_lines))
+
+ # Формируем сообщение
+ error_msg = (
+ f"❌ Обнаружены ошибки валидации\n\n"
+ f"📊 Статистика:\n"
+ f" • Обработано: {len(order_numbers)}\n"
+ f" • С ошибками: {len(validation_errors)}\n"
+ )
+ if orders_data:
+ error_msg += f" • Прошли валидацию: {len(orders_data)}\n"
+ if not_found:
+ error_msg += f" • Не найдено: {len(not_found)}\n"
+
+ error_msg += (
+ "\n⚠️ Отгрузки с ошибками валидации не будут обработаны.\n"
+ "Подробный отчет во вложенном файле."
+ )
+
+ await progress_msg.edit_text(
+ error_msg,
+ parse_mode='HTML'
+ )
+
+ # Отправляем файл с ошибками
+ with open(report_path, 'rb') as f:
+ await update.message.reply_document(
+ document=f,
+ filename=report_filename,
+ caption=(
+ "📄 Отчет об ошибках валидации\n\n"
+ "Исправьте указанные ошибки в МойСклад "
+ "и повторите генерацию."
+ ),
+ parse_mode='HTML'
+ )
+
+ # Удаляем временный файл
+ os.remove(report_path)
+
+ # Если нет ни одной валидной отгрузки - завершаем
+ if not orders_data:
+ await update.message.reply_text(
+ "Попробуйте ещё раз или вернитесь в главное меню:",
+ reply_markup=get_main_keyboard()
+ )
+ return MAIN_MENU
+
+ # Проверка результатов (если совсем ничего не найдено)
if not orders_data:
error_text = (
"❌ Не удалось обработать ни одной отгрузки\n\n"
@@ -1469,7 +1602,7 @@ async def batch_generation_process(
if not_found:
error_text += f"Не найдено: {', '.join(not_found)}\n"
if errors:
- error_text += f"\nОшибки:\n" + "\n".join(errors[:5])
+ error_text += "\nОшибки:\n" + "\n".join(errors[:5])
await progress_msg.edit_text(
error_text,