KNOTTA research & development

Сотрудник

Бэк-офис — планирование нарядов, рецензирование отчётов, клиентская база, отправка приглашений и контроль процесса.

Сотрудник

Роль: staff Полномочия: is_staff=True, is_superuser=False. Доступ к Django Admin и всему дашборду, но без прав суперпользователя.

Чем занимается сотрудник

  • Планирует и создаёт наряды — выбирает объект клиента, дату, бригадира и шаблон отчёта.
  • Рецензирует и утверждает отчёты бригад.
  • Ведёт клиентскую базу — добавляет клиентов, контактных лиц, объекты.
  • Отправляет приглашения контактным лицам.
  • Отправляет утверждённые отчёты клиентам одной кнопкой.
  • Контролирует расход материалов и услуг по нарядам.
  • Получает уведомления о новых отчётах на проверку (report_submitted) и о начале/завершении работ (work_started, work_completed).

Как зайти

Дашборд: /{ru|en}/dashboard/reports. Django Admin: /admin/ — для прямого редактирования сущностей.

Главный экран — список нарядов с боковой панелью отчёта. На широких экранах открывается двухпанельная раскладка, на мобильных — стек.

Планирование и создание наряда

Создание нарядов — это сценарий бэк-офиса. Бригадир получает уже готовый наряд с назначенной датой, объектом и шаблоном — и ведёт его дальше (запуск, отчёт, завершение).

Шаги создания

  1. В дашборде нажать «Создать наряд» (или через POST /api/service-visits/).
  2. Указать обязательные поля:
ПолеЧто выбрать
objectОбъект клиента из выпадающего списка (поиск по названию и адресу)
brigadierКто будет ответственным на выезде. Список ограничен пользователями с ролью brigadier
planned_forПлановая дата и время выезда
report_templateШаблон отчёта (SurveyJS). Если не указать — подставится текущий default из ReportSurveyTemplate.is_default=True
display_team_nameОпционально — название команды для UI («Бригада 3»)
  1. После сохранения наряд получает статус planned, бригадир видит его в своём дашборде.

Команда (ServiceVisitMember) на этапе создания не обязательна. Её можно либо назначить заранее (через эндпоинт /api/service-visits/{id}/members/), либо оставить пустой — фактический состав работников появится автоматически после утверждения отчёта (бригадир указывает их в SurveyJS, при → approved срабатывает синхронизация).

Изменение наряда

Сотрудник может менять поля наряда, пока он не в статусе completed:

  • Перенести дату (planned_for) — обычное обновление через PATCH /api/service-visits/{id}/.
  • Сменить объект — то же.
  • Переназначить бригадира — поле brigadier.
  • Сменить шаблон отчёта — поле report_template. Если отчёт уже создан — снимок шаблона у него не меняется; новый шаблон применится только к будущим отчётам по этому наряду (если бригадир пересоздаёт).

Отмена наряда — через POST /api/service-visits/{id}/cancelled/. Допустимо из planned или started, нельзя из completed.

Рецензирование отчётов

Когда бригадир подаёт отчёт (Report.status → submitted), сотрудник получает уведомление report_submitted (по умолчанию — email). В дашборде отчёт появляется в фильтре «На проверке».

Шаги рецензии

  1. Открыть отчёт.
  2. Просмотреть заполненные поля (survey_data) и прикреплённые файлы (фотографии).
  3. Принять решение:

Утвердить — нажать «Approve» (POST /api/reports/{id}/survey/approve/).

  • Report.status → approved.
  • Срабатывает автоматическая синхронизация бригады из survey_data — указанные работники добавляются в ServiceVisitMember (роль worker).
  • Бригадир получает уведомление report_approved.
  • Появляется кнопка «Отправить клиенту».

Отклонить — нажать «Reject», обязательно указать комментарий (rejection_comment).

  • Report.status → rejected.
  • Бригадир получает уведомление report_rejected с текстом комментария и ссылкой на редактирование.
  • Бригадир исправляет данные и подаёт отчёт повторно.

Отправка отчёта клиенту

