B2C Calls and Activities

sugarcrmdevelopers —  July 19, 2013

A quirk of users find with SugarCRM Activities and History items is that, by default, they automatically relate to an Account instead of a Contact. This makes reporting on the number of calls to a given Account easier, but for a heavily B2C-type business this doesn’t make sense. You called the person you’re calling.

Instead, it’d be nice for this business to have the default Related To field for a new Call to default to the Contact that you’re reviewing. To make it happen you’ll need to override the Widget Class for the Call-Creation subpanel. It sounds more complicated than it is.

Any time you want to adjust how a subpanel works, you’ll want to review the original form of it, which is held in /include/generic/SugarWidgets. To actually make your upgrade-safe change, you can extend the class and put your version in the custom directory. In this case, we want to extend SugarWidgetSubPanelTopScheduleCallButton. There’s a clause in it that sets the default parent_id and parent_type fields to the contact’s account, but only if there’s not another value already specified in a normally-empty array called $additionalFormFields. To minimize copypasta from the original file, we’ll fill that array and then call the parent function.


class SugarWidgetCustomSubPanelTopScheduleCallButton extends SugarWidgetSubPanelTopScheduleCallButton{
    public $module = 'Calls';
    public $title = 'LBL_NEW_BUTTON_TITLE';
    public $access_key = 'LBL_NEW_BUTTON_KEY';
    public $form_value = 'LNK_NEW_CALL';
    public $acl = 'edit';

     * LayoutManager::getClassFromWidgetDef() will call this widget with a
     * single param: $this, or the LayoutManager object itself. This is
     * inconsistent with the parent-parent of SugarWidgetSubPanelTopButton
     * which expects 4x string fields.
     * To reconcile, we'll take the single param and ignore and instead call
     * parent::SugarWidgetSubPanelTopButton(), feeding it the 4x strings it
     * apparently expects.
     * @param type $LayoutManager
    public function __construct($LayoutManager=''){
        return parent::SugarWidgetSubPanelTopButton($this->module,$this->title,$this->access_key,$this->form_value);

     * Override parent by assigning parent_type to Contacts, parent_name and
     * parent_id to match the $defines['focus'] Contact object.
     * @param type $defines
     * @param string $additionalFormFields
     * @return type
    public function &_get_form($defines, $additionalFormFields = null){
        if($defines['focus']->object_name == 'Contact'){
            $additionalFormFields['parent_type'] = !empty($additionalFormFields['parent_type']) ? $additionalFormFields['parent_type'] : 'Contacts';
            $additionalFormFields['parent_name'] = !empty($additionalFormFields['parent_name']) ? $additionalFormFields['parent_name'] : $defines['focus']->name;
            $additionalFormFields['parent_id'] = !empty($additionalFormFields['parent_id']) ? $additionalFormFields['parent_id'] : $defines['focus']->id;

        return parent::_get_form($defines,$additionalFormFields);

Now that the subpanel is available, we need to actually tell the Contact module to use it. Do this by overriding the existing activities subpanel layout like so:

 * Override the activities subpanel topbutton array.
$layout_defs['Contacts']['subpanel_setup']['activities']['top_buttons'] = array(
	array('widget_class' => 'SubPanelTopCreateTaskButton'),
	array('widget_class' => 'SubPanelTopScheduleMeetingButton'),
	array('widget_class' => 'CustomSubPanelTopScheduleCallButton'),
	array('widget_class' => 'SubPanelTopComposeEmailButton'),

This process can likewise be applied to Meetings and Tasks for a truly B2C way of working with activities.