SugarCRM 7 — Custom subpanels

This tutorial should hopefully help you to create a new subpanel under the Contacts module in Sugar using a custom link class and driven by SugarCRM 7’s new SugarQuery API. 1. Create a new link class This should go into custom/modules//YourNewLink.php and this class will act as the custom functionality that will build your link between the two records. /** * Custom filtered link */ class YourNewLink extends Link2 { /** * DB * * @var DBManager */ protected $db; public function __construct($linkName, $bean, $linkDef = false) { $this->focus = $bean; $this->name = $linkName; $this->db = DBManagerFactory::getInstance(); if (empty($linkDef)) { $this->def = $bean->field_defs[$linkName]; } else { $this->def = $linkDef; } } /** * Returns false if no relationship was found for this link * * @return bool */ public function loadedSuccesfully() { // this link always loads successfully return true; } /** * @see Link2::getRelatedModuleName() */ public function getRelatedModuleName() { return ''; } /** * * @see Link2::buildJoinSugarQuery() */ public function buildJoinSugarQuery($sugar_query, $options = array()) { $joinParams = array('joinType' => isset($options['joinType']) ? $options['joinType'] : 'INNER'); $jta = 'active_other_invites'; if (!empty($options['joinTableAlias'])) { $jta = $joinParams['alias'] = $options['joinTableAlias']; } $sugar_query->joinRaw($this->getCustomJoin($options), $joinParams); return $sugar_query->join[$jta]; } /** * Builds main join subpanel * @param string $params * @return string JOIN clause */ protected function getCustomJoin($params = array()) { $bean_id = $this->db->quoted($this->focus->id); $sql = " INNER JOIN("; $sql .= "SELECT id FROM accounts WHERE id={$bean_id}"; // This is essentially a select statement that will return a set of ids that you can match with the existing sugar_query $sql .= ") accounts_result ON accounts_result.id = sugar_query_table.id"; return $sql; } } The argument $sugar_query is a new SugarQuery object, the details of which are documented here. What you essentially need to do is extend this query with whatever join/filters you wish to add. This is done in the inner join I’ve specified. ...

August 13, 2014 · Shane Dowling

SugarCRM 7 — Making Ajax Requests

SugarCRM has a pretty great API if you know how to poll it. Today I’m sharing two examples of where I’ve needed to poll SugarCRM’s API with some sample jQuery code. A jQuery autocompleter If you’re declaring an input box and wish to autocomplete it’s results based on the results from a particular module, this sample code should get you started. $( "#your-input-box").autocomplete({ $.ajax({ { request.setRequestHeader("OAuth-Token", SUGAR.App.api.getOAuthToken()); }, response($.map(data.records, function(obj) { return { }; })); } }); }, $('#your-input-box').val(ui.item.label); $('#your-input-box-id').val(ui.item.id); return false; } }); Note: This leverages the existing SugarCRM API to populate this data. You can customise the filter however you want, just load up firebug/a web inspector and do a few sample requests from Sugar’s core fieldset if you need sample requests to work with. ...

August 9, 2014 · Shane Dowling

SugarCRM 7 — Add a new action to a record

Odds are if you’re customising SugarCRM, you will at some point need to add functionality to the records page. This article shows you a framework for creating actions on the UI, the API entrypoints to run your code and how to link it all together using SugarCRM’s sidecar functionality. 1. Add the button In custom/modules//clients/base/views/record/record.php, you’ll need this to add the core button array. $viewdefs[$module_name]['base']['view']['record']['buttons'] = array ( 0 => array ( 'type' => 'button', 'name' => 'cancel_button', 'label' => 'LBL_CANCEL_BUTTON_LABEL', 'css_class' => 'btn-invisible btn-link', 'showOn' => 'edit', ), 1 => array ( 'type' => 'rowaction', 'event' => 'button:save_button:click', 'name' => 'save_button', 'label' => 'LBL_SAVE_BUTTON_LABEL', 'css_class' => 'btn btn-primary', 'showOn' => 'edit', 'acl_action' => 'edit', ), 2 => array ( 'type' => 'actiondropdown', 'name' => 'main_dropdown', 'primary' => true, 'showOn' => 'view', 'buttons' => array ( 0 => array ( 'type' => 'rowaction', 'event' => 'button:edit_button:click', 'name' => 'edit_button', 'label' => 'LBL_EDIT_BUTTON_LABEL', 'acl_action' => 'edit', ), 1 => array ( 'type' => 'shareaction', 'name' => 'share', 'label' => 'LBL_RECORD_SHARE_BUTTON', 'acl_action' => 'view', ), 2 => array ( 'type' => 'pdfaction', 'name' => 'download-pdf', 'label' => 'LBL_PDF_VIEW', 'action' => 'download', 'acl_action' => 'view', ), 3 => array ( 'type' => 'pdfaction', 'name' => 'email-pdf', 'label' => 'LBL_PDF_EMAIL', 'action' => 'email', 'acl_action' => 'view', ), 4 => array ( 'type' => 'divider', ), 5 => array ( 'type' => 'rowaction', 'event' => 'button:do_some_task:click', 'name' => 'do_some_task', 'label' => 'LBL_DO_SOME_ACTION', 'acl_action' => 'view', ), 6 => array ( 'type' => 'rowaction', 'event' => 'button:find_duplicates_button:click', 'name' => 'find_duplicates_button', 'label' => 'LBL_DUP_MERGE', 'acl_action' => 'edit', ), 7 => array ( 'type' => 'rowaction', 'event' => 'button:duplicate_button:click', 'name' => 'duplicate_button', 'label' => 'LBL_DUPLICATE_BUTTON_LABEL', 'acl_module' => '', 'acl_action' => 'create', ), 8 => array ( 'type' => 'rowaction', 'event' => 'button:audit_button:click', 'name' => 'audit_button', 'label' => 'LNK_VIEW_CHANGE_LOG', 'acl_action' => 'view', ), 9 => array ( 'type' => 'divider', ), 10 => array ( 'type' => 'rowaction', 'event' => 'button:delete_button:click', 'name' => 'delete_button', 'label' => 'LBL_DELETE_BUTTON_LABEL', 'acl_action' => 'delete', ), ), ), 3 => array ( 'name' => 'sidebar_toggle', 'type' => 'sidebartoggle', ), ); Note what I’ve stored at array key 5. This is the custom button that will be rendered and the event button do_some_task will be called in the javacript file we’ll created. You can add this anywhere in the drop-down I just generally choose here. ...

