- Новый раздел «Предложения» в меню «Клиенты и сделки»: коммерческие предложения (КП) и презентации для клиентов с номером, сроком действия, ответственным и статусом, фильтры по виду, статусу и ответственному.
- Презентация — это ссылка на страницу сайта, например на кейсы для вашей сферы бизнеса, с коротким текстом менеджера. Клиент нажимает «Посмотреть» и сразу попадает на страницу, а в карточке видно, когда он её открыл.
- Одну презентацию можно отправлять многим клиентам: её создают один раз и отправляют из карточки любого лида или компании. У каждого клиента своя ссылка, открытие попадает в карточку того, кто открыл.
- В карточке лида, компании, сделки и клиента кнопка «Отправить презентацию» показывает готовые презентации с поиском — сначала те, что отправляют чаще, — и отмечает, какие этому клиенту уже отправляли и открывал ли он их.
- В карточке лида в меню «Действие» есть «Отправить презентацию» и «Отправить КП». «Отправить КП» показывает непринятые КП клиента и кнопку «Создать новое КП».
- Новое КП создаётся по шагам в одном окне: после сохранения сразу открываются позиции, а кнопка «Сохранить и отправить клиенту» ведёт к письму.
- Позиции КП собираются в удобном редакторе: разделы, количество, цена, скидка, итог пересчитывается сразу. Услугу можно выбрать из каталога магазина.
- Шаблоны КП: готовые тексты и позиции, из которых новое КП создаётся за минуту.
- Отправленное КП не меняется: правки сохраняются в новой версии, старые версии остаются в истории. Любую версию можно скачать в PDF в оформлении документов вашей компании.
- КП и презентации отправляются письмом или СМС. К письму с КП прикладывается PDF, текст презентации пишется с оформлением.
- Клиент открывает КП по личной ссылке без входа: позиции, итог, условия, срок действия, «Скачать PDF». Страница удобна на телефоне.
- Клиент может принять КП или задать вопрос прямо на странице. Вопрос приходит в переписку с клиентом в CRM.
- Когда клиент впервые открыл КП или презентацию, ответственному сразу ставится задача «Позвонить» на сегодня, а вне рабочего времени — на ближайший рабочий день. Если задача по этому предложению уже есть, новая не ставится. Правило можно отключить кнопкой «Настройки» в разделе «Предложения».
- У каждой отправки своя ссылка: в карточке видно, каким каналом и кому ушло предложение, когда клиент его открыл и сколько раз смотрел. Просмотры роботов и проверки ссылок почтовыми службами не засчитываются: в ленте они помечены «возможно, проверка ссылок».
- Ответственный получает уведомление, когда клиент открыл предложение, принял его или задал вопрос. В ленте лида и компании видны отправка, открытие и принятие с указанием канала.
- Переходы клиентов по презентации видны в Яндекс Метрике как переходы из CRM: с каналом отправки и номером презентации.
- Если менеджер отправил новую версию КП, клиент на старой ссылке видит «Есть обновлённое предложение». После срока действия страница сообщает, что предложение истекло.
Почта, телефония и SMS
КП и презентации
Коммерческие предложения и презентации для клиентов: отправка из карточки, честная отметка «Открыто», «Принять» и «Задать вопрос».
Описание
Раздел «Предложения» помогает менеджеру быстро подготовить коммерческое предложение, отправить его клиенту и узнать, когда клиент его открыл. В том же разделе живут презентации — готовые страницы сайта, которые можно отправить любому клиенту по личной ссылке.
Коммерческое предложение за пару минут
- КП создаётся прямо из карточки лида, компании, сделки или клиента — клиент подставится сам.
- Шаблоны КП: вступление, условия и типовые позиции заполняются одной кнопкой.
- Позиции группируются по разделам, у каждой — количество, цена и скидка. Итог считается сам, можно дать скидку на всё предложение.
- Если на сайте есть магазин, товары и услуги можно выбирать прямо из каталога.
- PDF оформляется по шаблону документов вашей компании: логотип, цвета и реквизиты.
- Отправленное КП не меняется. Если нужно что-то поправить, создаётся новая версия, а клиент на старой странице увидит, что есть обновлённое предложение.
Отправка из карточки клиента
- Кнопка «Отправить клиенту» отправляет КП письмом или СМС. Получатели подсказываются из контактов клиента.
- В письмо сразу попадает готовый текст, ссылка «Открыть предложение» и PDF-файл.
- У каждой отправки своя ссылка, поэтому видно, кому и каким способом ушло предложение и кто его открыл.
- Всё, что происходит с КП, появляется в ленте карточки клиента: создано, отправлено, открыто, принято.
Честная отметка «Открыто»
- Просмотр засчитывается, только когда страница действительно показана человеку.
- Не считаются проверки ссылок почтовыми службами и антивирусами, предпросмотр в мессенджерах, повторные открытия в течение получаса и просмотры сотрудников.
- При первом открытии ответственному приходит уведомление, а в его задачах появляется «Позвонить: клиент открыл предложение» — на сегодня или на начало ближайшего рабочего дня по графику сотрудника. Задачу можно отключить в настройках раздела.
- В карточке КП видны все отправки, история просмотров и вопросы клиента.
Страница предложения для клиента
- Клиент открывает КП по ссылке без регистрации: позиции, итог, условия, срок действия, контакты менеджера и реквизиты.
- Кнопка «Принять предложение» — менеджер сразу получает уведомление, а КП получает статус «Принято».
- Кнопка «Задать вопрос» — вопрос приходит в переписку с клиентом в CRM, менеджер узнаёт о нём сразу.
- Можно скачать PDF. Страница удобна и на телефоне.
Презентации
- Презентация — любая страница вашего сайта: каталог, решение для отрасли, готовые проекты. Менеджер добавляет её один раз и пишет короткое сопроводительное сообщение.
- Одна общая презентация отправляется многим клиентам. В карточке клиента кнопка «Отправить презентацию» открывает список готовых страниц, и видно, какую из них этому клиенту уже отправляли и открывал ли он её.
- Клиент переходит по личной ссылке и сразу попадает на нужную страницу сайта. В CRM появляется отметка «Открыто», уведомление и задача «Позвонить».
- К адресу страницы добавляются метки, поэтому переходы видны и в аналитике сайта.
Кто что видит
Раздел открыт всем сотрудникам с доступом в CRM. Каждое КП видят администратор, ответственный и его руководители, а также те, кому доступен клиент этого КП. Общие презентации видны всем сотрудникам.
Что понадобится
Предложения работают вместе с решением «Почта в CRM»: через него письма уходят из вашего почтового ящика. Для отправки СМС нужен подключённый SMS-сервис. Скоро в КП появятся необязательные позиции, которые клиент сможет выбрать сам, и выставление счёта из принятого предложения, а также отправка в мессенджеры.
На скриншотах — тестовые данные.
Установка
Подключите пакет в корне проекта на SkeekS Платформе, затем примените миграции проекта.
composer require skeeks/cms-proposal
Зависимости
- PHP>=8.0
- SkeekS CMS
skeeks/cms^6.4.9.64 - Backend
skeeks/cms-backend^2.1.1.20 - Почта в CRM
skeeks/cms-communication^1.4 - kartik-v/yii2-mpdf^1.0.6
Инструкция из репозитория
skeeks/cms-proposal
Единый реестр «Предложения» для CRM SkeekS CMS. Два вида:
- КП — коммерческое предложение: версии, позиции с разделами, шаблоны, PDF, страница КП по личной ссылке с учётом просмотров, «Принять» и «Задать вопрос»;
- Презентация — страница сайта (своего или любого, например
/works/sfery/plitka) и короткий текст менеджера: личная ссылка засчитывает просмотр и сразу переводит клиента на страницу.
Отправка, личные ссылки, учёт просмотров, отсев проверок ссылок, лента,
уведомления и задача менеджеру при первом открытии — общие для обоих видов.
Этап 3 проекта коммуникаций, согласованная архитектура —
skeeks/cms-communication/ARCHITECTURE.md, разделы «КП (реестр
предложений)», «Единый реестр „Предложения“: КП и Презентация» и «Отправить
клиенту».
Что в пакете
| Часть | Классы |
|---|---|
Вид (kind): proposal — КП, presentation — Презентация; выбирается при создании и не меняется. У Презентации — адрес страницы target_url (только http(s), путь сайта дополняется адресом сайта, хранится в предложении) и текст менеджера message, срок — по желанию; версий, позиций, PDF и «Принять» нет | models\CmsProposal |
КП: номер на сайте, название, клиент (лид, компания, сделка или клиент-человек cms_user не сотрудник), ответственный, статус, срок действия (14 дней), валюта, текущая версия | models\CmsProposal, models\queries\CmsProposalQuery (forManager(), forRecord(), forCompany(), search()) |
Версия: вступление и условия (RichTextInputWidget, пресет standard), позиции, сумма, скидка на всё, итог, копия наших реквизитов. Отправленная версия не меняется | models\CmsProposalVersion, services\ProposalVersions |
Позиция или раздел: как строка счёта, со ссылкой на товар cms-shop (без внешнего ключа) | models\CmsProposalItem, services\ProposalItems |
| Отправка: канал, получатель, сообщение CRM, секретный код личной ссылки, первый и последний просмотр, их число. Просмотр: время, браузер, робот | models\CmsProposalSend, models\CmsProposalView |
«Отправить клиенту» и «Прикрепить из… → КП» (communication.sendables['proposal']): ссылка на каждую отправку, PDF вложением; первая отправка фиксирует версию и сохраняет её PDF, черновик становится «Отправлено», лента «КП отправлено (канал)» | send\ProposalSendableSource, send\ProposalSendable, services\ProposalSends |
Страница КП для клиента /~kp/<код> без входа: позиции, итог, условия, срок, «Скачать PDF», «Принять», «Задать вопрос»; плашки «Есть обновлённое предложение» (?v=latest), «Предложение истекло», «Принято» | controllers\ProposalController, views/proposal/*, assets\ProposalPageAsset |
| Честный учёт просмотров: только сигнал из показанной страницы, роботы предпросмотра, повторы за 30 минут и сотрудники не считаются; первый просмотр отправки — «Открыто», лента «КП открыто (канал)», уведомление | services\ProposalViews |
| «Принять» (только новейшая отправленная версия, один раз) и «Задать вопрос» (входящее «Сообщение с сайта» в переписке клиента, лимиты, скрытое поле) | services\ProposalAnswers, models\CmsProposalQuestion |
| Уведомления ответственному (иначе автору) в колокольчике CRM | services\ProposalNotifier (CmsWebNotify) |
Страница-переход Презентации по той же ссылке /~kp/<код>: сигнал просмотра из страницы, затем переход на target_url с метками utm_source=crm, utm_medium=<канал>, utm_campaign=proposal-<номер> (уже указанные метки не затираются); без скриптов перехода нет, только ссылка «Перейти» | views/proposal/presentation.php, services\PresentationLinks, sxPresentationPage в proposal-page.js |
| Отсев проверок ссылок (оба вида): открытие в первые 30 секунд после ухода письма, из сетей почтовых служб и защитных систем, автоматическим браузером — в истории с причиной, в ленте «возможно, проверка ссылок», без статуса, уведомления и задачи | services\ProposalViews + skeeks/cms-communication services\LinkChecks |
Общая Презентация — без клиента («одна на всех»): создаётся в разделе, отправляется из карточки любого лида, компании, сделки или клиента. Клиент записывается в отправку (cms_proposal_send.cms_lead_id … cms_user_id) — запись CRM получателя из окна «Отправить клиенту» или «Прикрепить из…»; без записи CRM отправка отклоняется. Лента, уведомление («<клиент>: клиент открыл презентацию…») и задача — у клиента отправки; в карточке клиента блок показывает отправленные ему общие Презентации и состояние его отправок; общую Презентацию видят все сотрудники | CmsProposal::$isShared, CmsProposalSend::$client, CmsProposalQuery::shared()/forRecord(), ProposalUi::sentBadge() |
Текст менеджера Презентации — общий редактор текста (RichTextInputWidget, пресет basic, RichTextBehavior): в письмо идёт с оформлением (SendableHtmlInterface::getSendHtml()), в СМС — без тегов; старые тексты строками показываются абзацами | CmsProposal::MESSAGE_PRESET, getMessageHtml(), getMessageText() |
«Отправить презентацию» и «Отправить КП» в меню «Действие» блока «Следующий шаг» карточки лида (точка skeeks/cms CrmCardBlocksWidget::EVENT_ACTIONS). «Отправить КП» — окно с КП этого клиента, ждущими отправки (черновики первыми; пустой черновик ведёт в «Содержимое», остальные — в «Отправить клиенту»), и «+ Создать новое КП»; если таких КП нет — сразу окно создания | ProposalBootstrap, ProposalUi::nextStepActions(), AdminCmsProposalController::actionProposals(), views/admin-cms-proposal/proposals.php |
Шаги в одном окне: после «Сохранить» в окне создания КП открывается его «Содержимое», Презентация клиента — «Отправить клиенту», общая — её карточка; в «Содержимом» — «Сохранить и отправить клиенту» (submit-btn=send) | create on afterSave → afterSaveUrl, ProposalUi::nextStepFormCallback() (activeFormConfig.clientCallback), ProposalUi::sendUrl() |
| «Отправить презентацию» в блоке «Предложения» карточек: окно со списком готовых общих Презентаций (действующих; чаще отправляемые сверху, поиск, если их больше 7), у каждой — «Отправляли …» / «Открывал …» для этого клиента (повторная отправка разрешена); выбор открывает «Отправить клиенту» этой Презентации с этим клиентом; без Презентаций — «Создать общую презентацию» | AdminCmsProposalController::actionPresentations() (?source=proposal-client:lead.29), views/admin-cms-proposal/presentations.php, ProposalUi::presentationsUrl(), ProposalUi::recordSendCondition() |
| Задача менеджеру при первом открытии (оба вида): «Позвонить: клиент открыл предложение №…» ответственному (иначе автору) на сегодня, вне рабочего времени — на начало ближайшего рабочего периода (график сотрудника, без графика — пн–пт 9–18); привязана к лиду/компании/клиенту (сделка — через её компанию) и к предложению; не ставится, пока у него есть открытая задача по этому предложению; отключается настройкой | services\ProposalTasks, models\CmsProposalTask, components\ProposalSettings |
| «Клиент открыл: …» вверху карточки такой задачи | source\ProposalClientSource::origins() (RecordOriginInterface) |
| Шаблоны КП | models\CmsProposalTemplate, controllers\AdminCmsProposalTemplateController |
Раздел «Предложения» (ProposalSettings — кнопка «Настройки» у администратора): список с фильтрами по виду, статусу и ответственному, окно создания — сначала вид, затем поля вида; карточка (отправки с каналом и просмотрами, история просмотров, вопросы клиента), вкладка «Содержимое» с редактором позиций, «Отправить клиенту», «Новая версия», «Скачать PDF» | controllers\AdminCmsProposalController, widgets\ProposalItemsInputWidget, assets\* |
| «Создать предложение» из лида, компании, сделки | source\ProposalClientSource (?source=proposal-client:lead.15) |
| Блок «Предложения» в карточках лида, компании, сделки и клиента-человека | ProposalBootstrap, helpers\ProposalUi::cardBlock() на точке skeeks/cms CrmCardBlocksWidget |
| Лента: «КП создано», «Новая версия КП» (и события шага C) | services\ProposalFeed, log\ProposalLogRenderer |
| PDF версии через mPDF в оформлении шаблона документов сайта | services\ProposalPdf, views/pdf/proposal.php |
Права: раздел открыт всем сотрудникам с доступом в администрирование; каждое
КП видно администратору, ответственному и его руководителям, а также тем, кому
виден клиент КП (forManager() лида, компании, сделки). КП лида и сделки
видны в карточке их компании.
Зависимости
skeeks/cms^6.4.9.64 —CrmCardBlocksWidget(блоки пакетов в карточках),Skeeks::$recordSources,RichTextInputWidget,CmsDocumentTemplate.skeeks/cms-backend,kartik-v/yii2-mpdf(mPDF).skeeks/cms-communication^1.4 — «Отправить клиенту» (каналы письмо и СМС, позже мессенджеры),services\SiteMessagesдля вопросов клиента,services\LinkChecksдля проверок ссылок.skeeks/cms-shop— по желанию: выбор товара или услуги в редакторе позиций.
Страница КП для клиента
- Адрес —
/~kp/<код>(правилаurlManagerвconfig/web.php); код отправки — единственный доступ, как у страницы счётаcms-shop. Ссылка показывает ту версию, с которой её отправили;?v=latest— новейшую отправленную, действия страницы (seen,accept,ask,pdf) берут ту же. - Своя раскладка
views/proposal/layout.phpбезbeginPage()/head()/endBody(): пакеты сайта вешают на события View скрипты темы, баннер cookie, счётчики и ключевые слова, а страница отдаётся вResponse::$content, поэтомуcms-seoне дописывает в неё счётчики.noindexв заголовке и в meta,Referrer-Policy: no-referrer(код в адресе),Cache-Control: no-store. - Оформление — светлое, акцентный цвет и логотип из шаблона документов сайта (как PDF); на узком экране позиции идут карточками.
- Просмотр засчитывается запросом
POST …/seenиз скрипта страницы, когда она 1,5 секунды видна (visibilityState);curl, почтовые проверки и предпросмотр мессенджеров его не делают, а известные роботы (ProposalViews::BOT_PATTERNS) записываются в историю без счёта. - Сигнал передаёт признаки браузера (
navigator.webdriver, число языков, размер экрана): проверки ссылок в автоматическом браузере (LinkChecksпакетаskeeks/cms-communication) не засчитываются.
Презентация: страница-переход
- Та же ссылка
/~kp/<код>и то же оформление. Скрипт, как только страница 0,4 секунды видна, шлётPOST …/seenи затем (или через 2,5 секунды без ответа) заменяет страницу адресом презентации (location.replace: «Назад» не возвращает на переход). Сотрудник CRM видит, что переход не засчитан, и переходит через 3 секунды. - Адрес — только
CmsProposal::$target_url, никогда не параметр ссылки: страница не открытое перенаправление. К адресу добавляютсяutm_source=crm,utm_medium=<канал>,utm_campaign=proposal-<номер>(PresentationLinks::addUtm(), уже указанные метки и#фрагментсохраняются). - Без скриптов (роботы,
curl) просмотра и перехода нет — только ссылка «Перейти». После срока действия — «Ссылка больше не действует» и контакты ответственного, без перехода. - «Принять», «Задать вопрос» и PDF для Презентации отвечают 404.
Задача менеджеру при первом открытии
ProposalTasks::onFirstView()вызывается изProposalViewsпосле первого засчитанного просмотра отправки, для КП и Презентации; ошибка задачи пишется в журнал и не мешает клиенту.- Задача ядра
CmsTaskсебе (created_by= исполнитель, сразу «Принята»; на странице клиента никто не вошёл),plan_start_at— не раньше чем через 31 минуту (правило модели) в рабочем периоде сегодня, иначе начало ближайшего рабочего периода поwork_sheduleсотрудника. - Связь задачи с предложением —
cms_proposal_task: по ней ищется открытая задача ответственного по предложению (новая не ставится) и показывается «Клиент открыл: …» в карточке задачи. Закрытая задача не мешает новой при первом открытии следующей отправки. У общей Презентации открытая задача ищется по предложению и клиенту отправки: каждому открывшему клиенту — своя задача. - Настройка «Задача менеджеру при первом открытии»
(
ProposalSettings::$taskOnFirstView, по умолчанию включено) — кнопка «Настройки» в разделе у администратора; для кампаний этапа 4 будет своя настройка кампании.
Тест
php tests/proposal.php /app/vendor/autoload.php
SQLite в памяти: позиции и итоги, нумерация по сайтам, первая версия из
шаблона, реквизиты, правка черновика на месте, неизменяемость отправленной
версии, новая версия при правке, «Новая версия», лента, источник записи;
tests/client.php (запускается оттуда же) — отправка через «Отправить
клиенту» (ссылка на каждую отправку, фиксация версии, статус, лента, отказ
для истёкшего КП), просмотры (роботы, повтор, сотрудник, первый просмотр,
уведомление), «Принять» (только новейшая версия, один раз), «Задать вопрос»
(сообщение с сайта, связи с лидом и компанией, лимит), задача по первому
открытию КП; tests/presentation.php (оттуда же, шаг E) — Презентация (без
версий, проверка адреса, вид не меняется), её отправка («Посмотреть», без
файлов), адрес перехода с метками, отсев проверок ссылок, задача один раз
при открытой, новая после выполненной, выключение настройкой, расчёт
«сегодня / ближайший рабочий день».
Состояние работ
Выпущено 1.0.0 (23.10.2026) вместе с skeeks/cms 6.4.9.64 и
skeeks/cms-communication 1.4.0: КП (шаги B и C этапа 3) и Презентации с
задачей при первом открытии (шаг E). Проверено на стенде skeeks.com
настоящими письмами с тестового ящика: отправка письмом, отказ СМС до
провайдера на стенде, просмотр засчитывается один раз только из показанной
страницы (curl и проверки ссылок не засчитываются), «Принять», «Задать
вопрос», уведомления, задача «Позвонить», переход Презентации с метками;
светлая и тёмная темы, 375 px.
Дальше (по плану, cms-communication/ARCHITECTURE.md): шаг D — необязательные
позиции с выбором клиента и «Выставить счёт» из принятого КП.
Поддержка
Вопросы по установке и работе решения можно задать командой SkeekS или завести обращение в репозитории.
