Files
crm.clientright.ru/check_exec_list_statuses.php
Fedor da407a3294 Добавлен автоматический чекер статусов заявлений на исполнительный лист
- Создан скрипт check_exec_list_statuses.php
- Находит проекты со статусами: заявление на лист, выдача листа, исполнительное производство
- Проверяет наличие регистрационного номера (cf_2429) и отсутствие номера листа (cf_1752)
- Запрашивает статус через GetCourtStatus.php API
- Создает комментарии в проектах от ИИ Клиентправ (ID 23)
- Комментарии содержат полную историю движения дела и список документов
- Обработка таймаутов и ошибок API
- Подробное логирование в logs/auto_status_checker.log
- Добавлена документация AUTO_STATUS_CHECKER_README.md
- Готов к запуску через cron для автоматической проверки
2025-10-16 19:37:49 +03:00

237 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/*********************************************************************************
* Автоматическая проверка статусов заявлений на исполнительный лист
*
* Этот скрипт:
* 1. Находит проекты со статусами: "заявление на лист", "выдача листа", "исполнительное производство"
* 2. У которых есть регистрационный номер заявления (cf_2429)
* 3. Но НЕТ номера исполнительного листа (cf_1752)
* 4. Проверяет статус через API Debexpert
* 5. Извлекает исполнительные листы из ответа
* 6. Сохраняет их в проект
* 7. Обновляет поля проекта
********************************************************************************/
error_reporting(E_ALL);
ini_set('display_errors', '1');
// Устанавливаем рабочую директорию
chdir(__DIR__);
require_once 'config.inc.php';
require_once 'include/utils/utils.php';
require_once 'includes/Loader.php';
vimport('includes.runtime.Globals');
require_once 'include/database/PearDatabase.php';
require_once 'modules/Users/Users.php';
$adb = PearDatabase::getInstance();
// Логирование
function log_status_check($level, $message) {
$log_file = 'logs/auto_status_checker.log';
$timestamp = date('Y-m-d H:i:s');
$log_entry = "{$timestamp} - {$level}: {$message}\n";
file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
echo $log_entry;
}
log_status_check('INFO', "========== Начало автоматической проверки статусов ==========");
// 1. Получаем проекты, которые нужно проверить
$query = "
SELECT
p.projectid,
p.projectname,
p.projectstatus,
cf.cf_2429 AS reg_number_exec_list,
cf.cf_1752 AS exec_list_number,
cf.cf_2204 AS reg_number_claim
FROM vtiger_project p
JOIN vtiger_crmentity e ON e.crmid = p.projectid
JOIN vtiger_projectcf cf ON cf.projectid = p.projectid
WHERE e.deleted = 0
AND cf.cf_2429 IS NOT NULL
AND cf.cf_2429 != ''
AND p.projectstatus IN ('заявление на лист', 'выдача листа', 'исполнительное производство')
AND (cf.cf_1752 IS NULL OR cf.cf_1752 = '' OR cf.cf_1752 = '0')
ORDER BY p.projectid DESC
LIMIT 50
";
$result = $adb->pquery($query, array());
$projectCount = $adb->num_rows($result);
log_status_check('INFO', "Найдено проектов для проверки: $projectCount");
if ($projectCount == 0) {
log_status_check('INFO', "Нет проектов для проверки. Завершение.");
exit(0);
}
// Счетчики
$successCount = 0;
$errorCount = 0;
$timeoutCount = 0;
$updatedCount = 0;
// 2. Проверяем каждый проект
for ($i = 0; $i < $projectCount; $i++) {
$projectId = $adb->query_result($result, $i, 'projectid');
$projectName = $adb->query_result($result, $i, 'projectname');
$projectStatus = $adb->query_result($result, $i, 'projectstatus');
$regNumber = $adb->query_result($result, $i, 'reg_number_exec_list');
log_status_check('INFO', "");
log_status_check('INFO', "[$i/$projectCount] Проект #$projectId: $projectName");
log_status_check('INFO', " Статус: $projectStatus");
log_status_check('INFO', " Рег. номер: $regNumber");
// Проверяем статус через API
$apiUrl = "https://crm.clientright.ru/GetCourtStatus.php?registrationId=" . urlencode($regNumber);
log_status_check('DEBUG', " Запрос к API: $apiUrl");
// Делаем запрос с таймаутом 120 секунд
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$apiResponse = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
// Парсим ответ
if ($apiResponse === false) {
log_status_check('ERROR', " ❌ Ошибка CURL: $curlError");
$errorCount++;
continue;
}
$responseData = json_decode($apiResponse, true);
if (!$responseData) {
log_status_check('ERROR', " ❌ Ошибка парсинга JSON");
$errorCount++;
continue;
}
// Проверяем статус ответа
if (isset($responseData['status']) && $responseData['status'] === 'ERROR') {
$errorMessage = $responseData['message'] ?? 'Unknown error';
// Проверяем, это таймаут или другая ошибка
if (strpos($errorMessage, 'timed out') !== false || strpos($errorMessage, 'timeout') !== false) {
log_status_check('WARNING', " ⏱️ Таймаут API");
$timeoutCount++;
} else {
log_status_check('ERROR', " ❌ Ошибка API: $errorMessage");
$errorCount++;
}
continue;
}
// Успешный ответ
if (isset($responseData['status']) && $responseData['status'] === 'OK' && isset($responseData['data']['data'])) {
$appealData = $responseData['data']['data'][0] ?? null;
if (!$appealData) {
log_status_check('WARNING', " ⚠️ Пустые данные в ответе");
continue;
}
$currentState = $appealData['current_state_text'] ?? 'Не указан';
$history = $appealData['history'] ?? [];
$court = $appealData['court']['ZNACHATR'] ?? 'Не указан';
log_status_check('SUCCESS', " ✅ Получен статус: $currentState");
log_status_check('INFO', " Суд: $court");
log_status_check('INFO', " Событий в истории: " . count($history));
$successCount++;
// 3. Формируем комментарий с полученными данными (без эмодзи для совместимости)
$commentText = "=== АВТОМАТИЧЕСКАЯ ПРОВЕРКА СТАТУСА ОБРАЩЕНИЯ ===\n\n";
$commentText .= "Регистрационный номер: $regNumber\n";
$commentText .= "Суд: $court\n";
$commentText .= "Текущий статус: $currentState\n\n";
$commentText .= "ИСТОРИЯ ДВИЖЕНИЯ ДЕЛА:\n\n";
foreach ($history as $idx => $historyItem) {
$num = $idx + 1;
$statusText = $historyItem['status_text'] ?? 'Нет описания';
$direction = $historyItem['direction'] ?? '';
$created = $historyItem['created'] ?? '';
$files = $historyItem['files'] ?? [];
$directionIcon = $direction === 'OUT' ? '[ИСХОДЯЩЕЕ]' : '[ВХОДЯЩЕЕ]';
$commentText .= "{$num}. {$directionIcon} {$statusText}\n";
$commentText .= " Дата: {$created}\n";
if (count($files) > 0) {
$commentText .= " Документы (" . count($files) . "):\n";
foreach ($files as $file) {
$fileName = $file['name'] ?? 'Без названия';
$fileComment = $file['comment'] ?? '';
$commentText .= "{$fileName}";
if ($fileComment) {
$commentText .= " ({$fileComment})";
}
$commentText .= "\n";
}
}
$commentText .= "\n";
}
$commentText .= "Дата проверки: " . date('d.m.Y H:i:s');
// 4. Создаем комментарий от имени AI Assistant (ID 23)
$ai_bot_userid = 23;
$date_var = date('Y-m-d H:i:s');
$comment_id = $adb->getUniqueID("vtiger_crmentity");
// Вставляем в crmentity (от AI Bot пользователя)
$sql = "INSERT INTO vtiger_crmentity (crmid, smcreatorid, smownerid, setype, description, createdtime, modifiedtime, presence, deleted)
VALUES(?, ?, ?, 'ModComments', '', ?, ?, 1, 0)";
$params = array($comment_id, $ai_bot_userid, $ai_bot_userid, $adb->formatDate($date_var, true), $adb->formatDate($date_var, true));
$adb->pquery($sql, $params);
// Вставляем в modcomments (от AI Bot, customer = 0, userid = AI Bot)
// Используем прямой SQL с экранированием для корректного сохранения текста
$mysqli = new mysqli('localhost', 'ci20465_72new', 'EcY979Rn', 'ci20465_72new');
$mysqli->set_charset('utf8');
$escapedComment = $mysqli->real_escape_string($commentText);
$sql = "INSERT INTO vtiger_modcomments (modcommentsid, commentcontent, related_to, customer, userid, reasontoedit, channel, parent_comments)
VALUES($comment_id, '$escapedComment', $projectId, 0, $ai_bot_userid, '', 'Court Status API', 0)";
$mysqli->query($sql);
$mysqli->close();
log_status_check('SUCCESS', " 💬 Комментарий создан (ID: $comment_id)");
$updatedCount++;
} else {
log_status_check('WARNING', " ⚠️ Неожиданный формат ответа");
$errorCount++;
}
// Небольшая задержка между запросами, чтобы не перегружать API
sleep(2);
}
// 4. Итоговая статистика
log_status_check('INFO', "");
log_status_check('INFO', "========== Завершение проверки ==========");
log_status_check('INFO', "Проверено проектов: $projectCount");
log_status_check('SUCCESS', "✅ Успешных запросов: $successCount");
log_status_check('ERROR', "❌ Ошибок: $errorCount");
log_status_check('WARNING', "⏱️ Таймаутов: $timeoutCount");
log_status_check('INFO', "💬 Создано комментариев: $updatedCount");
log_status_check('INFO', "========================================");
?>