После утверждения:

  1. Нажать «Отправить клиенту» (POST /api/reports/{id}/survey/send-to-client/).
  2. Все контактные лица клиента, у которых включён топик report_ready (по умолчанию — да, канал email), получают письмо со ссылкой на публичную страницу отчёта.
  3. Report.sent_to_clientTrue.

Что в письме. Дата выезда, название и адрес объекта, ссылка на публичный отчёт. Получатель может открыть отчёт без авторизации.

Что если сотрудник передумал. Поле sent_to_client поднимается раз и не сбрасывается. Но повторный клик создаст ещё одну запись ReportDelivery (новую попытку отправки) — это полезно, когда первое письмо потерялось или попало в спам.

Ведение клиентской базы

Создание клиента

В Django Admin → ClientsAdd:

  • name — название (для физлиц — ФИО).
  • typeindividual / organization.
  • email, phone, address.
  • tax_id — для организаций (ИНН).

Контактные лица

Внутри карточки клиента (или через Contact persons):

  • ФИО, должность.
  • email, телефон.
  • preferred_languageru или en.

Galка notify_work_start / notify_report_ready устарела — настраивайте подписки через inline NotificationPreference (см. ниже).

Объекты клиента

Client objectsAdd:

  • name — короткое название («Парк у входа»).
  • address.
  • client — выбрать из выпадающего списка.

У клиента может быть несколько объектов. На каждый создаётся свой наряд.

Подписки на уведомления

В карточке ContactPerson есть inline-блок «Notification preferences». По умолчанию у нового контакта уже есть три записи:

TopicChannelEnabled
work_startedemailtrue
work_completedemailtrue
report_readyemailtrue

Снимите галку — топик отключится. Удалите запись — применится ролевое умолчание (то же самое).

Если у контакта есть привязанный Telegram (через User.contact_profileTelegramLink) — можно добавить запись с каналом telegram. Тогда уведомление пойдёт сразу по двум каналам.

Приглашения

Отправка приглашения

Из карточки ContactPerson → действие «Send invite» (или через эндпоинт API).

  1. Создаётся запись ClientInvite (status=pending, токен).
  2. Отправляется письмо-приглашение через Edge Function send-email.
  3. Получатель проходит по ссылке → регистрируется в Supabase Auth → возвращается на /auth/invite?token=... → создаётся User(role=client) → привязывается к ContactPerson.user.

Что делать, если приглашение не дошло

  1. Проверить, не попало ли в спам (sender — RESEND_FROM_EMAIL).
  2. В Django Admin → Client invites найти запись с этим email.
  3. Если статус — pending и expires_at ещё не истёк — отправить ссылку вручную (поле token → собрать URL /{locale}/auth/invite?token=<token>).
  4. Если истёк — создать новое приглашение (старое автоматически перейдёт в expired или удалите вручную).

Отзыв приглашения

ClientInvite.statusrevoked. Полезно, если ошиблись адресом или передумали давать доступ. Старая ссылка перестанет работать.

Контроль расхода материалов и услуг

При утверждении отчёта Django читает survey_data и создаёт записи:

  • ServiceVisitMaterial — какие материалы были использованы и в каком количестве. Цена фиксируется по MaterialPrice.active_price_on(now).
  • ServiceVisitService — какие услуги выполнены. Цена — по ServicePrice.active_price_on.

Сотрудник может проверить эти записи в Django Admin или через эндпоинты /api/service-visit-materials/ и /api/service-visit-services/.

Типичные сценарии

СценарийГде
Создать нарядДашборд → «Создать наряд»
Перенести дату нарядаДашборд / Django Admin → наряд → planned_for
Переназначить бригадираДашборд / Django Admin → наряд → brigadier
Отменить нарядДашборд → «Отменить»
Утвердить отчётДашборд /{locale}/dashboard/reports
Отклонить с комментариемДашборд → кнопка «Reject»
Отправить отчёт клиентуДашборд (после утверждения)
Создать клиента / объект / контактDjango Admin
Отправить приглашениеКарточка ContactPerson → action
Настроить уведомленияInline в карточке ContactPerson или User
Посмотреть, дошло ли emailDjango Admin → Report deliveries или эндпоинт /api/reports/{id}/deliveries/
Узнать историю изменений отчётаDjango Admin → отчёт → History
На странице