• Ручная настройка субпанелей в SugarCRM

    В статье Настройка субпанелей в SugarCRM я описал, как можно редактировать список полей, отображаемых в сабпанелях. Делалось это через студию в админке SugarCRM, и потому раздел был для администраторов SugarCRM. Но при всей своей крутизне и навороченности студии SugarCRM, все же не все действия можно там делать. Иногда встают задачи, когда необходимо ручками лезть в код и менять его по своему усмотрению.

    Но вернемся к нашему предмету разговора: сабпанелям. На в встал вопрос: А как же "запихать" в сабпанель "История" еще одно поле, а в частности - описание заметок? Т.е. пользователь хотел, чтобы в его CRM-системе в сабпанели "История", при отображении в ней заметок, помимо стандартных полей выводилось описание заметок.

    Сабпанель "История", как "Мероприятия", является несколько обособленным объектом в SugarCRM, и представляет собой "коллекцию" из нескольких модулей сразу. В частности, в сабпанели "История" отображаются записи модулей: "Звонки", "Встречи", "Задачи", "Заметки", "Е-майлы". Если посмотреть на описание этой сабпанели, например, для Контрагентов, то мы увидим следующий блок кода: Файл /modules/Accounts/metadata/subpaneldefs.php

    'history' => array(
            'order' => 20,
            'sort_order' => 'desc',
            'sort_by' => 'date_entered',
            'title_key' => 'LBL_HISTORY_SUBPANEL_TITLE',
            'type' => 'collection',
            'subpanel_name' => 'history',   //this values is not associated with a physical file.
            'header_definition_from_subpanel'=> 'meetings',
            'module'=>'History',
            'top_buttons' => array(
                    array('widget_class' => 'SubPanelTopCreateNoteButton'),
                    array('widget_class' => 'SubPanelTopArchiveEmailButton'),
                    array('widget_class' => 'SubPanelTopSummaryButton'),
            ),      
            'collection_list' => array(  
                    'tasks' => array(
                            'module' => 'Tasks',
                            'subpanel_name' => 'ForHistory',
                            'get_subpanel_data' => 'tasks',
                    ),
                    'meetings' => array(
                            'module' => 'Meetings',
                            'subpanel_name' => 'ForHistory',
                            'get_subpanel_data' => 'meetings',
                    ),
                    'calls' => array(
                            'module' => 'Calls',
                            'subpanel_name' => 'ForHistory',
                            'get_subpanel_data' => 'calls',
                    ),
                    'notes' => array(
                            'module' => 'Notes',
                            'subpanel_name' => 'ForHistory',
                            'get_subpanel_data' => 'notes',
                    ),      
                    'emails' => array(
                            'module' => 'Emails',
                            'subpanel_name' => 'ForHistory',
                            'get_subpanel_data' => 'emails',
                    ),      
            )                       
    ),
    

    Блок collection_list содержит список модулей, записи которых будут отображаться в сабпанели "История". Для каждого из модулей, как вы видите, присутствует параметр subpanel_name. Этот параметр указывает название сабпанели, чья конфигурация будет применена для вывода общей, итоговой сабпанели. Фактически, этот параметр указывает на название файла в модуле, который будет обработан при выводе итоговых данных. Файлы с названием, указанным в subpanel_name, находятся в /modules/модуль/metadata/subpanels/значение_subpanel_name.php.

    Как вы видите, все сабпанели называются ForHistory. Связано это с тем, что коллекционная субпанель будет работать только в том случае, если сабпанели каждого из модулей будут НАСТРОЕНЫ НА ОТОБРАЖЕНИЕ ОДИНАКОВЫХ ПОЛЕЙ В ОДИНАКОВОЙ ПОСЛЕДОВАТЕЛЬНОСТИ! Это ключевое условие. Если "докопаться" до функционала получения записей для коллекционной сабпанели, то можно увидеть, что SQL-запрос на получение связанных записей разных модулей формируется SugarCRM через UNION, т.е.:

    ( SELECT поля FROM звонки JOIN связи WHERE условия попадания)
    UNION
    ( SELECT поля FROM встречи JOIN связи WHERE условия попадания)
    UNION
    ( SELECT поля FROM задачи JOIN связи WHERE условия попадания)
    UNION
    ( SELECT поля FROM заметки JOIN связи WHERE условия попадания)
    UNION
    ( SELECT поля FROM емайлы JOIN связи WHERE условия попадания)
    

    а одно из условий корректного использования конструкции UNION в MySQL - это одинаковое кол-во и названия возвращаемого результата у каждого из SELECT-ов. Вот и получается по нашей задаче, что если мы хотим добавить какое-либо поле в отображение коллекционной сабпанели "История", то вывод этого поля необходимо прописать в файле ForHistory.php каждого из модулей, находящихся в коллекции.

    Для этого добавляем в каждый файл ForHistory.php в переменную list_fields, в нужное нам место (но это место должно быть для всех файлов одно и тоже) следующий код:

    'description'=>array(
            'vname' => 'LBL_DESCRIPTION',
            'width' => '30%',
    ),
    

    Эта конструкция укажет, что необходимо в результирующий список добавить поле "Описание".

    Получилось примерно следующее:

    programmer_detail_subpanels_customlist_1