Files
crm.clientright.ru/DOC_TEMPLATE_MODULE_MANUAL.md
Fedor 01c4fe80b5 chore: snapshot current working tree changes
Save all currently accumulated repository changes as a backup snapshot for Gitea so no local work is lost.
2026-03-26 14:19:01 +03:00

934 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

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

# 📘 МОДУЛЬ DocTemplate - ПОЛНЫЙ МАНУАЛ
**Версия:** 1.0
**Дата:** 2026-01-22
**Статус:** План реализации
---
## 📋 СОДЕРЖАНИЕ
1. [Обзор модуля](#обзор-модуля)
2. [Архитектура](#архитектура)
3. [Структура модуля](#структура-модуля)
4. [База данных](#база-данных)
5. [Процесс работы](#процесс-работы)
6. [Интерфейс пользователя](#интерфейс-пользователя)
7. [Технические детали](#технические-детали)
8. [Интеграция с PDFMaker](#интеграция-с-pdfmaker)
9. [План реализации](#план-реализации)
---
## 🎯 ОБЗОР МОДУЛЯ
### **Назначение**
Модуль `DocTemplate` предназначен для генерации документов (DOCX) из шаблонов Nextcloud с автоматическим заполнением переменных данными из модулей CRM.
### **Основные возможности**
- ✅ Создание и редактирование шаблонов документов
- ✅ Автоматическое заполнение переменных данными из CRM
- ✅ Поддержка связанных модулей
- ✅ Интеграция с OnlyOffice для редактирования
- ✅ Сохранение готовых документов в S3
- ✅ Двухпанельный редактор (переменные + OnlyOffice)
### **Аналогия**
Модуль аналогичен PDFMaker, но работает с DOCX файлами вместо PDF и использует шаблоны из Nextcloud.
---
## 🏗️ АРХИТЕКТУРА
### **Общая схема**
```
┌─────────────────────────────────────────────────────────────┐
│ NEXTCLOUD │
│ /Templates/ │
│ ├── pretenziya.docx ← ФИЗИЧЕСКИЕ ФАЙЛЫ │
│ ├── iskovoe_zayavlenie.docx │
│ └── soglashenie.docx │
└─────────────────────────────────────────────────────────────┘
│ WebDAV (скачивание/загрузка)
┌─────────────────────────────────────────────────────────────┐
│ CRM MODULE DocTemplate │
│ │
│ База данных: │
│ ┌─────────────────────────────────────┐ │
│ │ vtiger_doctemplate │ │
│ │ - templateid │ │
│ │ - templatename: "Претензия" │ │
│ │ - filename: "pretenziya.docx" │ ← Ссылка │
│ │ - module: "Project" │ │
│ │ - mapping: { │ │
│ │ "CLIENT_NAME": "$PROJECT_..." │ │
│ │ } │ │
│ └─────────────────────────────────────┘ │
│ │
│ Процесс генерации: │
│ 1. Получить метаданные из БД │
│ 2. Скачать шаблон из Nextcloud │
│ 3. Получить данные записи (CRMEntity) │
│ 4. Заполнить переменные по маппингу │
│ 5. Сохранить в S3 │
│ 6. Открыть в OnlyOffice │
└─────────────────────────────────────────────────────────────┘
```
### **Разделение ответственности**
- **Nextcloud:** Хранение физических файлов шаблонов (DOCX)
- **CRM:** Метаданные, маппинг переменных, логика генерации
- **S3:** Хранение готовых документов
- **OnlyOffice:** Редактирование шаблонов и готовых документов
---
## 📁 СТРУКТУРА МОДУЛЯ
```
modules/DocTemplate/
├── DocTemplate.php # Основной класс модуля
├── schema.xml # Схема БД (таблицы)
├── language/ # Языковые файлы
│ └── ru_ru.lang.php
├── models/ # Модели
│ ├── Module.php # Модель модуля
│ ├── Record.php # Модель записи
│ ├── Template.php # Модель шаблона
│ ├── TemplateGenerator.php # Генератор документов
│ ├── VariableProcessor.php # Обработчик переменных
│ ├── VariableExtractor.php # Извлечение переменных из DOCX
│ └── FieldMapper.php # Маппер полей
├── views/ # Представления
│ ├── List.php # Список шаблонов
│ ├── Detail.php # Детальный вид шаблона
│ ├── Edit.php # Редактирование шаблона (двухпанельный)
│ └── Create.php # Создание шаблона
├── actions/ # Действия
│ ├── GenerateDocument.php # Генерация документа
│ ├── ListTemplates.php # Список шаблонов для модуля
│ ├── ExtractVariables.php # Извлечение переменных из DOCX
│ ├── SaveMapping.php # Сохранение маппинга
│ ├── GetModuleFields.php # Получение списка полей модуля
│ ├── SaveTemplateContent.php # Сохранение содержимого шаблона
│ └── OnlyOfficeCallback.php # Callback от OnlyOffice
├── resources/ # Ресурсы
│ ├── DocTemplate.js # JS для UI
│ ├── DocTemplate.css # Стили
│ └── images/ # Иконки
└── helpers/ # Вспомогательные классы
└── NextcloudClient.php # Клиент Nextcloud (WebDAV)
```
---
## 🗄️ БАЗА ДАННЫХ
### **Таблица: `vtiger_doctemplate`**
Основная таблица для хранения шаблонов:
```sql
CREATE TABLE `vtiger_doctemplate` (
`templateid` int(11) NOT NULL AUTO_INCREMENT,
`templatename` varchar(255) NOT NULL, -- "Претензия"
`filename` varchar(255) NOT NULL, -- "pretenziya.docx"
`module` varchar(100) NOT NULL, -- "Project"
`description` text, -- Описание шаблона
`mapping` longtext, -- JSON маппинг переменных
`nextcloud_path` varchar(255) DEFAULT '/Templates/', -- Путь в Nextcloud
`is_active` tinyint(1) DEFAULT '1',
`owner` int(11) NOT NULL,
`createdtime` datetime NOT NULL,
`modifiedtime` datetime NOT NULL,
`deleted` tinyint(1) DEFAULT '0',
PRIMARY KEY (`templateid`)
) ENGINE=InnoDB;
```
**Пример записи:**
```json
{
"templateid": 1,
"templatename": "Претензия",
"filename": "pretenziya.docx",
"module": "Project",
"description": "Шаблон претензии для проектов",
"mapping": {
"CLIENT_NAME": "$PROJECT_PROJECTNAME$",
"DATE": "$PROJECT_CREATEDTIME$",
"AMOUNT": "$PROJECT_CF_1885$",
"CONTACT_NAME": "$CONTACTS_LASTNAME$"
},
"nextcloud_path": "/Templates/"
}
```
### **Таблица: `vtiger_doctemplate_seq`**
Счетчик для генерации ID:
```sql
CREATE TABLE `vtiger_doctemplate_seq` (
`id` int(11) NOT NULL DEFAULT '1'
) ENGINE=InnoDB;
```
### **Таблица: `vtiger_doctemplate_settings`**
Настройки шаблона:
```sql
CREATE TABLE `vtiger_doctemplate_settings` (
`templateid` int(11) NOT NULL,
`output_folder` varchar(255), -- Папка для сохранения готовых документов
`file_naming` varchar(255), -- Правило именования файлов
`auto_open` tinyint(1) DEFAULT '1', -- Автоматически открывать после генерации
`owner` int(11) NOT NULL,
`sharingtype` char(7) DEFAULT 'public',
PRIMARY KEY (`templateid`)
) ENGINE=InnoDB;
```
---
## 🔄 ПРОЦЕСС РАБОТЫ
### **1. Создание шаблона**
#### **Сценарий A: Создание пустого шаблона**
```
1. Пользователь создает запись шаблона в CRM
- Название: "Претензия"
- Модуль: Project
- Имя файла: pretenziya.docx
2. CRM создает пустой DOCX через PHPWord
3. CRM загружает файл в Nextcloud /Templates/
4. Открывается редактор (двухпанельный интерфейс)
```
#### **Сценарий B: Загрузка существующего файла**
```
1. Пользователь загружает DOCX файл через интерфейс CRM
2. CRM загружает файл в Nextcloud /Templates/
3. CRM создает запись в БД
4. CRM автоматически находит переменные в документе
5. Показывается форма настройки маппинга
```
---
### **2. Редактирование шаблона**
#### **Двухпанельный интерфейс:**
```
┌─────────────────────────────────────────────────────────┐
│ Редактирование: Претензия [💾 Сохранить] │
├──────────────┬──────────────────────────────────────────┤
│ │ │
│ ПЕРЕМЕННЫЕ │ ONLYOFFICE РЕДАКТОР │
│ │ ┌────────────────────────────────────┐ │
│ [🔍 Поиск] │ │ │ │
│ │ │ ПРЕТЕНЗИЯ │ │
│ Прямые поля: │ │ │ │
│ • projectname│ │ От: {CLIENT_NAME} │ │
│ • createdtime│ │ Дата: {DATE} │ │
│ • cf_1885 │ │ │ │
│ │ │ Сумма: {AMOUNT} │ │
│ Связанные: │ │ │ │
│ • Contacts │ │ │ │
│ - lastname │ └────────────────────────────────────┘ │
│ │ │
│ Функции: │ │
│ • formatDate │ │
│ │ │
└──────────────┴──────────────────────────────────────────┘
```
**Как работает:**
1. **Левая панель:** Список полей модуля (через `PDFMaker_Fields_Model`)
2. **Правая панель:** OnlyOffice редактор в iframe
3. **Клик по переменной:** Копируется в буфер обмена → вставить в документ (Ctrl+V)
4. **Сохранение:** Документ сохраняется в Nextcloud → CRM находит переменные → настройка маппинга
---
### **3. Настройка маппинга**
После сохранения шаблона CRM автоматически:
1. Скачивает DOCX из Nextcloud
2. Парсит через PHPWord
3. Находит все переменные `{VAR_NAME}`
4. Показывает форму настройки:
```
┌─────────────────────────────────────────────────────────┐
│ Настройка маппинга для "Претензия" │
├─────────────────────────────────────────────────────────┤
│ │
│ Найдены переменные: │
│ │
│ Переменная → Поле модуля │
│ ┌─────────────┐ ┌──────────────────────────────┐ │
│ │ CLIENT_NAME │ → │ $PROJECT_PROJECTNAME$ │ │
│ │ DATE │ → │ $PROJECT_CREATEDTIME$ │ │
│ │ AMOUNT │ → │ $PROJECT_CF_1885$ │ │
│ └─────────────┘ └──────────────────────────────┘ │
│ │
│ [+ Добавить переменную] │
│ │
│ [💾 Сохранить маппинг] │
│ │
└─────────────────────────────────────────────────────────┘
```
---
### **4. Генерация документа**
#### **Процесс:**
```
1. Пользователь в детальном виде записи (Project, HelpDesk, etc.)
нажимает кнопку "Создать из шаблона"
2. Показывается список шаблонов для модуля
3. Пользователь выбирает шаблон
4. CRM выполняет:
a. Получает метаданные шаблона из БД
b. Скачивает шаблон из Nextcloud (WebDAV)
c. Получает данные записи через CRMEntity
d. Заполняет переменные по маппингу
e. Сохраняет готовый документ в S3
f. Открывает документ в OnlyOffice
```
#### **Алгоритм генерации:**
```php
// Псевдокод
function generate($module, $recordId, $templateId) {
// 1. Получить шаблон
$template = getTemplate($templateId);
// 2. Скачать из Nextcloud
$docxContent = downloadFromNextcloud($template->filename);
// 3. Получить данные записи (как PDFMaker)
$focus = CRMEntity::getInstance($module);
$focus->retrieve_entity_info($recordId, $module);
// 4. Построить переменные из маппинга
$variables = buildVariables($template->mapping, $focus, $module);
// 5. Заменить переменные в DOCX
$filledContent = replaceVariables($docxContent, $variables);
// 6. Сохранить в S3
$filePath = saveToS3($filledContent, $module, $recordId);
// 7. Вернуть URL для OnlyOffice
return getOnlyOfficeUrl($filePath);
}
```
---
## 🎨 ИНТЕРФЕЙС ПОЛЬЗОВАТЕЛЯ
### **1. Список шаблонов (List View)**
```
┌─────────────────────────────────────────────────────────┐
│ Шаблоны документов [+ Создать] │
├─────────────────────────────────────────────────────────┤
│ │
│ Название │ Модуль │ Файл │ Действия│
│ ───────────────────────────────────────────────────── │
│ Претензия │ Project │ pretenziya.docx │ [✏️][👁️]│
│ Исковое заявл. │ Project │ isk.docx │ [✏️][👁️]│
│ Соглашение │ Contacts │ soglashenie.docx │ [✏️][👁️]│
│ │
└─────────────────────────────────────────────────────────┘
```
### **2. Детальный вид шаблона**
```
┌─────────────────────────────────────────────────────────┐
│ Претензия [Редактировать] [×]│
├─────────────────────────────────────────────────────────┤
│ │
│ Модуль: Project │
│ Файл: pretenziya.docx │
│ Путь: /Templates/ │
│ │
│ [📝 Редактировать содержимое] │
│ → Откроет двухпанельный редактор │
│ │
│ ──────────────────────────────────────────────────── │
│ │
│ Маппинг переменных: │
│ ┌──────────────────────────────────────────────────┐ │
│ │ CLIENT_NAME → $PROJECT_PROJECTNAME$ │ │
│ │ DATE → $PROJECT_CREATEDTIME$ │ │
│ │ AMOUNT → $PROJECT_CF_1885$ │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ [+ Добавить переменную] │
│ │
│ [💾 Сохранить] │
│ │
└─────────────────────────────────────────────────────────┘
```
### **3. Кнопка в модулях CRM**
В детальном виде модулей (Project, HelpDesk, Contacts) добавляется кнопка:
```
[📄 Создать из шаблона]
```
При клике открывается диалог выбора шаблона.
---
## 🔧 ТЕХНИЧЕСКИЕ ДЕТАЛИ
### **1. Формат переменных**
#### **В шаблоне DOCX:**
Пользователь пишет переменные в формате:
```
{CLIENT_NAME}
{DATE}
{AMOUNT}
```
#### **В маппинге CRM:**
Используется формат PDFMaker:
```json
{
"CLIENT_NAME": "$PROJECT_PROJECTNAME$",
"DATE": "$PROJECT_CREATEDTIME$",
"AMOUNT": "$PROJECT_CF_1885$"
}
```
**Преимущества формата PDFMaker:**
- Префикс модуля (`PROJECT_`) позволяет различать поля
- Поддержка связанных модулей (`$CONTACTS_LASTNAME$`)
- Единый формат с существующей системой
---
### **2. Получение данных записи**
Используется подход PDFMaker:
```php
// Создать экземпляр модуля
$focus = CRMEntity::getInstance($module);
// Очистить поля
foreach ($focus->column_fields as $cf_key => $cf_value) {
$focus->column_fields[$cf_key] = '';
}
// Получить данные записи
$focus->retrieve_entity_info($recordId, $module);
$focus->id = $recordId;
// Все поля доступны через:
$focus->column_fields['fieldname']
```
**Преимущества:**
- Работает со всеми модулями
- Учитывает кастомные поля
- Автоматическое форматирование значений
---
### **3. Обработка переменных**
#### **Прямые поля модуля:**
```php
// Маппинг: "CLIENT_NAME" => "$PROJECT_PROJECTNAME$"
// Извлечение: PROJECT_PROJECTNAME → module=PROJECT, field=projectname
$value = $focus->column_fields['projectname'];
```
#### **Связанные модули:**
```php
// Маппинг: "CONTACT_NAME" => "$CONTACTS_LASTNAME$"
// Извлечение: CONTACTS_LASTNAME → module=CONTACTS, field=lastname
$value = getRelatedFieldValue($recordId, 'Contacts', 'lastname');
```
#### **Вычисляемые поля:**
```php
// Маппинг: "FULL_DATE" => {"type": "function", "function": "formatDate", "params": ["createdtime", "d.m.Y"]}
$value = formatDate($focus->column_fields['createdtime'], 'd.m.Y');
```
---
### **4. Замена переменных в DOCX**
Для DOCX файлов используется PHPWord:
```php
function replaceDocxVariables($docxContent, $variables) {
// Сохранить во временный файл
$tempFile = tempnam(sys_get_temp_dir(), 'template_') . '.docx';
file_put_contents($tempFile, $docxContent);
// Загрузить через PHPWord
$phpWord = \PhpOffice\PhpWord\IOFactory::load($tempFile);
// Заменить переменные во всех секциях
foreach ($phpWord->getSections() as $section) {
foreach ($section->getElements() as $element) {
if ($element instanceof \PhpOffice\PhpWord\Element\Text) {
$text = $element->getText();
$text = replaceVariables($text, $variables);
$element->setText($text);
}
}
}
// Сохранить результат
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
$outputFile = tempnam(sys_get_temp_dir(), 'output_') . '.docx';
$writer->save($outputFile);
$result = file_get_contents($outputFile);
// Удалить временные файлы
unlink($tempFile);
unlink($outputFile);
return $result;
}
```
---
### **5. Интеграция с Nextcloud**
#### **Скачивание шаблона:**
```php
function downloadFromNextcloud($filename, $path = '/Templates/') {
$nextcloudUrl = 'https://office.clientright.ru:8443';
$username = 'admin';
$password = 'office';
$webdavUrl = $nextcloudUrl . '/remote.php/dav/files/' .
$username . $path . $filename;
$ch = curl_init($webdavUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$content = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("Шаблон не найден: {$filename}");
}
return $content;
}
```
#### **Загрузка шаблона:**
```php
function uploadToNextcloud($localFile, $filename, $path = '/Templates/') {
$nextcloudUrl = 'https://office.clientright.ru:8443';
$username = 'admin';
$password = 'office';
$webdavUrl = $nextcloudUrl . '/remote.php/dav/files/' .
$username . $path . $filename;
$ch = curl_init($webdavUrl);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, fopen($localFile, 'r'));
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localFile));
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 201 && $httpCode !== 204) {
throw new Exception("Ошибка загрузки в Nextcloud");
}
}
```
---
## 🔗 ИНТЕГРАЦИЯ С PDFMAKER
### **Что используем из PDFMaker:**
1. **Формат переменных:** `$MODULE_FIELDNAME$`
2. **Получение данных:** `CRMEntity::getInstance()` + `retrieve_entity_info()`
3. **Список полей:** `PDFMaker_Fields_Model::getSelectModuleFields()`
4. **Обработка типов полей:** `PDFMaker_PDFContentUtils_Model::getUITypeName()`
### **Преимущества:**
- ✅ Переиспользование проверенной логики
- ✅ Единый формат с существующей системой
- ✅ Поддержка связанных модулей из коробки
- ✅ Автоматическое форматирование полей
---
## 📋 ПЛАН РЕАЛИЗАЦИИ
### **Этап 1: Базовая структура модуля**
**Задачи:**
1. Создать структуру папок `modules/DocTemplate/`
2. Создать `DocTemplate.php` (основной класс)
3. Создать `schema.xml` с таблицами БД
4. Создать базовые модели (`Module.php`, `Record.php`, `Template.php`)
5. Зарегистрировать модуль в системе
**Файлы:**
- `modules/DocTemplate/DocTemplate.php`
- `modules/DocTemplate/schema.xml`
- `modules/DocTemplate/models/Module.php`
- `modules/DocTemplate/models/Record.php`
- `modules/DocTemplate/models/Template.php`
---
### **Этап 2: Интеграция с Nextcloud**
**Задачи:**
1. Создать `helpers/NextcloudClient.php` (WebDAV клиент)
2. Реализовать скачивание шаблонов
3. Реализовать загрузку шаблонов
4. Реализовать проверку существования файлов
**Файлы:**
- `modules/DocTemplate/helpers/NextcloudClient.php`
---
### **Этап 3: Генератор документов**
**Задачи:**
1. Создать `models/TemplateGenerator.php`
2. Интегрировать с PDFMaker (получение данных через CRMEntity)
3. Реализовать обработку переменных
4. Реализовать замену переменных в DOCX через PHPWord
5. Реализовать сохранение в S3
**Файлы:**
- `modules/DocTemplate/models/TemplateGenerator.php`
- `modules/DocTemplate/models/VariableProcessor.php`
---
### **Этап 4: Извлечение переменных**
**Задачи:**
1. Создать `models/VariableExtractor.php`
2. Реализовать парсинг DOCX через PHPWord
3. Реализовать поиск переменных `{VAR_NAME}`
4. Интегрировать с процессом сохранения шаблона
**Файлы:**
- `modules/DocTemplate/models/VariableExtractor.php`
---
### **Этап 5: UI - Список и детальный вид**
**Задачи:**
1. Создать `views/List.php` (список шаблонов)
2. Создать `views/Detail.php` (детальный вид)
3. Создать `views/Create.php` (создание шаблона)
4. Добавить языковые файлы
**Файлы:**
- `modules/DocTemplate/views/List.php`
- `modules/DocTemplate/views/Detail.php`
- `modules/DocTemplate/views/Create.php`
- `modules/DocTemplate/language/ru_ru.lang.php`
---
### **Этап 6: UI - Двухпанельный редактор**
**Задачи:**
1. Создать `views/Edit.php` (двухпанельный интерфейс)
2. Создать `resources/DocTemplate.js` (JS для редактора)
3. Создать `resources/DocTemplate.css` (стили)
4. Интегрировать OnlyOffice в iframe
5. Реализовать вставку переменных (копирование в буфер)
**Файлы:**
- `modules/DocTemplate/views/Edit.php`
- `modules/DocTemplate/resources/DocTemplate.js`
- `modules/DocTemplate/resources/DocTemplate.css`
---
### **Этап 7: Actions (API endpoints)**
**Задачи:**
1. Создать `actions/GenerateDocument.php`
2. Создать `actions/ListTemplates.php`
3. Создать `actions/ExtractVariables.php`
4. Создать `actions/SaveMapping.php`
5. Создать `actions/GetModuleFields.php`
6. Создать `actions/SaveTemplateContent.php`
**Файлы:**
- `modules/DocTemplate/actions/GenerateDocument.php`
- `modules/DocTemplate/actions/ListTemplates.php`
- `modules/DocTemplate/actions/ExtractVariables.php`
- `modules/DocTemplate/actions/SaveMapping.php`
- `modules/DocTemplate/actions/GetModuleFields.php`
- `modules/DocTemplate/actions/SaveTemplateContent.php`
---
### **Этап 8: Интеграция с модулями CRM**
**Задачи:**
1. Добавить кнопку "Создать из шаблона" в модули (Project, HelpDesk, Contacts)
2. Создать JavaScript для диалога выбора шаблона
3. Реализовать генерацию документа из детального вида
**Файлы:**
- `modules/DocTemplate/DocTemplate.php` (метод `addCustomLinks()`)
- `modules/DocTemplate/resources/DocTemplate.js` (функция `showTemplateDialog()`)
---
### **Этап 9: Тестирование**
**Задачи:**
1. Тестирование создания шаблонов
2. Тестирование редактирования шаблонов
3. Тестирование генерации документов
4. Тестирование на разных модулях
5. Проверка производительности
6. Обработка ошибок
---
## 🔑 КЛЮЧЕВЫЕ КОМПОНЕНТЫ
### **1. DocTemplate_TemplateGenerator_Model**
**Назначение:** Генерация документов из шаблонов
**Основные методы:**
- `generate($module, $recordId, $templateId)` - основная функция генерации
- `downloadFromNextcloud($filename, $path)` - скачивание шаблона
- `buildVariables($mapping, $focus, $module)` - построение переменных
- `replaceVariables($content, $variables)` - замена переменных
- `saveToS3($content, $module, $recordId, $template)` - сохранение в S3
---
### **2. DocTemplate_VariableProcessor_Model**
**Назначение:** Обработка переменных из маппинга
**Основные методы:**
- `process($config, $focus, $module)` - обработка переменной
- `getFieldValue($fieldConfig, $focus, $module)` - получение значения поля
- `getRelatedFieldValue($recordId, $relatedModule, $fieldName)` - связанные модули
- `callFunction($functionName, $params, $focus, $module)` - вызов функций
---
### **3. DocTemplate_VariableExtractor_Model**
**Назначение:** Извлечение переменных из DOCX
**Основные методы:**
- `extractVariables($docxContent)` - извлечение всех переменных
- `extractTextFromElement($element)` - извлечение текста из элемента PHPWord
---
### **4. DocTemplate_NextcloudClient_Helper**
**Назначение:** Работа с Nextcloud через WebDAV
**Основные методы:**
- `download($filename, $path)` - скачивание файла
- `upload($localFile, $filename, $path)` - загрузка файла
- `exists($filename, $path)` - проверка существования
- `listFiles($path)` - список файлов в папке
---
## 📊 ФОРМАТ МАППИНГА
### **JSON в поле `mapping`:**
```json
{
"CLIENT_NAME": "$PROJECT_PROJECTNAME$",
"DATE": "$PROJECT_CREATEDTIME$",
"AMOUNT": "$PROJECT_CF_1885$",
"CONTACT_NAME": "$CONTACTS_LASTNAME$",
"FULL_DATE": {
"type": "function",
"function": "formatDate",
"params": ["createdtime", "d.m.Y"]
},
"COMPANY_NAME": {
"type": "constant",
"value": "ООО \"Клиент Право\""
}
}
```
---
## 🎯 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
### **Пример 1: Создание шаблона претензии**
1. Создать запись шаблона в CRM:
- Название: "Претензия"
- Модуль: Project
- Файл: pretenziya.docx
2. Открыть редактор, написать:
```
ПРЕТЕНЗИЯ
Кому: УК "Жилищник"
От: {CLIENT_NAME}
Дата: {DATE}
Текст: {CLAIM_TEXT}
Сумма: {AMOUNT} рублей
```
3. Сохранить → CRM находит переменные
4. Настроить маппинг:
- CLIENT_NAME → $PROJECT_PROJECTNAME$
- DATE → $PROJECT_CREATEDTIME$
- CLAIM_TEXT → $PROJECT_DESCRIPTION$
- AMOUNT → $PROJECT_CF_1885$
5. Готово!
---
### **Пример 2: Генерация документа**
1. Открыть проект в CRM (recordId=400264)
2. Нажать "Создать из шаблона"
3. Выбрать шаблон "Претензия"
4. CRM:
- Скачивает pretenziya.docx из Nextcloud
- Получает данные проекта 400264
- Заполняет переменные:
- {CLIENT_NAME} → "Проект_1"
- {DATE} → "15.01.2025"
- {AMOUNT} → "400000"
- Сохраняет готовый документ в S3
- Открывает в OnlyOffice
---
## ⚠️ ОГРАНИЧЕНИЯ И ЗАМЕЧАНИЯ
1. **PHPWord работает только с DOCX**
- Для XLSX и PPTX используется простая замена текста
- Сложное форматирование может не сохраниться
2. **Переменные должны быть в тексте**
- Не работают в заголовках/колонтитулах (ограничение PHPWord)
- Не работают в таблицах (частично)
3. **Размер шаблона**
- Большие шаблоны (>10MB) могут загружаться медленно
4. **OnlyOffice API**
- Прямая вставка переменных через API требует настройки OnlyOffice Document Server
- Начальная реализация использует копирование в буфер обмена
---
## 🚀 ГОТОВНОСТЬ К РЕАЛИЗАЦИИ
**Все компоненты спроектированы:**
- ✅ Архитектура определена
- ✅ Структура модуля спроектирована
- ✅ База данных спроектирована
- ✅ UI/UX продуман
- ✅ Интеграция с PDFMaker определена
- ✅ Процессы описаны
**Следующий шаг:** Начать реализацию с Этапа 1 (базовая структура модуля)
---
## 📚 ССЫЛКИ НА ДОПОЛНИТЕЛЬНЫЕ ДОКУМЕНТЫ
- [План создания модуля](DOC_TEMPLATE_MODULE_PLAN.md)
- [Архитектура Nextcloud + CRM](DOC_TEMPLATE_ARCHITECTURE.md)
- [UX дизайн](DOC_TEMPLATE_UX_DESIGN.md)
- [Вставка переменных](DOC_TEMPLATE_VARIABLES_INSERTION.md)
- [Интерфейс редактора](DOC_TEMPLATE_EDITOR_UI.md)
- [Анализ PDFMaker](PDFMAKER_ANALYSIS.md)
---
**Модуль готов к реализации! 🎉**