feat: Интеграция уведомлений для событий судов
- Добавлена поддержка project_id в parscourt.php для создания уведомлений - Создана система парсеров судов (BaseCourtParser, MoscowCourtParser, RegionalCourtParser) - Интегрирован Browserless для парсинга московских судов (mos-sud.ru, mos-gorsud.ru) - Добавлены уведомления VDNotifierPro при обнаружении новых событий судов - Создан ParseAndCreateEvent.php для интеграции с CRM workflow - Создан CreateCourtEvent_v2.php для прямого создания событий в календаре CRM - Поддержка проверки дубликатов событий (можно отключить для тестирования) - Автоматическое определение типа суда и выбор подходящего парсера Функции: - Парсинг региональных судов (*.sudrf.ru) через HTML - Парсинг московских судов через Browserless API - Создание событий в CRM календаре с привязкой к проектам - Уведомления ответственных пользователей о новых событиях - Сохранение событий в таблицу subject для истории
This commit is contained in:
305
CreateCourtEvent_v2.php
Normal file
305
CreateCourtEvent_v2.php
Normal file
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
/**
|
||||
* Создание события в календаре CRM для судебного заседания (версия 2 - через SQL)
|
||||
*
|
||||
* Принимает POST запрос с данными:
|
||||
* - project_id: ID проекта (обязательно)
|
||||
* - event_name: Название события
|
||||
* - event_date: Дата события (формат DD.MM.YYYY)
|
||||
* - event_time: Время события (формат HH:MM)
|
||||
* - location: Место проведения
|
||||
* - result: Результат события
|
||||
* - basis: Основание
|
||||
* - note: Примечание
|
||||
* - publication_date: Дата размещения
|
||||
*/
|
||||
|
||||
// Устанавливаем рабочую директорию
|
||||
chdir(__DIR__);
|
||||
|
||||
// Логирование
|
||||
function log_event($level, $message) {
|
||||
$log_file = 'logs/create_court_event.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);
|
||||
}
|
||||
|
||||
// Функция для форматирования даты в формат CRM (YYYY-MM-DD)
|
||||
function formatDateForCRM($dateString) {
|
||||
if (empty($dateString)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Если формат DD.MM.YYYY
|
||||
if (preg_match('/^(\d{2})\.(\d{2})\.(\d{4})$/', $dateString, $matches)) {
|
||||
return $matches[3] . '-' . $matches[2] . '-' . $matches[1];
|
||||
}
|
||||
|
||||
// Если уже в формате YYYY-MM-DD
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $dateString)) {
|
||||
return $dateString;
|
||||
}
|
||||
|
||||
return $dateString;
|
||||
}
|
||||
|
||||
// Функция для форматирования времени в формат CRM (HH:MM:SS)
|
||||
function formatTimeForCRM($timeString) {
|
||||
if (empty($timeString)) {
|
||||
return '10:00:00'; // Время по умолчанию
|
||||
}
|
||||
|
||||
// Если формат HH:MM
|
||||
if (preg_match('/^(\d{1,2}):(\d{2})$/', $timeString, $matches)) {
|
||||
return sprintf('%02d:%02d:00', $matches[1], $matches[2]);
|
||||
}
|
||||
|
||||
// Если уже в формате HH:MM:SS
|
||||
if (preg_match('/^\d{2}:\d{2}:\d{2}$/', $timeString)) {
|
||||
return $timeString;
|
||||
}
|
||||
|
||||
return '10:00:00';
|
||||
}
|
||||
|
||||
try {
|
||||
log_event('INFO', '=== НАЧАЛО ОБРАБОТКИ ЗАПРОСА ===');
|
||||
|
||||
// Получаем данные из stdin
|
||||
$input = file_get_contents('php://stdin');
|
||||
if (!empty($input)) {
|
||||
log_event('DEBUG', "Входные данные из stdin: " . $input);
|
||||
$data = json_decode($input, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new Exception('Ошибка декодирования JSON: ' . json_last_error_msg());
|
||||
}
|
||||
} else {
|
||||
// Если stdin пустой, используем $_POST
|
||||
$data = $_POST;
|
||||
log_event('DEBUG', "Используем \$_POST: " . json_encode($data, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
// Проверяем обязательные параметры
|
||||
if (empty($data['project_id'])) {
|
||||
throw new Exception('Параметр project_id обязателен');
|
||||
}
|
||||
|
||||
$projectId = intval($data['project_id']);
|
||||
|
||||
// Извлекаем данные события
|
||||
$eventName = $data['event_name'] ?? 'Судебное заседание';
|
||||
$eventDate = $data['event_date'] ?? '';
|
||||
$eventTime = $data['event_time'] ?? '';
|
||||
$location = $data['location'] ?? '';
|
||||
$result = $data['result'] ?? '';
|
||||
$basis = $data['basis'] ?? '';
|
||||
$note = $data['note'] ?? '';
|
||||
$publicationDate = $data['publication_date'] ?? '';
|
||||
|
||||
log_event('INFO', "Создаем событие для проекта: $projectId");
|
||||
log_event('DEBUG', "Название: '$eventName', Дата: '$eventDate', Время: '$eventTime'");
|
||||
log_event('DEBUG', "Полные входные данные: " . json_encode($data, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
// Проверяем что дата не пустая
|
||||
if (empty($eventDate)) {
|
||||
throw new Exception('Дата события обязательна');
|
||||
}
|
||||
|
||||
// Подключаемся к базе данных
|
||||
$mysqli = new mysqli('localhost', 'ci20465_72new', 'EcY979Rn', 'ci20465_72new');
|
||||
if ($mysqli->connect_error) {
|
||||
throw new Exception('Не удалось подключиться к БД: ' . $mysqli->connect_error);
|
||||
}
|
||||
$mysqli->set_charset('utf8mb4');
|
||||
|
||||
// Получаем данные проекта
|
||||
$query = "SELECT e.smownerid, p.projectname, p.linktoaccountscontacts FROM vtiger_crmentity e
|
||||
JOIN vtiger_project p ON p.projectid = e.crmid
|
||||
WHERE e.crmid = ? AND e.deleted = 0";
|
||||
$stmt = $mysqli->prepare($query);
|
||||
$stmt->bind_param('i', $projectId);
|
||||
$stmt->execute();
|
||||
$result_query = $stmt->get_result();
|
||||
|
||||
if ($result_query->num_rows === 0) {
|
||||
throw new Exception("Проект $projectId не найден");
|
||||
}
|
||||
|
||||
$row = $result_query->fetch_assoc();
|
||||
$ownerId = $row['smownerid'];
|
||||
$projectName = $row['projectname'];
|
||||
$contactId = $row['linktoaccountscontacts'] ?? null;
|
||||
|
||||
log_event('DEBUG', "Владелец проекта: $ownerId, Название: $projectName, Контакт: " . ($contactId ?? 'нет'));
|
||||
|
||||
// Форматируем дату и время для CRM
|
||||
$formattedDate = formatDateForCRM($eventDate);
|
||||
$formattedTime = formatTimeForCRM($eventTime);
|
||||
$formattedDateTime = $formattedDate . ' ' . $formattedTime;
|
||||
|
||||
// Вычисляем время окончания (+1 час)
|
||||
$endDateTime = date('Y-m-d H:i:s', strtotime($formattedDateTime) + 3600);
|
||||
|
||||
log_event('DEBUG', "Дата начала: $formattedDateTime, Дата окончания: $endDateTime");
|
||||
|
||||
// Определяем тип события и статус - используем настройки как в workflow 3 (блок 18)
|
||||
$activityType = 'судебное заседание';
|
||||
$eventstatus = 'Planned'; // Запланировано (как в workflow)
|
||||
|
||||
log_event('DEBUG', "Установлен тип 'судебное заседание' и статус 'Planned' (как в workflow 3)");
|
||||
|
||||
// Формируем тему события с названием проекта
|
||||
$eventSubject = $eventName;
|
||||
if (!empty($projectName)) {
|
||||
$eventSubject = "[$projectName] $eventName";
|
||||
}
|
||||
|
||||
log_event('DEBUG', "Тип события: $activityType, Статус: $eventstatus, Тема: $eventSubject");
|
||||
|
||||
// Формируем описание события
|
||||
$description = "Автоматически созданное событие из судебного дела\n\n";
|
||||
|
||||
if (!empty($location)) {
|
||||
$description .= "Место: $location\n";
|
||||
}
|
||||
|
||||
if (!empty($result)) {
|
||||
$description .= "Результат: $result\n";
|
||||
}
|
||||
|
||||
if (!empty($basis)) {
|
||||
$description .= "Основание: $basis\n";
|
||||
}
|
||||
|
||||
if (!empty($note)) {
|
||||
$description .= "Примечание: $note\n";
|
||||
}
|
||||
|
||||
if (!empty($publicationDate)) {
|
||||
$description .= "Дата размещения: $publicationDate\n";
|
||||
}
|
||||
|
||||
// Получаем следующий ID
|
||||
$result_id = $mysqli->query("SELECT MAX(crmid) as max_id FROM vtiger_crmentity");
|
||||
$row_id = $result_id->fetch_assoc();
|
||||
$eventId = ($row_id['max_id'] ?? 0) + 1;
|
||||
|
||||
log_event('DEBUG', "Новый ID события: $eventId");
|
||||
|
||||
$created_time = date('Y-m-d H:i:s');
|
||||
|
||||
// Создаем запись в vtiger_crmentity
|
||||
$sql = "INSERT INTO vtiger_crmentity (crmid, smcreatorid, smownerid, modifiedby, setype, description, createdtime, modifiedtime, presence, deleted, label)
|
||||
VALUES (?, ?, ?, ?, 'Calendar', ?, ?, ?, 1, 0, ?)";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param('iiiissss', $eventId, $ownerId, $ownerId, $ownerId, $description, $created_time, $created_time, $eventSubject);
|
||||
$stmt->execute();
|
||||
|
||||
log_event('DEBUG', "Запись в vtiger_crmentity создана");
|
||||
|
||||
// Создаем запись в vtiger_activity
|
||||
$visibility = 'Public';
|
||||
|
||||
$endTime = date('H:i:s', strtotime($formattedDateTime) + 3600);
|
||||
|
||||
$sql = "INSERT INTO vtiger_activity (activityid, subject, activitytype, date_start, time_start, due_date, time_end, location, visibility, eventstatus)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param('isssssssss', $eventId, $eventSubject, $activityType, $formattedDate, $formattedTime, $formattedDate,
|
||||
$endTime, $location, $visibility, $eventstatus);
|
||||
$stmt->execute();
|
||||
|
||||
log_event('DEBUG', "Запись в vtiger_activity создана");
|
||||
|
||||
// Связываем событие с проектом (vtiger_seactivityrel)
|
||||
$sql = "INSERT INTO vtiger_seactivityrel (crmid, activityid) VALUES (?, ?)";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param('ii', $projectId, $eventId);
|
||||
$stmt->execute();
|
||||
|
||||
log_event('SUCCESS', "Событие привязано к проекту в vtiger_seactivityrel");
|
||||
|
||||
// Связываем событие с проектом через общую таблицу связей (vtiger_crmentityrel)
|
||||
// Это ключевая связь для отображения события в интерфейсе проекта!
|
||||
$sql = "INSERT INTO vtiger_crmentityrel (crmid, module, relcrmid, relmodule) VALUES (?, 'Project', ?, 'Calendar')";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param('ii', $projectId, $eventId);
|
||||
$stmt->execute();
|
||||
|
||||
log_event('SUCCESS', "Событие привязано к проекту в vtiger_crmentityrel (для отображения в UI)");
|
||||
|
||||
// Связываем событие с контактом (если контакт указан в проекте)
|
||||
if (!empty($contactId) && $contactId > 0) {
|
||||
$sql = "INSERT INTO vtiger_cntactivityrel (contactid, activityid) VALUES (?, ?)";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param('ii', $contactId, $eventId);
|
||||
$stmt->execute();
|
||||
log_event('SUCCESS', "Событие привязано к контакту: $contactId");
|
||||
} else {
|
||||
log_event('DEBUG', "Контакт не указан в проекте, пропускаем связывание");
|
||||
}
|
||||
|
||||
// Обновляем поля проекта с информацией о последнем событии
|
||||
try {
|
||||
// Формируем описание для cf_2496
|
||||
$cf2496Description = $eventSubject;
|
||||
if (!empty($result) && trim($result) !== '') {
|
||||
// Очищаем результат от лишних пробелов и дефисов
|
||||
$cleanResult = trim($result);
|
||||
$cf2496Description .= " - $cleanResult";
|
||||
}
|
||||
|
||||
$sql = "UPDATE vtiger_projectcf SET cf_1682 = ?, cf_1684 = ?, cf_2496 = ? WHERE projectid = ?";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param('sssi', $formattedDate, $formattedTime, $cf2496Description, $projectId);
|
||||
$stmt->execute();
|
||||
|
||||
log_event('SUCCESS', "Поля проекта обновлены (cf_1682, cf_1684, cf_2496)");
|
||||
log_event('DEBUG', "cf_2496 установлен: $cf2496Description");
|
||||
} catch (Exception $e) {
|
||||
log_event('WARNING', "Не удалось обновить поля проекта: " . $e->getMessage());
|
||||
}
|
||||
|
||||
// Обновляем последовательность
|
||||
$mysqli->query("UPDATE vtiger_crmentity_seq SET id = $eventId");
|
||||
|
||||
$mysqli->close();
|
||||
|
||||
// Формируем успешный ответ
|
||||
$response = [
|
||||
'success' => true,
|
||||
'event_id' => '4x' . $eventId,
|
||||
'event_numeric_id' => $eventId,
|
||||
'event_name' => $eventName,
|
||||
'event_date' => $formattedDate,
|
||||
'event_time' => $formattedTime,
|
||||
'project_id' => $projectId,
|
||||
'message' => 'Событие успешно создано и привязано к проекту'
|
||||
];
|
||||
|
||||
log_event('SUCCESS', "=== ОБРАБОТКА ЗАВЕРШЕНА УСПЕШНО ===");
|
||||
log_event('SUCCESS', "Событие создано: 4x$eventId");
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
|
||||
exit(0);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$error_message = $e->getMessage();
|
||||
log_event('ERROR', "Ошибка: $error_message");
|
||||
|
||||
$response = [
|
||||
'success' => false,
|
||||
'error' => $error_message,
|
||||
'timestamp' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
http_response_code(500);
|
||||
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user