Jump to content
SpravkaCRM.ru - Ваш справочник по CRM

SpravkaCRM.ru

Administrators
  • Content count

    297
  • Joined

  • Last visited

  • Days Won

    7

SpravkaCRM.ru last won the day on February 21

SpravkaCRM.ru had the most liked content!

Community Reputation

16 Good

About SpravkaCRM.ru

  • Rank
    Advanced Member

Recent Profile Visitors

4449 profile views
  1. Всем привет! Столкнулся с небольшой проблемой: SuiteCRM автоматически при отображении поля типа Text преобразует все URL в ссылки. То есть берет URL и "пихает" его в тег <A>. Классная штука на самом деле, удобно. Но мне надо было отключить её, так как я создал поле "source" => "non-db", в котором хочу сам формировать список ссылок, чтобы в карточке записи был набор ссылок типа такого: Ссылка 1 Ссылка 2 Ссылка 3 Именно так, нормальное название. А не: http://site.ru/page1.html http://site.ru/page2.html http://site.ru/page3.html Ведь удобнее видеть нормальное человеческое описание, кликнуть на него и попасть на желаемую страницу. По реализации: Добавил новое поле в модуль, в котором будет находится текст с списком ссылок: 'different_links' => array ( 'required' => false, 'name' => 'different_links', 'vname' => 'LBL_DIFFERENT_LINKS', 'type' => 'text', 'massupdate' => 0, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => '0', 'audited' => true, 'reportable' => true, 'unified_search' => false, 'merge_filter' => 'disabled', 'source' => 'non-db', ), Добавил хук after_retrieve в custom/Extension/modules/lm_CRMSystems/Ext/LogicHooks/calculateFields.php, чтобы можно было наполнять поле текстом: if (!isset($hook_array) || !is_array($hook_array)) { $hook_array = array(); } if (!isset($hook_array['after_retrieve']) || !is_array($hook_array['after_retrieve'])) { $hook_array['after_retrieve'] = array(); } $hook_array['after_retrieve'][] = Array(10, 'Ссылка на карточку на сервере', 'custom/modules/lm_CRMSystems/hooks.php', 'lm_CRMSystemsHooks', 'calculateFields'); Добавляем функцию для хука в файле custom/modules/lm_CRMSystems/hooks.php: /** * Получение ссылки на карточку CRM-системы на ее Сервере * @param $bean * @param $event * @param $arguments */ public function calculateFields($bean, $event, $arguments) { global $db; global $sugar_config; // Ссылки $bean->different_links = ""; // Ссылка на карточку на другом сервере switch ($sugar_config['CRMSystems']['systemType']) { case 'base': // Мы находимся на Базовом сервере // Пытаемся сформировать ссылка на карточку на сервере с проектами // Получаем URL сервера if(!empty($bean->lm_crmservers_lm_crmsystemslm_crmservers_ida)) { $sql = "SELECT `url` FROM `lm_crmservers` WHERE `deleted` = 0 AND `id` = '{$bean->lm_crmservers_lm_crmsystemslm_crmservers_ida}'"; $url = $db->getOne($sql, true); $bean->different_links .= '<li><A href="'.$url . '/index.php?module=lm_CRMSystems&action=DetailView&record=' . $bean->id.'" target="_blank">Карта на сервере с проектом</A></li>'; } break; case 'projects': // Мы находимся на Сервере с проектами // Добавляем ссылку на карточку на Базовом сервере // Ищем базовый сервер $sql = "SELECT `url` FROM `lm_crmservers` WHERE `deleted` = 0 AND `type` = 'base'"; $url = $db->getOne($sql, true); $bean->different_links .= '<li><A href="'.$url . '/index.php?module=lm_CRMSystems&action=DetailView&record=' . $bean->id.'" target="_blank">Карта на базовом сервере</A></li>'; break; } if($bean->different_links != '') { $bean->different_links = '<ul>'.$bean->different_links.'</ul>'; } } И вот что у меня получилось: Получается, что я сформировал корректную HTML-ссылку, а SuiteCRM внутри нее нашла URL, и обрамила ее своей ссылкой. Вышло не очень. Полез в функцию-обработчик полей типа Text include/SugarFields/Fields/Text/SugarFieldText.php, и видим там следующее: class SugarFieldText extends SugarFieldBase { function getDetailViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) { if(!isset($displayParams['nl2br'])){ $displayParams['nl2br'] = true; } if(!isset($displayParams['htmlescape']) && $vardef['editor'] != "html") { $displayParams['htmlescape'] = true; } if(!isset($displayParams['url2html'])) { $displayParams['url2html'] = true; } return parent::getDetailViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex); } Тут особо интересный блок: if(!isset($displayParams['url2html'])) { $displayParams['url2html'] = true; } То есть если при отображении поля использовать 'url2html' => false, то в теории оно не должно преобразовывать ссылки. Пробуем: в файле custom/modules/lm_CRMSystems/metadata/detailviewdefs.php описываем поле different_links: 11 => array ( 0 => 'lm_crmservers_lm_crmsystems_name', 1 => array( 'name' => 'different_links', 'label' => 'LBL_DIFFERENT_LINKS', 'displayParams' => array( 'url2html' => false, ), ), ), И вот что получилось после быстрого восстановления: То, что нужно!
  2. Добрый день! при помощи этой настройки можно регулировать нагрузку как на собственный сервер, так и на почтовый сервер. Большое количество писем, если сервер не очень мощный, может привести к нехватке памяти и все встанет. Так же некоторые почтовые сервера имеют ограничения на кол-во отправляемых через них писем в течении какого то кол-ва времени (в рамках борьбы со спамом или предлагая бизнес-тарифы). Для регулирования подобных вещей и применяется этот параметр
  3. Всем привет! Хочу показать мой вариант решения следующей проблемы: Есть бизнес-процесс, который настроен на модуль "Контрагенты". В результате срабатывания бизнес-процесса должны создаться две записи: Запись в модуле "Обращения" Запись в модуле "Документы" Но вся сложность заключается в том, что и Обращение и Документ должны не просто добавиться в Контрагент, но и между собой сформировать связь. То есть зайдя потом в карточку созданного Обращения мы должны увидеть в сабпанели созданный Документ! Если очень упрощенно, то мой бизнес-процесс выглядит так: Как вы видите, у меня в действиях отмечен чекбокс "Связать с записью в контролируемом модуле". Этот чекбокс позволяет созданным записям находится в соответствующих сабпанелях Контрагента. Но вот Обращение с Документом между собой никак не хотели связываться! Как я не тестировал, что не пробовал, но без доработки CRM-системы чисто имеющимися средствами эту задачу решить не получилось. Я пожалуй не буду утомлять рассуждениями на тему "что же тут делать и как я пришел к конечному результату", а просто опишу то, что в итоге было сделано в CRM-системе, что позволило решить эту задачу: 1. Первое: Добавляем в модуль Контрагенты два новых поля: custom/Extension/modules/Accounts/Ext/Vardefs/custom_fields.tmp.php: <?php $dictionary['Account']['fields']['tmp_document_id'] = array ( 'required' => false, 'name' => 'tmp_document_id', 'vname' => 'LBL_TMP_DOCUMENT_ID', 'type' => 'id', 'massupdate' => 0, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => 0, 'audited' => false, 'inline_edit' => true, 'reportable' => false, 'unified_search' => false, 'merge_filter' => 'disabled', 'len' => 36, 'size' => '20', 'source' => 'non-db', ); $dictionary['Account']['fields']['tmp_document'] = array ( 'required' => false, 'source' => 'non-db', 'name' => 'tmp_document', 'vname' => 'LBL_TMP_DOCUMENT', 'type' => 'relate', 'massupdate' => 1, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => '0', 'audited' => false, 'inline_edit' => true, 'reportable' => true, 'unified_search' => false, 'merge_filter' => 'disabled', 'len' => '255', 'size' => '20', 'id_name' => 'tmp_document_id', 'ext2' => 'Documents', 'module' => 'Documents', 'rname' => 'name', 'quicksearch' => 'enabled', 'studio' => 'visible', ); $dictionary['Account']['fields']['tmp_case_id'] = array ( 'required' => false, 'name' => 'tmp_case_id', 'vname' => 'LBL_TMP_CASE_ID', 'type' => 'id', 'massupdate' => 0, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => 0, 'audited' => false, 'inline_edit' => true, 'reportable' => false, 'unified_search' => false, 'merge_filter' => 'disabled', 'len' => 36, 'size' => '20', 'source' => 'non-db', ); $dictionary['Account']['fields']['tmp_case'] = array ( 'required' => false, 'source' => 'non-db', 'name' => 'tmp_case', 'vname' => 'LBL_TMP_CASE', 'type' => 'relate', 'massupdate' => 1, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => '0', 'audited' => false, 'inline_edit' => true, 'reportable' => true, 'unified_search' => false, 'merge_filter' => 'disabled', 'len' => '255', 'size' => '20', 'id_name' => 'tmp_case_id', 'ext2' => 'Cases', 'module' => 'Cases', 'rname' => 'name', 'quicksearch' => 'enabled', 'studio' => 'visible', ); custom/Extension/modules/Accounts/Ext/Language/ru_RU.TMP.php: <?php $mod_strings['LBL_TMP_DOCUMENT'] = 'TMP.DOCUMENT'; $mod_strings['LBL_TMP_DOCUMENT_ID'] = 'TMP.DOCUMENT_ID'; $mod_strings['LBL_TMP_CASE'] = 'TMP.CASE'; $mod_strings['LBL_TMP_CASE_ID'] = 'TMP.CASE_ID'; Обращаю ваше внимание на то, что данные поля имеют параметр 'source' => 'non-db', что говорит о том, что эти поля исключительно расчетные, и не хранят значения в базе данных. 2. Второе. Добавляю Hook на добавление связи Контрагента с чем-либо: custom/Extension/modules/Accounts/Ext/LogicHooks/tmp.hooks.php: <?php $hook_array['after_relationship_add'][] = Array( 10, 'TMP Fields', 'custom/modules/Accounts/TMPLogicHooks.php', 'TMPLogicHooks', 'setTMPFields' ); custom/modules/Accounts/TMPLogicHooks.php: <?php /** * Created by PhpStorm. * User: crmhosting * Date: 01.06.2018 * Time: 15:52 */ class TMPLogicHooks { /** * Заполняем временные поля значениями * @param $bean * @param $event * @param $arguments */ function setTMPFields($bean, $event, $arguments) { if($arguments['module'] == 'Accounts' AND $arguments['related_module'] == 'Cases') { // Если сейчас связь Контрагента и Обращения $bean->tmp_case_id = $arguments['related_bean']->id; } elseif ($arguments['module'] == 'Accounts' AND $arguments['related_module'] == 'Documents') { // Если сейчас связь Контрагента и Документа $bean->tmp_document_id = $arguments['related_bean']->id; } } } Таким образом мы во время связи Контрагента с Обращением или Документом заполняем наши вспомогательные поля. 3. Третье. Делаем быстрое восстановление. Чтобы в системе применились все добавленные поля и хуки. 4. Четвертое. В Бизнес-процессе в действии добавления Документа указываем связь с Обращением через нашу переменную tmp_case_id: Вот как теперь будет выглядеть бизнес-процесс: После срабатывания такого бизнес-процесса у создаваемого обращения появляется прямая связь с создаваемым документом. Что нам и было нужно. Давайте теперь немного объясню что же у нас получилось: Мы в Контрагенте создали пару полей. Но не простых, а типа relate - это когда в текущем модуле есть связь с записью в другом модул Мы в Контрагенты добавили хук after_relationship_add, который будет срабатывать каждый раз, когда к Контрагенту будет добавляться связь с записью другого модуля В момент, когда срабатывает бизнес-процесс, в первую очередь создается Обращение, а затем добавляется связь этого обращения с Контрагентом, что приводит к срабатыванию нашего хука Внутри хука мы видим, что добавляется связь Контрагента и Обращения. Мы добавляем в поле Контрагента tmp_case_id айди созданного и добавляемого Обращения Все, Обращение создано и привязано к Контрагенту Далее по бизнес-процессу создается Документ Документ мало того, что привязывается к Контрагенту, так мы в бизнес-процессе еще прописали ему некую связь с Обращениями, и указали, что связать он должен по полю TMP.CASE (а это как раз наше поле tmp_case_id, которое мы заполнили в прошлый раз, когда добавляли связь с Обращением) Таким образом создаваемый документ связывается с ранее созданным Обращением. Ну и связь двухсторонняя: если привязали Документ к Обращению, значит и Обращение привязано к Документу. Profit! Если что не понятно, или есть предложения по реализации данной задачи другими способами, то буду рад пообщаться в комментариях.
  4. Всем привет! Хочу поделиться одной доработкой, которая, на мой взгляд, немного полнее позволит понять роль модуля "Процессы" в работе с CRM-системой, и что не обязательно все на свете дописывать: можно еще и активно пользоваться встроенными средствами. Итак! Задача: в Обращениях выводить время последнего сообщения от Клиента. При этом выводить не только в карточке, но и в списках, отчетах и вообще везде, где заблагорассудится. Вот если задача была вывести только в карточке обращения, я наверное бы особо не заморачивался, и добавил расчётное поле source="non-db", в котором "на лету" определял последнее сообщение и подставлял его дату. Но тут задача получить универсальное поле. По этому решено было добавить полноценное поле в модуль "Обращения" (с хранением значения в базе данных) и заполнять его соответствующим значением. Добавляем поле (создаем файл custom/Extension/modules/Cases/Ext/Vardefs/last_reply_date.php): <?php $dictionary['Case']['fields']['last_reply_date'] = array ( 'name' => 'last_reply_date', 'vname' => 'LBL_LAST_REPLY_DATE', 'type' => 'datetimecombo', 'massupdate' => 0, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => '0', 'audited' => false, 'inline_edit' => true, 'reportable' => true, 'unified_search' => false, 'merge_filter' => 'disabled', 'size' => '20', 'enable_range_search' => false, 'dbType' => 'datetime', ); Добавляем локализацию для поля (custom/Extension/modules/Cases/Ext/Language/ru_RU.last_reply_date.php): <?php $mod_strings['LBL_LAST_REPLY_DATE'] = 'Последний ответ'; После выполнения быстрого восстановления в админке это поле появляется в списке полей модуля Обращения, и вы можете его использовать при формировании макетов. Далее наша задача это поле корректно заполнить. По задаче нам надо туда добавлять дату последного ответа клиента. Модуль с перепиской по Обращениям называется AOP_Case_Updates и в моей локализации по русски он звучит как "Обновления обращения". Чтобы выполнить нашу задачу нам надо при создании новой записи в этом модуле обновлять поле last_reply_date в записи родительского Обращения. Но так как в модуль "Обновления обращения" добавляются ответы как Клиента, так и сотрудника, ведущего переписку по Обращению, то нам надо определять дату только тогда, когда ответил клиент. Лично я определяю записи от клиентов отсутствием значения в поле `assigned_user_id` (если вы определяете это как то по другому, то пишите в комментариях, интересно будет узнать). Таким образом нам достаточно создать Бизнес-процесс, который будет привязан к модулю "Обновления обращения". В момент, когда будет создаваться новая запись, и в ней будет пусто поле `assigned_user_id` - это будет как раз наш случай, и мы должны будем обновить поле в родительском Обращении. Вот скрин этого Бизнес-процесса: Испытания показали, что данный механизм успешно работает. И небольшой бонус: То, что мы выше создали, будет исправно фиксировать дату последнего ответа для всех обращений, по которым клиенты только ответят с момента привнесения этого функционала. Далее я приведу листинг скрипта, который можно единоразово запустить в CRM-системе, и он найдет все Обращения, найдет все последние ответы клиентов по ним, и запишет дату: <?php if(!defined('sugarEntry'))define('sugarEntry', true); /** * Created by PhpStorm. * User: crmhosting * Date: 25.04.2018 * Time: 9:32 */ require_once('include/entryPoint.php'); global $db; // Получаем список Обращений $sql = " SELECT `cases`.`id` FROM `cases` WHERE `cases`.`deleted` = 0 "; $result = $db->query($sql, true); $counter = 0; while ($row = $db->fetchByAssoc($result)) { $counter++; // Получаем последнее сообщение, полученное от клиента $sql = " SELECT `date_entered` FROM `aop_case_updates` WHERE `deleted` = 0 AND `case_id` = '".$row['id']."' AND (`assigned_user_id` IS NULL OR `assigned_user_id` = '') ORDER BY `date_entered` DESC LIMIT 1 "; $date = $db->getOne($sql, true); if(!empty($date)) { // Если есть дата $sql = "UPDATE `cases` SET `last_reply_date` = '".$date."' WHERE `id` = '".$row['id']."'"; $db->query($sql, true); } } print_array("Всего записей звонков: " . $counter);
  5. Всем привет! В одном из проектов потребовалось формировать отчеты из данных, которые находятся в аудите. Напомню, что аудит - это табличка с информацией кто что поменял в карточке, вызываемая нажатием кнопки "Просмотр журнала изменений": Классная штука, конечно, этот аудит! Знай не забывай новые поля в него добавлять в студии... Но вот беда: работать с ним из модуля Отчеты нет возможности. Совсем. Если в кратце про аудит, то: Должен ли быть в модуле аудит полей или нет определяется в vardefs.php в параметре 'audited' для всего модуля: $dictionary['Account'] = array( 'table' => 'accounts', 'audited' => true, 'unified_search' => true, 'full_text_search' => true, 'unified_search_default_enabled' => true, 'duplicate_merge' => true, 'comment' => 'Accounts are organizations or entities that are the target of selling, support, and marketing activities, or have already purchased products or services', 'fields' => array( ................ Еще раз повторюсь, что это настройка, говорящая о принципиальной возможности работы с аудитом в текущем модуле. Вести аудит того или иного поля в модуле определяется также параметром 'audited' => true, в настройках того или иного поля: 'parent_id' => array( 'name' => 'parent_id', 'vname' => 'LBL_PARENT_ACCOUNT_ID', 'type' => 'id', 'required' => false, 'reportable' => false, 'audited' => true, 'comment' => 'Account ID of the parent of this account', ), Для хранения данных в базе данных используются таблицы с названием `модуль_audit` везде одинаковой структуры: Структура от модуля к модулю неизменна, потому что названия аудируемых полей хранятся в поле `field_name`, а значения поля в `before_value_string` и `after_value_string`. Нажимая "Быстрое восстановление" в админке мы восстанавливаем таблицы аудита в том числе там, где это необходимо (например, если добавили в модуль возможность аудировать записи). Так вот данные таблицы и все эти данные не являются объектами в понимании SuiteCRM, и к ним нет доступа из модуля AOR_Reports. По этому смотреть таблички - можем, строить аналитику по ним - нет. Решение задачи анализа изменения тех или иных полей в модуле на самом деле можно решить разными способами: Сделать аудит модулем (наш способ); Добавить в модуль для каждого поля, которое мы хотим наблюдать, еще одно поле-дублер, которое будет содержать предыдущее значение анализируемого поля. Например, нам надо видеть как поменялось поле "Статус" в модуле. Для этого мы можем добавить поле `status_before`, и в него при помощи тех же Hooks при смене поля "Статус" указывать предыдущее значение. В этом случае мы будем иметь прямой удобный доступ к `status_before` из отчетов, в студии (карточка записи, поиск по полю и т.д.). Но есть в этом подходе существенный минус: мы в дополнительном поле храним лишь предыдущее значение, историю изменений не получится хранить + для каждого нового поля, которое мы хотим анализировать, придется создавать доп.поля и настраивать их запись, что несколько не удобно. Можно добавить еще один модуль, в который мы будем записывать изменения значений в записях основного модуля. Например, при срабатывании Hooks. Кстати таким образом разработчики сделали хранение смены значений в модуле Обращения: AOP_Case_Events. Если грамотно реализовать этот метод, то в целом такой подход тоже может быть не плох. Но, например в AOP_Case_Events, явно указано какие поля необходимо фиксировать при смене в модуле Обращений. Это не удобно. Нужно постоянно привлекать разработчика, если захотите добавить новое поле в аудит. Плюс по сути это дубляж уже имеющихся в аудите данных. В общем не плохо, но аудит всеже лучше ))) Итак, давайте вернемся от теории к практике. На входе у нас есть таблица аудита, и нам надо из нее сделать модуль, при этом сохранив и не изменяя весь функционал аудирования, который уже есть. Я покажу на примере создания модуля аудирования для модуля Контрагенты. Модуль назовем AccountsAudit и по русски это будет "Аудит Контрагентов". Почти все файлы модуля будут лежать в /modules/AccountsAudit/, где структура папок и файлов будет следующей: Далее я приведу листинг всех этих файлов. modules/AccountsAudit/Dashlets/AccountsAuditDashlet/AccountsAuditDashlet.meta.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ if (!defined('sugarEntry') || !sugarEntry) { die('Not A Valid Entry Point'); } global $app_strings; $dashletMeta['AccountsAuditDashlet'] = array( 'module' => 'AccountsAudit', 'title' => translate('LBL_HOMEPAGE_TITLE', 'AccountsAudit'), 'description' => 'A customizable view into AccountsAudit', 'category' => 'Module Views' ); modules/AccountsAudit/Dashlets/AccountsAuditDashlet/AccountsAuditDashlet.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ if (!defined('sugarEntry') || !sugarEntry) { die('Not A Valid Entry Point'); } require_once('include/Dashlets/DashletGeneric.php'); require_once('modules/AccountsAudit/AccountsAudit.php'); class AccountsAuditDashlet extends DashletGeneric { function __construct($id, $def = null) { global $current_user, $app_strings; require('modules/AccountsAudit/metadata/dashletviewdefs.php'); parent::__construct($id, $def); if (empty($def['title'])) { $this->title = translate('LBL_HOMEPAGE_TITLE', 'AccountsAudit'); } $this->searchFields = $dashletData['AccountsAuditDashlet']['searchFields']; $this->columns = $dashletData['AccountsAuditDashlet']['columns']; $this->seedBean = new AccountsAudit(); } } modules/AccountsAudit/language/en_us.lang.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ $mod_strings = array ( 'LBL_ASSIGNED_TO_ID' => 'Assigned User Id', 'LBL_ASSIGNED_TO_NAME' => 'Assigned to', 'LBL_SECURITYGROUPS' => 'Security Groups', 'LBL_SECURITYGROUPS_SUBPANEL_TITLE' => 'Security Groups', 'LBL_ID' => 'ID', 'LBL_DATE_ENTERED' => 'Date Created', 'LBL_DATE_MODIFIED' => 'Date Modified', 'LBL_MODIFIED' => 'Modified By', 'LBL_MODIFIED_ID' => 'Modified By Id', 'LBL_MODIFIED_NAME' => 'Modified By Name', 'LBL_CREATED' => 'Created By', 'LBL_CREATED_ID' => 'Created By Id', 'LBL_DESCRIPTION' => 'Description', 'LBL_DELETED' => 'Deleted', 'LBL_NAME' => 'Name', 'LBL_CREATED_USER' => 'Created by User', 'LBL_MODIFIED_USER' => 'Modified by User', 'LBL_LIST_NAME' => 'Name', 'LBL_EDIT_BUTTON' => 'Edit', 'LBL_REMOVE' => 'Remove', 'LBL_LIST_FORM_TITLE' => 'Аудит Контрагентов List', 'LBL_MODULE_NAME' => 'Аудит Контрагентов', 'LBL_MODULE_TITLE' => 'Аудит Контрагентов', 'LBL_HOMEPAGE_TITLE' => 'My Аудит Контрагентов', 'LNK_NEW_RECORD' => 'Create Аудит Контрагентов', 'LNK_LIST' => 'View Аудит Контрагентов', 'LNK_IMPORT_ACCOUNTSAUDIT' => 'Импорт Аудит Контрагентов', 'LBL_SEARCH_FORM_TITLE' => ' Аудит Контрагентов', 'LBL_HISTORY_SUBPANEL_TITLE' => 'View History', 'LBL_ACTIVITIES_SUBPANEL_TITLE' => 'Activities', 'LBL_ACCOUNTSAUDIT_SUBPANEL_TITLE' => 'Аудит Контрагентов', 'LBL_NEW_FORM_TITLE' => 'New Аудит Контрагентов', ); modules/AccountsAudit/language/ru_RU.lang.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ $mod_strings = array ( 'LBL_ASSIGNED_TO_ID' => 'Ответственный(ая)', 'LBL_ASSIGNED_TO_NAME' => 'Ответственный(ая)', 'LBL_SECURITYGROUPS' => 'Группы пользователей', 'LBL_SECURITYGROUPS_SUBPANEL_TITLE' => 'Группы пользователей', 'LBL_ID' => 'ID', 'LBL_DATE_ENTERED' => 'Дата создания', 'LBL_DATE_MODIFIED' => 'Дата изменения', 'LBL_MODIFIED' => 'Изменено', 'LBL_MODIFIED_ID' => 'Изменено(ID)', 'LBL_MODIFIED_NAME' => 'Изменено', 'LBL_CREATED' => 'Создано', 'LBL_CREATED_BY' => 'Создано(ID)', 'LBL_DESCRIPTION' => 'Описание', 'LBL_DELETED' => 'Удалено', 'LBL_NAME' => 'Название', 'LBL_CREATED_USER' => 'Создано', 'LBL_MODIFIED_USER' => 'Изменено', 'LBL_LIST_NAME' => 'Название', 'LBL_EDIT_BUTTON' => 'Править', 'LBL_REMOVE' => 'Удалить', 'LBL_PARENT' => 'Контрагент', 'LBL_PARENT_ID' => 'Контрагент (ID)', 'LBL_DATE_CREATED' => 'Дата создания', 'LBL_FIELD_NAME' => 'Поле', 'LBL_DATA_TYPE' => 'Тип поля', 'LBL_BEFORE_VALUE_STRING' => 'Значение ДО', 'LBL_AFTER_VALUE_STRING' => 'Значение ПОСЛЕ', 'LBL_BEFORE_VALUE_TEXT' => 'Значение ДО (TEXT)', 'LBL_AFTER_VALUE_TEXT' => 'Значение ПОСЛЕ (TEXT)', 'LBL_LIST_FORM_TITLE' => 'Список аудита', 'LBL_MODULE_NAME' => 'Аудит Контрагентов', 'LBL_MODULE_TITLE' => 'Аудит Контрагентов', 'LBL_HOMEPAGE_TITLE' => 'Мой Аудит Контрагентов', 'LNK_NEW_RECORD' => 'Добавить строку аудита', 'LNK_LIST' => 'Просмотр Аудит Контрагентов', 'LNK_IMPORT_ACCOUNTSAUDIT' => 'Импорт Аудит Контрагентов', 'LBL_SEARCH_FORM_TITLE' => 'Фильтр Аудит Контрагентов', 'LBL_HISTORY_SUBPANEL_TITLE' => 'Просмотр истории', 'LBL_ACTIVITIES_SUBPANEL_TITLE' => 'Мероприятия', 'LBL_ACCOUNTSAUDIT_SUBPANEL_TITLE' => 'Аудит Контрагентов', 'LBL_NEW_FORM_TITLE' => 'Новый Аудит Контрагентов', 'LBL_ACCOUNTS_AUDIT' => 'Аудит', ); modules/AccountsAudit/metadata/subpanels/default.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ if (!defined('sugarEntry') || !sugarEntry) { die('Not A Valid Entry Point'); } $module_name = 'AccountsAudit'; $subpanel_layout = array( 'top_buttons' => array( array('widget_class' => 'SubPanelTopCreateButton'), array('widget_class' => 'SubPanelTopSelectButton', 'popup_module' => $module_name), ), 'where' => '', 'list_fields' => array( 'name' => array( 'vname' => 'LBL_NAME', 'widget_class' => 'SubPanelDetailViewLink', 'width' => '45%', ), 'date_modified' => array( 'vname' => 'LBL_DATE_MODIFIED', 'width' => '45%', ), 'edit_button' => array( 'vname' => 'LBL_EDIT_BUTTON', 'widget_class' => 'SubPanelEditButton', 'module' => $module_name, 'width' => '4%', ), 'remove_button' => array( 'vname' => 'LBL_REMOVE', 'widget_class' => 'SubPanelRemoveButton', 'module' => $module_name, 'width' => '5%', ), ), ); modules/AccountsAudit/metadata/dashletviewdefs.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ if (!defined('sugarEntry') || !sugarEntry) { die('Not A Valid Entry Point'); } global $current_user; $dashletData['AccountsAuditDashlet']['searchFields'] = array( 'date_entered' => array('default' => ''), 'date_modified' => array('default' => ''), 'assigned_user_id' => array( 'type' => 'assigned_user_name', 'default' => $current_user->name ) ); $dashletData['AccountsAuditDashlet']['columns'] = array( 'name' => array( 'width' => '40', 'label' => 'LBL_LIST_NAME', 'link' => true, 'default' => true ), 'date_entered' => array( 'width' => '15', 'label' => 'LBL_DATE_ENTERED', 'default' => true ), 'date_modified' => array( 'width' => '15', 'label' => 'LBL_DATE_MODIFIED' ), 'created_by' => array( 'width' => '8', 'label' => 'LBL_CREATED' ), 'assigned_user_name' => array( 'width' => '8', 'label' => 'LBL_LIST_ASSIGNED_USER' ), ); modules/AccountsAudit/metadata/detailviewdefs.php: <?php $module_name = 'AccountsAudit'; $viewdefs [$module_name] = array ( 'DetailView' => array ( 'templateMeta' => array ( 'form' => array ( 'buttons' => array ( 0 => 'EDIT', 1 => 'DUPLICATE', 2 => 'DELETE', 3 => 'FIND_DUPLICATES', ), ), 'maxColumns' => '2', 'widths' => array ( 0 => array ( 'label' => '10', 'field' => '30', ), 1 => array ( 'label' => '10', 'field' => '30', ), ), 'useTabs' => false, 'tabDefs' => array ( 'DEFAULT' => array ( 'newTab' => false, 'panelDefault' => 'expanded', ), ), ), 'panels' => array ( 'default' => array ( 0 => array ( 0 => 'id', ), 1 => array ( 0 => array ( 'name' => 'parent', 'studio' => 'visible', 'label' => 'LBL_PARENT', ), ), 2 => array ( 0 => 'date_created', ), 3 => array ( 0 => 'created_by_name', ), 4 => array ( 0 => array ( 'name' => 'field_name', 'label' => 'LBL_FIELD_NAME', ), ), 5 => array ( 0 => 'data_type', ), 6 => array ( 0 => 'before_value_string', ), 7 => array ( 0 => 'after_value_string', ), 8 => array ( 0 => 'before_value_text', ), 9 => array ( 0 => 'after_value_text', ), ), ), ), ); ?> modules/AccountsAudit/metadata/editviewdefs.php: <?php $module_name = 'AccountsAudit'; $viewdefs [$module_name] = array ( 'EditView' => array ( 'templateMeta' => array ( 'maxColumns' => '2', 'widths' => array ( 0 => array ( 'label' => '10', 'field' => '30', ), 1 => array ( 'label' => '10', 'field' => '30', ), ), 'useTabs' => false, 'tabDefs' => array ( 'DEFAULT' => array ( 'newTab' => false, 'panelDefault' => 'expanded', ), ), ), 'panels' => array ( 'default' => array ( 0 => array ( 0 => 'id', ), 1 => array ( 0 => array ( 'name' => 'parent', 'studio' => 'visible', 'label' => 'LBL_PARENT', ), ), 2 => array ( 0 => 'date_created', ), 3 => array ( 0 => 'created_by_name', ), 4 => array ( 0 => array ( 'name' => 'field_name', 'label' => 'LBL_FIELD_NAME', ), ), 5 => array ( 0 => 'data_type', ), 6 => array ( 0 => 'before_value_string', ), 7 => array ( 0 => 'after_value_string', ), 8 => array ( 0 => 'before_value_text', ), 9 => array ( 0 => 'after_value_text', ), ), ), ), ); ?> modules/AccountsAudit/metadata/listviewdefs.php: <?php $module_name = 'AccountsAudit'; $listViewDefs [$module_name] = array ( 'ID' => array ( 'width' => '32%', 'label' => 'LBL_ID', 'default' => true, 'link' => true, ), 'PARENT' => array ( 'type' => 'relate', 'studio' => 'visible', 'label' => 'LBL_PARENT', 'id' => 'PARENT_ID', 'link' => true, 'width' => '10%', 'default' => true, ), 'DATE_CREATED' => array ( 'width' => '20%', 'label' => 'LBL_DATE_CREATED', 'default' => true, 'link' => false, ), 'CREATED_BY_NAME' => array ( 'width' => '20%', 'label' => 'LBL_CREATED', 'default' => true, ), 'FIELD_NAME' => array ( 'width' => '20%', 'label' => 'LBL_FIELD_NAME', 'default' => true, 'link' => false, ), 'DATA_TYPE' => array ( 'width' => '20%', 'label' => 'LBL_DATA_TYPE', 'default' => true, 'link' => false, ), 'BEFORE_VALUE_STRING' => array ( 'width' => '20%', 'label' => 'LBL_BEFORE_VALUE_STRING', 'default' => true, 'link' => false, ), 'AFTER_VALUE_STRING' => array ( 'width' => '20%', 'label' => 'LBL_AFTER_VALUE_STRING', 'default' => true, 'link' => false, ), 'BEFORE_VALUE_TEXT' => array ( 'width' => '20%', 'label' => 'LBL_BEFORE_VALUE_TEXT', 'default' => true, 'link' => false, ), 'AFTER_VALUE_TEXT' => array ( 'width' => '20%', 'label' => 'LBL_AFTER_VALUE_TEXT', 'default' => true, 'link' => false, ), 'PARENT_ID' => array ( 'width' => '20%', 'label' => 'LBL_PARENT_ID', 'default' => false, 'link' => false, ), ); ?> modules/AccountsAudit/metadata/metafiles.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ $module_name = 'AccountsAudit'; $metafiles[$module_name] = array( 'detailviewdefs' => 'modules/' . $module_name . '/metadata/detailviewdefs.php', 'editviewdefs' => 'modules/' . $module_name . '/metadata/editviewdefs.php', 'listviewdefs' => 'modules/' . $module_name . '/metadata/listviewdefs.php', 'searchdefs' => 'modules/' . $module_name . '/metadata/searchdefs.php', 'popupdefs' => 'modules/' . $module_name . '/metadata/popupdefs.php', 'searchfields' => 'modules/' . $module_name . '/metadata/SearchFields.php', ); modules/AccountsAudit/metadata/popupdefs.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ if (!defined('sugarEntry') || !sugarEntry) { die('Not A Valid Entry Point'); } $module_name = 'AccountsAudit'; $object_name = 'AccountsAudit'; $_module_name = 'accountsaudit'; $popupMeta = array( 'moduleMain' => $module_name, 'varName' => $object_name, 'orderBy' => $_module_name . '.name', 'whereClauses' => array( 'name' => $_module_name . '.name', ), 'searchInputs' => array($_module_name . '_number', 'name', 'priority', 'status'), ); modules/AccountsAudit/metadata/quickcreatedefs.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ $module_name = 'AccountsAudit'; $viewdefs[$module_name]['QuickCreate'] = array( 'templateMeta' => array( 'maxColumns' => '2', 'widths' => array( array('label' => '10', 'field' => '30'), array('label' => '10', 'field' => '30') ), ), 'panels' => array( 'default' => array( array( 'name', 'assigned_user_name', ), ), ), ); modules/AccountsAudit/metadata/searchdefs.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ $module_name = 'AccountsAudit'; $searchdefs[$module_name] = array( 'templateMeta' => array( 'maxColumns' => '3', 'maxColumnsBasic' => '4', 'widths' => array('label' => '10', 'field' => '30'), ), 'layout' => array( 'basic_search' => array( 'name', array('name' => 'current_user_only', 'label' => 'LBL_CURRENT_USER_FILTER', 'type' => 'bool'), ), 'advanced_search' => array( 'name', array( 'name' => 'assigned_user_id', 'label' => 'LBL_ASSIGNED_TO', 'type' => 'enum', 'function' => array('name' => 'get_user_array', 'params' => array(false)) ), ), ), ); modules/AccountsAudit/metadata/SearchFields.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ if (!defined('sugarEntry') || !sugarEntry) { die('Not A Valid Entry Point'); } $module_name = 'AccountsAudit'; $searchFields[$module_name] = array( 'name' => array('query_type' => 'default'), 'current_user_only' => array( 'query_type' => 'default', 'db_field' => array('assigned_user_id'), 'my_items' => true, 'vname' => 'LBL_CURRENT_USER_FILTER', 'type' => 'bool' ), 'assigned_user_id' => array('query_type' => 'default'), //Range Search Support 'range_date_entered' => array('query_type' => 'default', 'enable_range_search' => true, 'is_date_field' => true), 'start_range_date_entered' => array( 'query_type' => 'default', 'enable_range_search' => true, 'is_date_field' => true ), 'end_range_date_entered' => array( 'query_type' => 'default', 'enable_range_search' => true, 'is_date_field' => true ), 'range_date_modified' => array('query_type' => 'default', 'enable_range_search' => true, 'is_date_field' => true), 'start_range_date_modified' => array( 'query_type' => 'default', 'enable_range_search' => true, 'is_date_field' => true ), 'end_range_date_modified' => array( 'query_type' => 'default', 'enable_range_search' => true, 'is_date_field' => true ), //Range Search Support ); modules/AccountsAudit/metadata/studio.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ /** * This file adds support for studio */ modules/AccountsAudit/AccountsAudit.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ require_once('include/SugarObjects/templates/audit/Audit.php'); class AccountsAudit extends Audit { public $new_schema = true; public $module_dir = 'AccountsAudit'; public $object_name = 'AccountsAudit'; public $table_name = 'accounts_audit'; public $importable = false; public $id; public $name; public $date_entered; public $date_modified; public $modified_user_id; public $modified_by_name; public $created_by; public $created_by_name; public $description; public $deleted; public $created_by_link; public $modified_user_link; public $assigned_user_id; public $assigned_user_name; public $assigned_user_link; public $SecurityGroups; public $parent; public $parent_id; public $date_created; public $field_name; public $data_type; public $before_value_string; public $after_value_string; public $before_value_text; public $after_value_text; public function bean_implements($interface) { switch($interface) { case 'ACL': return true; } return false; } } modules/AccountsAudit/Menu.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ if (!defined('sugarEntry') || !sugarEntry) { die('Not A Valid Entry Point'); } global $mod_strings, $app_strings, $sugar_config; if(ACLController::checkAccess('AccountsAudit', 'edit', true)){ $module_menu[]=array('index.php?module=AccountsAudit&action=EditView&return_module=AccountsAudit&return_action=DetailView', $mod_strings['LNK_NEW_RECORD'], 'Add', 'AccountsAudit'); } if(ACLController::checkAccess('AccountsAudit', 'list', true)){ $module_menu[]=array('index.php?module=AccountsAudit&action=index&return_module=AccountsAudit&return_action=DetailView', $mod_strings['LNK_LIST'],'View', 'AccountsAudit'); } modules/AccountsAudit/vardefs.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ $dictionary['AccountsAudit'] = array( 'table' => 'accounts_audit', 'audited' => false, 'inline_edit' => true, 'duplicate_merge' => false, 'fields' => array ( 'parent' => array ( 'required' => false, 'source' => 'non-db', 'name' => 'parent', 'vname' => 'LBL_PARENT', 'type' => 'relate', 'massupdate' => 0, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => '0', 'audited' => false, 'inline_edit' => true, 'reportable' => true, 'unified_search' => false, 'merge_filter' => 'disabled', 'len' => '255', 'size' => '20', 'id_name' => 'parent_id', 'ext2' => 'Accounts', 'module' => 'Accounts', 'rname' => 'name', 'quicksearch' => 'enabled', 'studio' => 'visible', ), 'accounts_audit_link' => array ( 'name' => 'accounts_audit_link', 'type' => 'link', 'relationship' => 'accounts_audit', 'vname' => 'LBL_ACCOUNTS_AUDIT', 'link_type' => 'one', 'module' => 'Accounts', 'bean_name' => 'Account', 'source' => 'non-db', ), 'created_by_link' => array( 'name' => 'created_by_link', 'type' => 'link', 'relationship' => 'accounts_audit_created_by', 'vname' => 'LBL_CREATED_BY_USER', 'link_type' => 'one', 'module' => 'Users', 'bean_name' => 'User', 'source' => 'non-db', ), ), 'relationships' => array ( 'accounts_audit' => array ( 'lhs_module' => 'AccountsAudit', 'lhs_table' => 'accounts_audit', 'lhs_key' => 'parent_id', 'rhs_module' => 'Accounts', 'rhs_table' => 'accounts', 'rhs_key' => 'id', 'relationship_type' => 'one-to-one', 'readonly' => false, 'deleted' => true, 'relationship_only' => false, 'for_activities' => false, 'is_custom' => true, 'from_studio' => true, 'relationship_name' => 'accounts_audit', ), 'accounts_audit_created_by' => array( 'lhs_module' => 'Users', 'lhs_table' => 'users', 'lhs_key' => 'id', 'rhs_module' => 'AccountsAudit', 'rhs_table' => 'accounts_audit', 'rhs_key' => 'created_by', 'relationship_type' => 'one-to-many' ), ), 'optimistic_locking' => true, 'unified_search' => false, ); if (!class_exists('VardefManager')) { require_once('include/SugarObjects/VardefManager.php'); } VardefManager::createVardef('AccountsAudit', 'AccountsAudit', array('audit')); Это были основные базовые (почти все) файлы модуля, без которых это все просто не будет работать. Файлы в себе не содержат по сути особо никакой логики, и просто должны быть, чтобы обеспечить необходимый функционал нового модуля. Обращаю ваше внимание на файлы AccountsAudit.php и vardefs.php: мы в них указали, что таблица нашего модуля будет называться "accounts_audit", то есть наша уже существующая таблица с аудированием. Таким образом мы просто вокруг уже существующей таблицы развернули модуль, который будет использовать ее для своей работы. Далее нам необходимо заявить в CRM-системе, что у нас появился новый модуль и объявить как он называется. Для этого в папке custom/Extension/application/Ext/Include/ добавляем файл AccountsAudit.php: <?php //WARNING: The contents of this file are auto-generated $beanList['AccountsAudit'] = 'AccountsAudit'; $beanFiles['AccountsAudit'] = 'modules/AccountsAudit/AccountsAudit.php'; $moduleList[] = 'AccountsAudit'; ?> А в папке custom/Extension/application/Ext/Language/ добавляем файл en_us.AccountsAudit.php <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ $app_list_strings['moduleList']['AccountsAudit'] = 'Аудит Контрагентов'; и файл ru_RU.AccountsAudit.php: <?php /** * * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. * Copyright (C) 2011 - 2017 SalesAgility Ltd. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not * reasonably feasible for technical reasons, the Appropriate Legal Notices must * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". */ $app_list_strings['moduleList']['AccountsAudit'] = 'Аудит Контрагентов'; Но это пока не все. Как выяснилось в процессе работы над заданием, в модуле отчетов мало указать связь модуля AccountsAudit -> Accounts! Необходимо еще "прокинуть" и обратную связь: Accounts -> AccountsAudit. Для этого добавляем файл /custom/Extension/modules/Accounts/Ext/Vardefs/auditFieds.php с следующим содержанием: <?php $dictionary['Account']['fields']['accounts_audit_link'] = array ( 'name' => 'accounts_audit_link', 'type' => 'link', 'relationship' => 'accounts_audit', 'vname' => 'LBL_ACCOUNTS_AUDIT', 'link_type' => 'one', 'module' => 'AccountsAudit', 'bean_name' => 'AccountsAudit', 'source' => 'non-db', ); $dictionary['Account']['relationships']['accounts_audit'] = array ( 'lhs_module' => 'AccountsAudit', 'lhs_table' => 'accounts_audit', 'lhs_key' => 'parent_id', 'rhs_module' => 'Accounts', 'rhs_table' => 'accounts', 'rhs_key' => 'id', 'relationship_type' => 'one-to-one', 'readonly' => false, 'deleted' => true, 'relationship_only' => false, 'for_activities' => false, 'is_custom' => true, 'from_studio' => true, 'relationship_name' => 'accounts_audit', ); Здесь мы добавили поле с линком на модуль AccountsAudit и добавили связь с AccountsAudit в модуле Контрагенты. Ну вот и все! Выполняем быстрое восстановление (там система предложит что то поменять в структуре таблицы accounts_audit, помоему добавить поле `deleted`, но это не страшно и никак не повлияет на функциональность аудирования), добавляем новый модуль "Аудит Контрагентов" в админке в "Настройка отображения закладок и субпанелей" и теперь у нас есть такой модуль, котором мы можем теперь полноценно пользоваться и в меню, и в Студии, и в Отчетах, и в Процессах и вообще:
  6. Добрый день! Попробуйте зайти в модуль с шаблонами и зайдите в любой первый попавшийся шаблон. Затем в строке браузера поменяйте его айдишник на 9f0d0646-1bf4-3da9-500a-5ad6dcec5796 и попробуйте загрузить страницу. Что будет? Пустая страница или загрузится шаблон?
  7. Добрый день! У вас не корректно настроены права доступа к файлам. SuiteCRM не может редактировать/добавлять их. Для начала посмотрите от имени кого запускается ваш сервер: echo exec("id"); Посмотрите, все ли файлы в проекте от этого пользователя и от этой группы? Выправить ситуацию с настройками доступа можно примерно так: chown -R 48:48 /var/www/vhosts/crmhosting.ru/crm/public_html/ find /var/www/vhosts/crmhosting.ru/crm/public_html -type d | xargs chmod 0755 find /var/www/vhosts/crmhosting.ru/crm/public_html -type f | xargs chmod 0644 подставляем только свои значения и пути. Если не помогло, то есть еще одна особенность в SuiteCRM по настройке доступа к файлам и папкам. В config.php: 'default_permissions' => array ( 'dir_mode' => 1533, 'file_mode' => 436, 'user' => 'apache', 'group' => 'apache', ), попробуйте тут явно задать юзера и группу (обычно они пустые в этом конфиге). Или "поиграйтесь" с цифрами. Например такие попробовать: 'default_permissions' => array ( 'dir_mode' => 1528, 'file_mode' => 432, 'user' => 'crmhosting', 'group' => 'staff', ), Попробуйте, потом расскажите что получилось )) В восстановлении оно лишь таблицу для аудита анализирует (есть или надо создать). Находится ли отдельно взятое поле в аудите или нет - это задача совсем других механизмов, а быстрому восстановлению отношения не имеющих.
  8. Добрый день! На скриншете не доработанная версия отчета по плановой загрузке сотрудника. Это не какой то отдельный модуль. Это CRM-система для разработчика: то, что я сам себе для своей компании пилю. Фактически сейчас там отображается плановое количество рабочих часов по дням для текущего сотрудника. Уже не помню что хотел вложить в этот отчет. Сейчас с точки зрения контроля работы сотрудников более удобным образом можно наблюдать следующую информацию: Слева распределение по сотрудникам сколько фактически отработано часов в день. Справа распределение фиктического относительно планового кол-ва часов. Тут календарь рабочих нагрузок для определения объема занятости сотрудника. Собирает в себе плановые нагрузки и фактически назначенные. Тут сублимированная информация по сотруднику из разных областей его деятельности. А тут у нас расчетная ведомость, где список фактически выполненных работ и суммарная стоимость к выплате сотрудникам в зависимости от выполненных работ. Как видите информацию в можно очень по разному представить к выводу. Я отталкивался от наиболее удобного мне формата для решения той или иной задачи. Вряд ли подобные отчеты можно найти где то уже готовыми, уж больно это все индивидуально. Потратив немного бюджета можно запилить именно то, что Вам будет удобно. Это не очень дорого, но очень удобно использовать.
  9. Если говорить про каждого отдельного сотрудника, то тогда уж можно лучше сделать графики прямо в карточке сотрудника. Открыл сотрудника - там панель с графиком. Типа такого: И не нужно плодить кучу дашлетов на главной.
  10. На сколько я помню логика работы SuiteCRM подразумевает возможность работы с несколькими полями с типом "валюта", но валюта будет одна. То есть все значения будут в рублях, долларах, или любой другой присутствующей в CRM валюте. Но хранение нескольких полей в разной валюте в рамках одной карточки не предусмотрено. Обусловлено тем, что все добавленные поля ссылаются на едиснтвенное поле, которое будет обозначать код валюты. То есть добавляем первое поле с валютой в карточку: формируется спец.поле, хранящее код валюты. Добавляем второе поле - оно будет получать код валюты из первого поля. И так далее. Сделать мультивалютность внутри одной карты можно, но это уже программировать.
  11. Всем привет! Столкнулся только что с ситуацией, когда в карточку Контрагента добавили поле с пользователем (связанная запись из Users), пытаемся в дашлете это поле использовать как фильтр, а оно не работает. Поле добавляли через файлы в /custom/Extensions/modules/Accounts/Ext/Vardefs/ В дашлете это выглядит примерно так: В карточке контрагента это же поле: После того, как в дашлете я выбираю это поле в виде фильтра, SuiteCRM формирует для выборки записей SQL-запрос примерно такого содержания: SELECT accounts.id , accounts.user_id2_c , LTRIM(RTRIM(CONCAT(IFNULL(jt0.first_name,''),' ',IFNULL(jt0.last_name,'')))) fixed_accountant_c , LTRIM(RTRIM(CONCAT(IFNULL(jt1.first_name,''),' ',IFNULL(jt1.last_name,'')))) fixed_accountant_c , jt1.created_by fixed_accountant_c_owner , 'Users' fixed_accountant_c_mod, accounts.assigned_user_id FROM accounts LEFT JOIN users jt0 ON accounts.user_id2_c = jt0.id AND jt0.deleted=0 LEFT JOIN users jt1 ON accounts.user_id2_c=jt1.id AND jt1.deleted=0 AND jt1.deleted=0 where (user_id2_c='d3c33565-3030-cebd-2db4-592308bd456b' ) AND accounts.deleted=0 Как мы видим ((accounts.id IN (''))) - совсем не то, что нам нужно. В результате анализа и поиска места, где это все собирается и как так получается был найден файл /include/Dashlets/DashletGeneric.php и в нем функция buildWhere() с таким участком: switch($widgetDef['type']) {// handle different types case 'date': case 'datetime': case 'datetimecombo': if(is_array($params) && !empty($params)) { if(!empty($params['date'])) $widgetDef['input_name0'] = $params['date']; $filter = 'queryFilter' . $params['type']; } else { $filter = 'queryFilter' . $params; } array_push($returnArray, $widgetClass->$filter($widgetDef, true)); break; case 'assigned_user_name': // This type runs through the SugarWidgetFieldname class, and needs a little extra help to make it through if ( ! isset($widgetDef['column_key']) ) { $widgetDef['column_key'] = $name; } // No break here, we want to run through the default handler case 'relate': if (isset($widgetDef['link']) && $this->seedBean->load_relationship($widgetDef['link'])) { $widgetLink = $widgetDef['link']; $widgetDef['module'] = $this->seedBean->$widgetLink->focus->module_name; $widgetDef['link'] = $this->seedBean->$widgetLink->getRelationshipObject()->name; } // No break - run through the default handler default: $widgetDef['input_name0'] = $params; if(is_array($params) && !empty($params)) { // handle array query array_push($returnArray, $widgetClass->queryFilterone_of($widgetDef, false)); } else { array_push($returnArray, $widgetClass->queryFilterStarts_With($widgetDef, true)); } $widgetDef['input_name0'] = $params; break; } Поле, по которому мы пытаемся в дашлете искать, создано при помощи такого массива: $dictionary['Account']['fields']['fixed_accountant_c'] = array ( 'required' => false, 'source' => 'non-db', 'name' => 'fixed_accountant_c', 'vname' => 'LBL_FIXED_ACCOUNTANT_C', 'type' => 'relate', 'massupdate' => 0, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => '0', 'audited' => false, 'inline_edit' => true, 'reportable' => true, 'unified_search' => false, 'merge_filter' => 'disabled', 'len' => '255', 'size' => '20', 'id_name' => 'user_id2_c', 'ext2' => 'Users', 'module' => 'Users', 'rname' => 'name', 'quicksearch' => 'enabled', 'studio' => 'visible', ); Судя по всему получается так, что в функции buildWhere() срабатывает case = 'relate'. Но так же выяснил, что НЕ срабатывает блок if (isset($widgetDef['link']) && $this->seedBean->load_relationship($widgetDef['link'])) {} просто по причине отсутствия 'link' в описании нашего поля. Решил добавить 'link', и ВСЕ ПОЛУЧИЛОСЬ!!! За основу для добавления link взял поле assigned_user_id, так как эти поля получились очень похожими: эти поля находятся в таблице `accounts` и ссылаются на таблицу и модуль с Пользователями (`users`) Таким образом в файл, в котором я описал мое поле, я добавил еще следующие блоки: $dictionary['Account']['fields']['fixed_accountant_c_link'] = array ( 'name' => 'fixed_accountant_c_link', 'type' => 'link', 'relationship' => 'fixed_accountant_c', 'vname' => 'LBL_FIXED_ACCOUNTANT_C_LINK', 'link_type' => 'one', 'module' => 'Users', 'bean_name' => 'User', 'source' => 'non-db', 'duplicate_merge' => 'enabled', 'rname' => 'fixed_accountant_c', 'id_name' => 'user_id2_c', 'table' => 'users', ); $dictionary['Account']['relationships']['fixed_accountant_c'] = array ( 'lhs_module' => 'Users', 'lhs_table' => 'users', 'lhs_key' => 'id', 'rhs_module' => 'Accounts', 'rhs_table' => 'accounts', 'rhs_key' => 'user_id2_c', 'relationship_type' => 'one-to-many' ); А в описание нашего поля вставляю link: $dictionary['Account']['fields']['fixed_accountant_c'] = array ( 'required' => false, 'source' => 'non-db', 'name' => 'fixed_accountant_c', 'vname' => 'LBL_FIXED_ACCOUNTANT_C', 'type' => 'relate', 'link'=>'fixed_accountant_c_link' , 'massupdate' => 0, 'no_default' => false, 'comments' => '', 'help' => '', 'importable' => 'true', 'duplicate_merge' => 'disabled', 'duplicate_merge_dom_value' => '0', 'audited' => false, 'inline_edit' => true, 'reportable' => true, 'unified_search' => false, 'merge_filter' => 'disabled', 'len' => '255', 'size' => '20', 'id_name' => 'user_id2_c', 'ext2' => 'Users', 'module' => 'Users', 'rname' => 'name', 'quicksearch' => 'enabled', 'studio' => 'visible', ); После этих манипуляций делаю быстрое восстановление и смотрим что получилось с генерацией SQL-запроса: SELECT accounts.id , accounts.name , accounts.renewal_date_c , accounts.time_zone_c , accounts.tariff_c , accounts.assigned_user_id FROM accounts where ((accounts.id IN ('d924c25c-7ab0-25c8-f5cd-5a58c168620a'))) AND accounts.deleted=0 ORDER BY accounts.date_entered DESC Что уже то, что нам нужно...
  12. Всем привет! Давайте разберем ситуацию, когда нам необходимо выполнить единоразово какую то задачу в CRM-системе, и мы хотим, чтобы эту задачу выполнил планировщик. Подобное может потребоваться, например когда: Пользователь должен запустить "тяжелый" алгоритм, результаты которого не надо сразу получить на экране. Например: синхронизация CRM-системы с какой-либо другой системой (если честно, я этот механизм "подсмотрел" в библиотеки связки Mautic и SuiteCRM). То есть пользователь где то в системе запускает синхронизацию и продолжает далее работать в CRM-системе, а CRM-система в этот момент производит долгую ресурсоёмкую процедуру синхронизации. В теории можно настроить запуск планировщик SuiteCRM на запуск из под root. Таким образом в задачах, выполняемых в планировщике, появится полный доступ к всему серверу. Это может пригодиться для каких то специфических задач (все же обычно запускать crontab из под root не рекомендуется). В этом случае запуск задачи из планировщика позволит сделать что то такое, что выполнить простым запросом не получится (в частности в данный момент при написании статьи мне было необходимо менять chmod у файла с логами php, которые создавались из под root). Нужна некая отсрочка выполнения некой задачи. Наверное можно еще много чего напридумывать, но статья про запуск задач в планировщике, а не про зачем это надо ))) Итак. Общий посыл к тому, что у нас должно происходить: Есть некая задача в планировщике Эту задачу не видно в списке задач, она не предназначена для цикличного воспроизведения, только разовый запуск Мы должны иметь некий механизм, который указывает ЕДИНОРАЗОВО запустить нашу задачу в планировщике Планировщик, используя его встроенные механизмы, видит необходимость запуска задачи и выполняет это действие Теперь давайте перейдем к практике. Давайте начнем с механизма создания задачи в планировщике: require_once('modules/SchedulersJobs/SchedulersJob.php'); require_once("include/SugarQueue/SugarJobQueue.php"); // Создаем задачу в планировщике $job = new SchedulersJob(); $job->name = "postInstall"; $job->target = "class::postInstallCRMHosting"; $job->assigned_user_id = '1'; $job->execute_time =$GLOBALS['db']->convert($GLOBALS['timedate']->getNow()->modify("+10 seconds")->asDb(), 'datetime'); $jq = new SugarJobQueue(); $jq->submitJob($job); Этот блок создаст запись в таблице `job_queue` (да да, именно в той, куда валятся все логи выполняемых задач в планировщике). Мы создаем запись с названием "postInstall" и указываем, что должен выполниться класс postInstallCRMHosting. Время выполнения - через 10 секунд. На самом деле задачи в планировщике выполняются по тикам crontab, который запускается ежеминутно в начале минуты. По этому если надо "прям сейчас", то все равно будет в ближайшую минуту. Но пусть будет 10 секунд. Также, при необходимости, можно указать через час/день/год. Таким образом в ближайшие минуту система попытается запустить выполнение задачи в классе postInstallCRMHosting. Давайте добавим файл с таким классом. Проще всего (и думаю правильнее всего) добавлять задачи в папку /custom/Extension/modules/Schedulers/Ext/ScheduledTasks. Например, файл с моей задачей будет выглядеть примерно так: /custom/Extension/modules/Schedulers/Ext/ScheduledTasks/CRMHosting.postInstall.php <?php /** * Created by PhpStorm. * User: crmhosting * Date: 06.05.2018 * Time: 9:39 */ class postInstallCRMHosting implements RunnableSchedulerJob { public function setJob(SchedulersJob $job) { $this->job = $job; } public function run($job_data) { /************************************ * Назначаем права на файл с логами */ $log_file = "/var/log/php-fpm/www-error.log"; exec("chmod 0777 " . $log_file); /************************************/ return true; } } Таким образом SuiteCRM выполнит наш скрипт единоразово в планировщике. В списке задач планировщика ничего не появится лишнего. Можно подобным образом запускать задачу необходимое количество раз.
  13. Всем привет! Просто небольшая заметка, но может кому пригодиться... Иногда бывает, что в карточке модуля на панели необходимо разместить некую информацию, но Label у этой информации будет лишним. Например: список ссылок, относящихся к тому или иному контрагенту: Как вы видите, здесь имеет место быть отдельная панель, и в этой панели единственная переменная, которая содержит кучу ссылок. В DetailView это выглядит примерно так: 'lbl_editview_panel12' => array ( 0 => array ( 0 => array ( 'name' => 'custom_all_link', 'label' => '', ), ), ), Видите две точки? Это наш пустой Label. Выглядит не красиво, не правда ли? Можно конечно было бы добавить туда какой-нибудь LBL_, но он тут избыточен! Панель и так называется "Ссылки". И внутрь вставлять еще раз "Ссылки" или что то такое уже было бы лишним! Давайте просто уберем вообще блок, в котором находится Label: 'lbl_editview_panel12' => array ( 0 => array ( 0 => array ( 'name' => 'custom_all_link', 'label' => '', 'hideLabel' => true, ), ), ), Теперь наш блок примет вид: Как вы видите Label для нашего поля перестал вообще отображаться!
  14. Всем привет! В последних на текущий момент (апрель 2018 года) версиях SuiteCRM (версии SuiteCRM 7.10.2 и 7.10.3) столкнулись с небольшой проблемой: куда то пропали боковые меню в модулях, доступных админу (которые находятся в админке). Например, когда смотрим на свой профиль: Начал искать что куда делось. Нашел не очень старые версии, в которых все работало. Состав меню определяется в том числе в файле Menu.php, лежащем в модуле. Там есть строки типа: $module_menu = Array(); if ($GLOBALS['current_user']->isAdminForModule('Users') ) { $module_menu = Array( Array("index.php?module=Users&action=EditView&return_module=Users&return_action=DetailView", $mod_strings['LNK_NEW_USER'], "Create"), Array("index.php?module=Users&action=EditView&usertype=group&return_module=Users&return_action=DetailView", $mod_strings['LNK_NEW_GROUP_USER'], "Create_Group_User") ); $module_menu[] = Array("index.php?module=Users&action=ListView&return_module=Users&return_action=DetailView", $mod_strings['LNK_USER_LIST'], "List"); $module_menu[] = Array("index.php?module=Import&action=Step1&import_module=Users&return_module=Users&return_action=index", $mod_strings['LNK_IMPORT_USERS'], "Import", 'Contacts'); } Ищем в /includes/ файлы, где активно используется переменная $module_menu. Внимание привлекла папка /include/MVC/ Сравниваем текущую версию этой папки с версией, где все работало: Смутило использование unset. Оказалось верно, что смутило. В общем убираем этот блок из файла SugarView.php, и вуа-ля:
×