<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Systems Consciousness &#187; Tutorials</title>
	<atom:link href="http://systemsconsciousness.com/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://systemsconsciousness.com</link>
	<description></description>
	<lastBuildDate>Sat, 07 Aug 2010 15:47:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Google Fusion Tables and Charts Example</title>
		<link>http://systemsconsciousness.com/2010/06/04/google-fusion-tables-and-charts-example/</link>
		<comments>http://systemsconsciousness.com/2010/06/04/google-fusion-tables-and-charts-example/#comments</comments>
		<pubDate>Fri, 04 Jun 2010 21:15:48 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Government]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Fusion Tables]]></category>
		<category><![CDATA[Google Charts]]></category>
		<category><![CDATA[Google Maps]]></category>

		<guid isPermaLink="false">http://systemsconsciousness.com/?p=34383</guid>
		<description><![CDATA[Google Fusion Tables and Google Maps example]]></description>
			<content:encoded><![CDATA[<p>I was at the <a href="http://personaldemocracy.com">Personal Democracy Forum</a> this week and had a nice chat with an engineer from the Google Maps team. He told me about <a href="http://tables.googlelabs.com/Home">Google Fusion Tables</a>. </p>
<p>Welcome to the future, everyone. Just let it sink in a little&#8230;</p>
<h2>United States &#8211; Percentage of Population on Facebook in 2009</h2>
<p><script src="http://www.gmodules.com/ig/ifr?url=http://www.google.com/ig/modules/geomap.xml&#038;up__table_query_url=http://tables.googlelabs.com/gvizdata?tq=select+gvizregion(col0)%252Ccol3%252Ccol0+from+113794++skip+0+limit+50&#038;up__table_query_refresh_interval=0&#038;up_region=US&#038;up_dataMode=regions&#038;w=625&#038;h=400&#038;border=%23ffffff%7C3px%2C1px+solid+%23999999&#038;synd=open&#038;output=js"></script></p>
<p>Tables are essentially just spreadsheets in their presentation. But in function they are actually more like SQL tables that you interact with via an API. You can store your own data on here and interact with it&#8211;read: you really don&#8217;t need a local SQL installation on your web server to create powerful web apps. Perhaps the most interesting thing of all is that there are also public tables, many of which include valuable socially and politically relevant data.</p>
<p>From within the Google Fusion tables account, you can also generate on-the-fly interactive charts, graphs and maps.</p>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2010/06/04/google-fusion-tables-and-charts-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SugarCRM Hack: Collapse Subpanels by Default</title>
		<link>http://systemsconsciousness.com/2010/04/09/sugarcrm-hack-collapse-subpanels-by-default/</link>
		<comments>http://systemsconsciousness.com/2010/04/09/sugarcrm-hack-collapse-subpanels-by-default/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 13:39:18 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[Hacks]]></category>
		<category><![CDATA[SugarCRM]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Subpanels]]></category>

		<guid isPermaLink="false">http://systemsconsciousness.com/?p=14469</guid>
		<description><![CDATA[You&#8217;re never going to roll out that CRM properly if your users are intimidated. SugarCRM is powerful stuff, but to some its many features can be overwhelming until you really get a feel for it. One hack that I just stumbled upon&#8211;while taking a break from resolving another problem with subpanels&#8211;is this handy little gem [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;re never going to roll out that CRM properly if your users are intimidated. SugarCRM is powerful stuff, but to some its many features can be overwhelming until you really get a feel for it. One hack that I just stumbled upon&#8211;while taking a break from resolving another problem with subpanels&#8211;is this handy little gem that collapses all subpanels by default.</p>
<p>There are a couple methods for this actually. One modification collapses subpanels by default, stores which ones are expanded during a user&#8217;s session, and then resets them to collapsed on the next login. The other method, and the one I prefer, is to collapse all subpanels by default, but also keep expanded subpanels open on the next login. I think most users will prefer the latter option, but I encourage you to experiment and share your feedback below. (These snipits come from <a href="http://www.sugarcrm.com/wiki/index.php?title=How_to_set_sub-panels_to_be_collapsed_by_default" target="_blank">this SugarCRM&#8217;s wiki post</a>.)</p>
<h2><span>To have all sub-panels collapsed by  default</span></h2>
<p>With the following code, all sub-panels are collpased by default.   Sub-panels that have been opened by the user will stay open through the  session, but once the user logs out, all sub-panels will be collapsed on  their next login.</p>
<p>Edit config_override.php (if it doesn&#8217;t exist, create it in Sugar&#8217;s root  directory) to include the following code:</p>
<pre>// Always hide subpanels when a user views a detail record
$sugar_config['hide_subpanels'] = true;

//When a user first visits a detail view hide all subpanels for a module. Then whatever subpanels are opened in that module stay open throughout the session regardless of what the record id is.
$sugar_config['hide_subpanels_on_login'] = true;</pre>
<h2><span>To have all sub-panels collapsed by  default except the user&#8217;s chosen sub-panels</span></h2>
<p>With the following code, all sub-panels are collapsed by default on  initial login.   Sub-panels that have been opened by the user will stay  open through the session, and will be automatically expanded every time  the user logs in.</p>
<p>Note:  This change is not upgrade safe, and may need to be repeated  after patching or upgrading an instance.</p>
<p>Edit the include/Subpanel/SubPanelTiles.php file.  Locate the following  code:</p>
<pre>    $tabs = array();
    $default_div_display = 'inline';
    if(!empty($sugar_config['hide_subpanels_on_login'])){
    if(!isset($_SESSION['visited_details'][$this-&gt;focus-&gt;module_dir])){
    setcookie($this-&gt;focus-&gt;module_dir . '_divs', '' );
    unset($_COOKIE[$this-&gt;focus-&gt;module_dir . '_divs']);
    $_SESSION['visited_details'][$this-&gt;focus-&gt;module_dir] = true;

    }
    $default_div_display = 'none';
    }
    $div_cookies = get_sub_cookies($this-&gt;focus-&gt;module_dir . '_divs');</pre>
<p>Replace the above with the following code:</p>
<pre>    $tabs = array();
    $default_div_display = 'inline';
    if(!empty($sugar_config['hide_subpanels_on_login'])){
    if(!isset($_SESSION['visited_details'][$this-&gt;focus-&gt;module_dir])){
    setcookie($this-&gt;focus-&gt;module_dir . '_divs', '' );
    unset($_COOKIE[$this-&gt;focus-&gt;module_dir . '_divs']);
    $_SESSION['visited_details'][$this-&gt;focus-&gt;module_dir] = true;

    }
    $default_div_display = 'none';
    }

    //Have the subpanel choices saved between sessions
    //If 'hide_subpanels_session_only' is set to 'true' then the old functionality is retained
    if(empty($sugar_config['hide_subpanels_session_only'])){
    $up_cookies=$current_user-&gt;getPreference('subpanel_cookie_'.$this-&gt;focus-&gt;module_dir);
    }
    $div_cookies = get_sub_cookies($this-&gt;focus-&gt;module_dir . '_divs');
    if(!empty($up_cookies)) {
    if(empty($div_cookies)) {
    $div_cookies=$up_cookies; //If there are no cookies, then use the UserPrefs copy of the previous cookie
    }
    }
    if(empty($sugar_config['hide_subpanels_session_only'])){
    //Save a copy of the cookie to the UserPrefs so that any new choices get saved
    $current_user-&gt;setPreference('subpanel_cookie_'.$this-&gt;focus-&gt;module_dir, $div_cookies, 0, 'global', $current_user);
    }</pre>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2010/04/09/sugarcrm-hack-collapse-subpanels-by-default/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Want Google Buzz to Buzz Off? Here&#8217;s How to Disable Connected Sites</title>
		<link>http://systemsconsciousness.com/2010/03/03/want-google-buzz-to-buzz-off-heres-how-to-disable-connected-sites-in-google-buzz/</link>
		<comments>http://systemsconsciousness.com/2010/03/03/want-google-buzz-to-buzz-off-heres-how-to-disable-connected-sites-in-google-buzz/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 19:50:39 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Buzz]]></category>
		<category><![CDATA[Help]]></category>

		<guid isPermaLink="false">http://systemsconsciousness.com/?p=2300</guid>
		<description><![CDATA[One of my coworkers is easily the most prolific Google Buzzer I know. So when she mentioned to me a few days ago that she doesn&#8217;t like Buzz I was more than a little perplexed about her seemingly high number of posts. (Or are they called Buzzes? Someone please help me with the nomenclature.)
As it [...]]]></description>
			<content:encoded><![CDATA[<p>One of my coworkers is easily the most prolific Google Buzzer I know. So when she mentioned to me a few days ago that she doesn&#8217;t like Buzz I was more than a little perplexed about her seemingly high number of posts. (Or are they called Buzzes? Someone please help me with the nomenclature.)</p>
<p>As it turns out, she&#8217;s yet to figure out how to disable the automatic posting of Tweets and other such &#8220;Connected Sites,&#8221; which seems to have the default setting of integrating everything. Well, <a href="http://postmatterpostings.wordpress.com/" target="_blank">Nadia</a>, this one&#8217;s for you and everyone else out there who would rather read instructions than click around and break stuff. (Webbies around the world salute you.)</p>
<p>Removing integration for Google Buzz&#8217;s &#8220;Connected Sites&#8221; feature/annoyance is easy. Just follow these steps:</p>
<ol>
<li>While logged into your GMail, click on Buzz.</li>
<li>At the top of the page, you&#8217;ll see your personal Buzz area&#8211;the place where you would type a post. Click on<em> Connected Sites </em>near your name. A tasteful lightbox window pops up.</li>
<li>Click on <em>Edit</em> and then <em>Remove Site</em> on any and all of the Connected Sites you want to remove.</li>
<li>Click <em>Save</em> at the bottom.</li>
</ol>
<p>That&#8217;s all there is to it! Happy buzzing, <a href="http://postmatterpostings.wordpress.com/" target="_blank">Nadia</a>.</p>
<p>Oh, and do visit her blog at <a href="http://postmatterpostings.wordpress.com/" target="_blank">postmatterpostings.wordpress.com</a> because it&#8217;s pretty awesome.</p>
<p style="padding-left: 30px;">
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2010/03/03/want-google-buzz-to-buzz-off-heres-how-to-disable-connected-sites-in-google-buzz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SugarCRM SOAP Examples Pt. 3: Upload a File via SOAP API</title>
		<link>http://systemsconsciousness.com/2009/11/24/sugarcrm-soap-examples-pt-3-upload-a-file-via-soap-api/</link>
		<comments>http://systemsconsciousness.com/2009/11/24/sugarcrm-soap-examples-pt-3-upload-a-file-via-soap-api/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 19:56:53 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[SugarCRM]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://systemsconsciousness.com/?p=1055</guid>
		<description><![CDATA[This is my third tutorial on the SugarCRM SOAP API. It&#8217;s slightly more advanced than the last two, so if you are new to the SOAP API, you should probably start with this one. If you are looking for more tutorials on SugarCRM SOAP API, (as always) LornaJane&#8217;s blog is a great intro, and the [...]]]></description>
			<content:encoded><![CDATA[<p>This is my third tutorial on the SugarCRM SOAP API. It&#8217;s slightly more advanced than the last two, so if you are new to the SOAP API, you should probably start with <a href="http://systemsconsciousness.com/2009/04/10/sugarcrm-soap-examples/" target="_self">this one</a>. If you are looking for more tutorials on SugarCRM SOAP API, (as always) <a href="http://www.lornajane.net/posts/2008/SugarCRM-SOAP-API-Examples" target="_blank">LornaJane&#8217;s blog</a> is a great intro, and the <a href="http://developers.sugarcrm.com/" target="_blank">Sugar Developer Forum</a> is tops. Enough plugs. Let&#8217;s get started! (And if you find the post useful, please visit one of my sponsors!)<br />
<script type="text/javascript">// <![CDATA[
 google_ad_client = "pub-7782798142568592"; /* systemsconsciousness - wide */ google_ad_slot = "2308144452"; google_ad_width = 468; google_ad_height = 60;
// ]]&gt;</script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
</script></p>
<p>Today I&#8217;m going to write about sending a file attachment to SugarCRM via the SOAP API. The setup, as in previous posts, is a LAMP web server running our main web site on WordPress&#8211;and the cForms plugin to process form input data. You don&#8217;t need cForms, but it&#8217;s a great plugin that will help you manage multiple types of forms on your WordPress site. It also has its own API, which allows you to run PHP code when a form is submitted. If you&#8217;re not using WordPress or cForms, that&#8217;s ok, too.</p>
<p>I&#8217;m going to skew the code for the non-WordPress users. But it will be almost identical if you are using WordPress/cForms. You&#8217;ll just need to substitute in the cForms variables. For easy setup, create a simple POST form with text fields of my_form_firstname and my_form_lastname, and with a file field.</p>
<p>We&#8217;re going to send a document through the web form on our web server to a Sugar server (which is also a web server, but you get the idea).</p>
<p>To begin, we&#8217;ll need to initialize our SOAP connection. This means connect to the Sugar server from our web server with our IP, username and password. The code (again) looks like this:</p>
<blockquote><p>$location = &#8216;http://YOUR.SUGARSERVER.WEB.ADDRESS/yoursugarcrmdirectory/soap.php&#8217;;</p>
<p>// set up options array with SugarCRM location, etc<br />
$options = array(<br />
&#8220;location&#8221; =&gt; $location,<br />
&#8220;uri&#8221; =&gt; &#8216;http://www.sugarcrm.com/sugarcrm&#8217;,<br />
&#8220;trace&#8221; =&gt; 1<br />
);</p>
<p>// user authentication array<br />
$user_auth = array(<br />
&#8220;user_name&#8221; =&gt; &#8216;YOUR_USERID&#8217;,<br />
&#8220;password&#8221; =&gt; MD5(&#8216;YOUR_PASSWORD&#8217;),<br />
&#8220;version&#8221; =&gt; &#8216;.01&#8242;<br />
);</p>
<p>// connect to soap server<br />
$client = new SoapClient(NULL, $options);</p>
<p>// Login to SugarCRM<br />
$response = $client-&gt;login($user_auth,&#8217;SOME_KEY&#8217;);</p>
<p>$session_id = $response-&gt;id;</p>
<p>$user_id = $client-&gt;get_user_id($session_id);</p>
<p>print_r($response);</p></blockquote>
<p>The last line can be commented out. It&#8217;s just there to indicate to you that your connection was successful. If it wasn&#8217;t successful, make sure:</p>
<ul>
<li>Your username and password are correct.</li>
<li>The URL for your Sugar server is correct.</li>
<li>Your user has access to write to the Contacts and Notes modules.</li>
<li>Your firewall has a web port open.</li>
</ul>
<p>If it worked, great! Let&#8217;s move on to the next step. (If not, hit up Google!) Let&#8217;s add data to a module. In this case, we&#8217;re going to use the Contacts module because it already has a built-in many-to-many relationship to the Notes module, where our attachment will ultimately reside&#8211;linked to our Contact! Here&#8217;s the code to write some data to the Contacts module:</p>
<blockquote><p>$response = $client-&gt;set_entry($session_id, &#8216;Contacts&#8217;, array(<br />
array(&#8220;name&#8221; =&gt; &#8216;first_name&#8217;,&#8221;value&#8221; =&gt; $_POST['my_form_firstname']),<br />
array(&#8220;name&#8221; =&gt; &#8216;last_name&#8217;,&#8221;value&#8221; =&gt; $_POST['my_form_lastname']),<br />
array(&#8220;name&#8221; =&gt; &#8216;assigned_user_id&#8217;,&#8221;value&#8221; =&gt; $user_id)<br />
));</p></blockquote>
<p>Simple enough. When you run this code, combined with the code above, you should find a new contact in your Contacts module. If you get in trouble, var_dump() and print_r() will be your best friends. Our next step will be to grab the uploaded document and insert it into the Notes module:</p>
<blockquote><p>$insert_contact_id = $response-&gt;id;</p>
<p>// create the note<br />
$response = $client-&gt;set_entry($session_id, &#8216;Notes&#8217;, array(<br />
array(&#8216;name&#8217;=&gt;&#8217;name&#8217;,'value&#8217;=&gt;$_POST['my_form_firstname'].&#8217; &#8216;.$_POST['my_form_lastname'].&#8217; Document&#8217;),<br />
array(&#8216;name&#8217;=&gt;&#8217;description&#8217;,'value&#8217;=&gt;&#8217;An attachment for &#8216;.$_POST['my_form_firstname'].&#8217; &#8216;.$_POST['my_form_lastname']),<br />
array(&#8216;name&#8217;=&gt;&#8217;parent_type&#8217;,'value&#8217;=&gt;&#8217;Contacts&#8217;),<br />
array(&#8216;name&#8217;=&gt;&#8217;parent_id&#8217;,'value&#8217;=&gt;$insert_contact_id)<br />
));</p>
<p>$note_id = $response-&gt;id;</p></blockquote>
<p>Note the first and last lines. Every time you issue a $response call, that is, when you reference your SoapClient class, you get a new $response-&gt;id. This way you can interact with SOAP at different stages in your application. In this instance, first we wrote a new Contact to Sugar, then we&#8217;re getting the $response-&gt;id of this call to create and attach a Note to the Contact. This occurs in this little bit above:</p>
<blockquote><p>array(&#8216;name&#8217;=&gt;&#8217;parent_type&#8217;,'value&#8217;=&gt;&#8217;Contacts&#8217;),<br />
array(&#8216;name&#8217;=&gt;&#8217;parent_id&#8217;,'value&#8217;=&gt;$insert_contact_id)</p></blockquote>
<p>Then, likewise, we get the $note_id, which is the $response-&gt;id for the Note attachment.</p>
<p>What we&#8217;ve yet to do at this point is get our file from our form and upload it as an attachment to the Notes record that we just created. If you&#8217;re not familiar with uploading documents via PHP and forms, then you&#8217;ll want to brush up on that. If you&#8217;re using cForms especially this will be very helpful because cForms requires you to be a little bit more strict with how you work with files than, say, if you&#8217;re just working with your own ground-up app. What I mean is&#8211;you need to know what the difference is between tmp_name, name and so forth.</p>
<p>Here we go&#8230; we&#8217;re going to get the target path of the file, open it to get its content, and then close it:</p>
<blockquote><p>// get the path from of your file<br />
$target_path = $_FILES['my_form_file']['tmp_name'][0];</p>
<p>// Un-comment this code to see if the file exists<br />
//if (file_exists($target_path)) {<br />
//echo &#8220;The file &#8220;.$_FILES['my_form_file']['name'][0].&#8221; exists&#8221;;<br />
//} else {<br />
//echo &#8220;The file &#8220;.$_FILES['my_form_file']['name'][0].&#8221; does NOT exist&#8221;;<br />
//}$fp = fopen($target_path, &#8216;rb&#8217;);<br />
$file = base64_encode(fread($fp, filesize($target_path)));<br />
fclose($fp);</p></blockquote>
<p>Our final step is going to be to attach (and relate) the file to the new record in the Notes module. See what we&#8217;re doing? Creating a Contact, relating a Note to it, and relating an attachment to that Note. Exciting! This code is simple. If you are convinced the above is working, proceed by adding this:</p>
<blockquote><p>//create the attachment that you will put into sugar<br />
$attachment=array(<br />
&#8216;id&#8217;=&gt;$note_id,<br />
&#8216;filename&#8217;=&gt;$_FILES['my_form_file']['name'][0],<br />
&#8216;file&#8217;=&gt;$file<br />
);</p>
<p>$response = $client-&gt;set_note_attachment($session_id,$attachment);</p></blockquote>
<p>By now you should be getting the hang of it. We&#8217;re creating an attachment just like we created the other two records. The $note_id variable will tell the attachment record which Note to relate to. The Note, remember, is already attached to our Contact. Then we&#8217;re using the set_note_attachment() function to put the attachment on the server.</p>
<p>That&#8217;s all there is to it!</p>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2009/11/24/sugarcrm-soap-examples-pt-3-upload-a-file-via-soap-api/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SugarCRM, cForms and PHP Date Format</title>
		<link>http://systemsconsciousness.com/2009/11/02/sugarcrm-cforms-and-php-date-format/</link>
		<comments>http://systemsconsciousness.com/2009/11/02/sugarcrm-cforms-and-php-date-format/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 15:39:53 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[SugarCRM]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cForms]]></category>
		<category><![CDATA[Date Format]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://systemsconsciousness.com/?p=1050</guid>
		<description><![CDATA[Something that has been plaguing my SugarCRM SOAP API implementation: inserting dates into the Leads module.
Just as in any other module, we have at least one date field. In this case, an &#8220;Expected Start Date&#8221; field for various fee-for-service inquiries is the culprit. Our original insert code for this field looked like this:
array(&#8220;name&#8221; =&#62; &#8216;expected_start_date_c&#8217;,&#8221;value&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>Something that has been plaguing my SugarCRM SOAP API implementation: inserting dates into the Leads module.</p>
<p>Just as in any other module, we have at least one date field. In this case, an &#8220;Expected Start Date&#8221; field for various fee-for-service inquiries is the culprit. Our original insert code for this field looked like this:</p>
<blockquote><p>array(&#8220;name&#8221; =&gt; &#8216;expected_start_date_c&#8217;,&#8221;value&#8221; =&gt; $POSTdataClean['cf2_field_18']),</p></blockquote>
<p>This didn&#8217;t work though because the date that&#8217;s coming in from cForms is of the format MM/DD/YYYY. What Sugar expects though is, &#8220;YYYY-MM-DD H:M:S.&#8221; So if you are going to insert a date into Sugar via the SOAP API, and you want it to work, you will want to use the following code:</p>
<blockquote><p>array(&#8220;name&#8221; =&gt; &#8217;start_date_c&#8217;,&#8221;value&#8221; =&gt; date(&#8216;Y-m-d H:i:s&#8217;, strtotime($POSTdataClean['cf2_field_18']))),</p></blockquote>
<p>If you&#8217;re looking for a deeper explanation, check out the PHP manual for <a href="http://php.net/manual/en/function.strtotime.php" target="_blank">strtotime</a> and <a href="http://php.net/manual/en/function.date.php" target="_blank">date</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2009/11/02/sugarcrm-cforms-and-php-date-format/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sync iPhone with Google Calendar: The Missing Link</title>
		<link>http://systemsconsciousness.com/2009/09/17/sync-iphone-with-google-calendar-the-missing-link/</link>
		<comments>http://systemsconsciousness.com/2009/09/17/sync-iphone-with-google-calendar-the-missing-link/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 14:26:32 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[Product Reviews]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[google calendar]]></category>
		<category><![CDATA[iphone sync with google calendar]]></category>

		<guid isPermaLink="false">http://systemsconsciousness.com/?p=952</guid>
		<description><![CDATA[I was so happy when I got my iPhone. I didn&#8217;t expect it to change my life, but as I considered it in my IT career, it was a lighter pair of handcuffs. Instead of carrying around a heavy laptop when I traveled just in case I had to respond to an emergency or remote [...]]]></description>
			<content:encoded><![CDATA[<p>I was so happy when I got my iPhone. I didn&#8217;t expect it to change my life, but as I considered it in my IT career, it was a lighter pair of handcuffs. Instead of carrying around a heavy laptop when I traveled <em>just in case</em> I had to respond to an emergency or remote into a server, I hoped that my iPhone could handle some of my heavy computing even with its tiny screen and awkward touch keypad.</p>
<p>After manually entering all of my contacts (and taking a few minutes to delete a few), I began playing around with the calendar. I loved its sleek and shiny Apple appeal. It&#8217;s really quite easy to use. But one thing was missing: the ability to sync with Google Calendar. (I&#8217;ve taken to GCal after using it at my day job&#8211;I was raised on Exchange, but the IT manager before me implemented Google Mail, and there really hasn&#8217;t been a reason to change. I haven&#8217;t looked back, to be honest.) But for eight months I lamented my purchase for this one fatal flaw, despite the fact that it mostly surpassed all of my other needs and expectations.</p>
<p>I&#8217;m happy to report now that with the new 3.0 iPhone OS, syncing with Google Calendar&#8211;even multiple calendars&#8211;is so very easy. You will not have to sync your contacts with Google, nor will you run the risk of deleting important information. You just set it up and it works. It takes about three minutes.</p>
<p>Visit this link and follow the instructions: <a href="http://justanotheriphoneblog.com/wordpress/general/google-calendar-speaks-caldav-to-the-iphone" target="_blank">http://justanotheriphoneblog.com/wordpress/general/google-calendar-speaks-caldav-to-the-iphone</a></p>
<p>Thanks to Just Another iPhone Blog for this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2009/09/17/sync-iphone-with-google-calendar-the-missing-link/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SugarCRM Dashlets Have No Content</title>
		<link>http://systemsconsciousness.com/2009/08/25/sugarcrm-dashlets-have-no-content/</link>
		<comments>http://systemsconsciousness.com/2009/08/25/sugarcrm-dashlets-have-no-content/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 14:56:21 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[SugarCRM]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[dashlet]]></category>
		<category><![CDATA[fix]]></category>
		<category><![CDATA[module]]></category>

		<guid isPermaLink="false">http://systemsconsciousness.com/?p=934</guid>
		<description><![CDATA[If your new SugarCRM module has records in it, but it doesn&#8217;t show up in the dashlet&#8211;in fact, if nothing shows up in the dashlet for your new module, then follow the steps below. It&#8217;s a quirky little bug but a pretty easy fix. If you find this helpful, and you want to see more, [...]]]></description>
			<content:encoded><![CDATA[<p>If your new SugarCRM module has records in it, but it doesn&#8217;t show up in the dashlet&#8211;in fact, if nothing shows up in the dashlet for your new module, then follow the steps below. It&#8217;s a quirky little bug but a pretty easy fix. If you find this helpful, and you want to see more, please consider visiting one of our sponsors. Each click makes us a few cents.</p>
<p><center><script type="text/javascript"><!--
google_ad_client = "pub-7782798142568592";
/* PSQ 468x60, created 3/29/09 */
google_ad_slot = "5865335050";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></center><BR><BR></p>
<p>1. In the modules folder of your SugarCRM install directory, find the folder for the module that is giving you the problem.</p>
<p>2. Open the metadata folder, and then open the file &#8220;dashletviewdefs.php&#8221;.</p>
<p>3. On the second line of the file you should see something like $dashletData['xxx_SomeModule']['searchFields'] = array ( where xxx_SomeModule is the SugarCRM name for your new module. This is probably what is causing your error. If this xxx_SomeModule is not the same as the module name giving you the error, change it to the correct SugarCRM name for the module. For example, change it to read xxx_TheRightModuleDashlet. You have to add Dashlet to the end, as well.</p>
<p>4. Do a find/replace on the file to change any of the variable names that read xxx_SomeModule to xxx_TheRightModuleDashlet.</p>
<p>5. Remove and re-add the dashlet to your home page in SugarCRM.</p>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2009/08/25/sugarcrm-dashlets-have-no-content/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SugarCRM SOAP Examples Pt. 2: Queries and Google Charts</title>
		<link>http://systemsconsciousness.com/2009/08/13/sugarcrm-soap-examples-pt-2/</link>
		<comments>http://systemsconsciousness.com/2009/08/13/sugarcrm-soap-examples-pt-2/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 21:19:23 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[SugarCRM]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Queries]]></category>
		<category><![CDATA[SOAP]]></category>

		<guid isPermaLink="false">http://systemsconsciousness.com/?p=874</guid>
		<description><![CDATA[It's been a while since I wrote my last tutorial on SugarCRM, and I think it's time for an update. In my previous set of examples, I discussed connecting/authenticating to the SugarCRM SOAP API, inserting records and relating records programatically. In this edition I'm going to discuss how to query your SugarCRM database to retrieve a record or a list of records.]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I wrote my <a href="http://systemsconsciousness.com/2009/04/10/sugarcrm-soap-examples/" target="_self">last tutorial on SugarCRM</a>, and I think it&#8217;s time for an update. In my previous set of examples, I discussed connecting/authenticating to the SugarCRM SOAP API, inserting records and relating records programatically. In this edition I&#8217;m going to discuss how to query your SugarCRM database to retrieve a count of records. Then I&#8217;m going to show you how to present this data with the Google Charts API.</p>
<p>If you&#8217;re new to the SugarCRM Community Edition, then you may have noticed that there is very little support built in for reporting. While the CE version is incredibly full in terms of features, it does lack some of the expanded functionality provided by paid version of the software. Have a look at <a href="http://www.sugarcrm.com/crm/gopro/gopro.html" target="_blank">this chart</a>, if you haven&#8217;t already. You&#8217;ll notice that most of the features you get when you upgrade to a paid version of SugarCRM relate to reporting. This is because a CRM system is great if it simply prevents you from passing around Excel files and Access or FileMaker databases, but it&#8217;s almost useless if it still doesn&#8217;t give you a high-level view of your data. The goal of this article is to provide some entry-level examples of querying your data so that ultimately you can create your own reports, save thousands of dollars for your project and impress your friends. If you like what you see, and you want to see more, please consider visiting one of our sponsors. Each click makes us a few cents.</p>
<p><center><script type="text/javascript"><!--
google_ad_client = "pub-7782798142568592";
/* PSQ 468x60, created 3/29/09 */
google_ad_slot = "5865335050";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></center><BR><BR></p>
<p><strong>Getting Started</strong></p>
<p>First, you&#8217;ll need to create your PHP document and add the components mentioned previously to connect to your database via the SOAP API. Again, you&#8217;ll find this explained in detail <a href="http://systemsconsciousness.com/2009/04/10/sugarcrm-soap-examples/" target="_self">here</a>. In the previous example I integrated my custom PHP with WordPress&#8217; cForms plug in. This time I&#8217;m going to forgo the extra step of integration and focus on the queries themselves. So, after you&#8217;ve created your PHP document, you should put it somewhere like the htdocs\sugarcrm\custom on your SugarCRM server. Of course, you don&#8217;t have to do this. Since you&#8217;re connecting via SOAP, you can keep this file on any web server. For reporting purposes though you may want to keep it on your SugarCRM server so that you can link to it and access it easily from within Sugar.</p>
<p>Second, you&#8217;ll need to get familiar with the Google Charts API. This API is one of the most amazing utilities to come out of Google. If this is the first time you&#8217;ve encountered the API, you&#8217;ll want to take a minute to look over the documentation <a href="http://code.google.com/apis/chart/" target="_blank">here</a>. Google Charts works by passing in a URL with certain GET variables for the image SRC declaration in your HTML tag. Got it? Good.</p>
<p><strong>The Bad News First</strong></p>
<p>Let me get it out of the way and say that Sugar&#8217;s SOAP API is weak. They are purported to have enhanced this functionality in the <a href="http://www.sugarcrm.com/forums/forumdisplay.php?f=151" target="_blank">upcoming version 5.5</a>, which is currently in its beta release. I&#8217;ve already mentioned in my previous post that the documentation for such is lacking, too. It&#8217;s highly problematic when a blogger such as myself is an authority on something I had no part in writing&#8211;I&#8217;ve just brute-forced my way into it. So the approaches I am taking now to achieve the level of functionality I need with Sugar are substandard, but I&#8217;m hoping that their promises of a better API in version 5.5 will indeed be upheld.</p>
<p>Yann Tiersen on the headphones. Let&#8217;s get down to business. If you haven&#8217;t seen LornaJane&#8217;s PHPDocumentor dump, go ahead and check that out <a href="http://web.lornajane.net/sugar_soap_doc/default/_SugarSoapUsers.php.html" target="_blank">here</a>. It will at least tell you the components that make up the many SugarCRM SOAP calls. But not much more than that. Speaking of time, though, you&#8217;ll need to add the following two lines of code to the top of your php page so that your queries don&#8217;t eat up all the memory and your page doesn&#8217;t time out while loading.</p>
<blockquote><p>ini_set(&#8220;memory_limit&#8221;,&#8221;80M&#8221;);  // fix for soap<br />
set_time_limit(120);  // another fix</p></blockquote>
<p><strong>The get_entries_count() Call</strong></p>
<p>The get_entries_count() call (thanks Joe!) is a simply query that just counts the number of records specified and returns that integer. This is a very useful query because SugarCRM&#8217;s SOAP API is really slow when used to return actual records lists. If you&#8217;re just building a report, then you&#8217;re probably mostly interested in record counts anyway. This query will run in less than half the time of the get_entry_list() call, which I explain in more detail below.</p>
<p>Let&#8217;s start by creating a simple query. Let&#8217;s query the Opportunities table and find out how many new records were created in April of 2009. You&#8217;ll need LornaJane&#8217;s documentation and a little experience with SQL.</p>
<blockquote style="text-align:left !important;"><p>$startdate=&#8221;2009-04-01&#8243;;<br />
$enddate=&#8221;2009-04-30&#8243;;<br />
$month_response = $client-&gt;get_entries_count($session_id,&#8217;Opportunities&#8217;, &#8216;date_entered between &#8220;&#8216;.$startdate.&#8217;&#8221; and &#8220;&#8216;.$enddate.&#8217;&#8221;&#8216;, FALSE);<br />
$month_num = $month_response-&gt;result_count;</p>
<p>print $month_num;</p></blockquote>
<p>It&#8217;s pretty easy to see what&#8217;s happening here. The get_entries_count() function requires the Session ID, declared in your authentication statement, as well as the table you&#8217;re querying. Then there&#8217;s the SQL query WHERE statement. You&#8217;ll inevitably find it annoying that only the WHERE statement goes into the function. This removes a ton of functionality and makes it difficult to retrieve data efficiently. SQL has a COUNT parameter, for instance, and if I could specify more of the SQL text then there wouldn&#8217;t be the need for this get_entries_count() function at all. The &#8220;FALSE&#8221; statement at the end tells Sugar not to include deleted records. If no records were entered in the Opportunities table in April, then this will output 0. Otherwise you should see an integer.</p>
<p>Now let&#8217;s make it fun. Say you had several different sales stages specified in your Opportunities table. In our company&#8217;s Sugar implementation, we have five sales stages: Active, Dormant, Closed, Closed Won, and Closed Lost. Let&#8217;s say that we want to make a pie chart of this using the Google Charts API. We&#8217;ll need to make several different calls to count the different sales stages, then we&#8217;ll need to perform some basic mathematical operations to get some percentages.</p>
<blockquote style="text-align:left !important;"><p>// get data for the OUTCOME pie chart<br />
$active_response = $client-&gt;get_entries_count($session_id,&#8217;Opportunities&#8217;, &#8217;sales_stage like &#8220;Active&#8221;&#8216;, FALSE);<br />
$active_num = $active_response-&gt;result_count;<br />
$dormant_response = $client-&gt;get_entries_count($session_id,&#8217;Opportunities&#8217;, &#8217;sales_stage like &#8220;Dormant&#8221;&#8216;, FALSE);<br />
$dormant_num = $dormant_response-&gt;result_count;<br />
$closed_response = $client-&gt;get_entries_count($session_id,&#8217;Opportunities&#8217;, &#8217;sales_stage like &#8220;Closed&#8221;&#8216;, FALSE);<br />
$closed_num = $closed_response-&gt;result_count;<br />
$closedwon_response = $client-&gt;get_entries_count($session_id,&#8217;Opportunities&#8217;, &#8217;sales_stage like &#8220;Closed Won&#8221;&#8216;, FALSE);<br />
$closedwon_num = $closedwon_response-&gt;result_count;<br />
$closedlost_response = $client-&gt;get_entries_count($session_id,&#8217;Opportunities&#8217;, &#8217;sales_stage like &#8220;Closed Lost&#8221;&#8216;, FALSE);<br />
$closedlost_num = $closedlost_response-&gt;result_count;</p>
<p>// do some math<br />
$active_percent=round($active_num/$total_num*100);<br />
$dormant_percent=round($dormant_num/$total_num*100);<br />
$closed_percent=round($closed_num/$total_num*100);<br />
$closedwon_percent=round($closedwon_num/$total_num*100);<br />
$closedlost_percent=round($closedlost_num/$total_num*100);</p></blockquote>
<p>The first thing you should notice is that this is highly inefficient. In normal SQL land we would have used the COUNT and GROUP BY calls to get this information in a few lines. There should be a better way to do this, and I&#8217;m convinced there is&#8211;I just haven&#8217;t been able to find it yet because Sugar&#8217;s documentation and API are just so thin. Imagine, for instance, if I wanted to return the total number of Opportunities for each country. It would take hours to list all of the necessary queries to do that, and it would take minutes to run.</p>
<p>Now, to display this data in a pretty Google Chart, just add the following bits.</p>
<blockquote style="text-align:left !important;"><p>print &#8216;&lt;img src=&#8221;http://chart.apis.google.com/chart?chs=325&#215;165&amp;chts=333333,12&amp;chco=5DA4A4,cccccc,666666,65C665,C36464&amp;chtt=&#8217;.$total_num.&#8217; Opportunities as of &#8216;.$today.&#8217;|&amp;chd=t:&#8217;.$active_percent.&#8217;,&#8217;.$dormant_percent.&#8217;,&#8217;.$closed_percent.&#8217;,&#8217;.$closedwon_percent.&#8217;,&#8217;.$closedlost_percent.&#8217;&amp;cht=p&amp;amp;chl=Active &#8216;.$active_num.&#8217; (&#8216;.$active_percent.&#8217;%)|Dormant &#8216;.$dormant_num.&#8217; (&#8216;.$dormant_percent.&#8217;%)|Closed &#8216;.$closed_num.&#8217; (&#8216;.$closed_percent.&#8217;%)|Won &#8216;.$closedwon_num.&#8217; (&#8216;.$closedwon_percent.&#8217;%)|Lost &#8216;.$closedlost_num.&#8217; (&#8216;.$closedlost_percent.&#8217;%)&#8221; alt=&#8221;Opportunity Outcomes&#8221; /&gt;&#8217;;</p></blockquote>
<p>You should see this, but with your own numbers, of course:</p>
<p style="text-align: center;"><img class="aligncenter" title="Pie" src="http://chart.apis.google.com/chart?chs=325x165&#038;chts=333333,12&#038;chco=5DA4A4,cccccc,666666,65C665,C36464&#038;chtt=1191%20Opportunities%20as%20of%20August%2014,%202009|&#038;chd=t:38,35,1,5,21&#038;cht=p&#038;chl=Active%20448%20(38%)|Dormant%20418%20(35%)|Closed%2014%20(1%)|Won%2064%20(5%)|Lost%20247%20(21%)" alt="" width="325" height="175" /></p>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2009/08/13/sugarcrm-soap-examples-pt-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SugarCRM SOAP Examples</title>
		<link>http://systemsconsciousness.com/2009/04/10/sugarcrm-soap-examples/</link>
		<comments>http://systemsconsciousness.com/2009/04/10/sugarcrm-soap-examples/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 17:56:21 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[SugarCRM]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Example]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SOAP]]></category>

		<guid isPermaLink="false">http://deanhaddock.com/mercury/?p=370</guid>
		<description><![CDATA[If you use SugarCRM, one thing that you&#8217;ll inevitably need in this time of integrating web services, platforms and devices is the ability to send data from a web form into SugarCRM. You can use SOAP for this, and it works well, for the most part. But you&#8217;ll find there are very few good examples [...]]]></description>
			<content:encoded><![CDATA[<p>If you use SugarCRM, one thing that you&#8217;ll inevitably need in this time of integrating web services, platforms and devices is the ability to send data from a web form into SugarCRM. You can use SOAP for this, and it works well, for the most part. But you&#8217;ll find there are very few good examples out there on the web to really clarify and demystify a clean SugarCRM/SOAP implementation.</p>
<p>The best example I have found is here: <a href="http://www.lornajane.net/posts/2008/SugarCRM-SOAP-API-Examples" target="_blank">http://www.lornajane.net/posts/2008/SugarCRM-SOAP-API-Examples</a>. LornaJane&#8217;s examples were an excellent start, and I thought I&#8217;d go ahead and provide you some more details. The upside of these examples is that you won&#8217;t need to install nusoap in order for them to work. If you like what you see, and you want to see more, please consider visiting one of our sponsors. Each click makes us a few cents.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-7782798142568592";
/* systemsconsciousness - wide */
google_ad_slot = "2308144452";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><BR><BR></p>
<p><strong>Setup:</strong> LAMP web server running the latest version of WordPress with tons of plugins and customization. I also use cForms. It&#8217;s not important that you are using WordPress or that you have cForms installed. I just happen to like cForms, and I think it&#8217;s a fun challenge to integrate all these different systems. If you do use WP and cForms, just follow the instructions in the cForms documentation for customizing my-functions.php in your plugins/cforms-custom directory. The only real difference will be that you will use $POSTdata['varname'] instead of the regular $_POST['varname']. You&#8217;ll also need to use stripslashes() and pay attention to the variable names that cForms passes. I won&#8217;t be going into the specific details of cForms-to-SugarCRM here, but you should be able to infer how to implement that from this explanation.</p>
<p>This example uses a simple web form POST calling a PHP document as an action. For simplicity, let&#8217;s assume you have a web form with the following fields: first_name, last_name, email_address, phone_number and message.</p>
<p>When you submit the form, it calls &#8220;form-action.php&#8221;. You will implement the examples here in this PHP file.</p>
<p><strong>Getting Started</strong></p>
<p>To get started, let&#8217;s just get a basic example going. Copy and paste the following code in your form-action.php document. If you want to look at the SugarCRM documentation for these SOAP calls, go here: <a href="http://sugarcrm.openapp.org/2006/04/24/using-sugarcrm-soap/" target="_blank">http://sugarcrm.openapp.org/2006/04/24/using-sugarcrm-soap/</a> Part of the reason I&#8217;m writing this post is because they don&#8217;t provide any examples for these calls. Once you get the hang of it though, that link will be quite helpful to you.</p>
<blockquote><p>&lt;?php</p>
<p>// set up options array<br />
$options = array(<br />
&#8220;location&#8221; =&gt; &#8216;http://your.website.here/sugarcrm/soap.php&#8217;,<br />
&#8220;uri&#8221; =&gt; &#8216;http://www.sugarcrm.com/sugarcrm&#8217;,<br />
&#8220;trace&#8221; =&gt; 1<br />
);</p>
<p>//user authentication array<br />
$user_auth = array(<br />
&#8220;user_name&#8221; =&gt; &#8216;YOUR_SUGAR_USERNAME&#8217;,<br />
&#8220;password&#8221; =&gt; MD5(&#8216;YOUR_SUGAR_PASSWORD&#8217;),<br />
&#8220;version&#8221; =&gt; &#8216;.01&#8242;<br />
);</p>
<p>// connect to soap server<br />
$client = new SoapClient(NULL, $options);</p>
<p>// Login to SugarCRM<br />
$response = $client-&gt;login($user_auth,&#8217;test&#8217;);</p>
<p>$session_id = $response-&gt;id;</p>
<p>// look what modules sugar exposes<br />
$response = $client-&gt;get_available_modules($session_id);</p>
<p>// look in more detail at the fields in a module<br />
//$response = $client-&gt;get_module_fields($session_id, &#8216;Accounts&#8217;);</p>
<p>var_dump($response);</p>
<p>?&gt;</p></blockquote>
<p>So what&#8217;s going on here? Your options array is storing some variables that you&#8217;ll use a few lines later in the SoapClient call. The options array is where you specify the connection parameters to the server that has your SugarCRM installation. Naturally, you&#8217;ll want to make sure you enable port 80 access through your router/firewall because that&#8217;s the default port for HTTP and also SOAP. The next array of interest is $user_auth, which is where you specify your user name, password and SOAP version. After that you pass the connection options into the SoapClient() call and then log in via the login() call. The &#8216;test&#8217; parameter is a required application name, which can be most anything you want to call it. Once you pass the authentication, the $session_id variable grabs the session id for your current SOAP connection. You&#8217;ll need this with most, if not all, calls that you make from this point forward.</p>
<p>The next few lines of code are the fun part. The &#8220;$response = $client-&gt;get_available_modules($session_id);&#8221; line is grabbing all of the modules in your SugarCRM installation. This is very useful, for instance, when you want to know if the particular module you are attempting to write to is exposed. It&#8217;s also helpful when you&#8217;re trying to debug your SOAP calls and you&#8217;ve used the wrong module name, and so on. Below that is another example call that, if you uncomment the line, will return all of the fields that are exposed in a specific module, in this example&#8211;Accounts. Finally, var_dump($response) echos out whatever your $response variable has collected above.</p>
<p>Play around with it and get a feel for how it works. Notice that any custom modules you create show up in the list of available modules. Notice also that some modules, like Users, don&#8217;t return any available fields at all.</p>
<p><span id="more-370"></span></p>
<p><strong>Inserting a Record</strong></p>
<p>Now that you&#8217;ve made your first SOAP call to SugarCRM, you&#8217;ll want to try to insert a record or two into a module. This, like the previous example, is pretty simple and straight forward, but there are a few quirks like anything else in SugarCRM.</p>
<p>Let&#8217;s take the previous example to the next level. Under your $session_id variable declaration, add this line: &#8220;$user_id = $client-&gt;get_user_id($session_id);&#8221; You&#8217;ll need this eventually to assign a given record to a user. In this case we&#8217;re going to use the authenticated user&#8217;s id. Now the fun part! Remove or comment out the get_available_modules and get_module_fields lines and replace them with this:</p>
<blockquote><p>$response = $client-&gt;set_entry($session_id, &#8216;Leads&#8217;, array(<br />
array(&#8220;name&#8221; =&gt; &#8216;first_name&#8217;,&#8221;value&#8221; =&gt; $_POST['first_name']),<br />
array(&#8220;name&#8221; =&gt; &#8216;last_name&#8217;,&#8221;value&#8221; =&gt; $_POST['last_name']),<br />
array(&#8220;name&#8221; =&gt; &#8216;email1&#8242;,&#8221;value&#8221; =&gt; $_POST['email_address']),<br />
array(&#8220;name&#8221; =&gt; &#8216;work_phone&#8217;,&#8221;value&#8221; =&gt; $_POST['phone_number']),<br />
array(&#8220;name&#8221; =&gt; &#8216;description&#8217;,&#8221;value&#8221; =&gt; $_POST['message']),<br />
<span style="color: #000000;">array(&#8220;name&#8221; =&gt; &#8216;assigned_user_id&#8217;,&#8221;value&#8221; =&gt; $user_id)</span><br />
));</p></blockquote>
<p>Here, we&#8217;re inserting the data passed from our form into the Leads module in SugarCRM. One thing you may notice instantly is that some of the variable names for the SugarCRM module have different names than the POSTed variables from our form. The email address, for instance, gets inserted into the email1 field for SugarCRM. This is because SugarCRM has its own way of dealing with multiple (primary, secondary, etc.) email addresses. The $_POST['message'] variable is being inserted into the description field in the Leads module for simplicity because SugarCRM includes a description field in this module by default. The last line inserts the authenticated user&#8217;s id into the record and associates your new Lead with this user. This can be really helpful, say, if you have a team of people using SugarCRM to correspond with clients, and each person deals with a different type of incomming Lead. Your form-action.php file should now look something like this:</p>
<blockquote><p>&lt;?php</p>
<p>// set up options array<br />
$options = array(<br />
&#8220;location&#8221; =&gt; &#8216;http://your.website.here/sugarcrm/soap.php&#8217;,<br />
&#8220;uri&#8221; =&gt; &#8216;http://www.sugarcrm.com/sugarcrm&#8217;,<br />
&#8220;trace&#8221; =&gt; 1<br />
);</p>
<p>//user authentication array<br />
$user_auth = array(<br />
&#8220;user_name&#8221; =&gt; &#8216;YOUR_SUGAR_USERNAME&#8217;,<br />
&#8220;password&#8221; =&gt; MD5(&#8216;YOUR_SUGAR_PASSWORD&#8217;),<br />
&#8220;version&#8221; =&gt; &#8216;.01&#8242;<br />
);</p>
<p>// connect to soap server<br />
$client = new SoapClient(NULL, $options);</p>
<p>// Login to SugarCRM<br />
$response = $client-&gt;login($user_auth,&#8217;test&#8217;);</p>
<p>$session_id = $response-&gt;id;<br />
<span style="color: #008000;">$user_id = $client-&gt;get_user_id($session_id);</span></p>
<p><span style="color: #008000;">// write our form data to the Leads module<br />
$response = $client-&gt;set_entry($session_id, &#8216;Leads&#8217;, array(<br />
array(&#8220;name&#8221; =&gt; &#8216;first_name&#8217;,&#8221;value&#8221; =&gt; $_POST['first_name']),<br />
array(&#8220;name&#8221; =&gt; &#8216;last_name&#8217;,&#8221;value&#8221; =&gt; $_POST['last_name']),<br />
array(&#8220;name&#8221; =&gt; &#8216;email1&#8242;,&#8221;value&#8221; =&gt; $_POST['email_address']),<br />
array(&#8220;name&#8221; =&gt; &#8216;work_phone&#8217;,&#8221;value&#8221; =&gt; $_POST['phone_number']),<br />
array(&#8220;name&#8221; =&gt; &#8216;description&#8217;,&#8221;value&#8221; =&gt; $_POST['message']),<br />
array(&#8220;name&#8221; =&gt; &#8216;assigned_user_id&#8217;,&#8221;value&#8221; =&gt; $user_id)<br />
));</span></p>
<p>var_dump($response);</p>
<p>?&gt;</p></blockquote>
<p>When you execute this code, you get something that looks like this:</p>
<blockquote><p>object(stdClass)#61 (2) {   ["id"]=&gt;   string(36) &#8220;7e084ce3-8ccb-1a73-4e82-49df645ff06a&#8221;   ["error"]=&gt;   object(stdClass)#58 (3) {     ["number"]=&gt;     string(1) &#8220;0&#8243;     ["name"]=&gt;     string(8) &#8220;No Error&#8221;     ["description"]=&gt;     string(8) &#8220;No Error&#8221;   } }</p></blockquote>
<p>Believe it or not, this means it worked. More evidence that it worked will be when the record pops up in your SugarCRM Leads module and you scream eureka and everyone in your office turns around to stare at you. When you&#8217;re ready to publish your form to a live website, just comment out the var_dump line and add something like, echo &#8220;Your form worked, and I&#8217;m awesome.&#8221;;.</p>
<p><!--more--></p>
<p><strong>Relating Two Records in Different Modules</strong></p>
<p>This example was a little tricky to figure out, but ultimately it&#8217;s pretty simple. You will inevitably need to relate a record with another record, say, for example, if you&#8217;re using the <a href="http://www.sugarforge.org/projects/ithelpdesk/" target="_blank">ITHelpDesk module</a> created by the good folks at <a href="http://www.storycorps.net" target="_blank">StoryCorps</a>. You could easily create a web form for your users to enter a support request on your company&#8217;s intranet site and have it go straight into the ITHelpDesk module. You&#8217;d just need to backtrack through these examples a bit to get the right module and field names, and then tweak the examples provided herein to write the appropriate data to the appropriate places. Then you could append the following bit of code to associate, say, the Support record with the Inventory record as its entered into SugarCRM.</p>
<p>But for simplicity sake, we&#8217;re just going to create an Account record and a Contact record and relate them instead of creating a Lead. Start by adding another field to your form, called organization_name. Then refer back to the previous example and edit the Leads insert example to insert into the Contacts table instead. Copy and paste the Contacts $response insert lines and modify it to add a record to the Accounts table. For this part, just add the organization_name variable to the Accounts module, which is stored as the &#8220;name&#8221; field in SugarCRM. If you stop at this point, you&#8217;ll just have a new account and a new contact in SugarCRM, but they won&#8217;t be related. They also won&#8217;t be related if you just put the organization_name in as the associated account in your Contacts $response insert. Don&#8217;t waste your juice trying to do this. Instead, you&#8217;ll need this little bit of code, which you&#8217;ll insert after your two $response inserts:</p>
<blockquote><p>$relationship = array(<br />
&#8216;module1&#8242; =&gt; &#8216;Contacts&#8217;,<br />
&#8216;module1_id&#8217; =&gt; &#8220;$contact_id&#8221;,<br />
&#8216;module2&#8242; =&gt; &#8216;Accounts&#8217;,<br />
&#8216;module2_id&#8217; =&gt; &#8220;$account_id&#8221;,<br />
);</p>
<p>// call set_relationship()<br />
$response = $client-&gt;set_relationship($session_id, $relationship);</p></blockquote>
<p>Pretty simple, right? This won&#8217;t work without the $contact_id and $account_id variables though, so you&#8217;ll need to call $contact_id = $response-&gt;id and $account_id = $response-&gt;id after each of your $response inserts. The final result will look something like this:</p>
<blockquote><p>&lt;?php</p>
<p>// set up options array<br />
$options = array(<br />
&#8220;location&#8221; =&gt; &#8216;http://your.website.here/sugarcrm/soap.php&#8217;,<br />
&#8220;uri&#8221; =&gt; &#8216;http://www.sugarcrm.com/sugarcrm&#8217;,<br />
&#8220;trace&#8221; =&gt; 1<br />
);</p>
<p>//user authentication array<br />
$user_auth = array(<br />
&#8220;user_name&#8221; =&gt; &#8216;YOUR_SUGAR_USERNAME&#8217;,<br />
&#8220;password&#8221; =&gt; MD5(&#8216;YOUR_SUGAR_PASSWORD&#8217;),<br />
&#8220;version&#8221; =&gt; &#8216;.01&#8242;<br />
);</p>
<p>// connect to soap server<br />
$client = new SoapClient(NULL, $options);</p>
<p>// Login to SugarCRM<br />
$response = $client-&gt;login($user_auth,&#8217;test&#8217;);</p>
<p>$session_id = $response-&gt;id;<br />
<span style="color: #000000;">$user_id = $client-&gt;get_user_id($session_id);</span></p>
<p><span style="color: #000000;">// write our form data to the Contacts module<br />
$response = $client-&gt;set_entry($session_id, &#8216;Contacts&#8217;, array(<br />
array(&#8220;name&#8221; =&gt; &#8216;first_name&#8217;,&#8221;value&#8221; =&gt; $_POST['first_name']),<br />
array(&#8220;name&#8221; =&gt; &#8216;last_name&#8217;,&#8221;value&#8221; =&gt; $_POST['last_name']),<br />
array(&#8220;name&#8221; =&gt; &#8216;email1&#8242;,&#8221;value&#8221; =&gt; $_POST['email_address']),<br />
array(&#8220;name&#8221; =&gt; &#8216;work_phone&#8217;,&#8221;value&#8221; =&gt; $_POST['phone_number']),<br />
array(&#8220;name&#8221; =&gt; &#8216;description&#8217;,&#8221;value&#8221; =&gt; $_POST['message']),<br />
array(&#8220;name&#8221; =&gt; &#8216;assigned_user_id&#8217;,&#8221;value&#8221; =&gt; $user_id)<br />
));</span></p>
<p><span style="color: #008000;">$contact_id = $response=&gt;id;</span></p>
<p><span style="color: #008000;">// write our form data to the Accounts module<br />
$response = $client-&gt;set_entry($session_id, &#8216;Contacts&#8217;, array(<br />
array(&#8220;name&#8221; =&gt; &#8216;name&#8217;,&#8221;value&#8221; =&gt; $_POST['organization_name']),<br />
array(&#8220;name&#8221; =&gt; &#8216;assigned_user_id&#8217;,&#8221;value&#8221; =&gt; $user_id)<br />
));</span></p>
<p><span style="color: #008000;">$account_id = $response=&gt;id;</span></p>
<p><span style="color: #008000;">$relationship = array(<br />
&#8216;module1&#8242; =&gt; &#8216;Contacts&#8217;,<br />
&#8216;module1_id&#8217; =&gt; &#8220;$contact_id&#8221;,<br />
&#8216;module2&#8242; =&gt; &#8216;Accounts&#8217;,<br />
&#8216;module2_id&#8217; =&gt; &#8220;$account_id&#8221;,<br />
);</span></p>
<p><span style="color: #008000;">// call set_relationship()<br />
$response = $client-&gt;set_relationship($session_id, $relationship);</span></p>
<p>//var_dump($response);</p>
<p>?&gt;</p></blockquote>
<p>Now if neither of us has made any blunders you should have a working web-to-SugarCRM form that creates a related Account record and a Contact record, both of which are assigned to the authenticated user. Clearly this is very useful technology because it allows your team to respond to web inquiries directly from SugarCRM. With creative use of such modules as the Google Calendar connector (which works, but you can&#8217;t uninstall it after you run a Repair or upgrade), you can do some pretty creative stuff to cut down on extraneous software and procedures.</p>
<p>Long live integration! And good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2009/04/10/sugarcrm-soap-examples/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Pour Some SugarCRM on Me</title>
		<link>http://systemsconsciousness.com/2008/11/21/sugarcrm-open-source-crm-solution/</link>
		<comments>http://systemsconsciousness.com/2008/11/21/sugarcrm-open-source-crm-solution/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 20:30:12 +0000</pubDate>
		<dc:creator>Dean Haddock</dc:creator>
				<category><![CDATA[SugarCRM]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CRM]]></category>
		<category><![CDATA[Data Management]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://deanhaddock.com/mercury/?p=155</guid>
		<description><![CDATA[SugarCRM is a web-based Customer Relationship Management web application that organizations can use to centralize and manage their internal data and work flows. It is a SaaS solution, remotely hosted and maintained on Sugar&#8217;s servers for a fee&#8211;$275 to $449 per user per year, depending on the level of service you require. They also offer [...]]]></description>
			<content:encoded><![CDATA[<p><a title="SugarCRM" href="http://www.sugarcrm.com/crm/" target="_blank">SugarCRM</a> is a web-based <a title="CRM" href="http://en.wikipedia.org/wiki/Customer_relationship_management" target="_blank">Customer Relationship Management</a> web application that organizations can use to centralize and manage their internal data and work flows. It is a <a title="SaaS" href="http://en.wikipedia.org/wiki/Software_as_a_Service" target="_blank">SaaS</a> solution, remotely hosted and maintained on Sugar&#8217;s servers for a fee&#8211;$275 to $449 per user per year, depending on the level of service you require. They also offer an on-sight solution and an open source <a title="SugarCRM Community Edition" href="http://www.sugarcrm.com/crm/community/sugarcrm-community.html" target="_blank">Community Edition</a>, which you can download and install on your own web server to meet your needs for free. This article discusses my experience implementing SugarCRM Community Edition,  including module building, upgrades, and considerations for the future of SugarCRM. If you like what you see, and you want to see more, please consider visiting one of our sponsors. Each click makes us a few cents.</p>
<p><center><script type="text/javascript"><!--
google_ad_client = "pub-7782798142568592";
/* PSQ 468x60, created 3/29/09 */
google_ad_slot = "5865335050";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></center><BR><BR></p>
<p>I first implemented SugarCRM about a year ago when my Information Technology team was looking for a help desk and inventory management solution. SugarCRM isn&#8217;t designed for this out-of-the-box, but it does allow you to create and modify modules to suit a wide array of data management needs. I was impressed at the &#8220;Fast Stack&#8221; installers that unpacked and configured Apache, MySQL and Sugar&#8217;s source files (more or less) automatically. I had SugarCRM running on a development server in minutes, and I quickly moved to installing and creating modules. While I found it overall a great application with a lot of promise, we chose to go with <a title="MS SharePoint" href="http://www.microsoft.com/sharepoint/default.mspx">Microsoft SharePoint</a> because, with the exception of myself, our IT team militantly supported MS.<span id="more-155"></span></p>
<p>But recently I&#8217;ve taken over the IT operations of a fantastic non-profit that embraces open source software, and in three weeks we&#8217;ve already implemented SugarCRM to track our IT hardware and software inventory, licenses and support issues. This was made easier by the IT coordinator keeping up with existing inventory so well. Our goal was to centralize the data in order to begin working with it, as opposed to merely logging the data in a FileMaker database. The goal in our IT implementation of SugarCRM is to not only keep a record of all computer and network equipment, but also associate this data with software, licenses and technical support issues. In doing this we could then produce reports and track buggy or defective products.</p>
<h3>Getting Started</h3>
<p>After evaluating a few other CRM&#8217;s, like <a title="DrupalCRM" href="http://drupal.org/node/55902" target="_blank">DrupalCRM</a> and <a title="SalesForce.com" href="http://SalesForce.com" target="_blank">SalesForce.com</a>, we chose SugarCRM because the price for the Community Edition&#8211;free&#8211;was in our budget. We also felt that SugarCRM offered more to us in terms of developing custom modules and taking advantage of modules that others have developed. Furthermore, if we do at some point require more assistance from SugarCRM for development, hosting or support, we can upgrade to one of the paid levels of service. This is very appealing to organizations who cannot or do not want to spend a lot of money on a CRM solution, and I hope to see more SaaS products adopt similar models in the future.</p>
<p>Overall the end-user side of SugarCRM is pretty stable, with the exception of a few annoying little bugs. But developers beware: The module builder is very flaky, and it is possible to totally destroy your SugarCRM installation with a few wrong clicks. I&#8217;ve rebuilt the help desk module I designed at least four times, and I&#8217;ve had to reinstall the entire SugarCRM package at least three times. We finally elected to implement parallel installations on a development server, where we build modules to deploy on a production SugarCRM server. This has been pretty agreeable so far, and the <a title="SugarCRM Overhead" href="http://www.sugarforge.org/content/getting-started/system-requirements.php" target="_blank">low application overhead</a> makes it affordable to do this. Once we are convinced of the robustness of a particular custom module, we publish it from within the module builder and then install it on the production server. Certainly it&#8217;s not the best idea to develop on a production server, if you have the resources for it. But also it shouldn&#8217;t be the case that a few wrong clicks will tank an application.</p>
<h3>Installing and Creating Modules</h3>
<p>Before creating modules from scratch, it&#8217;s a good idea to join the <a title="Sugar Forums" href="http://www.sugarcrm.com/forums/" target="_blank">Sugar Forums</a> and mill around <a title="SugarForge" href="http://www.sugarforge.org/" target="_blank">SugarForge</a> to see what is already available. Currently there are 472 modules available for SugarCRM, which seems like a huge amount. But one thing you will find is that these modules are not compatible with all versions of SugarCRM. We are currently using version 5.1.0b, which only supports 59 of the 472 existing modules (give or take). To give you an example of how disruptive this problem is I&#8217;ve found several really good modules that I&#8217;d like to install on our production server, but almost none of them are compatible with the latest release.</p>
<p>This is annoying for several reasons, but most importantly it is a huge disincentive to create new modules. Why should I create and publish a help desk module if it will be obsolete upon the next release? Is it fair of SugarCRM to expect me to rebuild the module every time I upgrade? What if I retire or transition to a new organization that doesn&#8217;t use SugarCRM? It&#8217;s obvious that a lot of developers have invested time in creating some pretty interesting plugins that are completely irrelevant now. This also makes new releases of SugarCRM something to dread rather than something to look forward to. There must be a better way, and I hope the developers at SugarCRM are working to meet this lofty but important obstacle.</p>
<p>Since we were unable to find a module for exactly what we need, we opted to build our own. The help desk module we created is comprised of four tables: Inventory, Software, Licenses and Support. We have each inventory item associated with a user. (The user table is built-in to the original installation, and the Community Edition does not grant you access to this within the application.) When we add a new computer, for instance, we input details like CPU speed, serial number, manufacturer, model, and so on. We can then click a select box and choose the user to assign the equipment to. We have another form to add new software inventory, like Microsoft Office, FileMaker, and anti-virus utilities. We then associate each piece of sofware to the computer inventory by license instances. These assets are also associated with the built-in Accounts table, which is in turn associated with the Contacts table.</p>
<p>If a user notifies us of a problem, we can create a support instance, which is attached to the specific machine and software giving the problem. Depending on the nature of the problem, we may need to contact the vendor or a third-party warranty provider. To this end each inventory and software item is associated with an account contact and warranty contact, if applicable. From a management perspective, this type of data can help us track our assets and workload, and it ultimately assists us in retiring (and ceasing to purchase) defective equipment.</p>
<h3>Beyond the Help Desk</h3>
<p>In the past few weeks our IT department has been meeting with different units within our organization to explore their data and tracking needs. Now that the Help Desk module is complete we are developing/revising a module that another department will use to track business contacts and sales leads. This is quite exciting because it is exactly what SugarCRM was designed to do. One thing most SugarCRM users will ultimately notice is that this application will offer way more than your organization probably needs. The module studio comes in extremely handy here so you can remove unnecessary fields and organizes tables in ways that are optimal for a particular department&#8217;s work flow.</p>
<p>This presents another issue though, namely user rights management. SugarCRM allows you to associate users with specific roles, much like Microsoft&#8217;s Active Directory. It&#8217;s not nearly as powerful as network level security policies, but it&#8217;s handy because you can assign specific rights to specific roles. If IT does not need to see the Opportunities and Leads tables, for instance, you can remove these tabs from the menu. Unfortunately, it&#8217;s not yet possible to omit data within specific tables based upon roles. By this I mean that there may be specific leads or contacts that only one role needs to see. Currently I would have to build a parallel module and store data in separate tables to satisfy this need.</p>
<p>Another limitation we&#8217;ve experienced is that there is no reporting module available in the Community Edition. Why they do not offer this baffles me, and I can only speculate that it&#8217;s because they want to up-sell their open source users to the paid version. There may be no reason to do this other than wanting clean and customizable reports. I can&#8217;t fault them for this from a business perspective, but it&#8217;s an artificial way to upsell me considering that the module clearly exists already. That is, there is no real cost limitation in providing this in the Community Edition. They just don&#8217;t offer it.</p>
<h3>The Future of SugarCRM</h3>
<p>This leads me to consider the future of SugarCRM. First let me state that my educational background is in institutional economics rather than computer science or any technologically related field. I&#8217;m trained academically to identify incentive structures within organizations and markets, rather intended or unintended. A practical example of this is something like downloading free mp3s as opposed to purchasing them outright. As an institutionalist, I look at the probability of actual enforcement of the DMCA for music theft and the ease of downloading free music illegally. I also scrutenize competing institutional structures, like the individual&#8217;s right to privacy, that may infringe upon the abilities of law enforcement agents to enforce a particular institutional arrangement.</p>
<p>With that bias in mind I have to admit that I&#8217;m not optimistic about the future of SugarCRM. Although they are clearly the market leader of open source CRM vendors, they have serious limitations in terms of their development policies. As I mentioned previously, the lack of compatibility among modules and version strongly discourages expanding their module-building community. A better approach to this would be to release a future version of SugarCRM that would adhere to the same module structure indefinitely. It is posisble to do this with a little bit of foresight, but in the five or so versions of SugarCRM that have been released there has been no evidence of them moving this direction.</p>
<p>Another future project that I would like to see SugarCRM implement is a very simple, blank PHP page generator that would let me click a few buttons and be editing a new PHP document. This seems like a very simple addition, but so far the SugarCRM development team has completely rejected this idea. For some reason the developers and even most of the community cannot see the utility in being able to interface with the database like this. Some of the debate has been quite heated, and I invite you to read the exchange between myself and a forum member, SugarDev.net, <a title="Sugar Forum Exchange" href="http://www.sugarcrm.com/forums/showthread.php?p=137750#post137750" target="_blank">here</a>. I admit that I thought I was conversing with an actual SugarCRM Developer rather than an unhelpful fellow user, and I was shocked as to his responses. But as soon as I learned he was just another user, I was certainly more accepting of his opinion, which is mainly that SugarCRM can&#8217;t or shouldn&#8217;t offer this PHP enhancement because it would be too difficult.</p>
<p>As far as I see it, SugarCRM Community Edition is just that&#8211;it exists for the community of users, which includes myself and my organization. If one of the community members has a need, it&#8217;s the responsibility of SugarCRM to help us meet that need. Even if SugarCRM cannot devote the development hours to implement the change for us, they should at the very least assure that their platform offers us the ability to enhance the system ourselves. Sure, there is a way to implement this little PHP enhancement on my own. But I&#8217;m not nearly familiar enough with the source code to do this. I doubt very seriously that SugarCRM will ever implement this for me, but I can tell you what I would do with it: I would create a PHP page that read data from SugarCRM&#8217;s database and presented it in a form-like manner on a page. I would even impement a solution to export tables (or parts of tables) as CSV and PDF. I would take full advantage of the <a title="Google Charts" href="http://code.google.com/apis/chart/" target="_blank">Google Charts API</a> to present clean graphical representations of the data in our SugarCRM implementation. I could even create my own custom forms and further integrate our SugarCRM installation with other databases in our network.</p>
<h3>Conclusion</h3>
<p>It&#8217;s obvious to me that not every organization is ready to take the non-linear leap that enables the product to grow beyond its original intent. Surely, SugarCRM was designed to be exactly what it is&#8211;a Customer Relationship Management tool. And it does this very, very well considering its occassional hangups. On the other hand, this web application is so close to being useable for greater data management needs that it seems criminal to hold it back</p>
<p>There are certainly many bugs floating around SugarCRM, but most of them are addressed very quickly via uprades and new releases. I definitely cannot complain about where the project is now compared to my first attempt at using it. But perhaps my perspective of the project, coming from two distinct times and organizations in which I used it, makes it more apparent to me than most that SugarCRM is far below its potential.</p>
<p>So what am I going to do about it? I will continue to contribute my opinions on the forums and otherwise in hopes that eventually my needs will be heard. I&#8217;ll continue to develop modules and deploy them for other organizations to use. At the time of writing this article our corporate attorneys are evaluating the logistics of deploying our first module for the public, namely the help desk module mentioned herein. Ultimately it will be published, but the current question is whether it is done so under my monicer or the company for which I work. I&#8217;m really looking forward to giving back to the SugarCRM community though, and I hope that by participating in this way they&#8217;ll be more likely to listen to recommendations.</p>
<p>I definitely recommend giving SugarCRM a try, but not without some degree of caution. It is very easy to install and use, but I encourage any new users of the application to spend some time trying to break it. As a developer, you will be able to break it very quickly. Just try making a new module and playing with the table relationships. Eventually you&#8217;ll delete a variable or field and find the error with which many of us have become very familiar. Fortunately though the application is pretty solid from the end user&#8217;s perspective, so when you are comfortable with it you&#8217;ll find it a powerful edition to your organization&#8217;s data management resources.</p>
<p>If you have any questions or feedback, join the SugarCRM Forum! Or feel free to contact me directly.</p>
]]></content:encoded>
			<wfw:commentRss>http://systemsconsciousness.com/2008/11/21/sugarcrm-open-source-crm-solution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
