retrieveCurrentUserInfoFromFile(8); // Фёдор Коробков } // Создаем документ через прямые SQL запросы (как в simple_project_updater.php) log_message('DEBUG', "Создаем документ через прямые SQL запросы"); global $mysqli; // Получаем следующий ID log_message('DEBUG', "Получаем следующий ID для документа"); $result = $mysqli->query("SELECT MAX(crmid) as max_id FROM vtiger_crmentity"); $row = $result->fetch_assoc(); $next_id = ($row['max_id'] ?? 0) + 1; log_message('DEBUG', "Следующий ID: $next_id"); $created_time = date('Y-m-d H:i:s'); // Создаем запись в vtiger_crmentity log_message('DEBUG', "Создаем запись в vtiger_crmentity"); $sql = "INSERT INTO vtiger_crmentity (crmid, smcreatorid, smownerid, modifiedby, setype, description, createdtime, modifiedtime, presence, deleted, label, source) VALUES ($next_id, 8, 8, 8, 'Documents', '" . $mysqli->real_escape_string($documentData['notecontent']) . "', '$created_time', '$created_time', 1, 0, '" . $mysqli->real_escape_string($documentData['notes_title']) . "', 'WEBSERVICE')"; log_message('DEBUG', "SQL: $sql"); $result = $mysqli->query($sql); if (!$result) { throw new Exception('Ошибка создания записи в vtiger_crmentity: ' . $mysqli->error); } log_message('DEBUG', "Запись в vtiger_crmentity создана"); // Создаем запись в vtiger_notes log_message('DEBUG', "Создаем запись в vtiger_notes"); $note_no = 'ДОК_' . $next_id; // Формируем S3 URL для filename $s3_bucket = 'f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c'; $s3_key = 'crm2/CRM_Active_Files/Documents/' . $next_id . '/' . $documentData['filename']; $s3_url = "https://s3.twcstorage.ru/$s3_bucket/$s3_key"; $sql = "INSERT INTO vtiger_notes (notesid, note_no, title, filename, notecontent, folderid, filetype, filelocationtype, filedownloadcount, filestatus, filesize, fileversion, tags, its4you_company, s3_bucket, s3_key, s3_etag, nc_path) VALUES ($next_id, '$note_no', '" . $mysqli->real_escape_string($documentData['notes_title']) . "', '" . $mysqli->real_escape_string(strip_tags(trim($s3_url))) . "', '" . $mysqli->real_escape_string($documentData['notecontent']) . "', 1, '" . $mysqli->real_escape_string($documentData['filetype']) . "', '" . $mysqli->real_escape_string($documentData['filelocationtype']) . "', 0, '" . $mysqli->real_escape_string($documentData['filestatus']) . "', " . intval($documentData['filesize']) . ", '" . $mysqli->real_escape_string($documentData['fileversion']) . "', '', '', '', '', '', '')"; log_message('DEBUG', "SQL vtiger_notes: $sql"); $result = $mysqli->query($sql); if (!$result) { throw new Exception('Ошибка создания записи в vtiger_notes: ' . $mysqli->error); } log_message('DEBUG', "Запись в vtiger_notes создана"); // Обновляем последовательность $mysqli->query("UPDATE vtiger_crmentity_seq SET id = $next_id"); log_message('DEBUG', "Документ создан с ID: $next_id"); return [ 'id' => '15x' . $next_id, 'notes_title' => $documentData['notes_title'], 'createdtime' => $created_time, 'modifiedtime' => $created_time ]; } // Функция для создания уведомления о приходе письма function createMailNotification($projectId, $documentId, $documentTitle, $plaintiffFio) { global $mysqli; log_message('INFO', "Создаем уведомление для проекта $projectId о документе $documentId"); // Получаем ответственного по проекту $query = "SELECT e.smownerid FROM vtiger_crmentity e WHERE e.crmid = ? AND e.deleted = 0"; $stmt = $mysqli->prepare($query); $stmt->bind_param('i', $projectId); $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows === 0) { log_message('WARNING', "Проект $projectId не найден или удален"); return false; } $row = $result->fetch_assoc(); $userId = $row['smownerid']; log_message('DEBUG', "Ответственный по проекту: пользователь $userId"); // Формируем текст уведомления $notificationTitle = "Письмо от $plaintiffFio - $documentTitle"; // Формируем ссылку на документ (VDNotifierPro убирает index.php? из ссылки) $documentLink = "module=Documents&view=Detail&record=$documentId"; // Проверяем, нет ли уже непрочитанного уведомления для этого документа $checkQuery = "SELECT id FROM vtiger_vdnotifierpro WHERE userid = ? AND crmid = ? AND status = 5"; $checkStmt = $mysqli->prepare($checkQuery); $checkStmt->bind_param('ii', $userId, $documentId); $checkStmt->execute(); $checkResult = $checkStmt->get_result(); if ($checkResult->num_rows > 0) { // Обновляем время существующего уведомления $existingId = $checkResult->fetch_assoc()['id']; $updateQuery = "UPDATE vtiger_vdnotifierpro SET modifiedtime = NOW() WHERE id = ?"; $updateStmt = $mysqli->prepare($updateQuery); $updateStmt->bind_param('i', $existingId); $updateStmt->execute(); log_message('INFO', "Обновлено существующее уведомление ID: $existingId"); return $existingId; } else { // Создаем новое уведомление $insertQuery = "INSERT INTO vtiger_vdnotifierpro (userid, modulename, crmid, modiuserid, link, title, action, modifiedtime, status) VALUES (?, 'Documents', ?, 0, ?, ?, '', NOW(), 5)"; $insertStmt = $mysqli->prepare($insertQuery); $insertStmt->bind_param('iiss', $userId, $documentId, $documentLink, $notificationTitle); $insertStmt->execute(); $notificationId = $mysqli->insert_id; log_message('SUCCESS', "Создано новое уведомление ID: $notificationId для пользователя $userId"); return $notificationId; } } // Функция для привязки документа к проекту через прямые SQL запросы function linkDocumentToProject($projectId, $documentId) { global $mysqli; log_message('DEBUG', "Привязываем документ $documentId к проекту $projectId"); // Создаем связь в vtiger_senotesrel $stmt = $mysqli->prepare("INSERT INTO vtiger_senotesrel (crmid, notesid) VALUES (?, ?)"); $stmt->bind_param('ii', $projectId, $documentId); $stmt->execute(); $stmt->close(); log_message('DEBUG', "Связь создана между проектом $projectId и документом $documentId"); return true; } try { // Читаем JSON из stdin $input = file_get_contents('php://stdin'); $data = json_decode($input, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception('Ошибка парсинга JSON: ' . json_last_error_msg()); } // Проверяем структуру данных - может быть массив или объект if (is_array($data) && isset($data[0])) { // Если это массив, берем первый элемент $item = $data[0]; } elseif (is_array($data) && isset($data['content'])) { // Если это объект, используем его напрямую $item = $data; } else { throw new Exception('Неверная структура данных: ожидается объект с полем content или массив объектов'); } // Проверяем наличие обязательных полей if (!$item || !isset($item['content']) || !is_array($item['content'])) { throw new Exception('Неверная структура данных: отсутствует content'); } $content = $item['content']; $file_url = trim($item['file'] ?? ''); $file_name = $item['file_name'] ?? ''; if (empty($file_url) || empty($file_name)) { throw new Exception('Отсутствует URL файла или имя файла'); } // Инициализируем пользователя CRM $current_user = new Users(); $current_user->retrieveCurrentUserInfoFromFile(8); // Фёдор Коробков log_message('INFO', "Инициализирован пользователь CRM: " . $current_user->user_name); // Подключаемся к базе данных для поиска проекта $mysqli = new mysqli('localhost', 'ci20465_72new', 'EcY979Rn', 'ci20465_72new'); if ($mysqli->connect_error) { throw new Exception('Не удалось подключиться к базе данных: ' . $mysqli->connect_error); } $mysqli->set_charset('utf8'); // Проверяем кодировку соединения $charset_result = $mysqli->query("SELECT @@character_set_connection, @@collation_connection"); if ($charset_result) { $charset_row = $charset_result->fetch_row(); log_message('DEBUG', "Кодировка БД: " . $charset_row[0] . ", collation: " . $charset_row[1]); } $plaintiff_fio = $content['plaintiff_fio'] ?? ''; $case_number = $content['case_number'] ?? ''; $uid = $content['uid'] ?? ''; log_message('DEBUG', "Поиск проекта по данным: plaintiff_fio='$plaintiff_fio', case_number='$case_number', uid='$uid'"); $project_id = null; // Улучшенный поиск по комбинации критериев с нестрогим соответствием $search_criteria = []; $search_params = []; $param_types = ''; // ФИО с учетом мужского/женского рода if ($plaintiff_fio) { $surname = explode(' ', $plaintiff_fio)[0]; $surname_male = $surname; // Соколов $surname_female = $surname . 'а'; // Соколова $search_criteria[] = "(p.projectname LIKE ? OR e.description LIKE ? OR p.projectname LIKE ? OR e.description LIKE ?)"; $search_params[] = "%" . $mysqli->real_escape_string($surname_male) . "%"; $search_params[] = "%" . $mysqli->real_escape_string($surname_male) . "%"; $search_params[] = "%" . $mysqli->real_escape_string($surname_female) . "%"; $search_params[] = "%" . $mysqli->real_escape_string($surname_female) . "%"; $param_types .= 'ssss'; log_message('DEBUG', "Поиск по ФИО: '$surname_male' и '$surname_female'"); } // Суд if (!empty($content['court'])) { $court = $content['court']; $search_criteria[] = "(e.description LIKE ? OR cf.cf_1499 LIKE ? OR cf.cf_2278 LIKE ?)"; $search_params[] = "%" . $mysqli->real_escape_string($court) . "%"; $search_params[] = "%" . $mysqli->real_escape_string($court) . "%"; $search_params[] = "%" . $mysqli->real_escape_string($court) . "%"; $param_types .= 'sss'; log_message('DEBUG', "Поиск по суду: '$court'"); } // Номер дела if ($case_number) { $search_criteria[] = "(p.project_no = ? OR e.description LIKE ?)"; $search_params[] = $case_number; $search_params[] = "%" . $mysqli->real_escape_string($case_number) . "%"; $param_types .= 'ss'; log_message('DEBUG', "Поиск по номеру дела: '$case_number'"); } // УИД if ($uid) { $search_criteria[] = "(e.description LIKE ?)"; $search_params[] = "%" . $mysqli->real_escape_string($uid) . "%"; $param_types .= 's'; log_message('DEBUG', "Поиск по УИД: '$uid'"); } // Выполняем поиск если есть критерии if (!empty($search_criteria)) { // Сначала пробуем строгий поиск (все критерии) $where_clause = implode(' AND ', $search_criteria); $sql = " SELECT p.projectid, p.projectname, p.project_no, e.description FROM vtiger_project p JOIN vtiger_crmentity e ON e.crmid = p.projectid AND e.deleted = 0 LEFT JOIN vtiger_projectcf cf ON cf.projectid = p.projectid WHERE $where_clause ORDER BY CASE WHEN p.projectname LIKE '%" . $mysqli->real_escape_string($surname ?? '') . "%' THEN 1 WHEN e.description LIKE '%" . $mysqli->real_escape_string($surname ?? '') . "%' THEN 2 ELSE 3 END, p.projectid ASC LIMIT 1 "; log_message('DEBUG', "Строгий поиск SQL: $sql"); log_message('DEBUG', "Параметры: " . json_encode($search_params)); $stmt = $mysqli->prepare($sql); if ($stmt) { if (!empty($search_params)) { $stmt->bind_param($param_types, ...$search_params); } $stmt->execute(); $result = $stmt->get_result(); if ($row = $result->fetch_assoc()) { $project_id = $row['projectid']; log_message('SUCCESS', "Найден проект (строгий поиск): ID=$project_id, название='{$row['projectname']}'"); } $stmt->close(); } else { log_message('ERROR', "Ошибка подготовки SQL: " . $mysqli->error); } // Если строгий поиск не дал результатов, пробуем поиск только по ФИО if (!$project_id && !empty($surname)) { $sql = " SELECT p.projectid, p.projectname, p.project_no, e.description FROM vtiger_project p JOIN vtiger_crmentity e ON e.crmid = p.projectid AND e.deleted = 0 LEFT JOIN vtiger_projectcf cf ON cf.projectid = p.projectid WHERE (p.projectname LIKE ? OR e.description LIKE ? OR p.projectname LIKE ? OR e.description LIKE ?) ORDER BY CASE WHEN p.projectname LIKE '%" . $mysqli->real_escape_string($surname) . "%' THEN 1 WHEN e.description LIKE '%" . $mysqli->real_escape_string($surname) . "%' THEN 2 ELSE 3 END, p.projectid ASC LIMIT 1 "; log_message('DEBUG', "Поиск только по ФИО SQL: $sql"); $stmt = $mysqli->prepare($sql); if ($stmt) { $surname_male = "%" . $mysqli->real_escape_string($surname) . "%"; $surname_female = "%" . $mysqli->real_escape_string($surname . 'а') . "%"; log_message('DEBUG', "Параметры поиска по ФИО: '$surname_male', '$surname_female'"); log_message('DEBUG', "Длина параметров: " . strlen($surname_male) . ", " . strlen($surname_female)); log_message('DEBUG', "Кодировка параметров: " . mb_detect_encoding($surname_male) . ", " . mb_detect_encoding($surname_female)); $stmt->bind_param('ssss', $surname_male, $surname_male, $surname_female, $surname_female); $stmt->execute(); $result = $stmt->get_result(); log_message('DEBUG', "Количество найденных записей: " . $result->num_rows); if ($row = $result->fetch_assoc()) { $project_id = $row['projectid']; log_message('SUCCESS', "Найден проект (поиск по ФИО): ID=$project_id, название='{$row['projectname']}'"); } else { log_message('DEBUG', "Проект не найден по ФИО"); } $stmt->close(); } else { log_message('ERROR', "Ошибка подготовки SQL для поиска по ФИО: " . $mysqli->error); } } } if (!$project_id) { throw new Exception('Проект не найден по указанным данным'); } log_message('INFO', "Найден проект ID: $project_id"); // Формируем название документа $document_title = "СУДЕБНЫЙ ДОКУМЕНТ"; if (!empty($content['document_title'])) { $document_title = $content['document_title']; } if (!empty($content['case_number'])) { $document_title .= " по делу " . $content['case_number']; } if (!empty($content['plaintiff_fio'])) { $document_title .= " " . $content['plaintiff_fio']; } $document_title .= " " . date('d.m.Y'); // Создаём документ через CRM API $documentData = [ 'notes_title' => $document_title, 'filename' => $file_name, 'assigned_user_id' => '19x8', // Фёдор Коробков 'notecontent' => "Документ создан автоматически из судебного документа.\n\n" . "Номер дела: " . ($content['case_number'] ?? 'не указан') . "\n" . "Суд: " . ($content['court'] ?? 'не указан') . "\n" . "Истец: " . ($content['plaintiff_fio'] ?? 'не указан') . "\n" . "УИД: " . ($content['uid'] ?? 'не указан') . "\n" . "Дата создания: " . date('d.m.Y H:i:s'), 'filetype' => 'application/pdf', 'filesize' => '0', // Будет обновлено после загрузки 'filelocationtype' => 'E', // External URL 'fileversion' => '1.0', 'filestatus' => '1', // Active 'folderid' => '22x1', // Default папка ]; log_message('INFO', "Создаём документ: $document_title"); $documentResult = createDocumentViaAPI($documentData); $documentWsId = $documentResult['id']; list(, $documentNumericId) = explode('x', $documentWsId, 2); log_message('SUCCESS', "Документ создан: $documentWsId (numeric: $documentNumericId)"); // S3 метаданные уже установлены при создании записи log_message('SUCCESS', "S3 метаданные установлены для документа $documentNumericId"); // Загружаем файл в S3 if (!empty($file_url) && !empty($file_name)) { log_message('DEBUG', "Начинаем загрузку файла в S3: $file_url"); // Скачиваем файл $file_content = file_get_contents($file_url); if ($file_content === false) { log_message('ERROR', "Не удалось скачать файл: $file_url"); } else { log_message('DEBUG', "Файл скачан, размер: " . strlen($file_content) . " байт"); // Генерируем ETag для S3 $s3_etag = '"' . md5($file_content) . '"'; // Формируем S3 ключ $s3_bucket = 'f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c'; $s3_key = 'crm2/CRM_Active_Files/Documents/' . $documentNumericId . '/' . $file_name; // Загружаем файл в S3 через S3Client try { log_message('DEBUG', "Загружаем конфигурацию S3"); // Загружаем конфигурацию S3 $config = require __DIR__ . '/file_storage/config.php'; log_message('DEBUG', "Конфигурация S3 загружена"); $s3Client = new S3Client($config['s3']); log_message('DEBUG', "S3Client создан"); // Создаем временный файл $temp_file = tempnam(sys_get_temp_dir(), 'crm_doc_'); file_put_contents($temp_file, $file_content); // Загружаем файл в S3 log_message('DEBUG', "Загружаем файл в S3 с ключом: $s3_key"); $result = $s3Client->uploadFile($temp_file, $s3_key, [ 'ContentType' => 'application/pdf' ]); // Удаляем временный файл unlink($temp_file); log_message('SUCCESS', "Файл успешно загружен в S3"); // Обновляем ETag, размер файла и S3 метаданные в БД $stmt = $mysqli->prepare(" UPDATE vtiger_notes SET s3_etag = ?, filesize = ?, s3_bucket = ?, s3_key = ? WHERE notesid = ? "); $file_size = strlen($file_content); $stmt->bind_param('sissi', $s3_etag, $file_size, $s3_bucket, $s3_key, $documentNumericId); $stmt->execute(); $stmt->close(); log_message('SUCCESS', "S3 ETag и размер файла обновлены"); } catch (Exception $e) { log_message('ERROR', "Ошибка загрузки в S3: " . $e->getMessage()); } } } // Привязываем документ к проекту $linkSuccess = linkDocumentToProject($project_id, (int)$documentNumericId); if ($linkSuccess) { log_message('SUCCESS', "Документ успешно привязан к проекту"); // Создаем уведомление о приходе письма $notificationId = createMailNotification($project_id, (int)$documentNumericId, $document_title, $plaintiff_fio); if ($notificationId) { log_message('SUCCESS', "Уведомление создано с ID: $notificationId"); } else { log_message('WARNING', "Не удалось создать уведомление"); } } else { log_message('ERROR', "Ошибка привязки документа к проекту"); } $mysqli->close(); // Формируем результат $result = [ 'success' => true, 'project_id' => $project_id, 'plaintiff_fio' => explode(' ', $plaintiff_fio)[0], 'case_number' => $case_number, 'uid' => $uid, 'document_id' => $documentNumericId, 'document_ws_id' => $documentWsId, 's3_url' => $s3_url, 'notification_id' => $notificationId ?? null, 'message' => 'Документ успешно создан через CRM API и добавлен к проекту' . ($notificationId ? ' с уведомлением' : '') ]; log_message('SUCCESS', "Обработка завершена успешно: " . json_encode($result, JSON_UNESCAPED_UNICODE)); echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); return 0; } catch (Exception $e) { $error_message = $e->getMessage(); log_message('ERROR', "Ошибка: $error_message"); echo json_encode([ 'success' => false, 'error' => $error_message, 'timestamp' => date('Y-m-d H:i:s') ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); return 1; } ?>