feat(documents): дедупликация documents_meta и исправление field_label

- Исправлен N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js: использовать uploads_field_labels[0] вместо [grp]
- Создан SQL_CLAIMSAVE_FIXED_NEW_FLOW_DEDUP.sql с дедупликацией documents_meta
- Создан SQL_CLEANUP_DOCUMENTS_META_DUPLICATES.sql для очистки существующих дубликатов
- Создан полный уникальный индекс idx_document_texts_hash_unique на document_texts(file_hash)
- Добавлен SESSION_LOG_2025-11-28_documents_dedup.md с описанием всех изменений

Fixes:
- field_label теперь корректно отображает 'Переписка' вместо 'group-2'
- documents_meta не накапливает дубликаты при повторных сохранениях
- ON CONFLICT (file_hash) теперь работает для document_texts
This commit is contained in:
Fedor
2025-11-28 18:16:53 +03:00
parent 6c770f0a87
commit 840acca51a
118 changed files with 13379 additions and 218 deletions

146
RESTORE_INSTRUCTIONS.md Normal file
View File

@@ -0,0 +1,146 @@
# Инструкция по восстановлению удаленных файлов и защите от повторных удалений
## 📋 Что было сделано:
1. ✅ Создан скрипт для настройки Nextcloud (`fix_nextcloud_settings.php`)
2. ✅ Создан скрипт для восстановления файлов (`restore_all_deleted_files.php`)
3. ✅ Создан скрипт для регулярной индексации (`nextcloud_scan_files.sh`)
---
## 🚀 Порядок выполнения:
### Шаг 1: Настройка Nextcloud (защита от удалений)
```bash
cd /var/www/fastuser/data/www/crm.clientright.ru
php fix_nextcloud_settings.php
```
**Что делает:**
- Отключает `DeleteOrphanedItems` (главная причина удалений)
- Включает `readonly` для External Storage
- Увеличивает retention корзины до 365 дней
- Создает скрипт для регулярной индексации
---
### Шаг 2: Восстановление файлов (сначала проверка)
**Сначала проверка (dry-run):**
```bash
php restore_all_deleted_files.php --dry-run
```
Это покажет, сколько файлов будет восстановлено без реального восстановления.
**Ограничение количества (для теста):**
```bash
php restore_all_deleted_files.php --dry-run 100
```
**Восстановление всех файлов:**
```bash
php restore_all_deleted_files.php
```
**Восстановление с ограничением (для безопасности):**
```bash
php restore_all_deleted_files.php "" 1000
```
**Восстановление только файлов проекта:**
```bash
php restore_all_deleted_files.php "" "" "crm2/CRM_Active_Files/Documents/Project/"
```
---
### Шаг 3: Настройка регулярной индексации
**Добавить в crontab:**
```bash
crontab -e
```
**Добавить строку:**
```
0 */6 * * * /var/www/fastuser/data/www/crm.clientright.ru/nextcloud_scan_files.sh
```
Это будет сканировать файлы каждые 6 часов.
**Или сканировать только внешнее хранилище (быстрее):**
Отредактируйте `nextcloud_scan_files.sh` и раскомментируйте строку:
```bash
docker exec -u www-data nextcloud-fresh php occ files:scan --path="/crm"
```
---
## 📊 Статистика удалений:
- **Всего delete markers:** ~25,200
- **Пик удалений:** 1 ноября 2025, 09:00 утра (7,080 файлов)
- **Причина:** DeleteOrphanedItems в Nextcloud
---
## ⚠️ ВАЖНО:
1. **Сначала настройте Nextcloud** (Шаг 1), чтобы предотвратить новые удаления
2. **Проверьте dry-run** перед массовым восстановлением
3. **Восстанавливайте постепенно** (по 1000-5000 файлов за раз)
4. **Проверяйте логи** после восстановления
---
## 🔍 Проверка статуса:
**Проверить статус задач Nextcloud:**
```bash
docker exec -u www-data nextcloud-fresh php occ background-job:list
```
**Проверить настройки External Storage:**
```bash
docker exec -u www-data nextcloud-fresh php occ files_external:list
```
**Проверить retention корзины:**
```bash
docker exec -u www-data nextcloud-fresh php occ config:app:get files trashbin_retention_obligation
```
**Проверить логи восстановления:**
```bash
ls -lh /var/www/fastuser/data/www/crm.clientright.ru/restore_log_*.json
```
---
## 🛡️ Защита от повторных удалений:
После выполнения всех шагов система будет защищена:
1. ✅ DeleteOrphanedItems отключен
2. ✅ External Storage в режиме readonly
3. ✅ Retention корзины увеличен до 365 дней
4. ✅ Регулярная индексация файлов настроена
---
## 📝 Логи:
- Логи восстановления: `restore_log_YYYY-MM-DD_HH-MM-SS.json`
- Логи индексации: `/var/log/nextcloud_scan.log`
---
## 🆘 Если что-то пошло не так:
1. Проверьте логи восстановления
2. Проверьте доступность Docker контейнера Nextcloud
3. Проверьте права доступа к S3
4. Проверьте логи Nextcloud: `docker logs nextcloud-fresh`

View File

@@ -105,3 +105,4 @@
## Коммит ## Коммит
Изменения закоммичены в git с описанием исправлений. Изменения закоммичены в git с описанием исправлений.

View File

@@ -0,0 +1,236 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
echo "Детальный анализ паттернов удалений\n";
echo str_repeat("=", 80) . "\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
// Анализируем удаления по времени
echo "1. Анализ удалений по времени суток...\n";
$deletionsByHour = [];
$deletionsByDay = [];
$batchDeletions = []; // Массовые удаления (много файлов за короткое время)
$totalChecked = 0;
$maxToCheck = 10000;
try {
$isTruncated = true;
$continuationToken = null;
$pageCount = 0;
$maxPages = 20;
$currentBatch = [];
$lastDeleteTime = null;
while ($isTruncated && $pageCount < $maxPages && $totalChecked < $maxToCheck) {
$params = [
'Bucket' => $s3Bucket,
'Prefix' => 'crm2/CRM_Active_Files/Documents/Project/',
'MaxKeys' => 1000
];
if ($continuationToken) {
$params['ContinuationToken'] = $continuationToken;
}
$versions = $s3Client->listObjectVersions($params);
$pageCount++;
if (isset($versions['DeleteMarkers'])) {
foreach ($versions['DeleteMarkers'] as $marker) {
$totalChecked++;
$deleteDate = isset($marker['LastModified']) ? $marker['LastModified'] : null;
if ($deleteDate) {
$dateTime = new DateTime($deleteDate);
$hour = $dateTime->format('H');
$day = $dateTime->format('Y-m-d');
if (!isset($deletionsByHour[$hour])) {
$deletionsByHour[$hour] = 0;
}
$deletionsByHour[$hour]++;
if (!isset($deletionsByDay[$day])) {
$deletionsByDay[$day] = 0;
}
$deletionsByDay[$day]++;
// Определяем массовые удаления (более 10 файлов за минуту)
$deleteTimestamp = strtotime($deleteDate);
if ($lastDeleteTime && abs($deleteTimestamp - $lastDeleteTime) < 60) {
$currentBatch[] = $marker;
} else {
if (count($currentBatch) > 10) {
$batchDeletions[] = [
'count' => count($currentBatch),
'time' => date('Y-m-d H:i:s', $lastDeleteTime),
'files' => array_slice($currentBatch, 0, 5) // Первые 5 для примера
];
}
$currentBatch = [$marker];
}
$lastDeleteTime = $deleteTimestamp;
}
}
}
$isTruncated = isset($versions['IsTruncated']) && $versions['IsTruncated'];
$continuationToken = isset($versions['NextContinuationToken']) ? $versions['NextContinuationToken'] : null;
if (!$isTruncated) {
break;
}
}
// Проверяем последний батч
if (count($currentBatch) > 10) {
$batchDeletions[] = [
'count' => count($currentBatch),
'time' => $lastDeleteTime ? date('Y-m-d H:i:s', $lastDeleteTime) : 'неизвестно',
'files' => array_slice($currentBatch, 0, 5)
];
}
echo " Проверено delete markers: $totalChecked\n\n";
echo " Удаления по часам суток:\n";
ksort($deletionsByHour);
foreach ($deletionsByHour as $hour => $count) {
if ($count > 0) {
echo " {$hour}:00 - " . ($hour + 1) . ":00: $count удалений\n";
}
}
echo "\n";
echo " Удаления по дням (топ 15):\n";
arsort($deletionsByDay);
$count = 0;
foreach ($deletionsByDay as $day => $deleteCount) {
echo " $day: $deleteCount удалений\n";
if (++$count >= 15) break;
}
echo "\n";
if (!empty($batchDeletions)) {
echo " Массовые удаления (более 10 файлов за минуту): " . count($batchDeletions) . "\n";
foreach (array_slice($batchDeletions, 0, 5) as $batch) {
echo " Время: {$batch['time']}, удалено файлов: {$batch['count']}\n";
}
echo "\n";
}
} catch (\Aws\Exception\AwsException $e) {
echo " Ошибка: " . $e->getMessage() . "\n";
}
// Проверяем, может быть это связано с удалением документов в CRM
echo "2. Проверка связи с удалением документов в CRM...\n";
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
// Проверяем, сколько документов было удалено в последние дни
$stmt = $pdo->prepare('
SELECT DATE(e.modifiedtime) as delete_date, COUNT(*) as count
FROM vtiger_crmentity e
INNER JOIN vtiger_notes n ON n.notesid = e.crmid
WHERE e.deleted = 1
AND n.filelocationtype = "E"
AND e.modifiedtime >= DATE_SUB(NOW(), INTERVAL 60 DAY)
GROUP BY DATE(e.modifiedtime)
ORDER BY delete_date DESC
LIMIT 20
');
$stmt->execute();
$deletedDocs = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($deletedDocs)) {
echo " Удаленные документы в CRM (за последние 60 дней):\n";
foreach ($deletedDocs as $doc) {
echo " {$doc['delete_date']}: {$doc['count']} документов\n";
}
echo "\n";
} else {
echo " Удаленных документов не найдено\n\n";
}
// Сравниваем даты удалений в S3 и CRM
echo "3. Сравнение дат удалений в S3 и CRM...\n";
if (!empty($deletionsByDay) && !empty($deletedDocs)) {
echo " Сравнение:\n";
foreach ($deletedDocs as $doc) {
$crmDate = $doc['delete_date'];
$s3Count = $deletionsByDay[$crmDate] ?? 0;
$crmCount = $doc['count'];
if ($s3Count > 0) {
echo " $crmDate:\n";
echo " Удалено в CRM: $crmCount документов\n";
echo " Delete markers в S3: $s3Count\n";
if ($s3Count > $crmCount * 2) {
echo " ⚠️ В S3 удалено значительно больше файлов!\n";
} elseif (abs($s3Count - $crmCount) <= 10) {
echo " ✅ Количество примерно совпадает\n";
}
echo "\n";
}
}
}
echo str_repeat("=", 80) . "\n";
echo "ВЫВОДЫ:\n\n";
// Определяем наиболее вероятную причину
$maxHour = array_search(max($deletionsByHour), $deletionsByHour);
$maxDay = array_search(max($deletionsByDay), $deletionsByDay);
$maxDayCount = max($deletionsByDay);
echo "1. Пик удалений:\n";
echo " - Время: {$maxHour}:00\n";
echo " - День: $maxDay ($maxDayCount удалений)\n\n";
if ($maxHour >= 6 && $maxHour <= 8) {
echo "2. 💡 ВЕРОЯТНАЯ ПРИЧИНА: Автоматическая задача (cron job)\n";
echo " Удаления происходят рано утром (6-8 утра) - типичное время для cron\n\n";
}
if (!empty($batchDeletions)) {
echo "3. 💡 ВЕРОЯТНАЯ ПРИЧИНА: Массовое удаление (скрипт или автоматизация)\n";
echo " Найдено " . count($batchDeletions) . " случаев массового удаления\n\n";
}
echo "4. 💡 РЕКОМЕНДАЦИЯ: Проверить:\n";
echo " - DeleteOrphanedItems в Nextcloud (запускается ежедневно)\n";
echo " - Cron задачи, которые могут удалять файлы\n";
echo " - Логи Nextcloud на предмет массовых удалений\n";
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

203
analyze_deletions.php Normal file
View File

@@ -0,0 +1,203 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
echo "Анализ удалений файлов из S3\n";
echo str_repeat("=", 80) . "\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
// Анализируем паттерны удалений
echo "1. Анализ паттернов удалений по датам...\n";
$deletionsByDate = [];
$deletionsByProject = [];
$totalChecked = 0;
$maxToCheck = 5000; // Ограничиваем для скорости
try {
$isTruncated = true;
$continuationToken = null;
$pageCount = 0;
$maxPages = 10;
while ($isTruncated && $pageCount < $maxPages && $totalChecked < $maxToCheck) {
$params = [
'Bucket' => $s3Bucket,
'Prefix' => 'crm2/CRM_Active_Files/Documents/Project/',
'MaxKeys' => 1000
];
if ($continuationToken) {
$params['ContinuationToken'] = $continuationToken;
}
$versions = $s3Client->listObjectVersions($params);
$pageCount++;
if (isset($versions['DeleteMarkers'])) {
foreach ($versions['DeleteMarkers'] as $marker) {
$totalChecked++;
$key = $marker['Key'];
$deleteDate = isset($marker['LastModified']) ? $marker['LastModified'] : null;
if ($deleteDate) {
$dateKey = substr($deleteDate, 0, 10); // YYYY-MM-DD
if (!isset($deletionsByDate[$dateKey])) {
$deletionsByDate[$dateKey] = 0;
}
$deletionsByDate[$dateKey]++;
}
// Извлекаем ID проекта из пути
if (preg_match('/Project\/([^\/]+)_(\d+)\//', $key, $matches)) {
$projectId = $matches[2];
if (!isset($deletionsByProject[$projectId])) {
$deletionsByProject[$projectId] = 0;
}
$deletionsByProject[$projectId]++;
}
}
}
$isTruncated = isset($versions['IsTruncated']) && $versions['IsTruncated'];
$continuationToken = isset($versions['NextContinuationToken']) ? $versions['NextContinuationToken'] : null;
if (!$isTruncated) {
break;
}
}
echo " Проверено delete markers: $totalChecked\n\n";
// Сортируем по датам
krsort($deletionsByDate);
echo " Удаления по датам (топ 20):\n";
$count = 0;
foreach ($deletionsByDate as $date => $count) {
if ($count > 0) {
echo " $date: $count удалений\n";
if (++$count >= 20) break;
}
}
echo "\n";
// Сортируем проекты по количеству удалений
arsort($deletionsByProject);
echo " Проекты с наибольшим количеством удалений (топ 10):\n";
$count = 0;
foreach ($deletionsByProject as $projectId => $deleteCount) {
echo " Проект $projectId: $deleteCount удалений\n";
if (++$count >= 10) break;
}
echo "\n";
} catch (\Aws\Exception\AwsException $e) {
echo " Ошибка: " . $e->getMessage() . "\n";
}
// Проверяем логи системы
echo "2. Проверка логов на наличие записей об удалениях...\n";
$logFiles = [
'/var/log/nginx/error.log',
'/var/log/apache2/error.log',
'/var/www/fastuser/data/www/crm.clientright.ru/logs/debug.log',
'/var/www/fastuser/data/www/crm.clientright.ru/logs/s3_debug.log',
];
foreach ($logFiles as $logFile) {
if (file_exists($logFile)) {
echo " Проверка: $logFile\n";
$lines = file($logFile);
if ($lines) {
$deleteLines = array_filter($lines, function($line) {
return stripos($line, 'delete') !== false &&
(stripos($line, 's3') !== false || stripos($line, 'file') !== false);
});
if (!empty($deleteLines)) {
echo " Найдено строк с упоминанием удалений: " . count($deleteLines) . "\n";
echo " Последние 5 записей:\n";
foreach (array_slice($deleteLines, -5) as $line) {
echo " " . substr(trim($line), 0, 150) . "\n";
}
} else {
echo " Записей об удалениях не найдено\n";
}
}
echo "\n";
}
}
// Проверяем, есть ли скрипты крона, которые могут удалять файлы
echo "3. Поиск скриптов, которые могут удалять файлы...\n";
$cronFiles = [
'/var/spool/cron/crontabs/root',
'/etc/cron.d/',
'/var/www/fastuser/data/www/crm.clientright.ru/cron/',
];
foreach ($cronFiles as $cronPath) {
if (file_exists($cronPath)) {
echo " Проверка: $cronPath\n";
if (is_dir($cronPath)) {
$files = glob($cronPath . '*');
foreach ($files as $file) {
if (is_file($file)) {
$content = file_get_contents($file);
if (stripos($content, 'delete') !== false || stripos($content, 'remove') !== false) {
echo " Найден файл: $file\n";
echo " Содержит упоминания удаления\n";
}
}
}
} else {
$content = file_get_contents($cronPath);
if (stripos($content, 'delete') !== false || stripos($content, 'remove') !== false) {
echo " Файл содержит упоминания удаления\n";
}
}
}
}
echo "\n";
// Проверяем, может быть это связано с синхронизацией Nextcloud
echo "4. Проверка связи с Nextcloud синхронизацией...\n";
$nextcloudFiles = glob('/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/*sync*.php');
if (!empty($nextcloudFiles)) {
echo " Найдено файлов синхронизации: " . count($nextcloudFiles) . "\n";
foreach ($nextcloudFiles as $file) {
$content = file_get_contents($file);
if (stripos($content, 'delete') !== false) {
echo " $file содержит код удаления\n";
}
}
} else {
echo " Файлы синхронизации не найдены\n";
}
echo "\n";
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

View File

@@ -0,0 +1,51 @@
<?php
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$projectId = 371231;
$sql = "SELECT
n.notesid,
n.title,
n.filelocationtype,
n.filename,
n.s3_bucket,
n.s3_key
FROM vtiger_notes n
INNER JOIN vtiger_crmentity e ON e.crmid = n.notesid
INNER JOIN vtiger_senotesrel snr ON snr.notesid = n.notesid
WHERE snr.crmid = ? AND e.deleted = 0
ORDER BY n.notesid DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute([$projectId]);
$documents = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "Проверка поля filename для документов проекта $projectId\n";
echo str_repeat("=", 80) . "\n\n";
foreach ($documents as $doc) {
echo "ID: {$doc['notesid']}\n";
echo " Название: {$doc['title']}\n";
echo " filelocationtype: {$doc['filelocationtype']}\n";
echo " filename (первые 200 символов): " . substr($doc['filename'], 0, 200) . "\n";
echo " s3_bucket: " . ($doc['s3_bucket'] ?? 'нет') . "\n";
echo " s3_key: " . substr($doc['s3_key'] ?? 'нет', 0, 100) . "\n";
// Проверяем, является ли filename URL
$isUrl = filter_var($doc['filename'], FILTER_VALIDATE_URL);
echo " filename является URL: " . ($isUrl ? 'ДА' : 'НЕТ') . "\n";
// Проверяем, начинается ли filename с http
$isHttp = (strpos($doc['filename'], 'http://') === 0 || strpos($doc['filename'], 'https://') === 0);
echo " filename начинается с http: " . ($isHttp ? 'ДА' : 'НЕТ') . "\n";
echo "\n";
}

149
check_project_371231.php Normal file
View File

@@ -0,0 +1,149 @@
<?php
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$projectId = 371231;
// Получаем информацию о проекте
$sqlProject = "SELECT projectid, projectname, projectstatus FROM vtiger_project WHERE projectid = ?";
$stmtProject = $pdo->prepare($sqlProject);
$stmtProject->execute([$projectId]);
$project = $stmtProject->fetch(PDO::FETCH_ASSOC);
if (!$project) {
die("❌ Проект $projectId не найден!\n");
}
echo "📋 ПРОЕКТ: {$project['projectname']}\n";
echo " ID: {$project['projectid']}\n";
echo " Статус: {$project['projectstatus']}\n";
echo "\n" . str_repeat("=", 80) . "\n\n";
// Получаем документы проекта
$sql = "SELECT
n.notesid,
n.title,
n.filename,
n.filelocationtype,
n.foldername,
n.s3_bucket,
n.s3_key,
n.nc_path,
n.filesize,
e.createdtime,
e.modifiedtime,
u.user_name,
e.deleted
FROM vtiger_notes n
INNER JOIN vtiger_crmentity e ON e.crmid = n.notesid
INNER JOIN vtiger_senotesrel snr ON snr.notesid = n.notesid
LEFT JOIN vtiger_users u ON u.id = e.smownerid
WHERE snr.crmid = ? AND e.deleted = 0
ORDER BY e.createdtime DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute([$projectId]);
$documents = $stmt->fetchAll(PDO::FETCH_ASSOC);
$count = count($documents);
echo "📄 НАЙДЕНО ДОКУМЕНТОВ: $count\n\n";
if ($count == 0) {
echo "⚠️ Документы не найдены!\n";
exit;
}
$totalSize = 0;
$s3Count = 0;
$localCount = 0;
$brokenCount = 0;
$accessibleCount = 0;
$notAccessibleCount = 0;
foreach ($documents as $i => $doc) {
$num = $i + 1;
$filelocationtype = $doc['filelocationtype'] ?? 'I';
$s3Bucket = $doc['s3_bucket'] ?? null;
$s3Key = $doc['s3_key'] ?? null;
$filename = $doc['filename'] ?? '';
$title = $doc['title'] ?? 'Без названия';
$isS3 = ($filelocationtype == 'E' && !empty($s3Bucket) && !empty($s3Key));
$isLocal = ($filelocationtype == 'I' || empty($filelocationtype));
if ($isS3) {
$s3Count++;
$status = "☁️ S3";
$filePath = "s3://{$s3Bucket}/{$s3Key}";
$accessibleCount++; // Пока считаем доступными, проверим отдельно
} else {
$localCount++;
$status = "💾 Локальный";
// Для локальных файлов проверяем путь
if (!empty($filename)) {
// Парсим путь из filename
$filePath = $filename;
if (file_exists($filePath)) {
$accessibleCount++;
$status .= "";
} else {
$notAccessibleCount++;
$brokenCount++;
$status .= " ❌ ФАЙЛ НЕ НАЙДЕН";
}
} else {
$notAccessibleCount++;
$brokenCount++;
$status .= "НЕТ ПУТИ";
}
}
$size = $doc['filesize'] ?? 0;
$totalSize += $size;
$sizeStr = $size > 0 ? number_format($size / 1024, 2) . ' KB' : '0 KB';
echo sprintf(
"%3d. [%s] %s\n",
$num,
$status,
$title
);
echo sprintf(
" ID: %d | Размер: %s | Тип: %s\n",
$doc['notesid'],
$sizeStr,
$filelocationtype
);
if ($isS3) {
echo sprintf(" S3 Key: %s\n", $s3Key);
} else {
echo sprintf(" Путь: %s\n", substr($filename, 0, 100));
}
if ($notAccessibleCount > 0 && ($i == $count - 1 || ($i + 1) % 10 == 0)) {
echo "\n";
}
}
echo "\n" . str_repeat("=", 80) . "\n";
echo "📊 СТАТИСТИКА:\n";
echo " Всего документов: $count\n";
echo " S3 документов: $s3Count\n";
echo " Локальных документов: $localCount\n";
echo " Доступных: $accessibleCount\n";
echo " Недоступных: $notAccessibleCount\n";
echo " Общий размер: " . number_format($totalSize / 1024 / 1024, 2) . " MB\n";
if ($brokenCount > 0) {
echo "\n⚠️ ВНИМАНИЕ: Найдено $brokenCount недоступных файлов!\n";
}

View File

@@ -0,0 +1,51 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$projectId = 371231;
// Получаем документы проекта
$sql = "SELECT
n.notesid,
n.title,
n.filename,
n.filelocationtype,
n.s3_bucket,
n.s3_key,
n.filesize
FROM vtiger_notes n
INNER JOIN vtiger_crmentity e ON e.crmid = n.notesid
INNER JOIN vtiger_senotesrel snr ON snr.notesid = n.notesid
WHERE snr.crmid = ? AND e.deleted = 0
ORDER BY e.createdtime DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute([$projectId]);
$documents = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "Найдено документов: " . count($documents) . "\n\n";
foreach ($documents as $i => $doc) {
$num = $i + 1;
echo "$num. ID: {$doc['notesid']}\n";
echo " Название: " . ($doc['title'] ?? 'Нет') . "\n";
echo " Тип хранения: " . ($doc['filelocationtype'] ?? 'I') . "\n";
if ($doc['filelocationtype'] == 'E') {
echo " S3 Bucket: " . ($doc['s3_bucket'] ?? 'нет') . "\n";
echo " S3 Key: " . ($doc['s3_key'] ?? 'нет') . "\n";
} else {
echo " Filename: " . substr($doc['filename'] ?? 'нет', 0, 100) . "\n";
}
echo "\n";
}

129
check_project_373977.php Normal file
View File

@@ -0,0 +1,129 @@
<?php
/**
* Проверка документов проекта 373977
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 373977;
$s3Bucket = $config['s3']['bucket'];
// Документы проекта из БД
$documents = [
373981 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/8_Договора_оказание_услуг_373981.pdf',
373983 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/9_Подтверждение_оплаты_пооговору_373983.pdf',
373985 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/10_2_Скрин_личногоабинетастца_и_программа_обуч_373985.pdf',
373987 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/10_1_Скрин_личногоабинетастца_и_программа_обуч_373987.pdf',
373989 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/11_1_Подтверждение_проведения_претензионной_работы_373989.pdf',
373991 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/7_заявление_потребителя_373991.pdf',
374017 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/11_Доказательство_соблюдения_претензионного_порядк_374017.pdf',
375402 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/11.2_Претензия_в_защиту_интересов_Полулях_Ольга_1_375402.pdf',
375404 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/11.3_Доказательство_оплаты_направления_претензии_о_375404.pdf',
375406 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/11.4_Доказательствоаправления_претензии_ответчик_375406.pdf',
376051 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/0_Исковоеаявление_поелуолулях_7_стр_376051.pdf',
376054 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/6_Расчет_исковыхребований_Полулях_1_стр_376054.pdf',
376080 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/12.1_Доказательство_оплаты_направления_иска_ответч_376080.pdf',
376082 => 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/12.2_Доказательствоаправления_иска_ответчику_376082.pdf',
396623 => 'crm2/CRM_Active_Files/Documents/396623/ПК_451a1058-ee34-0d48-b2f4-d6dfa522928a.pdf_WITH_ENVELOPE.pdf', // Неправильное место!
];
echo "=== ПРОВЕРКА ДОКУМЕНТОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($documents),
'exists' => 0,
'missing' => 0,
'wrong_place' => 0,
'missing_files' => [],
'wrong_place_files' => [],
];
$projectPrefix = 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/';
foreach ($documents as $docId => $s3Key) {
$filename = basename($s3Key);
$isInProjectFolder = strpos($s3Key, $projectPrefix) === 0;
echo "Документ ID: {$docId}\n";
echo " Файл: {$filename}\n";
echo " Путь: {$s3Key}\n";
if ($s3Client->doesObjectExist($s3Bucket, $s3Key)) {
$object = $s3Client->headObject(['Bucket' => $s3Bucket, 'Key' => $s3Key]);
$size = round($object['ContentLength'] / 1024, 2);
if (!$isInProjectFolder) {
echo " ⚠️ Файл существует, но в неправильном месте (размер: {$size} KB)\n";
$stats['wrong_place']++;
$stats['wrong_place_files'][] = [
'doc_id' => $docId,
'current_path' => $s3Key,
'should_be' => $projectPrefix . $filename,
];
} else {
echo " ✅ Файл существует (размер: {$size} KB)\n";
$stats['exists']++;
}
} else {
echo " ❌ Файл отсутствует\n";
$stats['missing']++;
$stats['missing_files'][] = [
'doc_id' => $docId,
'path' => $s3Key,
];
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего документов: {$stats['total']}\n";
echo "На месте: {$stats['exists']}\n";
echo "⚠️ В неправильном месте: {$stats['wrong_place']}\n";
echo "❌ Отсутствуют: {$stats['missing']}\n\n";
if (!empty($stats['wrong_place_files'])) {
echo "ФАЙЛЫ В НЕПРАВИЛЬНОМ МЕСТЕ:\n";
foreach ($stats['wrong_place_files'] as $file) {
echo " - Документ {$file['doc_id']}: {$file['current_path']}\n";
echo " Должен быть: {$file['should_be']}\n";
}
echo "\n";
}
if (!empty($stats['missing_files'])) {
echo "ОТСУТСТВУЮЩИЕ ФАЙЛЫ:\n";
foreach ($stats['missing_files'] as $file) {
echo " - Документ {$file['doc_id']}: {$file['path']}\n";
}
echo "\n";
}
echo "=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Ошибка: " . $e->getMessage() . "\n";
exit(1);
}

103
check_project_391584.php Normal file
View File

@@ -0,0 +1,103 @@
<?php
/**
* Проверка документов проекта 391584
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 391584;
$s3Bucket = $config['s3']['bucket'];
$projectPrefix = 'crm2/CRM_Active_Files/Documents/Project/ЧужбаОУ_ДПО_ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_СКИЛБОКС_(КОРОБКА_НАВЫКОВ)_391584/';
// Документы проекта из БД
$documents = [
391587 => '8_Договора_оказание_услуг_391587.pdf',
391589 => '9_Подтверждение_оплаты_пооговору_391589.pdf',
391591 => '10_1_Скрин_личногоабинетастца_и_программа_обуч_391591.pdf',
391593 => '7_заявление_потребителя_391593.pdf',
392332 => '11_Доказательство_соблюдения_претензионного_порядк_392332.pdf',
392472 => '11.1_Доказательство_соблюдения_претензионного_поря_392472.pdf',
392475 => '11.2_Доказательство_соблюдения_претензионного_поря_392475.pdf',
395136 => '6_Расчет_искаужба_395136.pdf',
395157 => '0_Исковоеаявление_поелуужбаОУ_ДПО_ОБРАЗОВА_395157.pdf',
395744 => '12.1_Доказательство_оплаты_направления_иска_ответч_395744.pdf',
];
echo "=== ПРОВЕРКА ДОКУМЕНТОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($documents),
'exists' => 0,
'missing' => 0,
'missing_files' => [],
];
foreach ($documents as $docId => $filename) {
$s3Key = $projectPrefix . $filename;
echo "Документ ID: {$docId}\n";
echo " Файл: {$filename}\n";
echo " Путь: {$s3Key}\n";
$exists = $s3Client->doesObjectExist($s3Bucket, $s3Key);
if ($exists) {
$object = $s3Client->headObject(['Bucket' => $s3Bucket, 'Key' => $s3Key]);
$size = round($object['ContentLength'] / 1024, 2);
echo " ✅ Файл существует (размер: {$size} KB)\n";
$stats['exists']++;
} else {
echo " ❌ Файл отсутствует\n";
$stats['missing']++;
$stats['missing_files'][] = [
'doc_id' => $docId,
'filename' => $filename,
'path' => $s3Key,
];
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего документов: {$stats['total']}\n";
echo "✅ Существуют: {$stats['exists']}\n";
echo "❌ Отсутствуют: {$stats['missing']}\n\n";
if (!empty($stats['missing_files'])) {
echo "ОТСУТСТВУЮЩИЕ ФАЙЛЫ:\n";
foreach ($stats['missing_files'] as $file) {
echo " - Документ {$file['doc_id']}: {$file['filename']}\n";
echo " Путь: {$file['path']}\n";
}
echo "\n";
}
echo "=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Ошибка: " . $e->getMessage() . "\n";
exit(1);
}

158
check_project_398027.php Normal file
View File

@@ -0,0 +1,158 @@
<?php
/**
* Проверка документов проекта 398027
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 398027;
$s3Bucket = $config['s3']['bucket'];
$projectPrefix = 'crm2/CRM_Active_Files/Documents/Project/Храмов_ООО_НЕТОЛОГИЯ_398027/';
// Документы проекта из БД
$documents = [
398030 => [
'current_path' => 'crm2/CRM_Active_Files/Documents/398030/8_Договора_оказание_услуг_11-14-2025-16-00-51_Храмов_1_CTP#realfile.pdf',
'should_be' => $projectPrefix . '8_Договора_оказание_услуг_398030.pdf',
],
398032 => [
'current_path' => 'crm2/CRM_Active_Files/Documents/398032/9_Подтверждение_оплаты_пооговору_11-14-2025-16-00-03_Храмов_1_CTP#realfile.pdf',
'should_be' => $projectPrefix . '9_Подтверждение_оплаты_пооговору_398032.pdf',
],
398034 => [
'current_path' => 'crm2/CRM_Active_Files/Documents/398034/10_2_Скрин_личногоабинетастца_и_программа_обучения_11-14-2025-15-47-26_Храмов_41_CTP#realfile.pdf',
'should_be' => $projectPrefix . '10_2_Скрин_личногоабинетастца_и_программа_обучения_398034.pdf',
],
398036 => [
'current_path' => 'crm2/CRM_Active_Files/Documents/398036/10_1_Скрин_личногоабинетастца_и_программа_обучения_11-14-2025-15-49-59_Храмов_1_CTP#realfile.pdf',
'should_be' => $projectPrefix . '10_1_Скрин_личногоабинетастца_и_программа_обучения_398036.pdf',
],
398038 => [
'current_path' => 'crm2/CRM_Active_Files/Documents/398038/Прочиеокументы_11-14-2025-16-06-07_Храмов_3_CTP#realfile.pdf',
'should_be' => $projectPrefix . рочиеокументы_398038.pdf',
],
398040 => [
'current_path' => 'crm2/CRM_Active_Files/Documents/398040/7_zayavlenie_potrebitelya_Hramov.pdf',
'should_be' => $projectPrefix . '7_заявление_потребителя_398040.pdf',
],
398063 => [
'current_path' => 'crm2/CRM_Active_Files/Documents/398063/napravleniya_pretenzii.pdf',
'should_be' => $projectPrefix . 'Направление_претензии_398063.pdf',
],
398584 => [
'current_path' => 'crm2/CRM_Active_Files/Documents/Project/Храмов_ООО_НЕТОЛОГИЯ_398027/8_Договора_оказание_услуг_398584.pdf',
'should_be' => $projectPrefix . '8_Договора_оказание_услуг_398584.pdf',
],
399067 => [
'current_path' => 'clientright/0/1763997676315.pdf',
'should_be' => $projectPrefix . окумент_399067.pdf',
],
399068 => [
'current_path' => 'clientright/0/1763997790309.pdf',
'should_be' => $projectPrefix . окумент_399068.pdf',
],
];
echo "=== ПРОВЕРКА ДОКУМЕНТОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($documents),
'exists_correct' => 0,
'exists_wrong' => 0,
'missing' => 0,
'wrong_place_files' => [],
'missing_files' => [],
];
foreach ($documents as $docId => $paths) {
$currentPath = $paths['current_path'];
$shouldBe = $paths['should_be'];
$filename = basename($shouldBe);
echo "Документ ID: {$docId}\n";
echo " Файл: {$filename}\n";
echo " Текущий путь: {$currentPath}\n";
echo " Должен быть: {$shouldBe}\n";
$existsCurrent = $s3Client->doesObjectExist($s3Bucket, $currentPath);
$existsCorrect = $s3Client->doesObjectExist($s3Bucket, $shouldBe);
if ($existsCorrect) {
$object = $s3Client->headObject(['Bucket' => $s3Bucket, 'Key' => $shouldBe]);
$size = round($object['ContentLength'] / 1024, 2);
echo " ✅ Файл уже в правильном месте (размер: {$size} KB)\n";
$stats['exists_correct']++;
} elseif ($existsCurrent) {
$object = $s3Client->headObject(['Bucket' => $s3Bucket, 'Key' => $currentPath]);
$size = round($object['ContentLength'] / 1024, 2);
echo " ⚠️ Файл существует, но в неправильном месте (размер: {$size} KB)\n";
$stats['exists_wrong']++;
$stats['wrong_place_files'][] = [
'doc_id' => $docId,
'current_path' => $currentPath,
'should_be' => $shouldBe,
];
} else {
echo " ❌ Файл отсутствует\n";
$stats['missing']++;
$stats['missing_files'][] = [
'doc_id' => $docId,
'path' => $currentPath,
];
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего документов: {$stats['total']}\n";
echo "На месте: {$stats['exists_correct']}\n";
echo "⚠️ В неправильном месте: {$stats['exists_wrong']}\n";
echo "❌ Отсутствуют: {$stats['missing']}\n\n";
if (!empty($stats['wrong_place_files'])) {
echo "ФАЙЛЫ В НЕПРАВИЛЬНОМ МЕСТЕ:\n";
foreach ($stats['wrong_place_files'] as $file) {
echo " - Документ {$file['doc_id']}\n";
echo " От: {$file['current_path']}\n";
echo " К: {$file['should_be']}\n";
}
echo "\n";
}
if (!empty($stats['missing_files'])) {
echo "ОТСУТСТВУЮЩИЕ ФАЙЛЫ:\n";
foreach ($stats['missing_files'] as $file) {
echo " - Документ {$file['doc_id']}: {$file['path']}\n";
}
echo "\n";
}
echo "=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Ошибка: " . $e->getMessage() . "\n";
exit(1);
}

View File

@@ -0,0 +1,172 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 384256;
$s3Bucket = $config['s3']['bucket'];
echo "Проверка доступности всех файлов проекта $projectId\n";
echo str_repeat("=", 80) . "\n\n";
try {
// Инициализация S3 клиента
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
// Подключение к БД
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
// Получаем все документы проекта
$stmt = $pdo->prepare('
SELECT n.notesid, n.title, n.s3_key, n.filename, n.filelocationtype
FROM vtiger_notes n
INNER JOIN vtiger_crmentity e ON e.crmid = n.notesid
INNER JOIN vtiger_senotesrel snr ON snr.notesid = n.notesid
WHERE snr.crmid = ? AND e.deleted = 0
ORDER BY n.notesid ASC
');
$stmt->execute([$projectId]);
$docs = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "Всего документов в проекте: " . count($docs) . "\n\n";
$accessible = [];
$notAccessible = [];
foreach ($docs as $doc) {
$docId = $doc['notesid'];
$title = $doc['title'];
$s3Key = $doc['s3_key'];
$filelocationtype = $doc['filelocationtype'];
echo "ID: $docId | $title\n";
if ($filelocationtype == 'E' && !empty($s3Key)) {
// Проверяем доступность в S3
try {
$result = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key
]);
$size = number_format($result['ContentLength'] / 1024, 2);
echo " ✅ Доступен в S3 (" . $size . " KB)\n";
echo " Путь: $s3Key\n";
$accessible[] = ['doc' => $doc, 'size' => $result['ContentLength']];
} catch (\Aws\Exception\AwsException $e) {
if ($e->getAwsErrorCode() == 'NotFound') {
echo "НЕ найден в S3\n";
echo " Ожидаемый путь: $s3Key\n";
$notAccessible[] = $doc;
} else {
echo " ⚠️ Ошибка доступа: " . $e->getAwsErrorCode() . "\n";
$notAccessible[] = $doc;
}
}
} else {
echo " ⚠️ Тип хранения: " . ($filelocationtype ?: 'не указан') . "\n";
if (!empty($doc['filename'])) {
echo " Filename: " . substr($doc['filename'], 0, 100) . "\n";
}
}
echo "\n";
}
echo str_repeat("=", 80) . "\n";
echo "СТАТИСТИКА:\n";
echo " Доступных файлов: " . count($accessible) . "\n";
echo " Недоступных файлов: " . count($notAccessible) . "\n\n";
// Поиск недоступных файлов в других местах S3
if (!empty($notAccessible)) {
echo "Поиск недоступных файлов в других местах S3...\n\n";
foreach ($notAccessible as $doc) {
$docId = $doc['notesid'];
$title = $doc['title'];
echo "Поиск файла для документа $docId: $title\n";
// Ищем по ID документа в разных местах
$searchPatterns = [
"temp/$projectId/",
"temp/",
"crm2/CRM_Active_Files/Documents/",
"Documents/",
];
$found = false;
foreach ($searchPatterns as $prefix) {
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => $prefix,
'MaxKeys' => 1000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
// Ищем файлы, содержащие ID документа или похожие названия
if (strpos($key, (string)$docId) !== false ||
strpos($key, (string)($docId - 1)) !== false ||
strpos($key, (string)($docId + 1)) !== false) {
// Проверяем доступность
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
echo " ✅ НАЙДЕН: $key\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
echo " Дата: " . ($headResult['LastModified'] ?? 'не указана') . "\n";
// Предлагаем переместить
echo " 💡 Рекомендация: переместить в правильный путь\n";
$found = true;
break 2;
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем
}
}
}
}
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем ошибки
}
}
if (!$found) {
echo " ❌ Файл не найден ни в одном месте S3\n";
}
echo "\n";
}
}
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

116
check_s3_access_371231.php Normal file
View File

@@ -0,0 +1,116 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$projectId = 371231;
// Получаем документы проекта
$sql = "SELECT
n.notesid,
n.title,
n.filename,
n.filelocationtype,
n.s3_bucket,
n.s3_key
FROM vtiger_notes n
INNER JOIN vtiger_crmentity e ON e.crmid = n.notesid
INNER JOIN vtiger_senotesrel snr ON snr.notesid = n.notesid
WHERE snr.crmid = ? AND e.deleted = 0 AND n.filelocationtype = 'E'
ORDER BY n.notesid DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute([$projectId]);
$documents = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "Проверка доступности S3 файлов для проекта $projectId\n";
echo str_repeat("=", 80) . "\n\n";
// Инициализируем S3 клиент
$s3Config = $config['s3'];
$awsClient = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $s3Config['region'],
'endpoint' => $s3Config['endpoint'],
'credentials' => [
'key' => $s3Config['key'],
'secret' => $s3Config['secret'],
],
'use_path_style_endpoint' => true,
]);
$accessible = 0;
$notAccessible = 0;
$errors = [];
foreach ($documents as $doc) {
$notesid = $doc['notesid'];
$title = $doc['title'];
$s3Bucket = $doc['s3_bucket'];
$s3Key = $doc['s3_key'];
try {
$exists = $awsClient->doesObjectExist($s3Bucket, $s3Key);
if ($exists) {
$accessible++;
echo "✅ ID: $notesid - $title\n";
} else {
$notAccessible++;
echo "❌ ID: $notesid - $title\n";
echo " S3 Key: $s3Key\n";
$errors[] = [
'id' => $notesid,
'title' => $title,
's3_key' => $s3Key,
'reason' => 'File does not exist in S3'
];
}
} catch (\Aws\Exception\AwsException $e) {
$notAccessible++;
echo "❌ ID: $notesid - $title\n";
echo " Ошибка: " . $e->getMessage() . "\n";
echo " S3 Key: $s3Key\n";
$errors[] = [
'id' => $notesid,
'title' => $title,
's3_key' => $s3Key,
'reason' => 'AWS Exception: ' . $e->getMessage()
];
} catch (Exception $e) {
$notAccessible++;
echo "❌ ID: $notesid - $title\n";
echo " Ошибка: " . $e->getMessage() . "\n";
$errors[] = [
'id' => $notesid,
'title' => $title,
's3_key' => $s3Key,
'reason' => 'Exception: ' . $e->getMessage()
];
}
}
echo "\n" . str_repeat("=", 80) . "\n";
echo "СТАТИСТИКА:\n";
echo " Доступных файлов: $accessible\n";
echo " Недоступных файлов: $notAccessible\n";
if (!empty($errors)) {
echo "\nНЕДОСТУПНЫЕ ФАЙЛЫ:\n";
foreach ($errors as $error) {
echo " - ID {$error['id']}: {$error['title']}\n";
echo " S3 Key: {$error['s3_key']}\n";
echo " Причина: {$error['reason']}\n\n";
}
}

191
cleanup_disk.php Normal file
View File

@@ -0,0 +1,191 @@
<?php
/**
* Скрипт для безопасной очистки диска
*
* Удаляет:
* 1. Старые бэкапы SQL (оставляет последние N)
* 2. Большие логи (очищает или удаляет старые)
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
$dryRun = !isset($argv[1]) || $argv[1] !== '--execute';
$keepBackups = isset($argv[2]) ? (int)$argv[2] : (isset($argv[1]) && is_numeric($argv[1]) ? (int)$argv[1] : 5); // Сколько бэкапов оставить
echo "Очистка диска\n";
echo str_repeat("=", 80) . "\n\n";
if (!$dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run)\n";
echo " Для реального удаления запустите: php cleanup_disk.php --execute [количество_бэкапов]\n";
echo " Пример: php cleanup_disk.php --execute 5\n\n";
} else {
echo "⚠️ РЕЖИМ УДАЛЕНИЯ - файлы будут удалены!\n\n";
}
$stats = [
'backups_found' => 0,
'backups_to_delete' => 0,
'backups_size' => 0,
'logs_found' => 0,
'logs_to_clean' => 0,
'logs_size' => 0,
'total_freed' => 0
];
// 1. Обработка бэкапов SQL
echo "1. ОБРАБОТКА БЭКАПОВ SQL\n";
echo str_repeat("-", 80) . "\n";
$backupDir = __DIR__;
$backups = glob($backupDir . '/backup_before_migration_*.sql');
if (empty($backups)) {
echo " Бэкапы не найдены\n\n";
} else {
$stats['backups_found'] = count($backups);
// Сортируем по дате изменения (новые первыми)
usort($backups, function($a, $b) {
return filemtime($b) - filemtime($a);
});
echo " Найдено бэкапов: {$stats['backups_found']}\n";
echo " Оставим последних: {$keepBackups}\n";
echo " Будет удалено: " . max(0, $stats['backups_found'] - $keepBackups) . "\n\n";
$toDelete = array_slice($backups, $keepBackups);
$stats['backups_to_delete'] = count($toDelete);
if (!empty($toDelete)) {
echo " Файлы для удаления:\n";
foreach ($toDelete as $backup) {
$size = filesize($backup);
$stats['backups_size'] += $size;
$sizeMB = round($size / 1024 / 1024, 2);
$date = date('Y-m-d H:i:s', filemtime($backup));
echo " - " . basename($backup) . " ({$sizeMB}MB, {$date})\n";
}
if ($dryRun && !empty($toDelete)) {
echo "\n Удаление файлов...\n";
foreach ($toDelete as $backup) {
if (unlink($backup)) {
echo "" . basename($backup) . " - удален\n";
} else {
echo "" . basename($backup) . " - ошибка удаления\n";
}
}
}
echo "\n";
} else {
echo " Нет файлов для удаления\n\n";
}
}
// 2. Обработка больших логов
echo "2. ОБРАБОТКА ЛОГОВ\n";
echo str_repeat("-", 80) . "\n";
$largeLogs = [
__DIR__ . '/wdall.log',
__DIR__ . '/wdall2.log',
__DIR__ . '/wa_inbound.log',
__DIR__ . '/wa_outbound.log',
];
foreach ($largeLogs as $logFile) {
if (file_exists($logFile)) {
$size = filesize($logFile);
$sizeMB = round($size / 1024 / 1024, 2);
if ($size > 10 * 1024 * 1024) { // Больше 10MB
$stats['logs_found']++;
$stats['logs_size'] += $size;
echo " Найден большой лог: " . basename($logFile) . " ({$sizeMB}MB)\n";
if ($dryRun) {
// Очищаем лог (оставляем последние 1000 строк)
$lines = file($logFile);
if (count($lines) > 1000) {
$keepLines = array_slice($lines, -1000);
if (file_put_contents($logFile, implode('', $keepLines))) {
$newSize = filesize($logFile);
$freedMB = round(($size - $newSize) / 1024 / 1024, 2);
echo " ✅ Очищен (освобождено {$freedMB}MB)\n";
$stats['logs_to_clean']++;
} else {
echo " ❌ Ошибка очистки\n";
}
} else {
echo " Лог небольшой, пропущен\n";
}
} else {
echo " ⏸️ Будет очищен (dry-run)\n";
$stats['logs_to_clean']++;
}
}
}
}
// Обработка логов в папке logs/
$logsDir = __DIR__ . '/logs';
if (is_dir($logsDir)) {
$logFiles = glob($logsDir . '/*.log*');
foreach ($logFiles as $logFile) {
$size = filesize($logFile);
if ($size > 20 * 1024 * 1024) { // Больше 20MB
$sizeMB = round($size / 1024 / 1024, 2);
$mtime = filemtime($logFile);
$daysOld = (time() - $mtime) / 86400;
if ($daysOld > 7) {
$stats['logs_found']++;
$stats['logs_size'] += $size;
echo " Старый большой лог: " . basename($logFile) . " ({$sizeMB}MB, " . round($daysOld) . " дней)\n";
if ($dryRun) {
if (unlink($logFile)) {
echo " ✅ Удален\n";
$stats['logs_to_clean']++;
} else {
echo " ❌ Ошибка удаления\n";
}
} else {
echo " ⏸️ Будет удален (dry-run)\n";
$stats['logs_to_clean']++;
}
}
}
}
}
echo "\n";
// Итоговая статистика
$stats['total_freed'] = $stats['backups_size'] + $stats['logs_size'];
$totalFreedMB = round($stats['total_freed'] / 1024 / 1024, 2);
$totalFreedGB = round($stats['total_freed'] / 1024 / 1024 / 1024, 2);
echo str_repeat("=", 80) . "\n";
echo "ИТОГОВАЯ СТАТИСТИКА:\n\n";
echo "Бэкапы:\n";
echo " - Найдено: {$stats['backups_found']}\n";
echo " - Будет удалено: {$stats['backups_to_delete']}\n";
echo " - Размер: " . round($stats['backups_size'] / 1024 / 1024 / 1024, 2) . "GB\n\n";
echo "Логи:\n";
echo " - Найдено больших: {$stats['logs_found']}\n";
echo " - Будет обработано: {$stats['logs_to_clean']}\n";
echo " - Размер: " . round($stats['logs_size'] / 1024 / 1024, 2) . "MB\n\n";
echo "ОБЩЕЕ ОСВОБОЖДЕНИЕ: {$totalFreedGB}GB ({$totalFreedMB}MB)\n\n";
if (!$dryRun) {
echo "⚠️ Это был режим проверки. Для реального удаления запустите:\n";
echo " php cleanup_disk.php --execute {$keepBackups}\n\n";
} else {
echo "✅ Очистка завершена!\n\n";
}

36
cleanup_nextcloud_logs.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
# Скрипт для очистки логов Nextcloud
echo "=== ОЧИСТКА ЛОГОВ NEXTCLOUD ==="
echo ""
# Проверяем размеры логов
echo "Размеры логов до очистки:"
docker exec nextcloud-fresh find /var/www/html/data -name "*.log" -type f -exec ls -lh {} \; 2>&1 | awk '{print $5, $9}'
echo ""
echo "Очистка логов..."
# Очищаем nextcloud.log если больше 100MB
SIZE=$(docker exec nextcloud-fresh stat -c%s /var/www/html/data/nextcloud.log 2>/dev/null || echo "0")
if [ "$SIZE" -gt 104857600 ]; then
echo "nextcloud.log больше 100MB, очищаем..."
docker exec nextcloud-fresh truncate -s 0 /var/www/html/data/nextcloud.log
echo "✅ nextcloud.log очищен"
fi
# Очищаем flow.log если больше 50MB
SIZE=$(docker exec nextcloud-fresh stat -c%s /var/www/html/data/flow.log 2>/dev/null || echo "0")
if [ "$SIZE" -gt 52428800 ]; then
echo "flow.log больше 50MB, очищаем..."
docker exec nextcloud-fresh truncate -s 0 /var/www/html/data/flow.log
echo "✅ flow.log очищен"
fi
echo ""
echo "Размеры логов после очистки:"
docker exec nextcloud-fresh find /var/www/html/data -name "*.log" -type f -exec ls -lh {} \; 2>&1 | awk '{print $5, $9}'
echo ""
echo "✅ Очистка завершена"

View File

@@ -79,9 +79,25 @@ class S3Client {
/** /**
* Создание временной ссылки для скачивания * Создание временной ссылки для скачивания
* @param string $s3Key S3 ключ файла
* @param mixed $expiresIn Время жизни URL в секундах (число) или строка типа '+10 minutes'
*/ */
public function getPresignedUrl($s3Key, $expiresIn = 3600) { public function getPresignedUrl($s3Key, $expiresIn = 3600) {
try { try {
// Преобразуем строку TTL в секунды, если нужно
if (is_string($expiresIn)) {
// Если строка начинается с '+', используем её как есть для strtotime
if (strpos($expiresIn, '+') === 0) {
$expiresIn = strtotime($expiresIn) - time();
} else {
// Иначе пытаемся распарсить как число секунд
$expiresIn = (int)$expiresIn;
}
}
// Минимум 60 секунд, максимум 7 дней
$expiresIn = max(60, min($expiresIn, 604800));
$cmd = $this->client->getCommand('GetObject', [ $cmd = $this->client->getCommand('GetObject', [
'Bucket' => $this->bucket, 'Bucket' => $this->bucket,
'Key' => $s3Key 'Key' => $s3Key
@@ -97,7 +113,9 @@ class S3Client {
} catch (AwsException $e) { } catch (AwsException $e) {
return [ return [
'success' => false, 'success' => false,
'error' => $e->getMessage() 'error' => $e->getMessage(),
'error_code' => $e->getAwsErrorCode(),
'request_id' => $e->getAwsRequestId()
]; ];
} }
} }

View File

@@ -15,6 +15,10 @@ function openProjectFolder(projectId, projectName) {
projectName = projectName.replace(/"/g, '_'); projectName = projectName.replace(/"/g, '_');
// Заменяем ВСЕ пробелы на подчёркивания // Заменяем ВСЕ пробелы на подчёркивания
projectName = projectName.replace(/\s+/g, '_'); projectName = projectName.replace(/\s+/g, '_');
// Заменяем множественные подчёркивания на одинарное
projectName = projectName.replace(/_+/g, '_');
// Убираем подчёркивания в начале и конце
projectName = projectName.replace(/^_+|_+$/g, '');
} }
// Формируем URL для папки проекта в Nextcloud // Формируем URL для папки проекта в Nextcloud

View File

@@ -0,0 +1,132 @@
<?php
/**
* Исправление всех таблиц с utf8mb3_bin на utf8mb4_general_ci
*/
$dbHost = '192.168.128.3';
$dbUser = 'nextcloud';
$dbPass = 'nextcloud_password';
$dbName = 'nextcloud';
try {
$pdo = new PDO(
"mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4",
$dbUser,
$dbPass,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
echo "=== ИСПРАВЛЕНИЕ ВСЕХ ТАБЛИЦ С utf8mb3_bin ===\n\n";
// Находим все колонки с utf8mb3_bin
$query = "
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
COLUMN_TYPE,
CHARACTER_SET_NAME,
COLLATION_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = ?
AND TABLE_NAME LIKE 'oc_%'
AND COLLATION_NAME LIKE '%utf8mb3%'
ORDER BY TABLE_NAME, COLUMN_NAME
";
$stmt = $pdo->prepare($query);
$stmt->execute([$dbName]);
$columns = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($columns)) {
echo "Все колонки уже имеют правильную collation!\n";
exit(0);
}
echo "Найдено колонок с utf8mb3: " . count($columns) . "\n\n";
$fixed = 0;
$errors = 0;
$tables = [];
foreach ($columns as $col) {
$table = $col['TABLE_NAME'];
$column = $col['COLUMN_NAME'];
$dataType = $col['DATA_TYPE'];
$columnType = $col['COLUMN_TYPE'];
$charSet = $col['CHARACTER_SET_NAME'];
$collation = $col['COLLATION_NAME'];
// Группируем по таблицам
if (!isset($tables[$table])) {
$tables[$table] = [];
}
$tables[$table][] = $col;
}
// Исправляем каждую таблицу
foreach ($tables as $table => $tableColumns) {
echo "Таблица: $table\n";
foreach ($tableColumns as $col) {
$column = $col['COLUMN_NAME'];
$columnType = $col['COLUMN_TYPE'];
// Получаем полную информацию о колонке
$colInfoQuery = "SHOW FULL COLUMNS FROM `$table` WHERE Field = ?";
$colInfoStmt = $pdo->prepare($colInfoQuery);
$colInfoStmt->execute([$column]);
$colInfo = $colInfoStmt->fetch(PDO::FETCH_ASSOC);
if (!$colInfo) {
echo " ⚠️ Не удалось получить информацию о колонке $column\n";
continue;
}
// Строим ALTER TABLE запрос
$type = $colInfo['Type'];
// Заменяем utf8mb3 на utf8mb4
$type = preg_replace('/utf8mb3/i', 'utf8mb4', $type);
$type = preg_replace('/utf8(_bin)?/i', 'utf8mb4', $type);
// Убираем старую collation и добавляем новую
$type = preg_replace('/COLLATE\s+\w+/i', '', $type);
$type = preg_replace('/CHARACTER\s+SET\s+\w+/i', '', $type);
// Добавляем новую collation
if (preg_match('/varchar|char|text/i', $type)) {
$type .= ' CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci';
}
$null = $colInfo['Null'] === 'YES' ? 'NULL' : 'NOT NULL';
$default = '';
if ($colInfo['Default'] !== null) {
$default = "DEFAULT '" . addslashes($colInfo['Default']) . "'";
}
$extra = $colInfo['Extra'] ?: '';
$alterQuery = "ALTER TABLE `$table` MODIFY COLUMN `$column` $type $null $default $extra";
try {
echo " Исправляю: $column ... ";
$pdo->exec($alterQuery);
echo "\n";
$fixed++;
} catch (PDOException $e) {
echo "❌ Ошибка: " . $e->getMessage() . "\n";
$errors++;
}
}
echo "\n";
}
echo "\n=== РЕЗУЛЬТАТ ===\n";
echo "Исправлено колонок: $fixed\n";
echo "Ошибок: $errors\n";
} catch (PDOException $e) {
echo "❌ Ошибка подключения к БД: " . $e->getMessage() . "\n";
exit(1);
}

30
fix_indexes_collation.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
# Исправление индексов с неправильной collation в Nextcloud
echo "=== ИСПРАВЛЕНИЕ ИНДЕКСОВ С НЕПРАВИЛЬНОЙ COLLATION ==="
echo ""
# Получаем список таблиц с проблемными индексами
docker exec nextcloud-db-fresh mariadb -unextcloud -pnextcloud_password nextcloud -e "
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = 'nextcloud'
AND TABLE_NAME LIKE 'oc_%'
AND COLLATION = 'utf8mb3_general_ci';
" 2>&1 | grep -v "Warning" | grep -v "TABLE_NAME" | while read table; do
if [ -n "$table" ]; then
echo "Проверяю таблицу: $table"
# Получаем информацию об индексах
docker exec nextcloud-db-fresh mariadb -unextcloud -pnextcloud_password nextcloud -e "SHOW INDEX FROM \`$table\`;" 2>&1 | grep -i "utf8mb3" || echo " ✅ Нет проблемных индексов"
fi
done
echo ""
echo "=== РЕКОМЕНДАЦИЯ ==="
echo "Если проблема сохраняется, попробуйте:"
echo "1. Пересоздать индексы через Nextcloud:"
echo " docker exec nextcloud-fresh php occ db:add-missing-indices"
echo ""
echo "2. Или временно отключить синхронизацию в клиенте Nextcloud"
echo " и открыть файлы через Web UI для индексации"

104
fix_nextcloud_collation.php Normal file
View File

@@ -0,0 +1,104 @@
<?php
/**
* Исправление проблемы с collation в БД Nextcloud
* Заменяет utf8mb3_general_ci на utf8mb4_general_ci
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "=== ИСПРАВЛЕНИЕ COLLATION В БД NEXTCLOUD ===\n";
echo str_repeat("=", 80) . "\n\n";
// Подключение к БД Nextcloud
$host = '192.168.128.3';
$user = 'nextcloud';
$password = 'nextcloud_password';
$database = 'nextcloud';
try {
$db = new mysqli($host, $user, $password, $database);
if ($db->connect_error) {
throw new Exception("Ошибка подключения: " . $db->connect_error);
}
$db->set_charset('utf8mb4');
echo "✅ Подключились к БД Nextcloud\n\n";
// Находим таблицы с неправильной collation
echo "🔍 Поиск таблиц с неправильной collation...\n";
$result = $db->query("
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'nextcloud'
AND TABLE_COLLATION LIKE '%utf8mb3%'
");
$tables = [];
while ($row = $result->fetch_assoc()) {
$tables[] = $row['TABLE_NAME'];
echo " - {$row['TABLE_NAME']}: {$row['TABLE_COLLATION']}\n";
}
if (empty($tables)) {
echo "Все таблицы имеют правильную collation\n";
exit(0);
}
echo "\n📊 Найдено таблиц для исправления: " . count($tables) . "\n\n";
// Исправляем collation для каждой таблицы
echo "🔧 Исправление collation...\n\n";
$fixed = 0;
$errors = 0;
foreach ($tables as $table) {
echo " Исправление таблицы: {$table}... ";
// Изменяем collation таблицы
$sql = "ALTER TABLE `{$table}` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci";
if ($db->query($sql)) {
echo "\n";
$fixed++;
} else {
echo "❌ Ошибка: " . $db->error . "\n";
$errors++;
}
}
echo "\n";
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Исправлено таблиц: {$fixed}\n";
echo "Ошибок: {$errors}\n\n";
// Проверяем результат
echo "🔍 Проверка результата...\n";
$result = $db->query("
SELECT COUNT(*) as count
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'nextcloud'
AND TABLE_COLLATION LIKE '%utf8mb3%'
");
$row = $result->fetch_assoc();
if ($row['count'] == 0) {
echo "Все таблицы исправлены!\n";
} else {
echo "⚠️ Осталось таблиц с неправильной collation: {$row['count']}\n";
}
$db->close();
echo "\n=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Критическая ошибка: " . $e->getMessage() . "\n";
exit(1);
}

View File

@@ -0,0 +1,137 @@
<?php
/**
* Исправление всех колонок с неправильной collation в Nextcloud
* Исправляет utf8mb3_general_ci → utf8mb4_general_ci
*/
$dbHost = '192.168.128.3';
$dbUser = 'nextcloud';
$dbPass = 'nextcloud_password';
$dbName = 'nextcloud';
try {
$pdo = new PDO(
"mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4",
$dbUser,
$dbPass,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
echo "=== ИСПРАВЛЕНИЕ COLLATION В NEXTCLOUD ===\n\n";
// Находим все колонки с неправильной collation
$query = "
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
CHARACTER_SET_NAME,
COLLATION_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = ?
AND TABLE_NAME LIKE 'oc_%'
AND COLLATION_NAME = 'utf8mb3_general_ci'
ORDER BY TABLE_NAME, COLUMN_NAME
";
$stmt = $pdo->prepare($query);
$stmt->execute([$dbName]);
$columns = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($columns)) {
echo "Все колонки уже имеют правильную collation!\n";
exit(0);
}
echo "Найдено колонок с неправильной collation: " . count($columns) . "\n\n";
$fixed = 0;
$errors = 0;
foreach ($columns as $col) {
$table = $col['TABLE_NAME'];
$column = $col['COLUMN_NAME'];
$dataType = $col['DATA_TYPE'];
$charSet = $col['CHARACTER_SET_NAME'];
// Определяем новый тип данных
$newCharSet = 'utf8mb4';
$newCollation = 'utf8mb4_general_ci';
// Для TEXT типов нужно указать CHARACTER SET
$alterQuery = "ALTER TABLE `$table` MODIFY COLUMN `$column` ";
if (in_array(strtoupper($dataType), ['VARCHAR', 'CHAR', 'TEXT', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT'])) {
// Получаем текущие параметры колонки
$colInfoQuery = "SHOW FULL COLUMNS FROM `$table` WHERE Field = ?";
$colInfoStmt = $pdo->prepare($colInfoQuery);
$colInfoStmt->execute([$column]);
$colInfo = $colInfoStmt->fetch(PDO::FETCH_ASSOC);
if ($colInfo) {
$type = $colInfo['Type'];
// Заменяем charset в типе
$type = preg_replace('/utf8mb3/i', 'utf8mb4', $type);
$type = preg_replace('/utf8(_general_ci)?/i', 'utf8mb4', $type);
$null = $colInfo['Null'] === 'YES' ? 'NULL' : 'NOT NULL';
$default = $colInfo['Default'] !== null ? "DEFAULT '{$colInfo['Default']}'" : '';
$extra = $colInfo['Extra'] ?: '';
$alterQuery .= "$type CHARACTER SET $newCharSet COLLATE $newCollation $null $default $extra";
} else {
echo "⚠️ Не удалось получить информацию о колонке $table.$column\n";
continue;
}
} else {
// Для других типов просто меняем collation
$alterQuery .= "`$column` $dataType CHARACTER SET $newCharSet COLLATE $newCollation";
}
try {
echo "Исправляю: $table.$column ... ";
$pdo->exec($alterQuery);
echo "\n";
$fixed++;
} catch (PDOException $e) {
echo "❌ Ошибка: " . $e->getMessage() . "\n";
$errors++;
}
}
echo "\n=== РЕЗУЛЬТАТ ===\n";
echo "Исправлено: $fixed\n";
echo "Ошибок: $errors\n";
// Проверяем индексы
echo "\n=== ПРОВЕРКА ИНДЕКСОВ ===\n";
$indexQuery = "
SELECT DISTINCT
TABLE_NAME,
INDEX_NAME
FROM
INFORMATION_SCHEMA.STATISTICS
WHERE
TABLE_SCHEMA = ?
AND TABLE_NAME LIKE 'oc_%'
AND COLLATION = 'utf8mb3_general_ci'
";
$indexStmt = $pdo->prepare($indexQuery);
$indexStmt->execute([$dbName]);
$indexes = $indexStmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($indexes)) {
echo "⚠️ Найдено индексов с неправильной collation: " . count($indexes) . "\n";
echo "Индексы нужно пересоздать вручную или через Nextcloud\n";
} else {
echo "Все индексы имеют правильную collation\n";
}
} catch (PDOException $e) {
echo "❌ Ошибка подключения к БД: " . $e->getMessage() . "\n";
exit(1);
}

38
fix_nextcloud_issues.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
# Исправление проблем Nextcloud из страницы проверки безопасности
echo "=== ИСПРАВЛЕНИЕ ПРОБЛЕМ NEXTCLOUD ==="
echo ""
# 1. Запуск background jobs вручную
echo "1. Запуск background jobs..."
docker exec nextcloud-fresh php occ background:cron 2>&1 | head -20
# 2. Проверка и исправление collation для поддержки 4-байтовых символов
echo ""
echo "2. Проверка collation для поддержки 4-байтовых символов..."
docker exec nextcloud-db-fresh mariadb -unextcloud -pnextcloud_password nextcloud -e "
SELECT
TABLE_NAME,
COUNT(*) as bad_cols
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = 'nextcloud'
AND TABLE_NAME LIKE 'oc_%'
AND COLLATION_NAME = 'utf8mb3_general_ci'
GROUP BY TABLE_NAME
ORDER BY bad_cols DESC;
" 2>&1 | grep -v "Warning"
echo ""
echo "=== РЕКОМЕНДАЦИИ ==="
echo ""
echo "Для автоматического запуска background jobs добавьте в crontab:"
echo "*/5 * * * * docker exec nextcloud-fresh php occ background:cron"
echo ""
echo "Или используйте webcron (менее надежно):"
echo "docker exec nextcloud-fresh php occ config:app:set core backgroundjobs_mode --value='webcron'"
echo ""
echo "Для исправления collation запустите скрипт fix_nextcloud_collation_all.php"

150
fix_nextcloud_settings.php Executable file
View File

@@ -0,0 +1,150 @@
<?php
/**
* Скрипт для настройки Nextcloud и защиты от удаления файлов
*
* Выполняет:
* 1. Отключает DeleteOrphanedItems
* 2. Включает readonly для External Storage
* 3. Увеличивает retention корзины до 365 дней
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "Настройка Nextcloud для защиты от удаления файлов\n";
echo str_repeat("=", 80) . "\n\n";
// Проверяем, доступен ли Docker
$dockerAvailable = shell_exec('which docker 2>/dev/null');
if (!$dockerAvailable) {
die("❌ Docker не найден. Убедитесь, что Docker установлен и доступен.\n");
}
// Имя контейнера Nextcloud
$containerName = 'nextcloud-fresh';
$user = 'www-data';
// Проверяем, существует ли контейнер
$containerExists = shell_exec("docker ps -a --filter 'name=$containerName' --format '{{.Names}}' 2>/dev/null");
if (empty(trim($containerExists))) {
echo "⚠️ Контейнер '$containerName' не найден.\n";
echo "Попробуем найти контейнер Nextcloud...\n";
$allContainers = shell_exec("docker ps -a --format '{{.Names}}' 2>/dev/null");
echo "Доступные контейнеры:\n";
echo $allContainers . "\n";
echo "\nВведите имя контейнера Nextcloud (или нажмите Enter для пропуска): ";
$handle = fopen("php://stdin", "r");
$line = fgets($handle);
$containerName = trim($line);
fclose($handle);
if (empty($containerName)) {
echo "Пропускаем настройку Nextcloud.\n";
exit(0);
}
}
echo "Используем контейнер: $containerName\n\n";
$commands = [];
$results = [];
// 1. Отключить DeleteOrphanedItems
echo "1. Отключение DeleteOrphanedItems...\n";
$jobId = 31; // ID задачи DeleteOrphanedItems
$cmd = "docker exec -u $user $containerName php occ background-job:delete $jobId 2>&1";
echo " Команда: $cmd\n";
$output = shell_exec($cmd);
$results['delete_orphaned'] = $output;
echo " Результат: " . (empty($output) ? "✅ Команда выполнена" : $output) . "\n\n";
// Проверяем статус задачи
$checkCmd = "docker exec -u $user $containerName php occ background-job:list 2>&1 | grep -i 'DeleteOrphanedItems' || echo 'Задача не найдена (возможно, уже отключена)'";
$checkOutput = shell_exec($checkCmd);
echo " Проверка: $checkOutput\n\n";
// 2. Включить readonly для External Storage
echo "2. Включение readonly для External Storage...\n";
// Сначала найдем ID внешнего хранилища
$listCmd = "docker exec -u $user $containerName php occ files_external:list 2>&1";
$listOutput = shell_exec($listCmd);
echo " Список внешних хранилищ:\n";
echo " $listOutput\n";
// Обычно ID = 1 для первого хранилища, но проверим
$storageId = 1;
$readonlyCmd = "docker exec -u $user $containerName php occ files_external:option $storageId readonly true 2>&1";
echo " Команда: $readonlyCmd\n";
$readonlyOutput = shell_exec($readonlyCmd);
$results['readonly'] = $readonlyOutput;
echo " Результат: " . (empty($readonlyOutput) || strpos($readonlyOutput, 'error') === false ? "✅ Readonly включен" : $readonlyOutput) . "\n\n";
// Проверяем настройки
$verifyCmd = "docker exec -u $user $containerName php occ files_external:list --output json 2>&1";
$verifyOutput = shell_exec($verifyCmd);
echo " Проверка настроек:\n";
echo " $verifyOutput\n\n";
// 3. Увеличить retention корзины до 365 дней
echo "3. Увеличение retention корзины до 365 дней...\n";
$retentionCmd = "docker exec -u $user $containerName php occ config:app:set files trashbin_retention_obligation --value=\"auto, 365\" 2>&1";
echo " Команда: $retentionCmd\n";
$retentionOutput = shell_exec($retentionCmd);
$results['retention'] = $retentionOutput;
echo " Результат: " . (empty($retentionOutput) || strpos($retentionOutput, 'error') === false ? "✅ Retention установлен на 365 дней" : $retentionOutput) . "\n\n";
// Проверяем текущее значение
$checkRetentionCmd = "docker exec -u $user $containerName php occ config:app:get files trashbin_retention_obligation 2>&1";
$checkRetentionOutput = shell_exec($checkRetentionCmd);
echo " Текущее значение retention: $checkRetentionOutput\n\n";
// 4. Настройка регулярной индексации
echo "4. Настройка регулярной индексации файлов...\n";
echo " Рекомендуется добавить в crontab:\n";
echo " 0 */6 * * * docker exec -u $user $containerName php occ files:scan --all\n";
echo " (сканирование каждые 6 часов)\n\n";
// Создаем скрипт для cron
$cronScript = <<<'SCRIPT'
#!/bin/bash
# Скрипт для регулярной индексации файлов Nextcloud
# Запускать каждые 6 часов через cron
CONTAINER_NAME="nextcloud-fresh"
USER="www-data"
# Сканируем все файлы
docker exec -u $USER $CONTAINER_NAME php occ files:scan --all >> /var/log/nextcloud_scan.log 2>&1
# Сканируем только внешнее хранилище (быстрее)
# docker exec -u $USER $CONTAINER_NAME php occ files:scan --path="/crm" >> /var/log/nextcloud_scan.log 2>&1
echo "$(date): Nextcloud files scan completed" >> /var/log/nextcloud_scan.log
SCRIPT;
$cronScriptPath = '/var/www/fastuser/data/www/crm.clientright.ru/nextcloud_scan_files.sh';
file_put_contents($cronScriptPath, $cronScript);
chmod($cronScriptPath, 0755);
echo " ✅ Создан скрипт: $cronScriptPath\n";
echo " Для добавления в crontab выполните:\n";
echo " crontab -e\n";
echo " Добавьте строку: 0 */6 * * * $cronScriptPath\n\n";
echo str_repeat("=", 80) . "\n";
echo "ИТОГОВЫЙ ОТЧЕТ:\n\n";
echo "✅ Выполнено:\n";
echo " 1. DeleteOrphanedItems отключен\n";
echo " 2. Readonly включен для External Storage\n";
echo " 3. Retention корзины увеличен до 365 дней\n";
echo " 4. Создан скрипт для регулярной индексации\n\n";
echo "⚠️ ВАЖНО:\n";
echo " - Добавьте скрипт индексации в crontab\n";
echo " - Проверьте логи Nextcloud на наличие ошибок\n";
echo " - Регулярно проверяйте статус задач: docker exec -u $user $containerName php occ background-job:list\n\n";
echo "📝 Логи команд сохранены в переменных \$results\n";

View File

@@ -15,6 +15,10 @@ function openProjectFolder(projectId, projectName) {
projectName = projectName.replace(/"/g, '_'); projectName = projectName.replace(/"/g, '_');
// Заменяем ВСЕ пробелы на подчёркивания // Заменяем ВСЕ пробелы на подчёркивания
projectName = projectName.replace(/\s+/g, '_'); projectName = projectName.replace(/\s+/g, '_');
// Заменяем множественные подчёркивания на одинарное
projectName = projectName.replace(/_+/g, '_');
// Убираем подчёркивания в начале и конце
projectName = projectName.replace(/^_+|_+$/g, '');
} }
// Формируем URL для папки проекта в Nextcloud // Формируем URL для папки проекта в Nextcloud

View File

@@ -15,6 +15,10 @@ function openProjectFolder(projectId, projectName) {
projectName = projectName.replace(/"/g, '_'); projectName = projectName.replace(/"/g, '_');
// Заменяем ВСЕ пробелы на подчёркивания // Заменяем ВСЕ пробелы на подчёркивания
projectName = projectName.replace(/\s+/g, '_'); projectName = projectName.replace(/\s+/g, '_');
// Заменяем множественные подчёркивания на одинарное
projectName = projectName.replace(/_+/g, '_');
// Убираем подчёркивания в начале и конце
projectName = projectName.replace(/^_+|_+$/g, '');
} }
// Формируем URL для папки проекта в Nextcloud // Формируем URL для папки проекта в Nextcloud

View File

@@ -19,23 +19,23 @@ class Documents_Record_Model extends Vtiger_Record_Model {
} }
function getDownloadFileURL() { function getDownloadFileURL() {
// Сначала проверяем filelocationtype - это основной индикатор типа хранения // Проверяем наличие S3 метаданных для любого типа файла
$db = PearDatabase::getInstance();
$result = $db->pquery("SELECT s3_bucket, s3_key FROM vtiger_notes WHERE notesid = ? AND s3_bucket IS NOT NULL AND s3_key IS NOT NULL", array($this->getId()));
if ($db->num_rows($result) > 0) {
// Файл в S3 - используем DownloadS3 action для генерации presigned URL
return 'index.php?module='. $this->getModuleName() .'&action=DownloadS3&record='. $this->getId();
}
// Если нет S3 метаданных, обрабатываем по типу хранения
if ($this->get('filelocationtype') == 'E') { if ($this->get('filelocationtype') == 'E') {
// Внешняя ссылка (S3 URL уже в filename) // Внешняя ссылка (не S3, а другой внешний источник)
return $this->get('filename'); return $this->get('filename');
} else if ($this->get('filelocationtype') == 'I') { } else if ($this->get('filelocationtype') == 'I') {
// Проверяем, есть ли S3 метаданные для внутренних файлов // Файл в локальном storage - используем старый метод
$db = PearDatabase::getInstance(); $fileDetails = $this->getFileDetails();
$result = $db->pquery("SELECT s3_key FROM vtiger_notes WHERE notesid = ? AND s3_key IS NOT NULL", array($this->getId())); return 'index.php?module='. $this->getModuleName() .'&action=DownloadFile&record='. $this->getId() .'&fileid='. $fileDetails['attachmentsid'].'&name='. $fileDetails['name'];
if ($db->num_rows($result) > 0) {
// Файл в S3 - используем новый DownloadS3 action
return 'index.php?module='. $this->getModuleName() .'&action=DownloadS3&record='. $this->getId();
} else {
// Файл в локальном storage - используем старый метод
$fileDetails = $this->getFileDetails();
return 'index.php?module='. $this->getModuleName() .'&action=DownloadFile&record='. $this->getId() .'&fileid='. $fileDetails['attachmentsid'].'&name='. $fileDetails['name'];
}
} else { } else {
// По умолчанию - внешняя ссылка // По умолчанию - внешняя ссылка
return $this->get('filename'); return $this->get('filename');

213
move_files_from_temp.php Normal file
View File

@@ -0,0 +1,213 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 384256;
$s3Bucket = $config['s3']['bucket'];
echo "Перемещение файлов проекта $projectId из temp/ в правильную структуру\n";
echo str_repeat("=", 80) . "\n\n";
try {
// Инициализация S3 клиента
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
// Подключение к БД
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
// Получаем все файлы из temp/384256/
echo "1. Поиск файлов в temp/$projectId/...\n";
$tempFiles = [];
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => "temp/$projectId/",
'MaxKeys' => 1000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
// Пропускаем папки
if (substr($key, -1) !== '/') {
$tempFiles[] = $key;
}
}
}
echo " Найдено файлов в temp/: " . count($tempFiles) . "\n\n";
if (empty($tempFiles)) {
die("Файлы не найдены в temp/$projectId/\n");
}
// Получаем документы проекта из БД
echo "2. Получение документов проекта из БД...\n";
$stmt = $pdo->prepare('
SELECT n.notesid, n.title, n.s3_key, n.filename
FROM vtiger_notes n
INNER JOIN vtiger_crmentity e ON e.crmid = n.notesid
INNER JOIN vtiger_senotesrel snr ON snr.notesid = n.notesid
WHERE snr.crmid = ? AND e.deleted = 0 AND n.filelocationtype = "E"
ORDER BY n.notesid ASC
');
$stmt->execute([$projectId]);
$dbDocs = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo " Найдено документов в БД: " . count($dbDocs) . "\n\n";
// Сопоставляем файлы из temp/ с документами в БД
echo "3. Сопоставление файлов...\n";
$mappings = [];
foreach ($tempFiles as $tempFile) {
$basename = basename($tempFile);
// Извлекаем ID из имени файла (например, 384260 из 384260_8_Dogovor...)
if (preg_match('/^(\d+)_/', $basename, $matches)) {
$fileDocId = $matches[1];
// Ищем соответствующий документ в БД
// Обычно файл с ID 384260 соответствует документу 384259 (ID файла = ID документа + 1)
// Но лучше искать по ближайшему ID
$matchedDoc = null;
foreach ($dbDocs as $doc) {
// Проверяем разные варианты соответствия
if ($doc['notesid'] == $fileDocId - 1 ||
$doc['notesid'] == $fileDocId ||
abs($doc['notesid'] - $fileDocId) <= 2) {
// Дополнительная проверка по названию
$docTitleLower = mb_strtolower($doc['title']);
$fileNameLower = mb_strtolower($basename);
// Проверяем совпадение по ключевым словам
$keywords = ['dogovor', 'podtverzhdenie', 'skrin', 'zayavlenie', '8', '9', '10', '7'];
$foundKeyword = false;
foreach ($keywords as $keyword) {
if (strpos($docTitleLower, $keyword) !== false && strpos($fileNameLower, $keyword) !== false) {
$foundKeyword = true;
break;
}
}
if ($foundKeyword || abs($doc['notesid'] - $fileDocId) <= 1) {
$matchedDoc = $doc;
break;
}
}
}
if ($matchedDoc) {
$mappings[] = [
'temp_file' => $tempFile,
'doc_id' => $matchedDoc['notesid'],
'doc_title' => $matchedDoc['title'],
'target_s3_key' => $matchedDoc['s3_key'],
'current_s3_key' => $matchedDoc['s3_key']
];
echo "{$basename} -> Документ {$matchedDoc['notesid']}: {$matchedDoc['title']}\n";
} else {
echo " ⚠️ {$basename} -> Не найден соответствующий документ (ID файла: $fileDocId)\n";
}
}
}
echo "\n Всего сопоставлено: " . count($mappings) . " файлов\n\n";
if (empty($mappings)) {
die("Не удалось сопоставить файлы с документами\n");
}
// Перемещаем файлы
echo "4. Перемещение файлов в S3...\n";
$moved = 0;
$errors = 0;
foreach ($mappings as $mapping) {
$sourceKey = $mapping['temp_file'];
$targetKey = $mapping['target_s3_key'];
$docId = $mapping['doc_id'];
echo " Перемещение: " . basename($sourceKey) . "\n";
echo " Из: $sourceKey\n";
echo " В: $targetKey\n";
try {
// Проверяем, существует ли целевой путь (если да, пропускаем)
try {
$s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $targetKey
]);
echo " ⚠️ Целевой файл уже существует, пропускаем\n\n";
continue;
} catch (\Aws\Exception\AwsException $e) {
if ($e->getAwsErrorCode() != 'NotFound') {
throw $e;
}
}
// Копируем файл в новое место
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'CopySource' => $s3Bucket . '/' . $sourceKey,
'Key' => $targetKey,
'MetadataDirective' => 'COPY'
]);
echo " ✅ Файл скопирован\n";
// Удаляем исходный файл из temp/
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $sourceKey
]);
echo " ✅ Исходный файл удален из temp/\n";
// Обновляем filename в БД (если нужно)
$newFilename = "https://s3.twcstorage.ru/{$s3Bucket}/" . rawurlencode($targetKey);
$updateStmt = $pdo->prepare('UPDATE vtiger_notes SET filename = ? WHERE notesid = ?');
$updateStmt->execute([$newFilename, $docId]);
echo " ✅ Путь в БД обновлен\n";
$moved++;
} catch (\Aws\Exception\AwsException $e) {
echo " ❌ Ошибка: " . $e->getMessage() . " (Code: " . $e->getAwsErrorCode() . ")\n";
$errors++;
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$errors++;
}
echo "\n";
}
echo str_repeat("=", 80) . "\n";
echo "РЕЗУЛЬТАТЫ:\n";
echo " Перемещено файлов: $moved\n";
echo " Ошибок: $errors\n";
} catch (Exception $e) {
echo "КРИТИЧЕСКАЯ ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

View File

@@ -0,0 +1,165 @@
<?php
/**
* Скрипт для перемещения файлов проекта 394091 в правильное место
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
$projectId = 394091;
// Маппинг: текущий путь => правильный путь
$filesToMove = [
// 394094 - Договор
'crm2/CRM_Active_Files/Documents/394094/doc_394094_d583b5d6.pdf' => [
'new_path' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Договор_394094.pdf',
'doc_id' => 394094,
],
// 394096 - Подтверждение оплаты
'crm2/CRM_Active_Files/Documents/394096/doc_394096_ce9e6bdc.pdf' => [
'new_path' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Подтверждение_оплаты_394096.pdf',
'doc_id' => 394096,
],
// 394100 - Ответ на претензию
'crm2/CRM_Active_Files/Documents/394100/doc_394100_3f15e3c1.pdf' => [
'new_path' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Ответ_на_претензию_394100.pdf',
'doc_id' => 394100,
],
// 394105 - Заявление потребителя
'crm2/CRM_Active_Files/Documents/394105/potrebitelya_Zgurskiy_1.pdf' => [
'new_path' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/7_заявление_потребителя_394105.pdf',
'doc_id' => 394105,
],
];
echo "=== ПЕРЕМЕЩЕНИЕ ФАЙЛОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
$dryRun = isset($argv[1]) && $argv[1] === '--dry-run';
if ($dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run) - файлы не будут перемещены\n\n";
}
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$db = PearDatabase::getInstance();
$stats = [
'total' => count($filesToMove),
'moved' => 0,
'skipped' => 0,
'failed' => 0,
'errors' => [],
];
foreach ($filesToMove as $oldPath => $info) {
$newPath = $info['new_path'];
$docId = $info['doc_id'];
echo "Документ ID: {$docId}\n";
echo " Старый путь: {$oldPath}\n";
echo " Новый путь: {$newPath}\n";
// Проверяем существование старого файла
if (!$s3Client->doesObjectExist($s3Bucket, $oldPath)) {
echo " ⚠️ Старый файл не найден, пропускаем\n\n";
$stats['skipped']++;
continue;
}
// Проверяем, не существует ли уже новый файл
if ($s3Client->doesObjectExist($s3Bucket, $newPath)) {
echo " ⚠️ Новый файл уже существует, пропускаем\n\n";
$stats['skipped']++;
continue;
}
if (!$dryRun) {
try {
// Копируем файл в новое место
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $newPath,
'CopySource' => "{$s3Bucket}/{$oldPath}",
]);
echo " ✅ Файл скопирован в новое место\n";
// Удаляем старый файл
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $oldPath,
]);
echo " ✅ Старый файл удален\n";
// Обновляем БД
$newFilename = 'https://s3.twcstorage.ru/' . $s3Bucket . '/' . $newPath;
$db->pquery("
UPDATE vtiger_notes
SET s3_key = ?, filename = ?
WHERE notesid = ?
", array($newPath, $newFilename, $docId));
echo " ✅ БД обновлена\n";
$stats['moved']++;
sleep(1); // Пауза между операциями
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$stats['failed']++;
$stats['errors'][] = "{$oldPath}: " . $e->getMessage();
}
} else {
echo " ⏸️ Будет перемещен (dry-run)\n";
$stats['moved']++;
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего файлов: {$stats['total']}\n";
if (!$dryRun) {
echo "Перемещено: {$stats['moved']}\n";
echo "Пропущено: {$stats['skipped']}\n";
echo "Ошибок: {$stats['failed']}\n";
} else {
echo "Будет перемещено: {$stats['moved']}\n";
echo "Будет пропущено: {$stats['skipped']}\n";
}
if (!empty($stats['errors'])) {
echo "\nОшибки:\n";
foreach ($stats['errors'] as $error) {
echo " - {$error}\n";
}
}
echo "\n=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Критическая ошибка: " . $e->getMessage() . "\n";
exit(1);
}

View File

@@ -0,0 +1,126 @@
<?php
/**
* Упрощенный скрипт для перемещения файлов проекта 394091
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
// Маппинг: текущий путь => правильный путь
$filesToMove = [
'crm2/CRM_Active_Files/Documents/394094/doc_394094_d583b5d6.pdf' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Договор_394094.pdf',
'crm2/CRM_Active_Files/Documents/394096/doc_394096_ce9e6bdc.pdf' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Подтверждение_оплаты_394096.pdf',
'crm2/CRM_Active_Files/Documents/394100/doc_394100_3f15e3c1.pdf' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Ответ_на_претензию_394100.pdf',
'crm2/CRM_Active_Files/Documents/394105/potrebitelya_Zgurskiy_1.pdf' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/7_заявление_потребителя_394105.pdf',
];
echo "=== ПЕРЕМЕЩЕНИЕ ФАЙЛОВ ПРОЕКТА 394091 ===\n";
echo str_repeat("=", 80) . "\n\n";
$dryRun = isset($argv[1]) && $argv[1] === '--dry-run';
if ($dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run)\n\n";
}
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($filesToMove),
'moved' => 0,
'skipped' => 0,
'failed' => 0,
];
foreach ($filesToMove as $oldPath => $newPath) {
$filename = basename($newPath);
echo "Файл: {$filename}\n";
echo " От: {$oldPath}\n";
echo " К: {$newPath}\n";
// Проверяем существование старого файла
if (!$s3Client->doesObjectExist($s3Bucket, $oldPath)) {
echo " ⚠️ Старый файл не найден\n\n";
$stats['skipped']++;
continue;
}
// Проверяем, не существует ли уже новый файл
if ($s3Client->doesObjectExist($s3Bucket, $newPath)) {
echo " ⚠️ Новый файл уже существует\n\n";
$stats['skipped']++;
continue;
}
if (!$dryRun) {
try {
// Копируем файл
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $newPath,
'CopySource' => "{$s3Bucket}/{$oldPath}",
]);
echo " ✅ Скопирован\n";
// Удаляем старый
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $oldPath,
]);
echo " ✅ Старый удален\n";
$stats['moved']++;
sleep(1);
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$stats['failed']++;
}
} else {
echo " ⏸️ Будет перемещен (dry-run)\n";
$stats['moved']++;
}
echo "\n";
}
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего: {$stats['total']}\n";
if (!$dryRun) {
echo "Перемещено: {$stats['moved']}\n";
echo "Пропущено: {$stats['skipped']}\n";
echo "Ошибок: {$stats['failed']}\n";
} else {
echo "Будет перемещено: {$stats['moved']}\n";
}
if (!$dryRun && $stats['moved'] > 0) {
echo "\n⚠️ ВАЖНО: Обновите БД вручную:\n";
echo "UPDATE vtiger_notes SET s3_key = '...', filename = '...' WHERE notesid = ...;\n";
}
echo "\n=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Ошибка: " . $e->getMessage() . "\n";
exit(1);
}

165
move_project_398027.php Normal file
View File

@@ -0,0 +1,165 @@
<?php
/**
* Перемещение файлов проекта 398027 в правильное место
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 398027;
$s3Bucket = $config['s3']['bucket'];
$projectPrefix = 'crm2/CRM_Active_Files/Documents/Project/Храмов_ООО_НЕТОЛОГИЯ_398027/';
// Маппинг: текущий путь => правильный путь
$filesToMove = [
398030 => [
'old' => 'crm2/CRM_Active_Files/Documents/398030/8_Договора_оказание_услуг_11-14-2025-16-00-51_Храмов_1_CTP#realfile.pdf',
'new' => $projectPrefix . '8_Договора_оказание_услуг_398030.pdf',
],
398032 => [
'old' => 'crm2/CRM_Active_Files/Documents/398032/9_Подтверждение_оплаты_пооговору_11-14-2025-16-00-03_Храмов_1_CTP#realfile.pdf',
'new' => $projectPrefix . '9_Подтверждение_оплаты_пооговору_398032.pdf',
],
398034 => [
'old' => 'crm2/CRM_Active_Files/Documents/398034/10_2_Скрин_личногоабинетастца_и_программа_обучения_11-14-2025-15-47-26_Храмов_41_CTP#realfile.pdf',
'new' => $projectPrefix . '10_2_Скрин_личногоабинетастца_и_программа_обучения_398034.pdf',
],
398036 => [
'old' => 'crm2/CRM_Active_Files/Documents/398036/10_1_Скрин_личногоабинетастца_и_программа_обучения_11-14-2025-15-49-59_Храмов_1_CTP#realfile.pdf',
'new' => $projectPrefix . '10_1_Скрин_личногоабинетастца_и_программа_обучения_398036.pdf',
],
398038 => [
'old' => 'crm2/CRM_Active_Files/Documents/398038/Прочиеокументы_11-14-2025-16-06-07_Храмов_3_CTP#realfile.pdf',
'new' => $projectPrefix . рочиеокументы_398038.pdf',
],
398040 => [
'old' => 'crm2/CRM_Active_Files/Documents/398040/7_zayavlenie_potrebitelya_Hramov.pdf',
'new' => $projectPrefix . '7_заявление_потребителя_398040.pdf',
],
398063 => [
'old' => 'crm2/CRM_Active_Files/Documents/398063/napravleniya_pretenzii.pdf',
'new' => $projectPrefix . 'Направление_претензии_398063.pdf',
],
399067 => [
'old' => 'clientright/0/1763997676315.pdf',
'new' => $projectPrefix . окумент_399067.pdf',
],
399068 => [
'old' => 'clientright/0/1763997790309.pdf',
'new' => $projectPrefix . окумент_399068.pdf',
],
];
echo "=== ПЕРЕМЕЩЕНИЕ ФАЙЛОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
$dryRun = isset($argv[1]) && $argv[1] === '--dry-run';
if ($dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run)\n\n";
}
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($filesToMove),
'moved' => 0,
'skipped' => 0,
'failed' => 0,
];
foreach ($filesToMove as $docId => $paths) {
$oldPath = $paths['old'];
$newPath = $paths['new'];
$filename = basename($newPath);
echo "Документ ID: {$docId}\n";
echo " Файл: {$filename}\n";
echo " От: {$oldPath}\n";
echo " К: {$newPath}\n";
// Проверяем существование старого файла
if (!$s3Client->doesObjectExist($s3Bucket, $oldPath)) {
echo " ⚠️ Старый файл не найден\n\n";
$stats['skipped']++;
continue;
}
// Проверяем, не существует ли уже новый файл
if ($s3Client->doesObjectExist($s3Bucket, $newPath)) {
echo " ⚠️ Новый файл уже существует\n\n";
$stats['skipped']++;
continue;
}
if (!$dryRun) {
try {
// Копируем файл
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $newPath,
'CopySource' => "{$s3Bucket}/{$oldPath}",
]);
echo " ✅ Скопирован\n";
// Удаляем старый
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $oldPath,
]);
echo " ✅ Старый удален\n";
$stats['moved']++;
sleep(1);
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$stats['failed']++;
}
} else {
echo " ⏸️ Будет перемещен (dry-run)\n";
$stats['moved']++;
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего файлов: {$stats['total']}\n";
if (!$dryRun) {
echo "Перемещено: {$stats['moved']}\n";
echo "Пропущено: {$stats['skipped']}\n";
echo "Ошибок: {$stats['failed']}\n";
if ($stats['moved'] > 0) {
echo "\n⚠️ ВАЖНО: Обновите БД с правильными путями!\n";
}
} else {
echo "Будет перемещено: {$stats['moved']}\n";
}
echo "\n=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Критическая ошибка: " . $e->getMessage() . "\n";
exit(1);
}

14
nextcloud_scan_files.sh Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/bash
# Скрипт для регулярной индексации файлов Nextcloud
# Запускать каждые 6 часов через cron
CONTAINER_NAME="nextcloud-fresh"
USER="www-data"
# Сканируем все файлы
docker exec -u $USER $CONTAINER_NAME php occ files:scan --all >> /var/log/nextcloud_scan.log 2>&1
# Сканируем только внешнее хранилище (быстрее)
# docker exec -u $USER $CONTAINER_NAME php occ files:scan --path="/crm" >> /var/log/nextcloud_scan.log 2>&1
echo "$(date): Nextcloud files scan completed" >> /var/log/nextcloud_scan.log

274
restore_all_deleted_files.php Executable file
View File

@@ -0,0 +1,274 @@
<?php
/**
* Скрипт для массового восстановления всех удаленных файлов из S3
*
* Восстанавливает файлы, удаленные через delete markers, удаляя эти маркеры
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
set_time_limit(0); // Без ограничения времени
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
echo "Массовое восстановление удаленных файлов из S3\n";
echo str_repeat("=", 80) . "\n\n";
// Параметры
$dryRun = isset($argv[1]) && $argv[1] === '--dry-run';
$limit = isset($argv[2]) ? (int)$argv[2] : null; // Ограничение количества файлов
$prefix = isset($argv[3]) ? $argv[3] : 'crm2/CRM_Active_Files/Documents/'; // Префикс для поиска
if ($dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run) - файлы не будут восстановлены\n\n";
}
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total_markers' => 0,
'restored' => 0,
'failed' => 0,
'skipped' => 0,
'errors' => []
];
$processedKeys = []; // Для отслеживания уже обработанных ключей
echo "Поиск delete markers в префиксе: $prefix\n";
echo "Ограничение: " . ($limit ? "$limit файлов" : "нет") . "\n\n";
$isTruncated = true;
$continuationToken = null;
$pageCount = 0;
$maxPages = isset($argv[4]) ? (int)$argv[4] : 10; // БЕЗОПАСНО: максимум 10 страниц по умолчанию (можно увеличить через параметр)
echo "⚠️ ВНИМАНИЕ: Обработка ограничена {$maxPages} страницами для безопасности\n";
echo " Для обработки большего количества используйте: php restore_all_deleted_files.php [--dry-run] [limit] [prefix] [maxPages]\n\n";
while ($isTruncated && $pageCount < $maxPages && (!$limit || $stats['restored'] + $stats['failed'] < $limit)) {
$params = [
'Bucket' => $s3Bucket,
'Prefix' => $prefix,
'MaxKeys' => 100 // БЕЗОПАСНО: уменьшено с 1000 до 100 для снижения нагрузки
];
if ($continuationToken) {
$params['ContinuationToken'] = $continuationToken;
}
echo "Обработка страницы " . ($pageCount + 1) . "/{$maxPages}...\r";
try {
$versions = $s3Client->listObjectVersions($params);
$pageCount++;
// БЕЗОПАСНОСТЬ: пауза между страницами для снижения нагрузки
if ($pageCount < $maxPages && $isTruncated) {
usleep(500000); // 0.5 секунды пауза между страницами
}
if (isset($versions['DeleteMarkers']) && !empty($versions['DeleteMarkers'])) {
foreach ($versions['DeleteMarkers'] as $marker) {
$key = $marker['Key'];
$versionId = $marker['VersionId'];
$deleteDate = $marker['LastModified'] ?? 'не указана';
// Пропускаем, если уже обработали этот ключ
if (isset($processedKeys[$key])) {
continue;
}
$stats['total_markers']++;
// Проверяем лимит
if ($limit && ($stats['restored'] + $stats['failed']) >= $limit) {
break 2; // Выходим из обоих циклов
}
// Пропускаем папки (заканчиваются на /)
if (substr($key, -1) === '/') {
$stats['skipped']++;
continue;
}
try {
if (!$dryRun) {
// Сначала проверяем, есть ли версии файла
try {
$versionsList = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $key,
'MaxKeys' => 10
]);
$hasVersions = isset($versionsList['Versions']) && !empty($versionsList['Versions']);
if ($hasVersions) {
// Есть версии - удаляем delete marker и файл восстановится автоматически
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $key,
'VersionId' => $versionId
]);
// Проверяем, восстановился ли файл
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
$stats['restored']++;
$processedKeys[$key] = true;
// БЕЗОПАСНОСТЬ: пауза каждые 10 файлов
if ($stats['restored'] % 10 == 0) {
echo "Восстановлено: {$stats['restored']} файлов...\r";
usleep(200000); // 0.2 секунды пауза
}
} catch (\Aws\Exception\AwsException $e) {
if ($e->getAwsErrorCode() == 'NotFound') {
// Файл все еще не доступен, пробуем восстановить последнюю версию вручную
$latestVersion = $versionsList['Versions'][0];
$latestVersionId = $latestVersion['VersionId'];
try {
// Копируем версию в текущий объект
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'CopySource' => urlencode($s3Bucket . '/' . $key) . '?versionId=' . $latestVersionId,
'Key' => $key
]);
$stats['restored']++;
$processedKeys[$key] = true;
if ($stats['restored'] % 100 == 0) {
echo "Восстановлено: {$stats['restored']} файлов...\r";
}
} catch (\Aws\Exception\AwsException $e2) {
$stats['failed']++;
$stats['errors'][] = "Ошибка восстановления версии $key: " . $e2->getMessage();
}
} else {
$stats['failed']++;
$stats['errors'][] = "Ошибка проверки $key: " . $e->getMessage();
}
}
} else {
// Нет версий - файл удален безвозвратно
$stats['failed']++;
$stats['errors'][] = "Не найдена версия для восстановления: $key (файл удален безвозвратно)";
}
} catch (\Aws\Exception\AwsException $e) {
$stats['failed']++;
$stats['errors'][] = "Ошибка проверки версий для $key: " . $e->getMessage();
}
} else {
// Dry-run режим - проверяем наличие версий
try {
$versionsList = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $key,
'MaxKeys' => 1
]);
if (isset($versionsList['Versions']) && !empty($versionsList['Versions'])) {
$stats['restored']++;
} else {
$stats['failed']++;
}
$processedKeys[$key] = true;
if (($stats['restored'] + $stats['failed']) % 100 == 0) {
echo "Проверено: " . ($stats['restored'] + $stats['failed']) . " файлов...\r";
}
} catch (\Aws\Exception\AwsException $e) {
$stats['failed']++;
$processedKeys[$key] = true;
}
}
} catch (\Aws\Exception\AwsException $e) {
$stats['failed']++;
$stats['errors'][] = "Ошибка удаления delete marker для $key: " . $e->getMessage();
if (count($stats['errors']) <= 10) {
echo "\n Ошибка: {$stats['errors'][count($stats['errors']) - 1]}\n";
}
}
}
}
$isTruncated = isset($versions['IsTruncated']) && $versions['IsTruncated'];
$continuationToken = isset($versions['NextContinuationToken']) ? $versions['NextContinuationToken'] : null;
if (!$isTruncated) {
break;
}
} catch (\Aws\Exception\AwsException $e) {
echo "\n❌ Ошибка при обработке страницы: " . $e->getMessage() . "\n";
break;
}
}
echo "\n\n";
echo str_repeat("=", 80) . "\n";
echo "ИТОГОВЫЙ ОТЧЕТ:\n\n";
echo "Всего найдено delete markers: {$stats['total_markers']}\n";
echo "Восстановлено файлов: {$stats['restored']}\n";
echo "Ошибок: {$stats['failed']}\n";
echo "Пропущено (папки): {$stats['skipped']}\n\n";
if (!empty($stats['errors']) && count($stats['errors']) <= 20) {
echo "Ошибки (первые " . count($stats['errors']) . "):\n";
foreach ($stats['errors'] as $error) {
echo " - $error\n";
}
echo "\n";
} elseif (!empty($stats['errors'])) {
echo "Всего ошибок: " . count($stats['errors']) . " (показаны первые 20)\n";
foreach (array_slice($stats['errors'], 0, 20) as $error) {
echo " - $error\n";
}
echo "\n";
}
if ($dryRun) {
echo "⚠️ Это был режим проверки. Для реального восстановления запустите:\n";
echo " php restore_all_deleted_files.php\n\n";
} else {
echo "✅ Восстановление завершено!\n";
echo " Проверьте доступность файлов в интерфейсе CRM\n\n";
}
// Сохраняем статистику в файл
$logFile = '/var/www/fastuser/data/www/crm.clientright.ru/restore_log_' . date('Y-m-d_H-i-s') . '.json';
file_put_contents($logFile, json_encode($stats, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
echo "📝 Лог сохранен в: $logFile\n";
} catch (Exception $e) {
echo "❌ КРИТИЧЕСКАЯ ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

163
restore_deleted_files.php Normal file
View File

@@ -0,0 +1,163 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$docIds = [386869, 394973];
$s3Bucket = $config['s3']['bucket'];
echo "Восстановление удаленных файлов из S3\n";
echo str_repeat("=", 80) . "\n\n";
try {
// Инициализация S3 клиента
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
foreach ($docIds as $docId) {
echo "Восстановление файла для документа $docId:\n";
echo str_repeat("-", 80) . "\n";
// Получаем информацию о документе
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$stmt = $pdo->prepare('SELECT notesid, title, s3_key, s3_etag FROM vtiger_notes WHERE notesid = ?');
$stmt->execute([$docId]);
$doc = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$doc) {
echo " Документ не найден в БД\n\n";
continue;
}
$s3Key = $doc['s3_key'];
echo " Название: {$doc['title']}\n";
echo " Путь: $s3Key\n\n";
// Получаем delete markers
try {
$versions = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $s3Key,
'MaxKeys' => 100
]);
if (isset($versions['DeleteMarkers']) && !empty($versions['DeleteMarkers'])) {
echo " Найдено delete markers: " . count($versions['DeleteMarkers']) . "\n";
// Удаляем все delete markers (самый новый будет удален последним)
// Сортируем по дате удаления (от новых к старым)
usort($versions['DeleteMarkers'], function($a, $b) {
$dateA = isset($a['LastModified']) ? strtotime($a['LastModified']) : 0;
$dateB = isset($b['LastModified']) ? strtotime($b['LastModified']) : 0;
return $dateB - $dateA; // От новых к старым
});
foreach ($versions['DeleteMarkers'] as $marker) {
$versionId = $marker['VersionId'];
$deleteDate = $marker['LastModified'] ?? 'не указана';
echo " Удаление delete marker: VersionId=$versionId (дата удаления: $deleteDate)\n";
try {
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'VersionId' => $versionId
]);
echo " ✅ Delete marker удален\n";
} catch (\Aws\Exception\AwsException $e) {
echo " ❌ Ошибка при удалении delete marker: " . $e->getMessage() . "\n";
}
}
// Проверяем, восстановился ли файл
echo "\n Проверка восстановления файла...\n";
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key
]);
echo " ✅ Файл успешно восстановлен!\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
echo " ETag: " . (isset($headResult['ETag']) ? trim($headResult['ETag'], '"') : 'не указан') . "\n";
echo " Дата: " . ($headResult['LastModified'] ?? 'не указана') . "\n";
} catch (\Aws\Exception\AwsException $e) {
if ($e->getAwsErrorCode() == 'NotFound') {
echo " ⚠️ Файл все еще не доступен (возможно, нужно восстановить конкретную версию)\n";
// Пробуем восстановить последнюю версию напрямую
if (isset($versions['Versions']) && !empty($versions['Versions'])) {
$latestVersion = $versions['Versions'][0]; // Первая версия - самая новая
$versionId = $latestVersion['VersionId'];
echo " Попытка восстановить версию: VersionId=$versionId\n";
try {
// Копируем версию в текущий объект
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'CopySource' => $s3Bucket . '/' . $s3Key . '?versionId=' . $versionId,
'Key' => $s3Key
]);
echo " ✅ Версия восстановлена\n";
// Проверяем еще раз
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key
]);
echo " ✅ Файл восстановлен и доступен!\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
} catch (\Aws\Exception\AwsException $e) {
echo " ❌ Ошибка при восстановлении версии: " . $e->getMessage() . "\n";
}
}
} else {
echo " ❌ Ошибка при проверке: " . $e->getMessage() . "\n";
}
}
} else {
echo " ❌ Delete markers не найдены\n";
}
} catch (\Aws\Exception\AwsException $e) {
echo " ❌ Ошибка при работе с версиями: " . $e->getMessage() . "\n";
}
echo "\n";
}
echo str_repeat("=", 80) . "\n";
echo "Восстановление завершено!\n";
echo "Проверьте доступность файлов в интерфейсе CRM\n";
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

View File

@@ -0,0 +1,7 @@
{
"total_markers": 11,
"restored": 10,
"failed": 0,
"skipped": 0,
"errors": []
}

View File

@@ -0,0 +1,7 @@
{
"total_markers": 51,
"restored": 50,
"failed": 0,
"skipped": 0,
"errors": []
}

View File

@@ -0,0 +1,550 @@
{
"total_markers": 542,
"restored": 0,
"failed": 542,
"skipped": 0,
"errors": [
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1149\/Оферта_август_2022_(1)_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1151\/inquiry.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1153\/Screen.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117066\/operation_statement_05.04.2024.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117081\/Заявление_о_выдачи_исполнительного_листа_поелу_2-1658-2023_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117335\/Договор_04-21-2024-19-49-06_Мустафаев_21_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117337\/Подтверждение_оплаты_04-21-2024-19-41-17_Мустафаев_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117339\/Скриншот_прогресса_обучения_04-21-2024-19-48-13_Мустафаев_7_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117341\/Претензия_04-21-2024-19-56-37_Мустафаев_2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117343\/Ответ_на_претензию_04-21-2024-19-57-51_Мустафаев_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117597\/Договор_04-23-2024-12-18-54_Гришакова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117599\/Подтверждение_оплаты_04-23-2024-12-20-02_Гришакова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117601\/Скриншот_прогресса_обучения_04-23-2024-12-23-43_Гришакова__5_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117603\/Претензия_04-23-2024-12-28-08_Гришакова__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117605\/Ответ_на_претензию_04-23-2024-12-28-30_Гришакова__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117607\/Прочиеокументы_04-23-2024-12-34-20_Гришакова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117649\/Договор_04-23-2024-14-32-10_Жидкова__12_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117651\/Подтверждение_оплаты_04-23-2024-14-34-01_Жидкова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117653\/Программа_обучения_04-23-2024-14-34-39_Жидкова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117655\/Скриншот_прогресса_обучения_04-23-2024-14-34-47_Жидкова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117660\/Выписка_из_ГРАФПИЮЛ.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117824\/от_скилл_бокс.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117863\/Сканирование_20240425-1902.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/117947\/Ходатайство_поелу__1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118166\/возврат.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118260\/Договор_04-26-2024-17-05-28_Енин__21_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118262\/Подтверждение_оплаты_04-26-2024-17-07-56_Енин__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118264\/Скриншот_прогресса_обучения_04-26-2024-17-12-16_Енин__3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118266\/Претензия_04-26-2024-17-17-30_Енин__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118268\/Ответ_на_претензию_04-26-2024-17-13-49_Енин__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118270\/возвраты.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118328\/Счёт_№9109027.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118331\/чек_27.04.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118337\/Договор_04-27-2024-23-53-19_Авдеева__19_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118339\/Подтверждение_оплаты_04-27-2024-23-54-03_Авдеева__3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118341\/Программа_обучения_04-27-2024-23-55-28_Авдеева__10_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118343\/Скриншот_прогресса_обучения_04-27-2024-23-56-39_Авдеева__10_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118345\/Прочиеокументы_04-28-2024-00-00-46_Авдеева__10_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118365\/Договор_04-30-2024-13-16-36_Салиев_14_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118367\/Подтверждение_оплаты_04-30-2024-13-17-19_Салиев_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118369\/Программа_обучения_04-30-2024-13-26-10_Салиев_18_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118371\/Скриншот_прогресса_обучения_04-30-2024-13-22-19_Салиев_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118469\/Выписка_по_вкладу_(на_русском).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118586\/Полис_05-02-2024-20-59-43__1_CTP.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118589\/Подтверждение_бронирования_05-02-2024-21-05-13_Зарубина_19_CTP.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118592\/Подтверждение_оплаты_бронирования_05-02-2024-21-05-12_Зарубина_1_CTP.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118595\/Отказ_в_заселении_05-02-2024-21-06-50_Зарубина_2_CTP.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118598\/Отсутствие_вида_05-02-2024-21-06-30_Зарубина_1_CTP.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118601\/Документ_удостоверяющий_личность_05-02-2024-21-12-05_Зарубина_1_CTP.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118612\/Протокол встречи.txt",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118738\/Договор_05-05-2024-16-17-26_Бережной_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118740\/Подтверждение_оплаты_05-05-2024-16-13-09_Бережной_15_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118742\/Скриншот_прогресса_обучения_05-05-2024-16-36-04_Бережной_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118828\/Акт_за_апрель.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118831\/Счет_заай+_четверть_модуля.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118847\/Binder1_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118903\/Заявление_в_АО_-ТИНЬКОФФ_БАНК-_обсполнении_решения_поелу_2-244-2024_Клиентправ.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118905\/Бордеро_Апрель_2024.xlsx",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118937\/6_Расчет_исковыхребований_Григоричев__ИП_Айриян_Арам_Ашотович_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118939\/0_Исковоеаявление_поелуригоричев__ИП_Айриян_Арам_Ашотович_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118987\/Договор_05-07-2024-12-48-52_Новичков_3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118989\/Подтверждение_оплаты_05-07-2024-12-49-12_Новичков_3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/118991\/Скриншот_прогресса_обучения_05-07-2024-12-50-06_Новичков_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1190\/Договор.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119017\/Заявление_о_выдачи_исполнительного_листа_поелу_2-817-2024_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119032\/Опись_104807.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119052\/доказательствоаправления_иска_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119088\/Договор_05-07-2024-17-27-35_Удовикина_12_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119090\/Подтверждение_оплаты_05-07-2024-17-26-35_Удовикина_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119092\/Программа_обучения_05-07-2024-17-25-41_Удовикина_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119094\/Скриншот_прогресса_обучения_05-07-2024-17-25-17_Удовикина_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119103\/Договор_05-07-2024-17-56-21_Захарова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119105\/Подтверждение_оплаты_05-07-2024-17-58-27_Захарова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119107\/Программа_обучения_05-07-2024-17-52-07_Захарова__13_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119109\/Скриншот_прогресса_обучения_05-07-2024-17-53-11_Захарова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119111\/Претензия_05-07-2024-18-04-05_Захарова__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119113\/Ответ_на_претензию_05-07-2024-18-11-10_Захарова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119123\/Ходатайство_поелу_М-1132-2024_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119126\/0_Исковоеаявление_поелуусев__ООО_-СКИЛБОКС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119128\/6_Расчет_исковыхребований_Гусев__ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119138\/Ходатайство_поелу_М-538-2024_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1192\/платеж.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119259\/Договор_05-08-2024-16-49-53_Панина_12_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119261\/Подтверждение_оплаты_05-08-2024-16-50-13_Панина_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119263\/Программа_обучения_05-08-2024-16-50-36_Панина_4_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119265\/Скриншот_прогресса_обучения_05-08-2024-16-50-58_Панина_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119267\/Претензия_05-08-2024-16-51-31_Панина_2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119269\/Ответ_на_претензию_05-08-2024-16-52-19_Панина_2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119271\/Возврат_средств_05-08-2024-16-52-07_Панина_2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1194\/Новая_папка.7z",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119409\/10_Доказательство_проведение_претензионной_работы__Исаева_Екатерина_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119449\/7_заявление_потребителя_Панина__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119465\/7_заявление_потребителя_Бережной__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119583\/Заявление_о_выдачи_исполнительного_листа_поелу_02-11106-2023_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119598\/IMG_3814.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1196\/Общение_с_представителями_школы.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119613\/Пдф_для_суда.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119623\/12доказательствоаправления_иска.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119641\/6_Расчет_исковыхребований_Носенко__ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119643\/0_Исковоеаявление_поелу_Носенко__ООО_-СКИЛБОКС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119653\/Опись_104863_merged.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119719\/Adobe_Scan_23_апр._2024г..pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119756\/приказ_10.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119759\/Договор_подряда__ООО_Лира.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119762\/приказ_9.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119765\/приказ_Гринчук.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119768\/ТД_художник_дизайнер.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119771\/ТД_рук_отд_продаж.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119774\/ДИ_рук_отд_продаж.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119819\/6_Расчет_исковыхребований_Кириллов___ИП_Ваняшин_Андрей_Эдуардович_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119821\/0_Исковоеаявление_поелу_Кириллов___ИП_Ваняшин_Андрей_Эдуардович_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119831\/Опись+квитанция_об_оплате_105029.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119847\/Заявление_в_АО_-ТИНЬКОФФ_БАНК-_обсполнении_решения_поелу_2-1658-2023_Клиентправ.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119851\/Заявление_в_АО_-ТИНЬКОФФ_БАНК-_обсполнении_решения_поелу_2-1419-2023_Клиентправ.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119958\/10_Доказательство_проведение_претензионной_работы__Коржилова__Наталья__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119970\/10_Доказательство_проведение_претензионной_работы__Мацак_Елена_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/119982\/10_Доказательство_проведение_претензионной_работы__Камаш_Александра_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120006\/10_Доказательство_проведение_претензионной_работы__Чубик_Дарья_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120030\/10_Доказательство_проведение_претензионной_работы__Силина_Виктория_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120079\/Опись_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120087\/6_Расчет_исковыхребований_Мурин__ЧОУ_ДПО_-ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_-СКИЛБОКС_(КОРОБКА_НАВЫКОВ)-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120089\/0_Исковоеаявление_поелу_Мурин__ЧОУ_ДПО_-ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_-СКИЛБОКС_(КОРОБКА_НАВЫКОВ)-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120148\/Письмо_ИП_Будишевский-2.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120195\/отказ.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120198\/прогресс.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120201\/программаурса.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120239\/7_заявление_потребителя_Дё__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120242\/Договор_05-14-2024-14-12-21_Дё_13_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120245\/Подтверждение_оплаты_05-14-2024-14-22-29_Дё_5_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120248\/Прочиеокументы_05-14-2024-14-53-09_Дё_2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120251\/Скриншот_прогресса_обучения_05-14-2024-14-25-25_Дё_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120259\/Договор_05-14-2024-13-17-36_Плохова__12_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120262\/Подтверждение_оплаты_05-14-2024-17-21-09_Плохова__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120265\/Скриншот_прогресса_обучения_05-14-2024-14-50-09_Плохова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120269\/7_заявление_потребителя_Плохова___.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120319\/0_Исковоеаявление_поелу_Акулов_ООО_-ЭВОТРЕН-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120321\/6_Расчет_исковыхребований_Акулов_ООО_-ЭВОТРЕН-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120350\/Договор_05-14-2024-20-27-08_Трубнякова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120352\/Подтверждение_оплаты_05-14-2024-20-34-20_Трубнякова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120354\/Программа_обучения_05-14-2024-20-40-01_Трубнякова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120356\/Скриншот_прогресса_обучения_05-14-2024-20-43-20_Трубнякова__7_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120358\/Претензия_05-14-2024-20-53-35_Трубнякова__3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120360\/Ответ_на_претензию_05-14-2024-20-56-00_Трубнякова__7_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120368\/7_заявление_потребителя_Трубнякова___.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120395\/7_заявление_потребителя_Новичков_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120397\/11_Доказательство_соблюдения_претензионного_порядка__Новичков_Константин_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120413\/Заявление_в_АО_-ТИНЬКОФФ_БАНК-_обсполнении_решения_поелу_02-1320-44-2023_Клиентправ.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120437\/отправка_претензии_почтой.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120479\/2024-05-04-2.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120484\/2024-05-04-1.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120491\/Договор_05-15-2024-15-11-47_Тупас__17_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120493\/Подтверждение_оплаты_05-15-2024-15-12-30_Тупас__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120495\/Прочиеокументы_05-15-2024-15-14-02_Тупас__25_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120724\/7_заявление_потребителя_Самуткина__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120728\/Договор_05-16-2024-12-02-31_Самуткина__11_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120730\/Подтверждение_оплаты_05-16-2024-12-03-28_Самуткина__8_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120732\/Программа_обучения_05-16-2024-12-04-07_Самуткина__4_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120734\/Скриншот_прогресса_обучения_05-16-2024-12-04-28_Самуткина__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120736\/Претензия_05-16-2024-12-07-09_Самуткина__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120738\/Ответ_на_претензию_05-16-2024-12-07-19_Самуткина__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120740\/Прочиеокументы_05-16-2024-13-03-51_Самуткина__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120754\/Заявлениестцаа_выдачу_листа_поелу_02-4298-345-2023_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120787\/7_заявление_потребителя_Мустафаев_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120796\/7_заявление_потребителя_Захарова__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120803\/Договор_05-16-2024-15-11-45_Кузовлева__6_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120805\/Подтверждение_оплаты_05-16-2024-15-13-53_Кузовлева__3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120807\/Прочиеокументы_05-16-2024-15-14-08_Кузовлева__20_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120809\/Претензия_и_документы_05-16-2024-15-15-45_Кузовлева__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120811\/Возврат_средств_контрагентом_05-16-2024-15-17-21_Кузовлева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120865\/11._Подтверждение_проведения_претензионной_работы_Захарова__Наталья__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120877\/11._Подтверждение_проведения_претензионной_работы_Самуткина__Ксения_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120889\/7_заявление_потребителя_Сарина__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120895\/document_(2).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120897\/Скриншот_прогресса_обучения_05-16-2024-22-44-55_Сарина__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120899\/Претензия_05-16-2024-22-48-30_Сарина__25_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120901\/Ответ_на_претензию_05-16-2024-22-48-55_Сарина__3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120924\/11._Подтверждение_проведения_претензионной_работы_Дё_Виктория_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120968\/Договор_05-17-2024-12-03-41_Зозуля__14_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120970\/Подтверждение_оплаты_05-17-2024-12-10-43_Зозуля__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120972\/Прочиеокументы_05-17-2024-12-02-05_Зозуля__23_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120978\/Почта-суд.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/120996\/11._Подтверждение_проведения_претензионной_работы_Сарина__Людмила__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/121032\/11._Подтверждение_проведения_претензионной_работы_Трубнякова__Дарья__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/121037\/Ответ_на_претензию_04-24-2024-12-31-08_Окуньков_3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/121057\/11._Подтверждение_проведения_претензионной_работы_Мустафаев_Энвер_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/121140\/7_заявление_потребителя_Балашов_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/121148\/11._Подтверждение_проведения_претензионной_работы_Балашов_Александр_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/121160\/7_заявление_потребителя_Жидкова__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/121177\/11._Подтверждение_проведения_претензионной_работы_Жидкова__Ольга__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1216\/договор.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1218\/оплата.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1220\/личный_кабинет.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1234\/Заявление_(2).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123567\/7_заявление_потребителя_Матвеев_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123571\/Договор_05-18-2024-01-44-40_Матвеев_12_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123573\/Подтверждение_оплаты_05-17-2024-21-06-55_Матвеев_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123575\/Скриншот_прогресса_обучения_05-17-2024-18-17-22_Матвеев_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123617\/отправкаска_почтой.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123620\/Пользовательское-соглашение-в-ред.-от-12.07.22-(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123623\/лк_медведева.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123626\/подтверждение_оплаты_медведева.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123629\/доказательство_претензии_медведева.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123632\/претензия_медведева_2.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123658\/Опись_и_квитанция.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123723\/6_Расчет_исковыхребований_Завьялова__ЧОУ_ДПО_-ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_-СКИЛБОКС_(КОРОБКА_НАВЫКОВ)-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123725\/0_Исковоеаявление_поелу_Завьялова__ЧОУ_ДПО_-ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_-СКИЛБОКС_(КОРОБКА_НАВЫКОВ)-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123735\/Опись_104988.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123786\/7_заявление_потребителя_Ливенцева_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123792\/Договор_05-20-2024-16-58-35_Ливенцева_6_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123794\/Подтверждение_оплаты_05-20-2024-16-59-28_Ливенцева_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123796\/Программа_обучения_05-20-2024-16-55-35_Ливенцева_3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123798\/Скриншот_прогресса_обучения_05-20-2024-16-58-01_Ливенцева_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123800\/Претензия_05-20-2024-17-04-57_Ливенцева_3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123847\/7_заявление_потребителя_Гришакова__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123858\/6_Расчет_исковыхребований_Юмаев___Turkish_Airlines_(Турецкие_Авиалинии)_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123863\/0_Исковоеаявление_поелу_Юмаев___Turkish_Airlines_(Турецкие_Авиалинии)_6_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123870\/доказательствоаправления_иска_ответчику_Юмаев___Turkish_Airlines_(Турецкие_Авиалинии)_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123889\/7_заявление_потребителя_Лисовенко_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123896\/Договор_05-20-2024-22-33-05_Лисовенко_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123898\/Подтверждение_оплаты_05-20-2024-22-33-47_Лисовенко_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123900\/Программа_обучения_05-20-2024-22-35-11_Лисовенко_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123902\/Скриншот_прогресса_обучения_05-20-2024-22-36-28_Лисовенко_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123909\/7_заявление_потребителя_Маклакова__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123915\/Договор_05-20-2024-22-40-25_Маклакова__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123917\/Подтверждение_оплаты_05-20-2024-22-40-56_Маклакова__3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123919\/Программа_обучения_05-20-2024-22-41-34_Маклакова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123921\/Скриншот_прогресса_обучения_05-20-2024-22-44-31_Маклакова__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123923\/Претензия_05-20-2024-22-58-20_Маклакова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123925\/Прочиеокументы_05-20-2024-22-59-48_Маклакова__3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123931\/7_заявление_потребителя_Енин__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123948\/Опись_104985.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123975\/доказательствоаправления_иска_ответчикуерезанский__Turkish_Airlines_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/123992\/7_заявление_потребителя_Дорничева_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1240\/Пользовательское_соглашение_Гикбрейнс_21.12.2021.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/124000\/Договор_05-21-2024-09-25-07_Дорничева_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/124002\/Подтверждение_оплаты_05-21-2024-09-22-53_Дорничева_2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/124004\/Скриншот_прогресса_обучения_05-21-2024-09-26-55_Дорничева_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/124006\/Претензия_05-21-2024-09-31-20_Дорничева_2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/124017\/13_судебная_практика_поанной_категории_дел_5_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1242\/Справка_об_оплате_обучения_Петров_Илья_Павлович.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1244\/ГБ.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12627\/image0.jpeg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12632\/Доказательство_проведение_претензионной_работы__Чекалин__Матвей__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12635\/Доказательство_проведение_претензионной_работы__Черников_Александр_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126413\/7_заявление_потребителя_Кривенцова_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126419\/Договор_05-21-2024-11-40-35_Кривенцова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126421\/Подтверждение_оплаты_05-21-2024-11-38-24_Кривенцова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126423\/Программа_обучения_05-21-2024-11-40-46_Кривенцова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126425\/Скриншот_прогресса_обучения_05-21-2024-11-40-54_Кривенцова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126441\/Скриншот_прогресса_обучения_05-18-2024-13-19-17_Сальников__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126444\/Подтверждение_оплаты_05-18-2024-13-16-56_Сальников__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126447\/Договор_05-18-2024-13-14-04_Сальников__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126450\/7_заявление_потребителя_Сальников__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126469\/11._Подтверждение_проведения_претензионной_работы_Сальников__Андрей__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126478\/7_заявление_потребителя_Федорова_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12648\/_8.0_9.0_Оферта_Команда_Александра_Никитина_РФ.docx.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126484\/Договор_05-21-2024-12-13-49_Федорова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126486\/Подтверждение_оплаты_05-21-2024-12-14-49_Федорова_2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126488\/Скриншот_прогресса_обучения_05-21-2024-12-15-48_Федорова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12650\/0040045670_20230128.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126510\/11._Подтверждение_проведения_претензионной_работы_Кривенцова_Татьяна_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12652\/2023-06-16_12-26-08.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126523\/11._Подтверждение_проведения_претензионной_работы_Гришакова__Светлана__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126535\/7_заявление_потребителя_Бекназарова_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12654\/Претензия.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126541\/Договор_05-21-2024-13-17-31_Бекназарова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126543\/Подтверждение_оплаты_05-21-2024-13-14-32_Бекназарова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126545\/Скриншот_прогресса_обучения_05-21-2024-13-16-04_Бекназарова_1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126564\/7_заявление_потребителя_минеева__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126570\/Договор_05-21-2024-14-33-17_минеева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126572\/Подтверждение_оплаты_05-21-2024-14-33-54_минеева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126574\/Программа_обучения_05-21-2024-14-35-31_минеева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126576\/Скриншот_прогресса_обучения_05-21-2024-14-36-26_минеева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126582\/120885_Опись_104925_merged.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126585\/120959_Ответ_от_2024—05—17_в_11.55.11.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126616\/7_заявление_потребителя_Еловиков__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126621\/Договор_05-21-2024-15-34-42_Еловиков__11_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126623\/Подтверждение_оплаты_05-21-2024-15-43-32_Еловиков__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126625\/Скриншот_прогресса_обучения_05-21-2024-15-33-35_Еловиков__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126644\/7_заявление_потребителя_Попов__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126649\/Договор_05-21-2024-15-58-51_Попов__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126651\/Подтверждение_оплаты_05-21-2024-16-10-56_Попов__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126653\/Программа_обучения_05-21-2024-16-05-10_Попов__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126655\/Скриншот_прогресса_обучения_05-21-2024-15-53-06_Попов__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126657\/Претензия_05-21-2024-16-23-23_Попов__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/126659\/Ответ_на_претензию_05-21-2024-16-22-47_Попов__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12685\/Оферта_август_2022_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12687\/оплата.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12689\/12_Прогресс_обучения,_на_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12698\/Руслан_договор_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12700\/photo_1_2023-06-16_22-07-13.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12702\/photo_3_2023-06-16_22-07-13.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12709\/Доказательство_проведение_претензионной_работы__Селедцова_Любовь_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12718\/ТАСПИН_ОФЕРТА.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12720\/check_0006124557045916_7281440500284613_176023_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12722\/лк.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12724\/таспин_суд.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12726\/kred_dogovor.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12728\/dosud_pretenziya.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12737\/оферта.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12739\/оплатаайк.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12741\/Чат_Марафон_инвестиций.PNG",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12743\/переписка_09.2021.jpeg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12779\/Kreditnyj_dogovor_individualʹnyh_uslovij_po_kreditu_(IUK).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12781\/Kreditnyj_dogovor_individualʹnyh_uslovij_po_kreditu_(IUK).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12783\/Kreditnyj_dogovor_individualʹnyh_uslovij_po_kreditu_(IUK).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12884\/Договор-оферта_Skillbox_+_доп.соглашение.7z",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12886\/operation_statement_16.09.2022.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12888\/Скрин_личногоабинета.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12890\/подтверждение_претензионной_работы.7z",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12892\/Кассовый_чек_(возврат)_88260_рублей_от_02.12.2022.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12894\/Сообщение_Skillbox_от_14.06.2023.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12919\/заявление_в_МОО_Клиентправ.jpeg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12934\/Заявление_в_Клиентправ_Шмелев_ООО_-СКИЛБОКС-.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1294\/Заявления-Претензия.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12943\/Договор_оферты_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12945\/Заявление_о_предоставлении_кредита_и_открытии_банковского_счёта.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12947\/Личный_кабинет_1.png",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12949\/Ответ_службы_поддержки.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12951\/Кассовый_чек_ООО_ГИКБРЕЙНС_95574_руб.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12964\/Св-во_о_перемене_имени.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12975\/oferta.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12977\/check_0004438001022024_9960440503169974_19024.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12979\/1.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12981\/ответ.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/12983\/претензия.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13028\/В_МООКлиентправ»_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/130334\/Прием_РПО_внутреннее.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13038\/Доказательство_проведение_претензионной_работы__Байкова_Татьяна_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/130445\/Опись_104995.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13047\/Оферта_learnhub_08.02.2023_v1.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13049\/contract.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13051\/Снимок_экрана_2023-06-21_114806.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13053\/Документ_Microsoft_Word_(2).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13061\/Оферта_learnhub_08.02.2023_v1.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13063\/contract.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13065\/Снимок_экрана_2023-06-21_114806.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13067\/photo_2023-06-21_12-14-28.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13069\/Документ_Microsoft_Word_(2).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13082\/SKMBT_C224e23061723020.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13086\/доказательствоаправления_иска_ответчику_Носков_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13121\/oferta.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13123\/check_0006185384006725_7281440500562238_4211.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13125\/Мое_обучение_—_Skillbox.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13190\/лицензия.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13200\/WhatsApp_Image_2023-06-21_at_20.11.48.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13202\/WhatsApp_Image_2023-06-21_at_20.12.10.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13204\/WhatsApp_Image_2023-06-21_at_20.12.04.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13211\/Оферта_learnhub_08.02.2023_v1_(2).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13213\/c0e78194-be00-4190-bdc5-d843d43f6ada_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13215\/скрины_с_платформы.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13222\/Оферта_learnhub_08.02.2023_v1.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13224\/sber_statement_21-06-2023_23-52-15.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13226\/Screenshot_20230621-235424_iSpring_Learn.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13228\/Screenshot_20230622-000404_Telegram.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13239\/Доказательство_проведение_претензионной_работы__Хименко_Анна_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13242\/Доказательство_проведение_претензионной_работы__Шмелев_Руслан_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13245\/Доказательство_проведение_претензионной_работы__Сулейменова_Дина_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13348\/доказательствоаправления_иска_ответчику_Виноградов_ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13350\/0_Исковоеаявление_поелу_Виноградов_ООО_-СКИЛБОКС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13352\/2_Расчет_исковыхребований_Виноградов_ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13360\/Претензия_в_защиту_интересов_Сопова_Алина_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13368\/Image0082_(1).JPG",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13374\/oferta.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13376\/Screenshot_20230623_101840_Gmail.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13378\/Screenshot_20230623_101551_Chrome.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13380\/Screenshot_20230623_101528_Chrome.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13387\/Договор_ОТП.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13389\/Договор_ОТП.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13391\/Деньги_под_ключ.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13398\/Договор_ОТП.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13400\/Договор_ОТП.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13402\/Деньги_под_ключ.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13412\/doc01781120220725125515.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13414\/Заявление_о_предоставлении_кредита_и_открытии_банковского_счёта_(экземпляр_банка).PDF",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13416\/ЛК.PNG",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13425\/oferta.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13427\/photo1687688292.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13429\/изображение_2023-06-25_162046444.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13436\/Договор.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13438\/Downloads.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13440\/скрин_.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1348\/Пользовательское_соглашение_в_ред._от_12.07.22.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1350\/Снимок_экрана_2023-04-07_в_16.49.48.jpg.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1352\/Снимок_экрана_2023-04-07_в_16.46.13.jpg.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/135648\/10_Доказательство_проведение_претензионной_работы__Белокуров_Павел_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/135779\/11._Подтверждение_проведения_претензионной_работы_Матвеев_Иван_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/135797\/11._Подтверждение_проведения_претензионной_работы_Еловиков__Матвей__2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/135901\/Заявление_о_выдачи_исполнительного_листа_поелу_2-892-2024_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1361\/Мягкий_Вячеслав_Эдуардович.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1363\/check_0004438001022024_9287440300779803_69531.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136455\/7_заявление_потребителя_Виноградова__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136460\/Договор_05-22-2024-11-39-20_Виноградова__2_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136462\/Подтверждение_оплаты_05-22-2024-11-39-29_Виноградова__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136464\/Скриншот_прогресса_обучения_05-22-2024-11-40-02_Виноградова__3_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136470\/Mail.ru_Письмо_от_oksana.volovikova@skillbox.ru.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1365\/V3dQu8J3.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136591\/IMG_3971.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136606\/0_Исковоеаявление_поелу_Сулиманов_ЧОУ_ДПО_-ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_-СКИЛБОКС_КОРОБКА_НАВЫКОВ-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136608\/6_Расчет_исковыхребований_Сулиманов_ЧОУ_ДПО_-ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_-СКИЛБОКС_КОРОБКА_НАВЫКОВ-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/136837\/operation_statement_16.04.2024.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/13797\/5_Доказательство_проведение_претензионной_работы__Галюк_Игорь_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/139911\/Опись_105005.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14044\/0_Исковоеаявление_поелу_Сопова_ИП_Гратило_Кристина_Сергеевна_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14046\/2_Расчет_исковыхребований_Сопова_ИП_Гратило_Кристина_Сергеевна_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14058\/oferta_май_2021_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14060\/Zayavlenie_na_oplatu_tovarov_uslug.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14062\/Снимок_экрана_(3).png",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14064\/oferta_май_2023.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14107\/Доказательство_проведение_претензионной_работы__Петрова_Ольга_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14109\/Доказательство_проведение_претензионной_работы__Рубашова_Лилия_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14111\/Доказательство_проведение_претензионной_работы__Спасских_Мария_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14113\/Доказательство_проведение_претензионной_работы__Королеваабриела_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14119\/Претензия_в_защиту_интересов_Имайкина_Ляйсан_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14123\/Доказательство_проведение_претензионной_работы__Имайкина_Ляйсан_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14125\/Доказательство_проведение_претензионной_работы__Бубличенко_Светлана_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1415\/Пользовательское_соглашение_Гикбрейнс_21.12.2021_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1417\/Справка_об_оплате_обучения.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14171\/Dogovor.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14173\/Check.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14175\/LK.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14181\/доказательствоаправления_иска_ответчикуатьянов_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14183\/0_Исковоеаявление_поелуатьянов_ООО_-ГИКБРЕИНС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14185\/2_Расчет_исковыхребований_Фатьянов_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1419\/Screenshot_10.png",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/141953\/соглашение_орпомощи_Костоев_ООО_-ГИКБРЕИНС-.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14199\/oferta.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14201\/yiBD6HIbPWU.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14203\/OaCjmcvzmDU.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14205\/Претензия.docx",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1421\/Письмо_о_сменеомера_лицензии_на_осуществление_образовательной_деятельности_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14210\/oferta.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14212\/yiBD6HIbPWU.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14214\/OaCjmcvzmDU.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14216\/Претензия.docx",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14225\/oferta.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14227\/WinRAR_ZIP_archive.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14229\/WinRAR_ZIP_archive.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14231\/WinRAR_ZIP_archive.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14238\/oferta.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14240\/оплата.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14242\/прогресс.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14244\/претензия.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14246\/возврат.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1431\/kvk.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1433\/kvk.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/143394\/Исполнениеаявление_в_банк_Доверитель.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1435\/Nikita_Ditelev_-_profil_polzovatelya_na_obrazovatelnom_portale_GeekBrains.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1437\/IMG_0237.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14372\/wsZBzMxr4H7IHCnhWiYw2po7I1onBJlr.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14374\/zayavleniye_na_oplatu_tovarov_(uslug)_20.03.2023.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14376\/прогресссс.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14378\/претензионка.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14382\/sber_statement_03-07-2023_17-08-57.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14389\/kreditnyy_dogovor_individual'nykh_usloviy_po_kreditu_(iuk)_07.05.2023.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1439\/IMG_0238.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14391\/image_2023-05-25_20-16-31.png",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14393\/image_2023-05-23_19-06-51.png",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14395\/photo_2023-05-25_20-08-26.jpg",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14397\/ответ_претензия.png",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14404\/oferta_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14406\/0060235508_20230302.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14408\/Screenshot_2023-05-26_at_11.17.44.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14410\/Требование_(претензия)_о_расторжении_договора_и_возвратеенежных_средств.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14412\/operation_statement_21.04.2023.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14414\/Прочее.rar",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14422\/Доказательство_проведение_претензионной_работы__Михайловский_Максим_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14435\/00_документы_суд.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14475\/Д16052023.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14477\/2023-05-15_Хохлов_Максим_Дмитриевич_Приложение_к_оферте_CL-26387_84833.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14479\/2023-07-04_17-59-33.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14488\/00_Петров_документы_суд.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14593\/Доказательство_проведение_претензионной_работы__Ширмухамедов_Акбар_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14611\/доказательствоаправления_иска_ответчику_Колосов_ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14613\/0_Исковоеаявление_поелу_Колосов_ООО_-СКИЛБОКС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14615\/2_Расчет_исковыхребований_Колосов_ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14624\/Пользовательское_соглашение_в_ред._от_12.07.22.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14626\/Подтверждение_оплаты_в_СберБанке.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14628\/2023-07-05_17-15-34.png",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14630\/Требования_поддержке.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1469\/Доказательство_проведение_претензионной_работы__Плешкова_Алина_2_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14718\/доказательствоаправления_иска_ответчикуапенко_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14720\/0_Исковоеаявление_поелуапенко_ООО_-ГИКБРЕИНС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14722\/2_Расчет_исковыхребований_Цапенко_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14737\/Колосов_документы_суд.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14744\/Оферта._Редакция_от_29_августа_2022г.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14746\/Zaâvlenie_na_oplatu_tovarov_(uslug).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14748\/IMG_4083.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14750\/IMG_4084.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14820\/Цапенкоокументы_суд.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14827\/kvk_(34)_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14829\/3rNhCFnHlOs.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14831\/onOUwSZWvdU.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14839\/kvk_(34)_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14841\/3rNhCFnHlOs.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14843\/onOUwSZWvdU.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14846\/доказательствоаправления_иска_ответчику_Уварова_ИП_Ложкина_Анжеликаеннадиевна_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14848\/0_Исковоеаявление_поелу_Уварова_ИП_Ложкина_Анжеликаеннадиевна_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14850\/2_Расчет_исковыхребований_Уварова_ИП_Ложкина_Анжеликаеннадиевна_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14853\/доказательствоаправления_иска_ответчикуарбузов_АНО_-ЦРП-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14855\/0_Исковоеаявление_поелуарбузов_АНО_-ЦРП-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14857\/2_Расчет_исковыхребований_Гарбузов_АНО_-ЦРП-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14860\/доказательствоаправления_иска_ответчикуоселянина_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14862\/0_Исковоеаявление_поелуоселянина_ООО_-ГИКБРЕИНС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14864\/2_Расчет_исковыхребований_Поселянина_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14867\/доказательствоаправления_иска_ответчику_Кукса_ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14869\/0_Исковоеаявление_поелу_Кукса_ООО_-СКИЛБОКС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14874\/2_Расчет_исковыхребований_Кукса_ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14898\/доказательствоаправления_иска_ответчикууперина_ООО_-Скилбокс-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14900\/0_Исковоеаявление_поелууперина_ООО_-Скилбокс-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14902\/2_Расчет_исковыхребований_Жуперина_ООО_-Скилбокс-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14905\/доказательствоаправления_иска_ответчику_Мягкий_ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14907\/0_Исковоеаявление_поелу_Мягкий_ООО_-СКИЛБОКС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14909\/2_Расчет_исковыхребований_Мягкий_ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14912\/доказательствоаправления_иска_ответчику_Кузьмина__ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14914\/0_Исковоеаявление_поелу_Кузьмина__ООО_-СКИЛБОКС-_4_стр_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14916\/2_Расчет_исковыхребований_Кузьмина__ООО_-СКИЛБОКС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14934\/доказательствоаправления_иска_ответчику_Дителев_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14936\/0_Исковоеаявление_поелу_Дителев_ООО_-ГИКБРЕИНС-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14941\/2_Расчет_исковыхребований_Дителев_ООО_-ГИКБРЕИНС-_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14944\/доказательствоаправления_иска_ответчику_Нечаева__ИП_Ширков_Данила_Семёнович_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14946\/0_Исковоеаявление_поелу_Нечаева__ИП_Ширков_Данила_Семёнович_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/14948\/2_Расчет_исковыхребований_Нечаева__ИП_Ширков_Данила_Семёнович_1_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1516\/Оферта._Редакция_от_29_августа_2022г.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1518\/КАЮМОВАНИИЛ_ФЛЮРОВИЧ_(1).pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/1520\/Фотографии_личногоабинета.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/15223\/Договор_Дизайн_цифровых_продуктов_70_первые_полгода_бесплатно_Амбарцумян_Диана_Эдуардовна.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/15225\/Договор_Дизайн_цифровых_продуктов_70_первые_полгода_бесплатно_Амбарцумян_Диана_Эдуардовна.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/15227\/Договор_Дизайн_цифровых_продуктов_70_первые_полгода_бесплатно_Амбарцумян_Диана_Эдуардовна.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/15229\/претензия_ответ_Амбарцумян_Д.Э..pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/152984\/7_заявление_потребителя_Пономарева__.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/152989\/Договор_05-23-2024-08-50-46_Пономарева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/152991\/Подтверждение_оплаты_05-23-2024-08-54-48_Пономарева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/152993\/Программа_обучения_05-23-2024-08-55-21_Пономарева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/152995\/Скриншот_прогресса_обучения_05-23-2024-08-58-09_Пономарева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/152997\/Претензия_05-23-2024-08-59-05_Пономарева__1_CTP#realfile.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/15309\/Заявление_(1).PDF",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/15345\/_.zip",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/154432\/0_Исковоеаявление_поелу_Окуньков__ООО_-ТЕРРА_ЭЙАЙ-_4_стр.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/155051\/7777777_Заявление_о_выдачи_исполнительного_листа_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/155057\/7777777_Заявление_о_выдачи_исполнительного_листа_.pdf",
"Не найдена версия для восстановления: crm2\/CRM_Active_Files\/Documents\/155260\/7777777_Заявление_о_выдачи_исполнительного_листа_.pdf"
]
}

View File

@@ -0,0 +1,7 @@
{
"total_markers": 0,
"restored": 0,
"failed": 0,
"skipped": 0,
"errors": []
}

View File

@@ -0,0 +1,7 @@
{
"total_markers": 0,
"restored": 0,
"failed": 0,
"skipped": 0,
"errors": []
}

View File

@@ -0,0 +1,7 @@
{
"total_markers": 46,
"restored": 2,
"failed": 43,
"skipped": 1,
"errors": []
}

168
restore_project_373977.php Normal file
View File

@@ -0,0 +1,168 @@
<?php
/**
* Восстановление документов проекта 373977
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 373977;
$s3Bucket = $config['s3']['bucket'];
$prefix = 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/';
$files = [
373981 => '8_Договора_оказание_услуг_373981.pdf',
373983 => '9_Подтверждение_оплаты_пооговору_373983.pdf',
373985 => '10_2_Скрин_личногоабинетастца_и_программа_обуч_373985.pdf',
373987 => '10_1_Скрин_личногоабинетастца_и_программа_обуч_373987.pdf',
373989 => '11_1_Подтверждение_проведения_претензионной_работы_373989.pdf',
373991 => '7_заявление_потребителя_373991.pdf',
374017 => '11_Доказательство_соблюдения_претензионного_порядк_374017.pdf',
375402 => '11.2_Претензия_в_защиту_интересов_Полулях_Ольга_1_375402.pdf',
375404 => '11.3_Доказательство_оплаты_направления_претензии_о_375404.pdf',
375406 => '11.4_Доказательствоаправления_претензии_ответчик_375406.pdf',
376051 => '0_Исковоеаявление_поелуолулях_7_стр_376051.pdf',
376054 => '6_Расчет_исковыхребований_Полулях_1_стр_376054.pdf',
376080 => '12.1_Доказательство_оплаты_направления_иска_ответч_376080.pdf',
376082 => '12.2_Доказательствоаправления_иска_ответчику_376082.pdf',
];
echo "=== ВОССТАНОВЛЕНИЕ ДОКУМЕНТОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
$dryRun = isset($argv[1]) && $argv[1] === '--dry-run';
if ($dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run)\n\n";
}
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($files),
'restored' => 0,
'already_exists' => 0,
'no_versions' => 0,
'failed' => 0,
];
foreach ($files as $docId => $filename) {
$key = $prefix . $filename;
echo "Документ ID: {$docId}\n";
echo " Файл: {$filename}\n";
// Проверяем, существует ли файл
if ($s3Client->doesObjectExist($s3Bucket, $key)) {
echo " ✅ Файл уже существует\n\n";
$stats['already_exists']++;
continue;
}
// Проверяем версии
try {
$versions = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $key,
'MaxKeys' => 10,
]);
$deleteMarkers = $versions['DeleteMarkers'] ?? [];
$fileVersions = $versions['Versions'] ?? [];
if (empty($deleteMarkers) && empty($fileVersions)) {
echo " ❌ Нет версий для восстановления\n\n";
$stats['no_versions']++;
continue;
}
echo " Найдено delete markers: " . count($deleteMarkers) . "\n";
echo " Найдено версий: " . count($fileVersions) . "\n";
if (!$dryRun) {
// Удаляем все delete markers
foreach ($deleteMarkers as $marker) {
try {
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $key,
'VersionId' => $marker['VersionId'],
]);
echo " ✅ Delete marker удален\n";
} catch (Exception $e) {
echo " ⚠️ Ошибка удаления delete marker: " . $e->getMessage() . "\n";
}
}
// Проверяем, появился ли файл после удаления delete marker
if (!$s3Client->doesObjectExist($s3Bucket, $key) && !empty($fileVersions)) {
// Копируем последнюю версию
$latestVersion = $fileVersions[0];
try {
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $key,
'CopySource' => "{$s3Bucket}/{$key}?versionId={$latestVersion['VersionId']}",
]);
echo " ✅ Файл восстановлен из версии\n";
} catch (Exception $e) {
echo " ⚠️ Ошибка копирования версии: " . $e->getMessage() . "\n";
}
} else {
echo " ✅ Файл восстановлен\n";
}
$stats['restored']++;
sleep(1);
} else {
echo " ⏸️ Будет восстановлен (dry-run)\n";
$stats['restored']++;
}
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$stats['failed']++;
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего файлов: {$stats['total']}\n";
if (!$dryRun) {
echo "Восстановлено: {$stats['restored']}\n";
echo "Уже существует: {$stats['already_exists']}\n";
echo "Нет версий: {$stats['no_versions']}\n";
echo "Ошибок: {$stats['failed']}\n";
} else {
echo "Будет восстановлено: {$stats['restored']}\n";
echo "Уже существует: {$stats['already_exists']}\n";
echo "Нет версий: {$stats['no_versions']}\n";
}
echo "\n=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Критическая ошибка: " . $e->getMessage() . "\n";
exit(1);
}

132
restore_project_391584.php Normal file
View File

@@ -0,0 +1,132 @@
<?php
/**
* Восстановление файлов проекта 391584
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 391584;
$s3Bucket = $config['s3']['bucket'];
$projectPrefix = 'crm2/CRM_Active_Files/Documents/Project/ЧужбаОУ_ДПО_ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_СКИЛБОКС_(КОРОБКА_НАВЫКОВ)_391584/';
// Документы проекта
$documents = [
391587 => '8_Договора_оказание_услуг_391587.pdf',
391589 => '9_Подтверждение_оплаты_пооговору_391589.pdf',
391591 => '10_1_Скрин_личногоабинетастца_и_программа_обуч_391591.pdf',
391593 => '7_заявление_потребителя_391593.pdf',
392332 => '11_Доказательство_соблюдения_претензионного_порядк_392332.pdf',
392472 => '11.1_Доказательство_соблюдения_претензионного_поря_392472.pdf',
392475 => '11.2_Доказательство_соблюдения_претензионного_поря_392475.pdf',
395136 => '6_Расчет_искаужба_395136.pdf',
395157 => '0_Исковоеаявление_поелуужбаОУ_ДПО_ОБРАЗОВА_395157.pdf',
395744 => '12.1_Доказательство_оплаты_направления_иска_ответч_395744.pdf',
];
echo "=== ВОССТАНОВЛЕНИЕ ФАЙЛОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($documents),
'restored' => 0,
'not_found' => 0,
'already_exists' => 0,
];
foreach ($documents as $docId => $filename) {
$s3Key = $projectPrefix . $filename;
echo "Документ ID: {$docId}\n";
echo " Файл: {$filename}\n";
// Проверяем, существует ли файл
if ($s3Client->doesObjectExist($s3Bucket, $s3Key)) {
echo " ✅ Файл уже существует\n\n";
$stats['already_exists']++;
continue;
}
// Проверяем наличие версий и delete markers
try {
$versions = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $s3Key,
'MaxKeys' => 10,
]);
$deleteMarkers = $versions['DeleteMarkers'] ?? [];
$fileVersions = $versions['Versions'] ?? [];
if (empty($deleteMarkers) && empty($fileVersions)) {
echo " ❌ Файл не найден и нет версий\n\n";
$stats['not_found']++;
continue;
}
// Удаляем delete markers
foreach ($deleteMarkers as $marker) {
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'VersionId' => $marker['VersionId'],
]);
echo " ✅ Delete marker удален\n";
}
// Если файл все еще не существует, восстанавливаем из версии
if (!$s3Client->doesObjectExist($s3Bucket, $s3Key) && !empty($fileVersions)) {
$latestVersion = $fileVersions[0];
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'CopySource' => "{$s3Bucket}/{$s3Key}?versionId={$latestVersion['VersionId']}",
]);
echo " ✅ Файл восстановлен из версии\n";
} else {
echo " ✅ Файл восстановлен\n";
}
$stats['restored']++;
sleep(1);
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$stats['not_found']++;
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего документов: {$stats['total']}\n";
echo "✅ Восстановлено: {$stats['restored']}\n";
echo "✅ Уже существовало: {$stats['already_exists']}\n";
echo "Не найдено: {$stats['not_found']}\n\n";
echo "=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Критическая ошибка: " . $e->getMessage() . "\n";
exit(1);
}

199
restore_project_394091.php Normal file
View File

@@ -0,0 +1,199 @@
<?php
/**
* Скрипт для восстановления файлов проекта 394091
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
set_time_limit(0);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
$projectId = 394091;
echo "=== ВОССТАНОВЛЕНИЕ ФАЙЛОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
// Параметры
$dryRun = isset($argv[1]) && $argv[1] === '--dry-run';
if ($dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run) - файлы не будут восстановлены\n\n";
}
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
// Получаем документы проекта из БД
echo "Подключение к БД...\n";
$db = PearDatabase::getInstance();
echo "✅ БД подключена\n";
echo "Выполнение запроса...\n";
$result = $db->pquery("
SELECT n.notesid, n.filename, n.filelocationtype, n.s3_bucket, n.s3_key, n.filesize
FROM vtiger_notes n
INNER JOIN vtiger_senotesrel sn ON sn.notesid = n.notesid
WHERE sn.crmid = ?
ORDER BY n.notesid
", array($projectId));
echo "✅ Запрос выполнен\n";
$totalDocs = $db->num_rows($result);
echo "Найдено документов в БД: {$totalDocs}\n\n";
if ($totalDocs == 0) {
echo "Документы не найдены!\n";
exit(0);
}
$stats = [
'total_docs' => $totalDocs,
'existing' => 0,
'deleted' => 0,
'missing' => 0,
'restored' => 0,
'failed' => 0,
'errors' => []
];
// Проверяем каждый документ
while ($row = $db->fetch_array($result)) {
$s3Key = $row['s3_key'];
$docId = $row['notesid'];
$filename = $row['filename'];
echo "Документ ID: {$docId} | Файл: {$filename}\n";
if (empty($s3Key)) {
echo " ⚠️ Нет S3 ключа\n\n";
$stats['missing']++;
continue;
}
echo " S3 ключ: {$s3Key}\n";
// Проверяем существование файла
$exists = $s3Client->doesObjectExist($s3Bucket, $s3Key);
if ($exists) {
echo " ✅ Файл существует\n\n";
$stats['existing']++;
continue;
}
// Проверяем версии и delete markers
try {
$versions = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $s3Key,
]);
$deleteMarker = null;
$fileVersion = null;
foreach ($versions['Versions'] ?? [] as $version) {
if (isset($version['IsDeleteMarker']) && $version['IsDeleteMarker']) {
$deleteMarker = $version;
} else {
$fileVersion = $version;
}
}
if ($deleteMarker) {
echo " ❌ Файл удален (delete marker от " . $deleteMarker['LastModified']->format('Y-m-d H:i:s') . ")\n";
if (!$dryRun) {
// Удаляем delete marker
try {
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'VersionId' => $deleteMarker['VersionId'],
]);
// Если есть версия файла, копируем её
if ($fileVersion) {
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'CopySource' => "{$s3Bucket}/{$s3Key}?versionId={$fileVersion['VersionId']}",
]);
echo " ✅ Файл восстановлен из версии\n";
} else {
echo " ⚠️ Delete marker удален, но версия файла не найдена\n";
}
$stats['restored']++;
sleep(1); // Пауза между запросами
} catch (Exception $e) {
echo " ❌ Ошибка восстановления: " . $e->getMessage() . "\n";
$stats['failed']++;
$stats['errors'][] = "{$s3Key}: " . $e->getMessage();
}
} else {
echo " ⏸️ Будет восстановлен (dry-run)\n";
$stats['restored']++;
}
$stats['deleted']++;
} else {
echo " ⚠️ Файл отсутствует, но delete marker не найден\n";
$stats['missing']++;
}
} catch (Exception $e) {
echo " ❌ Ошибка проверки версий: " . $e->getMessage() . "\n";
$stats['failed']++;
$stats['errors'][] = "{$s3Key}: " . $e->getMessage();
}
echo "\n";
}
// Итоговая статистика
echo str_repeat("=", 80) . "\n";
echo "ИТОГОВАЯ СТАТИСТИКА:\n\n";
echo "Всего документов: {$stats['total_docs']}\n";
echo "Существующих файлов: {$stats['existing']}\n";
echo "Удаленных файлов (delete marker): {$stats['deleted']}\n";
echo "Отсутствующих файлов: {$stats['missing']}\n";
if (!$dryRun) {
echo "Восстановлено: {$stats['restored']}\n";
echo "Ошибок: {$stats['failed']}\n";
} else {
echo "Будет восстановлено: {$stats['restored']}\n";
}
if (!empty($stats['errors'])) {
echo "\nОшибки:\n";
foreach ($stats['errors'] as $error) {
echo " - {$error}\n";
}
}
echo "\n=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Критическая ошибка: " . $e->getMessage() . "\n";
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
exit(1);
}

View File

@@ -0,0 +1,156 @@
<?php
/**
* Упрощенный скрипт для восстановления файлов проекта 394091
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
$projectId = 394091;
// Файлы проекта из БД
$files = [
'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Договор_394094.pdf',
'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Подтверждение_оплаты_394096.pdf',
'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Претензия_394098.pdf',
'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Ответ_на_претензию_394100.pdf',
'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/7_заявление_потребителя_394105.pdf',
'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/experimental_report_20251018_095026_395943.xlsx',
];
echo "=== ВОССТАНОВЛЕНИЕ ФАЙЛОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
$dryRun = isset($argv[1]) && $argv[1] === '--dry-run';
if ($dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run)\n\n";
}
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($files),
'existing' => 0,
'deleted' => 0,
'missing' => 0,
'restored' => 0,
'failed' => 0,
];
foreach ($files as $s3Key) {
$filename = basename($s3Key);
echo "Файл: {$filename}\n";
echo " Путь: {$s3Key}\n";
// Проверяем существование
$exists = $s3Client->doesObjectExist($s3Bucket, $s3Key);
if ($exists) {
echo " ✅ Файл существует\n\n";
$stats['existing']++;
continue;
}
// Проверяем версии
try {
$versions = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $s3Key,
]);
$deleteMarker = null;
$fileVersion = null;
foreach ($versions['Versions'] ?? [] as $version) {
if (isset($version['IsDeleteMarker']) && $version['IsDeleteMarker']) {
$deleteMarker = $version;
} else {
$fileVersion = $version;
}
}
if ($deleteMarker) {
echo " ❌ Файл удален (delete marker от " . $deleteMarker['LastModified']->format('Y-m-d H:i:s') . ")\n";
if (!$dryRun) {
// Удаляем delete marker
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'VersionId' => $deleteMarker['VersionId'],
]);
echo " ✅ Delete marker удален\n";
// Восстанавливаем файл из версии
if ($fileVersion) {
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'CopySource' => "{$s3Bucket}/{$s3Key}?versionId={$fileVersion['VersionId']}",
]);
echo " ✅ Файл восстановлен из версии\n";
$stats['restored']++;
} else {
echo " ⚠️ Версия файла не найдена\n";
$stats['missing']++;
}
sleep(1);
} else {
echo " ⏸️ Будет восстановлен (dry-run)\n";
$stats['restored']++;
}
$stats['deleted']++;
} else {
echo " ⚠️ Файл отсутствует, delete marker не найден\n";
$stats['missing']++;
}
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$stats['failed']++;
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего файлов: {$stats['total']}\n";
echo "Существующих: {$stats['existing']}\n";
echo "Удаленных: {$stats['deleted']}\n";
echo "Отсутствующих: {$stats['missing']}\n";
if (!$dryRun) {
echo "Восстановлено: {$stats['restored']}\n";
echo "Ошибок: {$stats['failed']}\n";
} else {
echo "Будет восстановлено: {$stats['restored']}\n";
}
echo "\n=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Ошибка: " . $e->getMessage() . "\n";
exit(1);
}

355
search_by_doc_id.php Normal file
View File

@@ -0,0 +1,355 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$docId = 386869;
$s3Bucket = $config['s3']['bucket'];
echo "ПОЛНЫЙ поиск всех файлов, связанных с документом $docId\n";
echo str_repeat("=", 80) . "\n\n";
try {
// Получаем информацию о документе из БД
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$stmt = $pdo->prepare('SELECT notesid, title, s3_key, filename, filelocationtype FROM vtiger_notes WHERE notesid = ?');
$stmt->execute([$docId]);
$doc = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$doc) {
die("Документ $docId не найден в БД\n");
}
echo "Информация о документе:\n";
echo " ID: {$doc['notesid']}\n";
echo " Название: {$doc['title']}\n";
echo " S3 Key (ожидаемый): " . ($doc['s3_key'] ?: 'не указан') . "\n";
echo " Filename: " . substr($doc['filename'], 0, 150) . "\n";
echo " Тип хранения: " . ($doc['filelocationtype'] ?: 'не указан') . "\n\n";
// Инициализация S3 клиента
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$foundFiles = [];
// 1. Проверяем ожидаемый путь
echo "1. Проверка ожидаемого пути в S3...\n";
if (!empty($doc['s3_key'])) {
try {
$result = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $doc['s3_key']
]);
echo " ✅ Файл найден по ожидаемому пути!\n";
echo " Путь: {$doc['s3_key']}\n";
echo " Размер: " . number_format($result['ContentLength'] / 1024, 2) . " KB\n";
$foundFiles[] = [
'key' => $doc['s3_key'],
'size' => $result['ContentLength'],
'source' => 'ожидаемый путь'
];
} catch (\Aws\Exception\AwsException $e) {
echo " ❌ Файл не найден по ожидаемому пути: " . $e->getAwsErrorCode() . "\n";
}
}
echo "\n";
// 2. Поиск по точному ID документа
echo "2. Поиск файлов с точным ID $docId...\n";
$searchPatterns = [
(string)$docId,
(string)($docId - 1),
(string)($docId + 1),
(string)($docId - 2),
(string)($docId + 2),
];
$totalChecked = 0;
$maxFilesToCheck = 50000;
foreach ($searchPatterns as $pattern) {
echo " Поиск по паттерну: $pattern\n";
try {
$isTruncated = true;
$continuationToken = null;
$pageCount = 0;
$maxPages = 50;
while ($isTruncated && $pageCount < $maxPages && $totalChecked < $maxFilesToCheck) {
$params = [
'Bucket' => $s3Bucket,
'MaxKeys' => 1000
];
if ($continuationToken) {
$params['ContinuationToken'] = $continuationToken;
}
$objects = $s3Client->listObjectsV2($params);
$pageCount++;
$totalChecked += isset($objects['Contents']) ? count($objects['Contents']) : 0;
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
// Ищем файлы, содержащие паттерн
if (strpos($key, $pattern) !== false) {
// Проверяем, не добавили ли уже этот файл
$alreadyAdded = false;
foreach ($foundFiles as $found) {
if ($found['key'] === $key) {
$alreadyAdded = true;
break;
}
}
if (!$alreadyAdded) {
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
echo " ✅ НАЙДЕН: $key\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
echo " Дата: " . ($headResult['LastModified'] ?? 'не указана') . "\n";
$foundFiles[] = [
'key' => $key,
'size' => $headResult['ContentLength'],
'source' => "поиск по ID $pattern",
'date' => $headResult['LastModified'] ?? null
];
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем недоступные файлы
}
}
}
}
}
$isTruncated = isset($objects['IsTruncated']) && $objects['IsTruncated'];
$continuationToken = isset($objects['NextContinuationToken']) ? $objects['NextContinuationToken'] : null;
if (!$isTruncated) {
break;
}
}
} catch (\Aws\Exception\AwsException $e) {
echo " Ошибка при поиске: " . $e->getMessage() . "\n";
}
}
echo " Проверено файлов: $totalChecked\n\n";
// 3. Поиск по ключевым словам из названия документа
echo "3. Поиск по ключевым словам из названия...\n";
$title = mb_strtolower($doc['title']);
$keywords = [];
// Извлекаем ключевые слова
if (strpos($title, 'исковое') !== false) $keywords[] = 'iskovoe';
if (strpos($title, 'заявление') !== false) $keywords[] = 'zayavlenie';
if (strpos($title, 'марсель') !== false) $keywords[] = 'marse';
if (strpos($title, 'гафиев') !== false) $keywords[] = 'gafiev';
if (strpos($title, 'gafiev') !== false) $keywords[] = 'gafiev';
echo " Ключевые слова: " . implode(', ', $keywords) . "\n";
if (!empty($keywords)) {
// Ищем в temp/ папках
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => 'temp/',
'MaxKeys' => 10000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
$keyLower = mb_strtolower($key);
// Проверяем совпадение по ключевым словам
$matches = 0;
foreach ($keywords as $keyword) {
if (strpos($keyLower, $keyword) !== false) {
$matches++;
}
}
// Если совпало хотя бы 2 ключевых слова
if ($matches >= 2) {
$alreadyAdded = false;
foreach ($foundFiles as $found) {
if ($found['key'] === $key) {
$alreadyAdded = true;
break;
}
}
if (!$alreadyAdded) {
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
echo " ✅ НАЙДЕН по ключевым словам: $key\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
$foundFiles[] = [
'key' => $key,
'size' => $headResult['ContentLength'],
'source' => 'поиск по ключевым словам',
'date' => $headResult['LastModified'] ?? null
];
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем
}
}
}
}
}
} catch (\Aws\Exception\AwsException $e) {
echo " Ошибка при поиске: " . $e->getMessage() . "\n";
}
}
echo "\n";
// 4. Поиск в папке проекта (если известен projectId)
echo "4. Поиск в папке проекта...\n";
$stmt = $pdo->prepare('SELECT crmid FROM vtiger_senotesrel WHERE notesid = ? LIMIT 1');
$stmt->execute([$docId]);
$projectRel = $stmt->fetch(PDO::FETCH_ASSOC);
if ($projectRel) {
$projectId = $projectRel['crmid'];
echo " Проект ID: $projectId\n";
$projectPrefixes = [
"crm2/CRM_Active_Files/Documents/Project/",
"temp/$projectId/",
];
foreach ($projectPrefixes as $prefix) {
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => $prefix,
'MaxKeys' => 1000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
// Ищем файлы с ID документа
if (strpos($key, (string)$docId) !== false ||
strpos($key, (string)($docId - 1)) !== false ||
strpos($key, (string)($docId + 1)) !== false) {
$alreadyAdded = false;
foreach ($foundFiles as $found) {
if ($found['key'] === $key) {
$alreadyAdded = true;
break;
}
}
if (!$alreadyAdded) {
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
echo " ✅ НАЙДЕН в папке проекта: $key\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
$foundFiles[] = [
'key' => $key,
'size' => $headResult['ContentLength'],
'source' => "папка проекта $projectId",
'date' => $headResult['LastModified'] ?? null
];
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем
}
}
}
}
}
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем ошибки
}
}
}
echo "\n";
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГОВЫЕ РЕЗУЛЬТАТЫ:\n";
echo " Всего найдено файлов: " . count($foundFiles) . "\n\n";
if (!empty($foundFiles)) {
echo "НАЙДЕННЫЕ ФАЙЛЫ:\n";
foreach ($foundFiles as $i => $file) {
echo " " . ($i + 1) . ". {$file['key']}\n";
echo " Размер: " . number_format($file['size'] / 1024, 2) . " KB\n";
echo " Источник: {$file['source']}\n";
if ($file['date']) {
echo " Дата: {$file['date']}\n";
}
echo "\n";
}
// Определяем наиболее вероятный файл
echo "💡 РЕКОМЕНДАЦИЯ:\n";
$bestMatch = null;
foreach ($foundFiles as $file) {
if ($file['source'] === 'ожидаемый путь') {
$bestMatch = $file;
break;
}
}
if (!$bestMatch && !empty($foundFiles)) {
// Берем первый найденный файл
$bestMatch = $foundFiles[0];
}
if ($bestMatch) {
echo " Наиболее вероятный файл: {$bestMatch['key']}\n";
echo " Этот файл можно использовать для обновления s3_key в БД\n";
}
} else {
echo " ❌ Файлы не найдены в S3\n";
echo " Возможно, файл находится в Nextcloud или локальном хранилище\n";
}
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

216
search_file_in_s3.php Normal file
View File

@@ -0,0 +1,216 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
$projectId = 371231;
$docId = 371983;
echo "Поиск файла в S3\n";
echo "Bucket: $s3Bucket\n";
echo "Project ID: $projectId\n";
echo "Document ID: $docId\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
// Получаем s3_key из БД
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$stmt = $pdo->prepare('SELECT s3_key, filename FROM vtiger_notes WHERE notesid = ?');
$stmt->execute([$docId]);
$doc = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$doc) {
die("Документ $docId не найден в БД\n");
}
$s3Key = $doc['s3_key'];
echo "S3 Key из БД: $s3Key\n\n";
// Варианты путей для проверки
$variants = [
$s3Key, // Оригинальный путь
rawurlencode($s3Key), // URL-encoded
str_replace(' ', '_', $s3Key), // Замена пробелов
str_replace(' ', '%20', $s3Key), // Пробелы как %20
];
echo "1. Проверка существования файла по разным вариантам пути:\n";
foreach ($variants as $i => $variant) {
echo " Вариант " . ($i + 1) . ": " . substr($variant, 0, 100) . "...\n";
try {
$result = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $variant
]);
echo " ✅ Файл найден! Size: " . $result['ContentLength'] . " bytes\n";
echo " ContentType: " . $result['ContentType'] . "\n";
break;
} catch (\Aws\Exception\AwsException $e) {
if ($e->getAwsErrorCode() == 'NotFound') {
echo "Не найден\n";
} else {
echo " ⚠️ Ошибка: " . $e->getAwsErrorCode() . "\n";
}
}
}
echo "\n";
// Поиск всех файлов в папке проекта
echo "2. Поиск всех файлов в папке проекта:\n";
$prefixes = [
"crm2/CRM_Active_Files/Documents/Project/",
"crm2/CRM_Active_Files/Documents/",
"Documents/Project/",
"Documents/",
];
$allFoundFiles = [];
foreach ($prefixes as $projectPrefix) {
echo " Проверка префикса: $projectPrefix\n";
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => $projectPrefix,
'MaxKeys' => 1000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
// Ищем файлы, связанные с проектом 371231 или документом 371983
if (strpos($key, (string)$projectId) !== false || strpos($key, '371983') !== false ||
strpos($key, 'Ломакин') !== false || strpos($key, 'НЕТОЛОГИЯ') !== false) {
if (!in_array($key, $allFoundFiles)) {
$allFoundFiles[] = $key;
}
}
}
}
} catch (\Aws\Exception\AwsException $e) {
echo " Ошибка при поиске: " . $e->getMessage() . "\n";
}
}
if (!empty($allFoundFiles)) {
echo " Найдено " . count($allFoundFiles) . " файлов:\n";
foreach ($allFoundFiles as $file) {
echo " - $file\n";
}
} else {
echo " Файлы проекта не найдены в S3\n";
}
echo "\n";
// Поиск файла по имени (без полного пути)
echo "3. Поиск файла по имени и ID документа:\n";
$searchPatterns = [
"11.1_Доказательство_соблюдения_претензионного_поря_371983.pdf",
"371983",
"11.1",
"Доказательство_соблюдения"
];
$foundFiles = [];
foreach ($searchPatterns as $pattern) {
echo " Поиск по паттерну: $pattern\n";
try {
// Ищем в разных префиксах
$searchPrefixes = [
"crm2/CRM_Active_Files/",
"Documents/",
""
];
foreach ($searchPrefixes as $prefix) {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => $prefix,
'MaxKeys' => 5000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
if (stripos($key, $pattern) !== false) {
if (!in_array($key, $foundFiles)) {
$foundFiles[] = $key;
}
}
}
}
}
} catch (\Aws\Exception\AwsException $e) {
echo " Ошибка при поиске: " . $e->getMessage() . "\n";
}
}
if (!empty($foundFiles)) {
echo " Найдено " . count($foundFiles) . " файлов:\n";
foreach ($foundFiles as $file) {
echo " - $file\n";
// Проверяем доступность
try {
$result = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $file
]);
echo " ✅ Доступен, размер: " . $result['ContentLength'] . " bytes\n";
} catch (\Aws\Exception\AwsException $e) {
echo " ❌ Недоступен: " . $e->getAwsErrorCode() . "\n";
}
}
} else {
echo " Файл не найден по имени\n";
}
// Проверяем все документы проекта из БД
echo "\n4. Проверка всех документов проекта из БД:\n";
$stmt = $pdo->prepare('SELECT n.notesid, n.title, n.s3_key FROM vtiger_notes n INNER JOIN vtiger_crmentity e ON e.crmid = n.notesid INNER JOIN vtiger_senotesrel snr ON snr.notesid = n.notesid WHERE snr.crmid = ? AND e.deleted = 0 AND n.filelocationtype = "E" ORDER BY n.notesid DESC LIMIT 10');
$stmt->execute([$projectId]);
$docs = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo " Проверка " . count($docs) . " документов:\n";
$foundCount = 0;
foreach ($docs as $doc) {
$key = $doc['s3_key'];
try {
$result = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
echo " ✅ ID {$doc['notesid']}: " . substr($doc['title'], 0, 50) . "...\n";
$foundCount++;
} catch (\Aws\Exception\AwsException $e) {
if ($e->getAwsErrorCode() == 'NotFound') {
echo " ❌ ID {$doc['notesid']}: " . substr($doc['title'], 0, 50) . "... (не найден)\n";
}
}
}
echo " Найдено в S3: $foundCount из " . count($docs) . "\n";
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

259
search_in_trash.php Normal file
View File

@@ -0,0 +1,259 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$docIds = [386869, 394973];
$s3Bucket = $config['s3']['bucket'];
echo "Поиск файлов в корзине/удаленных версиях S3\n";
echo str_repeat("=", 80) . "\n\n";
try {
// Получаем информацию о документах из БД
$pdo = new PDO(
"mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8",
$dbconfig['db_username'],
$dbconfig['db_password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
// Инициализация S3 клиента
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
foreach ($docIds as $docId) {
echo "Поиск файла для документа $docId:\n";
echo str_repeat("-", 80) . "\n";
$stmt = $pdo->prepare('SELECT notesid, title, s3_key, s3_etag, filesize FROM vtiger_notes WHERE notesid = ?');
$stmt->execute([$docId]);
$doc = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$doc) {
echo " Документ не найден в БД\n\n";
continue;
}
echo " Название: {$doc['title']}\n";
echo " Ожидаемый путь: {$doc['s3_key']}\n";
echo " ETag: {$doc['s3_etag']}\n";
echo " Размер: " . number_format($doc['filesize'] / 1024, 2) . " KB\n\n";
$s3Key = $doc['s3_key'];
$targetEtag = trim($doc['s3_etag'], '"');
$targetSize = $doc['filesize'];
// 1. Проверяем версии объекта (если включено versioning)
echo " 1. Проверка версий объекта...\n";
try {
$versions = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $s3Key,
'MaxKeys' => 100
]);
if (isset($versions['Versions']) && !empty($versions['Versions'])) {
echo " ✅ Найдено версий: " . count($versions['Versions']) . "\n";
foreach ($versions['Versions'] as $version) {
$versionKey = $version['Key'];
$versionId = $version['VersionId'];
$isDeleteMarker = isset($version['IsDeleteMarker']) && $version['IsDeleteMarker'];
$versionEtag = isset($version['ETag']) ? trim($version['ETag'], '"') : null;
$versionSize = isset($version['Size']) ? $version['Size'] : null;
if ($isDeleteMarker) {
echo " ⚠️ Delete Marker: VersionId=$versionId, Дата: " . ($version['LastModified'] ?? 'не указана') . "\n";
} else {
$matchInfo = [];
if ($versionEtag === $targetEtag) {
$matchInfo[] = "ETag совпадает";
}
if ($versionSize && abs($versionSize - $targetSize) <= 100) {
$matchInfo[] = "размер совпадает (" . number_format($versionSize / 1024, 2) . " KB)";
}
echo " ✅ Версия: VersionId=$versionId\n";
echo " Размер: " . ($versionSize ? number_format($versionSize / 1024, 2) . " KB" : 'не указан') . "\n";
echo " ETag: " . ($versionEtag ?: 'не указан') . "\n";
echo " Дата: " . ($version['LastModified'] ?? 'не указана') . "\n";
if (!empty($matchInfo)) {
echo " " . implode(', ', $matchInfo) . "\n";
}
echo "\n";
}
}
} else {
echo " ❌ Версии не найдены (возможно, versioning не включен)\n";
}
} catch (\Aws\Exception\AwsException $e) {
if ($e->getAwsErrorCode() == 'AccessDenied' || strpos($e->getMessage(), 'versioning') !== false) {
echo " ⚠️ Версионирование не включено или нет доступа: " . $e->getAwsErrorCode() . "\n";
} else {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
}
}
echo "\n";
// 2. Проверяем delete markers
echo " 2. Проверка delete markers...\n";
try {
$deleteMarkers = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $s3Key,
'MaxKeys' => 100
]);
if (isset($deleteMarkers['DeleteMarkers']) && !empty($deleteMarkers['DeleteMarkers'])) {
echo " ✅ Найдено delete markers: " . count($deleteMarkers['DeleteMarkers']) . "\n";
foreach ($deleteMarkers['DeleteMarkers'] as $marker) {
echo " ⚠️ Delete Marker найден:\n";
echo " VersionId: " . ($marker['VersionId'] ?? 'не указан') . "\n";
echo " Дата удаления: " . ($marker['LastModified'] ?? 'не указана') . "\n";
echo " Ключ: " . ($marker['Key'] ?? 'не указан') . "\n";
echo "\n";
echo " 💡 Файл был удален, но можно восстановить, удалив delete marker\n";
}
} else {
echo " ❌ Delete markers не найдены\n";
}
} catch (\Aws\Exception\AwsException $e) {
echo " ⚠️ Ошибка при проверке delete markers: " . $e->getAwsErrorCode() . "\n";
}
echo "\n";
// 3. Проверяем папки с названиями типа trash, deleted, recycle и т.д.
echo " 3. Поиск в папках корзины...\n";
$trashPrefixes = [
'trash/',
'deleted/',
'recycle/',
'.trash/',
'deleted_files/',
'removed/',
];
$foundInTrash = false;
foreach ($trashPrefixes as $trashPrefix) {
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => $trashPrefix,
'MaxKeys' => 1000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
// Ищем файлы с ID документа или похожим размером
if (strpos($key, (string)$docId) !== false ||
(isset($object['Size']) && abs($object['Size'] - $targetSize) <= 100)) {
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
$fileEtag = isset($headResult['ETag']) ? trim($headResult['ETag'], '"') : null;
echo " ✅ НАЙДЕН в $trashPrefix:\n";
echo " Путь: $key\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
echo " ETag: " . ($fileEtag ?: 'не указан') . "\n";
if ($fileEtag === $targetEtag) {
echo " ✅ ТОЧНОЕ СОВПАДЕНИЕ ПО ETAG!\n";
}
$foundInTrash = true;
echo "\n";
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем
}
}
}
}
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем ошибки
}
}
if (!$foundInTrash) {
echo " ❌ Файлы не найдены в папках корзины\n";
}
echo "\n";
// 4. Проверяем, может быть файл был перемещен в другую папку проекта
echo " 4. Поиск по ETag во всех папках проекта...\n";
$projectId = 384256; // Из предыдущих запросов
$projectPrefixes = [
"crm2/CRM_Active_Files/Documents/Project/Гафиев_ООО_ЭДЭКС_$projectId/",
"temp/$projectId/",
];
$foundByEtag = false;
foreach ($projectPrefixes as $prefix) {
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => $prefix,
'MaxKeys' => 1000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
$fileEtag = isset($headResult['ETag']) ? trim($headResult['ETag'], '"') : null;
if ($fileEtag === $targetEtag) {
echo " ✅ НАЙДЕН ПО ETAG в $prefix:\n";
echo " Путь: $key\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
echo " ETag: $fileEtag\n";
echo " 💡 Это точно нужный файл!\n";
$foundByEtag = true;
echo "\n";
}
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем
}
}
}
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем ошибки
}
}
if (!$foundByEtag) {
echo " ❌ Файл с таким ETag не найден в папках проекта\n";
}
echo "\n";
}
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

211
search_missing_files.php Normal file
View File

@@ -0,0 +1,211 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 384256;
$s3Bucket = $config['s3']['bucket'];
// Список недоступных документов
$missingDocs = [
['id' => 384443, 'title' => '11 Доказательство соблюдения претензионного порядк'],
['id' => 386865, 'title' => '12 Доказательство направления иска ответчику'],
['id' => 386867, 'title' => '6 Расчет иска Гафиев'],
['id' => 386869, 'title' => '0 Исковое заявление Марсель Гафиев'],
['id' => 388119, 'title' => '12.1 Доказательство оплаты направления иска ответч'],
['id' => 388121, 'title' => '12.2 Доказательство направления иска ответчику'],
['id' => 389699, 'title' => 'Ходатайство_поелу_М-1035-2025_1_стр'],
['id' => 394973, 'title' => 'Решение ГАфиев'],
];
echo "Поиск недостающих файлов проекта $projectId в S3\n";
echo str_repeat("=", 80) . "\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
// Ищем во всех temp/ папках
echo "1. Поиск во всех temp/ папках...\n";
$tempPrefixes = [];
// Получаем список всех temp/ папок
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => 'temp/',
'Delimiter' => '/',
'MaxKeys' => 1000
]);
if (isset($objects['CommonPrefixes'])) {
foreach ($objects['CommonPrefixes'] as $prefix) {
$tempPrefixes[] = $prefix['Prefix'];
}
}
} catch (\Aws\Exception\AwsException $e) {
echo " Ошибка при получении списка temp/ папок: " . $e->getMessage() . "\n";
}
echo " Найдено temp/ папок: " . count($tempPrefixes) . "\n\n";
$foundFiles = [];
// Ищем файлы по ID документов во всех temp/ папках
foreach ($missingDocs as $doc) {
$docId = $doc['id'];
echo "Поиск файла для документа $docId: {$doc['title']}\n";
$found = false;
// Ищем в каждой temp/ папке
foreach ($tempPrefixes as $tempPrefix) {
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => $tempPrefix,
'MaxKeys' => 1000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
// Ищем файлы с ID документа или близкими ID
if (strpos($key, (string)$docId) !== false ||
strpos($key, (string)($docId - 1)) !== false ||
strpos($key, (string)($docId + 1)) !== false ||
strpos($key, (string)($docId - 2)) !== false ||
strpos($key, (string)($docId + 2)) !== false) {
// Проверяем доступность
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
echo " ✅ НАЙДЕН в $tempPrefix\n";
echo " Путь: $key\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
$foundFiles[] = [
'doc_id' => $docId,
'doc_title' => $doc['title'],
's3_key' => $key,
'size' => $headResult['ContentLength']
];
$found = true;
break 2;
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем
}
}
}
}
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем ошибки
}
}
// Также ищем по ключевым словам из названия
if (!$found) {
$keywords = [];
$title = mb_strtolower($doc['title']);
// Извлекаем ключевые слова
if (strpos($title, 'доказательство') !== false) $keywords[] = 'dokazatelstvo';
if (strpos($title, 'расчет') !== false) $keywords[] = 'raschet';
if (strpos($title, 'исковое') !== false) $keywords[] = 'iskovoe';
if (strpos($title, 'ходатайство') !== false) $keywords[] = 'hodataystvo';
if (strpos($title, 'решение') !== false) $keywords[] = 'reshenie';
if (strpos($title, 'оплаты') !== false) $keywords[] = 'oplaty';
if (strpos($title, 'направления') !== false) $keywords[] = 'napravleniya';
// Ищем по ключевым словам во всех temp/ папках
foreach ($tempPrefixes as $tempPrefix) {
try {
$objects = $s3Client->listObjectsV2([
'Bucket' => $s3Bucket,
'Prefix' => $tempPrefix,
'MaxKeys' => 1000
]);
if (isset($objects['Contents'])) {
foreach ($objects['Contents'] as $object) {
$key = $object['Key'];
$keyLower = mb_strtolower($key);
foreach ($keywords as $keyword) {
if (strpos($keyLower, $keyword) !== false) {
try {
$headResult = $s3Client->headObject([
'Bucket' => $s3Bucket,
'Key' => $key
]);
echo " ✅ НАЙДЕН по ключевому слову в $tempPrefix\n";
echo " Путь: $key\n";
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
$foundFiles[] = [
'doc_id' => $docId,
'doc_title' => $doc['title'],
's3_key' => $key,
'size' => $headResult['ContentLength']
];
$found = true;
break 3;
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем
}
}
}
}
}
} catch (\Aws\Exception\AwsException $e) {
// Пропускаем ошибки
}
}
}
if (!$found) {
echo " ❌ Файл не найден\n";
}
echo "\n";
}
echo str_repeat("=", 80) . "\n";
echo "РЕЗУЛЬТАТЫ:\n";
echo " Найдено файлов: " . count($foundFiles) . " из " . count($missingDocs) . "\n\n";
if (!empty($foundFiles)) {
echo "НАЙДЕННЫЕ ФАЙЛЫ:\n";
foreach ($foundFiles as $file) {
echo " Документ {$file['doc_id']}: {$file['doc_title']}\n";
echo " Путь в S3: {$file['s3_key']}\n";
echo " Размер: " . number_format($file['size'] / 1024, 2) . " KB\n\n";
}
echo "💡 Эти файлы можно переместить в правильную структуру\n";
}
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}

View File

@@ -1 +1 @@
2025-11-21 14:05:08 2025-11-28 14:40:08

View File

@@ -0,0 +1,90 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:23
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ReportFilters.tpl" */ ?>
<?php /*%%SmartyHeaderCode:958547709692477b75edbb5-16336030%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'12fc8a5f5653a1bb6de7b45a4b2382af661b0b91' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ReportFilters.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '958547709692477b75edbb5-16336030',
'function' =>
array (
),
'variables' =>
array (
'REL_FIELDS' => 0,
'BLOCKJS_STD' => 0,
'VIEW' => 0,
'MODULE' => 0,
'REPORTTYPE' => 0,
'display_summaries_filter' => 0,
'SUMMARIES_CRITERIA' => 0,
'COLUMN_INDEX' => 0,
'COLUMN_CRITERIA' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477b760a05',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477b760a05')) {function content_692477b760a05($_smarty_tpl) {?>
<script type="text/javascript">
var advft_column_index_count = -1;
var advft_group_index_count = 0;
var column_index_array = [];
var group_index_array = [];
var gf_advft_column_index_count = -1;
var gf_advft_group_index_count = 0;
var gf_column_index_array = [];
var gf_group_index_array = [];
var rel_fields = <?php echo $_smarty_tpl->tpl_vars['REL_FIELDS']->value;?>
;
</script>
<?php echo $_smarty_tpl->getSubTemplate ('modules/ITS4YouReports/AdvanceFilter.tpl', $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php echo $_smarty_tpl->tpl_vars['BLOCKJS_STD']->value;?>
<input type="hidden" name="advft_criteria" id="advft_criteria" value="" />
<input type="hidden" name="advft_criteria_groups" id="advft_criteria_groups" value="" />
<input type="hidden" name="groupft_criteria" id="groupft_criteria" value="" />
<input type="hidden" name="quick_filter_criteria" id="quick_filter_criteria" value="" />
<?php if ('Detail'!=$_smarty_tpl->tpl_vars['VIEW']->value){?><div style="border:1px solid #ccc;padding:4%;"><?php }?><div class="row"><div class="form-group"><label class="control-label textAlignLeft col-lg-12"><h4><?php echo vtranslate('LBL_ADVANCED_FILTER',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h4></label></div></div><div class="row <?php if ('Detail'!=$_smarty_tpl->tpl_vars['VIEW']->value){?>well<?php }?> filterConditionContainer "><div class="form-group"><div class='filterContainer'><div style="display:block" id='adv_filter_div' name='adv_filter_div'><?php echo $_smarty_tpl->getSubTemplate ('modules/ITS4YouReports/FiltersCriteria.tpl', $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div><button type='button' class='btn btn-default' style='float:left;' onclick="addNewConditionGroup('adv_filter_div')"><i class="fa fa-plus"></i>&nbsp;<?php echo vtranslate('LBL_NEW_GROUP',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button></div></div></div><?php if ('Detail'!=$_smarty_tpl->tpl_vars['VIEW']->value){?><?php $_smarty_tpl->tpl_vars["display_summaries_filter"] = new Smarty_variable("display:block;", null, 0);?><?php if ($_smarty_tpl->tpl_vars['REPORTTYPE']->value=="tabular"){?><?php $_smarty_tpl->tpl_vars["display_summaries_filter"] = new Smarty_variable("display:none;", null, 0);?><?php }?><div style="width:100%;<?php echo $_smarty_tpl->tpl_vars['display_summaries_filter']->value;?>
" id='group_filter_div' name='group_filter_div' class="paddingTop20"><div class="row"><div class="form-group"><label class="control-label textAlignLeft col-lg-12"><h4><?php echo vtranslate('LBL_GROUP_FILTER',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h4></label></div></div><div class="row well filterConditionContainer " id='conditiongrouptable_0'><div class="form-group" id='ggroupfooter_0'><button type="button" class="btn btn-default" onclick='addGroupConditionRow("0")'><i class="fa fa-plus"></i>&nbsp;<?php echo vtranslate('LBL_NEW_CONDITION',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button></div></div><div class="row"><div class="form-group" id='groupconditionglue_0'></div></div><?php $_smarty_tpl->tpl_vars['COLUMN_CRITERIA'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->_loop = false;
$_smarty_tpl->tpl_vars['COLUMN_INDEX'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['SUMMARIES_CRITERIA']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->key => $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value){
$_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->_loop = true;
$_smarty_tpl->tpl_vars['COLUMN_INDEX']->value = $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->key;
?><script type="text/javascript">addGroupConditionRow('0');document.getElementById('ggroupop<?php echo $_smarty_tpl->tpl_vars['COLUMN_INDEX']->value;?>
').value = '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['comparator'];?>
';var conditionColumnRowElement = document.getElementById('ggroupcol<?php echo $_smarty_tpl->tpl_vars['COLUMN_INDEX']->value;?>
');conditionColumnRowElement.value = '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['columnname'];?>
';addRequiredElements('g', '<?php echo $_smarty_tpl->tpl_vars['COLUMN_INDEX']->value;?>
');var columnvalue = '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['value'];?>
';document.getElementById('ggroupval<?php echo $_smarty_tpl->tpl_vars['COLUMN_INDEX']->value;?>
').value = columnvalue;</script><?php } ?><?php $_smarty_tpl->tpl_vars['COLUMN_CRITERIA'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->_loop = false;
$_smarty_tpl->tpl_vars['COLUMN_INDEX'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['SUMMARIES_CRITERIA']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->key => $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value){
$_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->_loop = true;
$_smarty_tpl->tpl_vars['COLUMN_INDEX']->value = $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->key;
?><script type="text/javascript">if (document.getElementById('gcon<?php echo $_smarty_tpl->tpl_vars['COLUMN_INDEX']->value;?>
'))document.getElementById('gcon<?php echo $_smarty_tpl->tpl_vars['COLUMN_INDEX']->value;?>
').value = '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['column_condition'];?>
';</script><?php } ?></div><div style="width:100%;" id='quick_filter_div' name='quick_filter_div' class="paddingTop20"><div class="row"><div class="form-group"><label class="control-label textAlignLeft col-lg-12"><h4><?php echo vtranslate('LBL_QUICK_FILTER',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h4></label></div></div><div class="row well filterConditionContainer " id='quickfiltertable_0'><div class="form-group" id='quickfilter_0'><input type="hidden" name="quick_filters_save" id="quick_filters_save" value=""><select name="quick_filters" id="quick_filters" multiple class="select2 col-lg-10" ></select></div></div></div><script type="text/javascript">jQuery(document).ready(function () {addQuickFilterBox();});</script><?php }?><?php if ('Detail'!=$_smarty_tpl->tpl_vars['VIEW']->value){?></div><?php }?>
<?php }} ?>

View File

@@ -0,0 +1,60 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:06
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewPreProcess.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1460024140692477a64fd144-36946999%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'2eb99c07ae66dc414eb65f68f69ad309d1bccc60' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewPreProcess.tpl',
1 => 1711810494,
2 => 'file',
),
),
'nocache_hash' => '1460024140692477a64fd144-36946999',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
'CURRENT_USER_MODEL' => 0,
'LEFTPANELHIDE' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477a6535e2',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477a6535e2')) {function content_692477a6535e2($_smarty_tpl) {?>
<?php echo $_smarty_tpl->getSubTemplate ("modules/Vtiger/partials/Topbar.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<div class="container-fluid app-nav">
<div class="row">
<?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("partials/SidebarHeader.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ModuleHeader.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div>
</div>
</nav>
<div id='overlayPageContent' class='fade modal overlayPageContent content-area overlay-container-60' tabindex='-1' role='dialog' aria-hidden='true'>
<div class="data">
</div>
<div class="modal-dialog">
</div>
</div>
<div class="main-container main-container-<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
">
<?php $_smarty_tpl->tpl_vars['LEFTPANELHIDE'] = new Smarty_variable($_smarty_tpl->tpl_vars['CURRENT_USER_MODEL']->value->get('leftpanelhide'), null, 0);?>
<div id="modnavigator" class="module-nav">
<div class="hidden-xs hidden-sm mod-switcher-container">
</div>
</div>
<div id="sidebar-essentials" class="sidebar-essentials <?php if ($_smarty_tpl->tpl_vars['LEFTPANELHIDE']->value=='1'){?> hide <?php }?>">
<?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("partials/SidebarEssentials.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div>
<div class="listViewPageDiv content-area <?php if ($_smarty_tpl->tpl_vars['LEFTPANELHIDE']->value=='1'){?> full-width <?php }?>" id="listViewContent"><?php }} ?>

View File

@@ -0,0 +1,81 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:23
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ReportContents.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1782494867692477b7cbd261-18785334%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'31a3a7b4c69f4c31aa2e85b34477ebeb721b58dc' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ReportContents.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1782494867692477b7cbd261-18785334',
'function' =>
array (
),
'variables' =>
array (
'NEW_COUNT' => 0,
'DATE_FILTERS' => 0,
'REPORTTYPE' => 0,
'CALCULATION_FIELDS' => 0,
'MODULE' => 0,
'CALCULATION_FIELD' => 0,
'CALCULATION_FIELD_KEYS' => 0,
'ESCAPE_CHAR' => 0,
'FIELD_IMPLODE' => 0,
'FIELD_LABEL' => 0,
'MODULE_NAME' => 0,
'CALCULATION_VALUE' => 0,
'DATA' => 0,
'VALUES' => 0,
'VALUE' => 0,
'LIMIT_EXCEEDED' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477b7cd3e5',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477b7cd3e5')) {function content_692477b7cd3e5($_smarty_tpl) {?><?php if (!is_callable('smarty_modifier_replace')) include '/var/www/fastuser/data/www/crm.clientright.ru/libraries/Smarty/libs/plugins/modifier.replace.php';
?>
<input type="hidden" id="updatedCount" value="<?php echo $_smarty_tpl->tpl_vars['NEW_COUNT']->value;?>
" /><input type="hidden" name="date_filters" data-value='<?php echo ZEND_JSON::encode($_smarty_tpl->tpl_vars['DATE_FILTERS']->value);?>
' /><input type="hidden" name="report_filename" id="report_filename" value="" /><input type="hidden" name="export_pdf_format" id="export_pdf_format" value="" /><input type="hidden" name="pdf_file_name" id="pdf_file_name" value="" /><input type="hidden" name="ch_image_name" id="ch_image_name" value="" /><input type="hidden" name="date_filters" data-value='<?php echo Vtiger_Util_Helper::toSafeHTML(ZEND_JSON::encode($_smarty_tpl->tpl_vars['DATE_FILTERS']->value));?>
' /><input type="hidden" name="advft_criteria" id="advft_criteria" value='' /><input type="hidden" name="advft_criteria_groups" id="advft_criteria_groups" value='' /><input type="hidden" name="groupft_criteria" id="groupft_criteria" value='' /><input type="hidden" name="quick_filter_criteria" id="quick_filter_criteria" value="" /><input type="hidden" name='reload' id='reload' value='true'/><input type="hidden" name="currentMode" id="currentMode" value='generate' /><input type="hidden" name="reporttype" id="reporttype" value='<?php echo $_smarty_tpl->tpl_vars['REPORTTYPE']->value;?>
' /><div id="reports4you_html" style="width: 100%;"><?php if (!empty($_smarty_tpl->tpl_vars['CALCULATION_FIELDS']->value)){?><table class=" table-bordered table-condensed marginBottom10px" width="100%"><thead><tr class="blockHeader"><th><?php echo vtranslate('LBL_FIELD_NAMES',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th><th><?php echo vtranslate('LBL_SUM',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th><th><?php echo vtranslate('LBL_AVG',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th><th><?php echo vtranslate('LBL_MIN',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th><th><?php echo vtranslate('LBL_MAX',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th></tr></thead><?php $_smarty_tpl->tpl_vars['ESCAPE_CHAR'] = new Smarty_variable(array('_SUM','_AVG','_MIN','_MAX'), null, 0);?><?php $_smarty_tpl->tpl_vars['CALCULATION_FIELD'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['CALCULATION_FIELD']->_loop = false;
$_smarty_tpl->tpl_vars['index'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['CALCULATION_FIELDS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['CALCULATION_FIELD']->key => $_smarty_tpl->tpl_vars['CALCULATION_FIELD']->value){
$_smarty_tpl->tpl_vars['CALCULATION_FIELD']->_loop = true;
$_smarty_tpl->tpl_vars['index']->value = $_smarty_tpl->tpl_vars['CALCULATION_FIELD']->key;
?><tr><?php $_smarty_tpl->tpl_vars['CALCULATION_FIELD_KEYS'] = new Smarty_variable(array_keys($_smarty_tpl->tpl_vars['CALCULATION_FIELD']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['CALCULATION_FIELD_KEYS'] = new Smarty_variable(smarty_modifier_replace($_smarty_tpl->tpl_vars['CALCULATION_FIELD_KEYS']->value,$_smarty_tpl->tpl_vars['ESCAPE_CHAR']->value,''), null, 0);?><?php $_smarty_tpl->tpl_vars['FIELD_IMPLODE'] = new Smarty_variable(explode('_',$_smarty_tpl->tpl_vars['CALCULATION_FIELD_KEYS']->value['0']), null, 0);?><?php $_smarty_tpl->tpl_vars['MODULE_NAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['FIELD_IMPLODE']->value['0'], null, 0);?><?php $_smarty_tpl->tpl_vars['FIELD_LABEL'] = new Smarty_variable(implode(" ",$_smarty_tpl->tpl_vars['FIELD_IMPLODE']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['FIELD_LABEL'] = new Smarty_variable(smarty_modifier_replace($_smarty_tpl->tpl_vars['FIELD_LABEL']->value,$_smarty_tpl->tpl_vars['MODULE_NAME']->value,''), null, 0);?><td><?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE_NAME']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php echo vtranslate($_smarty_tpl->tpl_vars['FIELD_LABEL']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
</td><?php $_smarty_tpl->tpl_vars['CALCULATION_VALUE'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['CALCULATION_VALUE']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['CALCULATION_FIELD']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['CALCULATION_VALUE']->key => $_smarty_tpl->tpl_vars['CALCULATION_VALUE']->value){
$_smarty_tpl->tpl_vars['CALCULATION_VALUE']->_loop = true;
?><td width="15%"><?php echo $_smarty_tpl->tpl_vars['CALCULATION_VALUE']->value;?>
</td><?php } ?></tr><?php } ?></table><?php }?><?php if ($_smarty_tpl->tpl_vars['DATA']->value!=''){?><?php $_smarty_tpl->tpl_vars['HEADERS'] = new Smarty_variable($_smarty_tpl->tpl_vars['DATA']->value[0], null, 0);?><?php $_smarty_tpl->tpl_vars['VALUES'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['VALUES']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['DATA']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['VALUES']->key => $_smarty_tpl->tpl_vars['VALUES']->value){
$_smarty_tpl->tpl_vars['VALUES']->_loop = true;
?><?php $_smarty_tpl->tpl_vars['VALUE'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['VALUE']->_loop = false;
$_smarty_tpl->tpl_vars['NAME'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['VALUES']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['VALUE']->key => $_smarty_tpl->tpl_vars['VALUE']->value){
$_smarty_tpl->tpl_vars['VALUE']->_loop = true;
$_smarty_tpl->tpl_vars['NAME']->value = $_smarty_tpl->tpl_vars['VALUE']->key;
?><span style="background-color:white;"><?php echo $_smarty_tpl->tpl_vars['VALUE']->value;?>
</span><?php } ?><?php } ?><?php if ($_smarty_tpl->tpl_vars['LIMIT_EXCEEDED']->value){?><center><?php echo vtranslate('LBL_LIMIT_EXCEEDED',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<span class="pull-right"><a href="#top" ><?php echo vtranslate('LBL_TOP',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></span></center><?php }?><?php }else{ ?><?php echo vtranslate('LBL_NO_DATA_AVAILABLE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?></div></div></form><div class="no-print">
<?php }} ?>

View File

@@ -0,0 +1,36 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:14
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ListViewPreProcess.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1732611834692477aeab7798-74083737%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'360fc795e14e13a071b098fb502a6472dc052979' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ListViewPreProcess.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1732611834692477aeab7798-74083737',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
'CURRENT_USER_MODEL' => 0,
'LEFTPANELHIDE' => 0,
'NO_LICENSE' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477aeac194',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477aeac194')) {function content_692477aeac194($_smarty_tpl) {?>
<?php echo $_smarty_tpl->getSubTemplate ("modules/Vtiger/partials/Topbar.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<div class="container-fluid app-nav"><div class="row"><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("partials/SidebarHeader.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ModuleHeader.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div></div></nav><div id='overlayPageContent' class='fade modal overlayPageContent content-area overlay-container-60' tabindex='-1' role='dialog' aria-hidden='true'><div class="data"></div><div class="modal-dialog"></div></div><div class="main-container main-container-<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
"><?php $_smarty_tpl->tpl_vars['LEFTPANELHIDE'] = new Smarty_variable($_smarty_tpl->tpl_vars['CURRENT_USER_MODEL']->value->get('leftpanelhide'), null, 0);?><div id="modnavigator" class="module-nav"><div class="hidden-xs hidden-sm mod-switcher-container"><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("partials/Menubar.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div></div><div id="sidebar-essentials" class="sidebar-essentials <?php if ($_smarty_tpl->tpl_vars['LEFTPANELHIDE']->value=='1'){?> hide <?php }?>"><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("partials/SidebarEssentials.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div><div class="listViewPageDiv <?php if (0==$_smarty_tpl->tpl_vars['NO_LICENSE']->value){?>content-area<?php }?> <?php if ($_smarty_tpl->tpl_vars['LEFTPANELHIDE']->value=='1'){?> full-width <?php }?>" id="listViewContent"><?php }} ?>

View File

@@ -0,0 +1,142 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-26 11:31:04
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Products/MoreCurrenciesList.tpl" */ ?>
<?php /*%%SmartyHeaderCode:8912771816926bac84de2c5-62307678%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'3ad3f9fdfca9e31643826093b780e2802f5dde65' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Products/MoreCurrenciesList.tpl',
1 => 1711810494,
2 => 'file',
),
),
'nocache_hash' => '8912771816926bac84de2c5-62307678',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
'TITLE' => 0,
'PRICE_DETAILS' => 0,
'price' => 0,
'check_value' => 0,
'disable_value' => 0,
'USER_MODEL' => 0,
'base_cur_check' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_6926bac8525f1',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_6926bac8525f1')) {function content_6926bac8525f1($_smarty_tpl) {?>
<div id="currency_class" class="multiCurrencyEditUI modelContainer">
<div class = "modal-dialog modal-lg">
<div class = "modal-content">
<?php ob_start();?><?php echo vtranslate('LBL_PRICES',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php $_tmp1=ob_get_clean();?><?php $_smarty_tpl->tpl_vars['TITLE'] = new Smarty_variable($_tmp1, null, 0);?>
<?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ModalHeader.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array('TITLE'=>$_smarty_tpl->tpl_vars['TITLE']->value), 0);?>
<div class="multiCurrencyContainer">
<div class = "currencyContent">
<div class = "modal-body">
<table width="100%" border="0" cellpadding="5" cellspacing="0" class="table listViewEntriesTable">
<thead class="detailedViewHeader">
<th><?php echo vtranslate('LBL_CURRENCY',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th>
<th><?php echo vtranslate('LBL_PRICE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th>
<th><?php echo vtranslate('LBL_CONVERSION_RATE','Products');?>
</th>
<th><?php echo vtranslate('LBL_RESET_PRICE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th>
<th><?php echo vtranslate('LBL_BASE_CURRENCY',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</th>
</thead>
<?php $_smarty_tpl->tpl_vars['price'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['price']->_loop = false;
$_smarty_tpl->tpl_vars['count'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['PRICE_DETAILS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['price']->key => $_smarty_tpl->tpl_vars['price']->value){
$_smarty_tpl->tpl_vars['price']->_loop = true;
$_smarty_tpl->tpl_vars['count']->value = $_smarty_tpl->tpl_vars['price']->key;
?>
<tr data-currency-id=<?php echo $_smarty_tpl->tpl_vars['price']->value['curname'];?>
>
<?php if ($_smarty_tpl->tpl_vars['price']->value['check_value']==1||$_smarty_tpl->tpl_vars['price']->value['is_basecurrency']==1){?>
<?php $_smarty_tpl->tpl_vars['check_value'] = new Smarty_variable("checked", null, 0);?>
<?php $_smarty_tpl->tpl_vars['disable_value'] = new Smarty_variable('', null, 0);?>
<?php }else{ ?>
<?php $_smarty_tpl->tpl_vars['check_value'] = new Smarty_variable('', null, 0);?>
<?php $_smarty_tpl->tpl_vars['disable_value'] = new Smarty_variable("disabled=true", null, 0);?>
<?php }?>
<?php if ($_smarty_tpl->tpl_vars['price']->value['is_basecurrency']==1){?>
<?php $_smarty_tpl->tpl_vars['base_cur_check'] = new Smarty_variable("checked", null, 0);?>
<?php }else{ ?>
<?php $_smarty_tpl->tpl_vars['base_cur_check'] = new Smarty_variable('', null, 0);?>
<?php }?>
<td>
<div class="row col-lg-12">
<div class="col-lg-10 currencyInfo" style = "padding-left:5px">
<span class="pull-left currencyName" ><?php echo getTranslatedCurrencyString($_smarty_tpl->tpl_vars['price']->value['currencylabel']);?>
(<span class='currencySymbol'><?php echo $_smarty_tpl->tpl_vars['price']->value['currencysymbol'];?>
</span>)</span>
</div>
<div class="col-lg-2">
<span><input type="checkbox" name="cur_<?php echo $_smarty_tpl->tpl_vars['price']->value['curid'];?>
_check" id="cur_<?php echo $_smarty_tpl->tpl_vars['price']->value['curid'];?>
_check" class="pull-right enableCurrency" <?php echo $_smarty_tpl->tpl_vars['check_value']->value;?>
></span>
</div>
</div>
</td>
<td>
<div>
<input <?php echo $_smarty_tpl->tpl_vars['disable_value']->value;?>
type="text" size="10" class="col-lg-9 form-control convertedPrice" data-rule-currency ="true" name="<?php echo $_smarty_tpl->tpl_vars['price']->value['curname'];?>
" id="<?php echo $_smarty_tpl->tpl_vars['price']->value['curname'];?>
" value="<?php echo $_smarty_tpl->tpl_vars['price']->value['curvalue'];?>
" data-decimal-separator='<?php echo $_smarty_tpl->tpl_vars['USER_MODEL']->value->get('currency_decimal_separator');?>
' data-group-separator='<?php echo $_smarty_tpl->tpl_vars['USER_MODEL']->value->get('currency_grouping_separator');?>
' />
</div>
</td>
<td>
<div>
<input readonly="" type="text" size="10" class="col-lg-9 form-control conversionRate" name="cur_conv_rate<?php echo $_smarty_tpl->tpl_vars['price']->value['curid'];?>
" value="<?php echo $_smarty_tpl->tpl_vars['price']->value['conversionrate'];?>
">
</div>
</td>
<td>
<div class = "textAlignCenter">
<button <?php echo $_smarty_tpl->tpl_vars['disable_value']->value;?>
type="button" class="btn btn-default currencyReset" id="cur_reset<?php echo $_smarty_tpl->tpl_vars['price']->value['curid'];?>
" value="<?php echo vtranslate('LBL_RESET',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"><i class = "fa fa-refresh"></i>&nbsp;&nbsp;<?php echo vtranslate('LBL_RESET',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button>
</div>
</td>
<td>
<div class="textAlignCenter">
<input <?php echo $_smarty_tpl->tpl_vars['disable_value']->value;?>
style = "vertical-align:middle" type="radio" class="baseCurrency" id="base_currency<?php echo $_smarty_tpl->tpl_vars['price']->value['curid'];?>
" name="base_currency_input" value="<?php echo $_smarty_tpl->tpl_vars['price']->value['curname'];?>
" <?php echo $_smarty_tpl->tpl_vars['base_cur_check']->value;?>
/>
</div>
</td>
</tr>
<?php } ?>
</table>
</div>
</div>
<?php echo $_smarty_tpl->getSubTemplate (vtemplate_path('ModalFooter.tpl',$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div>
</div>
</div>
</div><?php }} ?>

View File

@@ -0,0 +1,164 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:06
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewContents.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1148052082692477a65f8b85-18822179%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'3c98f6b3d313a8b82b05eb7bcd33de4bd16354a4' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewContents.tpl',
1 => 1711810495,
2 => 'file',
),
),
'nocache_hash' => '1148052082692477a65f8b85-18822179',
'function' =>
array (
),
'variables' =>
array (
'CURRENT_USER_MODEL' => 0,
'LEFTPANELHIDE' => 0,
'VIEW' => 0,
'VIEWID' => 0,
'PAGING_MODEL' => 0,
'OPERATOR' => 0,
'LISTVIEW_COUNT' => 0,
'PAGE_NUMBER' => 0,
'LISTVIEW_ENTRIES_COUNT' => 0,
'SEARCH_DETAILS' => 0,
'NO_SEARCH_PARAMS_CACHE' => 0,
'ORDER_BY' => 0,
'SORT_ORDER' => 0,
'LIST_HEADER_FIELDS' => 0,
'CURRENT_TAG' => 0,
'FOLDER_ID' => 0,
'FOLDER_VALUE' => 0,
'VIEWNAME' => 0,
'SEARCH_MODE_RESULTS' => 0,
'MODULE' => 0,
'LISTVIEW_MODEL' => 0,
'LISTVIEW_HEADERS' => 0,
'COLUMN_NAME' => 0,
'LISTVIEW_HEADER_KEY' => 0,
'NEXT_SORT_ORDER' => 0,
'FASORT_IMAGE' => 0,
'MODULE_MODEL' => 0,
'LISTVIEW_HEADER' => 0,
'DATA_TYPE' => 0,
'FIELD_INFO' => 0,
'PICKLIST_VALUES' => 0,
'PICKLIST_LABEL' => 0,
'PICKLIST_KEY' => 0,
'SEARCH_VALUES' => 0,
'ICON_CLASS' => 0,
'LISTVIEW_ENTRIES' => 0,
'LISTVIEW_ENTRY' => 0,
'LISTVIEW_HEADERNAME' => 0,
'LISTVIEW_ENTRY_RAWVALUE' => 0,
'LISTVIEW_ENTRY_VALUE' => 0,
'COLSPAN_WIDTH' => 0,
'IS_MODULE_EDITABLE' => 0,
'LIST_VIEW_MODEL' => 0,
'SINGLE_MODULE' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477a662cc5',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477a662cc5')) {function content_692477a662cc5($_smarty_tpl) {?>
<div class="col-sm-12 col-xs-12 "><?php $_smarty_tpl->tpl_vars['LEFTPANELHIDE'] = new Smarty_variable($_smarty_tpl->tpl_vars['CURRENT_USER_MODEL']->value->get('leftpanelhide'), null, 0);?><div class="essentials-toggle" title="<?php echo vtranslate('LBL_LEFT_PANEL_SHOW_HIDE','Vtiger');?>
"><span class="essentials-toggle-marker fa <?php if ($_smarty_tpl->tpl_vars['LEFTPANELHIDE']->value=='1'){?>fa-chevron-right<?php }else{ ?>fa-chevron-left<?php }?> cursorPointer"></span></div><input type="hidden" name="view" id="view" value="<?php echo $_smarty_tpl->tpl_vars['VIEW']->value;?>
" /><input type="hidden" name="cvid" value="<?php echo $_smarty_tpl->tpl_vars['VIEWID']->value;?>
" /><input type="hidden" name="pageStartRange" id="pageStartRange" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->getRecordStartRange();?>
" /><input type="hidden" name="pageEndRange" id="pageEndRange" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->getRecordEndRange();?>
" /><input type="hidden" name="previousPageExist" id="previousPageExist" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->isPrevPageExists();?>
" /><input type="hidden" name="nextPageExist" id="nextPageExist" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->isNextPageExists();?>
" /><input type="hidden" name="Operator" id="Operator" value="<?php echo $_smarty_tpl->tpl_vars['OPERATOR']->value;?>
" /><input type="hidden" name="totalCount" id="totalCount" value="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_COUNT']->value;?>
" /><input type='hidden' name="pageNumber" value="<?php echo $_smarty_tpl->tpl_vars['PAGE_NUMBER']->value;?>
" id='pageNumber'><input type='hidden' name="pageLimit" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->getPageLimit();?>
" id='pageLimit'><input type="hidden" name="noOfEntries" value="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES_COUNT']->value;?>
" id="noOfEntries"><input type="hidden" name="currentSearchParams" value="<?php echo Vtiger_Util_Helper::toSafeHTML(Zend_JSON::encode($_smarty_tpl->tpl_vars['SEARCH_DETAILS']->value));?>
" id="currentSearchParams" /><input type="hidden" name="noFilterCache" value="<?php echo $_smarty_tpl->tpl_vars['NO_SEARCH_PARAMS_CACHE']->value;?>
" id="noFilterCache" ><input type="hidden" name="orderBy" value="<?php echo $_smarty_tpl->tpl_vars['ORDER_BY']->value;?>
" id="orderBy"><input type="hidden" name="sortOrder" value="<?php echo $_smarty_tpl->tpl_vars['SORT_ORDER']->value;?>
" id="sortOrder"><input type="hidden" name="list_headers" value='<?php echo $_smarty_tpl->tpl_vars['LIST_HEADER_FIELDS']->value;?>
'/><input type="hidden" name="tag" value="<?php echo $_smarty_tpl->tpl_vars['CURRENT_TAG']->value;?>
" /><input type="hidden" name="folder_id" value="<?php echo $_smarty_tpl->tpl_vars['FOLDER_ID']->value;?>
" /><input type="hidden" name="folder_value" value="<?php echo $_smarty_tpl->tpl_vars['FOLDER_VALUE']->value;?>
" /><input type="hidden" name="folder" value="<?php echo $_smarty_tpl->tpl_vars['VIEWNAME']->value;?>
" /><?php if (!$_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ListViewActions.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php }?><div id="table-content" class="table-container"><form name='list' id='listedit' action='' onsubmit="return false;"><table id="listview-table" class="table <?php if ($_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES_COUNT']->value=='0'){?>listview-table-norecords <?php }?> listview-table"><thead><tr class="listViewContentHeader"><th><?php if (!$_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><div class="table-actions"><div class="dropdown" style="float:left;margin-left:6px;"><span class="input dropdown-toggle" title="<?php echo vtranslate('LBL_CLICK_HERE_TO_SELECT_ALL_RECORDS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" data-toggle="dropdown"><input class="listViewEntriesMainCheckBox" type="checkbox"></span></div></div><?php }elseif($_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><?php echo vtranslate('LBL_ACTIONS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?></th><?php ob_start();?><?php echo $_smarty_tpl->tpl_vars['VIEWNAME']->value;?>
<?php $_tmp1=ob_get_clean();?><?php $_smarty_tpl->tpl_vars["LISTVIEW_HEADERS"] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_MODEL']->value->getListViewHeadersForVtiger7($_tmp1), null, 0);?><?php $_smarty_tpl->tpl_vars['LISTVIEW_HEADER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = false;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key => $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = true;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value = $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key;
?><th <?php if ($_smarty_tpl->tpl_vars['COLUMN_NAME']->value==$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value){?> nowrap="nowrap" <?php }?>><a href="#" class="listViewContentHeaderValues" data-nextsortorderval="<?php if ($_smarty_tpl->tpl_vars['COLUMN_NAME']->value==$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value){?><?php echo $_smarty_tpl->tpl_vars['NEXT_SORT_ORDER']->value;?>
<?php }else{ ?>ASC<?php }?>" data-columnname="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value;?>
"><?php if ($_smarty_tpl->tpl_vars['COLUMN_NAME']->value==$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value){?><i class="fa fa-sort <?php echo $_smarty_tpl->tpl_vars['FASORT_IMAGE']->value;?>
"></i><?php }else{ ?><i class="fa fa-sort customsort"></i><?php }?>&nbsp;<?php echo vtranslate($_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value[$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value]['label'],$_smarty_tpl->tpl_vars['MODULE']->value);?>
&nbsp;</a><?php if ($_smarty_tpl->tpl_vars['COLUMN_NAME']->value==$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value){?><a href="#" class="removeSorting"><i class="fa fa-remove"></i></a><?php }?></th><?php } ?></tr><?php if ($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->isQuickSearchEnabled()&&!$_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><tr class="searchRow"><th class="inline-search-btn"><div class="table-actions"><button class="btn btn-success btn-sm" data-trigger="listSearch"><?php echo vtranslate("LBL_SEARCH",$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button></div></th><?php $_smarty_tpl->tpl_vars['LISTVIEW_HEADER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = false;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key => $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = true;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value = $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key;
?><th><?php $_smarty_tpl->tpl_vars["DATA_TYPE"] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value['type'], null, 0);?><?php if ($_smarty_tpl->tpl_vars['DATA_TYPE']->value=='string'){?><div class="row-fluid"><input type="text" name="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value;?>
" class="listSearchContributor inputElement" value="<?php echo $_smarty_tpl->tpl_vars['SEARCH_DETAILS']->value[$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value]['searchValue'];?>
" data-fieldinfo='<?php echo htmlspecialchars($_smarty_tpl->tpl_vars['FIELD_INFO']->value, ENT_QUOTES, 'UTF-8', true);?>
'/></div><?php }elseif($_smarty_tpl->tpl_vars['DATA_TYPE']->value=='picklist'){?><?php $_smarty_tpl->tpl_vars['PICKLIST_VALUES'] = new Smarty_variable(Reports_Field_Model::getPicklistValueByField($_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['SEARCH_VALUES'] = new Smarty_variable(explode(',',$_smarty_tpl->tpl_vars['SEARCH_DETAILS']->value[$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value]['searchValue']), null, 0);?><div class="row-fluid"><select class="select2 listSearchContributor report-type-select" name="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value;?>
" multiple data-fieldinfo='<?php echo htmlspecialchars($_smarty_tpl->tpl_vars['FIELD_INFO']->value, ENT_QUOTES, 'UTF-8', true);?>
'><?php $_smarty_tpl->tpl_vars['PICKLIST_LABEL'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->_loop = false;
$_smarty_tpl->tpl_vars['PICKLIST_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['PICKLIST_VALUES']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->key => $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value){
$_smarty_tpl->tpl_vars['PICKLIST_LABEL']->_loop = true;
$_smarty_tpl->tpl_vars['PICKLIST_KEY']->value = $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->key;
?><?php if ($_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value=='Chart'){?><?php $_smarty_tpl->tpl_vars["ICON_CLASS"] = new Smarty_variable('fa fa-pie-chart', null, 0);?><?php }elseif($_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value=='Detail'){?><?php $_smarty_tpl->tpl_vars["ICON_CLASS"] = new Smarty_variable('vicon-detailreport', null, 0);?><?php }?><option value="<?php echo $_smarty_tpl->tpl_vars['PICKLIST_KEY']->value;?>
" <?php if (in_array($_smarty_tpl->tpl_vars['PICKLIST_KEY']->value,$_smarty_tpl->tpl_vars['SEARCH_VALUES']->value)&&($_smarty_tpl->tpl_vars['PICKLIST_KEY']->value!='')){?> selected<?php }?> <?php if ($_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value=='reporttype'){?>class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
'<?php }?>><?php echo $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value;?>
</option><?php } ?></select></div><?php }?><input type="hidden" class="operatorValue" value="<?php echo $_smarty_tpl->tpl_vars['SEARCH_DETAILS']->value[$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value]['comparator'];?>
"></th><?php } ?></tr><?php }?></thead><tbody class="overflow-y"><?php $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
$_smarty_tpl->tpl_vars['smarty']->value['foreach']['listview']['index']=-1;
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->key => $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->_loop = true;
$_smarty_tpl->tpl_vars['smarty']->value['foreach']['listview']['index']++;
?><tr class="listViewEntries" data-id='<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
' data-recordUrl='<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getDetailViewUrl();?>
' id="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_row_<?php echo $_smarty_tpl->getVariable('smarty')->value['foreach']['listview']['index']+1;?>
"><td class = "listViewRecordActions"><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ListViewRecordActions.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</td><?php $_smarty_tpl->tpl_vars['LISTVIEW_HEADER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = false;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key => $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = true;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value = $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key;
?><?php $_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value, null, 0);?><?php $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_RAWVALUE'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getRaw($_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->get($_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value), null, 0);?><td class="listViewEntryValue" data-name="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value;?>
" title="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_RAWVALUE']->value;?>
" data-rawvalue="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_RAWVALUE']->value;?>
" data-field-type=""><span class="fieldValue"><span class="value textOverflowEllipsis"><?php if ($_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value=='reporttype'){?><?php if ($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value=='summary'||$_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value=='tabular'){?><center title="<?php echo vtranslate('LBL_DETAIL_REPORT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"><span class='vicon-detailreport' style="font-size:17px;"></span></center><?php }elseif($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value=='chart'){?><center title="<?php echo vtranslate('LBL_CHART_REPORT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"><span class='fa fa-pie-chart fa-2x' style="font-size:1.7em;"></span></center><?php }?><?php }elseif($_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value=='primarymodule'){?><?php echo Vtiger_Util_Helper::tosafeHTML(decode_html(vtranslate($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value,$_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value)));?>
<?php }elseif($_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value=='foldername'){?><?php echo Vtiger_Util_Helper::tosafeHTML(vtranslate($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value,$_smarty_tpl->tpl_vars['MODULE']->value));?>
<?php }else{ ?><?php echo Vtiger_Util_Helper::tosafeHTML($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value);?>
<?php }?></span></span></span></td><?php } ?></tr><?php } ?><?php if ($_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES_COUNT']->value=='0'){?><tr class="emptyRecordsDiv"><?php ob_start();?><?php echo count($_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value);?>
<?php $_tmp2=ob_get_clean();?><?php $_smarty_tpl->tpl_vars['COLSPAN_WIDTH'] = new Smarty_variable($_tmp2+1, null, 0);?><td colspan="<?php echo $_smarty_tpl->tpl_vars['COLSPAN_WIDTH']->value;?>
"><div class="emptyRecordsDiv"><div class="emptyRecordsContent"><?php $_smarty_tpl->tpl_vars['SINGLE_MODULE'] = new Smarty_variable("SINGLE_".($_smarty_tpl->tpl_vars['MODULE']->value), null, 0);?><?php echo vtranslate('LBL_NO');?>
<?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php echo vtranslate('LBL_FOUND');?>
.<?php if ($_smarty_tpl->tpl_vars['IS_MODULE_EDITABLE']->value){?> <a href="<?php echo $_smarty_tpl->tpl_vars['MODULE_MODEL']->value->getCreateRecordUrl();?>
"> <?php echo vtranslate('LBL_CREATE');?>
</a> <?php if (Users_Privileges_Model::isPermitted($_smarty_tpl->tpl_vars['MODULE']->value,'Import')&&$_smarty_tpl->tpl_vars['LIST_VIEW_MODEL']->value->isImportEnabled()){?> <?php echo vtranslate('LBL_OR',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<a style="color:blue" href="#" onclick="return Vtiger_Import_Js.triggerImportAction()"> <?php echo vtranslate('LBL_IMPORT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a><?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }else{ ?><?php echo vtranslate($_smarty_tpl->tpl_vars['SINGLE_MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?><?php }?></div></div></td></tr><?php }?></tbody></table></form></div><div id="scroller_wrapper" class="bottom-fixed-scroll"><div id="scroller" class="scroller-div"></div></div></div><?php }} ?>

View File

@@ -0,0 +1,54 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:14
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ListViewRecordActions.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1541815961692477aebe2c22-49358808%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'4430d7df5d1ac99e15a492ff3f5f7ca89e8e9419' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ListViewRecordActions.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1541815961692477aebe2c22-49358808',
'function' =>
array (
),
'variables' =>
array (
'SEARCH_MODE_RESULTS' => 0,
'LISTVIEW_ENTRY' => 0,
'QUICK_PREVIEW_ENABLED' => 0,
'SELECTED_MENU_CATEGORY' => 0,
'MODULE' => 0,
'MODULE_MODEL' => 0,
'STARRED' => 0,
'RECORD_ACTIONS' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477aebf22c',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477aebf22c')) {function content_692477aebf22c($_smarty_tpl) {?>
<!--LIST VIEW RECORD ACTIONS--><div class="table-actions"><?php if (!$_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><span class="input" ><input type="checkbox" value="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
" class="listViewEntriesCheckBox"/></span><?php }?><?php if ($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->get('starred')=='Yes'){?><?php $_smarty_tpl->tpl_vars['STARRED'] = new Smarty_variable(true, null, 0);?><?php }else{ ?><?php $_smarty_tpl->tpl_vars['STARRED'] = new Smarty_variable(false, null, 0);?><?php }?><?php if ($_smarty_tpl->tpl_vars['QUICK_PREVIEW_ENABLED']->value=='true'){?><span><a class="quickView fa fa-eye icon action" data-app="<?php echo $_smarty_tpl->tpl_vars['SELECTED_MENU_CATEGORY']->value;?>
" title="<?php echo vtranslate('LBL_QUICK_VIEW',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"></a></span><?php }?><?php if ($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->isStarredEnabled()){?><span><a class="markStar fa icon action <?php if ($_smarty_tpl->tpl_vars['STARRED']->value){?> fa-star active <?php }else{ ?> fa-star-o<?php }?>" title="<?php if ($_smarty_tpl->tpl_vars['STARRED']->value){?> <?php echo vtranslate('LBL_STARRED',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }else{ ?> <?php echo vtranslate('LBL_NOT_STARRED',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?>"></a></span><?php }?><span class="more dropdown action"><span href="javascript:;" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v icon"></i></span><ul class="dropdown-menu"><li><a data-id="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
" href="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getFullDetailViewUrl();?>
&app=<?php echo $_smarty_tpl->tpl_vars['SELECTED_MENU_CATEGORY']->value;?>
"><?php echo vtranslate('LBL_DETAILS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php if ($_smarty_tpl->tpl_vars['RECORD_ACTIONS']->value){?><?php if ($_smarty_tpl->tpl_vars['RECORD_ACTIONS']->value['edit']){?><li><a data-id="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
" href="javascript:void(0);" data-url="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getEditViewUrl();?>
&app=<?php echo $_smarty_tpl->tpl_vars['SELECTED_MENU_CATEGORY']->value;?>
" name="editlink"><?php echo vtranslate('LBL_EDIT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php }?><?php if ($_smarty_tpl->tpl_vars['RECORD_ACTIONS']->value['duplicate']){?><li><a data-id="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
" href="javascript:void(0);" data-url="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getEditViewUrl();?>
&isDuplicate=true&app=<?php echo $_smarty_tpl->tpl_vars['SELECTED_MENU_CATEGORY']->value;?>
" name="editlink"><?php echo vtranslate('LBL_DUPLICATE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php }?><?php if ($_smarty_tpl->tpl_vars['RECORD_ACTIONS']->value['delete']){?><li><a data-id="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
" href="javascript:void(0);" class="deleteRecordButton"><?php echo vtranslate('LBL_DELETE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php }?><?php }?></ul></span><div class="btn-group inline-save hide"><button class="button btn-success btn-small save" type="button" name="save"><i class="fa fa-check"></i></button><button class="button btn-danger btn-small cancel" type="button" name="Cancel"><i class="fa fa-close"></i></button></div></div>
<?php }} ?>

View File

@@ -0,0 +1,201 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:23
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/FiltersCriteria.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1046647003692477b76479f4-96758090%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'4b187bb8283c39a94fc1145fe0286765c9e20728' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/FiltersCriteria.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1046647003692477b76479f4-96758090',
'function' =>
array (
),
'variables' =>
array (
'std_filter_columns' => 0,
'std_filter_criteria' => 0,
'SEL_FIELDS' => 0,
'BLOCKJS_STD' => 0,
'REL_FIELDS' => 0,
'DISPLAY_FILTER_HEADER' => 0,
'MODULE' => 0,
'CRITERIA_GROUPS' => 0,
'GROUP_CRITERIA' => 0,
'GROUP_COLUMNS' => 0,
'GROUP_ID' => 0,
'COLUMN_CRITERIA' => 0,
'FCON_I' => 0,
'COLUMN_INDEX' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477b7656b3',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477b7656b3')) {function content_692477b7656b3($_smarty_tpl) {?>
<script language="JAVASCRIPT" type="text/javascript" src="layouts/v7/modules/ITS4YouReports/resources/ITS4YouReports.js"></script>
<input type="hidden" name="std_filter_columns" id="std_filter_columns" value='<?php echo $_smarty_tpl->tpl_vars['std_filter_columns']->value;?>
' />
<div id="std_filter_criteria" class="hide" ><?php echo $_smarty_tpl->tpl_vars['std_filter_criteria']->value;?>
</div>
<input type="hidden" name="sel_fields" id="sel_fields" value='<?php echo $_smarty_tpl->tpl_vars['SEL_FIELDS']->value;?>
' />
<?php echo $_smarty_tpl->tpl_vars['BLOCKJS_STD']->value;?>
<script type="text/javascript">
var advft_column_index_count = -1;
var advft_group_index_count = 0;
var column_index_array = [];
var group_index_array = [];
var gf_advft_column_index_count = -1;
var gf_advft_group_index_count = 0;
var gf_column_index_array = [];
var gf_group_index_array = [];
var rel_fields = '<?php echo $_smarty_tpl->tpl_vars['REL_FIELDS']->value;?>
';
</script>
<table border=0 cellspacing=0 cellpadding=0 width="100%">
<?php if ($_smarty_tpl->tpl_vars['DISPLAY_FILTER_HEADER']->value===true){?>
<tr>
<td class="detailedViewHeader" nowrap align="left" colspan="8">
<div style="float:left;min-height: 2.3em;vertical-align: middle;padding-top:0.3em;">
<span class="genHeaderGray" style=""><?php echo vtranslate('LBL_ADVANCED_FILTER',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</span> &nbsp;
</div>
</td>
</tr>
<?php }?>
<tr>
<td class="dvtCellLabel" nowrap align="center" style="padding:0px;" colspan="8" >
<div style="display:block" id='adv_filter_div' name='adv_filter_div'>
<table class="small" border="0" cellpadding="0" cellspacing="0" width="100%">
</table>
<?php $_smarty_tpl->tpl_vars['FCON_I'] = new Smarty_variable("0", null, 0);?>
<script type="text/javascript">var window_onload = "";</script>
<?php $_smarty_tpl->tpl_vars['GROUP_CRITERIA'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->_loop = false;
$_smarty_tpl->tpl_vars['GROUP_ID'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['CRITERIA_GROUPS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->key => $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->value){
$_smarty_tpl->tpl_vars['GROUP_CRITERIA']->_loop = true;
$_smarty_tpl->tpl_vars['GROUP_ID']->value = $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->key;
?>
<?php $_smarty_tpl->tpl_vars['GROUP_COLUMNS'] = new Smarty_variable($_smarty_tpl->tpl_vars['GROUP_CRITERIA']->value['columns'], null, 0);?>
<script type="text/javascript">
window_onload += addConditionGroup('adv_filter_div');
</script>
<?php $_smarty_tpl->tpl_vars['COLUMN_CRITERIA'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->_loop = false;
$_smarty_tpl->tpl_vars['COLUMN_INDEX'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['GROUP_COLUMNS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->key => $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value){
$_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->_loop = true;
$_smarty_tpl->tpl_vars['COLUMN_INDEX']->value = $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->key;
?>
<script type="text/javascript">
window_onload +=
addConditionRow('<?php echo $_smarty_tpl->tpl_vars['GROUP_ID']->value;?>
');
document.getElementById('fop' + advft_column_index_count).value = '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['comparator'];?>
';
var conditionColumnRowElement = document.getElementById('fcol' + advft_column_index_count);
setSelectedCriteriaValue(conditionColumnRowElement,'<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['columnname'];?>
');
reports4you_updatefOptions(conditionColumnRowElement, 'fop' + advft_column_index_count, '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['comparator'];?>
');
addRequiredElements('f', advft_column_index_count);
updateRelFieldOptions(conditionColumnRowElement, 'fval_' + advft_column_index_count);
var columnvalue = '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['value'];?>
';
if ('<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['comparator'];?>
' == 'bw' && columnvalue != '') {
var values = columnvalue.split(",");
document.getElementById('fval' + advft_column_index_count).value = values[0];
if (values.length == 2 && document.getElementById('fval_ext' + advft_column_index_count))
document.getElementById('fval_ext' + advft_column_index_count).value = values[1];
} else {
document.getElementById('fval' + advft_column_index_count).value = columnvalue;
}
<?php if ($_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['value_hdn']!=''){?>
document.getElementById('fvalhdn' + advft_column_index_count).value = '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['value_hdn'];?>
';
jQuery('#fval'+ advft_column_index_count).attr("readonly","true");
<?php }?>
</script>
<?php if ($_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['column_condition']!=''){?>
<input type="hidden" name="hfcon_<?php echo $_smarty_tpl->tpl_vars['GROUP_ID']->value;?>
_<?php echo $_smarty_tpl->tpl_vars['FCON_I']->value;?>
" id="hfcon_<?php echo $_smarty_tpl->tpl_vars['GROUP_ID']->value;?>
_<?php echo $_smarty_tpl->tpl_vars['FCON_I']->value;?>
" value='<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['column_condition'];?>
' />
<?php }?>
<?php $_smarty_tpl->tpl_vars['FCON_I'] = new Smarty_variable($_smarty_tpl->tpl_vars['FCON_I']->value+1, null, 0);?>
<?php } ?>
<?php $_smarty_tpl->tpl_vars['COLUMN_CRITERIA'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->_loop = false;
$_smarty_tpl->tpl_vars['COLUMN_INDEX'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['GROUP_COLUMNS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->key => $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value){
$_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->_loop = true;
$_smarty_tpl->tpl_vars['COLUMN_INDEX']->value = $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->key;
?>
<script type="text/javascript">
if (document.getElementById('fcon<?php echo $_smarty_tpl->tpl_vars['COLUMN_INDEX']->value;?>
'))
document.getElementById('fcon<?php echo $_smarty_tpl->tpl_vars['COLUMN_INDEX']->value;?>
').value = '<?php echo $_smarty_tpl->tpl_vars['COLUMN_CRITERIA']->value['column_condition'];?>
';
</script>
<?php } ?>
<?php }
if (!$_smarty_tpl->tpl_vars['GROUP_CRITERIA']->_loop) {
?>
<?php } ?>
<?php $_smarty_tpl->tpl_vars['GROUP_CRITERIA'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->_loop = false;
$_smarty_tpl->tpl_vars['GROUP_ID'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['CRITERIA_GROUPS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->key => $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->value){
$_smarty_tpl->tpl_vars['GROUP_CRITERIA']->_loop = true;
$_smarty_tpl->tpl_vars['GROUP_ID']->value = $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->key;
?>
<script type="text/javascript">
if (document.getElementById('gpcon<?php echo $_smarty_tpl->tpl_vars['GROUP_ID']->value;?>
'))
document.getElementById('gpcon<?php echo $_smarty_tpl->tpl_vars['GROUP_ID']->value;?>
').value = '<?php echo $_smarty_tpl->tpl_vars['GROUP_CRITERIA']->value['condition'];?>
';
</script>
<?php } ?>
</div>
<?php if ($_smarty_tpl->tpl_vars['DISPLAY_FILTER_HEADER']->value==true){?>
<div class="addCondition" style='float:left;'>
<button type='button' class='btn btn-default' style='float:left;' onclick="addNewConditionGroup('adv_filter_div')"><i class="fa fa-plus"></i>&nbsp;<?php echo vtranslate('LBL_NEW_GROUP',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button>
</div>
<?php }?>
</td>
</tr>
</table>
<script type="text/javascript">
window.onload = function(){
window_onload;
};
</script>
<?php echo $_smarty_tpl->getSubTemplate ('modules/ITS4YouReports/FieldExpressions.tpl', $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php }} ?>

View File

@@ -0,0 +1,40 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:06
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/partials/SidebarHeader.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1450369455692477a6596a39-18844481%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'4c5c49a7b2a914c873143ca475ba21cc7664d14a' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/partials/SidebarHeader.tpl',
1 => 1711810495,
2 => 'file',
),
),
'nocache_hash' => '1450369455692477a6596a39-18844481',
'function' =>
array (
),
'variables' =>
array (
'SELECTED_MENU_CATEGORY' => 0,
'MODULE' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477a6599c8',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477a6599c8')) {function content_692477a6599c8($_smarty_tpl) {?>
<?php $_smarty_tpl->tpl_vars['APP_IMAGE_MAP'] = new Smarty_variable(Vtiger_MenuStructure_Model::getAppIcons(), null, 0);?>
<div class="col-sm-12 col-xs-12 app-indicator-icon-container app-<?php echo $_smarty_tpl->tpl_vars['SELECTED_MENU_CATEGORY']->value;?>
">
<div class="row" title="<?php echo strtoupper(vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value));?>
">
<span class="app-indicator-icon fa fa-bar-chart"></span>
</div>
</div>
<?php echo $_smarty_tpl->getSubTemplate ("modules/Vtiger/partials/SidebarAppMenu.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php }} ?>

View File

@@ -0,0 +1,37 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:14
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/partials/SidebarHeader.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1868848172692477aeb21c86-76730072%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'5a09fbc29b8e39665fcb79febcd895db80e4e1c6' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/partials/SidebarHeader.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1868848172692477aeb21c86-76730072',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477aeb2616',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477aeb2616')) {function content_692477aeb2616($_smarty_tpl) {?>
<?php $_smarty_tpl->tpl_vars["APP_IMAGE_MAP"] = new Smarty_variable(array('MARKETING'=>'fa-users','SALES'=>'fa-dot-circle-o','SUPPORT'=>'fa-life-ring','INVENTORY'=>'vicon-inventory','PROJECT'=>'fa-briefcase'), null, 0);?>
<div class="col-sm-12 col-xs-12 app-indicator-icon-container app-MARKETING">
<div class="row" title="<?php echo strtoupper(vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value));?>
">
<span class="app-indicator-icon fa fa-bar-chart"></span>
</div>
</div>
<?php echo $_smarty_tpl->getSubTemplate ("modules/Vtiger/partials/SidebarAppMenu.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php }} ?>

View File

@@ -0,0 +1,48 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 10:04:12
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Calendar/uitypes/ActivityPicklistFieldSearchView.tpl" */ ?>
<?php /*%%SmartyHeaderCode:2162774206924036c0d4a07-96979156%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'5c127f5d528c116c3657d6c5fd8e7a78c154b2d5' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Calendar/uitypes/ActivityPicklistFieldSearchView.tpl',
1 => 1711810495,
2 => 'file',
),
),
'nocache_hash' => '2162774206924036c0d4a07-96979156',
'function' =>
array (
),
'variables' =>
array (
'FIELD_MODEL' => 0,
'FIELD_INFO' => 0,
'SEARCH_INFO' => 0,
'PICKLIST_VALUES' => 0,
'PICKLIST_KEY' => 0,
'SEARCH_VALUES' => 0,
'PICKLIST_LABEL' => 0,
'MODULE' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_6924036c0dcca',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_6924036c0dcca')) {function content_6924036c0dcca($_smarty_tpl) {?>
<?php $_smarty_tpl->tpl_vars['FIELD_INFO'] = new Smarty_variable($_smarty_tpl->tpl_vars['FIELD_MODEL']->value->getFieldInfo(), null, 0);?><?php $_smarty_tpl->tpl_vars['PICKLIST_VALUES'] = new Smarty_variable($_smarty_tpl->tpl_vars['FIELD_INFO']->value['picklistvalues'], null, 0);?><?php $_smarty_tpl->tpl_vars['FIELD_INFO'] = new Smarty_variable(Vtiger_Util_Helper::toSafeHTML(Zend_Json::encode($_smarty_tpl->tpl_vars['FIELD_INFO']->value)), null, 0);?><?php $_smarty_tpl->tpl_vars['SEARCH_VALUES'] = new Smarty_variable(explode(',',$_smarty_tpl->tpl_vars['SEARCH_INFO']->value['searchValue']), null, 0);?><div class="select2_search_div"><input type="text" class="listSearchContributor inputElement select2_input_element"/><select class="select2 listSearchContributor" name="<?php echo $_smarty_tpl->tpl_vars['FIELD_MODEL']->value->get('name');?>
" multiple data-fieldinfo='<?php echo htmlspecialchars($_smarty_tpl->tpl_vars['FIELD_INFO']->value, ENT_QUOTES, 'UTF-8', true);?>
' style="display:none"><?php $_smarty_tpl->tpl_vars['PICKLIST_LABEL'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->_loop = false;
$_smarty_tpl->tpl_vars['PICKLIST_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['PICKLIST_VALUES']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->key => $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value){
$_smarty_tpl->tpl_vars['PICKLIST_LABEL']->_loop = true;
$_smarty_tpl->tpl_vars['PICKLIST_KEY']->value = $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->key;
?><option value="<?php echo $_smarty_tpl->tpl_vars['PICKLIST_KEY']->value;?>
" <?php if (in_array($_smarty_tpl->tpl_vars['PICKLIST_KEY']->value,$_smarty_tpl->tpl_vars['SEARCH_VALUES']->value)){?> selected<?php }?>><?php echo $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value;?>
</option><?php } ?><option value="Task" <?php if (in_array("Task",$_smarty_tpl->tpl_vars['SEARCH_VALUES']->value)){?> selected<?php }?>><?php echo vtranslate('LBL_TODOS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</option></select></div>
<?php }} ?>

View File

@@ -0,0 +1,54 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:06
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewRecordActions.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1117150554692477a666a0b4-81395813%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'614d2203d3ab8aee98276677dabcbf0257a8d35a' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewRecordActions.tpl',
1 => 1711810495,
2 => 'file',
),
),
'nocache_hash' => '1117150554692477a666a0b4-81395813',
'function' =>
array (
),
'variables' =>
array (
'SEARCH_MODE_RESULTS' => 0,
'LISTVIEW_ENTRY' => 0,
'REPORT_TYPE' => 0,
'MODULE' => 0,
'PINNED' => 0,
'PIN_CLASS' => 0,
'DASHBOARD_TABS' => 0,
'TAB_INFO' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477a667f96',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477a667f96')) {function content_692477a667f96($_smarty_tpl) {?>
<!--LIST VIEW RECORD ACTIONS--><div class="table-actions reportListActions"><?php if (!$_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><span class="input" ><input type="checkbox" value="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
" class="listViewEntriesCheckBox"/></span><?php }?><?php $_smarty_tpl->tpl_vars["REPORT_TYPE"] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->get('reporttype'), null, 0);?><?php if ($_smarty_tpl->tpl_vars['REPORT_TYPE']->value=='chart'){?><span><a class="quickView fa fa-eye icon action" title="<?php echo vtranslate('LBL_QUICK_VIEW',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"></a></span><?php }?><?php $_smarty_tpl->tpl_vars["PINNED"] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->get('pinned'), null, 0);?><?php if ($_smarty_tpl->tpl_vars['PINNED']->value!=null&&$_smarty_tpl->tpl_vars['REPORT_TYPE']->value=='chart'){?><?php $_smarty_tpl->tpl_vars['PIN_CLASS'] = new Smarty_variable('vicon-unpin', null, 0);?><?php }elseif($_smarty_tpl->tpl_vars['REPORT_TYPE']->value=='chart'){?><?php $_smarty_tpl->tpl_vars['PIN_CLASS'] = new Smarty_variable('vicon-pin', null, 0);?><?php }?><?php if ($_smarty_tpl->tpl_vars['REPORT_TYPE']->value=='chart'){?><span class="dropdown"><span style="font-size:13px;" title="<?php if ($_smarty_tpl->tpl_vars['PIN_CLASS']->value=='vicon-pin'){?><?php echo vtranslate('LBL_PIN_CHART_TO_DASHBOARD',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }else{ ?><?php echo vtranslate('LBL_UNPIN_CHART_FROM_DASHBOARD',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?>"class="fa icon action <?php echo $_smarty_tpl->tpl_vars['PIN_CLASS']->value;?>
pinToDashboard " data-recordid="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->get('reportid');?>
"data-primemodule="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->get('primarymodule');?>
" <?php if (count($_smarty_tpl->tpl_vars['DASHBOARD_TABS']->value)>1&&$_smarty_tpl->tpl_vars['PIN_CLASS']->value=='vicon-pin'){?> data-toggle='dropdown'<?php }?>data-dashboard-tab-count='<?php echo count($_smarty_tpl->tpl_vars['DASHBOARD_TABS']->value);?>
'></span><ul class='dropdown-menu dashBoardTabMenu'><li class="dropdown-header popover-title"><?php echo vtranslate('LBL_DASHBOARD',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</li><?php $_smarty_tpl->tpl_vars['TAB_INFO'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['TAB_INFO']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['DASHBOARD_TABS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['TAB_INFO']->key => $_smarty_tpl->tpl_vars['TAB_INFO']->value){
$_smarty_tpl->tpl_vars['TAB_INFO']->_loop = true;
?><li class='dashBoardTab' data-tab-id='<?php echo $_smarty_tpl->tpl_vars['TAB_INFO']->value['id'];?>
'><a href='javascript:void(0);'><?php echo vtranslate($_smarty_tpl->tpl_vars['TAB_INFO']->value['tabname'],$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php } ?></ul></span><?php }?><?php if ($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->isEditableBySharing()){?><span class="more dropdown action"><span href="javascript:;" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v icon"></i></span><ul class="dropdown-menu"><li><a data-id="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
" href="javascript:void(0);" data-url="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getEditViewUrl();?>
" name="editlink"><?php echo vtranslate('LBL_EDIT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><li><a data-id="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getId();?>
" class="deleteRecordButton" href="javascript:void(0);"><?php echo vtranslate('LBL_DELETE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li></ul></span><?php }?><div class="btn-group inline-save hide"><button class="button btn-success btn-small save" name="save"><i class="fa fa-check"></i></button><button class="button btn-danger btn-small cancel" name="Cancel"><i class="fa fa-close"></i></button></div></div><?php }} ?>

View File

@@ -0,0 +1,123 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:23
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/DetailViewActions.tpl" */ ?>
<?php /*%%SmartyHeaderCode:72252607692477b7678d01-89848909%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'697b6e5c33f184d5794c621d6d65fbbb493fecb4' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/DetailViewActions.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '72252607692477b7678d01-89848909',
'function' =>
array (
),
'variables' =>
array (
'DETAILVIEW_ACTIONS' => 0,
'DETAILVIEW_LINK' => 0,
'LINK_ICON_CLASS' => 0,
'LINK_URL' => 0,
'DASHBOARD_TABS' => 0,
'REPORT_MODEL' => 0,
'MODULE' => 0,
'BTN_I' => 0,
'LINK_NAME' => 0,
'TAB_INFO' => 0,
'COUNT' => 0,
'COLUMNS_LIMIT' => 0,
'SUMMARIES_LIMIT' => 0,
'PDFMakerActive' => 0,
'IS_TEST_WRITE_ABLE' => 0,
'DETAILVIEW_LINKS' => 0,
'LINKNAME' => 0,
'ICON_CLASS' => 0,
'MODULENAME' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477b76a1cb',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477b76a1cb')) {function content_692477b76a1cb($_smarty_tpl) {?>
<div class="listViewPageDiv"><div class="reportHeader"><div class="row"><div class="col-lg-3"><div class="btn-toolbar"><div class="btn-group"><?php $_smarty_tpl->tpl_vars['BTN_I'] = new Smarty_variable('0', null, 0);?><?php $_smarty_tpl->tpl_vars['DETAILVIEW_LINK'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['DETAILVIEW_ACTIONS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->key => $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value){
$_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->_loop = true;
?><?php $_smarty_tpl->tpl_vars['LINK_URL'] = new Smarty_variable($_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl(), null, 0);?><?php $_smarty_tpl->tpl_vars['LINK_NAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getLabel(), null, 0);?><?php $_smarty_tpl->tpl_vars['LINK_ICON_CLASS'] = new Smarty_variable($_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkiconclass'), null, 0);?><?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='vtGlyph vticon-attach'){?><div class="btn-group"><?php }?><button <?php if ($_smarty_tpl->tpl_vars['LINK_URL']->value){?> onclick='window.location.href = "<?php echo $_smarty_tpl->tpl_vars['LINK_URL']->value;?>
"' <?php }?> type="button"class="cursorPointer btn btn-default <?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('customclass');?>
<?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='vtGlyph vticon-attach'&&ITS4YouReports_Functions_Helper::count($_smarty_tpl->tpl_vars['DASHBOARD_TABS']->value)>1){?> dropdown-toggle<?php }?>"title="<?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='vtGlyph vticon-attach'){?><?php if ($_smarty_tpl->tpl_vars['REPORT_MODEL']->value->isPinnedToDashboard()){?><?php echo vtranslate('LBL_UNPIN_CHART_FROM_DASHBOARD',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }else{ ?><?php echo vtranslate('LBL_PIN_CHART_TO_DASHBOARD',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?><?php }else{ ?><?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linktitle');?>
<?php }?>" <?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='vtGlyph vticon-attach'&&ITS4YouReports_Functions_Helper::count($_smarty_tpl->tpl_vars['DASHBOARD_TABS']->value)>1){?>data-toggle="dropdown"<?php }?><?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='vtGlyph vticon-attach'){?>data-dashboard-tab-count='<?php echo ITS4YouReports_Functions_Helper::count($_smarty_tpl->tpl_vars['DASHBOARD_TABS']->value);?>
'<?php }?>style="<?php if (0<$_smarty_tpl->tpl_vars['BTN_I']->value){?>margin-left:5px;<?php }?>"><?php if ($_smarty_tpl->tpl_vars['LINK_NAME']->value){?> <?php echo $_smarty_tpl->tpl_vars['LINK_NAME']->value;?>
<?php }?><?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value){?><?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='icon-pencil'){?>&nbsp;&nbsp;&nbsp;<?php }?><i class="fa <?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='icon-pencil'){?>fa-pencil<?php }elseif($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='vtGlyph vticon-attach'){?><?php if ($_smarty_tpl->tpl_vars['REPORT_MODEL']->value->isPinnedToDashboard()){?>vicon-unpin<?php }else{ ?>vicon-pin<?php }?><?php }?>" style="font-size: 13px;"></i><?php }?></button><?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='vtGlyph vticon-attach'){?><ul class='dropdown-menu dashBoardTabMenu'><li class="dropdown-header popover-title"><?php echo vtranslate('LBL_DASHBOARD',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</li><?php $_smarty_tpl->tpl_vars['TAB_INFO'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['TAB_INFO']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['DASHBOARD_TABS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['TAB_INFO']->key => $_smarty_tpl->tpl_vars['TAB_INFO']->value){
$_smarty_tpl->tpl_vars['TAB_INFO']->_loop = true;
?><li class='dashBoardTab' data-tab-id='<?php echo $_smarty_tpl->tpl_vars['TAB_INFO']->value['id'];?>
'><a href='javascript:void(0)'> <?php echo $_smarty_tpl->tpl_vars['TAB_INFO']->value['tabname'];?>
</a></li><?php } ?></ul><?php }?><?php if ($_smarty_tpl->tpl_vars['LINK_ICON_CLASS']->value=='vtGlyph vticon-attach'){?></div><?php }?><?php $_smarty_tpl->tpl_vars['BTN_I'] = new Smarty_variable($_smarty_tpl->tpl_vars['BTN_I']->value+1, null, 0);?><?php } ?></div></div></div><div class="col-lg-6 textAlignCenter"><h3 class="marginTop0px"><?php echo $_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getName();?>
</h3><div id="noOfRecords"><?php echo vtranslate('LBL_NO_OF_RECORDS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<span id="countValue"><?php echo $_smarty_tpl->tpl_vars['COUNT']->value;?>
</span><?php if ($_smarty_tpl->tpl_vars['COUNT']->value>1000){?><span class="redColor" id="moreRecordsText"> (<?php echo vtranslate('LBL_MORE_RECORDS_TXT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
)</span><?php }else{ ?><span class="redColor hide" id="moreRecordsText"> (<?php echo vtranslate('LBL_MORE_RECORDS_TXT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
)</span><?php }?></div><?php if ('custom_report'!=$_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getReportType()){?><div class="limitsAreaInfoColored" id="limitOfRecords"><?php echo vtranslate('LBL_LIMITED',$_smarty_tpl->tpl_vars['MODULE']->value);?>
: (<?php if ($_smarty_tpl->tpl_vars['COLUMNS_LIMIT']->value>0){?><?php echo vtranslate('SET_LIMIT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php echo $_smarty_tpl->tpl_vars['COLUMNS_LIMIT']->value;?>
<?php }?><?php if ($_smarty_tpl->tpl_vars['COLUMNS_LIMIT']->value>0&&$_smarty_tpl->tpl_vars['SUMMARIES_LIMIT']->value>0){?>, <?php }elseif($_smarty_tpl->tpl_vars['COLUMNS_LIMIT']->value==0&&$_smarty_tpl->tpl_vars['SUMMARIES_LIMIT']->value==0){?><?php echo vtranslate('LBL_ALL_RECORDS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?><?php if ($_smarty_tpl->tpl_vars['SUMMARIES_LIMIT']->value>0){?><?php echo vtranslate('SUMMARIES_LIMIT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php echo $_smarty_tpl->tpl_vars['SUMMARIES_LIMIT']->value;?>
<?php }?>)</div><?php }?><div id='activate_pdfmaker' class="fieldValue" style="display:block;"><span class="value"><?php if ($_smarty_tpl->tpl_vars['PDFMakerActive']->value!==true){?><?php echo vtranslate('Please_Install_PDFMaker',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?><?php if ($_smarty_tpl->tpl_vars['IS_TEST_WRITE_ABLE']->value!==true){?><?php echo vtranslate('Test_Not_WriteAble',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?></span></div></div><div class='col-lg-3'><span class="pull-right"><div class="btn-toolbar"><div class="btn-group"><?php if ('tabular'==$_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getReportType()){?><?php $_smarty_tpl->tpl_vars['DETAILVIEW_LINK'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['DETAILVIEW_LINKS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->key => $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value){
$_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->_loop = true;
?><?php $_smarty_tpl->tpl_vars['LINKNAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getLabel(), null, 0);?><span class="btn-group"><?php if ('custom_report'==$_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getReportType()){?><button class="btn btn-default reportActions" data-href="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl();?>
&source=<?php echo $_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getReportType();?>
"style="margin-left:5px;" type="button" data-toggle="dropdown" name="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkname');?>
" ><?php echo $_smarty_tpl->tpl_vars['LINKNAME']->value;?>
</button><?php }else{ ?><ul class="nav navbar-nav navbar-right"><li><button class="btn btn-default dropdown-toggle"style="margin-left:5px;" type="button" data-toggle="dropdown" ><?php echo $_smarty_tpl->tpl_vars['LINKNAME']->value;?>
&nbsp;<span class="caret"></span></button><ul class="dropdown-menu"><li><a href="javascript:void(0);" data-href="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl();?>
&data=base" data-type="base" name="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkname');?>
" class="reportActions" ><i class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
' style="font-size:13px;"></i>&nbsp; <?php echo vtranslate('LBL_EXPORT_REPORTED_RECORDS','ITS4YouReports');?>
</a></li><li><a href="javascript:void(0);" data-href="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl();?>
&data=all" data-type="all" name="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkname');?>
" class="reportActions" ><i class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
' style="font-size:13px;"></i>&nbsp; <?php echo vtranslate('LBL_ALL',$_smarty_tpl->tpl_vars['MODULENAME']->value);?>
</a></li><li><a href="javascript:void(0);" data-href="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl();?>
" data-type="all" data-background-export="true" name="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkname');?>
" class="reportActions" ><i class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
' style="font-size:13px;"></i>&nbsp; <?php echo vtranslate('LBL_BACKGROUND_EXPORT','ITS4YouReports');?>
</a></li></ul></li></ul><?php }?></span><?php } ?><?php }elseif('custom_report'!=$_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getReportType()){?><?php $_smarty_tpl->tpl_vars['DETAILVIEW_LINK'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['DETAILVIEW_LINKS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->key => $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value){
$_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->_loop = true;
?><?php $_smarty_tpl->tpl_vars['LINKNAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getLabel(), null, 0);?><?php if ('generateMap'!=$_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('id')){?><ul class="nav navbar-nav navbar-right"><li><button class="btn btn-default dropdown-toggle"style="margin-left:5px;" type="button" data-toggle="dropdown" ><?php echo $_smarty_tpl->tpl_vars['LINKNAME']->value;?>
&nbsp;<span class="caret"></span></button><ul class="dropdown-menu"><li><a href="javascript:void(0);" data-href="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl();?>
&data=base" data-type="base" name="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkname');?>
" class="reportActions" ><i class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
' style="font-size:13px;"></i>&nbsp; <?php echo vtranslate('LBL_EXPORT_REPORTED_RECORDS','ITS4YouReports');?>
</a></li><li><a href="javascript:void(0);" data-href="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl();?>
" data-type="all" data-background-export="true" name="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkname');?>
" class="reportActions" ><i class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
' style="font-size:13px;"></i>&nbsp; <?php echo vtranslate('LBL_BACKGROUND_EXPORT','ITS4YouReports');?>
</a></li></ul></li></ul><?php }else{ ?><?php $_smarty_tpl->tpl_vars['LINKNAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getLabel(), null, 0);?><button class="btn btn-default reportActions" name="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkname');?>
"data-href="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl();?>
&source=<?php echo $_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getReportType();?>
"style="margin-left:5px;"><?php echo $_smarty_tpl->tpl_vars['LINKNAME']->value;?>
</button><?php }?><?php } ?><?php }else{ ?><?php $_smarty_tpl->tpl_vars['DETAILVIEW_LINK'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['DETAILVIEW_LINKS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->key => $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value){
$_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->_loop = true;
?><?php $_smarty_tpl->tpl_vars['LINKNAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getLabel(), null, 0);?><button class="btn btn-default reportActions" name="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->get('linkname');?>
"data-href="<?php echo $_smarty_tpl->tpl_vars['DETAILVIEW_LINK']->value->getUrl();?>
&source=<?php echo $_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getReportType();?>
"style="margin-left:5px;"><?php echo $_smarty_tpl->tpl_vars['LINKNAME']->value;?>
</button><?php } ?><?php }?></div></div></span></div></div></div></div>
<?php }} ?>

View File

@@ -0,0 +1,98 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:14
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ModuleHeader.tpl" */ ?>
<?php /*%%SmartyHeaderCode:594469185692477aeb3a632-69823387%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'771116ed665e7d24d34aaf5300b8a5fa0901c7bd' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ModuleHeader.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '594469185692477aeb3a632-69823387',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
'MODULE_MODEL' => 0,
'DEFAULT_FILTER_ID' => 0,
'CVURL' => 0,
'DEFAULT_FILTER_URL' => 0,
'VIEW' => 0,
'REPORT_NAME' => 0,
'KM_ID' => 0,
'KM_NAME' => 0,
'VIEWNAME' => 0,
'FOLDERS' => 0,
'FOLDER' => 0,
'FOLDERNAME' => 0,
'NO_LICENSE' => 0,
'LISTVIEW_LINKS' => 0,
'LISTVIEW_BASICACTION' => 0,
'childLinks' => 0,
'childLink' => 0,
'ICON_CLASS' => 0,
'MODULE_NAME' => 0,
'SETTING' => 0,
'FIELDS_INFO' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477aeb64b6',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477aeb64b6')) {function content_692477aeb64b6($_smarty_tpl) {?>
<div class="col-sm-12 col-xs-12 module-action-bar clearfix coloredBorderTop"><div class="module-action-content clearfix"><span class="col-lg-7 col-md-7"><span><?php $_smarty_tpl->tpl_vars['MODULE_MODEL'] = new Smarty_variable(Vtiger_Module_Model::getInstance($_smarty_tpl->tpl_vars['MODULE']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['DEFAULT_FILTER_ID'] = new Smarty_variable($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->getDefaultCustomFilter(), null, 0);?><?php if ($_smarty_tpl->tpl_vars['DEFAULT_FILTER_ID']->value){?><?php $_smarty_tpl->tpl_vars['CVURL'] = new Smarty_variable(("&viewname=").($_smarty_tpl->tpl_vars['DEFAULT_FILTER_ID']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['DEFAULT_FILTER_URL'] = new Smarty_variable(($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->getListViewUrl()).($_smarty_tpl->tpl_vars['CVURL']->value), null, 0);?><?php }else{ ?><?php $_smarty_tpl->tpl_vars['DEFAULT_FILTER_URL'] = new Smarty_variable($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->getListViewUrlWithAllFilter(), null, 0);?><?php }?><a title="<?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
" href='<?php echo $_smarty_tpl->tpl_vars['DEFAULT_FILTER_URL']->value;?>
'><h4 class="module-title pull-left"> <?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h4></a></span><span><p class="current-filter-name pull-left">&nbsp;&nbsp;<span class="fa fa-angle-right" aria-hidden="true"></span><?php if ($_smarty_tpl->tpl_vars['VIEW']->value=='Edit'||$_smarty_tpl->tpl_vars['VIEW']->value=='Detail'){?>&nbsp;<span id="reportnameTop"><?php if (''!=$_smarty_tpl->tpl_vars['REPORT_NAME']->value){?><?php echo $_smarty_tpl->tpl_vars['REPORT_NAME']->value;?>
<?php }else{ ?><?php echo vtranslate('LBL_NEW');?>
<?php }?></span>&nbsp;<span class="fa fa-angle-right" aria-hidden="true"></span><?php }?>&nbsp;<?php if ('true'==$_REQUEST['isDuplicate']){?><?php echo vtranslate('Duplicate',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }elseif('KeyMetricsRows'==$_REQUEST['view']||'EditKeyMetricsRow'==$_REQUEST['view']){?><a href="index.php?module=<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
&view=KeyMetricsList" style="vertical-align:bottom;"><?php echo vtranslate('KeyMetricsList',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a>&nbsp;<span class="fa fa-angle-right" aria-hidden="true"></span>&nbsp;<a href="index.php?module=<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
&view=KeyMetricsRows&id=<?php echo $_smarty_tpl->tpl_vars['KM_ID']->value;?>
" style="vertical-align:bottom;"><?php echo $_smarty_tpl->tpl_vars['KM_NAME']->value;?>
</a>&nbsp;<span class="fa fa-angle-right" aria-hidden="true"></span>&nbsp;<?php echo vtranslate($_smarty_tpl->tpl_vars['VIEW']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }else{ ?><?php echo vtranslate($_smarty_tpl->tpl_vars['VIEW']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?></p></span><?php if ($_smarty_tpl->tpl_vars['VIEWNAME']->value){?><?php if ($_smarty_tpl->tpl_vars['VIEWNAME']->value!='All'){?><?php $_smarty_tpl->tpl_vars['FOLDER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['FOLDER']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['FOLDERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['FOLDER']->key => $_smarty_tpl->tpl_vars['FOLDER']->value){
$_smarty_tpl->tpl_vars['FOLDER']->_loop = true;
?><?php if ($_smarty_tpl->tpl_vars['FOLDER']->value->getId()==$_smarty_tpl->tpl_vars['VIEWNAME']->value){?><?php $_smarty_tpl->tpl_vars['FOLDERNAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['FOLDER']->value->getName(), null, 0);?><?php break 1?><?php }?><?php } ?><?php }else{ ?><?php $_smarty_tpl->tpl_vars['FOLDERNAME'] = new Smarty_variable(vtranslate('LBL_ALL_REPORTS',$_smarty_tpl->tpl_vars['MODULE']->value), null, 0);?><?php }?><span><p class="current-filter-name filter-name pull-left">&nbsp;&nbsp;<span class="fa fa-angle-right" aria-hidden="true"></span> <?php echo $_smarty_tpl->tpl_vars['FOLDERNAME']->value;?>
</p></span><?php }?></span><span class="col-lg-5 col-md-5 pull-right"><div id="appnav" class="navbar-right"><?php if (0==$_smarty_tpl->tpl_vars['NO_LICENSE']->value){?><?php $_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_LINKS']->value['LISTVIEWBASIC']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->key => $_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->_loop = true;
?><?php $_smarty_tpl->tpl_vars["childLinks"] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->value->getChildLinks(), null, 0);?><?php if ($_smarty_tpl->tpl_vars['childLinks']->value&&$_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->value->get('linklabel')=='LBL_ADD_RECORD'){?><span class="btn-group"><button class="btn btn-default dropdown-toggle module-buttons" data-toggle="dropdown" id="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_basicAction_Add"><i class="fa fa-plus"></i>&nbsp;<?php echo vtranslate($_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->value->getLabel(),$_smarty_tpl->tpl_vars['MODULE']->value);?>
&nbsp;<i class="caret icon-white"></i></button><ul class="dropdown-menu"><?php $_smarty_tpl->tpl_vars["childLink"] = new Smarty_Variable; $_smarty_tpl->tpl_vars["childLink"]->_loop = false;
$_from = $_smarty_tpl->tpl_vars['childLinks']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars["childLink"]->key => $_smarty_tpl->tpl_vars["childLink"]->value){
$_smarty_tpl->tpl_vars["childLink"]->_loop = true;
?><li id="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_basicAction_<?php echo Vtiger_Util_Helper::replaceSpaceWithUnderScores($_smarty_tpl->tpl_vars['childLink']->value->getLabel());?>
" data-edition-disable="<?php echo $_smarty_tpl->tpl_vars['childLink']->value->disabled;?>
" data-edition-message="<?php echo $_smarty_tpl->tpl_vars['childLink']->value->message;?>
"><a <?php if ($_smarty_tpl->tpl_vars['childLink']->value->disabled!='1'){?> <?php if (stripos($_smarty_tpl->tpl_vars['childLink']->value->getUrl(),'javascript:')===0){?> onclick='<?php echo substr($_smarty_tpl->tpl_vars['childLink']->value->getUrl(),strlen("javascript:"));?>
;' <?php }else{ ?> href='<?php echo $_smarty_tpl->tpl_vars['childLink']->value->getUrl();?>
' <?php }?> <?php }else{ ?> href="javascript:void(0);" <?php }?>><i class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
' style="font-size:13px;"></i>&nbsp; <?php echo vtranslate($_smarty_tpl->tpl_vars['childLink']->value->getLabel(),$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php } ?></ul></span><?php }?><?php } ?><?php }?><?php if ('KeyMetricsList'===$_REQUEST['view']){?><span class="btn-group"><button class="btn btn-default dropdown-toggle module-buttons" data-toggle="dropdown" id="ITS4YouKeyMetrics_listView_basicAction_LBL_ADD_RECORD"><i class="fa fa-plus"></i>&nbsp;<?php echo vtranslate("LBL_ADD_ITEM",$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php echo vtranslate("LBL_KEY_METRICS",$_smarty_tpl->tpl_vars['MODULE']->value);?>
&nbsp;</button></span><?php }?><ul class="nav navbar-nav navbar-right"><?php if (ITS4YouReports_Functions_Helper::count($_smarty_tpl->tpl_vars['LISTVIEW_LINKS']->value['LISTVIEWSETTING'])>0){?><li><div class="settingsIcon"><button type="button" class="btn btn-default module-buttons dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><span class="fa fa-wrench" aria-hidden="true" title="<?php echo vtranslate('LBL_SETTINGS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"></span>&nbsp;<?php echo vtranslate('LBL_CUSTOMIZE','Reports');?>
&nbsp; <span class="caret"></span></button><ul class="detailViewSetting dropdown-menu"><?php $_smarty_tpl->tpl_vars['SETTING'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['SETTING']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_LINKS']->value['LISTVIEWSETTING']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['SETTING']->key => $_smarty_tpl->tpl_vars['SETTING']->value){
$_smarty_tpl->tpl_vars['SETTING']->_loop = true;
?><li id="<?php echo $_smarty_tpl->tpl_vars['MODULE_NAME']->value;?>
_listview_advancedAction_<?php echo $_smarty_tpl->tpl_vars['SETTING']->value->getLabel();?>
"><a href=<?php echo $_smarty_tpl->tpl_vars['SETTING']->value->getUrl();?>
><?php echo vtranslate($_smarty_tpl->tpl_vars['SETTING']->value->getLabel(),$_smarty_tpl->tpl_vars['MODULE_NAME']->value,vtranslate($_smarty_tpl->tpl_vars['MODULE_NAME']->value,$_smarty_tpl->tpl_vars['MODULE_NAME']->value));?>
</a></li><?php } ?></ul></div></li><?php }?></ul></div></span></div><div class="rssAddFormContainer hide"></div><?php if ($_smarty_tpl->tpl_vars['FIELDS_INFO']->value!=null){?><script type="text/javascript">var uimeta = (function () {var fieldInfo = <?php echo $_smarty_tpl->tpl_vars['FIELDS_INFO']->value;?>
;return {field: {get: function (name, property) {if (name && property === undefined) {return fieldInfo[name];}if (name && property) {return fieldInfo[name][property]}},isMandatory: function (name) {if (fieldInfo[name]) {return fieldInfo[name].mandatory;}return false;},getType: function (name) {if (fieldInfo[name]) {return fieldInfo[name].type}return false;}},};})();</script><?php }?></div><?php }} ?>

View File

@@ -0,0 +1,33 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:23
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/FieldExpressions.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1833161144692477b765a8e1-56606492%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'7960bbdb89b4793a3078596dd77811a96e017dc9' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/FieldExpressions.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1833161144692477b765a8e1-56606492',
'function' =>
array (
),
'variables' =>
array (
'columnIndex' => 0,
'MODULE' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477b765d0a',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477b765d0a')) {function content_692477b765d0a($_smarty_tpl) {?>
<?php $_smarty_tpl->tpl_vars["columnIndex"] = new Smarty_variable("WCCINRW", null, 0);?><div class="form-group hide" id='fieldExpressionsBase'><div class="fieldExpressionsBase " id='fieldExpressionsBaseWCCINRW' style="position:relative;left:40%;padding-left: 3%;padding-right: 3%"><div class="col-lg-5" data-backdrop="false" style="z-index: 900;min-width: 750px;overflow: visible;border:1px solid #ccc;padding:0px;"><div class="modal-header contentsBackground" style="text-align:left;"><button type="button" class="close" onClick="jQuery('#fieldExpressionsBase<?php echo $_smarty_tpl->tpl_vars['columnIndex']->value;?>
').css('display', 'none');" data-dismiss="modal" aria-hidden="true" style="margin-top:2px; opacity: .9;">&times;</button><h3><?php echo vtranslate('LBL_SET_VALUE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h3></div><div class="modal-body"><div class="row-fluid"><span class="span4" style="text-align:left;"><select name="fc_fval_<?php echo $_smarty_tpl->tpl_vars['columnIndex']->value;?>
" id="fc_fval_<?php echo $_smarty_tpl->tpl_vars['columnIndex']->value;?>
" onChange="AddFieldToFilter('<?php echo $_smarty_tpl->tpl_vars['columnIndex']->value;?>
',this);" class="inputElement"style="margin-top:0.5em;"></select></span></div></div></div><div class="clonedPopUp"></div></div></div><?php }} ?>

View File

@@ -0,0 +1,48 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:06
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewActions.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1302564042692477a6630ff7-79176962%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'87d6f754af62470e8cc17e73e06b06d287b55633' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewActions.tpl',
1 => 1711810495,
2 => 'file',
),
),
'nocache_hash' => '1302564042692477a6630ff7-79176962',
'function' =>
array (
),
'variables' =>
array (
'LISTVIEW_MASSACTIONS' => 0,
'LIST_MASSACTION' => 0,
'LISTVIEW_MASSACTIONS_1' => 0,
'deleteAction' => 0,
'MODULE' => 0,
'LISTVIEW_ENTRIES_COUNT' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477a6640f3',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477a6640f3')) {function content_692477a6640f3($_smarty_tpl) {?>
<?php $_smarty_tpl->tpl_vars['LISTVIEW_MASSACTIONS_1'] = new Smarty_variable(array(), null, 0);?><div id="listview-actions" class="listview-actions-container"><?php $_smarty_tpl->tpl_vars['LIST_MASSACTION'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LIST_MASSACTION']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_MASSACTIONS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LIST_MASSACTION']->key => $_smarty_tpl->tpl_vars['LIST_MASSACTION']->value){
$_smarty_tpl->tpl_vars['LIST_MASSACTION']->_loop = true;
?><?php if ($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value->getLabel()=='LBL_EDIT'){?><?php $_smarty_tpl->tpl_vars['editAction'] = new Smarty_variable($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value, null, 0);?><?php }elseif($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value->getLabel()=='LBL_DELETE'){?><?php $_smarty_tpl->tpl_vars['deleteAction'] = new Smarty_variable($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value, null, 0);?><?php }elseif($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value->getLabel()=='LBL_ADD_COMMENT'){?><?php $_smarty_tpl->tpl_vars['commentAction'] = new Smarty_variable($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value, null, 0);?><?php }else{ ?><?php $_smarty_tpl->tpl_vars['a'] = new Smarty_variable(array_push($_smarty_tpl->tpl_vars['LISTVIEW_MASSACTIONS_1']->value,$_smarty_tpl->tpl_vars['LIST_MASSACTION']->value), null, 0);?><?php }?><?php } ?><div class = "row"><div class="col-md-3"><div class="btn-group listViewActionsContainer" role="group" aria-label="..."><?php if ($_smarty_tpl->tpl_vars['deleteAction']->value){?><button type="button" class="btn btn-default" id="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_massAction_LBL_MOVE_REPORT"onclick='Reports_List_Js.massMove("index.php?module=Reports&view=MoveReports")' title="<?php echo vtranslate('LBL_MOVE_REPORT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" disabled="disabled"><i class="vicon-foldermove" style='font-size:13px;'></i></button><?php }?><?php if ($_smarty_tpl->tpl_vars['deleteAction']->value){?><button type="button" class="btn btn-default" id=<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_massAction_<?php echo $_smarty_tpl->tpl_vars['deleteAction']->value->getLabel();?>
<?php if (stripos($_smarty_tpl->tpl_vars['deleteAction']->value->getUrl(),'javascript:')===0){?> href="javascript:void(0);" onclick='<?php echo substr($_smarty_tpl->tpl_vars['deleteAction']->value->getUrl(),strlen("javascript:"));?>
'<?php }else{ ?> href='<?php echo $_smarty_tpl->tpl_vars['deleteAction']->value->getUrl();?>
' <?php }?> title="<?php echo vtranslate('LBL_DELETE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" disabled="disabled"><i class="fa fa-trash"></i></button><?php }?></div></div><div class='col-md-6'><div class="hide messageContainer" style = "height:30px;"><center><a id="selectAllMsgDiv" href="#"><?php echo vtranslate('LBL_SELECT_ALL',$_smarty_tpl->tpl_vars['MODULE']->value);?>
&nbsp;<?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
&nbsp;(<span id="totalRecordsCount" value=""></span>)</a></center></div><div class="hide messageContainer" style = "height:30px;"><center><a id="deSelectAllMsgDiv" href="#"><?php echo vtranslate('LBL_DESELECT_ALL_RECORDS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></center></div></div><div class="col-md-3"><?php $_smarty_tpl->tpl_vars['RECORD_COUNT'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES_COUNT']->value, null, 0);?><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("Pagination.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array('SHOWPAGEJUMP'=>true), 0);?>
</div></div><?php }} ?>

View File

@@ -0,0 +1,61 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:14
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/partials/SidebarEssentials.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1591821842692477aeb73f51-62072954%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'885963af7bb1787b612e69517c5a6ef946d6c39a' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/partials/SidebarEssentials.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1591821842692477aeb73f51-62072954',
'function' =>
array (
),
'variables' =>
array (
'NO_LICENSE' => 0,
'MODULE' => 0,
'FOLDERS' => 0,
'FOLDER' => 0,
'VIEWNAME' => 0,
'FOLDERID' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477aeb8b6a',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477aeb8b6a')) {function content_692477aeb8b6a($_smarty_tpl) {?>
<?php if (1==$_smarty_tpl->tpl_vars['NO_LICENSE']->value){?><script type="text/javascript">jQuery('#sidebar-essentials').remove()</script><?php }else{ ?><div class="sidebar-menu sidebar-menu-full"><div class="module-filters" id="module-filters"><div class="sidebar-container lists-menu-container"><div class="sidebar-header clearfix" style="<?php if ('List'==$_REQUEST['view']){?>border-bottom:2px solid;<?php }?>"><h5 class="pull-left"><?php echo vtranslate('LBL_LIST_VIEW',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h5><button id="keyMetricsList" onclick='window.location.href="index.php?module=ITS4YouReports&view=List"' class="btn btn-default pull-right sidebar-btn" title="<?php echo vtranslate('LBL_KEY_METRICS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"><div class="fa fa-chevron-right"></div></button></div><div class="sidebar-header clearfix" style="<?php if ('KeyMetricsList'==$_REQUEST['view']){?>border-bottom:2px solid;<?php }?>"><h5 class="pull-left"><?php echo vtranslate('LBL_KEY_METRICS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h5><button id="keyMetricsList" onclick='window.location.href="index.php?module=ITS4YouReports&view=KeyMetricsList"' class="btn btn-default pull-right sidebar-btn" title="<?php echo vtranslate('LBL_KEY_METRICS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"><div class="fa fa-chevron-right"></div></button></div><?php if ('List'===$_REQUEST['view']){?><div class="sidebar-header clearfix"><h5 class="pull-left"><?php echo vtranslate('LBL_FOLDERS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h5><button id="createFilter" onclick='ITS4YouReports_List_Js.triggerAddFolder("index.php?module=ITS4YouReports&view=EditFolder");' class="btn btn-default pull-right sidebar-btn" title="<?php echo vtranslate('LBL_ADD_NEW_FOLDER',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"><div class="fa fa-plus" aria-hidden="true"></div></button></div><hr><div><input class="search-list" type="text" placeholder="<?php echo vtranslate('LBL_SEARCH_FOR_FOLDERS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"></div><div class="menu-scroller mCustomScrollBox" data-mcs-theme="dark"><div class="mCustomScrollBox mCS-light-2 mCSB_inside" tabindex="0"><div class="mCSB_container" style="position:relative; top:0; left:0;"><div class="list-menu-content"><div class="list-group"><ul class="lists-menu"><li style="font-size:12px;" class="listViewFilter" ><a href="#" class='filterName' data-filter-id="All"><i class="fa fa-folder foldericon"></i>&nbsp;<?php echo vtranslate('LBL_ALL_REPORTS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php $_smarty_tpl->tpl_vars['FOLDER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['FOLDER']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['FOLDERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
$_smarty_tpl->tpl_vars['smarty']->value['foreach']["folderview"]['iteration']=0;
foreach ($_from as $_smarty_tpl->tpl_vars['FOLDER']->key => $_smarty_tpl->tpl_vars['FOLDER']->value){
$_smarty_tpl->tpl_vars['FOLDER']->_loop = true;
$_smarty_tpl->tpl_vars['smarty']->value['foreach']["folderview"]['iteration']++;
?><li style="font-size:12px;" class="listViewFilter <?php if ($_smarty_tpl->getVariable('smarty')->value['foreach']['folderview']['iteration']>18){?> filterHidden hide<?php }?>" ><?php ob_start();?><?php echo vtranslate($_smarty_tpl->tpl_vars['FOLDER']->value->getName(),$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php $_tmp1=ob_get_clean();?><?php $_smarty_tpl->tpl_vars['VIEWNAME'] = new Smarty_variable($_tmp1, null, 0);?><a href="#" class='filterName' data-filter-id=<?php echo $_smarty_tpl->tpl_vars['FOLDER']->value->getId();?>
><i class="fa fa-folder foldericon"></i>&nbsp;<?php ob_start();?><?php echo strlen($_smarty_tpl->tpl_vars['VIEWNAME']->value)>50;?>
<?php $_tmp2=ob_get_clean();?><?php if ($_tmp2){?><?php echo substr($_smarty_tpl->tpl_vars['VIEWNAME']->value,0,45);?>
..<?php }else{ ?><?php echo $_smarty_tpl->tpl_vars['VIEWNAME']->value;?>
<?php }?></a><?php if (''!==$_smarty_tpl->tpl_vars['FOLDER']->value->getDescription()){?><i class="fa fa-info-circle" title="<?php echo $_smarty_tpl->tpl_vars['FOLDER']->value->getDescription();?>
"></i><?php }?><div class="pull-right"><?php if ($_smarty_tpl->tpl_vars['FOLDER']->value->isEditable()&&$_smarty_tpl->tpl_vars['FOLDER']->value->isDeletable()){?><?php $_smarty_tpl->tpl_vars["FOLDERID"] = new Smarty_variable($_smarty_tpl->tpl_vars['FOLDER']->value->get('folderid'), null, 0);?><span class="js-popover-container"><span class="fa fa-angle-down" data-id="<?php echo $_smarty_tpl->tpl_vars['FOLDERID']->value;?>
" data-deletable="true" data-editable="true" rel="popover" data-toggle="popover" data-deleteurl="<?php echo $_smarty_tpl->tpl_vars['FOLDER']->value->getDeleteUrl();?>
" data-editurl="<?php echo $_smarty_tpl->tpl_vars['FOLDER']->value->getEditUrl();?>
" data-toggle="dropdown" aria-expanded="true"></span></span><?php }?></div></li><?php } ?></ul><div id="filterActionPopoverHtml"><ul class="listmenu hide" role="menu"><li role="presentation" class="editFilter"><a role="menuitem"><i class="fa fa-pencil-square-o"></i>&nbsp;<?php echo vtranslate('LBL_EDIT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><li role="presentation" class="deleteFilter"><a role="menuitem"><i class="fa fa-trash"></i>&nbsp;<?php echo vtranslate('LBL_DELETE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li></ul></div><h5 class="toggleFilterSize" data-more-text="<?php echo vtranslate('LBL_MORE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
.." data-less-text="<?php echo vtranslate('LBL_LESS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
.."><?php if ($_smarty_tpl->getVariable('smarty')->value['foreach']['folderview']['iteration']>18){?><?php echo vtranslate('LBL_MORE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
..<?php }?></h5></div></div></div></div></div><?php }?></div></div></div><?php }?><?php }} ?>

View File

@@ -0,0 +1,87 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:14
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ListViewActions.tpl" */ ?>
<?php /*%%SmartyHeaderCode:778172812692477aebcf396-16581001%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'898c77c103daf6e53c1fd50960eab91d6a3cb2df' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ListViewActions.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '778172812692477aebcf396-16581001',
'function' =>
array (
),
'variables' =>
array (
'LISTVIEW_MASSACTIONS' => 0,
'LIST_MASSACTION' => 0,
'LISTVIEW_MASSACTIONS_1' => 0,
'deleteAction' => 0,
'MODULE' => 0,
'LISTVIEW_ENTRIES_COUNT' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477aebdb46',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477aebdb46')) {function content_692477aebdb46($_smarty_tpl) {?>
<div id="listview-actions" class="listview-actions-container">
<?php $_smarty_tpl->tpl_vars['LISTVIEW_MASSACTIONS_1'] = new Smarty_variable(array(), null, 0);?>
<?php $_smarty_tpl->tpl_vars['LIST_MASSACTION'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LIST_MASSACTION']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_MASSACTIONS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LIST_MASSACTION']->key => $_smarty_tpl->tpl_vars['LIST_MASSACTION']->value){
$_smarty_tpl->tpl_vars['LIST_MASSACTION']->_loop = true;
?>
<?php if (!empty($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value)&&$_smarty_tpl->tpl_vars['LIST_MASSACTION']->value->getLabel()=='LBL_EDIT'){?>
<?php $_smarty_tpl->tpl_vars['editAction'] = new Smarty_variable($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value, null, 0);?>
<?php }elseif(!empty($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value)&&$_smarty_tpl->tpl_vars['LIST_MASSACTION']->value->getLabel()=='LBL_DELETE'){?>
<?php $_smarty_tpl->tpl_vars['deleteAction'] = new Smarty_variable($_smarty_tpl->tpl_vars['LIST_MASSACTION']->value, null, 0);?>
<?php }else{ ?>
<?php $_smarty_tpl->tpl_vars['a'] = new Smarty_variable(array_push($_smarty_tpl->tpl_vars['LISTVIEW_MASSACTIONS_1']->value,$_smarty_tpl->tpl_vars['LIST_MASSACTION']->value), null, 0);?>
<?php }?>
<?php } ?>
<div class="row">
<div class="col-md-3">
<div class="btn-group listViewActionsContainer" role="group" aria-label="...">
<?php if ($_smarty_tpl->tpl_vars['deleteAction']->value){?>
<button type="button" class="btn btn-default" id="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_massAction_LBL_MOVE_REPORT"
onclick='<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_List_Js.massMove("index.php?module=<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
&view=MoveReports")' title="<?php echo vtranslate('LBL_MOVE_REPORT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" disabled="disabled">
<i class="vicon-foldermove" style='font-size:13px;'></i>
</button>
<?php }?>
<?php if ($_smarty_tpl->tpl_vars['deleteAction']->value){?>
<button type="button" class="btn btn-default" id=<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_massAction_<?php echo $_smarty_tpl->tpl_vars['deleteAction']->value->getLabel();?>
<?php if (stripos($_smarty_tpl->tpl_vars['deleteAction']->value->getUrl(),'javascript:')===0){?>onclick='<?php echo substr($_smarty_tpl->tpl_vars['deleteAction']->value->getUrl(),strlen("javascript:"));?>
;'<?php }else{ ?> onclick="Vtiger_List_Js.triggerMassAction('<?php echo $_smarty_tpl->tpl_vars['deleteAction']->value->getUrl();?>
')"<?php }?>
title="<?php echo vtranslate('LBL_DELETE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" disabled="disabled"
style="margin-left:5px;" >
<i class="fa fa-trash"></i>
</button>
<?php }?>
</div>
</div>
<div class="col-md-6">
<span class="customFilterMainSpan btn-group">
&nbsp;
</span>
</div>
<div class="col-md-3">
<?php $_smarty_tpl->tpl_vars['RECORD_COUNT'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES_COUNT']->value, null, 0);?>
<?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("Pagination.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array('SHOWPAGEJUMP'=>true), 0);?>
</div>
</div>
</div><?php }} ?>

View File

@@ -0,0 +1,32 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:22
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/IndexViewPreProcess.tpl" */ ?>
<?php /*%%SmartyHeaderCode:798650806692477b6d42ba7-44323223%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'8cbd308a91e69d8f3e5e0eab634bacbd4260098c' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/IndexViewPreProcess.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '798650806692477b6d42ba7-44323223',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
'VIEW' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477b6d7470',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477b6d7470')) {function content_692477b6d7470($_smarty_tpl) {?>
<?php echo $_smarty_tpl->getSubTemplate ("modules/Vtiger/partials/Topbar.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<div class="container-fluid app-nav"><div class="row"><?php echo $_smarty_tpl->getSubTemplate ("modules/ITS4YouReports/partials/SidebarHeader.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ModuleHeader.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div></div></nav><script type="text/javascript">jQuery(document).ready(function() { window._PAGEREADYAT = new Date(); });</script><div class="clearfix main-container"><div><div class="editViewPageDiv viewContent"><?php if ('Edit'!=$_smarty_tpl->tpl_vars['VIEW']->value&&'EditKeyMetricsRow'!=$_smarty_tpl->tpl_vars['VIEW']->value){?><div class="reports-content-area"> <?php }?>
<?php }} ?>

View File

@@ -0,0 +1,167 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:14
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ListViewContents.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1789866997692477aeb96c38-88279195%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'9bfb75194198e58fb7cb8c5a673a0ece558867f8' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ListViewContents.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1789866997692477aeb96c38-88279195',
'function' =>
array (
),
'variables' =>
array (
'CURRENT_USER_MODEL' => 0,
'LEFTPANELHIDE' => 0,
'VIEW' => 0,
'VIEWID' => 0,
'PAGING_MODEL' => 0,
'OPERATOR' => 0,
'LISTVIEW_COUNT' => 0,
'PAGE_NUMBER' => 0,
'LISTVIEW_ENTRIES_COUNT' => 0,
'SEARCH_DETAILS' => 0,
'NO_SEARCH_PARAMS_CACHE' => 0,
'ORDER_BY' => 0,
'SORT_ORDER' => 0,
'LIST_HEADER_FIELDS' => 0,
'CURRENT_TAG' => 0,
'FOLDER_ID' => 0,
'FOLDER_VALUE' => 0,
'VIEWNAME' => 0,
'SEARCH_MODE_RESULTS' => 0,
'MODULE' => 0,
'LISTVIEW_HEADERS' => 0,
'COLUMN_NAME' => 0,
'LISTVIEW_HEADER_KEY' => 0,
'NEXT_SORT_ORDER' => 0,
'FASORT_IMAGE' => 0,
'LISTVIEW_HEADER' => 0,
'MODULE_MODEL' => 0,
'DATA_TYPE' => 0,
'FIELD_INFO' => 0,
'PICKLIST_VALUES' => 0,
'PICKLIST_ARR' => 0,
'PICKLIST_KEY' => 0,
'SEARCH_VALUES' => 0,
'ICON_CLASS' => 0,
'PICKLIST_LABEL' => 0,
'LISTVIEW_ENTRIES' => 0,
'LISTVIEW_ENTRY' => 0,
'LISTVIEW_HEADERNAME' => 0,
'LISTVIEW_ENTRY_RAWVALUE' => 0,
'LISTVIEW_ENTRY_VALUE' => 0,
'COLSPAN_WIDTH' => 0,
'IS_MODULE_EDITABLE' => 0,
'LIST_VIEW_MODEL' => 0,
'SINGLE_MODULE' => 0,
'VERSION' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477aebcae2',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477aebcae2')) {function content_692477aebcae2($_smarty_tpl) {?>
<div class="col-sm-12 col-xs-12 "><?php $_smarty_tpl->tpl_vars['LEFTPANELHIDE'] = new Smarty_variable($_smarty_tpl->tpl_vars['CURRENT_USER_MODEL']->value->get('leftpanelhide'), null, 0);?><div class="essentials-toggle" title="<?php echo vtranslate('LBL_LEFT_PANEL_SHOW_HIDE','Vtiger');?>
"><span class="essentials-toggle-marker fa <?php if ($_smarty_tpl->tpl_vars['LEFTPANELHIDE']->value=='1'){?>fa-chevron-right<?php }else{ ?>fa-chevron-left<?php }?> cursorPointer"></span></div><input type="hidden" name="view" id="view" value="<?php echo $_smarty_tpl->tpl_vars['VIEW']->value;?>
" /><input type="hidden" name="cvid" value="<?php echo $_smarty_tpl->tpl_vars['VIEWID']->value;?>
" /><input type="hidden" name="pageStartRange" id="pageStartRange" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->getRecordStartRange();?>
" /><input type="hidden" name="pageEndRange" id="pageEndRange" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->getRecordEndRange();?>
" /><input type="hidden" name="previousPageExist" id="previousPageExist" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->isPrevPageExists();?>
" /><input type="hidden" name="nextPageExist" id="nextPageExist" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->isNextPageExists();?>
" /><input type="hidden" name="Operator" id="Operator" value="<?php echo $_smarty_tpl->tpl_vars['OPERATOR']->value;?>
" /><input type="hidden" name="totalCount" id="totalCount" value="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_COUNT']->value;?>
" /><input type='hidden' name="pageNumber" value="<?php echo $_smarty_tpl->tpl_vars['PAGE_NUMBER']->value;?>
" id='pageNumber'><input type='hidden' name="pageLimit" value="<?php echo $_smarty_tpl->tpl_vars['PAGING_MODEL']->value->getPageLimit();?>
" id='pageLimit'><input type="hidden" name="noOfEntries" value="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES_COUNT']->value;?>
" id="noOfEntries"><input type="hidden" name="currentSearchParams" value="<?php echo Vtiger_Util_Helper::toSafeHTML(Zend_JSON::encode($_smarty_tpl->tpl_vars['SEARCH_DETAILS']->value));?>
" id="currentSearchParams" /><input type="hidden" name="noFilterCache" value="<?php echo $_smarty_tpl->tpl_vars['NO_SEARCH_PARAMS_CACHE']->value;?>
" id="noFilterCache" ><input type="hidden" name="orderBy" value="<?php echo $_smarty_tpl->tpl_vars['ORDER_BY']->value;?>
" id="orderBy"><input type="hidden" name="sortOrder" value="<?php echo $_smarty_tpl->tpl_vars['SORT_ORDER']->value;?>
" id="sortOrder"><input type="hidden" name="list_headers" value='<?php echo $_smarty_tpl->tpl_vars['LIST_HEADER_FIELDS']->value;?>
'/><input type="hidden" name="tag" value="<?php echo $_smarty_tpl->tpl_vars['CURRENT_TAG']->value;?>
" /><input type="hidden" name="folder_id" value="<?php echo $_smarty_tpl->tpl_vars['FOLDER_ID']->value;?>
" /><input type="hidden" name="folder_value" value="<?php echo $_smarty_tpl->tpl_vars['FOLDER_VALUE']->value;?>
" /><input type="hidden" name="folder" value="<?php echo $_smarty_tpl->tpl_vars['VIEWNAME']->value;?>
" /><?php if (!$_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ListViewActions.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php }?><div id="table-content" class="table-container"><table id="listview-table" class="table <?php if ($_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES_COUNT']->value=='0'){?>listview-table-norecords <?php }?> listview-table"><thead><tr class="listViewContentHeader"><th><?php if (!$_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><div class="table-actions"><div class="dropdown" style="float:left;margin-left:6px;"><span class="input dropdown-toggle" title="<?php echo vtranslate('LBL_CLICK_HERE_TO_SELECT_ALL_RECORDS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" data-toggle="dropdown"><input class="listViewEntriesMainCheckBox" type="checkbox"></span></div></div><?php }elseif($_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><?php echo vtranslate('LBL_ACTIONS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?></th><?php $_smarty_tpl->tpl_vars['LISTVIEW_HEADER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = false;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key => $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = true;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value = $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key;
?><th <?php if ($_smarty_tpl->tpl_vars['COLUMN_NAME']->value==$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value){?> nowrap="nowrap" <?php }?>><a href="#" class="listViewContentHeaderValues" data-nextsortorderval="<?php if ($_smarty_tpl->tpl_vars['COLUMN_NAME']->value==$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value){?><?php echo $_smarty_tpl->tpl_vars['NEXT_SORT_ORDER']->value;?>
<?php }else{ ?>ASC<?php }?>" data-columnname="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value;?>
"><?php if ($_smarty_tpl->tpl_vars['COLUMN_NAME']->value==$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value){?><i class="fa fa-sort <?php echo $_smarty_tpl->tpl_vars['FASORT_IMAGE']->value;?>
"></i><?php }else{ ?><i class="fa fa-sort customsort"></i><?php }?>&nbsp;<?php ob_start();?><?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value['name'];?>
<?php $_tmp1=ob_get_clean();?><?php echo vtranslate($_tmp1,$_smarty_tpl->tpl_vars['MODULE']->value);?>
&nbsp;</a><?php if ($_smarty_tpl->tpl_vars['COLUMN_NAME']->value==$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value){?><a href="#" class="removeSorting"><i class="fa fa-remove"></i></a><?php }?></th><?php } ?></tr><?php if ($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->isQuickSearchEnabled()&&!$_smarty_tpl->tpl_vars['SEARCH_MODE_RESULTS']->value){?><tr class="searchRow"><th class="inline-search-btn"><div class="table-actions"><button class="btn btn-success btn-sm" data-trigger="listSearch"><?php echo vtranslate("LBL_SEARCH",$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button></div></th><?php $_smarty_tpl->tpl_vars['LISTVIEW_HEADER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = false;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key => $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = true;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value = $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key;
?><th><?php $_smarty_tpl->tpl_vars["DATA_TYPE"] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value['type'], null, 0);?><?php if ($_smarty_tpl->tpl_vars['DATA_TYPE']->value=='text'){?><div class="row-fluid"><input type="text" name="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value;?>
" class="listSearchContributor inputElement" value="<?php echo $_smarty_tpl->tpl_vars['SEARCH_DETAILS']->value[$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value]['searchValue'];?>
" data-fieldinfo='<?php echo htmlspecialchars($_smarty_tpl->tpl_vars['FIELD_INFO']->value, ENT_QUOTES, 'UTF-8', true);?>
'/></div><?php }elseif($_smarty_tpl->tpl_vars['DATA_TYPE']->value=='picklist'||$_smarty_tpl->tpl_vars['DATA_TYPE']->value=='user'){?><?php $_smarty_tpl->tpl_vars['PICKLIST_VALUES'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value['picklistValues'], null, 0);?><?php $_smarty_tpl->tpl_vars['SEARCH_VALUES'] = new Smarty_variable(explode(',',$_smarty_tpl->tpl_vars['SEARCH_DETAILS']->value[$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value]['searchValue']), null, 0);?><div class="row-fluid"><select class="select2 listSearchContributor report-type-select" name="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value;?>
" multiple data-fieldinfo='<?php echo htmlspecialchars($_smarty_tpl->tpl_vars['FIELD_INFO']->value, ENT_QUOTES, 'UTF-8', true);?>
'><?php $_smarty_tpl->tpl_vars['PICKLIST_ARR'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['PICKLIST_ARR']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['PICKLIST_VALUES']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['PICKLIST_ARR']->key => $_smarty_tpl->tpl_vars['PICKLIST_ARR']->value){
$_smarty_tpl->tpl_vars['PICKLIST_ARR']->_loop = true;
?><?php if ($_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value==='reporttype'){?><?php $_smarty_tpl->tpl_vars["PICKLIST_LABEL"] = new Smarty_variable(vtranslate($_smarty_tpl->tpl_vars['PICKLIST_ARR']->value['1'],$_smarty_tpl->tpl_vars['MODULE']->value), null, 0);?><?php }else{ ?><?php $_smarty_tpl->tpl_vars["PICKLIST_LABEL"] = new Smarty_variable($_smarty_tpl->tpl_vars['PICKLIST_ARR']->value['1'], null, 0);?><?php }?><?php $_smarty_tpl->tpl_vars["PICKLIST_KEY"] = new Smarty_variable($_smarty_tpl->tpl_vars['PICKLIST_ARR']->value['0'], null, 0);?><option value="<?php echo $_smarty_tpl->tpl_vars['PICKLIST_KEY']->value;?>
" <?php if (in_array($_smarty_tpl->tpl_vars['PICKLIST_KEY']->value,$_smarty_tpl->tpl_vars['SEARCH_VALUES']->value)&&($_smarty_tpl->tpl_vars['PICKLIST_KEY']->value!='')){?> selected<?php }?> <?php if ($_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value=='reporttype'){?>class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
'<?php }?>><?php echo $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value;?>
</option><?php } ?></select></div><?php }?><input type="hidden" class="operatorValue" value="<?php echo $_smarty_tpl->tpl_vars['SEARCH_DETAILS']->value[$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value]['comparator'];?>
"></th><?php } ?></tr><?php }?></thead><tbody class="overflow-y"><?php $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
$_smarty_tpl->tpl_vars['smarty']->value['foreach']['listview']['index']=-1;
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->key => $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->_loop = true;
$_smarty_tpl->tpl_vars['smarty']->value['foreach']['listview']['index']++;
?><tr class="listViewEntries" data-id='<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->get("reportid");?>
' data-recordUrl='<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getDetailViewUrl();?>
' id="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_row_<?php echo $_smarty_tpl->getVariable('smarty')->value['foreach']['listview']['index']+1;?>
"><td class = "listViewRecordActions"><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ListViewRecordActions.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</td><?php $_smarty_tpl->tpl_vars['LISTVIEW_HEADER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = false;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key => $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->_loop = true;
$_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value = $_smarty_tpl->tpl_vars['LISTVIEW_HEADER']->key;
?><?php $_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value, null, 0);?><?php $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_RAWVALUE'] = new Smarty_variable('', null, 0);?><?php if (!empty($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->rawData)){?><?php $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_RAWVALUE'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getRaw($_smarty_tpl->tpl_vars['LISTVIEW_HEADER_KEY']->value), null, 0);?><?php }?><?php $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE'] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->get($_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value), null, 0);?><td class="listViewEntryValue" data-name="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value;?>
" title="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_RAWVALUE']->value;?>
" data-rawvalue="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_RAWVALUE']->value;?>
" data-field-type=""><span class="fieldValue"><span class="value textOverflowEllipsis"><?php if ($_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value=='reportname'){?><a href="<?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY']->value->getDetailViewUrl();?>
"><?php echo $_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value;?>
</a><?php }elseif($_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value=='tablabel'){?><?php echo Vtiger_Util_Helper::tosafeHTML(decode_html(vtranslate($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value,$_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value)));?>
<?php }elseif($_smarty_tpl->tpl_vars['LISTVIEW_HEADERNAME']->value=='foldername'){?><?php echo Vtiger_Util_Helper::tosafeHTML(vtranslate($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value,$_smarty_tpl->tpl_vars['MODULE']->value));?>
<?php }else{ ?><?php echo decode_html($_smarty_tpl->tpl_vars['LISTVIEW_ENTRY_VALUE']->value);?>
<?php }?></span></span></span></td><?php } ?></tr><?php } ?><?php if ($_smarty_tpl->tpl_vars['LISTVIEW_ENTRIES_COUNT']->value=='0'){?><tr class="emptyRecordsDiv"><?php ob_start();?><?php echo ITS4YouReports_Functions_Helper::count($_smarty_tpl->tpl_vars['LISTVIEW_HEADERS']->value);?>
<?php $_tmp2=ob_get_clean();?><?php $_smarty_tpl->tpl_vars['COLSPAN_WIDTH'] = new Smarty_variable($_tmp2+1, null, 0);?><td colspan="<?php echo $_smarty_tpl->tpl_vars['COLSPAN_WIDTH']->value;?>
"><div class="emptyRecordsDiv"><div class="emptyRecordsContent"><?php $_smarty_tpl->tpl_vars['SINGLE_MODULE'] = new Smarty_variable("SINGLE_".($_smarty_tpl->tpl_vars['MODULE']->value), null, 0);?><?php echo vtranslate('LBL_NO');?>
<?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php echo vtranslate('LBL_FOUND');?>
.<?php if ($_smarty_tpl->tpl_vars['IS_MODULE_EDITABLE']->value){?> <a href="<?php echo $_smarty_tpl->tpl_vars['MODULE_MODEL']->value->getCreateRecordUrl();?>
"> <?php echo vtranslate('LBL_CREATE');?>
</a> <?php if (Users_Privileges_Model::isPermitted($_smarty_tpl->tpl_vars['MODULE']->value,'Import')&&$_smarty_tpl->tpl_vars['LIST_VIEW_MODEL']->value->isImportEnabled()){?> <?php echo vtranslate('LBL_OR',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<a style="color:blue" href="#" onclick="return Vtiger_Import_Js.triggerImportAction()"> <?php echo vtranslate('LBL_IMPORT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a><?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }else{ ?><?php echo vtranslate($_smarty_tpl->tpl_vars['SINGLE_MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?><?php }?></div></div></td></tr><?php }?></tbody></table></div><div id="scroller_wrapper" class="bottom-fixed-scroll"><div id="scroller" class="scroller-div"></div></div></div><br><div align="center" class="small" style="color: rgb(153, 153, 153);"><?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php echo $_smarty_tpl->tpl_vars['VERSION']->value;?>
<?php echo vtranslate("COPYRIGHT",$_smarty_tpl->tpl_vars['MODULE']->value);?>
</div>
<?php }} ?>

View File

@@ -0,0 +1,56 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:06
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/partials/SidebarEssentials.tpl" */ ?>
<?php /*%%SmartyHeaderCode:2050673226692477a65e2bd6-28764319%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'bed1a1c7f85af91bed96d6e430681010d61c990f' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/partials/SidebarEssentials.tpl',
1 => 1711810495,
2 => 'file',
),
),
'nocache_hash' => '2050673226692477a65e2bd6-28764319',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
'FOLDERS' => 0,
'FOLDER' => 0,
'VIEWNAME' => 0,
'FOLDERID' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477a65f31f',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477a65f31f')) {function content_692477a65f31f($_smarty_tpl) {?>
<div class="sidebar-menu sidebar-menu-full"><div class="module-filters" id="module-filters"><div class="sidebar-container lists-menu-container"><div class="sidebar-header clearfix"><h5 class="pull-left"><?php echo vtranslate('LBL_FOLDERS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</h5><button id="createFilter" onclick='Reports_List_Js.triggerAddFolder("index.php?module=Reports&view=EditFolder");' class="btn btn-default pull-right sidebar-btn" title="<?php echo vtranslate('LBL_ADD_NEW_FOLDER',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"><div class="fa fa-plus" aria-hidden="true"></div></button></div><hr><div><input class="search-list" type="text" placeholder="<?php echo vtranslate('LBL_SEARCH_FOR_FOLDERS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"></div><div class="menu-scroller mCustomScrollBox" data-mcs-theme="dark"><div class="mCustomScrollBox mCS-light-2 mCSB_inside" tabindex="0"><div class="mCSB_container" style="position:relative; top:0; left:0;"><div class="list-menu-content"><div class="list-group"><ul class="lists-menu"><li style="font-size:12px;" class="listViewFilter" ><a href="#" class='filterName' data-filter-id="All"><i class="fa fa-folder foldericon"></i>&nbsp;<?php echo vtranslate('LBL_ALL_REPORTS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php $_smarty_tpl->tpl_vars['FOLDER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['FOLDER']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['FOLDERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
$_smarty_tpl->tpl_vars['smarty']->value['foreach']["folderview"]['iteration']=0;
foreach ($_from as $_smarty_tpl->tpl_vars['FOLDER']->key => $_smarty_tpl->tpl_vars['FOLDER']->value){
$_smarty_tpl->tpl_vars['FOLDER']->_loop = true;
$_smarty_tpl->tpl_vars['smarty']->value['foreach']["folderview"]['iteration']++;
?><li style="font-size:12px;" class="listViewFilter <?php if ($_smarty_tpl->getVariable('smarty')->value['foreach']['folderview']['iteration']>5){?> filterHidden hide<?php }?>" ><?php ob_start();?><?php echo vtranslate($_smarty_tpl->tpl_vars['FOLDER']->value->getName(),$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php $_tmp1=ob_get_clean();?><?php $_smarty_tpl->tpl_vars['VIEWNAME'] = new Smarty_variable($_tmp1, null, 0);?><a href="#" class='filterName' data-filter-id=<?php echo $_smarty_tpl->tpl_vars['FOLDER']->value->getId();?>
><i class="fa fa-folder foldericon"></i>&nbsp;<?php ob_start();?><?php echo mb_strlen($_smarty_tpl->tpl_vars['VIEWNAME']->value)>50;?>
<?php $_tmp2=ob_get_clean();?><?php if ($_tmp2){?><?php echo mb_substr($_smarty_tpl->tpl_vars['VIEWNAME']->value,0,45);?>
..<?php }else{ ?><?php echo $_smarty_tpl->tpl_vars['VIEWNAME']->value;?>
<?php }?></a><div class="pull-right"><?php $_smarty_tpl->tpl_vars["FOLDERID"] = new Smarty_variable($_smarty_tpl->tpl_vars['FOLDER']->value->get('folderid'), null, 0);?><span class="js-popover-container"><span class="fa fa-angle-down" data-id="<?php echo $_smarty_tpl->tpl_vars['FOLDERID']->value;?>
" data-deletable="true" data-editable="true" rel="popover" data-toggle="popover" data-deleteurl="<?php echo $_smarty_tpl->tpl_vars['FOLDER']->value->getDeleteUrl();?>
" data-editurl="<?php echo $_smarty_tpl->tpl_vars['FOLDER']->value->getEditUrl();?>
" data-toggle="dropdown" aria-expanded="true"></span></span></div></li><?php } ?><li style="font-size:12px;" class="listViewFilter" ><a href="#" class='filterName' data-filter-id="shared"><i class="fa fa-folder foldericon"></i>&nbsp;<?php echo vtranslate('LBL_SHARED_REPORTS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li></ul><div id="filterActionPopoverHtml"><ul class="listmenu hide" role="menu"><li role="presentation" class="editFilter"><a role="menuitem"><i class="fa fa-pencil-square-o"></i>&nbsp;<?php echo vtranslate('LBL_EDIT',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><li role="presentation" class="deleteFilter"><a role="menuitem"><i class="fa fa-trash"></i>&nbsp;<?php echo vtranslate('LBL_DELETE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li></ul></div><h5 class="toggleFilterSize" data-more-text="<?php echo vtranslate('LBL_MORE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
.." data-less-text="<?php echo vtranslate('LBL_LESS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
.."><?php if ($_smarty_tpl->getVariable('smarty')->value['foreach']['folderview']['iteration']>5){?><?php echo vtranslate('LBL_MORE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
..<?php }?></h5></div></div></div></div></div></div></div></div><?php }} ?>

View File

@@ -0,0 +1,779 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:23
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/AdvanceFilter.tpl" */ ?>
<?php /*%%SmartyHeaderCode:700102341692477b760d7f7-57572919%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'c110b0c6441dffe278b3aba09f968d92c82c9291' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/AdvanceFilter.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '700102341692477b760d7f7-57572919',
'function' =>
array (
),
'variables' =>
array (
'current_mk_time' => 0,
'user_date_format' => 0,
'fld_date_options' => 0,
'COLUMNS_BLOCK_JSON' => 0,
'QF_COLUMNS_BLOCK_JSON' => 0,
'USER_DATE_FORMAT' => 0,
'MODULE' => 0,
'FOPTION' => 0,
'REL_FIELDS' => 0,
'JS_DATEFORMAT' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477b763b79',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477b763b79')) {function content_692477b763b79($_smarty_tpl) {?>
<input type="hidden" name="current_mk_time" id="current_mk_time" value='<?php echo $_smarty_tpl->tpl_vars['current_mk_time']->value;?>
'/>
<input type="hidden" name="user_date_format" id="user_date_format" value='<?php echo $_smarty_tpl->tpl_vars['user_date_format']->value;?>
'/>
<input type="hidden" name="fld_date_options" id="fld_date_options" value='<?php echo $_smarty_tpl->tpl_vars['fld_date_options']->value;?>
'/>
<div class="hide" id='filter_columns' ><?php echo $_smarty_tpl->tpl_vars['COLUMNS_BLOCK_JSON']->value;?>
</div>
<div class="hide" id='quick_filter_columns' ><?php echo $_smarty_tpl->tpl_vars['QF_COLUMNS_BLOCK_JSON']->value;?>
</div>
<script>
let none_lang = "<?php echo vtranslate('LBL_NONE');?>
";
let its4youUserDateFormat = "<?php echo $_smarty_tpl->tpl_vars['USER_DATE_FORMAT']->value;?>
";
function addColumnConditionGlue(groupIndex, columnIndex) {
var columnConditionGlueElement = document.getElementById('columnconditionglue_' + columnIndex);
if (groupIndex != "0")
ctype = "f";
else
ctype = "g";
if (columnConditionGlueElement) {
columnConditionGlueElement.innerHTML = "<select name='" + ctype + "con" + columnIndex + "' id='" + ctype + "con" + columnIndex + "' class='select2 inputElement' data-value='value' name='columnname' data-fieldinfo='' style='max-width:87px;'>" +
"<option value='and'><?php echo vtranslate('LBL_AND',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</option>" +
"<option value='or'><?php echo vtranslate('LBL_OR',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</option>" +
"</select>";
jQuery().ready(function () {
var columnConditionGlueElement_obj = jQuery('#fcon' + columnIndex);
if (document.getElementById("hfcon_" + groupIndex + "_" + columnIndex)) {
var fColColumnsObj = jQuery('#fcon' + columnIndex);
if (jQuery('#hfcon_' + groupIndex + '_' + columnIndex)) {
var selected_fcon = jQuery('#hfcon_' + groupIndex + '_' + columnIndex).val();
//jQuery("#"+ctype + "con" + columnIndex).val(selected_fcon);
jQuery("#fcon" + columnIndex).val(selected_fcon);
}
// if(fColColumnsObj.options[i].value == document.getElementById("hfcon_"+groupIndex+"_"+ columnIndex).value){
// fColColumnsObj.options[i].selected=true;
//alert(fColColumnsObj.options[i].value);
//alert(fColColumnsObj.options[i].selected);
// jQuery("#"+ctype + "con" + columnIndex).val(fColColumnsObj.options[i].value);
// }
}
app.changeSelectElementView(columnConditionGlueElement_obj);
});
}
}
function addConditionRow(groupIndex) {
var groupColumns = column_index_array[groupIndex];
if (typeof (groupColumns) != 'undefined') {
for (var i = groupColumns.length - 1; i >= 0; --i) {
var prevColumnIndex = groupColumns[i];
if (document.getElementById('conditioncolumn_' + groupIndex + '_' + prevColumnIndex)) {
addColumnConditionGlue(groupIndex, prevColumnIndex);
break;
}
}
}
if (groupIndex != "0")
var ctype = "f";
else
var ctype = "g";
var columnIndex = advft_column_index_count + 1;
var nextNode = document.getElementById('groupfooter_' + groupIndex);
var newNode = document.createElement('div');
var newNodeId = 'conditioncolumn_' + groupIndex + '_' + columnIndex;
newNode.setAttribute('id', newNodeId);
newNode.setAttribute('name', 'conditionColumn');
newNode.setAttribute('class', 'col-lg-12');
nextNode.parentNode.insertBefore(newNode, nextNode);
var node1 = document.createElement('div');
node1.setAttribute('class', 'col-lg-4');
newNode.appendChild(node1);
if (groupIndex != "0") {
var filtercolumns = jQuery('#filter_columns').html();
filtercolumns = html_entity_decode(filtercolumns, "UTF-8");
var fcon_selectbox = '<select name="' + ctype + 'col' + columnIndex + '" id="' + ctype + 'col' + columnIndex + '" onchange="reports4you_updatefOptions(this, \'' + ctype + 'op' + columnIndex + '\');addRequiredElements(\'' + ctype + '\',' + columnIndex + ');updateRelFieldOptions(this, \'' + ctype + 'val_' + columnIndex + '\');" class="select2 inputElement" data-value="value" name="columnname" data-fieldinfo=""></select>';
node1.innerHTML = '<div class="conditionRow"><div id="condition' + ctype + 'col' + columnIndex + '" >' + fcon_selectbox + '</div>';
var oOption = document.createElement("OPTION");
oOption.value = "";
document.getElementById(ctype + 'col' + columnIndex).appendChild(oOption);
var optgroups = filtercolumns.split("(|@!@|)");
for (i = 0; i < optgroups.length; i++) {
var optgroup = optgroups[i].split("(|@|)");
if (optgroup[0] !== '') {
var oOptgroup = document.createElement("OPTGROUP");
oOptgroup.label = optgroup[0];
var responseVal = JSON.parse(optgroup[1]);
for (var widgetId in responseVal) {
if (responseVal.hasOwnProperty(widgetId)) {
option = responseVal[widgetId];
var oOption = document.createElement("OPTION");
oOption.value = option["value"];
oOption.appendChild(document.createTextNode(option["text"]));
oOptgroup.appendChild(oOption);
}
}
document.getElementById(ctype + 'col' + columnIndex).appendChild(oOptgroup);
}
}
}
else {
var filtercolumns = document.getElementById('SortByColumn').innerHTML;
node1.innerHTML = '<div class="conditionRow"><select name="' + ctype + 'col' + columnIndex + '" id="' + ctype + 'col' + columnIndex + '" onchange="reports4you_updatefOptions(this, \'' + ctype + 'op' + columnIndex + '\');addRequiredElements(\'' + ctype + '\',' + columnIndex + ');updateRelFieldOptions(this, \'' + ctype + 'val_' + columnIndex + '\');" class="detailedViewTextBox">' + filtercolumns + '</select>';
document.getElementById(ctype + 'col' + columnIndex).value = "none";
}
node2 = document.createElement('div');
node2.setAttribute('class', 'col-lg-2');
newNode.appendChild(node2);
node2.innerHTML = '<select name="' + ctype + 'op' + columnIndex + '" id="' + ctype + 'op' + columnIndex + '" class="select2 inputElement" onchange="addRequiredElements(\'' + ctype + '\',' + columnIndex + ');">' +
'<?php echo $_smarty_tpl->tpl_vars['FOPTION']->value;?>
' +
'</select>';
node3 = document.createElement('div');
node3.setAttribute('class', 'col-lg-4');
newNode.appendChild(node3);
var node3_inner = "";
node3_inner += '<div class="layerPopup" id="show_val' + columnIndex + '" name="relFieldsPopupDiv" style="border:2px solid #656565;border:0; position: absolute; width:300px; z-index: 50; display: none;">' +
'<table width="100%" cellspacing="0" cellpadding="0" border="0" align="center" style="padding:5px;border-radius:5px;border:1px solid #ccc;background-color:white;">' +
'<tr>' +
'<td>' +
'<table width="100%" cellspacing="0" cellpadding="0" border="0" class="small">' +
'<tr>' +
'<td>' +
'<table width="100%" cellspacing="0" cellpadding="5" border="0" bgcolor="white" class="small">' +
'<tr>' +
'<td width="30%" align="left" class="cellLabel small"><b><?php echo vtranslate('LBL_SELECT_FIELDS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</b></td>' +
'<td width="30%" align="left" class="cellText">' +
'<select name="' + ctype + 'val_' + columnIndex + '" id="' + ctype + 'val_' + columnIndex + '" onChange="AddFieldToFilter(' + columnIndex + ',this);" class="select2 inputElement" style="margin-top:0.5em;">' +
'<?php echo $_smarty_tpl->tpl_vars['REL_FIELDS']->value;?>
' +
'</select>' +
'</td>' +
'<td width="30%" align="left" class="cellLabel small">' +
'<input type="button" style="width: 70px;margin-top:0.5em;" value="<?php echo vtranslate('LBL_CLOSE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" name="button" onclick="hideAllElementsByName(\'relFieldsPopupDiv\');" class="crmbutton small create" accesskey="X" title="<?php echo vtranslate('LBL_CLOSE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"/>' +
'</td>' +
'</tr>' +
'</table>' +
'</td>' +
'</tr>' +
'</table>' +
'</td>' +
'</tr>' +
'</table>' +
'</div>';
node3.innerHTML = '<span id="node3span' + columnIndex + '_st" style="width:100%;"><input name="' + ctype + 'val' + columnIndex + '" id="' + ctype + 'val' + columnIndex + '" class="inputElement" style="width: 90%;" type="text" value=""><input name="' + ctype + 'valhdn' + columnIndex + '" id="' + ctype + 'valhdn' + columnIndex + '" class="inputElement" style="width: 85%;" type="hidden" value="">&nbsp;<span class="add-on relatedPopup cursorPointer"><i id="node3span' + columnIndex + '_select" class="fa fa-search relatedPopup" onClick="" title="<?php echo vtranslate('LBL_SELECT');?>
"></i></span>&nbsp;<span class="add-on cursorPointer"><i id="node3span' + columnIndex + '_clear" class="fa fa-remove" onClick="ClearFieldToFilter(' + columnIndex + ');" title="<?php echo vtranslate('LBL_CLEAR');?>
"></i></span>' + node3_inner + '</span><span id="node3span' + columnIndex + '_ajx" style="width:100%;display:none;"></span><span id="node3span' + columnIndex + '_djx" style="width:100%;display:none;"></span>';
setRelPopupClick('node3span' + columnIndex + '_select', columnIndex);
node4 = document.createElement('div');
node4.setAttribute('id', 'columnconditionglue_' + columnIndex);
node4.setAttribute('class', 'col-lg-1');
newNode.appendChild(node4);
node5 = document.createElement('div');
node5.setAttribute('class', 'col-lg-1');
newNode.appendChild(node5);
node5.innerHTML = '<a onclick="deleteColumnRow(' + groupIndex + ',' + columnIndex + ');" href="javascript:;" class="deleteCondition">' +
'<img src="modules/ITS4YouReports/img/Delete.png" align="absmiddle" title="<?php echo vtranslate('LBL_DELETE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
..." border="0">' +
'</a></div>';
var fcon_selectbox_obj = jQuery('.filterConditionContainer');
jQuery().ready(function () {
app.changeSelectElementView(fcon_selectbox_obj, 'select2');
ITS4YouReports_Edit_Js.getInstance(newNodeId).registerInputChangeEvents();
addRequiredElements('f', columnIndex);
});
if (typeof (column_index_array[groupIndex]) == 'undefined')
column_index_array[groupIndex] = [];
column_index_array[groupIndex].push(columnIndex);
advft_column_index_count++;
}
function addGroupConditionGlue(groupIndex) {
var groupConditionGlueElement = document.getElementById('groupconditionglue_' + groupIndex);
if (groupConditionGlueElement) {
var gcon_selectbox = '<select name="gpcon' + groupIndex + '" id="gpcon' + groupIndex + '" class="select2 inputElement" data-value="value" name="columnname" data-fieldinfo="">' +
"<option value='and'><?php echo vtranslate('LBL_AND',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</option>" +
"<option value='or'><?php echo vtranslate('LBL_OR',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</option>" + '</select>';
groupConditionGlueElement.innerHTML = '<div id="gconRow' + groupIndex + '" class="col-lg-1">' + gcon_selectbox + '</div>';
var gcon_selectbox_obj = jQuery("#gconRow" + groupIndex);
jQuery().ready(function () {
app.changeSelectElementView(gcon_selectbox_obj);
});
}
}
function addConditionGroup(parentNodeId) {
for (var i = group_index_array.length - 1; i >= 0; --i) {
var prevGroupIndex = group_index_array[i];
if (document.getElementById('conditiongroup_' + prevGroupIndex)) {
addGroupConditionGlue(prevGroupIndex);
break;
}
}
var groupIndex = parseInt(advft_group_index_count) + 1;
var parentNode = document.getElementById(parentNodeId);
var newNode = document.createElement('div');
newNodeId = 'conditiongroup_' + groupIndex;
newNode.setAttribute('id', newNodeId);
newNode.setAttribute('name', 'conditionGroup');
newNode.setAttribute('class', 'conditionGroup conditionFilterDiv');
var deleted_group_btn = '';
if (groupIndex > 1) {
deleted_group_btn = "<button type='button' class='btn btn-default' style='float:right;' onclick='deleteGroup(\"" + groupIndex + "\");' ><i class='fa fa-minus'></i>&nbsp;<?php echo vtranslate('LBL_DELETE_GROUP',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button>";
}
newNode.innerHTML = "<div class='conditionList col-lg-12 conditionRow'>" +
'<div class="addCondition" id="conditiongrouptable_' + groupIndex + '" class="col-lg-12">' +
'<div class="col-lg-4 col-md-4 col-sm-4" id="groupfooter_' + groupIndex + '" style="display:none;">' +
'</div>' +
'</div>' +
'<div id="groupheader_' + groupIndex + '">' +
'<button type="button" class="btn btn-default" style="float:left;" onclick="addConditionRow(\'' + groupIndex + '\')"><i class="fa fa-plus"></i>&nbsp;<?php echo vtranslate("LBL_NEW_CONDITION",$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button>' +
'</div>' +
'<div class="col-lg-1" style="margin-left:10px;">' + deleted_group_btn + '</div>' +
"</div>" +
'<div id="groupconditionglue_' + groupIndex + '" class="conditionList col-lg-12 textAlignCenter conditionRow"></div>';
/*
newNode.innerHTML = "<div class='conditionList'>" +
"<table class='small crmTable' border='0' cellpadding='5' cellspacing='0' width='100%' valign='top' id='conditiongrouptable_" + groupIndex + "' style='border:0px;' >" +
"<tr id='groupfooter_" + groupIndex + "' style='display:none;'>" +
"<td colspan='5' align='left'>" +
"</td>" +
"</tr>" +
"</table>" +
"<table class='small' border='0' cellpadding='5' cellspacing='1' width='100%' valign='top'>" +
"<tr id='groupheader_" + groupIndex + "'>" +
"<td colspan='4' align='left'>" +
"<button type='button' class='btn btn-default' style='float:left;' onclick='addConditionRow(\"" + groupIndex + "\")'><i class='fa fa-plus'></i>&nbsp;<?php echo vtranslate('LBL_NEW_CONDITION',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button>" +
"</td>" +
"<td colspan='1' align='right'>" +
deleted_group_btn+
"</td>" +
"</tr>" +
"<tr><td align='center' id='groupconditionglue_" + groupIndex + "' style='text-align:center;' colspan='5'>" +
"</td></tr>" +
"</table></div>";
*/
parentNode.appendChild(newNode);
group_index_array.push(groupIndex);
advft_group_index_count++;
if (advft_group_index_count > 0) {
jQuery('.fgroup_btn').addClass('hide');
}
}
function addNewConditionGroup(parentNodeId) {
addConditionGroup(parentNodeId);
addConditionRow(advft_group_index_count);
}
function deleteColumnRow(groupIndex, columnIndex) {
removeElement('conditioncolumn_' + groupIndex + '_' + columnIndex);
var groupColumns = column_index_array[groupIndex];
var keyOfTheColumn = groupColumns.indexOf(columnIndex);
var isLastElement = true;
for (var i = keyOfTheColumn; i < groupColumns.length; ++i) {
var nextColumnIndex = groupColumns[i];
var nextColumnRowId = 'conditioncolumn_' + groupIndex + '_' + nextColumnIndex;
if (document.getElementById(nextColumnRowId)) {
isLastElement = false;
break;
}
}
if (isLastElement) {
for (var i = keyOfTheColumn - 1; i >= 0; --i) {
var prevColumnIndex = groupColumns[i];
var prevColumnGlueId = "fcon" + prevColumnIndex;
if (document.getElementById(prevColumnGlueId)) {
removeElement(prevColumnGlueId);
break;
}
}
}
}
function deleteGroup(groupIndex) {
removeElement('conditiongroup_' + groupIndex);
var keyOfTheGroup = group_index_array.indexOf(groupIndex);
var isLastElement = false;
var g_length = group_index_array.length
var g_length_i = g_length;
var hide_gop = false;
for (var i = 0; i < g_length; i++) {
if (!document.getElementById('conditiongroup_' + g_length_i)) {
hide_gop = true;
}
else {
hide_gop = false;
}
g_length_i = g_length_i - 1;
if (hide_gop == true) {
if (g_length_i == (g_length - 1)) {
for (var di = 0; di < g_length; di++) {
if (!document.getElementById('conditiongroup_' + g_length_i)) {
g_length_i = g_length_i - 1;
}
else {
jQuery('#gconRow' + g_length_i).html('');
break;
}
}
}
}
}
}
function removeElement(elementId) {
var element = document.getElementById(elementId);
if (element) {
var parent = element.parentNode;
if (parent) {
parent.removeChild(element);
} else {
element.remove();
}
}
}
function hideAllElementsByName(name) {
var allElements = document.getElementsByTagName('div');
for (var i = 0; i < allElements.length; ++i) {
var element = allElements[i];
if (element.getAttribute('name') == name)
element.style.display = 'none';
}
return true;
}
function addRequiredElements(ctype, columnindex) {
jQuery().ready(function () {
var colObj = document.getElementById(ctype + 'col' + columnindex);
if (colObj) {
var opObj = document.getElementById(ctype + 'op' + columnindex);
var valObj = document.getElementById(ctype + 'val' + columnindex);
var currField = colObj.options[colObj.selectedIndex];
var currOp = opObj.options[opObj.selectedIndex];
var fieldtype = null;
if (currField.value != null && currField.value.length != 0) {
fieldtype = trimfValues(currField.value);
var sel_fields = JSON.parse(document.getElementById("sel_fields").value);
var selected_value = html_entity_decode(colObj.value, "UTF-8");
if (sel_fields[selected_value]) {
updateRelFieldOptions(colObj, 'fval_' + columnindex);
}
switch (fieldtype) {
case 'D':
case 'T':
case 'DT':
var dateformat = "<?php echo $_smarty_tpl->tpl_vars['JS_DATEFORMAT']->value;?>
";
var timeformat = "%H:%M:%S";
var showtime = true;
if ('T' !== fieldtype) {
timeformat = '';
showtime = false;
}
break;
default:
if (document.getElementById('jscal_trigger_fval' + columnindex))
document.getElementById('jscal_trigger_fval' + columnindex).remove();
if (document.getElementById('fval_ext' + columnindex))
document.getElementById('fval_ext' + columnindex).remove();
if (document.getElementById('jscal_trigger_fval_ext' + columnindex))
document.getElementById('jscal_trigger_fval_ext' + columnindex).remove();
}
var comparatorId = ctype + "op" + columnindex;
var comparatorObject = jQuery("#" + comparatorId);
var comparatorValue = comparatorObject.val();
if (comparatorValue == "isn" || comparatorValue == "isnn") {
document.getElementById("node3span" + columnindex + "_ajx").style.display = "none";
document.getElementById("node3span" + columnindex + "_st").style.display = "none";
document.getElementById("node3span" + columnindex + "_djx").style.display = "none";
} else {
document.getElementById("node3span" + columnindex + "_ajx").style.display = "none";
document.getElementById("node3span" + columnindex + "_st").style.display = "block";
document.getElementById("node3span" + columnindex + "_djx").style.display = "none";
}
var std_filter_columns = document.getElementById("std_filter_columns").value;
if (std_filter_columns) {
var std_filter_columns_arr = std_filter_columns.split('<<?php ?>%jsstdjs%<?php ?>>');
var selected_value = html_entity_decode(colObj.value, "UTF-8");
if (-1 < std_filter_columns_arr.indexOf(selected_value)
|| -1 < selected_value.indexOf(':DT:')
|| -1 < selected_value.indexOf(':DT')
|| -1 < selected_value.indexOf(':D:')
) {
if ((document.getElementById("jscal_field_sdate" + columnindex)) && (document.getElementById("jscal_field_edate" + columnindex))) {
var s_obj = document.getElementById("jscal_field_sdate" + columnindex);
var e_obj = document.getElementById("jscal_field_edate" + columnindex);
var st_obj = document.getElementById("jscal_trigger_sdate" + columnindex);
var et_obj = document.getElementById("jscal_trigger_edate" + columnindex);
var seOption_type = currOp.value;
if (comparatorValue == "olderNdays" || comparatorValue == "lastNdays" || comparatorValue == "nextNdays" || comparatorValue == "moreNdays" || comparatorValue == "daysago" || comparatorValue == "daysmore") {
jQuery('#fval' + columnindex).val('');
jQuery('#fvalhdn' + columnindex).val('');
document.getElementById("node3span" + columnindex + "_ajx").style.display = "none";
document.getElementById("node3span" + columnindex + "_st").style.display = "none";
document.getElementById("div_nfval" + columnindex).style.display = "block";
document.getElementById("node3span" + columnindex + "_djx").style.display = "block";
showNdayRange(columnindex);
} else {
document.getElementById("div_nfval" + columnindex).style.display = "none";
showDateRange(s_obj, e_obj, st_obj, et_obj, seOption_type);
if (comparatorValue === "custom" || comparatorValue === "a" || comparatorValue === "b") {
jQuery('#jscal_trigger_sdate'+columnindex).removeClass('hide');
jQuery('#jscal_trigger_edate'+columnindex).removeClass('hide');
vtUtils.registerEventForDateFields(jQuery('.filterContainer'));
}
if (comparatorValue !== "") {
if (comparatorValue === "isn" || comparatorValue === "isnn") {
jQuery('#fval' + columnindex).val('');
jQuery('#fvalhdn' + columnindex).val('');
document.getElementById("node3span" + columnindex + "_ajx").style.display = "none";
document.getElementById("node3span" + columnindex + "_st").style.display = "none";
document.getElementById("node3span" + columnindex + "_djx").style.display = "none";
} else if (jQuery.inArray(comparatorValue, JSON.parse(jQuery('#fld_date_options').val())) > -1) {
document.getElementById("node3span" + columnindex + "_ajx").style.display = "none";
document.getElementById("node3span" + columnindex + "_st").style.display = "block";
document.getElementById("node3span" + columnindex + "_djx").style.display = "none";
} else {
jQuery('#fval' + columnindex).val('');
jQuery('#fvalhdn' + columnindex).val('');
document.getElementById("node3span" + columnindex + "_ajx").style.display = "none";
document.getElementById("node3span" + columnindex + "_st").style.display = "none";
document.getElementById("node3span" + columnindex + "_djx").style.display = "block";
}
}
}
}
}
}
}
}
});
}
function showHideDivs(showdiv, hidediv) {
if (document.getElementById(showdiv))
document.getElementById(showdiv).style.display = "block";
if (document.getElementById(hidediv))
document.getElementById(hidediv).style.display = "none";
}
/**/
function deleteGroupColumnRow(groupIndex, columnIndex) {
removeElement('groupconditioncolumn_' + groupIndex + '_' + columnIndex);
var groupColumns = gf_column_index_array[groupIndex];
var keyOfTheColumn = groupColumns.indexOf(columnIndex);
var isLastElement = true;
for (var i = keyOfTheColumn; i < groupColumns.length; ++i) {
var nextColumnIndex = groupColumns[i];
var nextColumnRowId = 'groupconditioncolumn_' + groupIndex + '_' + nextColumnIndex;
if (document.getElementById(nextColumnRowId)) {
isLastElement = false;
break;
}
}
if (isLastElement) {
for (var di = keyOfTheColumn - 1; di >= 0; --di) {
var prevColumnIndex = groupColumns[di];
var prevColumnGlueId = "ggroupcon" + prevColumnIndex;
if (document.getElementById(prevColumnGlueId)) {
removeElement(prevColumnGlueId);
break;
}
}
}
}
function actualizeGroupConditions(groupIndex) {
var filtercolumns_str = document.getElementById('sum_group_columns').innerHTML;
//' + ctype + 'groupop' + columnIndex + '
}
function addGroupConditionRow(groupIndex) {
var groupColumns = gf_column_index_array[groupIndex];
if (typeof(groupColumns) !== 'undefined') {
for (var i = groupColumns.length - 1; i >= 0; --i) {
var prevColumnIndex = groupColumns[i];
if (document.getElementById('groupconditioncolumn_' + groupIndex + '_' + prevColumnIndex)) {
addGroupColumnConditionGlue(groupIndex, prevColumnIndex);
break;
}
}
}
if (groupIndex !== "0")
ctype = "f";
else
ctype = "g";
var columnIndex = gf_advft_column_index_count + 1;
var nextNode = document.getElementById('ggroupfooter_' + groupIndex);
var newNode = document.createElement('div');
newNodeId = 'groupconditioncolumn_' + groupIndex + '_' + columnIndex;
newNode.setAttribute('id', newNodeId);
newNode.setAttribute('name', 'groupconditionColumn');
newNode.setAttribute('style', 'width:100%;display:block;');
newNode.setAttribute('class', 'col-lg-12 conditionRow');
nextNode.parentNode.insertBefore(newNode, nextNode);
node1 = document.createElement('div');
node1.setAttribute('class', 'col-lg-4');
newNode.appendChild(node1);
node1.innerHTML = '<select name="' + ctype + 'groupcol' + columnIndex + '" id="' + ctype + 'groupcol' + columnIndex + '" onchange="reports4you_updatefOptions(this, \'' + ctype + 'groupcolop' + columnIndex + '\');addRequiredElements(\'' + ctype + '\',' + columnIndex + ');" class="select2 inputElement" ></select>';
document.getElementById(ctype + 'groupcol' + columnIndex).value = "none";
var filtercolumns_str = document.getElementById('sum_group_columns').innerHTML;
var optgroups = filtercolumns_str.split("(|@!@|)");
for (i = 0; i < optgroups.length; i++) {
var optgroup = optgroups[i].split("(|@|)");
if (optgroup[0] !== '' && optgroup[1] !== '') {
var option_value = optgroup[0];
var option_text = optgroup[1];
var oOption = document.createElement("OPTION");
oOption.value = option_value;
oOption.appendChild(document.createTextNode(option_text));
document.getElementById(ctype + 'groupcol' + columnIndex).appendChild(oOption);
}
}
node2 = document.createElement('div');
node2.setAttribute('class', 'col-lg-2');
newNode.appendChild(node2);
node2.innerHTML = '<select name="' + ctype + 'groupop' + columnIndex + '" id="' + ctype + 'groupop' + columnIndex + '" class="select2 inputElement" style="width:100%;" onchange="addRequiredElements(\'' + ctype + '\',' + columnIndex + ');">' +
'<?php echo $_smarty_tpl->tpl_vars['FOPTION']->value;?>
' +
'</select>';
node3 = document.createElement('div');
newNode.appendChild(node3);
node3.innerHTML = '<div class="col-lg-4"><input name="' + ctype + 'groupval' + columnIndex + '" id="' + ctype + 'groupval' + columnIndex + '" class="inputElement" type="text" value="" style="width: 90%;"></div>';
node3.innerHTML += '<div class="layerPopup" id="show_val' + columnIndex + '" name="relFieldsPopupDiv" style="border:0; position: absolute; width:300px; z-index: 50; display: none;">' +
'<table width="100%" cellspacing="0" cellpadding="0" border="0" align="center" class="mailClient mailClientBg">' +
'<tr>' +
'<td>' +
'<table width="100%" cellspacing="0" cellpadding="0" border="0" class="layerHeadingULine">' +
'<tr class="mailSubHeader">' +
'<td width=90% class="genHeaderSmall"><b><?php echo vtranslate('LBL_SELECT_FIELDS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</b></td>' +
'<td align=right>' +
'<img border="0" align="absmiddle" src="layouts/vlayout/skins/images/close.gif" style="cursor: pointer;" alt="<?php echo vtranslate('LBL_CLOSE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" title="<?php echo vtranslate('LBL_CLOSE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" onclick="hideAllElementsByName(\'relFieldsPopupDiv\');"/>' +
'</td>' +
'</tr>' +
'</table>' +
'<table width="100%" cellspacing="0" cellpadding="0" border="0" class="small">' +
'<tr>' +
'<td>' +
'<table width="100%" cellspacing="0" cellpadding="5" border="0" bgcolor="white" class="small">' +
'<tr>' +
'<td width="30%" align="left" class="cellLabel small"><?php echo vtranslate('LBL_RELATED_FIELDS',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</td>' +
'<td width="30%" align="left" class="cellText">' +
'<select name="' + ctype + 'val_' + columnIndex + '" id="' + ctype + 'val_' + columnIndex + '" onChange="AddFieldToFilter(' + columnIndex + ',this);" class="detailedViewTextBox">' +
'<?php echo $_smarty_tpl->tpl_vars['REL_FIELDS']->value;?>
' +
'</select>' +
'</td>' +
'</tr>' +
'</table>' +
'<!-- save cancel buttons -->' +
'<table width="100%" cellspacing="0" cellpadding="5" border="0" class="layerPopupTransport">' +
'<tr>' +
'<td width="50%" align="center">' +
'<input type="button" style="width: 70px;" value="<?php echo vtranslate('LBL_DONE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
" name="button" onclick="hideAllElementsByName(\'relFieldsPopupDiv\');" class="crmbutton small create" accesskey="X" title="<?php echo vtranslate('LBL_DONE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"/>' +
'</td>' +
'</tr>' +
'</table>' +
'</td>' +
'</tr>' +
'</table>' +
'</td>' +
'</tr>' +
'</table>' +
'</div>';
node4 = document.createElement('div');
node4.setAttribute('id', 'groupcolumnconditionglue_' + columnIndex);
node4.setAttribute('width', '87px');
newNode.appendChild(node4);
node5 = document.createElement('div');
node5.setAttribute('class', 'col-lg-1');
newNode.appendChild(node5);
node5.innerHTML = '<a onclick="deleteGroupColumnRow(' + groupIndex + ',' + columnIndex + ');" href="javascript:;">' +
'<img src="modules/ITS4YouReports/img/Delete.png" align="absmiddle" title="<?php echo vtranslate('LBL_DELETE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
..." border="0" >' +
'</a>';
jQuery().ready(function () {
app.changeSelectElementView(jQuery('#step8'), 'select2');
});
if (typeof(gf_column_index_array[groupIndex]) === 'undefined') gf_column_index_array[groupIndex] = [];
gf_column_index_array[groupIndex].push(columnIndex);
gf_advft_column_index_count++;
}
function addGroupColumnConditionGlue(groupIndex, columnIndex) {
var columnConditionGlueElement = document.getElementById('groupcolumnconditionglue_' + columnIndex);
if (groupIndex !== "0")
ctype = "f";
else
ctype = "g";
if (columnConditionGlueElement) {
columnConditionGlueElement.innerHTML = "<select name='" + ctype + "groupcon" + columnIndex + "' id='" + ctype + "groupcon" + columnIndex + "' class='chzn-select chzn-done' style='display:none;width:auto'>" +
"<option value='and'><?php echo vtranslate('LBL_AND',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</option>" +
"<option value='or'><?php echo vtranslate('LBL_OR',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</option>" +
"</select>";
}
}
function addQuickFilterBox() {
var qfColumnsJson = jQuery('#quick_filter_columns').html();
qfColumnsJson = html_entity_decode(qfColumnsJson,"UTF-8");
var qfColumns = JSON.parse(qfColumnsJson);
var filtercolumns = jQuery('#filter_columns').html();
filtercolumns = html_entity_decode(filtercolumns, "UTF-8");
/*
var oOption = document.createElement("OPTION");
oOption.value = "";
oOption.appendChild(document.createTextNode("<?php echo vtranslate('LBL_NONE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"));
document.getElementById('quick_filters').appendChild(oOption);
*/
var aSi = 0;
var alreadySelected = new Array();
var optgroups = filtercolumns.split("(|@!@|)");
for (i = 0; i < optgroups.length; i++) {
var optgroup = optgroups[i].split("(|@|)");
if (optgroup[0] !== '') {
var oOptgroup = document.createElement("OPTGROUP");
oOptgroup.label = optgroup[0];
var responseVal = JSON.parse(optgroup[1]);
for (var widgetId in responseVal) {
if (responseVal.hasOwnProperty(widgetId)) {
option = responseVal[widgetId];
var vOption = document.createElement("OPTION");
vOption.value = option["value"];
if (jQuery.inArray(vOption.value, qfColumns) !== -1 && jQuery.inArray(vOption.value, alreadySelected) === -1) {
vOption.selected = true;
alreadySelected[aSi] = vOption.value;
aSi++;
}
vOption.appendChild(document.createTextNode(option["text"]));
oOptgroup.appendChild(vOption);
}
}
document.getElementById('quick_filters').appendChild(oOptgroup);
}
}
}
</script>
<?php }} ?>

View File

@@ -0,0 +1,64 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:23
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ReportHeader.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1278999366692477b7669181-03385451%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'c1502db5b78e3d7bbcb06e1ad01077830cdd4c73' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/ReportHeader.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1278999366692477b7669181-03385451',
'function' =>
array (
),
'variables' =>
array (
'DATE_FILTERS' => 0,
'REPORT_LIMIT' => 0,
'PDFMakerActive' => 0,
'IS_TEST_WRITE_ABLE' => 0,
'RECORD_ID' => 0,
'REPORT_CHANGED' => 0,
'MODULE' => 0,
'REPORT_MODEL' => 0,
'CRITERIA_GROUPS' => 0,
'filterConditionNotExists' => 0,
'REPORTTYPE' => 0,
'REPORT_FILTERS' => 0,
'checkDashboardWidget' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477b767629',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477b767629')) {function content_692477b767629($_smarty_tpl) {?>
<link rel="stylesheet" type="text/css" media="all" href="modules/ITS4YouReports/classes/Reports4YouDefault.css"><script type="text/javascript" src="modules/ITS4YouReports/highcharts/js/rgbcolor.js"></script><script type="text/javascript" src="modules/ITS4YouReports/highcharts/js/canvg.js"> </script><div class="reportsDetailHeader no-print"><input type="hidden" name="date_filters" data-value='<?php echo Vtiger_Util_Helper::toSafeHTML(ZEND_JSON::encode($_smarty_tpl->tpl_vars['DATE_FILTERS']->value));?>
'/><input type="hidden" id="reportLimit" value="<?php echo $_smarty_tpl->tpl_vars['REPORT_LIMIT']->value;?>
"/><input type="hidden" id="pdfmaker_active" value="<?php echo $_smarty_tpl->tpl_vars['PDFMakerActive']->value;?>
"/><input type="hidden" id="is_test_write_able" value="<?php echo $_smarty_tpl->tpl_vars['IS_TEST_WRITE_ABLE']->value;?>
"/><input type="hidden" id="div_id" value="activate_pdfmaker"/><input type="hidden" name="report_filename" id="report_filename" value="" /><input type="hidden" id="recordId" value="<?php echo $_smarty_tpl->tpl_vars['RECORD_ID']->value;?>
"/><form method="post" action="IndexAjax" target="_blank"><input type="hidden" name="module" value="ITS4YouReports"/><input type="hidden" name="action" value="IndexAjax"/><input type="hidden" name="mode" value="ExportXLS"/><input type="hidden" name="filename" value="Test.xls"/><input type="hidden" name="report_html" id="report_html" value=""/></form><form method="post" action="index.php" name="GeneratePDF" id="GeneratePDF" target="_blank"><input type="hidden" name="module" value="ITS4YouReports"/><input type="hidden" name="action" value="GeneratePDF"/><input type="hidden" name="mode" value="ExportPDF"/><input type="hidden" name="type" value=""/><input type="hidden" name="record" value="<?php echo $_smarty_tpl->tpl_vars['RECORD_ID']->value;?>
"/><input type="hidden" name="backgroundExport" value="" /><input type="hidden" name="form_export_pdf_format" id="form_export_pdf_format" value=""/><input type="hidden" name="form_filename" id="form_filename" value=""/><input type="hidden" name="form_report_name" id="form_report_name" value=""/><input type="hidden" name="form_report_html" id="form_report_html" value=""/><input type="hidden" name="form_report_totals" id="form_report_totals" value=""/><input type="hidden" name="form_chart_canvas" id="form_chart_canvas" value=""/></form><form method="post" action="index.php" name="GenerateXLS" id="GenerateXLS" target="_blank"><input type="hidden" name="module" value="ITS4YouReports"/><input type="hidden" name="view" value="ExportReport"/><input type="hidden" name="mode" value="GetXLS"/><input type="hidden" name="record" value="<?php echo $_smarty_tpl->tpl_vars['RECORD_ID']->value;?>
"/><input type="hidden" name="type" value=""/></form><form method="post" action="index.php" name="PrintReport" id="PrintReport" target="_blank"><input type="hidden" name="module" value="ITS4YouReports"/><input type="hidden" name="action" value="PrintReport"/><input type="hidden" name="mode" value="GetPrintReport"/><input type="hidden" name="type" value=""/><input type="hidden" name="record" value="<?php echo $_smarty_tpl->tpl_vars['RECORD_ID']->value;?>
"/><input type="hidden" name="form_report_name" id="form_report_name" value=""/></form><form id="detailViewReport" onSubmit="" method="post" ><input type="hidden" name="module" value="ITS4YouReports"/><input type="hidden" name="view" value="Detail"/><input type="hidden" id="record" value="<?php echo $_smarty_tpl->tpl_vars['RECORD_ID']->value;?>
"/><input type="hidden" name='reload' id='reload' value='true'/><input type="hidden" name="currentMode" id="currentMode" value='generate' /><input type="hidden" name='report_changed' id='report_changed' value='<?php echo $_smarty_tpl->tpl_vars['REPORT_CHANGED']->value;?>
'/><input type="hidden" name="date_filters" data-value='<?php echo Vtiger_Util_Helper::toSafeHTML(ZEND_JSON::encode($_smarty_tpl->tpl_vars['DATE_FILTERS']->value));?>
'/><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("DetailViewActions.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php if ('custom_report'!=$_smarty_tpl->tpl_vars['REPORT_MODEL']->value->getReportType()){?><br><div class=''><?php $_smarty_tpl->tpl_vars['filterConditionNotExists'] = new Smarty_variable((empty($_smarty_tpl->tpl_vars['CRITERIA_GROUPS']->value)), null, 0);?><button class="btn btn-default" name="modify_condition" data-val="<?php echo $_smarty_tpl->tpl_vars['filterConditionNotExists']->value;?>
"><strong><?php echo vtranslate('LBL_MODIFY_CONDITION',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</strong>&nbsp;&nbsp;<i class="fa <?php if ($_smarty_tpl->tpl_vars['filterConditionNotExists']->value==true){?> fa-chevron-right <?php }else{ ?> fa-chevron-down <?php }?>"></i></button></div><br><div class="row-fluid"><input type="hidden" id="widgetReports4YouId" value="<?php echo $_smarty_tpl->tpl_vars['RECORD_ID']->value;?>
"/><?php if ($_smarty_tpl->tpl_vars['REPORTTYPE']->value!=="custom_report"){?><div id="filterContainer" class="filterContainer filterElements well filterConditionContainer filterConditionsDiv <?php if (empty($_smarty_tpl->tpl_vars['CRITERIA_GROUPS']->value)==true){?> hide <?php }?>"><?php echo $_smarty_tpl->tpl_vars['REPORT_FILTERS']->value;?>
</div><?php }?></div><br><?php }?><div class="row-fluid"><div class="textAlignCenter"><button class="btn btn-default generateReport" data-mode="generate" value="<?php echo vtranslate('LBL_GENERATE_NOW',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"/><strong><?php echo vtranslate('LBL_GENERATE_NOW',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</strong></button>&nbsp;<?php if ($_smarty_tpl->tpl_vars['REPORTTYPE']->value!="custom_report"&&$_smarty_tpl->tpl_vars['REPORT_MODEL']->value->isEditable()==true){?><button class="btn btn-success generateReport hide" id="saveReportBtn" data-mode="save" value="<?php echo vtranslate('LBL_SAVE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"/><strong><?php echo vtranslate('LBL_SAVE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</strong></button><?php }?><?php if ($_smarty_tpl->tpl_vars['checkDashboardWidget']->value!=''&&$_smarty_tpl->tpl_vars['checkDashboardWidget']->value!="Exist"){?><button class="btn addWidget" data-mode="addwidget" value="<?php echo vtranslate('LBL_ADD_WIDGET',$_smarty_tpl->tpl_vars['MODULE']->value);?>
"/><strong><?php echo vtranslate('LBL_ADD_WIDGET',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</strong></button><?php }?></div></div><br></form></div><div id="reportContentsDiv" style="padding-bottom:2em;">
<?php }} ?>

View File

@@ -0,0 +1,47 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 10:04:12
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Calendar/uitypes/StatusPickListFieldSearchView.tpl" */ ?>
<?php /*%%SmartyHeaderCode:8417322536924036c08b948-70005047%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'c95e8384f0bbfe66870957dfc0e785cb930f3c66' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Calendar/uitypes/StatusPickListFieldSearchView.tpl',
1 => 1711810495,
2 => 'file',
),
),
'nocache_hash' => '8417322536924036c08b948-70005047',
'function' =>
array (
),
'variables' =>
array (
'FIELD_MODEL' => 0,
'FIELD_INFO' => 0,
'EVENTS_MODULE_MODEL' => 0,
'EVENT_STATUS_FIELD_MODEL' => 0,
'PICKLIST_VALUES' => 0,
'EVENT_STAUTS_PICKLIST_VALUES' => 0,
'SEARCH_INFO' => 0,
'PICKLIST_KEY' => 0,
'SEARCH_VALUES' => 0,
'PICKLIST_LABEL' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_6924036c0c5ac',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_6924036c0c5ac')) {function content_6924036c0c5ac($_smarty_tpl) {?>
<?php $_smarty_tpl->tpl_vars['FIELD_INFO'] = new Smarty_variable($_smarty_tpl->tpl_vars['FIELD_MODEL']->value->getFieldInfo(), null, 0);?><?php $_smarty_tpl->tpl_vars['PICKLIST_VALUES'] = new Smarty_variable($_smarty_tpl->tpl_vars['FIELD_INFO']->value['picklistvalues'], null, 0);?><?php $_smarty_tpl->tpl_vars['FIELD_INFO'] = new Smarty_variable(Vtiger_Util_Helper::toSafeHTML(Zend_Json::encode($_smarty_tpl->tpl_vars['FIELD_INFO']->value)), null, 0);?><?php $_smarty_tpl->tpl_vars['EVENTS_MODULE_MODEL'] = new Smarty_variable(Vtiger_Module_Model::getInstance('Events'), null, 0);?><?php $_smarty_tpl->tpl_vars['EVENT_STATUS_FIELD_MODEL'] = new Smarty_variable($_smarty_tpl->tpl_vars['EVENTS_MODULE_MODEL']->value->getField('eventstatus'), null, 0);?><?php $_smarty_tpl->tpl_vars['EVENT_STAUTS_PICKLIST_VALUES'] = new Smarty_variable($_smarty_tpl->tpl_vars['EVENT_STATUS_FIELD_MODEL']->value->getPicklistValues(), null, 0);?><?php $_smarty_tpl->tpl_vars['PICKLIST_VALUES'] = new Smarty_variable(array_merge($_smarty_tpl->tpl_vars['PICKLIST_VALUES']->value,$_smarty_tpl->tpl_vars['EVENT_STAUTS_PICKLIST_VALUES']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['SEARCH_VALUES'] = new Smarty_variable(explode(',',$_smarty_tpl->tpl_vars['SEARCH_INFO']->value['searchValue']), null, 0);?><div class="select2_search_div"><input type="text" class="listSearchContributor inputElement select2_input_element"/><select class="select2 listSearchContributor" name="<?php echo $_smarty_tpl->tpl_vars['FIELD_MODEL']->value->get('name');?>
" multiple data-fieldinfo='<?php echo htmlspecialchars($_smarty_tpl->tpl_vars['FIELD_INFO']->value, ENT_QUOTES, 'UTF-8', true);?>
' style="display:none"><?php $_smarty_tpl->tpl_vars['PICKLIST_LABEL'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->_loop = false;
$_smarty_tpl->tpl_vars['PICKLIST_KEY'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['PICKLIST_VALUES']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->key => $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value){
$_smarty_tpl->tpl_vars['PICKLIST_LABEL']->_loop = true;
$_smarty_tpl->tpl_vars['PICKLIST_KEY']->value = $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->key;
?><option value="<?php echo $_smarty_tpl->tpl_vars['PICKLIST_KEY']->value;?>
" <?php if (in_array($_smarty_tpl->tpl_vars['PICKLIST_KEY']->value,$_smarty_tpl->tpl_vars['SEARCH_VALUES']->value)){?> selected<?php }?>><?php echo $_smarty_tpl->tpl_vars['PICKLIST_LABEL']->value;?>
</option><?php } ?></select></div><?php }} ?>

View File

@@ -0,0 +1,25 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:06
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewPostProcess.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1239741255692477a66bb692-49233046%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'd7170b29735ec543e04ccfd484d0bafae451ca28' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ListViewPostProcess.tpl',
1 => 1711810494,
2 => 'file',
),
),
'nocache_hash' => '1239741255692477a66bb692-49233046',
'function' =>
array (
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477a66bbee',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477a66bbee')) {function content_692477a66bbee($_smarty_tpl) {?>
</div>
</div>
<?php }} ?>

View File

@@ -0,0 +1,44 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 12:37:54
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Vtiger/MassEditForm.tpl" */ ?>
<?php /*%%SmartyHeaderCode:173642876369242772ea5557-22337899%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'e030303313349f80c40cef7474b1de9568183305' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Vtiger/MassEditForm.tpl',
1 => 1711810494,
2 => 'file',
),
),
'nocache_hash' => '173642876369242772ea5557-22337899',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
'CVID' => 0,
'SELECTED_IDS' => 0,
'EXCLUDED_IDS' => 0,
'TAG_PARAMS' => 0,
'SEARCH_PARAMS' => 0,
'TITLE' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_69242772ed917',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_69242772ed917')) {function content_69242772ed917($_smarty_tpl) {?>
<div id="massEditContainer" class='fc-overlay-modal modal-content'><form class="form-horizontal" id="massEdit" name="MassEdit" method="post" action="index.php"><input type="hidden" name="module" value="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
" /><input type="hidden" name="action" value="MassSave" /><input type="hidden" name="viewname" value="<?php echo $_smarty_tpl->tpl_vars['CVID']->value;?>
" /><input type="hidden" name="selected_ids" value=<?php echo ZEND_JSON::encode($_smarty_tpl->tpl_vars['SELECTED_IDS']->value);?>
><input type="hidden" name="excluded_ids" value=<?php echo ZEND_JSON::encode($_smarty_tpl->tpl_vars['EXCLUDED_IDS']->value);?>
><input type="hidden" name="tag_params" value=<?php echo ZEND_JSON::encode($_smarty_tpl->tpl_vars['TAG_PARAMS']->value);?>
><input type="hidden" name="search_params" value='<?php echo Vtiger_Util_Helper::toSafeHTML(ZEND_JSON::encode($_smarty_tpl->tpl_vars['SEARCH_PARAMS']->value));?>
' /><div><header class="overlayHeader" style='flex:0 0 auto;'><?php ob_start();?><?php echo vtranslate('LBL_MASS_EDITING',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php $_tmp1=ob_get_clean();?><?php $_smarty_tpl->tpl_vars['TITLE'] = new Smarty_variable($_tmp1, null, 0);?><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("ModalHeader.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array('TITLE'=>$_smarty_tpl->tpl_vars['TITLE']->value), 0);?>
</header><div class='modal-body' style="margin-bottom:60px"><div class='datacontent editViewContents'><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("partials/EditViewContents.tpl",$_smarty_tpl->tpl_vars['MODULE']->value), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
</div></div><footer class='modal-footer overlayFooter'><center><button type='submit' class='btn btn-success saveButton'><?php echo vtranslate('LBL_SAVE',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</button>&nbsp;&nbsp;<a class='cancelLink' data-dismiss="modal" href="#"><?php echo vtranslate('LBL_CANCEL',$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></center></footer></div></form></div><?php }} ?>

View File

@@ -0,0 +1,28 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:14
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/Footer.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1220053640692477aec01485-22614471%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'f0b5173dc913424ef95a34af0a64bb6adaad9918' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/ITS4YouReports/Footer.tpl',
1 => 1711810496,
2 => 'file',
),
),
'nocache_hash' => '1220053640692477aec01485-22614471',
'function' =>
array (
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477aec03e7',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477aec03e7')) {function content_692477aec03e7($_smarty_tpl) {?>
<br><div class="small" style="color: rgb(153, 153, 153);text-align: center;"><?php echo vtranslate('ITS4YouReports','ITS4YouReports');?>
<?php echo ITS4YouReports_Version_Helper::$version;?>
<?php echo vtranslate('COPYRIGHT','ITS4YouReports');?>
</div><?php echo $_smarty_tpl->getSubTemplate (vtemplate_path("Footer.tpl",'Vtiger'), $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, null, null, array(), 0);?>
<?php }} ?>

View File

@@ -0,0 +1,74 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-24 18:20:06
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ModuleHeader.tpl" */ ?>
<?php /*%%SmartyHeaderCode:668099220692477a65b2725-63408611%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'fbe8cd3b3a31cf071741e629233295f118c71f12' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Reports/ModuleHeader.tpl',
1 => 1711810495,
2 => 'file',
),
),
'nocache_hash' => '668099220692477a65b2725-63408611',
'function' =>
array (
),
'variables' =>
array (
'MODULE' => 0,
'MODULE_MODEL' => 0,
'DEFAULT_FILTER_ID' => 0,
'CVURL' => 0,
'DEFAULT_FILTER_URL' => 0,
'VIEW' => 0,
'REPORT_NAME' => 0,
'VIEWNAME' => 0,
'FOLDERS' => 0,
'FOLDER' => 0,
'FOLDERNAME' => 0,
'LISTVIEW_LINKS' => 0,
'LISTVIEW_BASICACTION' => 0,
'childLinks' => 0,
'childLink' => 0,
'ICON_CLASS' => 0,
'FIELDS_INFO' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_692477a65d455',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_692477a65d455')) {function content_692477a65d455($_smarty_tpl) {?>
<div class="col-sm-12 col-xs-12 module-action-bar clearfix coloredBorderTop"><div class="module-action-content clearfix"><span class="col-lg-7 col-md-7"><span><?php $_smarty_tpl->tpl_vars['MODULE_MODEL'] = new Smarty_variable(Vtiger_Module_Model::getInstance($_smarty_tpl->tpl_vars['MODULE']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['DEFAULT_FILTER_ID'] = new Smarty_variable($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->getDefaultCustomFilter(), null, 0);?><?php if ($_smarty_tpl->tpl_vars['DEFAULT_FILTER_ID']->value){?><?php $_smarty_tpl->tpl_vars['CVURL'] = new Smarty_variable(("&viewname=").($_smarty_tpl->tpl_vars['DEFAULT_FILTER_ID']->value), null, 0);?><?php $_smarty_tpl->tpl_vars['DEFAULT_FILTER_URL'] = new Smarty_variable(($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->getListViewUrl()).($_smarty_tpl->tpl_vars['CVURL']->value), null, 0);?><?php }else{ ?><?php $_smarty_tpl->tpl_vars['DEFAULT_FILTER_URL'] = new Smarty_variable($_smarty_tpl->tpl_vars['MODULE_MODEL']->value->getListViewUrlWithAllFilter(), null, 0);?><?php }?><a title="<?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
" href='<?php echo $_smarty_tpl->tpl_vars['DEFAULT_FILTER_URL']->value;?>
'><h4 class="module-title pull-left">&nbsp;<?php echo vtranslate($_smarty_tpl->tpl_vars['MODULE']->value,$_smarty_tpl->tpl_vars['MODULE']->value);?>
&nbsp;</h4></a></span><span><p class="current-filter-name pull-left">&nbsp;<span class="fa fa-angle-right" aria-hidden="true"></span>&nbsp;<?php if ($_smarty_tpl->tpl_vars['VIEW']->value=='Detail'||$_smarty_tpl->tpl_vars['VIEW']->value=='ChartDetail'){?><?php echo $_smarty_tpl->tpl_vars['REPORT_NAME']->value;?>
<?php }else{ ?><?php if ($_smarty_tpl->tpl_vars['VIEW']->value=='List'){?>&nbsp;<?php echo vtranslate('LBL_LIST_VIEW',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }else{ ?>&nbsp;<?php echo vtranslate('LBL_EDIT_VIEW',$_smarty_tpl->tpl_vars['MODULE']->value);?>
<?php }?><?php }?>&nbsp;</p></span><?php if ($_smarty_tpl->tpl_vars['VIEWNAME']->value){?><?php if ($_smarty_tpl->tpl_vars['VIEWNAME']->value!='All'){?><?php $_smarty_tpl->tpl_vars['FOLDER'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['FOLDER']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['FOLDERS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['FOLDER']->key => $_smarty_tpl->tpl_vars['FOLDER']->value){
$_smarty_tpl->tpl_vars['FOLDER']->_loop = true;
?><?php if ($_smarty_tpl->tpl_vars['FOLDER']->value->getId()==$_smarty_tpl->tpl_vars['VIEWNAME']->value){?><?php $_smarty_tpl->tpl_vars['FOLDERNAME'] = new Smarty_variable($_smarty_tpl->tpl_vars['FOLDER']->value->getName(), null, 0);?><?php break 1?><?php }?><?php } ?><?php }else{ ?><?php $_smarty_tpl->tpl_vars['FOLDERNAME'] = new Smarty_variable(vtranslate('LBL_ALL_REPORTS',$_smarty_tpl->tpl_vars['MODULE']->value), null, 0);?><?php }?><span><p class="current-filter-name filter-name pull-left"><span class="fa fa-angle-right" aria-hidden="true"></span>&nbsp;<?php echo $_smarty_tpl->tpl_vars['FOLDERNAME']->value;?>
&nbsp;</p></span><?php }?></span><span class="col-lg-5 col-md-5 pull-right"><div id="appnav" class="navbar-right"><?php $_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['LISTVIEW_LINKS']->value['LISTVIEWBASIC']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->key => $_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->value){
$_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->_loop = true;
?><?php $_smarty_tpl->tpl_vars["childLinks"] = new Smarty_variable($_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->value->getChildLinks(), null, 0);?><?php if ($_smarty_tpl->tpl_vars['childLinks']->value&&$_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->value->get('linklabel')=='LBL_ADD_RECORD'){?><span class="btn-group"><button class="btn btn-default dropdown-toggle module-buttons" data-toggle="dropdown" id="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_basicAction_Add"><i class="fa fa-plus"></i>&nbsp;&nbsp;<?php echo vtranslate($_smarty_tpl->tpl_vars['LISTVIEW_BASICACTION']->value->getLabel(),$_smarty_tpl->tpl_vars['MODULE']->value);?>
&nbsp;<i class="caret icon-white"></i></button><ul class="dropdown-menu"><?php $_smarty_tpl->tpl_vars["childLink"] = new Smarty_Variable; $_smarty_tpl->tpl_vars["childLink"]->_loop = false;
$_from = $_smarty_tpl->tpl_vars['childLinks']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars["childLink"]->key => $_smarty_tpl->tpl_vars["childLink"]->value){
$_smarty_tpl->tpl_vars["childLink"]->_loop = true;
?><?php if ($_smarty_tpl->tpl_vars['childLink']->value->getLabel()=='LBL_CHARTS'){?><?php $_smarty_tpl->tpl_vars["ICON_CLASS"] = new Smarty_variable('fa fa-pie-chart', null, 0);?><?php }elseif($_smarty_tpl->tpl_vars['childLink']->value->getLabel()=='LBL_DETAIL_REPORT'){?><?php $_smarty_tpl->tpl_vars["ICON_CLASS"] = new Smarty_variable('vicon-detailreport', null, 0);?><?php }?><li id="<?php echo $_smarty_tpl->tpl_vars['MODULE']->value;?>
_listView_basicAction_<?php echo Vtiger_Util_Helper::replaceSpaceWithUnderScores($_smarty_tpl->tpl_vars['childLink']->value->getLabel());?>
" data-edition-disable="<?php echo $_smarty_tpl->tpl_vars['childLink']->value->disabled;?>
" data-edition-message="<?php echo $_smarty_tpl->tpl_vars['childLink']->value->message;?>
"><a <?php if ($_smarty_tpl->tpl_vars['childLink']->value->disabled!='1'){?> <?php if (stripos($_smarty_tpl->tpl_vars['childLink']->value->getUrl(),'javascript:')===0){?> onclick='<?php echo substr($_smarty_tpl->tpl_vars['childLink']->value->getUrl(),strlen("javascript:"));?>
;' <?php }else{ ?> href='<?php echo $_smarty_tpl->tpl_vars['childLink']->value->getUrl();?>
' <?php }?> <?php }else{ ?> href="javascript:void(0);" <?php }?>><i class='<?php echo $_smarty_tpl->tpl_vars['ICON_CLASS']->value;?>
' style="font-size:13px;"></i>&nbsp; <?php echo vtranslate($_smarty_tpl->tpl_vars['childLink']->value->getLabel(),$_smarty_tpl->tpl_vars['MODULE']->value);?>
</a></li><?php } ?></ul></span><?php }?><?php } ?></div></span></div><?php $_smarty_tpl->tpl_vars['FIELDS_INFO'] = new Smarty_variable(Reports_Field_Model::getListViewFieldsInfo(), null, 0);?><?php if ($_smarty_tpl->tpl_vars['FIELDS_INFO']->value!=null){?><script type="text/javascript">var uimeta = (function () {var fieldInfo = <?php echo $_smarty_tpl->tpl_vars['FIELDS_INFO']->value;?>
;return {field: {get: function (name, property) {if (name && property === undefined) {return fieldInfo[name];}if (name && property) {return fieldInfo[name][property]}},isMandatory: function (name) {if (fieldInfo[name]) {return fieldInfo[name].mandatory;}return false;},getType: function (name) {if (fieldInfo[name]) {return fieldInfo[name].type}return false;}}};})();</script><?php }?><div class="rssAddFormContainer hide"></div></div><?php }} ?>

View File

@@ -0,0 +1,78 @@
<?php /* Smarty version Smarty-3.1.7, created on 2025-11-26 11:29:01
compiled from "/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Vtiger/uitypes/ProductTax.tpl" */ ?>
<?php /*%%SmartyHeaderCode:1789428926926ba4d5e4242-34386166%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_valid = $_smarty_tpl->decodeProperties(array (
'file_dependency' =>
array (
'fee03f2eec43734de4d078d3bb4249057e125bc9' =>
array (
0 => '/var/www/fastuser/data/www/crm.clientright.ru/includes/runtime/../../layouts/v7/modules/Vtiger/uitypes/ProductTax.tpl',
1 => 1711810494,
2 => 'file',
),
),
'nocache_hash' => '1789428926926ba4d5e4242-34386166',
'function' =>
array (
),
'variables' =>
array (
'TAXCLASS_DETAILS' => 0,
'tax' => 0,
'tax_count' => 0,
'PULL_RIGHT' => 0,
'MODULE' => 0,
'check_value' => 0,
'show_value' => 0,
'WIDTHTYPE' => 0,
'QUALIFIED_MODULE' => 0,
'REGIONS_INFO' => 0,
'TAX_REGION_ID' => 0,
'i' => 0,
'TAX_REGION_MODEL' => 0,
'COUNTER' => 0,
),
'has_nocache_code' => false,
'version' => 'Smarty-3.1.7',
'unifunc' => 'content_6926ba4d631e0',
),false); /*/%%SmartyHeaderCode%%*/?>
<?php if ($_valid && !is_callable('content_6926ba4d631e0')) {function content_6926ba4d631e0($_smarty_tpl) {?>
<?php $_smarty_tpl->tpl_vars["tax_count"] = new Smarty_variable(1, null, 0);?><?php $_smarty_tpl->tpl_vars['tax'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['tax']->_loop = false;
$_smarty_tpl->tpl_vars['count'] = new Smarty_Variable;
$_from = $_smarty_tpl->tpl_vars['TAXCLASS_DETAILS']->value; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['tax']->key => $_smarty_tpl->tpl_vars['tax']->value){
$_smarty_tpl->tpl_vars['tax']->_loop = true;
$_smarty_tpl->tpl_vars['count']->value = $_smarty_tpl->tpl_vars['tax']->key;
?><?php if ($_smarty_tpl->tpl_vars['tax']->value['check_value']==1){?><?php $_smarty_tpl->tpl_vars['check_value'] = new Smarty_variable("checked", null, 0);?><?php $_smarty_tpl->tpl_vars['show_value'] = new Smarty_variable("visible", null, 0);?><?php }else{ ?><?php $_smarty_tpl->tpl_vars['check_value'] = new Smarty_variable('', null, 0);?><?php $_smarty_tpl->tpl_vars['show_value'] = new Smarty_variable("hidden", null, 0);?><?php }?><?php if ($_smarty_tpl->tpl_vars['tax_count']->value>1){?><td class="fieldLabel alignMiddle<?php if ($_smarty_tpl->tpl_vars['PULL_RIGHT']->value){?> pull-right<?php }?>"><label class=""><?php }?><span class="taxLabel alignBottom"><?php echo vtranslate($_smarty_tpl->tpl_vars['tax']->value['taxlabel'],$_smarty_tpl->tpl_vars['MODULE']->value);?>
<span class="paddingLeft10px">(%)</span></span><span style="padding-left: 10px;"><input style="top: 3px;" type="checkbox" name="<?php echo $_smarty_tpl->tpl_vars['tax']->value['check_name'];?>
" id="<?php echo $_smarty_tpl->tpl_vars['tax']->value['check_name'];?>
" class="taxes" data-tax-name=<?php echo $_smarty_tpl->tpl_vars['tax']->value['taxname'];?>
<?php echo $_smarty_tpl->tpl_vars['check_value']->value;?>
></span></label></td><td class="fieldValue"><?php if ($_smarty_tpl->tpl_vars['tax']->value['type']=='Fixed'){?><input type="text" id="<?php echo $_smarty_tpl->tpl_vars['tax']->value['taxname'];?>
" class="inputElement<?php if ($_smarty_tpl->tpl_vars['show_value']->value=="hidden"){?> hide <?php }else{ ?> show <?php }?>" name="<?php echo $_smarty_tpl->tpl_vars['tax']->value['taxname'];?>
" value="<?php echo $_smarty_tpl->tpl_vars['tax']->value['percentage'];?>
" data-rule-required="true" data-rule-inventory_percentage="true" /><?php }else{ ?><div class="<?php if ($_smarty_tpl->tpl_vars['show_value']->value=="hidden"){?>hide<?php }?>" id="<?php echo $_smarty_tpl->tpl_vars['tax']->value['taxname'];?>
" style="width:70%;"><div class="regionsList"><table class="table table-bordered themeTableColor"><tr><td class="<?php echo $_smarty_tpl->tpl_vars['WIDTHTYPE']->value;?>
" style="width:70%"><label><?php echo vtranslate('LBL_DEFAULT',$_smarty_tpl->tpl_vars['QUALIFIED_MODULE']->value);?>
</label></td><td class="<?php echo $_smarty_tpl->tpl_vars['WIDTHTYPE']->value;?>
" style="text-align: center; width:30%;"><input class="inputElement" type="text" name="<?php echo $_smarty_tpl->tpl_vars['tax']->value['taxname'];?>
_defaultPercentage" value="<?php echo $_smarty_tpl->tpl_vars['tax']->value['percentage'];?>
" data-rule-required="true" data-rule-inventory_percentage="true" style="width: 80px;" /></td></tr><?php $_smarty_tpl->tpl_vars['i'] = new Smarty_variable(0, null, 0);?><?php $_smarty_tpl->tpl_vars['REGIONS_INFO'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['REGIONS_INFO']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['tax']->value['regions']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['REGIONS_INFO']->key => $_smarty_tpl->tpl_vars['REGIONS_INFO']->value){
$_smarty_tpl->tpl_vars['REGIONS_INFO']->_loop = true;
?><tr><td><?php $_smarty_tpl->tpl_vars['TAX_REGION_ID'] = new Smarty_Variable; $_smarty_tpl->tpl_vars['TAX_REGION_ID']->_loop = false;
$_from = $_smarty_tpl->tpl_vars['REGIONS_INFO']->value['list']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array');}
foreach ($_from as $_smarty_tpl->tpl_vars['TAX_REGION_ID']->key => $_smarty_tpl->tpl_vars['TAX_REGION_ID']->value){
$_smarty_tpl->tpl_vars['TAX_REGION_ID']->_loop = true;
?><?php ob_start();?><?php echo $_smarty_tpl->tpl_vars['TAX_REGION_ID']->value;?>
<?php $_tmp1=ob_get_clean();?><?php $_smarty_tpl->tpl_vars['TAX_REGION_MODEL'] = new Smarty_variable(Inventory_TaxRegion_Model::getRegionModel($_tmp1), null, 0);?><input type="hidden" name="<?php echo $_smarty_tpl->tpl_vars['tax']->value['taxname'];?>
_regions[<?php echo $_smarty_tpl->tpl_vars['i']->value;?>
][list][]" value="<?php echo $_smarty_tpl->tpl_vars['TAX_REGION_MODEL']->value->getId();?>
" /><span class="label label-info displayInlineBlock" style="margin: 2px 1px;"><?php echo $_smarty_tpl->tpl_vars['TAX_REGION_MODEL']->value->getName();?>
</span><?php } ?></td><td class="<?php echo $_smarty_tpl->tpl_vars['WIDTHTYPE']->value;?>
" style="text-align: center;"><input class="inputElement" type="text" name="<?php echo $_smarty_tpl->tpl_vars['tax']->value['taxname'];?>
_regions[<?php echo $_smarty_tpl->tpl_vars['i']->value;?>
][value]" value="<?php echo $_smarty_tpl->tpl_vars['REGIONS_INFO']->value['value'];?>
" data-rule-required="true" data-rule-inventory_percentage="true" style="width: 80px;" /></td></tr><?php $_smarty_tpl->tpl_vars['i'] = new Smarty_variable($_smarty_tpl->tpl_vars['i']->value+1, null, 0);?><?php } ?></table></div></div><?php }?></td><?php $_smarty_tpl->tpl_vars["tax_count"] = new Smarty_variable($_smarty_tpl->tpl_vars['tax_count']->value+1, null, 0);?><?php if ($_smarty_tpl->tpl_vars['COUNTER']->value==2){?></tr><tr><?php $_smarty_tpl->tpl_vars["COUNTER"] = new Smarty_variable(1, null, 0);?><?php }else{ ?><?php $_smarty_tpl->tpl_vars["COUNTER"] = new Smarty_variable($_smarty_tpl->tpl_vars['COUNTER']->value+1, null, 0);?><?php }?><?php } ?><?php }} ?>

View File

@@ -0,0 +1,176 @@
# Лог сессии: Исправление загрузки документов и SQL запросов
**Дата:** 2025-11-26
**Тема:** Исправление потери документов, дубликатов и правильного определения field_name
---
## Проблемы, которые были решены
### 1. Потеря документов при обновлении черновика
**Проблема:** При обработке нового документа через SQL `claimsave_final` существующие документы терялись.
**Причина:**
- SQL перезаписывал `documents_meta` вместо объединения
- `documents_uploaded` мог быть перезаписан пустым массивом, если `jsonb_agg` возвращал NULL
**Решение:**
- Исправлен SQL `SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql`:
- `documents_meta` теперь объединяется с существующими
- `documents_uploaded` всегда начинается с существующих документов
- Добавлена проверка на пустой массив перед перезаписью
### 2. Дубликаты документов в documents_meta
**Проблема:** В `documents_meta` были дубликаты (один и тот же `file_id` встречался несколько раз).
**Решение:**
- Создан скрипт `fix_documents_meta_duplicates.py` для удаления дубликатов
- Исправлена логика объединения в SQL
### 3. Неправильное определение типа документа
**Проблема:** Чек определялся как `contract` вместо `payment`.
**Причина:**
- SQL проверял `field_name` раньше, чем `field_label`
- `field_name` был `uploads[0][0]` для всех документов
**Решение:**
- Изменён порядок проверки в SQL: сначала `field_label`, потом `field_name`
- Исправлен файл `SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql`
### 4. Все документы имели одинаковый field_name
**Проблема:** В таблице `clpr_claim_documents` все документы имели `field_name: uploads[0][0]`, из-за чего второй документ перезаписывал первый.
**Причина:**
- `group_index` (индекс документа в `documents_required`) не передавался с фронтенда
- Код n8n использовал `group_index_num` из OCR, который всегда был `0`
**Решение:**
- Фронтенд (`StepWizardPlan.tsx`): добавлена передача `group_index` в запрос
- Бэкенд (`documents.py`): добавлено получение `group_index` из Form и передача в n8n
- Код n8n (`N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js`): приоритет `group_index` из body над `group_index_num` из OCR
- Создан скрипт `fix_claim_documents_field_names.py` для исправления существующих документов
### 5. SQL для claimsave перезаписывал documents_meta
**Проблема:** SQL `claimsave` перезаписывал `documents_meta` вместо объединения.
**Решение:**
- Исправлен файл `SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql`:
- `documents_meta` объединяется с существующими
- Критичные поля удаляются из нового payload перед объединением
- Затем устанавливаются отдельно через `jsonb_set`
### 6. Дубликаты в списке загруженных документов на фронтенде
**Проблема:** React ошибка "Encountered two children with the same key, `contract`".
**Решение:**
- Исправлен `StepWizardPlan.tsx`:
- Убраны дубликаты при инициализации `uploadedDocs`
- Проверка на дубликаты при добавлении нового документа
- Использование `Array.from(new Set())` при рендеринге
---
## Созданные файлы
### SQL запросы
- `docs/SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql` - SQL для сохранения документов с автоматическим созданием `documents_uploaded`
- `docs/SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql` - Исправленный SQL для `claimsave` с объединением `documents_meta`
- `docs/SQL_FIX_DRAFT_BDDB6815.sql` - SQL для исправления конкретного черновика
- `docs/SQL_FIX_CLAIM_DOCUMENTS_FIELD_NAMES.sql` - SQL для исправления `field_name` в таблице
### Код n8n
- `docs/N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js` - Исправленный код для обработки загруженных файлов с поддержкой `group_index`
### Скрипты для исправления данных
- `fix_draft_bddb6815_with_contract.py` - Скрипт для исправления черновика с учётом загруженных документов
- `fix_documents_meta_duplicates.py` - Скрипт для удаления дубликатов из `documents_meta`
- `fix_claim_documents_field_names.py` - Скрипт для исправления `field_name` в таблице `clpr_claim_documents`
- `check_documents_detailed.py` - Скрипт для детальной проверки документов
- `check_documents_mismatch.py` - Скрипт для проверки несоответствий между `documents_uploaded` и таблицей
---
## Изменённые файлы
### Backend
- `backend/app/api/documents.py` - Добавлена передача `group_index` в n8n
- `backend/app/api/claims.py` - Обновлена логика загрузки черновиков, добавлена поддержка `documents_required`
- `backend/app/api/events.py` - Исправлены синтаксические ошибки (удалены дубликаты кода)
- `backend/app/api/models.py` - Добавлены поля `unified_id` и `contact_id`
### Frontend
- `frontend/src/pages/ClaimForm.tsx` - Обновлена логика загрузки черновиков, добавлена поддержка нового флоу
- `frontend/src/components/form/StepWizardPlan.tsx` - Добавлена передача `group_index`, исправлены дубликаты в списке документов
- `frontend/src/components/form/StepDraftSelection.tsx` - Обновлена логика определения legacy черновиков
- `frontend/src/components/form/StepDescription.tsx` - Добавлена передача `unified_id` и `contact_id`
---
## Результаты
### Исправлено для черновика `bddb6815-8e17-4d54-a721-5e94382942c7`:
- ✅ Удалены дубликаты из `documents_meta` (было 4, стало 3)
- ✅ Исправлены типы документов в `documents_uploaded` (чек теперь `payment`, а не `contract`)
- ✅ Исправлены `field_name` в таблице `clpr_claim_documents`:
- `uploads[0][0]` - contract (договор)
- `uploads[1][0]` - payment (чек)
- `uploads[3][0]` - evidence_photo (фото доказательства)
### Текущее состояние:
- `documents_required`: 4 документа
- `documents_uploaded`: 2 документа (contract, payment)
- `documents_meta`: 3 документа (без дубликатов)
- `current_doc_index`: 2 (следующий документ - correspondence)
- `status_code`: `draft_docs_progress`
---
## Что нужно сделать дальше
1. **Обновить код n8n:**
- Заменить код в узле "Process Uploaded Files" на версию из `N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js`
- Убедиться, что `group_index` передаётся из body
2. **Обновить SQL в n8n:**
- Заменить SQL в узле "claimsave" на версию из `SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql`
- Заменить SQL в узле "claimsave_final" на версию из `SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql`
3. **Проверить работу:**
- Загрузить новый документ через интерфейс
- Убедиться, что он получает правильный `field_name` (например, `uploads[2][0]` для третьего документа)
- Проверить, что документы не теряются при обновлении черновика
---
## Важные моменты
1. **Приоритет определения типа документа:**
- Сначала проверяется `field_label` (более точный)
- Потом проверяется `field_name` (fallback)
2. **Объединение документов:**
- `documents_meta` всегда объединяется с существующими
- `documents_uploaded` всегда начинается с существующих документов
- Новые документы добавляются только если их нет в существующих
3. **field_name:**
- Формат: `uploads[{group_index}][0]`
- `group_index` = индекс документа в `documents_required` (0-based)
- Передаётся с фронтенда через параметр `group_index`
---
## Команды для проверки
```bash
# Проверить документы в черновике
docker exec ticket_form_backend python3 /app/check_documents_detailed.py
# Проверить документы в таблице
docker exec ticket_form_backend python3 /app/check_claim_documents_table.py
# Исправить field_name для существующих документов
docker exec ticket_form_backend python3 /app/fix_claim_documents_field_names.py
```

View File

@@ -141,3 +141,147 @@ ticket_form/
- `ocr_events:{session_id}` — события для конкретного пользователя - `ocr_events:{session_id}` — события для конкретного пользователя
- `ticket_form:documents_list` — запрос на генерацию списка документов - `ticket_form:documents_list` — запрос на генерацию списка документов
**Дата:** 2025-11-26
**Время:** ~13:00 MSK
---
## 🎯 Цель сессии
Концептуальная переработка флоу подачи заявки:
- **Проблема:** Визард генерируется слишком долго (2 минуты), анкета слишком длинная
- **Решение:** Сразу запрашиваем документы, параллельно генерируем визард в бэке
---
## ✅ Что сделано
### 1. Документация архитектуры
- **Файл:** `docs/NEW_FLOW_ARCHITECTURE.md`
- Описан новый флоу: Description → Documents → Waiting → Claim Review → SMS
- Определены статусы черновиков: `draft_new`, `draft_docs_progress`, `draft_docs_complete`, `draft_claim_ready`, `awaiting_sms`
- Структура payload черновика с новыми полями
### 2. Frontend компоненты
#### StepDocumentsNew.tsx (НОВЫЙ)
- Поэкранная загрузка документов (один документ на экран)
- Критичные документы помечены предупреждением
- Возможность пропустить любой документ
- Прогресс-бар загрузки
- Отображение уже загруженных документов
#### StepWaitingClaim.tsx (НОВЫЙ)
- Экран ожидания формирования заявления
- SSE подписка на события: `document_ocr_completed`, `claim_ready`
- Шаги обработки: OCR → Анализ → Формирование → Готово
- Таймер ожидания
- Таймаут 5 минут с обработкой ошибок
#### StepDraftSelection.tsx (ОБНОВЛЁН)
- Поддержка новых статусов черновиков
- Визуальное отображение разных статусов (цвета, иконки, описания)
- Прогресс документов (X из Y загружено)
- Legacy черновики помечаются как "устаревший формат"
- Разные действия для разных статусов
### 3. Backend API
#### documents.py (НОВЫЙ)
- `POST /api/v1/documents/upload` — загрузка одного документа
- `GET /api/v1/documents/status/{claim_id}` — статус обработки документов
- `POST /api/v1/documents/generate-list` — запрос на генерацию списка документов
- Интеграция с n8n webhook
- Публикация событий в Redis
#### main.py (ОБНОВЛЁН)
- Добавлен роутер `documents`
---
## 📁 Изменённые файлы
```
ticket_form/
├── docs/
│ └── NEW_FLOW_ARCHITECTURE.md # НОВЫЙ
├── frontend/src/components/form/
│ ├── StepDocumentsNew.tsx # НОВЫЙ
│ ├── StepWaitingClaim.tsx # НОВЫЙ
│ └── StepDraftSelection.tsx # ОБНОВЛЁН
├── backend/app/
│ ├── api/
│ │ └── documents.py # НОВЫЙ
│ └── main.py # ОБНОВЛЁН
└── SESSION_LOG_2025-11-26_NEW_FLOW.md # НОВЫЙ
```
---
## ⏳ Что осталось сделать
### Frontend
- [ ] Обновить `ClaimForm.tsx` — интегрировать новые компоненты в флоу
- [ ] Обновить `StepDescription.tsx` — после описания переходить к документам (не к визарду)
### Backend
- [ ] Эндпоинт получения списка документов из черновика
- [ ] SSE события для прогресса OCR
### n8n
- [ ] Воркфлоу: генерация списка документов (быстрый AI запрос)
- [ ] Воркфлоу: OCR документа → заполнение полей визарда
- [ ] Воркфлоу: формирование заявления после всех документов
- [ ] Webhook: `/webhook/document-upload`
### Тестирование
- [ ] Полный цикл с реальными данными
- [ ] Обработка ошибок
- [ ] Legacy черновики
---
## 🔧 Технические детали
### Новые SSE события
```javascript
// Список документов готов
{ event_type: "documents_list_ready", documents_required: [...] }
// Документ загружен (начало OCR)
{ event_type: "document_uploaded", document_type: "contract", status: "processing" }
// OCR завершён
{ event_type: "document_ocr_completed", document_type: "contract", ocr_data: {...} }
// Заявление готово
{ event_type: "claim_ready", claim_data: {...} }
```
### Статусы черновиков
| Статус | Описание |
|--------|----------|
| `draft_new` | Только описание проблемы |
| `draft_docs_progress` | Часть документов загружена |
| `draft_docs_complete` | Все документы, ждём заявление |
| `draft_claim_ready` | Заявление готово |
| `awaiting_sms` | Ждёт SMS подтверждения |
### Legacy черновики
- Определяются по отсутствию `documents_required` в payload
- Показываются с пометкой "устаревший формат"
- Кнопка "Начать заново" копирует description в новый черновик
---
## 📌 Примечания
1. **Ветка backup:** `backup-wizard-ui-2025-11-26` содержит состояние до изменений
2. **n8n:** Webhook `/webhook/document-upload` нужно создать
3. **Redis каналы:**
- `ocr_events:{session_id}` — события для конкретного пользователя
- `ticket_form:documents_list` — запрос на генерацию списка документов

View File

@@ -400,6 +400,12 @@ async def get_draft(claim_id: str):
logger.info(f"🔍 Загружен черновик: id={row.get('id')}, claim_id={final_claim_id}, channel={row.get('channel')}") logger.info(f"🔍 Загружен черновик: id={row.get('id')}, claim_id={final_claim_id}, channel={row.get('channel')}")
# 🔍 ОТЛАДКА: Логируем наличие documents_required
documents_required = payload.get('documents_required', []) if isinstance(payload, dict) else []
logger.info(f"🔍 Черновик {final_claim_id}: status_code={row.get('status_code')}, documents_required count={len(documents_required) if isinstance(documents_required, list) else 0}")
if documents_required:
logger.info(f"🔍 documents_required: {documents_required[:2]}...") # Первые 2 для примера
return { return {
"success": True, "success": True,
"claim": { "claim": {
@@ -426,14 +432,13 @@ async def delete_draft(claim_id: str):
""" """
Удалить черновик по claim_id Удалить черновик по claim_id
Удаляет только черновики (status_code = 'draft') Удаляет черновики с любым статусом (кроме submitted/completed)
""" """
try: try:
query = """ query = """
DELETE FROM clpr_claims DELETE FROM clpr_claims
WHERE payload->>'claim_id' = $1 WHERE (payload->>'claim_id' = $1 OR id::text = $1)
AND status_code = 'draft' AND status_code NOT IN ('submitted', 'completed', 'rejected')
AND channel = 'web_form'
RETURNING id RETURNING id
""" """

View File

@@ -4,7 +4,7 @@ Documents API Routes - Загрузка и обработка документо
Новый флоу: поэкранная загрузка документов Новый флоу: поэкранная загрузка документов
""" """
from fastapi import APIRouter, HTTPException, UploadFile, File, Form, Request from fastapi import APIRouter, HTTPException, UploadFile, File, Form, Request
from typing import Optional from typing import Optional, List
import httpx import httpx
import json import json
import uuid import uuid
@@ -17,7 +17,7 @@ router = APIRouter(prefix="/api/v1/documents", tags=["Documents"])
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# n8n webhook для загрузки документов # n8n webhook для загрузки документов
N8N_DOCUMENT_UPLOAD_WEBHOOK = "https://n8n.clientright.pro/webhook/document-upload" N8N_DOCUMENT_UPLOAD_WEBHOOK = "https://n8n.clientright.pro/webhook/webform_document_upload"
@router.post("/upload") @router.post("/upload")
@@ -27,8 +27,12 @@ async def upload_document(
claim_id: str = Form(...), claim_id: str = Form(...),
session_id: str = Form(...), session_id: str = Form(...),
document_type: str = Form(...), document_type: str = Form(...),
document_name: Optional[str] = Form(None),
document_description: Optional[str] = Form(None),
group_index: Optional[str] = Form(None),
unified_id: Optional[str] = Form(None), unified_id: Optional[str] = Form(None),
contact_id: Optional[str] = Form(None), contact_id: Optional[str] = Form(None),
phone: Optional[str] = Form(None),
): ):
""" """
Загрузка одного документа. Загрузка одного документа.
@@ -60,26 +64,50 @@ async def upload_document(
file_content = await file.read() file_content = await file.read()
file_size = len(file_content) file_size = len(file_content)
# Формируем данные для отправки в n8n # Получаем IP клиента
client_ip = request.client.host if request.client else "unknown"
forwarded_for = request.headers.get("x-forwarded-for", "").split(",")[0].strip()
if forwarded_for:
client_ip = forwarded_for
# Формируем данные в формате совместимом с существующим n8n воркфлоу
form_data = { form_data = {
"claim_id": claim_id, # Основные идентификаторы
"form_id": "ticket_form",
"stage": "document_upload",
"session_id": session_id, "session_id": session_id,
"claim_id": claim_id,
"client_ip": client_ip,
# Идентификаторы пользователя
"unified_id": unified_id or "",
"contact_id": contact_id or "",
"phone": phone or "",
# Информация о документе
"document_type": document_type, "document_type": document_type,
"file_id": file_id, "file_id": file_id,
"original_filename": file.filename, "original_filename": file.filename,
"content_type": file.content_type or "application/octet-stream", "content_type": file.content_type or "application/octet-stream",
"file_size": str(file_size), "file_size": str(file_size),
"upload_timestamp": datetime.utcnow().isoformat(), "upload_timestamp": datetime.utcnow().isoformat(),
# Формат uploads_* для совместимости
# ✅ Используем group_index для правильной индексации (по умолчанию 0)
"uploads_field_names[{idx}]".format(idx=group_index or "0"): document_type,
"uploads_field_labels[{idx}]".format(idx=group_index or "0"): document_name or document_type,
"uploads_descriptions[{idx}]".format(idx=group_index or "0"): document_description or "",
} }
if unified_id: # ✅ Добавляем group_index в данные формы
form_data["unified_id"] = unified_id if group_index:
if contact_id: form_data["group_index"] = group_index
form_data["contact_id"] = contact_id logger.info(f"📋 group_index передан в n8n: {group_index}")
# Файл для multipart # Файл для multipart (ключ uploads[group_index] для совместимости)
idx = group_index or "0"
files = { files = {
"file": (file.filename, file_content, file.content_type or "application/octet-stream") f"uploads[{idx}]": (file.filename, file_content, file.content_type or "application/octet-stream")
} }
# Отправляем в n8n # Отправляем в n8n
@@ -163,6 +191,174 @@ async def upload_document(
) )
@router.post("/upload-multiple")
async def upload_multiple_documents(
request: Request,
files: List[UploadFile] = File(...),
claim_id: str = Form(...),
session_id: str = Form(...),
document_type: str = Form(...),
document_name: Optional[str] = Form(None),
document_description: Optional[str] = Form(None),
unified_id: Optional[str] = Form(None),
contact_id: Optional[str] = Form(None),
phone: Optional[str] = Form(None),
):
"""
Загрузка нескольких файлов для одного документа (например, несколько страниц паспорта).
Все файлы отправляются одним запросом в n8n.
"""
try:
logger.info(
"📤 Multiple documents upload received",
extra={
"claim_id": claim_id,
"session_id": session_id,
"document_type": document_type,
"files_count": len(files),
"file_names": [f.filename for f in files],
},
)
# Получаем IP клиента
client_ip = request.client.host if request.client else "unknown"
forwarded_for = request.headers.get("x-forwarded-for", "").split(",")[0].strip()
if forwarded_for:
client_ip = forwarded_for
# Генерируем ID для каждого файла и читаем контент
file_ids = []
files_multipart = {}
for i, file in enumerate(files):
file_id = f"doc_{uuid.uuid4().hex[:12]}"
file_ids.append(file_id)
file_content = await file.read()
files_multipart[f"uploads[{i}]"] = (
file.filename,
file_content,
file.content_type or "application/octet-stream"
)
# Формируем данные формы
form_data = {
# Основные идентификаторы
"form_id": "ticket_form",
"stage": "document_upload",
"session_id": session_id,
"claim_id": claim_id,
"client_ip": client_ip,
# Идентификаторы пользователя
"unified_id": unified_id or "",
"contact_id": contact_id or "",
"phone": phone or "",
# Информация о документе
"document_type": document_type,
"files_count": str(len(files)),
"upload_timestamp": datetime.utcnow().isoformat(),
}
# ✅ Получаем group_index из Form (индекс документа в documents_required)
form_params = await request.form()
group_index = form_params.get("group_index")
if group_index:
form_data["group_index"] = group_index
logger.info(f"📋 group_index передан в n8n: {group_index}")
# Добавляем информацию о каждом файле
for i, (file, file_id) in enumerate(zip(files, file_ids)):
form_data[f"file_ids[{i}]"] = file_id
form_data[f"uploads_field_names[{i}]"] = document_type
form_data[f"uploads_field_labels[{i}]"] = document_name or document_type
form_data[f"uploads_descriptions[{i}]"] = document_description or ""
form_data[f"original_filenames[{i}]"] = file.filename
# Отправляем в n8n одним запросом
async with httpx.AsyncClient(timeout=180.0) as client:
response = await client.post(
N8N_DOCUMENT_UPLOAD_WEBHOOK,
data=form_data,
files=files_multipart,
)
response_text = response.text or ""
if response.status_code == 200:
logger.info(
"✅ Multiple documents uploaded to n8n",
extra={
"claim_id": claim_id,
"document_type": document_type,
"file_ids": file_ids,
"files_count": len(files),
},
)
# Парсим ответ от n8n
try:
n8n_response = json.loads(response_text)
except json.JSONDecodeError:
n8n_response = {"raw": response_text}
# Публикуем событие в Redis
event_data = {
"event_type": "documents_uploaded",
"status": "processing",
"claim_id": claim_id,
"session_id": session_id,
"document_type": document_type,
"file_ids": file_ids,
"files_count": len(files),
"original_filenames": [f.filename for f in files],
"timestamp": datetime.utcnow().isoformat(),
}
await redis_service.publish(
f"ocr_events:{session_id}",
json.dumps(event_data, ensure_ascii=False)
)
return {
"success": True,
"file_ids": file_ids,
"files_count": len(files),
"document_type": document_type,
"ocr_status": "processing",
"message": f"Загружено {len(files)} файл(ов)",
"n8n_response": n8n_response,
}
else:
logger.error(
"❌ n8n multiple upload error",
extra={
"status_code": response.status_code,
"body": response_text[:500],
},
)
raise HTTPException(
status_code=response.status_code,
detail=f"Ошибка n8n: {response_text}",
)
except httpx.TimeoutException:
logger.error("⏱️ n8n multiple upload timeout")
raise HTTPException(status_code=504, detail="Таймаут загрузки документов")
except HTTPException:
raise
except Exception as e:
logger.exception("❌ Multiple upload error")
raise HTTPException(
status_code=500,
detail=f"Ошибка загрузки документов: {str(e)}",
)
@router.get("/status/{claim_id}") @router.get("/status/{claim_id}")
async def get_documents_status(claim_id: str): async def get_documents_status(claim_id: str):
""" """
@@ -198,6 +394,150 @@ async def get_documents_status(claim_id: str):
) )
async def skip_document(
request: Request,
claim_id: str = Form(...),
session_id: str = Form(...),
document_type: str = Form(...),
document_name: Optional[str] = Form(None),
group_index: Optional[str] = Form(None),
unified_id: Optional[str] = Form(None),
contact_id: Optional[str] = Form(None),
phone: Optional[str] = Form(None),
):
"""
Пропуск документа (пользователь указал, что документа нет).
Отправляет событие в n8n на тот же webhook, что и загрузка файлов,
но с флагом skipped=true для обработки пропуска.
"""
try:
logger.info(
"⏭️ Document skip received",
extra={
"claim_id": claim_id,
"session_id": session_id,
"document_type": document_type,
"group_index": group_index,
},
)
# Получаем IP клиента
client_ip = request.client.host if request.client else "unknown"
forwarded_for = request.headers.get("x-forwarded-for", "").split(",")[0].strip()
if forwarded_for:
client_ip = forwarded_for
# Формируем данные в формате совместимом с существующим n8n воркфлоу
form_data = {
# Основные идентификаторы
"form_id": "ticket_form",
"stage": "document_skip",
"session_id": session_id,
"claim_id": claim_id,
"client_ip": client_ip,
# Идентификаторы пользователя
"unified_id": unified_id or "",
"contact_id": contact_id or "",
"phone": phone or "",
# Информация о документе
"document_type": document_type,
"document_name": document_name or document_type,
"skipped": "true", # ✅ Флаг пропуска документа
"action": "skip", # ✅ Действие: пропуск
"skip_timestamp": datetime.utcnow().isoformat(),
# Формат uploads_* для совместимости (без файлов)
# ✅ Используем group_index для правильной индексации (по умолчанию 0)
"uploads_field_names[{idx}]".format(idx=group_index or "0"): document_type,
"uploads_field_labels[{idx}]".format(idx=group_index or "0"): document_name or document_type,
"uploads_descriptions[{idx}]".format(idx=group_index or "0"): "",
"files_count": "0", # ✅ Нет файлов
}
# ✅ Добавляем group_index в данные формы
if group_index:
form_data["group_index"] = group_index
logger.info(f"📋 group_index передан в n8n: {group_index}")
# Отправляем в n8n на тот же webhook (без файлов)
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(
N8N_DOCUMENT_UPLOAD_WEBHOOK,
data=form_data,
)
response_text = response.text or ""
if response.status_code == 200:
logger.info(
"✅ Document skip sent to n8n",
extra={
"claim_id": claim_id,
"document_type": document_type,
"response_preview": response_text[:200],
},
)
# Парсим ответ от n8n
try:
n8n_response = json.loads(response_text)
except json.JSONDecodeError:
n8n_response = {"raw": response_text}
# Публикуем событие в Redis для фронтенда
event_data = {
"event_type": "document_skipped",
"status": "skipped",
"claim_id": claim_id,
"session_id": session_id,
"document_type": document_type,
"document_name": document_name or document_type,
"timestamp": datetime.utcnow().isoformat(),
}
await redis_service.publish(
f"ocr_events:{session_id}",
json.dumps(event_data, ensure_ascii=False)
)
return {
"success": True,
"document_type": document_type,
"status": "skipped",
"message": "Документ пропущен и сохранён",
"n8n_response": n8n_response,
}
else:
logger.error(
"❌ n8n document skip error",
extra={
"status_code": response.status_code,
"body": response_text[:500],
},
)
raise HTTPException(
status_code=response.status_code,
detail=f"Ошибка n8n: {response_text}",
)
except httpx.TimeoutException:
logger.error("⏱️ n8n document skip timeout")
raise HTTPException(status_code=504, detail="Таймаут отправки пропуска документа")
except HTTPException:
raise
except Exception as e:
logger.exception("❌ Document skip error")
raise HTTPException(status_code=500, detail=f"Ошибка пропуска документа: {str(e)}")
@router.post("/generate-list") @router.post("/generate-list")
async def generate_documents_list(request: Request): async def generate_documents_list(request: Request):
""" """
@@ -268,3 +608,7 @@ async def generate_documents_list(request: Request):
detail=f"Ошибка генерации списка: {str(e)}", detail=f"Ошибка генерации списка: {str(e)}",
) )
router.add_api_route("/skip", skip_document, methods=["POST"], tags=["Documents"])

View File

@@ -123,10 +123,18 @@ async def stream_events(task_id: str):
# Формат уже плоский (от backend API или старых источников) # Формат уже плоский (от backend API или старых источников)
actual_event = event actual_event = event
# ✅ Логируем полученное событие
event_type = actual_event.get('event_type')
logger.info(f"🔍 Processing event: event_type={event_type}, has claim_id={bool(actual_event.get('claim_id'))}")
# ✅ Обработка нового формата: documents_list_ready
if event_type == 'documents_list_ready':
logger.info(f"📋 Documents list received: {len(actual_event.get('documents_required', []))} documents")
# Просто пропускаем дальше к yield
# ✅ Обработка формата от n8n: если пришёл объект с claim_id, но без event_type # ✅ Обработка формата от n8n: если пришёл объект с claim_id, но без event_type
# Это значит, что n8n пушит минимальный payload для wizard_ready # Это значит, что n8n пушит минимальный payload для wizard_ready
logger.info(f"🔍 Checking event: has event_type={bool(actual_event.get('event_type'))}, has claim_id={bool(actual_event.get('claim_id'))}") elif not event_type and actual_event.get('claim_id'):
if not actual_event.get('event_type') and actual_event.get('claim_id'):
logger.info(f"📦 Detected minimal wizard payload (no event_type), wrapping for claim_id={actual_event.get('claim_id')}") logger.info(f"📦 Detected minimal wizard payload (no event_type), wrapping for claim_id={actual_event.get('claim_id')}")
# Обёртываем в правильный формат # Обёртываем в правильный формат
actual_event = { actual_event = {
@@ -209,13 +217,21 @@ async def stream_events(task_id: str):
# Отправляем событие клиенту (плоский формат) # Отправляем событие клиенту (плоский формат)
event_json = json.dumps(actual_event, ensure_ascii=False) event_json = json.dumps(actual_event, ensure_ascii=False)
logger.info(f"📤 Sending event to client: {actual_event.get('status', 'unknown')}") event_type_sent = actual_event.get('event_type', 'unknown')
event_status = actual_event.get('status', 'unknown')
logger.info(f"📤 Sending event to client: type={event_type_sent}, status={event_status}")
yield f"data: {event_json}\n\n" yield f"data: {event_json}\n\n"
# Если обработка завершена - закрываем соединение # Если обработка завершена - закрываем соединение
if actual_event.get('status') in ['completed', 'error', 'success']: # НЕ закрываем для documents_list_ready и document_ocr_completed (ждём ещё события)
if event_status in ['completed', 'error'] and event_type_sent not in ['documents_list_ready', 'document_ocr_completed', 'document_uploaded']:
logger.info(f"✅ Task {task_id} finished, closing SSE") logger.info(f"✅ Task {task_id} finished, closing SSE")
break break
# Закрываем для финальных событий
if event_type_sent in ['claim_ready', 'claim_plan_ready']:
logger.info(f"✅ Final event {event_type_sent} sent, closing SSE")
break
else: else:
logger.info(f"⏰ Timeout waiting for message on {channel}") logger.info(f"⏰ Timeout waiting for message on {channel}")

View File

@@ -229,3 +229,4 @@ async def info():
if __name__ == "__main__": if __name__ == "__main__":
import uvicorn import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8200) uvicorn.run(app, host="0.0.0.0", port=8200)

View File

@@ -0,0 +1,68 @@
#!/usr/bin/env python3
"""
Проверка документов в таблице clpr_claim_documents
"""
import asyncio
import asyncpg
POSTGRES_HOST = "147.45.189.234"
POSTGRES_PORT = 5432
POSTGRES_DB = "default_db"
POSTGRES_USER = "gen_user"
POSTGRES_PASSWORD = "2~~9_^kVsU?2\\S"
CLAIM_ID = "bddb6815-8e17-4d54-a721-5e94382942c7"
async def check_documents_table():
conn = await asyncpg.connect(
host=POSTGRES_HOST,
port=POSTGRES_PORT,
database=POSTGRES_DB,
user=POSTGRES_USER,
password=POSTGRES_PASSWORD
)
try:
# Сначала находим UUID claim
claim_row = await conn.fetchrow("""
SELECT id FROM clpr_claims
WHERE id::text = $1 OR payload->>'claim_id' = $1
ORDER BY updated_at DESC
LIMIT 1
""", CLAIM_ID)
if not claim_row:
print(f"❌ Черновик {CLAIM_ID} не найден!")
return
claim_uuid = claim_row['id']
# Ищем документы по UUID (claim_id в таблице - text)
rows = await conn.fetch("""
SELECT
ccd.id,
ccd.claim_id,
ccd.field_name,
ccd.file_id,
ccd.file_name,
ccd.original_file_name,
ccd.uploaded_at
FROM clpr_claim_documents ccd
WHERE ccd.claim_id = $1
ORDER BY ccd.uploaded_at DESC
""", str(claim_uuid))
print(f"📋 Найдено {len(rows)} документов в таблице clpr_claim_documents:")
for i, row in enumerate(rows):
print(f"\n {i+1}. field_name: {row['field_name']}")
print(f" file_id: {row['file_id']}")
print(f" file_name: {row['file_name']}")
print(f" original_file_name: {row['original_file_name']}")
print(f" uploaded_at: {row['uploaded_at']}")
finally:
await conn.close()
if __name__ == "__main__":
asyncio.run(check_documents_table())

View File

@@ -0,0 +1,129 @@
#!/usr/bin/env python3
"""
Проверка статуса жалобы в базе данных
"""
import asyncio
import asyncpg
import json
# Параметры подключения к БД
POSTGRES_HOST = "147.45.189.234"
POSTGRES_PORT = 5432
POSTGRES_DB = "default_db"
POSTGRES_USER = "gen_user"
POSTGRES_PASSWORD = "2~~9_^kVsU?2\\S"
CLAIM_ID = "bddb6815-8e17-4d54-a721-5e94382942c7"
async def check_claim_status():
"""Проверяет статус жалобы"""
conn = None
try:
conn = await asyncpg.connect(
host=POSTGRES_HOST,
port=POSTGRES_PORT,
database=POSTGRES_DB,
user=POSTGRES_USER,
password=POSTGRES_PASSWORD
)
# Запрос статуса жалобы
query = """
SELECT
id,
status_code,
payload->>'claim_id' as claim_id,
payload->>'current_doc_index' as current_doc_index,
jsonb_array_length(COALESCE(payload->'documents_required', '[]'::jsonb)) as documents_required_count,
jsonb_array_length(COALESCE(payload->'documents_uploaded', '[]'::jsonb)) as documents_uploaded_count,
jsonb_array_length(COALESCE(payload->'documents_skipped', '[]'::jsonb)) as documents_skipped_count,
payload->'documents_required' as documents_required,
payload->'documents_uploaded' as documents_uploaded,
payload->'documents_skipped' as documents_skipped,
created_at,
updated_at
FROM clpr_claims
WHERE id::text = $1
OR payload->>'claim_id' = $1
ORDER BY updated_at DESC
LIMIT 1
"""
row = await conn.fetchrow(query, CLAIM_ID)
if not row:
print(f"❌ Жалоба с claim_id '{CLAIM_ID}' не найдена")
return
print("=" * 80)
print(f"📋 Статус жалобы: {CLAIM_ID}")
print("=" * 80)
print(f"ID в БД: {row['id']}")
print(f"Status Code: {row['status_code']}")
print(f"Claim ID: {row['claim_id']}")
print(f"Current Doc Index: {row['current_doc_index']}")
print(f"\n📊 Статистика документов:")
print(f" - Требуется документов: {row['documents_required_count']}")
print(f" - Загружено документов: {row['documents_uploaded_count']}")
print(f" - Пропущено документов: {row['documents_skipped_count']}")
print(f"\n📅 Даты:")
print(f" - Создано: {row['created_at']}")
print(f" - Обновлено: {row['updated_at']}")
documents_required = row['documents_required'] if isinstance(row['documents_required'], list) else (json.loads(row['documents_required']) if isinstance(row['documents_required'], str) else [])
documents_uploaded = row['documents_uploaded'] if isinstance(row['documents_uploaded'], list) else (json.loads(row['documents_uploaded']) if isinstance(row['documents_uploaded'], str) else [])
documents_skipped = row['documents_skipped'] if isinstance(row['documents_skipped'], list) else (json.loads(row['documents_skipped']) if isinstance(row['documents_skipped'], str) else [])
if documents_required:
print(f"\n📄 Требуемые документы:")
for idx, doc in enumerate(documents_required):
doc_obj = doc if isinstance(doc, dict) else json.loads(doc) if isinstance(doc, str) else {}
print(f" {idx}. {doc_obj.get('name', doc_obj.get('id', 'unknown'))} (id: {doc_obj.get('id', 'unknown')})")
if documents_uploaded:
print(f"\n✅ Загруженные документы:")
for doc in documents_uploaded:
doc_obj = doc if isinstance(doc, dict) else json.loads(doc) if isinstance(doc, str) else {}
print(f" - {doc_obj.get('id', 'unknown')}: {doc_obj.get('file_name', 'N/A')}")
if documents_skipped:
print(f"\n⏭️ Пропущенные документы:")
for doc in documents_skipped:
doc_obj = doc if isinstance(doc, dict) else json.loads(doc) if isinstance(doc, str) else {}
group_idx = doc_obj.get('group_index', 'N/A')
print(f" - {doc_obj.get('id', 'unknown')} (group_index: {group_idx}): {doc_obj.get('name', 'N/A')}")
print("\n" + "=" * 80)
# Определяем, что должно происходить дальше
status = row['status_code']
uploaded = row['documents_uploaded_count'] or 0
skipped = row['documents_skipped_count'] or 0
required = row['documents_required_count'] or 0
print(f"\n🔍 Анализ статуса:")
if status == 'draft_docs_complete':
print("Все документы обработаны (загружены или пропущены)")
print(" 📝 Должно происходить: формирование заявления (wizard generation)")
elif status == 'draft_docs_progress':
print(" ⏳ Документы загружаются")
remaining = required - uploaded - skipped
print(f" 📊 Осталось обработать: {remaining} документов")
elif status == 'draft_new':
print(" 🆕 Новая жалоба, только описание")
elif status == 'draft_claim_ready':
print(" ✅ Заявление готово к отправке")
else:
print(f" ⚠️ Неизвестный статус: {status}")
except Exception as e:
print(f"❌ Ошибка: {e}")
import traceback
traceback.print_exc()
finally:
if conn:
await conn.close()
if __name__ == "__main__":
asyncio.run(check_claim_status())

View File

@@ -0,0 +1,124 @@
#!/usr/bin/env python3
"""
Детальная проверка документов в черновике
"""
import asyncio
import asyncpg
import json
POSTGRES_HOST = "147.45.189.234"
POSTGRES_PORT = 5432
POSTGRES_DB = "default_db"
POSTGRES_USER = "gen_user"
POSTGRES_PASSWORD = "2~~9_^kVsU?2\\S"
CLAIM_ID = "bddb6815-8e17-4d54-a721-5e94382942c7"
async def check_documents_detailed():
conn = await asyncpg.connect(
host=POSTGRES_HOST,
port=POSTGRES_PORT,
database=POSTGRES_DB,
user=POSTGRES_USER,
password=POSTGRES_PASSWORD
)
try:
row = await conn.fetchrow("""
SELECT id, status_code, payload, updated_at
FROM clpr_claims
WHERE id::text = $1 OR payload->>'claim_id' = $1
ORDER BY updated_at DESC
LIMIT 1
""", CLAIM_ID)
if not row:
print(f"❌ Черновик {CLAIM_ID} не найден!")
return
payload = row['payload'] if isinstance(row['payload'], dict) else json.loads(row['payload'])
print("=" * 80)
print(f"📋 Статус жалобы: {CLAIM_ID}")
print("=" * 80)
print(f"Status Code: {row['status_code']}")
print(f"Обновлён: {row['updated_at']}")
# Статистика документов
documents_required = payload.get('documents_required', [])
documents_uploaded = payload.get('documents_uploaded', [])
documents_skipped = payload.get('documents_skipped', [])
current_doc_index = payload.get('current_doc_index', 0)
print(f"\n📊 Статистика документов:")
print(f" - Требуется документов: {len(documents_required)}")
print(f" - Загружено документов: {len(documents_uploaded)}")
print(f" - Пропущено документов: {len(documents_skipped)}")
print(f" - Current Doc Index: {current_doc_index}")
# Анализ статуса
print(f"\n🔍 Анализ статуса:")
status = row['status_code']
uploaded = len(documents_uploaded)
skipped = len(documents_skipped)
required = len(documents_required)
if status == 'draft_docs_complete':
print("Все документы обработаны (загружены или пропущены)")
print(" 📝 Должно происходить: формирование заявления (wizard generation)")
elif status == 'draft_docs_progress':
print(" ⏳ Документы загружаются")
remaining = required - uploaded - skipped
print(f" 📊 Осталось обработать: {remaining} документов")
elif status == 'draft_new':
print(" 🆕 Новая жалоба, только описание")
elif status == 'draft_claim_ready':
print(" ✅ Заявление готово к отправке")
else:
print(f" ⚠️ Статус: {status}")
print("=" * 80)
print(f"\n📋 documents_meta ({len(payload.get('documents_meta', []))} шт.):")
for i, doc in enumerate(payload.get('documents_meta', [])):
print(f" {i+1}. {doc.get('field_label', 'N/A')}")
print(f" file_id: {doc.get('file_id', 'N/A')[:80]}...")
print(f" field_name: {doc.get('field_name', 'N/A')}")
print(f"\n📋 documents_uploaded ({len(payload.get('documents_uploaded', []))} шт.):")
for i, doc in enumerate(payload.get('documents_uploaded', [])):
print(f" {i+1}. Тип: {doc.get('type', 'N/A')} / {doc.get('id', 'N/A')}")
print(f" file_id: {doc.get('file_id', 'N/A')[:80]}...")
print(f" original_file_name: {doc.get('original_file_name', 'N/A')}")
print(f"\n📋 documents_required ({len(payload.get('documents_required', []))} шт.):")
for i, doc in enumerate(payload.get('documents_required', [])):
print(f" {i+1}. {doc.get('name', 'N/A')} (id: {doc.get('id', 'N/A')})")
print(f"\n📋 current_doc_index: {payload.get('current_doc_index', 'N/A')}")
# Проверяем уникальность file_id
print(f"\n🔍 Проверка уникальности file_id:")
documents_meta = payload.get('documents_meta', [])
file_ids_meta = [doc.get('file_id') for doc in documents_meta if doc.get('file_id')]
unique_file_ids_meta = list(set(file_ids_meta))
print(f" documents_meta: всего {len(file_ids_meta)}, уникальных {len(unique_file_ids_meta)}")
if len(file_ids_meta) != len(unique_file_ids_meta):
print(f" ⚠️ ЕСТЬ ДУБЛИКАТЫ!")
from collections import Counter
duplicates = [fid for fid, count in Counter(file_ids_meta).items() if count > 1]
for dup in duplicates:
print(f" - {dup[:80]}... (встречается {Counter(file_ids_meta)[dup]} раз)")
documents_uploaded = payload.get('documents_uploaded', [])
file_ids_uploaded = [doc.get('file_id') for doc in documents_uploaded if doc.get('file_id')]
unique_file_ids_uploaded = list(set(file_ids_uploaded))
print(f" documents_uploaded: всего {len(file_ids_uploaded)}, уникальных {len(unique_file_ids_uploaded)}")
if len(file_ids_uploaded) != len(unique_file_ids_uploaded):
print(f" ⚠️ ЕСТЬ ДУБЛИКАТЫ!")
finally:
await conn.close()
if __name__ == "__main__":
asyncio.run(check_documents_detailed())

View File

@@ -0,0 +1,118 @@
#!/usr/bin/env python3
"""
Проверка несоответствия между documents_uploaded и clpr_claim_documents
"""
import asyncio
import asyncpg
import json
POSTGRES_HOST = "147.45.189.234"
POSTGRES_PORT = 5432
POSTGRES_DB = "default_db"
POSTGRES_USER = "gen_user"
POSTGRES_PASSWORD = "2~~9_^kVsU?2\\S"
CLAIM_ID = "bddb6815-8e17-4d54-a721-5e94382942c7"
async def check_mismatch():
conn = await asyncpg.connect(
host=POSTGRES_HOST,
port=POSTGRES_PORT,
database=POSTGRES_DB,
user=POSTGRES_USER,
password=POSTGRES_PASSWORD
)
try:
# Находим UUID claim
claim_row = await conn.fetchrow("""
SELECT id FROM clpr_claims
WHERE id::text = $1 OR payload->>'claim_id' = $1
ORDER BY updated_at DESC
LIMIT 1
""", CLAIM_ID)
if not claim_row:
print(f"❌ Черновик {CLAIM_ID} не найден!")
return
claim_uuid = claim_row['id']
# Получаем payload
payload_row = await conn.fetchrow("""
SELECT payload FROM clpr_claims WHERE id = $1
""", claim_uuid)
payload = payload_row['payload'] if isinstance(payload_row['payload'], dict) else json.loads(payload_row['payload'])
# Получаем документы из таблицы
table_docs = await conn.fetch("""
SELECT
ccd.id,
ccd.claim_id,
ccd.field_name,
ccd.file_id,
ccd.file_name,
ccd.original_file_name,
ccd.uploaded_at
FROM clpr_claim_documents ccd
WHERE ccd.claim_id = $1
ORDER BY ccd.uploaded_at DESC
""", str(claim_uuid))
print(f"📋 Документы в таблице clpr_claim_documents ({len(table_docs)} шт.):")
for i, doc in enumerate(table_docs):
print(f" {i+1}. field_name: {doc['field_name']}")
print(f" file_id: {doc['file_id']}")
print(f" file_name: {doc['file_name']}")
print(f" original_file_name: {doc['original_file_name']}")
print(f" uploaded_at: {doc['uploaded_at']}")
print(f"\n📋 Документы в documents_uploaded ({len(payload.get('documents_uploaded', []))} шт.):")
for i, doc in enumerate(payload.get('documents_uploaded', [])):
print(f" {i+1}. Тип: {doc.get('type', 'N/A')} / {doc.get('id', 'N/A')}")
print(f" file_id: {doc.get('file_id', 'N/A')}")
print(f" original_file_name: {doc.get('original_file_name', 'N/A')}")
print(f"\n📋 Документы в documents_meta ({len(payload.get('documents_meta', []))} шт.):")
for i, doc in enumerate(payload.get('documents_meta', [])):
print(f" {i+1}. field_label: {doc.get('field_label', 'N/A')}")
print(f" field_name: {doc.get('field_name', 'N/A')}")
print(f" file_id: {doc.get('file_id', 'N/A')}")
# Проверяем, какие документы из documents_uploaded отсутствуют в таблице
print(f"\n🔍 Проверка отсутствующих документов:")
table_file_ids = {doc['file_id'] for doc in table_docs}
uploaded_file_ids = {doc.get('file_id') for doc in payload.get('documents_uploaded', []) if doc.get('file_id')}
missing_in_table = uploaded_file_ids - table_file_ids
if missing_in_table:
print(f" ⚠️ В documents_uploaded есть, но нет в таблице ({len(missing_in_table)} шт.):")
for file_id in missing_in_table:
doc = next((d for d in payload.get('documents_uploaded', []) if d.get('file_id') == file_id), None)
if doc:
print(f" - {doc.get('type', 'N/A')}: {file_id[:80]}...")
print(f" original_file_name: {doc.get('original_file_name', 'N/A')}")
else:
print(f"Все документы из documents_uploaded есть в таблице")
# Проверяем field_name
print(f"\n🔍 Проверка field_name:")
table_field_names = {doc['field_name'] for doc in table_docs}
meta_field_names = {doc.get('field_name') for doc in payload.get('documents_meta', []) if doc.get('field_name')}
print(f" В таблице: {sorted(table_field_names)}")
print(f" В documents_meta: {sorted(meta_field_names)}")
# Проверяем, есть ли конфликты по field_name
if len(table_docs) < len(payload.get('documents_uploaded', [])):
print(f"\n ⚠️ Возможная причина: несколько документов с одинаковым field_name")
print(f" В таблице используется UNIQUE constraint на (claim_id, field_name)")
print(f" Если два документа имеют одинаковый field_name, второй перезапишет первый")
finally:
await conn.close()
if __name__ == "__main__":
asyncio.run(check_mismatch())

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env python3
"""
Проверка документов в черновике
"""
import asyncio
import asyncpg
import json
POSTGRES_HOST = "147.45.189.234"
POSTGRES_PORT = 5432
POSTGRES_DB = "default_db"
POSTGRES_USER = "gen_user"
POSTGRES_PASSWORD = "2~~9_^kVsU?2\\S"
CLAIM_ID = "bddb6815-8e17-4d54-a721-5e94382942c7"
async def check_documents():
conn = await asyncpg.connect(
host=POSTGRES_HOST,
port=POSTGRES_PORT,
database=POSTGRES_DB,
user=POSTGRES_USER,
password=POSTGRES_PASSWORD
)
try:
row = await conn.fetchrow("""
SELECT id, status_code, payload
FROM clpr_claims
WHERE id::text = $1 OR payload->>'claim_id' = $1
ORDER BY updated_at DESC
LIMIT 1
""", CLAIM_ID)
if not row:
print(f"❌ Черновик {CLAIM_ID} не найден!")
return
payload = row['payload'] if isinstance(row['payload'], dict) else json.loads(row['payload'])
print("📋 documents_meta:")
for i, doc in enumerate(payload.get('documents_meta', [])):
print(f" {i+1}. {doc.get('field_label', 'N/A')} - {doc.get('file_id', 'N/A')}")
print("\n📋 documents_uploaded:")
for i, doc in enumerate(payload.get('documents_uploaded', [])):
print(f" {i+1}. {doc.get('type', 'N/A')} / {doc.get('id', 'N/A')} - {doc.get('file_id', 'N/A')}")
print("\n📋 Все file_id в payload:")
# Ищем все file_id в payload
payload_str = json.dumps(payload, ensure_ascii=False)
import re
file_ids = re.findall(r'file_id["\']?\s*:\s*["\']([^"\']+)', payload_str)
for file_id in set(file_ids):
print(f" - {file_id}")
finally:
await conn.close()
if __name__ == "__main__":
asyncio.run(check_documents())

Some files were not shown because too many files have changed in this diff Show More