Files
public/mklab_base_indicators/TECHNICAL.md

205 lines
10 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.

# Слои показателей - Базовый модуль
**name**: mklab_base_indicators
**version**: 19.0.2025.11.17
**author**: MK.Lab
**depends:** `base`
## Архитектура
Модуль реализует структуру данных **направленного гиперграфа** для аналитики KPI.
```
mklab_base_indicators
├── hg.node — вершина графа (generic: res_model + res_id)
├── hg.index — показатель (метрика), привязан к вершине
├── hg.index.code — классификатор показателей
├── hg.value — значение показателя (план/факт/дата/формула)
├── hg.link — направленная связь: source_node к [target_nodes]
└── hg.hg_mixin — AbstractModel: подключает любую модель к графу
```
---
## Модели
### `hg.node` — Вершина графа
**Файл:** `models/hg_node.py`
Вершина представляет конкретный объект Odoo в структуре гиперграфа. Хранит generic-ссылку на запись через пару `(res_model, res_id)`. При подключении модели через `hg.hg_mixin` вершина создаётся автоматически при создании записи.
| Поле | Тип | Описание |
|---|---|---|
| `name` | Char | Название вершины |
| `res_id` | Integer | ID записи в Odoo |
| `res_model` | Char | Техническое имя модели (`project.task`, `sale.order` и др.) |
#### Методы
**`goto_related()`** — возвращает действие `ir.actions.act_window` для открытия связанной записи в диалоге. Используется для навигации из графа к исходному объекту.
---
### `hg.index` — Показатель
**Файл:** `models/hg_index.py`
Показатель — именованная KPI-метрика, привязанная к конкретной вершине графа. Хранит историю значений через связанные записи `hg.value` и вычисляет актуальное значение на текущую дату.
| Поле | Тип | Описание |
|---|---|---|
| `name` | Char | Название показателя |
| `node_id` | Many2one → `hg.node` | Вершина-владелец показателя |
| `internal_code_id` | Many2one → `hg.index.code` | Внутренний классификатор |
| `external_code` | Char | Внешний код для интеграций |
| `public` | Boolean | Признак публичного показателя |
| `value_ids` | One2many → `hg.value` | История значений показателя |
| `current_value` | Float | Текущее значение на сегодня |
#### Методы
**`_compute_current_value()`** — вычисляет `current_value` на основе `value_ids`. Из всех значений отбираются те, у которых `date_due <= сегодня`. Среди отобранных берётся запись с наибольшей датой — её `value_float_actual` становится текущим значением. Если подходящих значений нет — возвращается `0`.
**`calc()`** — метод вычисления значения показателя по формуле или связанным вершинам. Вызывается явно при необходимости пересчёта.
---
### `hg.index.code` — Классификатор показателей
**Файл:** `models/hg_index_code.py`
Справочник внутренних кодов для группировки показателей. Позволяет объединять показатели разных вершин в один срез при аналитике (например, «Выручка» по всем задачам проекта).
| Поле | Тип | Описание |
|---|---|---|
| `name` | Char | Название кода |
| `index_ids` | One2many → `hg.index` | Показатели с данным кодом |
---
### `hg.value` — Значение показателя
**Файл:** `models/hg_value.py`
Хранит конкретное числовое значение (плановое и фактическое) для показателя на определённую дату. Поддерживает два режима: простое значение и вычисление по формуле.
| Поле | Тип | Описание |
|---|---|---|
| `name` | Char | Название значения |
| `index_id` | Many2one → `hg.index` | Родительский показатель |
| `date_due` | Date (required) | Дата значения |
| `value_float_plan` | Float | Плановое значение |
| `value_float_actual` | Float | Фактическое значение |
| `type` | Selection | `alone` — простое значение; `formula` — вычисляется по формуле |
| `formula` | Char | Python-выражение для вычисления (используется при `type='formula'`) |
#### Методы
**`calc()`** — вычисляет `value_float_actual` для значений с `type='formula'`. Вычисление выполняется через `safe_eval` с контекстом:
| Переменная | Значение |
|---|---|
| `node_value` | текущая запись `hg.value` |
| `node_index` | родительский показатель `hg.index` |
| `datatime` | текущая дата `fields.Date.today()` |
---
### `hg.link` — Матрица связности
**Файл:** `models/hg_link.py`
Представляет направленное гиперребро графа: один источник и множество вершин-приёмников. Используется для построения отчётов по связанным объектам и визуализации зависимостей.
| Поле | Тип | Описание |
|---|---|---|
| `name` | Char | Название строки связи |
| `source_id` | Many2one → `hg.node` | Вершина-источник |
| `target_ids` | Many2many → `hg.node` | Множество вершин-приёмников |
---
### `hg.hg_mixin` — Миксин для моделей
**Файл:** `models/hg_mixin.py`
**Тип:** `models.AbstractModel`
Абстрактная модель, подключаемая через `_inherit` к любой модели Odoo. После подключения модель автоматически становится участником гиперграфа: при создании записи создаётся соответствующая вершина `hg.node`.
#### Подключение к модели
```python
class ProjectTask(models.Model):
_name = 'project.task'
_inherit = ['project.task', 'hg.hg_mixin']
```
#### Поля, добавляемые в модель
| Поле | Тип | Описание |
|---|---|---|
| `node_id` | Many2one → `hg.node` | Вершина графа для данной записи |
| `index_ids` | Many2many → `hg.index` | Показатели, привязанные к вершине записи |
| `related_ids` | Many2many → `hg.node` | Вершины-приёмники из матрицы связности |
#### Методы
**`create()`** — переопределён: после создания записи автоматически создаёт `hg.node` с `res_model` и `res_id` текущей записи, устанавливает `node_id`.
**`_compute_indexes()`** — ищет все `hg.index` с `node_id` равным вершине записи, заполняет `index_ids`.
**`_compute_related()`** — ищет все `hg.link` где `source_id` равен вершине записи, собирает все `target_ids` из найденных связей, заполняет `related_ids`.
---
## Представления и меню
**Файл:** `views/views.xml`
Создаёт корневое меню **«Слои показателей»** со следующей структурой:
```
Слои показателей
├── Граф
│ ├── Вершины графа → hg.node (list / form)
│ └── Матрица связности → hg.link (list / form)
└── Показатели
├── Показатели → hg.index (list / form)
├── Значения показателей → hg.value (list / form)
└── Внутренний код → hg.index.code (list / form)
```
---
## Безопасность
**Файл:** `security/res_groups.xml`
Группа `group_indicators_admin`**«Администратор Слоёв показателей»**. Полный CRUD-доступ ко всем моделям модуля.
**Файл:** `security/ir.model.access.csv`
| Модель | Группа | Права |
|---|---|---|
| `hg.node` | `group_indicators_admin` | CRUD |
| `hg.index` | `group_indicators_admin` | CRUD |
| `hg.index.code` | `group_indicators_admin` | CRUD |
| `hg.value` | `group_indicators_admin` | CRUD |
| `hg.link` | `group_indicators_admin` | CRUD |
| `hg.hg_mixin` | `group_indicators_admin` | CRUD |
---
## Тесты
**Файл:** `tests/`
| Файл | Что покрывает |
|---|---|
| `test_hg_node.py` | Создание вершины, метод `goto_related()` |
| `test_hg_index.py` | Создание показателя, вычисление `current_value` в различных сценариях |
| `test_hg_value.py` | Создание значения, вызов `calc()` для типов `alone` и `formula` |
| `test_hg_link.py` | Создание связи с вершинами-приёмниками и без них |
| `test_indicators.py` | Интеграционный тест цепочки модулей |
---