August 7, 2014 · Shane Dowling

SugarCRM — Sugar powered by Salt!

SugarCRM can be a pain to setup, especially if you are managing many installs on different servers/environments. I’m a big fan of using salt to configure my servers. I rarely manage any servers directly anymore and generally run things through my salt master. This guide should hopefully get you up and running with a production ready setup of SugarCRM that you can re-use over and over. If you are looking for a decent primer on saltstack, this video will give you a really useful introduction to what salt can really do. I’m barely scratching the surface. ...

August 2, 2014 · Shane Dowling

Log Queries with MySQL Proxy

What is it? Have you ever found yourself wanting live statistics of you mysql database, or a log of all the erroring queries. Well MySQL Proxy might MySQL Proxy is a simple program that sits between your client and MySQL server(s) that can monitor, analyze or transform their communication. Basically MySQL Proxy collects database queries and acts on them using scripts built in lua that can do some useful things. I find this handy when debugging SugarCRM as sometimes failed database queries get suppressed(especially when making API requests) and I needed a transparent way to check nothing has failed on the DB side. ...

July 19, 2014 · Shane Dowling

SugarCRM — Versioning Your Database

One issue that constantly re-occurs for me using SugarCRM is that certain knowledge is only stored in it’s database. So say you want to revert to a previous version of Sugar and wish to obtain the Studio customisations you’ve done at that version, say two days ago, well your just out of luck. This is pretty annoying considering most of your day to day changes will probably be in Studio and you have no real way to see those changes outside of Sugar’s “View History”, which leaves a lot to be desired mostly as again, it’s all in the DB. You’re effectively left to sharing a database dump between developers. ...

July 16, 2014 · Shane Dowling

SugarCRM 7 — Set recordlist row colours based on row data

The tutorial shows you how to do two useful things in SugarCRM 7. Firstly, how to call actions when rows get updated in SugarCRM’s recordlist and secondly, how to set information based on row data. The example I have here will essentially update the table colours based on a specific data value in each row. So say you have a drop-down with the values Red,Green,Orange and Yellow this will update the rows to the specified colour. The key call here is this.collection.on(‘data:sync:complete’), which essentially fires when the sidecar(read backbone), data sync is completed. ...

July 12, 2014 · Shane Dowling

Minimalist MySQL Reporting

Sometimes business folk can have crazy demands on the types of reports your system should produce and sometimes these can be really time consuming and painful to get right. Often I find the most flexible solution is to give these power-users access to tidier version of the raw data within a tool they’re comfortable playing with themselves. To that end, Excel has a serviceable ODBC connector that costs $35 and will allow your power users to pull data in from MySQL and filter/play around to their hearts content. The problem is a) formatting the data in such a way to provide useful information to your users and b) opening up data access just enough to allow these reporting users into your system. ...

July 10, 2014 · Shane Dowling

SugarCRM 7 — Colour Code Rows based on data values

Add this into your recordlist javascript file. render_colors : function() { console.log('here'); $("tr[name^='<YOUR_MODULE']").each(function() { //loop over each row if($(this).find('div[data-original-title="Out"]').length > 0) { //check value of TD $(this).find($('td')).each(function() { $(this).css("background-color", "#FFBABA"); }); } else if($(this).find('div[data-original-title="In"]').length > 0) { $(this).find($('td')).each(function() { $(this).css("background-color", "#C3F8B5"); }); } else if($(this).find('div[data-original-title="Withdrawn"]').length > 0) { $(this).find($('td')).each(function() { $(this).css("background-color", "#FFCF8F"); }); } else if($(this).find('div[data-original-title="Reserved"]').length > 0) { $(this).find($('td')).each(function() { $(this).css("background-color", "#FAFE8E"); }); } }); }

July 10, 2014 · Shane Dowling

Your brain on stoicism

For the last few months I’ve been attempting to practice Stoicism and wanted to share the effects of what regular stoic practice has had. If you’ve never heard of Stoicism I’d recommend fourhourworkweek.com’s introduction, which is very pragmatic. Essentially, what happens after several weeks of watching your emotional reactions, evaluating what’s in your control and feeling indifference to what isn’t. Certainty The first noticeable effect was stoicism seems to have cultivated a sort of centred calm feeling within my decision making. A certainty that wasn’t there before, like a rational backbone on which decisions are made. This is a net effect I’ve never gotten from say tradional mindfulness practice(simply as it’s a topic not addressed). Say I’m facing a difficult meeting or presentation and I need to make a decision on something important I’m going to say. Instead of feeling this vague anxiety or dread and avoiding the problem, I force myself to make a note of it. I hold the feeling in my awareness and remind myself of the preparation I’ve done. If my decision either way makes me look foolish, well that’s out of my control. The emotional background noise is suspended and it’s reduced decision fatigute by a significant amount. It’s a very useful default technique to go to. ...

July 10, 2014 · Shane Dowling