Wednesday, December 15, 2010

It is all in the details.

Before I got into the consulting world, I worked at a CRM vendor where I had the fortune of working alongside some very talented individuals.  

There was a special level of understanding within the group that facilitated many tasks, especially when it came to elaborating new features to the development team.  Given this special synergy, communication amongst team members tended to be rather efficient, virtually eliminating the need for long, drawn out meetings that would usually make us want to stab our eyes out.  

Unfortunately, environments like this are not common place and simultaneously, the nature of software development requires clear and efficient communication amongst the parties involved.  Lacking this communication usually results in one of two things (or both):
  • Unexpected delays
  • Undesired results
In the world of software development, one cannot afford to leave requests open to interpretation or one might not get what was envisioned, and correcting problems will usually result in missed deadlines.  

Perhaps you are wondering about the relevance of these points to the CRM consulting world.  Allow me to explain.

Monday, December 13, 2010

You are not seeing double.

A few days ago I got reacquainted with an issue I had previously run into, but forgotten about.  Lets talk a little bit about the issue first, and then its solution. 

From time-to-time, the need to retrieve a list of SugarCRM users via the SOAP API presents itself.  For example, my CRM SkyDialer tool allows one to schedule an activity and as part of that process, one is allowed to select the user to whom the activity is assigned.

That list of users is dynamically generated by means of a call to the get_entry_list() method.  Now, for the problem.

When calling the get_entry_list() method, one has the ability to limit the records returned by specifying a WHERE clause as a parameter.  Logic would dictate that if one wanted a complete list of all active users within the instance of SugarCRM in question, the following WHERE clause would provide the desired results:

users.status = 'Active' AND users.deleted = 0

So far, so good, but somewhere in the life cycle of SugarCRM (version 5.5.1 is my best guess), a change was made to the relevant code that is responsible for providing the results.  This change in turn causes a problem when executing the get_entry_list() method with the above clause.  

If it does not provide the proper results, what exactly happens?

Sunday, November 7, 2010

My Two Rules of Logic Hooks

As you may have ascertained from prior posts, something about the logic hooks feature really draws my attention.  I think a lot of it has to do with the fact that the main limit on its capabilities is one's creativity and that power is quite appealing.

Regardless of the reason or the intended purpose of the logic hook, there are a couple of rules that I've learned one should always adhere to in order to avoid problems.

Curious about what they are?  Keep reading.

Wednesday, September 22, 2010

At The Top Of The List...

As you might have already guessed, a large part of my day-to-day CRM consulting work involves me asking questions.  Here is a small sampling of some common ones:

  • Where do you store your leads?
  • How are you tracking your sales?
  • Can you describe your marketing processes?

This line of questioning helps me get a better grasp on the intended goals for the CRM implementation.  I then translate this information into functionality contained within software packages such as SugarCRM and voila! we have a CRM system.

Conversely, clients tend to also present a wide range of questions and covering a variety of topics, some more technical than others, but all equally interesting.  One question in particular that I often times encounter is the following:

Which CRM system is best?

Thursday, September 16, 2010

SugarCRM Cookbook: .NET and Dates

A user of my CandyWrapper library recently requested some help addressing a problem they were experiencing with the insertion of dates into SugarCRM via C#.

After some investigation, I identified the source of the problem was the format in which the date was being submitted to the SugarCRM SOAP API.  

The interaction reminded me of the frequency at which this particular problem appears within the SugarCRM Forums.  Its actually rather understandable as there isn't much documentation covering the subject.  

If you are also a C# developer, the code snippet that solved the problem is provided below:

01 DateTime dtTemp = System.DateTime.Now;
02 dtTemp = TimeZone.CurrentTimeZone.ToUniversalTime(dtTemp);
03 string sDate = String.Format("{0:yyyy-MM-dd HH:mm:ss}", dtTemp);

This is the standard way in which I handle dates in my C# projects, but there is a special twist to my code which is worth highlighting and might help save you some additional frustration in your projects.

