Adding custom module to related to field in SuiteCRM

posted in: SuiteCRM | 0

Sometimes when you create a new module you want it to appear in the “Related To” dropdowns around SuiteCRM. This post will cover the simple method of adding modules to these dropdowns.

 

In this post we’ll add a fictional “Sport” module to the dropdown. We’ll end up with this:

RelatedToWithSport

 

The related to dropdown, like most in SuiteCRM can be changed by using the dropdown editor within SuiteCRM. We’re going to use the dropdown editor to add our custom module.

 

If you want to target the Related To module in Notes then edit the record_type_display_notes dropdown. For other related to dropdowns edit the parent_type_display.

We start by adding a new entry to the dropdown with the modules name as the “Item Name” and the display label we wish to use as the “Display Label”. I.e. in our example we’ll have

“ABC_Sport” as the “Item Name” and “Sport” as the “Display Label” as in this image:

 

DropdownEditorSport

 

And that’s it! SuiteCRM will use the module name to load the correct popup when searching for the module and will store this when saving the record. Your custom module can now be added to notes and the like.

 

Make a custom module importable

posted in: SuiteCRM | 0

If you’ve created a custom module but are getting the message “Imports aren’t set up for this module type” then it’s very easy to add this functionality to your custom module.

 

In the bean file modules/ABC_Your_Module/ABC_Your_Module.php simply add the line

var $importable = true;

 

After the class definition and you’ll be able to import this module.

SuiteCRM Missing Field Definitions

posted in: SuiteCRM | 0

If you move instances of SuiteCRM around it’s possible to have a copy of the SuiteCRM files that reference a custom field that doesn’t exist in the fields_meta_data table.

This can cause broken SQL queries since SuiteCRM will try to reference a field but won’t have it’s name. A broken query may look something like:

UPDATE my_custom_module SET name='Foo', =NULL,=NULL WHERE id='1234';

This can be fixed in one of two ways.

The first, preferred way is to get the info from the fields_meta_data table. This mysqldump command will create a file with the fields meta data:

mysqldump -uYourDBUser --insert-ignore --no-create-info -p YourDB fields_meta_data > fields_meta_data.sql

This can then be used to populate the new DB:

mysql -uYourDBUser -p YourNewDB < fields_meta_data.sql

The second is to find and remove the fields which are causing the issue. The following script will list any entries in the vardefs without a name which causes the original broken queries. Simply change the $base variable to be the path to the SuiteCRM instance you want to check and run php -f fieldcheck.php:

Once you have found the offending fields you can remove the definitions for them.

 

Add row buttons to the List View in SuiteCRM

posted in: SuiteCRM | 0

A previous post covered adding a button to the List View. However this was adding an action button to the list as a whole. This post will cover adding buttons for each row.

By the end of this post you will be able to add buttons such as this one:

ViewOnCalButton

Our example will look at the calls module. We’ll add a simple button to view the call on the calendar.

First off we will create a new non-db field in the calls module. We add the following file to custom/Extension/modules/Calls/Ext/Vardefs/ViewOnCalButton.php (we use the filename ‘ViewOnCalButton.php’ but this can be whatever you wish).

 

Next we add the language string for our new field. We place this file in custom/Extension/modules/Calls/Ext/Language/en_us.ViewOnCalButton.php:

 

In order to actually have the field display as a button we set up a logic hook to fill in the value. First we must define the logic hook in custom/Extension/modules/Calls/Ext/LogicHooks/ViewOnCal.php:

And then implement the hook itself and add it to custom/modules/Calls/ViewOnCalHook.php:

Note that we are creating a button which links to the calendar but this can do whatever actions you require. We must do a quick repair and rebuild from the admin menu in order for our changes above to take effect.

 

Finally we add the button to the list view. This can either be done in studio or by editing the list view defs. Let’s do this through studio:

ViewCalButton Studio

 

And there we have it. We now have the following:

ViewOnCalButton

 

Upon clicking we should be taken to the calendar.

 

Note that the above button is just an example and has a few issues that could be improved upon. If we click “View on calendar” for a call that isn’t ours we will be taken to a calendar page without the call on it. Can you see any other improvements? Let me know in the comments,

