2025-10-16 19:37:49 +03:00
|
|
|
|
<?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++;
|
|
|
|
|
|
|
2025-10-16 19:54:07 +03:00
|
|
|
|
// 3. Формируем комментарий с полученными данными
|
|
|
|
|
|
$commentText = "АВТОМАТИЧЕСКАЯ ПРОВЕРКА СТАТУСА ОБРАЩЕНИЯ\n\n";
|
2025-10-16 19:37:49 +03:00
|
|
|
|
$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)
|
2025-10-16 19:54:07 +03:00
|
|
|
|
VALUES($comment_id, '$escapedComment', $projectId, 0, $ai_bot_userid, '', 'Telegram AI Bot', 0)";
|
2025-10-16 19:37:49 +03:00
|
|
|
|
$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', "========================================");
|
|
|
|
|
|
|
|
|
|
|
|
?>
|
|
|
|
|
|
|