Командировка создается из чата задачи путем нажатия в соответствующей кнопки чат-бота.
Создать командировку сможет только тот, кто вщиках, ответсвенном или наблюдателях к задаче

Вкоде: файл bots-master/bot.php и файл include/133_mtr.php
bot.php:
if ($command['COMMAND'] == 'Командировка') {
133_mtr.php:
if(trim($mess['CHAT_ENTITY_TYPE']) == "TASKS" && $mess['FROM_USER_ID'] != 487) {
Стадии можно двигать только вперед.
В коде: весь код, отвечающий за движения по стадиям и редактирования полей командировки находится в файле php_interface/include/crm_dynamic.php.
if ($entityTypeId === 167)
Также в бизнес-процессах реализована функциональность, которая выполняется при переводе командировки в ту или иную стадию:
https://gkyw.ru/bizproc/processes/59/bp_list/
Дату окончания командировки можно менять только на первых трех стадиях командировки (ограничения в php_interface/include/crm_dynamic.php).
Если необходимо изменить в другой стадии, то в таблице b_crm_dynamic_items_167 (база данных Битрикса) нужно изменить поле UF_CRM_6_CLOSEDATE.
Поле "Дата окончания командировки" - UF_CRM_6_CLOSEDATE - является обязательным на всех стадиях кроме "Перенести в след стадию ---->" и "Не требуется", однако, для дополнительной безопасности был реализован БП, срабатывающий при изменении элемента сущности командировок, представляющий функционал перемещения элемента на стадию "Перенести в след стадию ---->" в случае заполнения "Дата окончания командировки" пустыми данными (очищении), и отправляющий уведомление сотруднику внесшему изменения о необходимости заполнения поля:
crm/configs/bp/CRM_DYNAMIC_167/edit/582/
При переводе командировки на вторую стадию у сотрудников, указанных в поле "Командируемые сотрудники", создаётся отсутствие в графике отсутствий. В php_interface/include/crm_dynamic.php
.png)
Если дата командировки меняется, то меняется и дата в отсутствиях, но только в том случае, если командировка находится в первых четырех стадиях. В противном случае не меняются стадии самой командировки.
В php_interface/include/crm_dynamic.php
.png)
Если к платежу привязан счет на оплату, то командировка из счета на оплату копируется в платеж.
https://gkyw.ru/services/lists/28/bp_edit/264/#A15081_11623_44233_96696
Затраты на командировку. Складываются из следующих показателей:
Поле «Затраты на командировку» (UF_CRM_6_PAYMENTS) в карточке командировки обновляется периодически запускающимся бизнес-процессом https://gkyw.ru/bizproc/processes/61/bp_edit/266/
Для удаления командировки необходимо переместить ее в стадию «Не требуется».
Каждый день по расписанию запускается бизнес-процесс, который проверяет все командировки в данной стадии и автоматически переносит их в стадию «Составление авансового отчета».
https://gkyw.ru/bizproc/processes/59/bp_edit/147/#A38630_24493_34924_37152
Перемещать командировку в эту стадию могут только ответственный либо наблюдатели, либо участники команды.
Перемещать из финальной стадии в стадию «Проверка авансового отчета» могут только пользователи из группы «Действия с первичными документами».
Перемещать в эту стадию могут только пользователи, имеющие отношение к элементу crm (сделка, лид, мтр), который привязан к командировке. Этими пользователями могут быть ответственный, создатель, наблюдатели crm.
Существует бизнес-процесс, который каждые сутки проверяет все командировки в стадии «Проверка авансового отчета» и пишет в чат сообщение о необходимости проверки соответствующим пользователям.
Перемещать в данную стадию могут только пользователи из группы «Действия с первичными документами».
Перемещать командировку в эту стадию могут только ответственный либо наблюдатели, либо участники команды.
Существует бизнес-процесс, который каждые сутки проверяет все командировки в стадии «Составление авансового отчета». Если с момента окончания командировки (UF_CRM_6_CLOSEDATE) прошло более 7 дней, об этом отправляется сообщение в чат командировки.
Смена команды возможна только в первой стадии командировки.
Делаются в списке Путевые листы: https://gkyw.ru/services/lists/103/view/0/?list_section_id=
Пример завершенного путевого листа: https://gkyw.ru/services/lists/103/element/0/3636386/?list_section_id=
При внесении изменений в путевой лист необходимо пересчитать поля:
Адрес папки с приложением на диске http://gkyw.ru/marketplace/appPayment/
Примечания:
Файл /modules/m_payments.php:
Метод action_list(). Для пользователя Никитина Е.Г. ставим метку ADMIN, чтобы она могла видеть все платежи
Метод action_filter(). Для пользователя Калёнова Н.Н. доступен весь список з/п. С окладами и премиями
.png)
Если сумма платежа не равна сумме разбитых платежей, возможно возникла какая-то ошибка при разбиении. В таком случае сумма будет выдела красным
.png)
Дополнительные значки
.png)
Выдача доступов к расчётным счетам и функциям приложения осуществляется в модальном окне по кнопке "Доступ"
.png)
Доступ к функциям приложения отмечается чекбоксами.
Если пользователям 1, 2, 3 нужно выдать такой же доступ, как у пользователя 5, первым отмечается пользователь 5. После того, как подгрузятся чекбоксы, выделяем пользователей 1, 2, 3 и жмём на "Сохранить"
Любой пользователь, у которого есть доступ к приложению, может выдать любому другому пользователю доступ к функциям и р/с в рамках своего доступа
 (1).png)
Доступ к р/с предоставляется как "один ко многим".
К одному р/с можно дать доступ сразу нескольким сотрудникам.
Так же одному сотруднику можно дать доступ к нескольким р/с
Во вкладке "Счета" можно скрыть "ненужные" счета
.png)
Если у пользователя есть доступ к наличным платежам, становится доступна вкладка "Сейф". В ней пользователя может видеть остаток и движение наличных своего сейфа.
Просмотр всех сейфов доступен пользователям Белоглазов А. и Ровнов А. (прописано в main.php)
.png)
Сохранение правил осуществляется в файл rule в папке rules в каталоге с приложением appPayment.
.png)
Выполнение правил осуществляется регулярно запускаемым бизнес-процессом: https://gkyw.ru/bizproc/processes/61/bp_edit/162/
Ответственный за платёж
Если, при загрузке выписки, будет найден подходящий платёж, ответственным за этот платёж станет указанный в правиле пользователь.
 (1).png)