Car Reg Plate Game in Python

posted in: Games | 0

Me and my wife occasionally play a simple game when on longer car journeys. In the UK the last 3 characters in a car registration plate are letters.

by Cnbrb - Own work. Licensed under Public Domain via Wikimedia Commons.
by CnbrbOwn work. Licensed under Public Domain via Wikimedia Commons.

The aim of the game is to come up with words which start with the first letter, end with the last letter and contain the middle letter. So for the example plate in the image above we’d use SMR, a word that we could choose would be ‘speedometer (since it starts with s, ends with r and contains m’). Computers, unsurprisingly, are very good at this. Here’s an example of a super simple python script which prints matching words (this assumes you are on a Linux system, or at least a system with /usr/share/dict/words.

It can be called using python reg_plate_game.py "BD51 SMR". This example outputs the following:

salamander
samovar
sampler
scamper
scandalmonger
schemer
schmaltzier
schoolmaster
scimitar
scoutmaster
scrambler
scummier
seamier
seemlier
semester
semicircular
semiconductor
seminar
semitrailer
shimmer
shoemaker
similar
simmer
simper
simpler
simulator
skimpier
slammer
sledgehammer
slimier
slimmer
slumber
slummer
smacker
smaller
smarmier
smarter
smear
smellier
smelter
smoggier
smoker
smokier
smolder
smoother
smother
smoulder
smudgier
smugger
smuggler
smuttier
solemner
somber
spammer
speedometer
squirmier
stammer
stammerer
steamer
steamier
steamroller
stepmother
stormier
streamer
stumbler
stumpier
sublimer
submitter
summer
summerier
summoner
supercomputer
swampier
swimmer
sympathizer

Adding a button to the List View in SuiteCRM

posted in: SuiteCRM | 0

It’s possible to add your own action menu items to the List view. By the end of this post you’ll be able to add your own menu items like this one:

Custom List View Button

In our case we’ll be adding this to the “Calls” list view.

First off we add the string for the menu item text. In this case “New action”. We place this into `custom/Extension/modules/Calls/Ext/Language/en_us.CustomMenuAction.php` (the `CustomMenuAction` part can be anything you like.

 

 

Next we create a new custom list view for the calls module and place this in `custom/modules/Calls/views/view.list.php` (customising views can be found in my SuiteCRM book).

This does the actual work of adding the button. This adds a new bit of HTML to the array `$this->lv->actionsMenuExtraItems`. SuiteCRM will then pick this up and add this to the list of action buttons.

In this case the button just points to a new entry point `myNewEntryPoint`. Adding entry points will be covered in a future post (if you are impatient you can always checkout my SuiteCRM book).

Chase the ace – The curse of the dealer

posted in: Games | 0

Introduction

Chase the ace is a simple card game that I was taught when I was younger from my dad. Recently on holiday I was playing with some friends and for a few games it was always the dealer that was put out of the game first. We’d noticed this before and has dubbed it “The curse of the dealer”. I was curious to see if the curse had any basis or if it was just chance.

The rules

For those of you not familiar with Chase the Ace it is the simplest card game I know. Each player is dealt a card (the more players the better!). Play starts to the left of the dealer with each player deciding whether to keep his current card or to force the player on their left to swap with them. When play reaches the dealer they can choose to swap with the deck. After every player has had their turn the person (or persons) with the lowest card (Aces are low) is knocked out of the game. The next round starts again without the losing players until a player remains (or all players are knocked out).

Testing the curse

I created a simple python script to play a bunch of hands with 10 players and keep track of which player or players were knocked out first (the source of which can be found on GitHub.

 

The strategy played is pretty simple (so it may affect the outcome) and uses the following rules:

  • If a player swaps with us and we end up with a higher card then we always keep that card (since we are guaranteed to stay in).
  • If we have a card higher than a 7 keep it.
  • Otherwise swap.

Using 10 players for 10,000,000 hands gave the following results:

Position 0 1 2 3 4 5 6 7 8 9 Total
Loses 791547 1037209 1146774 1206951 1252666 1280194 1305464 1322220 1328504 1325231 11996760
% Loses 6.60 8.65 9.56 10.06 10.44 10.67 10.88 11.02 11.07 11.04

 

Conclusion

We can see that the dealer is indeed at a disadvantage and, in fact your odds of losing decreases as you get closer to early positions. I suspect that this is due to bad cards “bubbling up” through the positions. If you have a high card and are in later position you have a higher chance of losing it. I may revisit this code at some point and see if this code can be reused to generate an optional strategy.

Edit: Someone has pointed out that, in fact, it’s the second to last player that loses slightly more. I’m rerunning this with more games to see if this is chance or not – there may be a point where all players are equally disadvantaged.

 

SuiteCRM Push Notifications

posted in: SuiteCRM | 0

SuiteCRM Push Notifications is a package which adds push notifications using third parties as a possible workflow action. It currently only supports PushBullet.

Simply define your PushBullet API token for users that wish to receive notifications:

UserPage

Then create a new workflow with the user as the recipient (careful not to accidentally bomb yourself with notifications!):
PushAction

SuiteCRM Push Notifications is available on GitHub or on the SuiteCRM extensions directory.

SuiteCRM for Developers Released

posted in: SuiteCRM | 0

Intro

I work with SuiteCRM at my day job daily and have become quite experienced in it’s use, particularly customising and developing with SuiteCRM. However as a young project it lacks the wealth of resources that other projects have. Even the project from which it is forked could do better with documentation. There is docs, and some other good resources online but they take some searching for.

Enter SuiteCRM for Developers

I decided to write a book that covers some of the common development tasks that can be performed in SuiteCRM and provide a reference for making customisations. SuiteCRM for Developers is that book. It provides some of the knowledge that I have gathered from working with both SugarCRM and SuiteCRM and, hopefully, provides a good starting point for those wishing to develop with SuiteCRM.

Now released

I’m now pleased to announce that SuiteCRM for Developers has now been published on Leanpub. It’s available at an introductory rate of $14.99. I’m considering this version 1.0 and I plan to add additions and corrections. If there’s something you would like to see that I’ve missed or something that is wrong then feel free to Contact me.

 

SuiteCRM Custom Search Fields

posted in: SuiteCRM | 0

Intro

Sometimes you may want to add custom search fields to a module that do more than simply search a field. In this post we’ll be looking at how to add a custom search field which will allow searching for all accounts that have no associated contacts.

Adding the field

First off we create a copy of modules/Accounts/metadata/searchdefs.phpand place this in custom/modules/Accounts/metadata/searchdefs.php. We then add a new key to the $searchdefs ['Accounts']['layout']['basic_search']array which  will look something like:
We also need to add a language string for our new search field. This can be done by simply adding a new file at custom/Extension/modules/Accounts/Ext/Language/en_us.NoContactFilter.php:

This will give us the following:

NoContactSearchExample1

 

Unfortunately, SuiteCRM displays our new search field as a dropdown rather than a checkbox, stay tuned for a future post on how to change this.

 

Adding the logic

Now we have a wonderful search dropdown on our Accounts list view. It doesn’t actually do anything however. Let’s change that.

 

We create a copy of modules/Accounts/metadata/SearchFields.phpand place this in custom/modules/Accounts/metadata/SearchFields.php in exactly the same manner as we did for searchdefs.php above. We add our new search field to the $searchFields['Accounts']  array.

It should look something like:

This creates a subquery filter type. Specifying a query type of format allows us to use {0} in our query to access the dropdown value. SuiteCRM will only display account ids that match what our subquery returns.

SELECT accounts.id 
FROM accounts 
LEFT JOIN accounts_contacts ON (accounts.id = accounts_contacts.account_id AND accounts_contacts.deleted = 0)WHERE (NOT {0} AND accounts_contacts.id IS NOT NULL) OR ({0} AND accounts_contacts.id IS NULL)

We make use of this to force only accounts with contacts when “No” is selected (the NOT {0} AND accounts_contacts.id IS NOT NULL part of the query) and only accounts with no contacts when “Yes” is selected (the {0} AND accounts_contacts.id IS NULL part of the query).

Conclusion

Adding custom subqueries in this manner allows a huge amount of custom filters to be created. Have an idea for a custom filter? Have a better way of doing the above? Then let me know in the comments.

1 2