SugarCRM 7 — Conditional Read Only Fields

SugarCRM has a few ways to set fields as read-only, but it leaves a lot to be desired. One of the missing features that you might need to implement is having a module flagged as read-only on the record view based on a field on the module or the result of an API request. I have found a way to do it but it is mostly basic UI hacking and doesn’t set the field read-only everywhere on the UI, just the record view page. So it will remain on the recordlist view or within other subpanels as editable, so bear this in mind as it’s only useful for very specific cases. ...

February 6, 2016 · Shane Dowling

NetworkX — Get all Paths from all sources to sinks

Often when I’m working with graphs and a set of masses in a spectrum I need to be able to iterate over all paths for all sources and sinks in that graph. Especially if I’m looking to compare multiple ideal spectrums against a given spectrum. Here’s some code that will allow me to quickly iterate over all source->sink paths in a given graph G. #!/usr/bin/env python """ Shane Dowling, 04 Nov 2015 Will iterate over all sources, sinks and get all paths """ import networkx as nx G = nx.DiGraph() # Fill in a few edges sink_nodes = [node for node, outdegree in G.out_degree(G.nodes()).items() if outdegree == 0] source_nodes = [node for node, indegree in G.in_degree(G.nodes()).items() if indegree == 0] for [(source, sink) for sink in sink_nodes for source in source_nodes]: for path in nx.all_simple_paths(G, source=source, target=sink): print(path)

November 4, 2015 · Shane Dowling

Generate Binary Tree From String

Recently while implementing the Small Parsimony Problem I had the need to generate a binary tree from a string in Python. The pseudo-code in the question implicitly assumes you have some functionality that will generate a DNA sequence like CAAATCCC into a binary tree, then run SmallParsimony on it. I couldn’t find that functionality anywhere, so I decided to implement something simple in networkx. Hopefully it’s useful. #!/usr/bin/env python """ Shane Dowling, 27 Oct 2015 To run simply call generate_leaf_graph and pass in s string. """ def count_predecessors(T): pred = 0 for v in T.nodes(): pred += 1 return pred def generate_leaf_graph(s): """ Will generate a leaf graph and return it along with the Character dictionary representing the characters at each leaf node position """ T = nx.DiGraph() Character = {} i = 0 parI = len(s) for (son, daughter) in zip(s[0::2], s[1::2]): Character[i] = son Character[i+1] = daughter T.add_edge(parI, i) T.add_edge(parI, i+1) i += 2 parI += 1 while count_predecessors(T) > 1: for v in T.nodes(): T.add_edge(parI, v) T.add_edge(parI, v+1) parI += 1 return [T, Character]

October 27, 2015 · Shane Dowling

SugarCRM — Conditional Actions

Say you need to hide certain actions in Sugar depending on the status of a field, I’ve come across a great snippet of code from an awesome comment by Felix Nilam on the SugarCRM forums and wanted to show you a brief snippet of how it could work. Make sure to call it before render, otherwise I had issues with this.meta.buttons already having rendered. ({ extendsFrom: 'RecordView', initialize: function (options) { app.view.invokeParent(this, {type: 'view', name: 'record', method: 'initialize', args:[options]}); this.before('render', this.mycustom_button_visibility, this); this.before('render', this.mycustom2_button_visibility, this); }, mycustom_button_visibility : function() { if(typeof this.model.get('some_field') != 'undefined' && this.model.get('some_field') != 'some_value') { this.hide_button('some_button_name'); } }, mycustom2_button_visibility : function() { if(typeof this.model.get('some_second_field') != 'undefined' && this.model.get('some_second_field') != 'some_value') { this.hide_button('some_second_button_name'); } }, hide_button: function(name) { var button_sel = ''; var button_index = ''; // find the buttons index for the share button _.find(this.meta.buttons, function(bn, idx) { if(bn.name == 'main_dropdown') { button_sel = idx; _.find(bn.buttons, function(bbn, idx_bbn) { if(bbn.name == name) { button_index = idx_bbn; return true; } }); return true; } }); if(button_sel != '' && button_index != '') { //remove the meta this.meta.buttons[button_sel].buttons.splice(button_index, 1); } } }) Props to Felix for the snippet and I hope this helps others. ...

October 15, 2015 · Shane Dowling

Bioinformatics/Rosalind — Skeleton Generator

Working through part 4 of my Cousera Bioinformatics specialisation, I decided to write a generator that creates a standardised approach to structure, write and test your algorithmic code. It also works for Rosalind problems. Explanations are in the README. If you have any issues or are confused by anything, feel free to get in touch! You can find the code here.

September 27, 2015 · Shane Dowling

Tiddlywiki to Org-Mode

Okay, I swear this is the last document conversion script I’m writing this year. I’ve been on a bit of a rampage to move all of my life in Emacs Org-Mode and converting all of my Tiddlywiki notes into Org mode has been on my list for a while. Thankfully both formats are pretty simple so the script was fairly straightforward. You can find it here, simply fill in the folder locations and give it a run. ...

August 31, 2015 · Shane Dowling

OSQA to Tiddlywiki

Recently I’ve been trying out Tiddlywiki as an alternative to Evernote. I decided to try convert my existing OSQA install to Tiddlywiki as I’m travelling a lot and don’t always have access to my servers via the internet. Here’s a python script I wrote that might help anyones trying to do the same. You can find it here on github. Any questions or queries, just let me know!

July 27, 2015 · Shane Dowling

Verify you're hidden with conky

I run a few scripts to ensure my identity stays hidden day to day on my laptop. Here’s a few conky scripts to verify things are as they should be. VPN Because I don’t always know my ip or what my VPN’s ip is, I wanted conky to display the location I currently appear at from my VPN. If the location was the same as where I physically am, something’s gone wrong. To implement this, I wrote a python script and using ipinfo.io grab my location and print it to conky. ...

July 26, 2015 · Shane Dowling

SugarCRM 7 — Adding an action to the listview headerpanel

This tutorial should show you how to add a custom button/action that will appear across all modules. It’s a little similar to this tutorial with a few changes to how the button gets rendered and the actions get called. 1. Adding the button to the headerpanel Firstly you’ll need to create a new folder to store the headerpane actions, so create this folder in the sugarcrm root directory custom/clients/base/views/list-headerpane/. Then create the file list-headerpane.php with this content. This will add a button next to the Create button for all modules. ...

July 25, 2015 · Shane Dowling

SugarCRM — Prevent currencies getting overridden

SugarCRM has some neat features involving currency rates, but one of the more annoying ones is that Sugar will automatically update the base rate every time you save a record with a currency field attached. This can be fairly annoying default behaviour if you wish to maintain the correct record value at the time of sale. The problem Say for example you have a custom module Books and your systems base currency is USD. You sell a book for 10 Euros at 11 dollars(the currenct change rate). If say a few weeks later you wanted to change the status of the Book to say, note down that the invoice was received and the exchange rate in that time has changed drastically. When you hit save Sugar would re-calculate the Euro value again(and despite the item being sold for 10 Euros originally the exchange rate has now changed and Sugar shows say 12 Euros, which is completely inconsistent with what you’ve invoiced. ...

April 16, 2015 · Shane Dowling