Тилаус время-деньги

Отчёты

Обновлено 2026-10-27

Отчёты о выполнении

Отчёт фиксирует выполненный объём работы по смете: к какой работе сметы он привязан, кто работал, какой объём и за какой период. По отчётам система считает факт по смете и суммы для исполнителей и бригадира.

Кто участвует в отчёте

В отчёте указываются исполнители и при необходимости бригадир. От состава участников и их ролей зависит, как рассчитаются суммы.

Роли исполнителей

  • Партнёр — основной исполнитель, когда в отчёте нет помощников. Объём работы делится поровну между всеми партнёрами, каждому считается своя сумма по его ставке.
  • Специалист — основной исполнитель, когда в отчёте есть хотя бы один помощник. То же, что партнёр: объём делится между специалистами, сумма считается по ставке каждого.
  • Помощник — дополнительный участник. Объём тоже делится поровну между помощниками, сумма считается по ставке помощника. В одном отчёте не бывает одновременно партнёров и специалистов: либо только партнёры (без помощников), либо специалисты и помощники.
  • Бригадир — указывается отдельно от исполнителей. Бригадиру сумма считается на весь объём отчёта по своей ставке (объём не делится с исполнителями).

Итог: у каждого исполнителя — своя доля объёма и своя сумма; у бригадира — сумма на полный объём. Общая сумма по отчёту складывается из сумм всех исполнителей и суммы бригадира.

Откуда берутся ставки

Ставки для расчёта сумм берутся из тарифов типа работ: для каждой роли (партнёр, специалист, помощник, бригадир) задаётся ставка по объекту и дате. Если для конкретного человека в тарифах указана персональная ставка — используется она, иначе ставка по умолчанию для этой роли.

Цена для расчёта берётся из прайса (тип работ, объект, дата). На неё могут действовать коэффициенты, заданные в работе сметы. Итоговая сумма по каждому участнику: цена (с коэффициентами) × ставка × его доля объёма (для бригадира — весь объём).

Для разработчиков

Роли: RoleEnum (PARTNER, SPECIALIST, ASSISTANT, FOREMAN, HANDYMAN). Партнёры и специалисты взаимоисключающие; при наличии помощников основные идут как SPECIALIST (getPartnerRole).

Расчёт: WorkTypeHelp::calcSums(); исполнители — calcGroupSums() (amountPerUser = amount/count); бригадир — отдельно, sum = priceRateAndCoef*amount.

Ставки: searchRates($work_type, $place_id, $date, $role). Суммы исполнителей — report_item_performers.sum; бригадир — report_items.foreman_sum, foreman_rate_id, foreman_rate_value.

Применение: ReportItemCalculatorService::applyCalculationToReportItem().

Как считаются суммы по элементам отчёта

Основные исполнители (партнёры или специалисты)

  • Система смотрит, есть ли в отчёте помощники. Если нет — все основные считаются партнёрами, если есть — специалистами.
  • Объём отчёта делится поровну между всеми основными (между всеми партнёрами или всеми специалистами).
  • Для каждого человека берётся его ставка из тарифов (роль «партнёр» или «специалист», объект, дата).
  • Сумма = (цена с коэффициентами × ставка) × доля объёма этого человека.

Пример: объём 10 м, два партнёра с одинаковой ставкой. Каждому — 5 м, сумма каждому считается от 5 м по его ставке.

Помощники

  • Объём отчёта делится поровну между всеми помощниками (отдельно от основных).
  • Для каждого помощника — ставка из тарифов (роль «помощник»).
  • Сумма = (цена с коэффициентами × ставка помощника) × доля объёма помощника.

То есть у основных и у помощников считаются свои доли от одного и того же объёма отчёта; общая сумма по отчёту включает и тех и других.

Бригадир

  • Бригадир указывается в отчёте отдельно (поле «Бригадир»).
  • Если у типа работ включена опция «не считать бригадира» — сумма бригадиру не считается.
  • Иначе берётся ставка бригадира из тарифов (роль «бригадир», объект, дата).
  • Сумма бригадира считается на весь объём отчёта: (цена с коэффициентами × ставка бригадира) × объём отчёта. Объём не делится с исполнителями.

Сумма бригадира хранится отдельно от сумм исполнителей и участвует в общей сумме по отчёту и в отчётах по выплатам.

Для разработчиков

calcSums: rate_is_percent — цена из PriceHelp::findPriceForWork, иначе price=1. coefficient_value по коэффициентам работы.