Сохранение правил по ответственным осуществляется в файл assigned в папке rules в каталоге с приложением appPayment.
Применительно к полю «Назначение платежа» поиск соответствия определяется по подстроке.
Расчетный счет в приложении появляется сразу, как только добавляется в реквизит организации. Но доступ к этому счёту нужно выдавать отдельно.
.png)
При загрузке платежей из выписки устанавливается ответственный за контрагента. Если его нет, ответственный за нашу компанию.
Если платёж "по карте", ответственным за платёж будет ответственный за карту на дату платежа
Разбиение на задачу
Для получения доступ к задаче необходимо зайти в нужную Сделку, во вкладку задачи, выбрать нужную задачу, справа жмакнуть на кнопу «Получить доступ» и только после этого откроется доступ и можно разбивать платежи.
Разбиение на командировку
Если платёж не разбит, при разбиении на командировку, в платёж прописывается ID задачи из командировку, CRM из задачи и ID самой командировки.
Если платёж разбит, в платёж прописывается только ID командировки
Разбиение на счёт
Плюсовые платежи можно разбить на Счёт(159).
Список счетов формируется исходя из данных платежа (ИНН контрагента)
К платежам одновременно привязываются и счета и счета на оплату (при наличии). В некоторых моментах это вызывает путаницу, т.к. ID счёта может совпадать.
Поэтому для разделения можно ориентироваться на ID задачи и Ссылку на счёт.
Если ID задачи 0 - это Счёт.
Если ID задачи любой другой – Счёт на оплату.
Если в ссылке crm/type/159 – это Счёт.
Если в ссылке crm/type/128 – это Счёт на оплату.
.png)
Для запросов можно пользоваться конструкцией:
"SELECT e6.VALUE AS LINK
FROM b\_iblock\_element AS e
LEFT JOIN b\_iblock\_element\_property AS e6 ON e6.IBLOCK\_ELEMENT\_ID = e.ID AND e6.IBLOCK\_PROPERTY\_ID =158
WHERE e.IBLOCK\_ID =28AND e6.VALUE LIKE '%/crm/type/159/%'"
Адрес папки с приложением на диске http://gkyw.ru/marketplace/appPayFot/
В личной карточке сотрудника есть опция «Отображать баланс».
Если ограничение стоит на отдел, то нужно смотреть в коде:
.png)
Если не отображается фот выполненных задач, возможно, это связано с тем, что не выставлена галочка «Отображать баланс» в профиле.
Должности подтягиваются из штатного расписания. В списке «Штатное расписание» должны быть элементы, привязанные к id отдела, в который осуществляется прием сотрудника.
Имеются следующие ограничения:
В случае наличия выговора начисляется 70% от оклада.
Если у сотрудника выбран график «Работа в офисе (4ч) FaceControl», либо другой график с указанием длительности работы, то оклад будет пересчитан.
Длительность р/д по графику – считается без учета перерыва, то есть если общая длительность 5ч и перерыв 1ч, то длительность р/д будет 4
Сначала будет посчитана ставка по формуле «Длительность р/д по графику»/8. Потом будет получена сумма оклада по штатному расписанию и умножена на ставку.
Пример:
4/8 = 0,5; 30 000*0,5 = 15 000.
Если возникает необходимость, неразбитые платежи можно просто удалять.
Перепривязка/переразбитие платежей осуществляется путем редактирования элементов соответствующих списков:
Смена одного элемента в платеже подразумевает так же смену связанных с ним элементов.
Командировки могут быть привязаны к задачам, сделкам и МТР; задачи – к элементам CRM (например, сделкам).
Например, если меняется привязка платежа к командировке, необходимо также необходимо изменить привязанную задачу и сделку. Посмотреть, к какой задаче привязана командировка, можно в ее карточке.
Вся работа с начислениями осуществляется в списке «Заработная плата»: https://gkyw.ru/services/lists/27/view/0/?list_section_id=
Здесь, в частности, можно изменить сумму выплаты конкретному сотруднику за конкретный месяц.
В приложении «Мои данные» возможно начисление нулевой выплаты в случае, если
(сумма Топлива + Переводы + Задачи) + (сумма ФОТ ответственного в завершенных задачах) меньше нуля
Для такого начисления требуется дальнейшее подтверждение руководителем.
Если у сотрудника система работы «Руководитель подразделения», то ФОТ руководителя рассчитывается как
Сумма начисления (ЗП + Премия) * 100 / Сумма ФОТов ответственных в закрытых задачах за месяц * ФОТ конкретной задачи / 100
Изменения в штатное расписания вносятся путем редактирования элементов списка «Штатное расписание»: https://gkyw.ru/services/lists/70/view/0/?list_section_id=
Пример элемента для должности «Инженер-программист» в ОИТ: https://gkyw.ru/services/lists/70/element/0/3214928/?list_section_id=
ID подразделения можно посмотреть в «Структуре компании»:
Привязка сотрудника к элементу штатного расписания (пользовательское поле UF_ID_POSITION*) осуществляется при приеме сотрудника на работу через приложение «Мои данные» либо при переводе сотрудника в другую должность посредством использования бота.
Изменение оклада и названия должности осуществляется путем редактирования элемента списка «Штатное расписание».
*UF_ID_POSITION больше не используется. Создано новое множественное поле UF_USR_STAFFTABLE
Руководитель может принять в свой отдел любого пользователя на должность из штатного расписания
.png)
Если пользователь находится в нескольких отделах, около его ФИО будет показа кнопка удаления из отдела %20(1)%20(1).png)
Оклад начисляется в каждом отделе согласно штатного расписания
Методы «getVacation» и «getNormTime» перенесены в папку «include» в файл «NormTime_Vacation.php». Добавлен файл «appSetting.php», в котором располагаются настройки приложения, в частности праздничные дни 2024 года и константы учета отсутствий.
В методах «getVacation» и «getNormTime» изменен способ получения праздничных дней. Учитываются праздничные дни календаря Битрикс и дни, указанные в «appSetting.php» в массиве «HOLYDAYS_2024».
Добавлен учет отсутствий из настроек модуля «Интранет». Учет происходит согласно настройке «VACATION_FROM_INTRANET», которая позволяет отбирать отсутствия для отпуска из настроек модуля, либо из массива «VACATION_LIST».
Включен учет сокращенных рабочих дней, настраиваемый «ABSENCE_SHORT_WORK_DAY». При указании «true» сокращенный рабочий день, например, в выходной приравнивается к рабочему, а не считается выходным.
Во вкладке «Общая информация» изменено отображение. В формулу нормы часов заносятся сокращенные рабочие дни и указывается вычет отсутствий в рабочие дни. Рабочие дни теперь указывают общее количество рабочих дней в месяце с учетом праздников и сокращенных рабочих дней.
Функционал отсутствия в боте описывается несколькими командами (178 - 183). Функционал до обновления оставлен в bot.php и нескольких файлах handler_... Новый функционал размещён в файле handler_absence.php, где располагается код обработки команд, поступающих в список "Бот".
При поступлении команды боту или ввода сообщения, начинающегося с "Даты начала и окончания", в список добавится новый элемент с номером команды, параметрами, диалогом и отправителем. После чего запускается БП, где подключается файл handler_absence.php.
Функции приведённые в handler_absence.php располагаются в файле functions.php, подключаемом в коде БП.
При создании отсутствия сотрудник может передать обязанности на любого сотрудника через ссылку на него. ID сотрудника, исполняющего обязанности, записывается в пользовательское поле IO_USER в инфоблоке отсутствий.
Исполняющий обязанности сотрудник отображается в карточке профиля сотрудника со ссылкой на профиль для быстрого перехода. Функционал описан в init.php в функции GetDutyTransferStr.
Клавиатура бота зависит от пользователя и перестраивается при каждом вызове.
При выборе пункта "отсутствие" будет сформирована клавиатура, где всегда есть кнопки "Создать отсутствие с передачей обязанностей" и "Создать отсутствие без передачей обязанностей". Если у пользователя указан только один руководитель, то появится кнопка "Создать отсутствие с передачей обязанностей руководителю". Если у пользователя есть отсутствия, которые ещё не начались, то для него доступна функция смены исполняющего обязанности, это реализуется кнопкой "Сменить и.о. в отсутствии".
После выбора создания отсутствия формируется клавиатура с кнопками типов. При нажатии на кнопку в поле ввода текста сообщения будет вставлен текст, который бот интерпретирует, как команду. При этом кнопка выбора ежегодного отпуска может быть неактивна, если у сотрудника не установлена дата принятия на работу.
Весь функционал обёрнут в обработчик исключения, поэтому при возникновении ошибки в чат пользователю будет отправлено сообщение "Произошла ошибка. Данные об ошибке перенаправлены администратору.", а данные пересылаются администратору 906 с указанием ID пользователя.
Для обеспечения корректного функционирования в init.php добавлено условие на обновление отсутствия, так как из публичной части портала через график отсутствий сбрасывается и.о. сотрудника. Поиск осуществляется по дате 30.06.2025.
Папки подключаются в чате сущности (сделки или задачи) путем взаимодействия с ботом:
В сделке:
В задаче:
Для некоторых старых сделок автоматическое создание папки может не осуществляться корректно.
В бд в таблице b_uts_crm_deal по VALUE_ID ищется сделка. В поле UF_OLD_DEAL_CATALOG ставится 1, затем сделка вручную обновляется из карточки. Актуально для сделок с id< 49602 без каталогов
Пустые папки задач (!), созданные более суток назад, удаляются автоматически.
После создания счета в crm_dynamic.php отрабатывает событие «Operation\Add». В нем получаются данные по сделке и проверяется его заполнение, далее заполняется поле «COMPANY_ID» в счете через БД в соответствии со значением из сделки.
Закрытие счета вручную не допускается!
Функция возвращает прежнее значение поля "Дата платежа", при попытке изменения Счета, находящегося в финальных стадиях, и, отправляет уведомление пользователю, пытавшемуся изменить значение поля. Реализована в crm_dynamic.php, и отмечена комментариями: // === Запрет изменения поля "Дата платежа" в Счетах. Работает лишь при изменении поля уже существующего Счета, но не при создании нового Счета.
При создании Счета выполняется бизнес-процесс CRM, который проверяет, указана ли Сделка в соответствующем поле Счета, и, если таковая обнаружена, заполняет поля "реквизиты нашей Компании" и "Клиент" в Счета из указанной Сделки
https://gkyw.ru/crm/configs/bp/CRM_DYNAMIC_159/edit/599/
Сначала формируется список из ИНН контрагента и ID "нашей компании" из приходных счетов.
По этим реквизитам ищутся неразбитые плюсовые платежи (в которых указана наша компания и ИНН контрагента из счёта)
Если найден неразбитый платёж и он один - проверяется сумма платежа и сумма счёта. Если сумма одинаковая - счёт закрывается, платёж разбивается.
После разбиения платежа в счет вносятся изменения, на основании этого платежа, а именно:
В платеж в свою очередь вносится вся информация по данному счет, на который он был переразбит.
Код шаблона БП для автозапуска находится по ссылке.
После разбитии счета отправляется сообщение в чат План поступлений ДС о поступлении. Сообщение формируется в методе sendPlanToPay в файле crm_dynamic.php
.png)
Доступно пользователям из группы «Действия с первичными документами».
.png)
При перепривязывании счета к другому элементу CRM меняется привязка к CRM у соответствующего счету платежу.
Стадия счета изменяется автоматически в зависимости от того, сколько времени осталось до наступления даты завершения. БП: https://gkyw.ru/bizproc/processes/61/bp_edit/156/.
Из любого счета можно запустить БП "План поступлений". Подробнее о работе БП на странице "Бизнес-процессы"
Выписываются в следующих случаях:
За просроченную задачу. Просроченной считается задача, которая находится в статусе «выполняется» с момента дедлайна которой прошло более суток.
Предупреждение бухгалтеру в случае наличия у него просроченных счетов на оплату. Просроченным считается счет на оплату, у которого: 1) Планируемая дата оплаты меньше сегодняшней. 2) Сумма и валюта = Осталось оплатить. 3) Находится в стадии «Ожидает оплаты».
Предупреждение пользователю в случае, если у него имеется просроченный неутвержденный авансовый отчет.
Проверяется командировка в стадии «Утверждение авансового отчета». Проверяется, сколько времени прошло с текущего момента до значения, указанного в поле «Дата окончания командировки». Если прошло более 2-х недель, выписывается предупреждение.
Каждый день в указанное время проверяется входящая почта на почтовых ящиках наших (!) компаний. Если к указанному времени почта не разобрана, выписывается предупреждение сотрудникам из группы “Действия с электронной почтой”.
Выписывает предупреждение ответственному за сделку в случае ее просрочки. Просроченной считается сделка, у которой: 1) Дата завершения меньше сегодняшней 2) Стадия не терминальная. Рассматриваются только сделки категорий «Объект» и «Объект-исключения». Сделки в стадии «Работы приостановлены» и «Заключение договора» из рассмотрения исключены.
Предупреждение за командировку выписывается пользователю в случае, если у него имеется просроченный неутвержденный авансовый отчет.
Проверяется командировка в стадии «Утверждение авансового отчета». Проверяется, сколько времени прошло с текущего момента до значения, указанного в поле «Дата окончания командировки». Если прошло более 2-х недель, выписывается предупреждение.
Группа "Не получать автоматических взысканий". В административной панели id = 37. Данная доработка исключает пользователей состоящих в группе "Не получать автоматических взысканий" из списка сотрудников, которым будет выдано автоматическое предупреждение, и затрагивает следующие БП (из ленты):
"Предупреждение". id = 43 . Данный БП выдает предупреждения за просроченные задачи
"Предупреждение за платежи". id = 136
"Предупреждение за командировки". id = 106
"Предупреждение за письма". id = 108
"Предупреждение за топливные платежи". id = 112
"Предупреждение за сделки". id = 120
"Предупреждение за счета на оплату". id = 146\
Используется прерывание цикла перед созданием предупреждения:
%20(1)%20(1).png)
Либо, исключение пользователя состоящего в группе "Не получать автоматических взысканий" из списка сотрудников, которым будет выдано предупреждение:
%20(1).png)
Либо, исключение пользователя из списка сотрудников, которым будет выдано предупреждение непосредственно при получении данных в SQL - запросе:
%20(1)%20(1).png)
Прогулы автоматически выставляются пользователям, которые за текущую дату не начинали рабочий день.
Неактивные пользователи и пользователи с графиком «Не учитывать рабочее время» не рассматриваются.
Автоматически выписываются выговоры тем пользователям, у которых за месяц 3 и более прогула.
Ежедневно по расписанию запускается БП, в котором за текущий месяц собираются предупреждения, замечания и выговоры сотрудников в соответствующие массивы и перебираются в данном порядке. По списку предупреждений формируется поисковая подстрока, которая при совпадении со ссылкой из замечания удаляет текущее предупреждение из отобранного списка. Таким образом реализуется связь между замечаниями, сделанные за конкретные предупреждения. Аналогично происходит с замечаниями и выговорами.
После отбора всех дисциплинарных взысканий и удаления, упомянутых в ранее опубликованных в ленте новостей предупреждений и замечаний, формируются замечания и выговоры при наличии трёх и более предупреждений и замечаний соответственно.
Все замечания и выговоры, созданные автоматически, публикуются от имени Алексея Ровного.
Для предотвращения возможного зацикливания БП помимо счетчика дисциплинарных взысканий ($usersStrikes) осуществляется проверка на количество предупреждений и замечаний в массиве. При возникновении зацикливания администратору Юлия Евсеева отправляется уведомление о попытке создания дисциплинарного взыскания при отсутствии трёх предупреждений или замечаний, а также цикл останавливается и переходит к обработке данных по следующему сотруднику.
Логика БП запускается при выполнении условия
date("N") < 6 && !in_array(date("d.m.Y"), $holidays)
что предотвращает выписывание замечаний и выговоров в выходные дни и праздники по календарю Битрикс.
Каждый день в 17:00 запускается БП, который проверяет счета на оплату, которые находятся в стадии «Оплачено» более одного дня. При нахождении таковых в чат отправляется сообщение «Данный счёт был оплачен 01.10.2024г. Алексей Ровнов, прошу проверить правильность заполнения полей в карточке счёта на оплату и/или загрузить требуемый платёж.», где вместо «01.10.2024» подставляется дата ПП из счета на оплату, а вместо «Алексей Ровнов» упоминается сотрудник из группы 24 «Оплата счетов», относящийся к данному счету на оплату.
После отправки сообщения в чат в пользовательские поля UF_STRIKE записывается 1, что свидетельствует о том, что в чат счета на оплату было отправлено сообщение, а UF_STRIKE_DATE записывается дата отправки сообщения, по которой проверяется прошествие 3-х дней для выписывания предупреждения и изменяется UF_STRIKE на 2, что свидетельствует о выписывании предупреждения.
В нерабочие дни БП срабатывает и увеличивает значение UF_HOLIDAY_STRIKE на 1 по всем проблемным счетам, что реализует выписывание предупреждений через 3 рабочих дня. Если по проблемному счету значение этого поля больше 0, то в рабочие дни значение уменьшается на 1.
Предупреждение получают все сотрудники, относящиеся к группе 24, кроме сотрудника Александр Белоглазов. В предупреждении указывается, за какой счет на оплату оно было выписано.
Каждые полчаса запускается бизнес-процесс, который анализирует логи сервера (файл access.log) на предмет совершаемых пользователями закачек. Ищет записи, обозначающие закачку с десктопного приложения (признак – наличие подстроки desktop_app/storage.php?action=Download&token_sid=). Если таких закачек совершается много за короткий период времени, то очевидно, что имеет место быть включенная у пользователя синхронизация. Сообщение об этом отсылается в соответствующий чат.
Реализуется через приложение «Чаты групп» и работающий с его данными бизнес-процесс. Приложение сохраняет данные в элементы списка «Настройки групп». Бизнес-процесс запускается раз в сутки, считывает настройки из элементов списка и добавляет в соответствующие группы и чаты пользователей в соответствии с критериями, которые заданы приложением.
Элемент списка хранит следующие настройки:
Руководитель. Если указана 1, то в группу будут добавлены все руководители подразделений.
Смена рабочего графика осуществляется в чат-боте.
При редактировании рабочего времени у какого-либо пользователя отправляет в чат «Распорядок дня» сообщение об этом.
Для фиксирования рабочего времени по графику «FaceControl» используется программная система из двух приложений:
В случае, если пользователь с рабочим графиком “FaceControl” не завершил рабочий день при уходе, сервер TimeControl автоматически завершает его. Длительность рабочего дня в Б24 при этом устанавливается равной 5 минутам.
В случае, если сотрудник с графиком «Удаленное рабочее место» подходит к FaceControl, то при условии, что его рабочий день завершен или приостановлен, график автоматически сменится на «FaceControl», если рабочий день не завершен/приостановлен, то сотруднику придет оповещение о том, что график сменить нельзя.
В Б24 имеется бизнес-процесс, При создании на диске файла с расширениемbak отправляет в соответствующий чат сообщение об этом.
У привязанных к компании счетах на оплату автоматически проставляется поле «Работает по ЭДО» в соответствии с тем, как данное поле выставлено у компании.
Существует периодически запускаемый бизнес-процесс, который по ИНН контрагента в соответствующем поле платежа находит контрагента из списка компаний и вписывает найденную компанию в соответствующее поле платежа.
БП: https://gkyw.ru/bizproc/processes/61/bp_edit/155/
Происходит, если не заполнены реквизиты.
БП: https://gkyw.ru/crm/configs/bp/CRM_COMPANY/edit/447/
Старый способ загрузки лидов: если лид загружен из Селдона, то проставляется соответствующее значение источника в поле SOURCE_ID. Также инициализируются значения полей Название и Цена лида (переписываются из временных полей).
Текущий способ загрузки лидов. Лиды загружаются посредством приложения "Госзакупки в лид" (приложение разработано нами). Приложение работает таким образом, что при вводе реестрового номера в карточку лида (при создании и/или обновлении) информация о нем подтягивается в карточку с сайта госзакупок.
Также по прописанному в лиде ИНН организатора ищется контакт или компания в CRM и привязывается к лиду. Если у привязанной компании тип «Постоянный заказчик», то лид переходит в стадию «Постоянный заказчик».
Также производится проверка, существует ли уже лид с таким реестровым номером. Если существует, то он удаляется.
По ИНН организатора выбираются предыдущие лиды данного заказчика. В ленту лида пишется информация по прошлым лидам.
Каждый день, перед проверкой даты окончания сроков закупки, происходит актуализация полей «Окончание срока закупки[endpoint]» и «Окончание приёма заявок», у всех лидов, в категории стадий «в работе» и заполненным полем «Реестровый номер закупки[endpoint]». Бизнес-процесс, осуществляющий эти действия, описан в разделе документации "Бизнес-процессы".
Каждый день просматриваются лиды в стадиях «В работе» и «Постоянный заказчик», у которых дата окончания приема заявок меньше сегодняшней даты. Данным лидам устанавливается статус «Не подходит».
В рабочие дни ищутся лиды в статусе «В работе», у которых с момента последнего действия с ними прошло два и более рабочих дней. Такие лиды переходят в статус «Новая».
Ответственным за лид устанавливается пользователь, который перенес его в эту стадию.
Каждый день проверяются лиды, у которых значение поля UF_CRM_1682507651806 равно сегодняшней дате, обнуляется это поле и устанавливает этим лидам статус «В работе».
Ответственным за лид устанавливается пользователь, который перенес его в эту стадию.
В поле Название лида пишется его Краткое наименование.
Создается задача по ведению закупки.
Создается папка лида.
При переведении ЛИДа в ручном режиме в данную стадию необходимо выбрать причину выбраковки. Доступны:
"не указано";
"нужна лицензия ФСТЭК".
Для удобства, данное поле установлено как обязательное, что способствует автоматическому появлению окна для заполнения поля.
Отправляется сообщение в чат «Результаты торгов».
В случае со статусом «Не подходит» Создается задача «Анализ причины отклонения».
По адресу M:\ОПР имеются следующие каталоги: M:\ОПР!Степанушкина, M:\ОПР!Леонтьева, M:\ОПР!Сафронов и т.д.
При перенесении ЛИДа в стадию "в работе ОПР" формируется рабочий каталог закупки со следующими параметрами:
Наш порядковый номер (0001, 0002 и так далее);
Номер закупки с ЕИС (или с торговой площадки), например 32414225058 или ПР1792/2024;
Указанные атрибуты указываются через дефис (для удобства восприятия).
Это каталог должен формироваться в папке сотрудника, взявшего ЛИД в работу (M:\ОПР!Степанушкина, если взяла Ирина Степанушкина , M:\ОПР!Леонтьева, если взяла Мария Леонтьева ).
Сформированный каталог содержит подпапки с названиями: "!ИД", "!Заявка", "!Хлам".
При переносе ЛИДа в стадию "закупка подана" и указании юр. лица. от которого подана заявка, название нового каталога дополняется организацией, указанной при смене стадии на "Закупка подана".
Реализовано в соответствующих роботах.
Автоматически устанавливается дата завершения сделки равной сроку по договору (UF_DATE_TERM). Выполняется только при создании сделки.
Функция по очищению поля "Дата завершения" находится в init.php и отмечена комментарием
// === очищение поля "Дата завершения" для воронок Объект и Объект-исключение
Функция расположена в init.php и отмечена комментарием
// === ограничить круг лиц способных менять дату завершения сделки (воронки Объект и Объект-ислючение)
Данная функция проверяет какие поля пришли для обновления в элемент сделки перед обновлением, и, если:\
выполняется очищения обновляемого поля перед апдейтом элемента, а пользователь, совершивший модификацию элемента получает соответствующее уведомление.
Разрешенные группы:
id 38 - "Изменение Даты завершения Сделок и Сделок-исключений" - группа в Административной панели
id 33 - отдел ОПР - подразделение CRM
Осуществляется по принципу: номер – название, указанное при создании.
Каждый день запускается бизнес-процесс, который находит все закрытые сделки (успешные либо провальные) и устанавливает им дату завершения следующим образом:
Дата выставляется «пустой» во всех остальных случаях.
Проверяется, как именно была закрыта сделка. Если не из бота, то происходит откат в предыдущую стадию (Алексею Ровнову можно закрывать без бота).
Находит все закрытые сделки (успешные либо провальные) и устанавливает им дату завершения следующим образом:
Дата подписания последнего АВР выставляется в случае наличия «успешных» АВР у сделки.
Дата оплаты последнего счета ставится в случае, если нет АВР, но есть счета (тип оплаты – наличные).
Дата выставляется «пустой» во всех остальных случаях.
Каждый день запускается бизнес-процесс, который производит расчет поля Налог (сумма всех АВР у сделки) и обновляет его у сделок.
Ограничения реализованы в бизнес-процессе, обрабатывающем события от бота.
При создании АВР срабатывает БП «Сделка и бухгалтер» в «Процессы CRM» . Этот бизнес процесс проверяет сумму всех АВР прикрепленных к той же сделке, что и созданный АВР и если эта сумма превысит сумму по сделке, то отправится сообщение в чат «При добавлении данного АВР сумма всех АВР по прикрепленной сделке…»
Также данный БП добавляет в чат бухгалтеров нашей компании, к которой прикреплен АВР.
При создании АВР выполняется бизнес-процесс CRM, который
проверяет, указана ли Сделка в соответствующем поле АВР, и, если таковая обнаружена, заполняет поля "реквизиты нашей Компании" и "Клиент" в АВР из указанной Сделки
https://gkyw.ru/crm/configs/bp/CRM_DYNAMIC_144/edit/598/
Ответственный по сделке автоматически добавляется наблюдателем в привязанные АВР.
После создания АВР в crm_dynamic.php отрабатывает событие «Operation\Add». В нем получаются данные по сделке и проверяется его заполнение, далее заполняется поле «COMPANY_ID» в АВР через БД в соответствии со значением из сделки.
Каждый день запускается бизнес-процесс, который находит АВР в стадии «АВР отправлен заказчику», у которых дата завершения меньше текущей, и переводит их в стадию «Документы не предоставлены».
Доступно пользователям из группы «Действия с первичными документами».
.png)
Автоматически проверяется, есть ли в системе АВР с таким же номером счета/фактуры, привязанный к той же нашей компании и с датой подписания того же года. Если имеется, то поле Номер счета/фактуры у данного АВР очищается.
Дата завершения АВР устанавливается как дата подписания + 2 месяца.
Происходит инициализация контакта, компании и реквизитов в соответствии с теми, которые имеются у привязанной сделки.
Если сотрудник не относится к группе «Действия с первичными документами», он не сможет перевести АВР в эту стадию.
На этой стадии происходит удаление из наблюдателей бухгалтеров нашей компании.
Если значения суммы, номера счета/фактуры и даты подписания АВР в Б24 не совпадают с таковыми в 1С, то в чат АВР в Битриксе отправляется это сообщение.
Раз в 3 дня осуществляется проверка подписанных в Битриксе АВР. Если АВР подписан в Битриксе, но не подписан в 1С, осуществляется его автоматический перенос в стадию «Документы не предоставлены».
Создается из комментариев к задаче, если написать «Оплатить счет».
Для редактирования полей счета на оплату необходимо вернуть его в первую стадию.
Если планируемая даты оплаты не заполнена, то она выставляется равной дате завершения.
Если у счета на оплату меняется CRM, то она меняется и в соответствующем счету платеже.
При переводе Счета на оплату в стадии: «Сбор закрывающих документов», «Документы не предоставлены», «Перенесено из бухгалтерии», «Документы не требуются», вызывается в init.php БП «Событие CRM» по шаблону.
При переводе на Оплачено запускается БП, который проверяет подходящий платёж. Если такой платёж есть - он разбивается на счёт и счёт переходит на стадию «Сбор закрывающих документов». Если платежа нет, счёт висит на стадии «Оплачено». Раз в день запускается БП, который проверяет подходящие платежи для всех счетов, которые на стадии оплачено и, если платёж найден - разбивается и двигается стадия счёта на оплату (закрытие расходных и приходных счетов).
В стадию «Сбор закрывающих документов» возможен возврат счета из стадии «Документы не предоставлены» и терминальных стадий.
Ищутся счета на оплату в стадии «Оплачено» с заполненными и отличными от нуля полями «Осталось оплатить», «Номер ПП», «Дата ПП».
У таких счетов на оплату находится значение поля «Номер задачи» и по нему формируется ссылка на задачу.
Затем ищутся все платежи, привязанные к данному счету на оплату по полю ID счета. Считается их сумма.
Найденная сумма вычитается из суммы счета на оплату. Таким образом определяем, есть ли еще остаток для оплаты.
Затем ищутся все платежи, совпадающие со счетом на оплату по значению полей «Номер ПП», «Дата ПП», «Наша компания», «ИНН контрагента», которые не разбиты (не заполнены ID счета, ID задачи и Начисление з/п) и подходят по сумме (сумма платежа >= сумме остатка).
Выбираем первый такой платеж. Разбиваем. Если при его разбитии остается остаток, то переводим счет на оплату на предыдущую стадию и отправляем сообщение о частичной оплате счета. Иначе – переводим счет в стадию «Сбор закрывающих документов» и запускаем БП «Событие CRM» для отправки информации об изменившейся стадии в чат Счета на оплату.
Периодически запускающийся БП: https://gkyw.ru/bizproc/processes/61/bp_edit/157/#A2735_88301_59918_63926
Автоматически ищутся счета на оплату, у которых поле «Стадия» пустое, но при этом заполнены и отличны от нуля поля «Осталось оплатить», «Номер ПП», «Дата ПП», а также реквизиты контрагента.
Ищутся платежи, совпадающие с этим счетом на оплату по значению полей «Номер ПП», «Дата ПП», «Наша компания», «ИНН контрагента», которые не разбиты на этот счет (не заполнено поле ID счета) и подходят по сумме (сумма платежа = - сумме счета на оплату).
Если такие платежи найдены, то счет переводится в стадию «Ожидает оплаты». Проставляются номер и ссылка на задачу и привязка к CRM (подтягиваются у соответствующего платежа). Далее стадия корректируется в зависимости от планируемой даты оплаты.
Периодически запускающийся БП:
https://gkyw.ru/bizproc/processes/61/bp_edit/268/
Оплаченный счет удаляется, если платёж, которым был закрыт счёт, переразбивается на другую задачу.
Название МТР в Битриксе синхронизируется с названием МТР в Гелиосе.
Программно разрешено менять Ровнову А.В., Ровнову Е.В. и всем, у кого есть роль в CRM "Техподдержка".
PHP-скрипт бизнес-процесса находится здесь: https://gkyw.ru/crm/configs/bp/CRM_DYNAMIC_133/edit/543/#A76049_7123_89746_52397 Он реализует автоматизированную логику управления стадиями элементов CRM с особой обработкой стадии "Инвентаризация". Код предназначен для работы с материально-техническими ресурсами (МТР) и ведения истории изменения стоимости.
<?php
use Bitrix\Crm\Service;
use Bitrix\Main\Application;
CModule::IncludeModule("iblock");
CModule::IncludeModule("crm");
$id = {{ID}}; // ID текущего элемента
$factory = Service\Container::getInstance()->getFactory(133);
$item = $factory->getItem($id);
Назначение:
iblock и crm Битрикс$name = $item->getTitle(); //название элемента
$currentStageId = $item->getStageId();
$previousStageId = $item->getPreviousStageId();
$connection = Application::getConnection();
$helper = $connection->getSqlHelper();
// Получаем названия стадий
$currentStageName = '';
$previousStageName = '';
$result = $connection->query("
SELECT NAME FROM b_crm_status WHERE STATUS_ID = '" . $helper->forSql($currentStageId) . "'
")->fetch();
if ($result && isset($result['NAME'])) {
$currentStageName = $result['NAME'];
}
$result = $connection->query("
SELECT NAME FROM b_crm_status WHERE STATUS_ID = '" . $helper->forSql($previousStageId) . "'
")->fetch();
if ($result && isset($result['NAME'])) {
$previousStageName = $result['NAME'];
}
Функционал:
b_crm_statusgetSqlHelper() для защиты от SQL-инъекций// Получение значения поля UF_CRM_7_INV_ACTIVE (булево)
$isInventoryActive = $item->get('UF_CRM_7_INV_ACTIVE');
$cost = $item->get('UF_CRM_7_COST');
Назначение полей:
UF_CRM_7_INV_ACTIVE - флаг активности инвентаризации (boolean)UF_CRM_7_COST - стоимость элемента// === Условие 1: вход в "Инвентаризацию" ===
if ($currentStageName === 'Инвентаризация' && !$isInventoryActive) {
$item->set('UF_CRM_7_COST', null); // очищаем стоимость
$item->set('UF_CRM_7_INV_ACTIVE', true); // устанавливаем флаг
$saveResult = $item->save();
}
Условия срабатывания:
false)Выполняемые действия:
UF_CRM_7_COST = null)UF_CRM_7_INV_ACTIVE = true)// === Условие 2: выход из "Инвентаризации" ===
if ($previousStageName === 'Инвентаризация' && $currentStageName !== 'Инвентаризация' && $isInventoryActive) {
// создаём элемент в списке "История изменения стоимости"
$iblockId = 184;
$date = date('Y-m-d H:i:s');
$userId = $item->get('MOVED_BY');
$el = new CIBlockElement;
$fields = [
'IBLOCK_ID' => $iblockId,
'NAME' => $name,
'ACTIVE' => 'Y',
'PROPERTY_VALUES' => [
'DATA' => $date,
'STOIMOST' => $cost,
'OPERATOR' => $userId,
'MTR' => $id,
],
];
if (!$el->Add($fields)) {
// $rootActivity->WriteToTrackingService("Ошибка добавления в историю стоимости: " . $el->LAST_ERROR);
}
// Сброс флага
$item->set('UF_CRM_7_INV_ACTIVE', false);
$saveResult = $item->save();
}
Условия срабатывания:
true)Выполняемые действия:
NAME - название элементаDATA - дата и время операцииSTOIMOST - стоимость на момент выхода из инвентаризацииOPERATOR - ID пользователя, выполнившего перемещениеMTR - ID элемента МТРUF_CRM_7_INV_ACTIVE = false)// Для использования в БП
//$isExit = ($previousStageName === 'Инвентаризация' && $currentStageName !== 'Инвентаризация');
//$rootActivity->SetVariable("isInventoryExit", $isExit);
Назначение: Закомментированный код предназначен для использования в бизнес-процессах Битрикс24. Позволяет передать переменную isInventoryExit в БП для дальнейшей обработки.
getSqlHelper()->forSql() для предотвращения SQL-инъекцийUF_CRM_7_INV_ACTIVE - контроль состояния инвентаризацииUF_CRM_7_COST - хранение стоимости элементаMOVED_BY - отслеживание пользователя, изменившего стадиюКод реализует автоматизацию процесса инвентаризации в CRM Битрикс24:
Система особенно полезна для управления материально-техническими ресурсами предприятия с требованиями к отслеживанию изменения стоимости активов в процессе инвентаризации.
Название Аренды ТС в Битриксе синхронизируется с названием МТР в Гелиосе.
Если задача привязана к лиду, то также осуществляется привязка ее к группе ОПР.
Формирование названия задачи осуществляется по принципу «Номер сделки – порядковый номер первой родительской задачи в иерархии – порядковый номер следующей задачи в родительской иерархии - … - название задачи.
Если задача не привязана к CRM, она удаляется.
Дочерние задачи наследуют привязку родительской задачи к CRM.
Простановка группы задачи осуществляется по следующему принципу: находится первое в списке подразделение ответственного, сохраняются его id и название; если есть группа, привязанная к подразделению с соответствующим id, выбирается она; если такой группы нет, просматриваются группы ответственного и среди них ищется совпадение по сохраненному названию подразделения.
Определяется либо в описании самой задачи при создании задачи, либо в комментариях к ней при дальнейшей работе.
При создании задачи можно указать начальный ФОТ, в описании прописав строку «ФОТ сумма» (например, «ФОТ 50000).
Устанавливает ФОТ в задаче: - Постановщик задачи; - Ответственный или наблюдатель Сделки, в состав которой входит эта задача; - Участник группы Установка ФОТа задач без согласования
ФОТ ответственного = ФОТ задачи – суммарный ФОТ подзадач.
В случае, если может получиться отрицательный ФОТ ответственного, то ФОТ задачи пересчитывается как равный сумме ФОТов всех подзадач. Как правило, для этого действия необходимо подтверждение постановщика родительской задачи (за исключением пользователей из группы «Установка ФОТа задач без согласования»).
Если дочерняя задача перепривязывается к другой задаче, то осуществляется пересчет ФОТа у прежней родительской задачи.
Если меняется ФОТ в закрытой задаче, привязанной к закрытой сделке, об этом отправляется сообщение Ровнову А.
Закрытие задач с отрицательным ФОТом запрещено. Ограничение находится в init.php.
Функционал «ФОТ по ШР» и «Общий ФОТ по ШР» описан в БП https://gkyw.ru/bizproc/processes/35/bp_edit/448/ запускаемым из init.php при срабатывании событий OnTaskUpdate и OnTaskElapsedTimeAdd.
При создании задачи «ФОТ по ШР» и «Общий ФОТ по ШР» присваивается значение 0 из БП https://gkyw.ru/bizproc/processes/34/bp_edit/48/ (Базовая установка ФОТ по ШР) для отображения в задачи.
ФОТ по штатному расписанию рассчитывается по формуле: ФОТ по ШР = Оклад сотрудника * 12 месяцев / (248 рабочих дней - 20 отпускных дней) / 8 часовой рабочий день / 60 минут * Время выполнения задачи в минутах.
«Общий ФОТ по ШР» рассчитывается, как сумма «Общий ФОТ по ШР» и «ФОТ по ШР» всех подзадач.
Время выполнения задачи рассчитывается в том же БП по логам для задач со стандартным учетом времени (возможен учет времени для всех задач).
Стандартный учет времени включается для всех новых задач группы ОКПО автоматически и сохраняет свою активность несмотря на возможные изменения. Функционал запрета отключения описан в БП.
«Общий ФОТ по ШР» и «ФОТ по ШР» записывается в круглых скобках рядом с полями «ФОТ» и «ФОТ ответственного» соответственно. В скобках рядом с «ФОТ» прибавляется значение «ФОТ ответственного» текущей задачи.
.png)
https://gkyw.ru/bizproc/processes/35/bp_edit/49/ запускаемым из init.php при срабатывании событий OnTaskUpdate.
При изменении задачи в БП происходит проверка на отключение 'ALLOW_TIME_TRACKING', при отключении происходит обновление и отправка сообщения сотруднику, изменившему задачу, о невозможности отключения учета времени.
Поле скрывается для всех сотрудников, кроме администраторов, постановщика задачи и администраторов и модераторов групп (b_sonet_user2group), из init.php («FOT to SL» для поиска).
Поля ФОТа задач доступны только сотрудникам относящимся к:
Функционал реализован в компоненте задач, расположенном в «/home/bitrix/www/local/modules/tasks/lib/provider/tasklist.php» («Доступ к полям ФОТ» для поиска).
Написанный функционал изменяет значения всех полей ФОТ на пустое, что гарантирует полное скрытие значений в этих полях на всех страницах, где отображаются задачи.
Скрытие реализуется постепенной проверкой. Сначала проверяется пользователь на администратора. В случае отрицательного ответа осуществляется проверка на соответствие пользователя на постановщика или исполнителя задачи. В случае отрицательного ответа осуществляется проверка пользователя на непосредственного руководителя или руководителя по иерархии исполнителя задачи. Если соответствие на найдено, то осуществляется перебор всех CRM, привязанных к задаче. При нахождении сделки проверяется наличие её в массиве разрешенных задач (это сделано для разгрузки от повторного поиска соответствий по сделке). Если в массиве нет подходящей сделки, то осуществляется поиск методом «\Bitrix\Crm\DealTable::getList», если сделка не содержится в массиве неподходящих задач, после при удачном получении ответственного происходит сравнение с пользователем и записывается сделка в массив при положительном результате, иначе получается список наблюдателей методом «\Bitrix\Crm\Observer\Entity\ObserverTable::getList». Дальше перебирается массив наблюдателей на совпадение с пользователем. Если ни ответственный, ни наблюдатели не соответствуют, то дальше будет осуществлена проверка на непосредственного руководителя ответственного за сделку. В случае отрицательного результата по всем перечисленным условиям, то сделка записывается в массив неподходящих. Далее происходит переопределение значений ФОТ, если ни одно из условий не дало положительного результата.
Если по задаче у сотрудника нет доступа, то такая задача в списке будет отображаться со всеми полями ФОТ, но значение не будет указано.
.png)
В случае, если дату первого завершения задачи необходимо все же изменить, то редактируется запись в бд: меняется значение поля UF_CLOSEDATE_FIRST в записи в таблице b_uts_tasks_task. Поиск задачи осуществляется по VALUE_ID.
Если задача переводится в статус важной, об этом отправляется уведомление в чат задачи.
Завершение задачи невозможно, если у нее имеются незавершенные дочерние задачи.
Завершение задачи невозможно, если ее ответственный не относится к производственному сектору. В таком случае нужно либо изменить ответственного за задачу, либо в профиле ответственного изменить систему работы на «Производственный сектор».
Папка задачи удаляется при ее удалении и восстанавливается при восстановлении.
Если в комментариях к задаче оставить фразу «Списание» - создастся списание, если «Приход» - приход.
Задача «6423-2 Передача денежных средств из сейфа в сейф».
Существует бизнес-процесс, который считает сумму платежей по этой задаче и направляет сведения об этом в чат задачи: https://gkyw.ru/bizproc/processes/61/bp_edit/259/#A6026_91701_57622_78918
Выдается постановщиком в форме редактирования задачи (реализовано в init.php).
Существует бизнес-процесс, который считает сумму платежей (остаток) по каждому счёту, остаток по сейфу каждого сотрудника, задолженность по зп и кредиту и направляет сведения об этом в чат «финансовая информация»:
https://gkyw.ru/bizproc/processes/128/view/0/?list_section_id=
.png)
В процессе создания кода нужно было учесть и вывести два варианта: без учёта ИП Горлова и Юникс-ВЭСТ Власовы и с учётом ИП Горлова и Юникс-ВЭСТ Власовы.
Оба варианта выводятся в чат.
Топливные платежи загружаются скриптом /home/bitrix/www/marketplace/appFuel/reqStart.php в соответствующий список. Скрипт запускается каждую минуту.
Если в топливном платеже указан номер авто, скрипт проверяет наличие элемента Аренда ТС или МТР с указанным номером.
Если элемент найден, в топливный платёж записывается найденный элемент. Ответственный за этот элемент становится "держателем карты".
После добавления платежа запускается БП https://gkyw.ru/services/lists/42/bp_edit/338/ для РН карт (корп)
https://gkyw.ru/services/lists/139/bp_edit/442/ для РН карт (аренда)
https://gkyw.ru/services/lists/132/bp_edit/463/ для Я.Заправки (корп)
https://gkyw.ru/services/lists/113/bp_edit/462/ для Я.Заправки (аренда)
БП проверяет наличие путевого листа по полю Авто.
Если ПЛ найден, в топливном платеже заполняются поля сделка/задача/командировка, которые указаны в путевом листе и ID путевого листа. После этого топливный платёж считается разбитым.
Функционал приложения находится в /home/bitrix/www/marketplace/rwf_interface/index.php
При загрузке приложения осуществляется проверка пользователя на администратора и предоставляется доступ к данным. После происходит загрузка всех топливных платежей.
При нажатии на текстовое поле
.png)
появляется окно со списком всех сотрудников компании, в котором осуществляется поиск и выбор сотрудника, задачи которого необходимо просмотреть. После выбора сотрудника его ФИО отобразится в этом поле.
Список сотрудников загружается при первом открытии списка, а при последующих открытиях загружается из сформированного массива.
Таблица с задачами отображает список всех задач сотрудника
.png)
Для обнуления ФОТа задачи необходимо отметить её в столбце выбора (при этом вся строка выделится цветом), а после нажать кнопку «Обнулить выбранные ФОТ». После задача будет обновлена, а таблица перезагрузится с новыми данными.
Для удаления задачи необходимо отметить её в столбце выбора (при этом вся строка выделится цветом), а после нажать кнопку «Удалить выбранные задачи». После задача будет удалена, а таблица перезагрузится с новыми данными.
Кнопка «Обновить таблицу» заново загружает таблицу задач выбранного ранее сотрудника.
Почтовый модуль скопирован в /local/modules/mail/
В файл /local/modules/mail/lib/imap.php добавлен метод approveAction(), который запрещает удалять, перемещать, отмечать как прочитанное письма из почтовых ящиков "наших" компаний, если пользователь не состоит в 33 группе (Действия с электронной почтой).
Метод вызывается из moveMails(), seen(), delete()
Плюсовые платежи могут быть разбиты автоматически, при условии, что есть разбитый минусовой платёж с таким же номером платёжного поручения, сумой и «нашей компанией»
Скрипт разбиения находится в БП «Списание расходных платежей» https://gkyw.ru/bizproc/processes/61/bp_edit/157/
Раз в сутки запускается бизнес-процесс, который дублирует реквизиты в компании: https://gkyw.ru/bizproc/processes/147/bp_edit/478/
Скрипт предназначен для автоматической синхронизации данных компаний в CRM-системе Битрикс24. Он ищет компании, отмеченные флагом IS_MY_COMPANY = 'Y', и создает для них дубликаты (если их еще нет), а также синхронизирует реквизиты, контакты и дополнительные пользовательские поля (мультиполе). В случае наличия дубликатов, он обновляет синхронизирует данные в привязанный оригинал.
CompanySyncService
run()IS_MY_COMPANY = 'Y'.UF_BASE_ID.syncToOriginal() для обновления оригинала.createDuplicate() для его создания.createDuplicate($original)! .UF_BASE_ID равным ID оригинала.IS_MY_COMPANY = 'N'.syncRequisitesFromOriginal() — копирует реквизиты из оригинала.copyContacts() — копирует контакты.copyMultiFields() — копирует дополнительные поля.syncToOriginal($originalId, $duplicateId)copyCompanyFields().syncRequisitesFromDuplicate()).copyContacts()).copyMultiFields()).copyCompanyFields($fromId, $toId)$fromId.! из названия.$toId новыми данными.syncRequisitesFromOriginal(), syncRequisitesFromDuplicate(), createRequisite(), updateRequisite())UF_PARENT_ID) — обновляют его данными дубля.syncBankDetailsFromOriginal() и syncBankDetailsFromDuplicate()).syncBankDetailsFromOriginal(), syncBankDetailsFromDuplicate(), syncBankDetailsGeneric())UF_PARENT_ID).updateBankRequisiteUF()).updateRequisiteUF(), updateBankRequisiteUF())b_uts_uf_requisite создают или проверяют наличие связи между сущностями (реквизитами, банковскими реквизитами).copyContacts())Bitrix\Crm\Binding\ContactCompanyTable::upsert().copyMultiFields())IS_MY_COMPANY = 'Y'.На обновлении компании запускается бизнес-процесс https://gkyw.ru/crm/configs/bp/CRM_COMPANY/edit/485/ , который синхронизирует изменения в «зеркальной» карточке с оригиналом.
В дубликаты компаний добавляется символ «!» в начало названия.
Талица b_crm_dynamic_items_1066, пользовательские поля CRM_28.
Претензии связаны со сделками. Название претензии формируется при создании через БП из порядкового номера претензии и названия сделки.
Претензия может быть оплачена заказчиком (пользовательское поле UF_PAY_CLIENT).
Закрывать претензию могут только участники группы «Закрытие претензий» (35). Проверку на группу осуществляют роботы на стадии успех и провал. Если сотрудник не относится к этой группе, стадия откатывается через обновление в БД.
Для реализации этого ограничения разработан специальный модуль, который находится в /local/modules/deletefilelimit.
Настройки модуля находятся здесь: https://gkyw.ru/bitrix/admin/settings.php?lang=ru&mid=deletefilelimit&mid_menu=1
Этот функционал представляет собой защиту от случайного удаления важных папок в системе Bitrix. Он работает так:
Это защитный механизм, который предотвращает случайное удаление папок, которые используются в активных задачах, и помогает избежать потери важных данных и нарушения рабочих процессов.
Этот фрагмент кода расположен в файле init.php в директории .../bitrix/php_interface/981948711/ - стандартном месте для пользовательских обработчиков событий в Bitrix. Технически это:
onAfterMarkDeletedObject модуля disk, который вызывается после того, как объект был помечен на удаление.instanceof (только папки и ссылки на папки)tasks через CModule::IncludeModule('tasks')b_uts_tasks_task для проверки связи папки с задачами через поле UF_FOLDER_ID$deletedBy):
$deletedBy != 1): восстановление папки через метод restore() и создание уведомления через CIMNotify::Add()AddEventHandler()Данный скрипт расположен в файле home/bitrix/www/bitrix/php_interface/init.php
Скрипт предназначен для оповещения участников события о смене дат проведения события.
Скрипт автоматизирует управление чатами, связанными с событиями календаря в системе Bitrix24. После редактирования календарного выполняется:
AddEventHandler("calendar", "OnAfterCalendarEventEdit", "EventTimeUpdate");
EventTimeUpdate(&$arFields)$arFields — массив с данными события, включающий:
ID — ID событияNAME — название событияDATE_FROM — дата и время началаDATE_TO — дата и время окончанияATTENDEES_CODES — массив кодов участников (например, U123)Из массива ATTENDEES_CODES извлекаются ID пользователей:
$userIds = [];
if (!empty($arFields['ATTENDEES_CODES']) && is_array($arFields['ATTENDEES_CODES'])) {
foreach ($arFields['ATTENDEES_CODES'] as $code) {
if (preg_match('/^U(\d+)$/', $code, $matches)) {
$userIds[] = intval($matches[1]);
}
}
}
Выполняется SQL-запрос к таблице b_im_chat для поиска чата по ENTITY_TYPE='CALENDAR' и ENTITY_ID=$eventId.
$db = Bitrix\Main\Application::getConnection();
$sql = $db->query("SELECT ID FROM b_im_chat WHERE ENTITY_TYPE = 'CALENDAR' AND ENTITY_ID = " . $eventId);
$dbRes = $sql->fetch();
$dbRes не пуст), извлекается его ID.$prevMessageRes = \Bitrix\Im\Model\MessageTable::getList([
'order' => ['ID' => 'DESC'],
'limit' => 10,
'filter' => [
'=CHAT_ID' => $chatId,
'=AUTHOR_ID' => 0,
],
]);
Начало: и Окончание:).В данной части происходит поиск сообщения с четкой структурой, из которой извлекаются "Начало" и "Окончание", и, сравнение с соответствующими актуальными полями элемента после его изменения:
while ($msg = $prevMessageRes->fetch()) {
if (strpos($msg['MESSAGE'], 'Начало:') !== false && strpos($msg['MESSAGE'], 'Окончание:') !== false) {
preg_match('/Начало:\s*(.+)\nОкончание:\s*(.+)/', $msg['MESSAGE'], $matches);
if (count($matches) === 3) {
$prevFrom = trim($matches[1]);
$prevTo = trim($matches[2]);
// Если даты совпадают с текущими, сообщение не отправлять
if ($prevFrom === $arFields['DATE_FROM'] && $prevTo === $arFields['DATE_TO']) {
$sendMessage = false;
}
}
break;
}
}
Этот блок гарантирует, что повторное сообщение о времени события не отправляется, если даты остались без изменений.
Если чат не найден — создается новый, заполняя его название, тип, участников и связывая с событием:
$chat = new \CIMChat();
$chatId = $chat->Add([
'TITLE' => $arFields['NAME'],
'TYPE' => IM_MESSAGE_CHAT,
'ENTITY_TYPE' => 'CALENDAR',
'ENTITY_ID' => $eventId,
'AUTHOR_ID' => 0,
'USERS' => $userIds,
]);
Если список участников непустой, они добавляются в чат:
if (!empty($chatId) && !empty($userIds)) {
$chat = new \CIMChat(0);
foreach ($userIds as $userId) {
$chat->AddUser($chatId, $userId);
}
}
Если $sendMessage равно true, формируется сообщение с актуальными датами и отправляется:
if ($sendMessage) {
$message .= "Начало: " . $arFields['DATE_FROM'] . "[BR]" .
"Окончание: " . $arFields['DATE_TO'];
\CIMChat::AddMessage([
"TO_CHAT_ID" => $chatId,
"MESSAGE" => $message,
"SYSTEM" => "Y"
]);
}
Раз в сутки запускается скрипт для автоматического создания отзывов на сделки. Скрипт автоматически создает отзывы для крупных сделок. Он находит все активные сделки из воронки "Объект" с суммой от 500 000, у которых еще нет привязанного отзыва, и создает новый отзыв. Каждый созданный отзыв привязывается к своей сделке и назначается тому же ответственному сотруднику, что и сделка.
Закрытие сделки, в которой имеются незавершенные отзывы, невозможно!
Скрипт использует Bitrix API для работы с CRM-сущностями. Он получает фабрики для работы со сделками (тип 2) и отзывами (тип 1080). Фильтрует сделки по категории (только с CATEGORY_ID=0), сумме (от 500 000) и стадии (исключая закрытые). Для каждой найденной сделки скрипт проверяет наличие связанных отзывов по полю PARENT_ID_2. Если отзыв не найден, создается новый элемент с заголовком, содержащим название сделки, и тем же ответственным. Создание происходит через операции фабрики с использованием методов createItem, getAddOperation и launch для выполнения операции.
Ограничения на закрытие сделки по незавершенным отзывам действуют в боте (бизнес-процесс по списку "Бот").
При перемещении отзыва в эту стадию запускается робот CRM. Скрипт добавляет комментарий к созданному отзыву с инструкцией для ответственного сотрудника. Комментарий описывает условия получения отзыва от заказчика. Успешным завершением считается получение официального отзыва на фирменном бланке с исходящим номером от заказчика. Сотруднику предоставляется ссылка на шаблоны отзывов. Если отношения с заказчиком стали нерабочими или натянутыми, допускается завершение элемента с отрицательным результатом.
Скрипт использует Bitrix API для создания комментария в таймлайне CRM-элемента. Сначала подключается модуль CRM, затем определяется тип сущности (1080) и ID конкретного элемента через плейсхолдер. Ответственный за элемент определяется из плейсхолдера, его ID извлекается из строки разделенной подчеркиванием. Создается форматированный текст комментария с HTML-разметкой, описывающий задачу и условия успеха/неудачи. Комментарий прикрепляется к сущности через метод CommentEntry::create с указанием текста, автора и привязки, устанавливая флаг закрепления IS_FIXED в значение 'Y'.
При перемещении отзыва в эту стадию запускается робот CRM. Скрипт проверяет права пользователя при закрытии отзыва. Если пользователь, передвигающий отзыв, не входит в группу "Действия с отзывами от заказчика", система автоматически возвращает отзыв в стадию "В работе" и отправляет уведомление о недостаточных правах. Если же пользователь имеет необходимые права, отзыв успешно закрывается с соответствующим уведомлением.
Скрипт использует Bitrix API для работы с модулем мгновенных сообщений (im) и пользователями. Сначала подключается модуль im, затем получает ID пользователя из плейсхолдера "Кем передвинут", разбивая строку по символу подчеркивания. Проверяет принадлежность пользователя к группе №36 ("Действия с отзывами от заказчика") с помощью метода CUser::GetUserGroup. В зависимости от результата проверки, устанавливает переменную бизнес-процесса "permission" в 0 или 1 и формирует соответствующее сообщение. Наконец, создает и отправляет уведомление пользователю с помощью метода CIMNotify::Add, используя модуль bizproc.
Проверка на права доступа к полям скрытых элементов была отключена на создание счёта на оплату и командировки в файлах 128_tasks.php и 133_mtr.php, так как метод processFieldsWithPermissions из /home/bitrix/www/bitrix/modules/crm/lib/Service/Operation.php возвращает ошибку типа "[Сделка #№] У Вас нет прав на просмотр этого элемента". Проверка отключается через метод disableCheckAccess(), а в случаях, когда элемент не был создан, то есть пришедший ID = 0, ведётся логирование полей и ответа от метода launch().
Для доступа к изменению счетов на оплату добавлен код проверки текущего пользователя на создателя или ответственного за счёт на оплату в файле crm_dynamic.php, который отключает проверку доступа к полям скрытых элементов:
try
{
global $USER;
$uid = (int)$USER->getId();
$created = (int)$item->getCreatedBy();
$assigned = (int)$item->getAssignedById();
if ($uid === $created || $uid === $assigned)
{
$operation->disableCheckAccess();
}
}
catch (Throwable $t)
{}
Скрипт предназначен для динамического скрытия элементов меню в зависимости от URL-параметра.
Данный скрипт расположен в файле home/bitrix/www/bitrix/php_interface/init.php.
Скрипт добавляется строкой на страницу через метод addString.
%20(1).png)
По умолчанию - пункты под "еще" у меню скрываются.
Чтобы показать скрытые элементы и кнопку, нужно установить GET параметр showmorebtnmenu=1.
Данная разработка реализована в виде дополнения к бизнес-процессу https://gkyw.ru/bizproc/processes/34/bp_edit/48/ ленты новостей "Добавление задачи", который срабатывает при Добавлении новой задачи.