Let us analyze it, line by line.

Wednesday, September 15, 2010

CandyWrapper 101: Why Use It?

One of my more popular contributions to the SugarCRM community is something I've dubbed CandyWrapper.  If you are not familiar with it, give its project page a look over at

The basic premise for its existence is to help minimize the amount of work required to interact with the SugarCRM SOAP API when programming in .NET.  It accomplishes this task by minimizing the amount of code a programmer needs to write in order to interact with the SugarCRM SOAP API.

Second to this, it eliminates the need to know intricacies of the SugarCRM SOAP API.  This is helpful for developers that may be well versed in .NET languages such as C#, but perhaps have never worked with SugarCRM's API.  Rather than having to sift through documentation and tedious trial-and-error scenarios to determine the manner in which the SugarCRM SOAP API expects things, CandyWrapper presents a standard approach and does all the dirty work behind the scenes.

But, exactly what does that mean?  

Let us take a quick look at a C# example to illustrate the advantages of using CandyWrapper.  Within it we will take a look at both the standard C# code one would use without CandyWrapper and of course, we will also look at code that takes advantage of it.  

Wednesday, September 8, 2010

SugarCRM Stack Installers: Yay or Nay?

Interested in installing SugarCRM to try it out for yourself?  Great, however, determining which are the appropriate files to download might be a bit confusing.  

In case you are wondering why, take a minute to browse the SugarCRM download page.  If you are unsure about which file to download, the Download Wizard is a useful tool that will guide you through the selection process.  

If, however, you are just browsing around, you might note that some of the available choices are labeled with the tag "FastStack."  These differ from the main install package--usually named or the like--in that they are intended to simplify the process of installing not only Sugar, but also the underlying technologies on which it relies, i.e. PHP, MySQL/MS-SQL and Apache.  

If the idea is to simplify the process, why wouldn't that simply be the default or only install method?  

Friday, September 3, 2010

SugarCRM 101: How Do I Manage Multiple Businesses?

I realized the other day that too much of the content on this blog tends to be rather technical.  While helpful, there are also a number of topics worth discussing that don't fall into that category and are often quite valuable to new users or prospects.  A recent message on the SugarCRM Forums from a potential user reminded me of that very point.

The question was rather short and simple: can I use SugarCRM to manage multiple businesses?

Some folks will argue that it is possible, and it certainly is through the manipulation and creative use of built in security features and customization tools.  However, SugarCRM is not specifically designed with that concept in mind and attempting to use it for such purposes can quickly lead to problems.  

Saturday, August 28, 2010

SugarCRM Server Migrations Demystified

Perhaps one of the more interesting administrative tasks you might be required to undertake as a SugarCRM administrator is that of moving your installation from one server to another.  Your reason for needing to do this will likely relate to the retirement of the current server or perhaps simply moving from a hosted environment to an in house deployment.

Regardless, what makes the task interesting is the perceived complexity one might face in accomplishing the task. However, there is no reason to be nervous or worry.  Many of the potential challenges can be attributed to a handful of issues, mostly related to system configuration.

Let us begin with the most common issue: PHP configuration.

It is unlikely that the software configuration of the new server is an exact match of the system from which you are moving away.  This may seem like a minor issue, but in reality, this is the most common oversight in these type of operations.  To avoid the frustrations (and lost time) such an oversight might cause, you should first check the version of PHP and configuration (PHP.INI) on the new server and make sure that it is compatible with the version of SugarCRM you are currently using.  

A list of compatible versions of PHP, per SugarCRM version, is available on the SugarCRM web site.  Your findings might require you to either downgrade or upgrade the version of PHP on the new server prior to migrating the instance.

Often times administrators get themselves into trouble because in addition to migrating the instance to a new server, they also want to simultaneously upgrade SugarCRM to its most recent version.

Tuesday, August 10, 2010

SugarCRM Troubleshooting: SMTP Problems on Hostgator

