feat: добавлена валидация при массовой генерации XML
- Каждая отгрузка теперь валидируется перед генерацией - При наличии критических ошибок валидации создается текстовый отчет - Отчет содержит: * Список отгрузок с критическими ошибками * Детальное описание каждой ошибки * Отгрузки не найденные в системе * Ошибки обработки * Список успешно прошедших валидацию - Отгрузки с ошибками исключаются из генерации XML - Успешно прошедшие валидацию отгрузки обрабатываются как обычно - Улучшена обработка ошибок и информативность сообщений
This commit is contained in:
parent
b29bf9a354
commit
7866009e24
141
bot.py
141
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"❌ <b>Обнаружены ошибки валидации</b>\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 = (
|
||||
"❌ <b>Не удалось обработать ни одной отгрузки</b>\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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user