В рамках работы данного PHP кода объявляется класс AutoFot, который исполняется в случае создании задачи с названием "ФОТ ОИТ" и ответственным задачи == начальник подразделения ОИТ (department = 19)
Обновляет название задачи текущим месяцем и годом.
Создает подзадачи для сотрудников отдела, исключая руководителя.
Отправляет сообщения в чат задачи с информацией о созданных подзадачах и статистикой выполненных задач и обращений за месяц.
Обновляет родительскую задачу.
Собирает статистику по завершенным задачам и обращениям за текущий месяц.
| Свойство | Описание | |
|---|---|---|
| $task | Объект для работы с задачами CTasks | new CTasks() |
| $currentMonthName | Название текущего месяца | null |
| $currentYear | Текущий год | null |
| $botId | ID бота для отправки сообщений | 487 |
| $departmentId | ID отдела, для получения сотрудников | 19 |
| $newParentTaskId | ID новой родительской задачи | 290968 |
| $oldTypeId | ID типа обращения | 190 |
| $newTypeId | ID типа обращения (новые) | 1096 |
__construct()
Инициализация объекта, установка текущего месяца и года.
setCurrentMonthAndYear()
Определяет название текущего месяца на русском языке и текущий год.
processTask($taskId)
Основной метод обработки задачи.
Проверяет, содержит ли заголовок задачи фразу "ФОТ ОИТ".
Обновляет название задачи.
Создает подзадачи для сотрудников отдела.\
updateTaskTitle($taskId, $taskData)
Обновляет название задачи, добавляя название месяца и года.
createSubtasksForUsers($taskData)
Создает подзадачи для каждого сотрудника отдела, исключая руководителя.
Получает список пользователей отдела.
Для каждого пользователя создает подзадачу с названием, содержащим его фамилию, инициалы и текущий месяц.\
getGroupUsers()
Возвращает список ID сотрудников отдела, исключая руководителя.
Получает ID менеджера отдела.
Получает список подчиненных пользователей.\
createSubtask($userId, $parentTaskId, $subtaskTitle)
Создает подзадачу для указанного пользователя, привязанную к родительской задаче.
Передает параметры в API задач, создает подзадачу, отправляет сообщение и собирает статистику.\
sendMessageToTaskChat($taskId, $message)
Отправляет сообщение в чат задачи.
Создает чат, если не существует, и отправляет сообщение с помощью API CIMChat.\
sendCompletedTasksAndRequests($userId, $taskId)
Собирает и отправляет статистику по завершенным задачам и обращениям за текущий месяц.
getCompletedTasks($userId)
Возвращает список завершенных задач пользователя за текущий месяц.
getCompletedRequests($userId)
Возвращает список завершенных обращений (CRM-запросов) за текущий месяц, объединяя старый и новый типы.
getCompletedStatuses($typeId)
Получает список ID статусов, соответствующих завершенным этапам, для указанного типа обращения.
checkAndProcessTask($taskId)
Проверяет задачу по ID, при необходимости запускает обработку и обновляет родительскую задачу.
Данный код реализует расширенную автоматизацию для Смарт-процесса. Он автоматически меняет стадии элемента, при в случае изменения поля "дата завершения печати", и, наоборот, устанавливает дату завершения печати в случае смены стадии, и отправляет в чат элемента уведомления.
Функционал реализован в
crm_dynamic.php
crm.Service\Container, внутри которого переопределяется метод getFactory().getFactory(int $entityTypeId)entityTypeId == 1096, что соответствует смарт-процессу Обращения.entityTypeId == 1096При идентификации типа сущности создается анонимный класс, расширяющий Service\Factory\Dynamic, который переопределяет метод getUpdateOperation().
getUpdateOperation()Item).Operation::ACTION_AFTER_SAVE, которое выполняется после сохранения элемента.ACTION_AFTER_SAVEОбъект действия реализует метод process(Item $item), который содержит основную логику:
process()process()b_option (year_holidays).$stagesTable — соответствует стадиям процесса.$messagesTable — содержит текстовые сообщения для уведомлений.UF_CRM_41_CLOSEDATE, вычисляется разница рабочих дней.sendChatMessage() ищет чат, связанный с элементом.include_once($_SERVER["DOCUMENT_ROOT"]."/local/classes/WorkdayHelper.php");
— данный класс выполняет функционал расчета разницы дней между текущим днем и датой окончания. Способен работать в обе стороны (изменилась дата - необходимо соответствие стадии; изменилась стадия - необходимо соответствие новой дате).
sendChatMessage($entityTypeID, $itemID, $msg) — отправляет сообщение в чат по идентификатору элемента.