Here is a good example of a problem where its source could have more easily been discovered by having shell (or similar) access to the server hosting SugarCRM.

While in the process of attempting to configure SugarCRM to use a GMail account, the following error was continually encountered: 

Can't connect to '{}' as user '' with password 'xxx': Can't connect to,993: Connection refused.  

Changing user names, passwords, etc. all resulted in the same error. However, using the same credentials on a locally installed copy of the same version of SugarCRM worked flawlessly.

Things got more mysterious when the output of phpinfo() on both systems appeared to match each other, thus eliminating a previously encountered problem I detailed in an earlier post. Having eliminated all other variables, I was left with one final one: connectivity/firewall issues.

Wednesday, July 21, 2010

SugarCRM Unable to Open a Required File??

Does this error look familiar to you? 

Fatal error: SugarBean::require_once() [function.require]: Failed opening required '' (include_path='C:\xampp\xampp\htdocs\sugarce55\include/..;.;C:\xampp\xampp\php\pear\') in C:\xampp\xampp\htdocs\sugarce55\data\SugarBean.php on line 3367 

I ran into the above error a few days ago when accessing the ListView for Tasks. Seemed rather puzzling as it had worked without errors just 2 - 3 minutes prior to that. I should point out this occurred on my development system, so there weren't any other users logged into SugarCRM that could have in turn broken something. 

Anyway, I quickly realized that when it did work, the Tasks table was empty. Seemed like a strange error for it to be related to data, but that's where things were pointing.

Wednesday, July 14, 2010

Release Time - SugarCRM 6.0

Yesterday, the good folks at SugarCRM announced the General Availability of version 6.0 of its flagship product, SugarCRM.

Although some folks I interact with are eager to upgrade, I generally recommend folks wait 3 - 4 months AFTER the initial release of ANY software package before considering it production ready.  That statement has a tendency to draw some fire, as people like to point out that since SugarCRM itself has stated it is ready for use by the masses, it should be fine.  

Allow me to explain my reasons, in hopes of also helping you avoid some headaches.   

Monday, June 14, 2010

SugarCRM Troubleshooting: Install Time Problems

Sometimes weird things happen for a reason.  Here is a good example.

A few days ago, I decided to reset the database for a test installation of SugarCRM 5.5 that I have on my laptop.  By that I mean that I ran the installer again, my goal being to cause it to overwrite the already existing database.  My reason for doing so is that I wanted the demo data to test something for a project I was working on.

For those of you wondering how I went about getting the installer to run again, all I did was edit my config.php file and changed this:

'installer_locked' => true,


'installer_locked' => false,

That modification to config.php allows one to run the installer again although the installation may already be operational.  Obviously you wouldn't want to do this on a regular basis as this process could potentially cause you to accidentally delete your SugarCRM data, but it does have its uses and thus is helpful to know.

Now, back to my situation.  After changing my config.php file, I proceeded to walk through the installation process as normal.  I filled in the various fields with the appropriate data and continued through the installation wizard without any problems.

Problems, however, did arise when I got to the final stage of the installation wizard while creating the database.

Friday, June 4, 2010

SugarCRM Customization: Read-only Fields

It is no secret that I am a big fan of the ease of which the SugarCRM framework facilitates a number of customizations.

A few months back I shared a simple example that demonstrated said simplicity quite well through a customization of the search popup windows. Let us take a look at another equally simple and useful modification.

This time around we are going to look at something just as easy, but serving a completely different purpose.

In this scenario we will assume that we have a need to create a read-only field, one that cannot be edited via the SugarCRM interface.  This is helpful for scenarios where records may contain important data that should not be changed by any user.  A good example of this is financial data from external systems, such as your ERP solution.

Because this data is coming from another system, it is usually input into SugarCRM by means of a link or other programmatic approach that eliminates the need for the user to actually enter the data by editing the record.

Allowing users to manipulate the values would create the potential for faulty analysis.  For example, if one of the values relates to a customer's outstanding balance, a user could accidentally (or purposely) increase or decrease it, in turn misleading the next person that views said record.  Hence the value of using a read-only field.

Converting a field into a read-only field is quite simple.  Read on to see the step-by-step instructions.

Monday, May 3, 2010

Database Administration via SugarCRM Framework

Recently I found myself in a situation that required me to delete a large amount of records from a SugarCRM database.  More to the point, I needed to delete all the account and contact records.

Under normal circumstances, the task would have been rather simple.  One approach that would normally work would be to simply select all the records via the ListView and then delete the records.  A second -- and faster --- approach would be to simply truncate the table via a MySQL database administration tool such as SQLyog or phpMyAdmin.

Notice I stated "normal circumstances."  

My scenario was such that the environment hosting the SugarCRM instance in question did not allow me to select all the records and then delete them.  Due to number of records that needed to be processed (over 70K), the system tended to time out and fail.  Smaller batches was simply not going to work as it was taking a minute or more to process 200 contacts.  At that pace, it would have taken me hours to delete the entire batch of records just in one module.  

You may be wondering why I even bothered with the ListView when the SQLyog/phpMyAdmin option would have been far easier and faster.  The answer is actually equally simple.  Much like many other hosting providers, this one in particular does not provide a means for connecting directly to the database via external tools.  It is further complicated by the fact that similar tools could not be installed -- nor were available -- on the server, nor was I able to access the file system.

I am stuck, right?

Well, not quite.  After giving it some thought for a few minutes, I realized I could manipulate the SugarCRM framework to get it to do what I needed, although it is not really designed for the task I had in mind.

Let us take a look at how I solved this particular problem.

Tuesday, April 27, 2010

SugarCRM Troubleshooting: IMAP Connectivity

You may have read my previous post from a few months ago where I discuss a potential scenario that may keep you from being able to use the SugarCRM email client for IMAP accounts that require SSL.

While troubleshooting similar connectivity issues, I have found it helpful to use some PHP scripts to perform the basics of verifying that the server is actually capable of connecting to the mail server.  

Assuming we cannot connect through the scripts, it would make sense that we would also not be able to connect via SugarCRM.  

Some of the common reasons for not being able to connect include:
  • Firewall restrictions
  • Missing PHP extensions (e.g. IMAP)
  • Incorrect account information 
Should any of those (or other) conditions exist, the scripts will fail and you know you need to look elsewhere for your solution, instead of within SugarCRM.

Thursday, February 18, 2010

SugarCRM Customization: Styled Data

Want to make something stand out on the DetailView of your records? Here is a quick way of doing that: add some CSS styling to it.

The best part is that it is very simple to apply this effect.  In order to apply styling to a value (say, to make it show up in red) for a field named interest_c, add the following line to the field's definition array in detailviewdefs.php stored in custom/modules/Contacts/metadata

'customCode' => '<span style="color: red">{$fields.interest_c.value}</span>',

SugarCRM Logic Hook: Proper Casing Fields

Sorry for my absence. Been meaning to write, but been caught up with other cool things.  Anyway, wanted to post a quick and easy one that many might find helpful. 

One of the biggest challenges with a database application such as SugarCRM is ensuring that data is entered in a uniform manner by its various users. The use of drop down and multi-select fields helps address this challenge quite well, but said field types cannot be used in all places. 

A good example of where they cannot be used is the Last Name field on a Contact entry. However, at the same time, it would be nice to be able to enforce some uniformity in the field's values, for example, ensure that names are being entered in proper case.  

This need provides us with a great opportunity to once again highlight the power of logic hooks. In our example, the uniformity we want to introduce is the proper casing of the text entered into the Last Name field. Thus, values that are typed in as "doe" are automatically corrected and saved to the database as "Doe."

A logic hook is the perfect solution as it is transparent to the user and easily extended to support other fields.

Lets take a look at how we can accomplish the above...