# Отчёт по срокам сделки

Этот отчёт является ключевым инструментом для глубокого анализа и оптимизации процесса продаж. Он предоставляет общую картину эффективности на каждом этапе, позволяя аналитикам и руководителям отдела продаж точно определить, какие подразделения или менеджеры закрывают сделки быстрее всего. Также он помогает выявить узкие места в воронке, отображая длительность каждого этапа — от первичной обработки до бронирования и финальной сделки. Используя такие показатели, как Общий и Средний срок сделки в сочетании с детализацией по этапам (<mark style="background-color:blue;">Неразобранное</mark>, <mark style="background-color:blue;">Проверка</mark>, <mark style="background-color:blue;">Подбор</mark> и т.д.), вы получаете возможность принимать обоснованные решения для системного сокращения цикла продаж.

### Работа с отчётом

#### Фильтры отчёта

1. Дата:

* При открытии отчёта фильтр по умолчанию выбирает тип «Дата появления заявки».
* Нажмите на тип даты, чтобы выбрать событие, по которому будет ограничена выборка заявок (например, «Дата начала сделки»).

<figure><img src="https://2409287958-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfkymnT1WRuXnrJRm6ZIO%2Fuploads%2FNNxs2eMztJWlpDaVa5o6%2F%D0%BE%D0%BF%D1%81%D1%81%201.jpg?alt=media&#x26;token=6f7143b3-57fe-4ce7-9b39-c5a44b95680e" alt=""><figcaption></figcaption></figure>

2. Отдел и Менеджер (Ответственный):

* Эти фильтры используют формат мультиселекта[^1] и позволяют точно отсортировать данные отчёта по конкретным отделам продаж и ответственным сотрудникам в сделке.

3. Сотрудник сопровождения сделки и Опции:

* Фильтрует отчёт по сопровождающему сотруднику. Для более наглядной работы с этим фильтром рекомендуется включить опцию «Группировать по сотруднику сопровождения».
* При активации этой опции в отчёте устанавливается следующая иерархия вложенности: Сотрудник сопровождения $$\rightarrow$$ Отдел продаж $$\rightarrow$$ Менеджер (Ответственный).

### Технический паспорт отчёта

#### Структура и источник данных

<figure><img src="https://2409287958-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfkymnT1WRuXnrJRm6ZIO%2Fuploads%2FNk1JlS544iKiJFM7Rmxl%2F%D0%BE%D0%BF%D1%81%D1%81%202.jpg?alt=media&#x26;token=77ca60ff-9128-48b8-a04a-bb90e8216f87" alt=""><figcaption></figcaption></figure>

Отчёт представляет собой комбинацию данных по длительности этапов и количеству сделок.&#x20;

{% hint style="info" %}
Важно: точную продолжительность этапов невозможно получить напрямую через листинги или стандартные реестры системы. Для контроля и детальной проверки расчетов следует использовать  <mark style="background-color:purple;">MacroData</mark>.
{% endhint %}

#### Данные в системе&#x20;

**Общий срок сделок (1).**

