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,