Партнёры/специалисты: calcGroupSums(partners|specialists, amount, …, role) → amountPerUser = amount/count, userSum = priceRateAndCoef*amountPerUser → performers[].sum. Помощники: calcGroupSums(assistants, amount, …, ASSISTANT).

Бригадир: при !no_calc_for_foreman — searchRates(…,'foreman'), arForeman['sum'] = priceRateAndCoef*amount; сохраняется в foreman_sum.

Результат: performers (pivot sum) + foreman (foreman_sum). В смете sum_fact_performers: pivot.sum + foreman_sum по report_items работы.

Связь отчётов со сметой

Данные из отчётов попадают в смету и участвуют в расчёте фактических показателей по работе:

  • Фактический объём по работе сметы — это сумма объёмов всех отчётов, привязанных к этой работе (с учётом пересчёта единиц измерения, если у типа работ настроена конвертация). Либо используется ручной факт, если его ввёл руководитель.
  • Сумма по факту для заказчика по работе = цена работы × фактический объём (цена берётся из сметы, не из отчётов).
  • Сумма по факту для исполнителей по работе — это сумма полей «сумма» всех исполнителей по всем отчётам этой работы плюс суммы бригадиров из этих отчётов.

Подробнее о том, как считаются объёмы, цены и суммы в смете — в разделе «Сметы: Объёмы, цены и суммы».

Для разработчиков

PlanHelp::getPlanWorkRowOptimized: amount_fact из ReportItem (конвертация через MeasureHelp::getConvertAmount при разных measure); sum_fact_performer += performer->pivot->sum + report_item->foreman_sum по report_items работы.

Привязка элемента отчёта к работе сметы

В форме отчёта можно указать, к какой смете, разделу и работе относится элемент. Если выбрать только смету или смету и раздел, но не выбирать конкретную работу, система сама решает, к какой работе привязать отчёт (или создаёт новую работу).

Как выбирается работа, если пользователь её не указал

  1. Раздел. Если указана только смета — берётся раздел по умолчанию в этой смете (если задан) или первый раздел. Если указан раздел — используется он.
  2. Поиск подходящей работы. Система смотрит только работы того же типа, что и элемент отчёта (например, «Штукатурка», «Укладка плитки»). В выбранном разделе ищется работа, у которой совпадают:
    • Параметры типа работ (все значения параметров у отчёта и у работы в смете должны быть одинаковыми);
    • Коэффициенты (набор коэффициентов у отчёта и у работы должен совпадать).
  3. Если такая работа найдена — отчёт привязывается к ней (к первой подходящей в списке).
  4. Если подходящей работы нет — в этом разделе создаётся новая работа: тот же тип работ, те же параметры и коэффициенты, что в отчёте. Название новой работы система формирует сама из названия типа работ и значений параметров (например, «Штукатурка | стена | 15 мм»). Отчёт привязывается к этой новой работе.

Итого: при указании только сметы (и при необходимости раздела) отчёт не «прилипает» к случайной работе — привязка идёт к работе с тем же типом и теми же параметрами/коэффициентами; если такой работы нет, создаётся новая с автогенерируемым названием.

Для разработчиков

Логика в Help::addReportItemInPlan(ReportItem, plan, section, work). При work пустом: определяется plan_section_id (default_section_id плана, иначе первый раздел, иначе создаётся раздел «Раздел N»). Кандидаты: $planSection->works()->where('work_type_id', $reportItem->work_type_id)->get(). По каждому кандидату проверка: совпадение data['params'][param_id] по всем params типа работ и совпадение списков коэффициентов (reportItem->coefficients vs data['coefficients']). Первое совпадение — привязка к этой работе. Если совпадений нет — создаётся new PlanWork (name = '', plan_section_id, work_type_id, data из отчёта, amount 0, price/rate из отчёта), save(). При сохранении PlanWork::beforeSave() при пустом name вызывает Help::getPlanWorkName($this->data, $this->work_type) и подставляет имя: название типа + | + суффикс из getSuffixPlanWork($data, $work_type) (параметры и calc_logic типа). Итог: reportItem->plan_work_id = $planWork->id.

Не нашли нужный шаг? Напишите в поддержку.

В поддержку

Заказать звонок

Оставьте контакты — перезвоним в ближайшее время.

Мы используем cookie для работы сайта и аналитики (Яндекс.Метрика). Продолжая, вы соглашаетесь с политикой обработки персональных данных.