Показатель **Общий срок сделок (1)** представляет собой суммарную продолжительность пребывания всех завершенных заявок от [момента их создания](#user-content-fn-2)[^2] до фактического перехода в статус <mark style="background-color:blue;">Сделка проведена</mark>.

Принцип выбора данных в <mark style="background-color:purple;">MacroData</mark> (без учёта фильтров):

Для получения этих данных необходимо связать таблицы `estate_buys` и `estate_buys_statuses_log`, чтобы найти дату перехода в финальный статус (100) и рассчитать временную разницу.

```sql
SELECT 
    T1.manager_name, 
    T1.total_seconds, 
    CASE 
        WHEN T1.total_seconds >= 31536000 
            THEN CONCAT(FLOOR(T1.total_seconds / 31536000), ' г ', FLOOR((T1.total_seconds % 31536000) / 2592000), ' мес')  
        ELSE CONCAT(T1.total_seconds, ' с') 
    END AS total_time_formatted 
FROM 
    (
        SELECT
            U.users_name AS manager_name, 
            SUM(TIMESTAMPDIFF(SECOND, EB.date_added, EBSL.log_date)) AS total_seconds 
        FROM 
            estate_buys EB 
        INNER JOIN 
            estate_buys_statuses_log EBSL 
            ON EB.id = EBSL.estate_buy_id AND EBSL.status_to = 100 AND EBSL.status_from <> 100 
        INNER JOIN 
            users U ON EB.manager_id = U.id 
        WHERE 
            EB.status = 100 
        GROUP BY 
            U.users_name 
    ) AS T1 
ORDER BY 
    T1.total_seconds DESC;
```

**Всего сделок (2).**&#x20;

Количество **Всего сделок (2)** соответствует числу заявок, которые имеют текущий [статус «Сделка проведена»](#user-content-fn-3)[^3] и подпадают под условия фильтрации.

Проверка данных в CRM: Для проверки перейдите в Листинг заявок и установите фильтр по дате и текущему статусу <mark style="background-color:blue;">Сделка проведена</mark>. Обратите внимание, чтобы в обоих периодах был выбран одинаковый тип даты.

<figure><img src="https://2409287958-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfkymnT1WRuXnrJRm6ZIO%2Fuploads%2FFNAyf1m3vS63CGz8wyt9%2F%D0%BE%D0%BF%D1%81%D1%81%203.jpg?alt=media&#x26;token=1431ac47-6ad3-4eff-85c2-a1d6e965532b" alt=""><figcaption></figcaption></figure>

Принцип выбора данных в <mark style="background-color:purple;">MacroData</mark> (без учёта фильтров):

```sql
SELECT 
    U.users_name AS manager_name, 
    COUNT(EB.id) AS "Всего сделок" 
FROM 
    users U 
INNER JOIN 
    estate_buys EB ON U.id = EB.manager_id 
WHERE  
    EB.status = 100 
GROUP BY 
    U.id, U.users_name 
ORDER BY 
    "Всего сделок" DESC;
```

Проверка длительности этапов (4-9).

Статусы **Неразобранное**, **Проверка**, **Подбор**, **Отложено**, **Бронь**, **Сделка в работе (4-9)** отражают среднее время пребывания заявки в каждом из этих статусов в [реальных часах](#user-content-fn-4)[^4].

Принцип выбора данных в <mark style="background-color:purple;">MacroData</mark> на примере статуса **Неразобранное (4)**:

```sql
SELECT 
    U.users_name AS manager_name, 
    ROUND(AVG(SD.duration_seconds)) AS "Неразобранное" 
FROM 
    users U 
INNER JOIN 
    estate_buys EB ON U.id = EB.manager_id 
INNER JOIN 
    ( 
        SELECT 
            EBSL_ENTRY.estate_buy_id, 
            TIMESTAMPDIFF(SECOND, EB_SUB.date_added, ( 
                SELECT MIN(EBSL_EXIT.log_date) 
                FROM estate_buys_statuses_log EBSL_EXIT 
                WHERE EBSL_EXIT.estate_buy_id = EBSL_ENTRY.estate_buy_id 
                AND EBSL_EXIT.log_date > EBSL_ENTRY.log_date 
            )) AS duration_seconds 
        FROM 
            estate_buys_statuses_log EBSL_ENTRY 
        INNER JOIN 
            estate_buys EB_SUB ON EBSL_ENTRY.estate_buy_id = EB_SUB.id 
        WHERE 
            EBSL_ENTRY.status_to = 5  
            AND EB_SUB.status = 100  
    ) AS SD ON EB.id = SD.estate_buy_id 
WHERE 
    EB.status = 100 
GROUP BY 
    U.id, U.users_name 
ORDER BY 
    "Неразобранное" DESC;
```

Адаптация запроса для других статусов.

Чтобы рассчитать среднее время для любого [другого статуса](#user-content-fn-5)[^5], выполните следующие три шага:

1. Измените псевдоним столбца: Замените `AS "Неразобранное"` на нужное название статуса (например, `AS "Проверка"`).
2. Измените фильтр статуса: Замените `EBSL_ENTRY.status_to = 5` на требуемый номер статуса (например, `10`).
3. Измените логику расчета времени.

{% hint style="warning" %}
Внимание: Для всех статусов, кроме «Неразобранное» (5), измените формулу `TIMESTAMPDIFF` в подзапросе `SD`, заменив `EB_SUB.date_added` на дату входа в статус (`EBSL_ENTRY.log_date`):
{% endhint %}

* Для Неразобранного (5): $$\rightarrow$$ `TIMESTAMPDIFF(SECOND, EB_SUB.date_added, ...)`
* Для Проверки (10) и всех остальных: $$\rightarrow$$ `TIMESTAMPDIFF(SECOND, EBSL_ENTRY.log_date, ...)`

#### Расчётные данные

**Средний срок сделки (3).**

**Средний срок сделки (3)** — это результат деления **Общего срока сделок (1)** на **Всего сделок (2)**. Запрос выводит все три столбца для проверки.

Принцип выбора данных в <mark style="background-color:purple;">MacroData</mark> (без учёта фильтров):

```sql
SELECT 
    U.users_name AS manager_name, 
    T1.total_seconds AS "Общее время (сек)", 
    T1.total_deals AS "Всего сделок", 
    T1.avg_sec_to_deal AS "Средний срок сделки (сек)" 
FROM 
    users U 
INNER JOIN 
    ( 
        SELECT 
            EB.manager_id, 
            SUM(TIMESTAMPDIFF(SECOND, EB.date_added, EBSL.log_date)) AS total_seconds, 
            COUNT(EB.id) AS total_deals, 
            ROUND(SUM(TIMESTAMPDIFF(SECOND, EB.date_added, EBSL.log_date)) / COUNT(EB.id)) AS avg_sec_to_deal 
        FROM 
            estate_buys EB 
        INNER JOIN 
            estate_buys_statuses_log EBSL 
            ON EB.id = EBSL.estate_buy_id AND EBSL.status_to = 100 AND EBSL.status_from <> 100 
        WHERE 
            EB.status = 100 
        GROUP BY 
            EB.manager_id 
    ) AS T1 ON U.id = T1.manager_id 
ORDER BY 
    T1.avg_sec_to_deal DESC;
```

[^1]: множественного выбора

[^2]: `date_added`

[^3]: Статус 100 в MacroData

[^4]: общее календарное время, не рабочее

[^5]: Проверка (10), Подбор (20) и т.д.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.macrodigital.ru/manual/macrocrm/otchety/otchyot-po-srokam-sdelki.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
